UNPKG

@bitbybit-dev/occt

Version:

Bit By Bit Developers CAD algorithms using OpenCascade Technology kernel. Run in Node and in Browser.

154 lines (153 loc) 6.29 kB
import * as Inputs from "../../api/inputs/inputs"; export class SolidsService { constructor(occ, shapeGettersService, facesService, enumService, entitiesService, converterService, transformsService, vectorHelperService) { this.occ = occ; this.shapeGettersService = shapeGettersService; this.facesService = facesService; this.enumService = enumService; this.entitiesService = entitiesService; this.converterService = converterService; this.transformsService = transformsService; this.vectorHelperService = vectorHelperService; } fromClosedShell(inputs) { const shell = this.converterService.getActualTypeOfShape(inputs.shape); const builder = new this.occ.BRepBuilderAPI_MakeSolid_3(shell); const result = builder.Solid(); builder.delete(); shell.delete(); return result; } createBox(inputs) { let center = [...inputs.center]; if (inputs.originOnCenter === undefined) { inputs.originOnCenter = true; } if (!inputs.originOnCenter) { center = [center[0], center[1] + inputs.height / 2, center[2]]; } return this.entitiesService.bRepPrimAPIMakeBox(inputs.width, inputs.length, inputs.height, center); } createCube(inputs) { let center = [...inputs.center]; if (inputs.originOnCenter === undefined) { inputs.originOnCenter = true; } if (!inputs.originOnCenter) { center = [center[0], center[1] + inputs.size / 2, center[2]]; } return this.entitiesService.bRepPrimAPIMakeBox(inputs.size, inputs.size, inputs.size, center); } createBoxFromCorner(inputs) { const box = this.entitiesService.bRepPrimAPIMakeBox(inputs.width, inputs.length, inputs.height, inputs.corner); const cornerBox = this.transformsService.translate({ shape: box, translation: [inputs.width / 2, inputs.height / 2, inputs.length / 2] }); box.delete(); return cornerBox; } createCylinder(inputs) { const dir = inputs.direction ? inputs.direction : [0., 1., 0.]; let result; let angle; if (inputs.angle === undefined) { angle = Math.PI * 2; } else { angle = this.vectorHelperService.degToRad(inputs.angle); } const cyl = this.entitiesService.bRepPrimAPIMakeCylinder(inputs.center, dir, inputs.radius, inputs.height, angle); if (inputs.originOnCenter) { const halfHeight = -(inputs.height / 2); const normDir = this.vectorHelperService.normalize(dir); result = this.transformsService.translate({ shape: cyl, translation: [normDir[0] * halfHeight, normDir[1] * halfHeight, normDir[2] * halfHeight] }); cyl.delete(); } else { result = cyl; } return result; } createCylindersOnLines(inputs) { const cylinders = inputs.lines.map(line => { return this.entitiesService.bRepPrimAPIMakeCylinderBetweenPoints(line.start, line.end, inputs.radius); }); return cylinders; } createSphere(inputs) { return this.entitiesService.bRepPrimAPIMakeSphere(inputs.center, [0., 0., 1.], inputs.radius); } createCone(inputs) { const ax = this.entitiesService.gpAx2(inputs.center, inputs.direction); const makeCone = new this.occ.BRepPrimAPI_MakeCone_4(ax, inputs.radius1, inputs.radius2, inputs.height, inputs.angle); const coneShape = makeCone.Shape(); makeCone.delete(); ax.delete(); return coneShape; } filterSolidPoints(inputs) { const points = []; if (inputs.points.length > 0) { const classifier = new this.occ.BRepClass3d_SolidClassifier_1(); classifier.Load(inputs.shape); inputs.points.forEach(pt => { const gpPnt = this.entitiesService.gpPnt(pt); classifier.Perform(gpPnt, inputs.tolerance); const top = classifier.State(); const type = this.enumService.getTopAbsStateEnum(top); if (inputs.keepOn && type === Inputs.OCCT.topAbsStateEnum.on) { points.push(pt); } if (inputs.keepIn && type === Inputs.OCCT.topAbsStateEnum.in) { points.push(pt); } if (inputs.keepOut && type === Inputs.OCCT.topAbsStateEnum.out) { points.push(pt); } if (inputs.keepUnknown && type === Inputs.OCCT.topAbsStateEnum.unknown) { points.push(pt); } gpPnt.delete(); }); classifier.delete(); return points; } else { return []; } } getSolidVolume(inputs) { const gprops = new this.occ.GProp_GProps_1(); this.occ.BRepGProp.VolumeProperties_1(inputs.shape, gprops, true, false, false); const vol = gprops.Mass(); gprops.delete(); return vol; } getSolidSurfaceArea(inputs) { const faces = this.shapeGettersService.getFaces(inputs); const faceAreas = this.facesService.getFacesAreas({ shapes: faces }); return faceAreas.reduce((p, c) => p + c, 0); } getSolidsVolumes(inputs) { if (inputs.shapes === undefined) { throw (Error(("Shapes are not defined"))); } return inputs.shapes.map(s => this.getSolidVolume({ shape: s })); } getSolidCenterOfMass(inputs) { const gprops = new this.occ.GProp_GProps_1(); this.occ.BRepGProp.VolumeProperties_1(inputs.shape, gprops, true, false, false); const gppnt = gprops.CentreOfMass(); const pt = [gppnt.X(), gppnt.Y(), gppnt.Z()]; gprops.delete(); gppnt.delete(); return pt; } getSolidsCentersOfMass(inputs) { if (inputs.shapes === undefined) { throw (Error(("Shapes are not defined"))); } return inputs.shapes.map(s => this.getSolidCenterOfMass({ shape: s })); } getSolids(inputs) { return this.shapeGettersService.getSolids(inputs); } }