UNPKG

@polygonjs/polygonjs

Version:

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

245 lines (244 loc) 9.41 kB
"use strict"; import { CADSopNode } from "./_BaseCAD"; import { NodeParamsConfig, ParamConfig } from "../utils/params/ParamsConfig"; import { cadGeometryTypeFromShape } from "../../../core/geometry/modules/cad/CadCommon"; import { CadObject } from "../../../core/geometry/modules/cad/CadObject"; import { TypeAssert } from "../../poly/Assert"; import { SopType } from "../../poly/registers/nodes/types/Sop"; import { CadLoaderSync } from "../../../core/geometry/modules/cad/CadLoaderSync"; var BooleanMode = /* @__PURE__ */ ((BooleanMode2) => { BooleanMode2["ALL_IN_SEQUENCE"] = "process all in sequence"; BooleanMode2["ONE_TO_ONE"] = "one to one"; BooleanMode2["ONE_TO_MANY"] = "one to many"; return BooleanMode2; })(BooleanMode || {}); const BOOLEAN_MODES = ["process all in sequence" /* ALL_IN_SEQUENCE */, "one to one" /* ONE_TO_ONE */, "one to many" /* ONE_TO_MANY */]; export var BooleanCadOperationType = /* @__PURE__ */ ((BooleanCadOperationType2) => { BooleanCadOperationType2["INTERSECT"] = "intersect"; BooleanCadOperationType2["SECTION"] = "section"; BooleanCadOperationType2["SUBTRACT"] = "subtract"; BooleanCadOperationType2["UNION"] = "union"; return BooleanCadOperationType2; })(BooleanCadOperationType || {}); export const BOOLEAN_CAD_OPERATION_TYPES = [ "intersect" /* INTERSECT */, "subtract" /* SUBTRACT */, "union" /* UNION */, "section" /* SECTION */ ]; class CADBooleanSopParamsConfig extends NodeParamsConfig { constructor() { super(...arguments); /** @param operation */ this.operation = ParamConfig.INTEGER(BOOLEAN_CAD_OPERATION_TYPES.indexOf("intersect" /* INTERSECT */), { menu: { entries: BOOLEAN_CAD_OPERATION_TYPES.map((name, value) => ({ name, value })) } }); /** @param mode */ this.mode = ParamConfig.INTEGER(BOOLEAN_MODES.indexOf("one to many" /* ONE_TO_MANY */), { menu: { entries: BOOLEAN_MODES.map((name, value) => ({ name, value })) } }); } } const ParamsConfig = new CADBooleanSopParamsConfig(); export class CADBooleanSopNode extends CADSopNode { constructor() { super(...arguments); this.paramsConfig = ParamsConfig; } static type() { return SopType.CAD_BOOLEAN; } initializeNode() { this.io.inputs.setCount(1, 2); } setOperation(operation) { this.p.operation.set(BOOLEAN_CAD_OPERATION_TYPES.indexOf(operation)); } cook(inputCoreGroups) { const oc = CadLoaderSync.oc(); const operation = BOOLEAN_CAD_OPERATION_TYPES[this.pv.operation]; const mode = BOOLEAN_MODES[this.pv.mode]; switch (mode) { case "process all in sequence" /* ALL_IN_SEQUENCE */: { return this._createBooleansAllInSequence(oc, operation, inputCoreGroups); } case "one to one" /* ONE_TO_ONE */: { return this._createBooleansOneToOne(oc, operation, inputCoreGroups); } case "one to many" /* ONE_TO_MANY */: { return this._createBooleansOneToMany(oc, operation, inputCoreGroups); } } TypeAssert.unreachable(mode); } _createBooleansAllInSequence(oc, operation, inputCoreGroups) { const newObjects = []; const inputCoreGroup0 = inputCoreGroups[0]; const inputCoreGroup1 = inputCoreGroups[1]; let shapeObjects0 = inputCoreGroup0.cadObjectsWithShape(); if (shapeObjects0) { if (inputCoreGroup1) { const shapeObjects1 = inputCoreGroup1.cadObjectsWithShape(); if (shapeObjects1) { shapeObjects0 = shapeObjects0.concat(shapeObjects1); } } _createBooleansAllInSequence(oc, operation, shapeObjects0, newObjects); } this.setCADObjects(newObjects); } _createBooleansOneToOne(oc, operation, inputCoreGroups) { const newObjects = []; const inputCoreGroup0 = inputCoreGroups[0]; const inputCoreGroup1 = inputCoreGroups[1]; if (!inputCoreGroup1) { this.states.error.set("input 1 required for this mode"); return; } const shapeObjects0 = inputCoreGroup0.cadObjectsWithShape(); const shapeObjects1 = inputCoreGroup1.cadObjectsWithShape(); if (shapeObjects0 && shapeObjects1) { _createBooleansOneToOne(oc, operation, shapeObjects0, shapeObjects1, newObjects); } this.setCADObjects(newObjects); } _createBooleansOneToMany(oc, operation, inputCoreGroups) { const newObjects = []; const inputCoreGroup0 = inputCoreGroups[0]; const inputCoreGroup1 = inputCoreGroups[1]; if (!inputCoreGroup1) { this.states.error.set("input 1 required for this mode"); return; } const shapeObjects0 = inputCoreGroup0.cadObjectsWithShape(); const shapeObjects1 = inputCoreGroup1.cadObjectsWithShape(); if (shapeObjects0 && shapeObjects1) { _createBooleansOneToMany(oc, operation, shapeObjects0, shapeObjects1, newObjects); } this.setCADObjects(newObjects); } // override async cook(inputCoreGroups: CadCoreGroup[]) { // const oc = await CadLoader.core(); // const coreGroup0 = inputCoreGroups[0]; // const coreGroup1 = inputCoreGroups[1]; // const object0 = coreGroup0.objects()[0]; // const object1 = coreGroup1.objects()[0]; // const operation = BOOLEAN_CAD_OPERATION_TYPES[this.pv.operation]; // const apiClass = { // [BooleanCadOperationType.INTERSECT]: oc.BRepAlgoAPI_Common_3, // [BooleanCadOperationType.SUBTRACT]: oc.BRepAlgoAPI_Cut_3, // [BooleanCadOperationType.UNION]: oc.BRepAlgoAPI_Fuse_3, // [BooleanCadOperationType.SECTION]: oc.BRepAlgoAPI_Section_3, // }[operation]; // if (object0 && object1 && CoreCadType.isShape(object0) && CoreCadType.isShape(object1)) { // const cut = new apiClass(object0.object(), object1.object(), new oc.Message_ProgressRange_1()); // cut.Build(new oc.Message_ProgressRange_1()); // const shape = cut.Shape(); // this.setShell(shape); // } else { // this.setCadObjects([object0]); // } // } } function _createBooleansAllInSequence(oc, operation, shapeObjects, newObjects) { let previousShape; for (const shapeObject of shapeObjects) { if (previousShape) { const newShape = _booleanOperation(oc, operation, previousShape, shapeObject.cadGeometry()); previousShape = newShape; } else { previousShape = shapeObject.cadGeometry(); } } if (previousShape) { const type = cadGeometryTypeFromShape(oc, previousShape); if (type) { newObjects.push(new CadObject(previousShape, type)); } else { console.log("no type", previousShape); } } } function _createBooleansOneToOne(oc, operation, shapeObjects0, shapeObjects1, newObjects) { const minVerticesCount = Math.min(shapeObjects0.length, shapeObjects1.length); for (let i = 0; i < minVerticesCount; i++) { const shape0 = shapeObjects0[i].cadGeometry(); const shape1 = shapeObjects1[i].cadGeometry(); const newShape = _booleanOperation(oc, operation, shape0, shape1); const type = cadGeometryTypeFromShape(oc, newShape); if (type) { newObjects.push(new CadObject(newShape, type)); } else { console.log("no type", newShape); } } } function _createBooleansOneToMany(oc, operation, shapeObjects0, shapeObjects1, newObjects) { for (const shapeObject0 of shapeObjects0) { let previousBooleanShapeResult = shapeObject0.cadGeometry(); for (const shapeObject1 of shapeObjects1) { previousBooleanShapeResult = _booleanOperation( oc, operation, previousBooleanShapeResult, shapeObject1.cadGeometry() ); } if (previousBooleanShapeResult) { const type = cadGeometryTypeFromShape(oc, previousBooleanShapeResult); if (type) { newObjects.push(new CadObject(previousBooleanShapeResult, type)); } else { console.log("no type", previousBooleanShapeResult); } } } } function _booleanOperation(oc, operation, shape0, shape1) { switch (operation) { case "intersect" /* INTERSECT */: { return _booleanOperationIntersect(oc, shape0, shape1); } case "subtract" /* SUBTRACT */: { return _booleanOperationSubtract(oc, shape0, shape1); } case "union" /* UNION */: { return _booleanOperationUnion(oc, shape0, shape1); } case "section" /* SECTION */: { return _booleanOperationSection(oc, shape0, shape1); } } TypeAssert.unreachable(operation); } function _booleanOperationIntersect(oc, shape0, shape1) { const operation = new oc.BRepAlgoAPI_Common_3(shape0, shape1, CadLoaderSync.Message_ProgressRange); operation.Build(CadLoaderSync.Message_ProgressRange); const shape = operation.Shape(); operation.delete(); return shape; } function _booleanOperationSubtract(oc, shape0, shape1) { const operation = new oc.BRepAlgoAPI_Cut_3(shape0, shape1, CadLoaderSync.Message_ProgressRange); operation.Build(CadLoaderSync.Message_ProgressRange); const shape = operation.Shape(); operation.delete(); return shape; } function _booleanOperationUnion(oc, shape0, shape1) { const operation = new oc.BRepAlgoAPI_Fuse_3(shape0, shape1, CadLoaderSync.Message_ProgressRange); operation.Build(CadLoaderSync.Message_ProgressRange); const shape = operation.Shape(); operation.delete(); return shape; } function _booleanOperationSection(oc, shape0, shape1) { const operation = new oc.BRepAlgoAPI_Section_3(shape0, shape1, true); const shape = operation.Shape(); operation.delete(); return shape; }