UNPKG

@polygonjs/polygonjs

Version:

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

179 lines (178 loc) 5.79 kB
"use strict"; import { CADSopNode } from "./_BaseCAD"; import { NodeParamsConfig, ParamConfig } from "../utils/params/ParamsConfig"; import { CadGC, CadGeometryType, cadGeometryTypeFromShape, cadDowncast } from "../../../core/geometry/modules/cad/CadCommon"; import { SopType } from "../../poly/registers/nodes/types/Sop"; import { CadLoaderSync } from "../../../core/geometry/modules/cad/CadLoaderSync"; import { CadObject } from "../../../core/geometry/modules/cad/CadObject"; import { isBooleanTrue } from "../../../core/Type"; class CADExtrudeSopParamsConfig extends NodeParamsConfig { constructor() { super(...arguments); /** @param direction */ this.dir = ParamConfig.VECTOR3([0, 1, 0]); /** @param height */ this.height = ParamConfig.FLOAT(1, { range: [-10, 10], rangeLocked: [false, false] }); /** @param create caps */ this.cap = ParamConfig.BOOLEAN(1); /** @param convert caps to faces */ this.capsAsFaces = ParamConfig.BOOLEAN(1); } } const ParamsConfig = new CADExtrudeSopParamsConfig(); export class CADExtrudeSopNode extends CADSopNode { constructor() { super(...arguments); this.paramsConfig = ParamsConfig; } static type() { return SopType.CAD_EXTRUDE; } initializeNode() { this.io.inputs.setCount(1); } cook(inputCoreGroups) { const inputCoreGroup = inputCoreGroups[0]; const extrudeDir = CadLoaderSync.gp_Vec; extrudeDir.SetCoord_2( this.pv.dir.x * this.pv.height, this.pv.dir.y * this.pv.height, this.pv.dir.z * this.pv.height ); const newObjects = []; const inputObjects = inputCoreGroup.cadObjects(); if (inputObjects) { const oc = CadLoaderSync.oc(); CadGC.withGC((r) => { const options = { oc, r, newObjects, extrudeDir }; for (const object of inputObjects) { this._processObject(object, options); } }); } this.setCADObjects(newObjects); } _processObject(object, options) { const type = object.type; switch (type) { case CadGeometryType.VERTEX: { return this._processVertexObject(object, options); } case CadGeometryType.EDGE: { return this._processEdgeObject(object, options); } case CadGeometryType.WIRE: { return this._processWireObject(object, options); } case CadGeometryType.FACE: { return this._processFaceObject(object, options); } case CadGeometryType.SHELL: { return this._processShellObject(object, options); } default: { return options.newObjects.push(object); } } } _processVertexObject(object, options) { const { oc, r, newObjects, extrudeDir } = options; const vertex = object.cadGeometry(); const prismApi = r(new oc.BRepPrimAPI_MakePrism_1(vertex, extrudeDir, false, true)); const prism = prismApi.Shape(); const type = cadGeometryTypeFromShape(oc, prism); if (type) { const newObject = new CadObject(prism, type); newObjects.push(newObject); } } _processEdgeObject(object, options) { const { oc, r, extrudeDir, newObjects } = options; const edge = object.cadGeometry(); const api = r(new oc.BRepPrimAPI_MakePrism_1(edge, extrudeDir, false, true)); const shapes = [api.Shape()]; for (const shape of shapes) { const type = cadGeometryTypeFromShape(oc, shape); if (type) { const newObject = new CadObject(shape, type); newObjects.push(newObject); } } } _processWireObject(object, options) { const wire = object.cadGeometry(); this._processWire(wire, options); } _processWire(wire, options) { const { oc, r, extrudeDir, newObjects } = options; const api = r(new oc.BRepPrimAPI_MakePrism_1(wire, extrudeDir, false, true)); const shapes = [api.Shape()]; if (isBooleanTrue(this.pv.cap)) { const addCap = (capShape, invert) => { if (!capShape) { return; } if (cadGeometryTypeFromShape(oc, capShape) == CadGeometryType.WIRE) { const wire2 = cadDowncast(oc, capShape); if (isBooleanTrue(this.pv.capsAsFaces)) { const capApi = r(new oc.BRepBuilderAPI_MakeFace_15(wire2, true)); if (capApi.IsDone()) { const face = capApi.Face(); shapes.push(invert ? face.Complemented() : face); } } else { shapes.push(capShape); } } }; addCap(api.FirstShape(), false); addCap(api.LastShape(), true); } for (const shape of shapes) { const type = cadGeometryTypeFromShape(oc, shape); if (type) { const newObject = new CadObject(shape, type); newObjects.push(newObject); } } } _processFaceObject(object, options) { this._processFace(object.cadGeometry(), options); } _processFace(face, options) { const { oc, r, newObjects, extrudeDir } = options; const api = r(new oc.BRepPrimAPI_MakePrism_1(face, extrudeDir, false, true)); const shapes = [api.Shape()]; for (const shape of shapes) { const type = cadGeometryTypeFromShape(oc, shape); if (type) { const newObject = new CadObject(shape, type); newObjects.push(newObject); } } } _processShellObject(object, options) { const { oc, r, newObjects, extrudeDir } = options; const shell = object.cadGeometry(); const prismApi = r(new oc.BRepPrimAPI_MakePrism_1(shell, extrudeDir, false, true)); const prism = prismApi.Shape(); const type = cadGeometryTypeFromShape(oc, prism); if (type) { const newObject = new CadObject(prism, type); newObjects.push(newObject); } } }