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