@bitbybit-dev/occt
Version:
Bit By Bit Developers CAD algorithms using OpenCascade Technology kernel. Run in Node and in Browser.
838 lines (837 loc) • 39.6 kB
JavaScript
import * as Inputs from "../../api/inputs/inputs";
export class EdgesService {
constructor(occ, occRefReturns, shapeGettersService, entitiesService, iteratorService, converterService, enumService, geomService, transformsService, vecHelper) {
this.occ = occ;
this.occRefReturns = occRefReturns;
this.shapeGettersService = shapeGettersService;
this.entitiesService = entitiesService;
this.iteratorService = iteratorService;
this.converterService = converterService;
this.enumService = enumService;
this.geomService = geomService;
this.transformsService = transformsService;
this.vecHelper = vecHelper;
}
getCornerPointsOfEdgesForShape(inputs) {
const edges = this.shapeGettersService.getEdges(inputs);
let points = [];
edges.forEach((edge) => {
const param1 = { current: 0 };
const param2 = { current: 0 };
const crvHandle = this.occRefReturns.BRep_Tool_Curve_2(edge, param1, param2);
try {
const crv = crvHandle.get();
if (crv) {
const pt1 = crv.Value(param1.current);
const pt2 = crv.Value(param2.current);
const pt1g = [pt1.X(), pt1.Y(), pt1.Z()];
const pt2g = [pt2.X(), pt2.Y(), pt2.Z()];
pt1.delete();
pt2.delete();
points.push(pt1g);
points.push(pt2g);
}
}
catch (ex) {
console.log(ex);
}
});
if (points.length > 0) {
points = this.vecHelper.removeAllDuplicateVectors(points);
}
return points;
}
getCircularEdgesAlongWire(inputs) {
return this.getEdgesAlongWire(inputs).filter(edge => this.isEdgeCircular({ shape: edge }));
}
getLinearEdgesAlongWire(inputs) {
return this.getEdgesAlongWire(inputs).filter(edge => this.isEdgeLinear({ shape: edge }));
}
getEdgesAlongWire(inputs) {
if (inputs.shape && this.enumService.getShapeTypeEnum(inputs.shape) === Inputs.OCCT.shapeTypeEnum.edge) {
return [inputs.shape];
}
if (!inputs.shape || inputs.shape.IsNull()) {
throw (new Error("Shape is not provided or is of incorrect type"));
}
const edges = [];
const wireWithFixedEdges = this.fixEdgeOrientationsAlongWire(inputs);
this.iteratorService.forEachEdgeAlongWire(wireWithFixedEdges, (i, edge) => {
edges.push(edge);
});
return edges;
}
fixEdgeOrientationsAlongWire(inputs) {
const edges = [];
this.iteratorService.forEachEdgeAlongWire(inputs.shape, (i, edge) => {
edges.push(edge);
});
// rebuilding wire from edges along wire fixes edge directions
return this.converterService.combineEdgesAndWiresIntoAWire({ shapes: edges });
}
arcThroughThreePoints(inputs) {
const gpPnt1 = this.entitiesService.gpPnt(inputs.start);
const gpPnt2 = this.entitiesService.gpPnt(inputs.middle);
const gpPnt3 = this.entitiesService.gpPnt(inputs.end);
const segment = new this.occ.GC_MakeArcOfCircle_4(gpPnt1, gpPnt2, gpPnt3);
const hcurve = new this.occ.Handle_Geom_Curve_2(segment.Value().get());
const makeEdge = new this.occ.BRepBuilderAPI_MakeEdge_24(hcurve);
const shape = makeEdge.Edge();
gpPnt1.delete();
gpPnt2.delete();
gpPnt3.delete();
segment.delete();
hcurve.delete();
makeEdge.delete();
return shape;
}
arcThroughTwoPointsAndTangent(inputs) {
const gpPnt1 = this.entitiesService.gpPnt(inputs.start);
const gpVec = this.entitiesService.gpVec(inputs.tangentVec);
const gpPnt2 = this.entitiesService.gpPnt(inputs.end);
const segment = new this.occ.GC_MakeArcOfCircle_5(gpPnt1, gpVec, gpPnt2);
const hcurve = new this.occ.Handle_Geom_Curve_2(segment.Value().get());
const makeEdge = new this.occ.BRepBuilderAPI_MakeEdge_24(hcurve);
const shape = makeEdge.Edge();
gpPnt1.delete();
gpVec.delete();
gpPnt2.delete();
segment.delete();
hcurve.delete();
makeEdge.delete();
return shape;
}
arcFromCircleAndTwoAngles(inputs) {
const circle = this.getGpCircleFromEdge({ shape: inputs.circle });
const radAlpha1 = this.vecHelper.degToRad(inputs.alphaAngle1);
const radAlpha2 = this.vecHelper.degToRad(inputs.alphaAngle2);
const arc = new this.occ.GC_MakeArcOfCircle_1(circle, radAlpha1, radAlpha2, inputs.sense);
const hcurve = new this.occ.Handle_Geom_Curve_2(arc.Value().get());
const makeEdge = new this.occ.BRepBuilderAPI_MakeEdge_24(hcurve);
const shape = makeEdge.Edge();
circle.delete();
arc.delete();
hcurve.delete();
makeEdge.delete();
return shape;
}
arcFromCirclePointAndAngle(inputs) {
const circle = this.getGpCircleFromEdge({ shape: inputs.circle });
const radAlpha = this.vecHelper.degToRad(inputs.alphaAngle);
const point = this.entitiesService.gpPnt(inputs.point);
const arc = new this.occ.GC_MakeArcOfCircle_2(circle, point, radAlpha, inputs.sense);
const hcurve = new this.occ.Handle_Geom_Curve_2(arc.Value().get());
const makeEdge = new this.occ.BRepBuilderAPI_MakeEdge_24(hcurve);
const shape = makeEdge.Edge();
circle.delete();
arc.delete();
point.delete();
hcurve.delete();
makeEdge.delete();
return shape;
}
lineEdge(inputs) {
const gpPnt1 = this.entitiesService.gpPnt(inputs.start);
const gpPnt2 = this.entitiesService.gpPnt(inputs.end);
const segment = new this.occ.GC_MakeSegment_1(gpPnt1, gpPnt2);
const segVal = segment.Value();
const seg = segVal.get();
const hcurve = new this.occ.Handle_Geom_Curve_2(seg);
const edgeMaker = new this.occ.BRepBuilderAPI_MakeEdge_24(hcurve);
const edge = edgeMaker.Edge();
edgeMaker.delete();
hcurve.delete();
gpPnt1.delete();
gpPnt2.delete();
segVal.delete();
seg.delete();
return edge;
}
getEdgeLength(inputs) {
const makeWire = new this.occ.BRepBuilderAPI_MakeWire_2(inputs.shape);
const wire = makeWire.Wire();
const curve = new this.occ.BRepAdaptor_CompCurve_2(wire, false);
const length = this.geomService.curveLength({ shape: curve });
curve.delete();
wire.delete();
makeWire.delete();
return length;
}
getEdgeLengthsOfShape(inputs) {
const edgesOnShape = this.shapeGettersService.getEdges({ shape: inputs.shape });
return edgesOnShape.map(edge => {
return this.getEdgeLength({ shape: edge });
});
}
getEdgesLengths(inputs) {
if (inputs.shapes === undefined) {
throw (Error(("Shapes are not defined")));
}
return inputs.shapes.map(edge => this.getEdgeLength({ shape: edge }));
}
getEdgesCentersOfMass(inputs) {
if (inputs.shapes === undefined) {
throw (Error(("Shapes are not defined")));
}
return inputs.shapes.map(edge => this.geomService.getLinearCenterOfMass({ shape: edge }));
}
edgesToPoints(inputs) {
const shapeType = this.enumService.getShapeTypeEnum(inputs.shape);
let edges = [];
if (shapeType === Inputs.OCCT.shapeTypeEnum.edge) {
edges = [inputs.shape];
}
else if (shapeType === Inputs.OCCT.shapeTypeEnum.wire) {
edges = this.getEdgesAlongWire({ shape: inputs.shape });
}
else {
edges = this.shapeGettersService.getEdges({ shape: inputs.shape });
}
// Reuse edgeToPoints for each edge to ensure consistent direction handling
const allEdgePoints = edges.map(edge => {
return this.edgeToPoints(Object.assign(Object.assign({}, inputs), { shape: edge }));
});
return allEdgePoints;
}
startPointOnEdge(inputs) {
const edge = inputs.shape;
const wire = this.converterService.combineEdgesAndWiresIntoAWire({ shapes: [edge] });
const curve = new this.occ.BRepAdaptor_CompCurve_2(wire, false);
const pt = this.geomService.pointOnCurveAtParam({ shape: curve, param: 0 });
curve.delete();
return pt;
}
endPointOnEdge(inputs) {
const edge = inputs.shape;
const wire = this.converterService.combineEdgesAndWiresIntoAWire({ shapes: [edge] });
const curve = new this.occ.BRepAdaptor_CompCurve_2(wire, false);
const pt = this.geomService.pointOnCurveAtParam({ shape: curve, param: 1 });
curve.delete();
return pt;
}
edgeToPoints(inputs) {
const edgePoints = [];
const aLocation = new this.occ.TopLoc_Location_1();
const adaptorCurve = new this.occ.BRepAdaptor_Curve_2(inputs.shape);
const tangDef = new this.occ.GCPnts_TangentialDeflection_2(adaptorCurve, inputs.angularDeflection, inputs.curvatureDeflection, inputs.minimumOfPoints, inputs.uTolerance, inputs.minimumLength);
const nrPoints = tangDef.NbPoints();
const tangDefValues = [];
for (let j = 0; j < nrPoints; j++) {
const tangDefVal = tangDef.Value(j + 1);
edgePoints.push([
tangDefVal.X(),
tangDefVal.Y(),
tangDefVal.Z()
]);
tangDefValues.push(tangDefVal);
}
tangDefValues.forEach(v => v.delete());
aLocation.delete();
adaptorCurve.delete();
tangDef.delete();
// Ensure tessellation matches edge direction
// The tessellation might be in reverse order relative to the edge's start->end direction
if (edgePoints.length > 1) {
const edgeStart = this.startPointOnEdge({ shape: inputs.shape });
const tessStart = edgePoints[0];
const tessEnd = edgePoints[edgePoints.length - 1];
// Check if first tessellation point is closer to edge start or end
const distStartToStart = this.vecHelper.distanceBetweenPoints(tessStart, edgeStart);
const distEndToStart = this.vecHelper.distanceBetweenPoints(tessEnd, edgeStart);
// If the last tessellation point is closer to the edge start, the array is reversed
if (distEndToStart < distStartToStart) {
edgePoints.reverse();
}
}
return edgePoints;
}
makeEdgeFromGeom2dCurveAndSurfaceBounded(inputs, umin, umax) {
const curve2d = new this.occ.Handle_Geom2d_Curve_2(inputs.curve);
const surface = new this.occ.Handle_Geom_Surface_2(inputs.surface);
const res = new this.occ.BRepBuilderAPI_MakeEdge_31(curve2d, surface, umin, umax);
const resShape = res.Shape();
const r = this.converterService.getActualTypeOfShape(resShape);
resShape.delete();
res.delete();
return r;
}
makeEdgeFromGeom2dCurveAndSurface(inputs) {
const curve2d = new this.occ.Handle_Geom2d_Curve_2(inputs.curve);
const surface = new this.occ.Handle_Geom_Surface_2(inputs.surface);
const res = new this.occ.BRepBuilderAPI_MakeEdge_30(curve2d, surface);
const resShape = res.Shape();
const r = this.converterService.getActualTypeOfShape(resShape);
resShape.delete();
res.delete();
return r;
}
constraintTanLinesFromTwoPtsToCircle(inputs) {
const cirDir = this.getCircularEdgePlaneDirection({ shape: inputs.circle });
const cirPos = this.getCircularEdgeCenterPoint({ shape: inputs.circle });
const alignOpt = new Inputs.OCCT.AlignDto();
alignOpt.fromDirection = cirDir;
alignOpt.toDirection = [0, 0, 1];
alignOpt.fromOrigin = cirPos;
alignOpt.toOrigin = [0, 0, 0];
alignOpt.shape = inputs.circle;
const circleAligned = this.transformsService.align(alignOpt);
const ptVertex1 = this.entitiesService.makeVertex(inputs.point1);
alignOpt.shape = ptVertex1;
const ptVertex1Aligned = this.transformsService.align(alignOpt);
ptVertex1.delete();
const pt1Aligned = this.converterService.vertexToPoint({ shape: ptVertex1Aligned });
ptVertex1Aligned.delete();
const pt2d1 = this.entitiesService.gpPnt2d([pt1Aligned[0], pt1Aligned[1]]);
const ptVertex2 = this.entitiesService.makeVertex(inputs.point2);
alignOpt.shape = ptVertex2;
const ptVertex2Aligned = this.transformsService.align(alignOpt);
ptVertex2.delete();
const pt2Aligned = this.converterService.vertexToPoint({ shape: ptVertex2Aligned });
ptVertex2Aligned.delete();
const pt2d2 = this.entitiesService.gpPnt2d([pt2Aligned[0], pt2Aligned[1]]);
const circle = this.getGpCircle2dFromEdge({ shape: circleAligned });
circleAligned.delete();
const qCircle = new this.occ.GccEnt_QualifiedCirc(circle, this.enumService.getGccEntPositionFromEnum(Inputs.OCCT.gccEntPositionEnum.unqualified));
circle.delete();
const lin1 = new this.occ.GccAna_Lin2d2Tan_2(qCircle, pt2d1, inputs.tolerance);
const lin2 = new this.occ.GccAna_Lin2d2Tan_2(qCircle, pt2d2, inputs.tolerance);
qCircle.delete();
const solutions1 = [];
for (let i = 1; i <= lin1.NbSolutions(); i++) {
const sol = lin1.ThisSolution(i);
const location = sol.Location();
const edgeLine = this.lineEdge({ start: [location.X(), location.Y(), 0], end: pt1Aligned });
alignOpt.fromDirection = [0, 0, 1];
alignOpt.toDirection = cirDir;
alignOpt.fromOrigin = [0, 0, 0];
alignOpt.toOrigin = cirPos;
alignOpt.shape = edgeLine;
const aligned = this.transformsService.align(alignOpt);
solutions1.push(aligned);
sol.delete();
location.delete();
edgeLine.delete();
}
lin1.delete();
const solutions2 = [];
for (let i = 1; i <= lin2.NbSolutions(); i++) {
const sol = lin2.ThisSolution(i);
const location = sol.Location();
const edgeLine = this.lineEdge({ start: [location.X(), location.Y(), 0], end: pt2Aligned });
alignOpt.fromDirection = [0, 0, 1];
alignOpt.toDirection = cirDir;
alignOpt.fromOrigin = [0, 0, 0];
alignOpt.toOrigin = cirPos;
alignOpt.shape = edgeLine;
const aligned = this.transformsService.align(alignOpt);
solutions2.push(aligned);
sol.delete();
location.delete();
edgeLine.delete();
}
lin2.delete();
let resultingSol = [];
if (inputs.positionResult === Inputs.OCCT.positionResultEnum.all) {
resultingSol = [...solutions1, ...solutions2];
}
else if (inputs.positionResult === Inputs.OCCT.positionResultEnum.keepSide1) {
resultingSol = [solutions1[1], solutions2[0]];
}
else if (inputs.positionResult === Inputs.OCCT.positionResultEnum.keepSide2) {
resultingSol = [solutions1[0], solutions2[1]];
}
else {
resultingSol = [...solutions1, ...solutions2];
}
if (resultingSol.length === 2 && inputs.circleRemainder !== Inputs.OCCT.circleInclusionEnum.none) {
let startPoint;
let endPoint;
if (inputs.positionResult === Inputs.OCCT.positionResultEnum.keepSide2) {
if (inputs.circleRemainder === Inputs.OCCT.circleInclusionEnum.keepSide1) {
startPoint = this.startPointOnEdge({ shape: resultingSol[1] });
endPoint = this.startPointOnEdge({ shape: resultingSol[0] });
}
else if (inputs.circleRemainder === Inputs.OCCT.circleInclusionEnum.keepSide2) {
startPoint = this.startPointOnEdge({ shape: resultingSol[0] });
endPoint = this.startPointOnEdge({ shape: resultingSol[1] });
}
}
else if (inputs.positionResult === Inputs.OCCT.positionResultEnum.keepSide1) {
if (inputs.circleRemainder === Inputs.OCCT.circleInclusionEnum.keepSide1) {
startPoint = this.startPointOnEdge({ shape: resultingSol[0] });
endPoint = this.startPointOnEdge({ shape: resultingSol[1] });
}
else if (inputs.circleRemainder === Inputs.OCCT.circleInclusionEnum.keepSide2) {
startPoint = this.startPointOnEdge({ shape: resultingSol[1] });
endPoint = this.startPointOnEdge({ shape: resultingSol[0] });
}
}
const edge = this.arcFromCircleAndTwoPoints({ circle: inputs.circle, start: startPoint, end: endPoint, sense: true });
resultingSol.splice(1, 0, edge);
}
return resultingSol;
}
constraintTanLinesFromPtToCircle(inputs) {
const cirDir = this.getCircularEdgePlaneDirection({ shape: inputs.circle });
const cirPos = this.getCircularEdgeCenterPoint({ shape: inputs.circle });
const alignOpt = new Inputs.OCCT.AlignDto();
alignOpt.fromDirection = cirDir;
alignOpt.toDirection = [0, 0, 1];
alignOpt.fromOrigin = cirPos;
alignOpt.toOrigin = [0, 0, 0];
alignOpt.shape = inputs.circle;
const circleAligned = this.transformsService.align(alignOpt);
const ptVertex = this.entitiesService.makeVertex(inputs.point);
alignOpt.shape = ptVertex;
const ptVertexAligned = this.transformsService.align(alignOpt);
ptVertex.delete();
const ptAligned = this.converterService.vertexToPoint({ shape: ptVertexAligned });
ptVertexAligned.delete();
const pt2d = this.entitiesService.gpPnt2d([ptAligned[0], ptAligned[1]]);
const circle = this.getGpCircle2dFromEdge({ shape: circleAligned });
circleAligned.delete();
const qCircle = new this.occ.GccEnt_QualifiedCirc(circle, this.enumService.getGccEntPositionFromEnum(Inputs.OCCT.gccEntPositionEnum.unqualified));
circle.delete();
const lin = new this.occ.GccAna_Lin2d2Tan_2(qCircle, pt2d, inputs.tolerance);
qCircle.delete();
const solutions = [];
for (let i = 1; i <= lin.NbSolutions(); i++) {
const sol = lin.ThisSolution(i);
const location = sol.Location();
const edgeLine = this.lineEdge({ start: [location.X(), location.Y(), 0], end: ptAligned });
alignOpt.fromDirection = [0, 0, 1];
alignOpt.toDirection = cirDir;
alignOpt.fromOrigin = [0, 0, 0];
alignOpt.toOrigin = cirPos;
alignOpt.shape = edgeLine;
const aligned = this.transformsService.align(alignOpt);
solutions.push(aligned);
sol.delete();
location.delete();
edgeLine.delete();
}
lin.delete();
let resultingSol = [];
if (inputs.positionResult === Inputs.OCCT.positionResultEnum.all) {
resultingSol = [...solutions];
}
else if (inputs.positionResult === Inputs.OCCT.positionResultEnum.keepSide1) {
resultingSol = [solutions[0]];
}
else if (inputs.positionResult === Inputs.OCCT.positionResultEnum.keepSide2) {
resultingSol = [solutions[1]];
}
else {
resultingSol = [...solutions];
}
if (resultingSol.length === 2 && inputs.circleRemainder !== Inputs.OCCT.circleInclusionEnum.none) {
let startPoint;
let endPoint;
if (inputs.circleRemainder === Inputs.OCCT.circleInclusionEnum.keepSide1) {
startPoint = this.startPointOnEdge({ shape: resultingSol[1] });
endPoint = this.startPointOnEdge({ shape: resultingSol[0] });
}
else if (inputs.circleRemainder === Inputs.OCCT.circleInclusionEnum.keepSide2) {
startPoint = this.startPointOnEdge({ shape: resultingSol[0] });
endPoint = this.startPointOnEdge({ shape: resultingSol[1] });
}
const edge = this.arcFromCircleAndTwoPoints({ circle: inputs.circle, start: startPoint, end: endPoint, sense: true });
resultingSol.splice(1, 0, edge);
}
return resultingSol;
}
constraintTanLinesOnTwoCircles(inputs) {
const cirDir = this.getCircularEdgePlaneDirection({ shape: inputs.circle1 });
const cirPos = this.getCircularEdgeCenterPoint({ shape: inputs.circle1 });
const alignOpt = new Inputs.OCCT.AlignDto();
alignOpt.fromDirection = cirDir;
alignOpt.toDirection = [0, 0, 1];
alignOpt.fromOrigin = cirPos;
alignOpt.toOrigin = [0, 0, 0];
alignOpt.shape = inputs.circle1;
const circle1Aligned = this.transformsService.align(alignOpt);
alignOpt.shape = inputs.circle2;
const circle2Aligned = this.transformsService.align(alignOpt);
const circle1 = this.getGpCircle2dFromEdge({ shape: circle1Aligned });
const circle2 = this.getGpCircle2dFromEdge({ shape: circle2Aligned });
circle1Aligned.delete();
circle2Aligned.delete();
const qCircle1 = new this.occ.GccEnt_QualifiedCirc(circle1, this.enumService.getGccEntPositionFromEnum(Inputs.OCCT.gccEntPositionEnum.unqualified));
const qCircle2 = new this.occ.GccEnt_QualifiedCirc(circle2, this.enumService.getGccEntPositionFromEnum(Inputs.OCCT.gccEntPositionEnum.unqualified));
circle1.delete();
circle2.delete();
const lin1 = new this.occ.GccAna_Lin2d2Tan_3(qCircle1, qCircle2, inputs.tolerance);
const lin2 = new this.occ.GccAna_Lin2d2Tan_3(qCircle2, qCircle1, inputs.tolerance);
qCircle1.delete();
qCircle2.delete();
const lin1Sols = [];
for (let i = 1; i <= lin1.NbSolutions(); i++) {
const sol = lin1.ThisSolution(i);
lin1Sols.push(sol);
}
lin1.delete();
const lin2Sols = [];
for (let i = 1; i <= lin2.NbSolutions(); i++) {
const sol = lin2.ThisSolution(i);
lin2Sols.push(sol);
}
lin2.delete();
let adjustLin2Sol;
if (lin2Sols.length === 4) {
adjustLin2Sol = [lin2Sols[2], lin2Sols[1], lin2Sols[0], lin2Sols[3]];
}
else if (lin2Sols.length === 2) {
adjustLin2Sol = [lin2Sols[1], lin2Sols[0]];
}
const solutions = [];
for (let i = 0; i < lin1Sols.length; i++) {
const sol1 = lin1Sols[i];
const sol2 = adjustLin2Sol[i];
const locationStart = sol1.Location();
const startPoint = [locationStart.X(), locationStart.Y(), 0];
const locationEnd = sol2.Location();
const endPoint = [locationEnd.X(), locationEnd.Y(), 0];
const edgeLine = this.lineEdge({ start: startPoint, end: endPoint });
alignOpt.fromDirection = [0, 0, 1];
alignOpt.toDirection = cirDir;
alignOpt.fromOrigin = [0, 0, 0];
alignOpt.toOrigin = cirPos;
alignOpt.shape = edgeLine;
const aligned = this.transformsService.align(alignOpt);
solutions.push(aligned);
edgeLine.delete();
sol1.delete();
sol2.delete();
locationStart.delete();
locationEnd.delete();
}
let resultingSol = [];
if (inputs.positionResult === Inputs.OCCT.positionResultEnum.all) {
resultingSol = [...solutions];
}
else if (inputs.positionResult === Inputs.OCCT.positionResultEnum.keepSide1 && solutions.length === 4) {
resultingSol = [solutions[1], solutions[3]];
}
else if (inputs.positionResult === Inputs.OCCT.positionResultEnum.keepSide2 && solutions.length === 4) {
resultingSol = [solutions[0], solutions[2]];
}
else if (inputs.positionResult === Inputs.OCCT.positionResultEnum.keepSide1 && solutions.length === 2) {
resultingSol = [];
}
else if (inputs.positionResult === Inputs.OCCT.positionResultEnum.keepSide2 && solutions.length === 2) {
resultingSol = [solutions[0], solutions[1]];
}
else {
resultingSol = [...solutions];
}
if (resultingSol.length === 2 && inputs.circleRemainders !== Inputs.OCCT.twoCircleInclusionEnum.none) {
let startPoint1;
let startPoint2;
let endPoint1;
let endPoint2;
if (inputs.circleRemainders === Inputs.OCCT.twoCircleInclusionEnum.outside) {
if (inputs.positionResult === Inputs.OCCT.positionResultEnum.keepSide2 || inputs.positionResult === Inputs.OCCT.positionResultEnum.all) {
startPoint1 = this.startPointOnEdge({ shape: resultingSol[1] });
startPoint2 = this.startPointOnEdge({ shape: resultingSol[0] });
}
else if (inputs.positionResult === Inputs.OCCT.positionResultEnum.keepSide1) {
startPoint1 = this.startPointOnEdge({ shape: resultingSol[0] });
startPoint2 = this.startPointOnEdge({ shape: resultingSol[1] });
}
endPoint1 = this.endPointOnEdge({ shape: resultingSol[0] });
endPoint2 = this.endPointOnEdge({ shape: resultingSol[1] });
}
else if (inputs.circleRemainders === Inputs.OCCT.twoCircleInclusionEnum.inside) {
if (inputs.positionResult === Inputs.OCCT.positionResultEnum.keepSide2 || inputs.positionResult === Inputs.OCCT.positionResultEnum.all) {
startPoint1 = this.startPointOnEdge({ shape: resultingSol[0] });
startPoint2 = this.startPointOnEdge({ shape: resultingSol[1] });
}
else if (inputs.positionResult === Inputs.OCCT.positionResultEnum.keepSide1) {
startPoint1 = this.startPointOnEdge({ shape: resultingSol[1] });
startPoint2 = this.startPointOnEdge({ shape: resultingSol[0] });
}
endPoint1 = this.endPointOnEdge({ shape: resultingSol[1] });
endPoint2 = this.endPointOnEdge({ shape: resultingSol[0] });
}
else if (inputs.circleRemainders === Inputs.OCCT.twoCircleInclusionEnum.insideOutside) {
if (inputs.positionResult === Inputs.OCCT.positionResultEnum.keepSide2 || inputs.positionResult === Inputs.OCCT.positionResultEnum.all) {
startPoint1 = this.startPointOnEdge({ shape: resultingSol[0] });
startPoint2 = this.startPointOnEdge({ shape: resultingSol[1] });
}
else if (inputs.positionResult === Inputs.OCCT.positionResultEnum.keepSide1) {
startPoint1 = this.startPointOnEdge({ shape: resultingSol[1] });
startPoint2 = this.startPointOnEdge({ shape: resultingSol[0] });
}
endPoint1 = this.endPointOnEdge({ shape: resultingSol[0] });
endPoint2 = this.endPointOnEdge({ shape: resultingSol[1] });
}
else if (inputs.circleRemainders === Inputs.OCCT.twoCircleInclusionEnum.outsideInside) {
if (inputs.positionResult === Inputs.OCCT.positionResultEnum.keepSide2 || inputs.positionResult === Inputs.OCCT.positionResultEnum.all) {
startPoint1 = this.startPointOnEdge({ shape: resultingSol[1] });
startPoint2 = this.startPointOnEdge({ shape: resultingSol[0] });
}
else if (inputs.positionResult === Inputs.OCCT.positionResultEnum.keepSide1) {
startPoint1 = this.startPointOnEdge({ shape: resultingSol[0] });
startPoint2 = this.startPointOnEdge({ shape: resultingSol[1] });
}
endPoint1 = this.endPointOnEdge({ shape: resultingSol[1] });
endPoint2 = this.endPointOnEdge({ shape: resultingSol[0] });
}
const edge1 = this.arcFromCircleAndTwoPoints({ circle: inputs.circle1, start: startPoint1, end: startPoint2, sense: true });
const edge2 = this.arcFromCircleAndTwoPoints({ circle: inputs.circle2, start: endPoint1, end: endPoint2, sense: true });
resultingSol.unshift(edge1);
resultingSol.push(edge2);
}
return resultingSol;
}
constraintTanCirclesOnCircleAndPnt(inputs) {
const cirDir = this.getCircularEdgePlaneDirection({ shape: inputs.circle });
const cirPos = this.getCircularEdgeCenterPoint({ shape: inputs.circle });
const { alignOpt, circle1Aligned: circleAligned } = this.alignCircle(cirDir, cirPos, inputs.circle);
const ptVertex = this.entitiesService.makeVertex(inputs.point);
alignOpt.shape = ptVertex;
const ptVertexAligned = this.transformsService.align(alignOpt);
ptVertex.delete();
const ptAligned = this.converterService.vertexToPoint({ shape: ptVertexAligned });
ptVertexAligned.delete();
const pt2d = this.entitiesService.gpPnt2d([ptAligned[0], ptAligned[1]]);
const circle = this.getGpCircle2dFromEdge({ shape: circleAligned });
circleAligned.delete();
const qCircle = new this.occ.GccEnt_QualifiedCirc(circle, this.enumService.getGccEntPositionFromEnum(Inputs.OCCT.gccEntPositionEnum.unqualified));
circle.delete();
const lin1 = new this.occ.GccAna_Circ2d2TanRad_3(qCircle, pt2d, inputs.radius, inputs.tolerance);
qCircle.delete();
const lin1Sols = [];
for (let i = 1; i <= lin1.NbSolutions(); i++) {
const sol = lin1.ThisSolution(i);
lin1Sols.push(sol);
}
lin1.delete();
const solutions = [];
for (let i = 0; i < lin1Sols.length; i++) {
const sol = lin1Sols[i];
const res = this.reconstructCircleAndAlignBack(lin1Sols, sol, alignOpt, cirDir, cirPos);
solutions.push(res);
}
return solutions;
}
alignCircle(cirDir, cirPos, circle) {
const alignOpt = new Inputs.OCCT.AlignDto();
alignOpt.fromDirection = cirDir;
alignOpt.toDirection = [0, 0, 1];
alignOpt.fromOrigin = cirPos;
alignOpt.toOrigin = [0, 0, 0];
alignOpt.shape = circle;
const circle1Aligned = this.transformsService.align(alignOpt);
return { alignOpt, circle1Aligned };
}
constraintTanCirclesOnTwoCircles(inputs) {
const cirDir = this.getCircularEdgePlaneDirection({ shape: inputs.circle1 });
const cirPos = this.getCircularEdgeCenterPoint({ shape: inputs.circle1 });
const { alignOpt, circle1Aligned } = this.alignCircle(cirDir, cirPos, inputs.circle1);
alignOpt.shape = inputs.circle2;
const circle2Aligned = this.transformsService.align(alignOpt);
const circle1 = this.getGpCircle2dFromEdge({ shape: circle1Aligned });
const circle2 = this.getGpCircle2dFromEdge({ shape: circle2Aligned });
circle1Aligned.delete();
circle2Aligned.delete();
const qCircle1 = new this.occ.GccEnt_QualifiedCirc(circle1, this.enumService.getGccEntPositionFromEnum(Inputs.OCCT.gccEntPositionEnum.unqualified));
const qCircle2 = new this.occ.GccEnt_QualifiedCirc(circle2, this.enumService.getGccEntPositionFromEnum(Inputs.OCCT.gccEntPositionEnum.unqualified));
circle1.delete();
circle2.delete();
const lin1 = new this.occ.GccAna_Circ2d2TanRad_1(qCircle1, qCircle2, inputs.radius, inputs.tolerance);
qCircle1.delete();
qCircle2.delete();
const lin1Sols = [];
for (let i = 1; i <= lin1.NbSolutions(); i++) {
const sol = lin1.ThisSolution(i);
lin1Sols.push(sol);
}
lin1.delete();
const solutions = [];
for (let i = 0; i < lin1Sols.length; i++) {
const sol = lin1Sols[i];
const res = this.reconstructCircleAndAlignBack(lin1Sols, sol, alignOpt, cirDir, cirPos);
solutions.push(res);
}
return solutions;
}
divideEdgeByParamsToPoints(inputs) {
const edge = inputs.shape;
const wire = this.converterService.combineEdgesAndWiresIntoAWire({ shapes: [edge] });
const curve = new this.occ.BRepAdaptor_CompCurve_2(wire, false);
const points = this.geomService.divideCurveToNrSegments(Object.assign(Object.assign({}, inputs), { shape: curve }), curve.FirstParameter(), curve.LastParameter());
curve.delete();
wire.delete();
return points;
}
divideEdgeByEqualDistanceToPoints(inputs) {
const edge = inputs.shape;
const wire = this.converterService.combineEdgesAndWiresIntoAWire({ shapes: [edge] });
const curve = new this.occ.BRepAdaptor_CompCurve_2(wire, false);
const points = this.geomService.divideCurveByEqualLengthDistance(Object.assign(Object.assign({}, inputs), { shape: curve }));
curve.delete();
wire.delete();
return points;
}
pointOnEdgeAtParam(inputs) {
const edge = inputs.shape;
const { uMin, uMax } = this.getEdgeBounds(edge);
const curve = this.converterService.getGeomCurveFromEdge(edge, uMin, uMax);
const gpPnt = this.entitiesService.gpPnt([0, 0, 0]);
const param = this.vecHelper.remap(inputs.param, 0, 1, uMin, uMax);
if (curve) {
curve.D0(param, gpPnt);
const pt = [gpPnt.X(), gpPnt.Y(), gpPnt.Z()];
gpPnt.delete();
return pt;
}
else {
return undefined;
}
}
reconstructCircleAndAlignBack(lin1Sols, sol, alignOpt, dir, pos) {
const locationStart = sol.Location();
const startPoint = [locationStart.X(), locationStart.Y(), 0];
const circle = this.entitiesService.createCircle(sol.Radius(), startPoint, [0, 0, 1], Inputs.OCCT.typeSpecificityEnum.edge);
alignOpt.fromDirection = [0, 0, 1];
alignOpt.toDirection = dir;
alignOpt.fromOrigin = [0, 0, 0];
alignOpt.toOrigin = pos;
alignOpt.shape = circle;
const aligned = this.transformsService.align(alignOpt);
circle.delete();
sol.delete();
locationStart.delete();
return aligned;
}
arcFromCircleAndTwoPoints(inputs) {
const circle = this.getGpCircleFromEdge({ shape: inputs.circle });
const gpPnt1 = this.entitiesService.gpPnt(inputs.start);
const gpPnt2 = this.entitiesService.gpPnt(inputs.end);
const arc = new this.occ.GC_MakeArcOfCircle_3(circle, gpPnt1, gpPnt2, inputs.sense);
const hcurve = new this.occ.Handle_Geom_Curve_2(arc.Value().get());
const makeEdge = new this.occ.BRepBuilderAPI_MakeEdge_24(hcurve);
const shape = makeEdge.Edge();
circle.delete();
gpPnt1.delete();
gpPnt2.delete();
arc.delete();
hcurve.delete();
makeEdge.delete();
return shape;
}
getCircularEdgePlaneDirection(inputs) {
const circle = this.getGpCircleFromEdge(inputs);
const axis = circle.Position();
const dir = axis.Direction();
const result = [dir.X(), dir.Y(), dir.Z()];
dir.delete();
axis.delete();
circle.delete();
return result;
}
getCircularEdgeCenterPoint(inputs) {
const circle = this.getGpCircleFromEdge(inputs);
const location = circle.Location();
const result = [location.X(), location.Y(), location.Z()];
location.delete();
circle.delete();
return result;
}
getCircularEdgeRadius(inputs) {
const circle = this.getGpCircleFromEdge(inputs);
const radius = circle.Radius();
circle.delete();
return radius;
}
getGpCircleFromEdge(inputs) {
const curve = new this.occ.BRepAdaptor_Curve_2(inputs.shape);
try {
const circle = curve.Circle();
curve.delete();
return circle;
}
catch (ex) {
curve.delete();
throw new Error("Edge is not a circular edge.");
}
}
getGpCircle2dFromEdge(inputs) {
const curve = new this.occ.BRepAdaptor_Curve_2(inputs.shape);
try {
const circle = curve.Circle();
const ax = circle.Position();
const location = circle.Location();
const ax2d = this.entitiesService.gpAx2d([location.X(), location.Y()], [1, 0]);
const radius = circle.Radius();
const circle2d = new this.occ.gp_Circ2d_2(ax2d, radius, true);
curve.delete();
circle.delete();
ax.delete();
location.delete();
ax2d.delete();
return circle2d;
}
catch (ex) {
curve.delete();
throw new Error("Edge is not a circular edge.");
}
}
tangentOnEdgeAtParam(inputs) {
const edge = inputs.shape;
const { uMin, uMax } = this.getEdgeBounds(edge);
const curve = this.converterService.getGeomCurveFromEdge(edge, uMin, uMax);
const param = this.vecHelper.remap(inputs.param, 0, 1, uMin, uMax);
const vec = curve.DN(param, 1);
const vector = [vec.X(), vec.Y(), vec.Z()];
vec.delete();
return vector;
}
pointOnEdgeAtLength(inputs) {
const edge = inputs.shape;
const wire = this.converterService.combineEdgesAndWiresIntoAWire({ shapes: [edge] });
const curve = new this.occ.BRepAdaptor_CompCurve_2(wire, false);
const res = this.geomService.pointOnCurveAtLength(Object.assign(Object.assign({}, inputs), { shape: curve }));
curve.delete();
wire.delete();
return res;
}
tangentOnEdgeAtLength(inputs) {
const edge = inputs.shape;
const wire = this.converterService.combineEdgesAndWiresIntoAWire({ shapes: [edge] });
const curve = new this.occ.BRepAdaptor_CompCurve_2(wire, false);
const res = this.geomService.tangentOnCurveAtLength(Object.assign(Object.assign({}, inputs), { shape: curve }));
wire.delete();
curve.delete();
return res;
}
getEdgeBounds(edge) {
const p1 = { current: 0 };
const p2 = { current: 0 };
this.occRefReturns.BRep_Tool_Range_1(edge, p1, p2);
return { uMin: p1.current, uMax: p2.current };
}
isEdgeCircular(inputs) {
const curve = new this.occ.BRepAdaptor_Curve_2(inputs.shape);
try {
curve.Circle();
curve.delete();
return true;
}
catch (ex) {
return false;
}
}
isEdgeLinear(inputs) {
const curve = new this.occ.BRepAdaptor_Curve_2(inputs.shape);
try {
curve.Line();
curve.delete();
return true;
}
catch (ex) {
return false;
}
}
}