@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
245 lines (244 loc) • 9.41 kB
JavaScript
;
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;
}