@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
JavaScript
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);
}
}