UNPKG

@polygonjs/polygonjs

Version:

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

118 lines (107 loc) 3.79 kB
/** * Applies a CAD fillet operation * * */ import {CADSopNode} from './_BaseCAD'; import {NodeParamsConfig, ParamConfig} from '../utils/params/ParamsConfig'; import type {OpenCascadeInstance, TopoDS_Shape} from '../../../core/geometry/modules/cad/CadCommon'; import {step} from '../../../core/geometry/modules/cad/CadConstant'; import {CoreCadType} from '../../../core/geometry/modules/cad/CadCoreType'; import {traverseEdges} from '../../../core/geometry/modules/cad/CadTraverse'; import {CadGeometryType, cadGeometryTypeFromShape} from '../../../core/geometry/modules/cad/CadCommon'; import {TypeAssert} from '../../poly/Assert'; import {CoreGroup} from '../../../core/geometry/Group'; import {SopType} from '../../poly/registers/nodes/types/Sop'; import {CadObject} from '../../../core/geometry/modules/cad/CadObject'; import {CadLoaderSync} from '../../../core/geometry/modules/cad/CadLoaderSync'; // import {CadCoreEdge} from '../../../core/geometry/modules/cad/CadCoreEdge'; // import {CoreString} from '../../../core/String'; // import {SetUtils} from '../../../core/SetUtils'; // import {coreObjectInstanceFactory} from '../../../core/geometry/CoreObjectFactory'; import {EntityGroupType} from '../../../core/geometry/EntityGroupCollection'; import {CadEntityGroupCollection} from '../../../core/geometry/modules/cad/CadEntityGroupCollection'; enum FilletMode { ROUND = 'round', STRAIGHT = 'straight', } const FILLET_MODES: FilletMode[] = [FilletMode.STRAIGHT, FilletMode.ROUND]; class CADFilletSopParamsConfig extends NodeParamsConfig { /** @param edges group */ group = ParamConfig.STRING(''); /** @param mode */ mode = ParamConfig.INTEGER(FILLET_MODES.indexOf(FilletMode.ROUND), { menu: { entries: FILLET_MODES.map((name, value) => ({name, value})), }, }); /** @param radius */ radius = ParamConfig.FLOAT(0.1, { range: [0, 1], rangeLocked: [true, false], step, }); } const ParamsConfig = new CADFilletSopParamsConfig(); export class CADFilletSopNode extends CADSopNode<CADFilletSopParamsConfig> { override paramsConfig = ParamsConfig; static override type() { return SopType.CAD_FILLET; } protected override initializeNode() { this.io.inputs.setCount(1); } override cook(inputCoreGroups: CoreGroup[]) { const oc = CadLoaderSync.oc(); const inputCoreGroup = inputCoreGroups[0]; const mode = FILLET_MODES[this.pv.mode]; const newObjects: CadObject<CadGeometryType>[] = []; const inputObjects = inputCoreGroup.cadObjects(); if (inputObjects) { const groupName = this.pv.group; for (const object of inputObjects) { if (CoreCadType.isShape(object)) { const shape = object.cadGeometry(); const api = _getApi(oc, mode, shape); const radius = this.pv.radius; let edgesCount = 0; CadEntityGroupCollection.traverseEntitiesInGroup({ groupName, groupType: EntityGroupType.EDGE, object, shape, traverseFunction: traverseEdges, onEntityTraversed: (edge, i) => { api.Add_2(radius, edge); edgesCount++; }, }); if (edgesCount > 0) { const newShape = api.Shape(); api.delete(); const type = cadGeometryTypeFromShape(oc, newShape); if (type) { newObjects.push(new CadObject(newShape, type)); } else { console.log('no type', newShape); } } else { newObjects.push(object); } } } } this.setCADObjects(newObjects); } } function _getApi(oc: OpenCascadeInstance, mode: FilletMode, shape: TopoDS_Shape) { switch (mode) { case FilletMode.ROUND: { return new oc.BRepFilletAPI_MakeFillet(shape, oc.ChFi3d_FilletShape.ChFi3d_Rational as any); } case FilletMode.STRAIGHT: { return new oc.BRepFilletAPI_MakeChamfer(shape); } } TypeAssert.unreachable(mode); }