UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

100 lines (99 loc) 3.84 kB
"use strict"; 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() }; }