@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
100 lines (99 loc) • 3.84 kB
JavaScript
;
import { CADSopNode } from "./_BaseCAD";
import { NodeParamsConfig, ParamConfig } from "../utils/params/ParamsConfig";
import { step } from "../../../core/geometry/modules/cad/CadConstant";
import { CadLoader } from "../../../core/geometry/modules/cad/CadLoader";
import { CadGC } from "../../../core/geometry/modules/cad/CadCommon";
import { SopType } from "../../poly/registers/nodes/types/Sop";
import { CadLoaderSync } from "../../../core/geometry/modules/cad/CadLoaderSync";
import { cadShapeTranslate } from "../../../core/geometry/modules/cad/toObject3D/CadShapeCommon";
const FILLET_RADIUS_SAFETY_MARGIN = 0.01;
const HALF_PI = 0.5 * Math.PI;
class CADRectangleSopParamsConfig extends NodeParamsConfig {
constructor() {
super(...arguments);
/** @param size */
this.size = ParamConfig.VECTOR2([1, 1]);
/** @param center */
this.center = ParamConfig.VECTOR3([0, 0, 0]);
/** @param fillet radius */
this.filletRadius = ParamConfig.FLOAT(0.1, {
range: [0, 1],
rangeLocked: [true, false],
step
});
}
}
const ParamsConfig = new CADRectangleSopParamsConfig();
export class CADRectangleSopNode extends CADSopNode {
constructor() {
super(...arguments);
this.paramsConfig = ParamsConfig;
}
static type() {
return SopType.CAD_RECTANGLE;
}
async cook(inputCoreGroups) {
const oc = await CadLoader.core(this);
CadGC.withGC((r) => {
const w = this.pv.size.x;
const h = this.pv.size.y;
const minDim = Math.min(w, h);
const rad = Math.min(this.pv.filletRadius, minDim / 2 - FILLET_RADIUS_SAFETY_MARGIN);
const x = w / 2 - rad;
const z = h / 2 - rad;
const arc0 = _createArc(oc, r, x, z, rad, 3);
const arc1 = _createArc(oc, r, x, -z, rad, 0);
const arc2 = _createArc(oc, r, -x, -z, rad, 1);
const arc3 = _createArc(oc, r, -x, z, rad, 2);
const edgesCount = 8;
const linesCount = 4;
const edges = r(new oc.TopTools_Array1OfShape_2(0, edgesCount - 1));
const vertices = r(new oc.TopTools_Array1OfShape_2(0, 7));
edges.SetValue(0, arc0.edge);
edges.SetValue(2, arc1.edge);
edges.SetValue(4, arc2.edge);
edges.SetValue(6, arc3.edge);
vertices.SetValue(0, arc0.vertex1);
vertices.SetValue(1, arc1.vertex0);
vertices.SetValue(2, arc1.vertex1);
vertices.SetValue(3, arc2.vertex0);
vertices.SetValue(4, arc2.vertex1);
vertices.SetValue(5, arc3.vertex0);
vertices.SetValue(6, arc3.vertex1);
vertices.SetValue(7, arc0.vertex0);
for (let i = 0; i < linesCount; i += 1) {
const startVertex = oc.TopoDS.Vertex_2(vertices.Value(i * 2));
const endVertex = oc.TopoDS.Vertex_2(vertices.Value(i * 2 + 1));
const edgeApi = r(new oc.BRepBuilderAPI_MakeEdge_2(startVertex, endVertex));
const edge = edgeApi.Edge();
edges.SetValue(i * 2 + 1, edge);
}
const wireApi = r(new oc.BRepBuilderAPI_MakeWire_1());
for (let i = 0; i < edgesCount; i++) {
wireApi.Add_1(oc.TopoDS.Edge_2(edges.Value(i)));
}
const wire = wireApi.Wire();
const shape = cadShapeTranslate(wire, this.pv.center);
this.setCADShape(shape);
});
}
}
function _createArc(oc, r, x, z, radius, angleIncrement) {
const dir = CadLoaderSync.gp_Dir;
dir.SetCoord_2(0, 1, 0);
const axis = r(new oc.gp_Ax2_1());
axis.SetDirection(dir);
const offset = r(new oc.gp_Vec_4(x, 0, z));
axis.Translate_1(offset);
const circle = new oc.gp_Circ_2(axis, radius);
const angleStart = angleIncrement * HALF_PI;
const angleEnd = (angleIncrement + 1) * HALF_PI;
const api = r(new oc.BRepBuilderAPI_MakeEdge_9(circle, angleStart, angleEnd));
const edge = api.Edge();
return {
edge,
vertex0: api.Vertex1(),
vertex1: api.Vertex2()
};
}