Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions packages/dev/occt/bitbybit-dev-occt/bitbybit-dev-occt.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2071,6 +2071,35 @@ export declare class GeomAPI {
delete(): void;
}

export declare class GeomAPI_ProjectPointOnCurve {
Init_1(P: gp_Pnt, Curve: Handle_Geom_Curve): void;
Init_2(P: gp_Pnt, Curve: Handle_Geom_Curve, Umin: Standard_Real, Usup: Standard_Real): void;
Init_3(Curve: Handle_Geom_Curve, Umin: Standard_Real, Usup: Standard_Real): void;
Perform(P: gp_Pnt): void;
NbPoints(): Graphic3d_ZLayerId;
Point(Index: Graphic3d_ZLayerId): gp_Pnt;
Parameter_1(Index: Graphic3d_ZLayerId): Standard_Real;
Parameter_2(Index: Graphic3d_ZLayerId, U: Standard_Real): void;
Distance(Index: Graphic3d_ZLayerId): Standard_Real;
NearestPoint(): gp_Pnt;
LowerDistanceParameter(): Standard_Real;
LowerDistance(): Standard_Real;
Extrema(): Extrema_ExtPC;
delete(): void;
}

export declare class GeomAPI_ProjectPointOnCurve_1 extends GeomAPI_ProjectPointOnCurve {
constructor();
}

export declare class GeomAPI_ProjectPointOnCurve_2 extends GeomAPI_ProjectPointOnCurve {
constructor(P: gp_Pnt, Curve: Handle_Geom_Curve);
}

export declare class GeomAPI_ProjectPointOnCurve_3 extends GeomAPI_ProjectPointOnCurve {
constructor(P: gp_Pnt, Curve: Handle_Geom_Curve, Umin: Standard_Real, Usup: Standard_Real);
}

export declare class GeomAPI_PointsToBSpline {
Init_1(Points: TColgp_Array1OfPnt, DegMin: Graphic3d_ZLayerId, DegMax: Graphic3d_ZLayerId, Continuity: GeomAbs_Shape, Tol3D: Standard_Real): void;
Init_2(Points: TColgp_Array1OfPnt, ParType: Approx_ParametrizationType, DegMin: Graphic3d_ZLayerId, DegMax: Graphic3d_ZLayerId, Continuity: GeomAbs_Shape, Tol3D: Standard_Real): void;
Expand Down Expand Up @@ -10595,6 +10624,10 @@ export type OpenCascadeInstance = {FS: typeof FS} & {
ShapeUpgrade_UnifySameDomain_1: typeof ShapeUpgrade_UnifySameDomain_1;
ShapeUpgrade_UnifySameDomain_2: typeof ShapeUpgrade_UnifySameDomain_2;
GeomAPI: typeof GeomAPI;
GeomAPI_ProjectPointOnCurve: typeof GeomAPI_ProjectPointOnCurve;
GeomAPI_ProjectPointOnCurve_1: typeof GeomAPI_ProjectPointOnCurve_1;
GeomAPI_ProjectPointOnCurve_2: typeof GeomAPI_ProjectPointOnCurve_2;
GeomAPI_ProjectPointOnCurve_3: typeof GeomAPI_ProjectPointOnCurve_3;
GeomAPI_PointsToBSpline: typeof GeomAPI_PointsToBSpline;
GeomAPI_PointsToBSpline_1: typeof GeomAPI_PointsToBSpline_1;
GeomAPI_PointsToBSpline_2: typeof GeomAPI_PointsToBSpline_2;
Expand Down
Binary file modified packages/dev/occt/bitbybit-dev-occt/bitbybit-dev-occt.wasm
Binary file not shown.
1 change: 1 addition & 0 deletions packages/dev/occt/bitbybit-dev-occt/bitbybit-dev-occt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@
- symbol: Geom2d_VectorWithMagnitude
- symbol: GeomAPI
- symbol: GeomAPI_PointsToBSpline
- symbol: GeomAPI_ProjectPointOnCurve
- symbol: GeomAbs_JoinType
- symbol: GeomAbs_Shape
- symbol: GeomLProp_SLProps
Expand Down
31 changes: 31 additions & 0 deletions packages/dev/occt/bitbybit-dev-occt/cdn.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import ocFullJS from "./bitbybit-dev-occt.js";

const initOpenCascade = ({
mainJS = ocFullJS,
mainWasm = "https://cdn.jsdelivr.net/gh/bitbybit-dev/bitbybit-assets@0.19.6/wasm/bitbybit-dev-occt.a9520351.wasm",
worker = undefined,
libs = [],
module = {},
} = {}) => {
return new Promise((resolve, reject) => {
new mainJS({
locateFile(path) {
if (path.endsWith('.wasm')) {
return mainWasm;
}
if (path.endsWith('.worker.js') && !!worker) {
return worker;
}
return path;
},
...module
}).then(async oc => {
for (let lib of libs) {
await oc.loadDynamicLibrary(lib, { loadAsync: true, global: true, nodelete: true, allowUndefined: false });
}
resolve(oc);
});
});
};

export default initOpenCascade;
3 changes: 2 additions & 1 deletion packages/dev/occt/bitbybit-dev-occt/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import ocFullJS from "./bitbybit-dev-occt.js";
import ocFullWasm from "./bitbybit-dev-occt.wasm";

const initOpenCascade = ({
mainJS = ocFullJS,
mainWasm = "https://cdn.jsdelivr.net/gh/bitbybit-dev/bitbybit-assets@0.19.6/wasm/bitbybit-dev-occt.a9520351.wasm",
mainWasm = ocFullWasm,
worker = undefined,
libs = [],
module = {},
Expand Down
1 change: 1 addition & 0 deletions packages/dev/occt/generate-prod-build-yaml.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ async function start() {
"GeomLib",
"GeomAPI",
"GeomAPI_PointsToBSpline",
"GeomAPI_ProjectPointOnCurve",
"Geom_BezierCurve",
"BitByBitDev",
"gp_Trsf2d",
Expand Down
50 changes: 46 additions & 4 deletions packages/dev/occt/lib/api/inputs/occ-inputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3581,9 +3581,11 @@ export namespace OCCT {
face: U;
}
export class PipeWiresCylindricalDto<T> {
constructor(shapes?: T[], radius?: number) {
constructor(shapes?: T[], radius?: number, withContact?: boolean, withCorrection?: boolean) {
if (shapes !== undefined) { this.shapes = shapes; }
if (radius !== undefined) { this.radius = radius; }
if (withContact !== undefined) { this.withContact = withContact; }
if (withCorrection !== undefined) { this.withCorrection; }
}
/**
* Wire paths to pipe
Expand All @@ -3598,11 +3600,23 @@ export namespace OCCT {
* @step 1
*/
radius = 0.1;
/**
* If withContact is true, the section is translated to be in contact with the spine.
* @default false
*/
withContact = false;
/**
* If withCorrection is true, the section is rotated to be orthogonal to the spine's tangent in the correspondent point.
* @default false
*/
withCorrection = false;
}
export class PipeWireCylindricalDto<T> {
constructor(shape?: T, radius?: number) {
constructor(shape?: T, radius?: number, withContact?: boolean, withCorrection?: boolean) {
if (shape !== undefined) { this.shape = shape; }
if (radius !== undefined) { this.radius = radius; }
if (withContact !== undefined) { this.withContact = withContact; }
if (withCorrection !== undefined) { this.withCorrection; }
}
/**
* Wire path to pipe
Expand All @@ -3617,12 +3631,24 @@ export namespace OCCT {
* @step 1
*/
radius = 0.1;
/**
* If withContact is true, the section is translated to be in contact with the spine.
* @default false
*/
withContact = false;
/**
* If withCorrection is true, the section is rotated to be orthogonal to the spine's tangent in the correspondent point.
* @default false
*/
withCorrection = false;
}
export class PipePolygonWireNGonDto<T> {
constructor(shapes?: T, radius?: number, nrCorners?: number) {
constructor(shapes?: T, radius?: number, nrCorners?: number, withContact?: boolean, withCorrection?: boolean) {
if (shapes !== undefined) { this.shape = shapes; }
if (radius !== undefined) { this.radius = radius; }
if (nrCorners !== undefined) { this.nrCorners = nrCorners; }
if (withContact !== undefined) { this.withContact = withContact; }
if (withCorrection !== undefined) { this.withCorrection; }
}
/**
* Wire path to pipe
Expand All @@ -3645,6 +3671,16 @@ export namespace OCCT {
* @step 1
*/
nrCorners = 6;
/**
* If withContact is true, the section is translated to be in contact with the spine.
* @default false
*/
withContact = false;
/**
* If withCorrection is true, the section is rotated to be orthogonal to the spine's tangent in the correspondent point.
* @default false
*/
withCorrection = false;
}
export class ExtrudeDto<T> {
constructor(shape?: T, direction?: Base.Vector3) {
Expand Down Expand Up @@ -3954,10 +3990,11 @@ export namespace OCCT {
index = 1;
}
export class RotationExtrudeDto<T> {
constructor(shape?: T, height?: number, angle?: number) {
constructor(shape?: T, height?: number, angle?: number, makeSolid?: boolean) {
if (shape !== undefined) { this.shape = shape; }
if (height !== undefined) { this.height = height; }
if (angle !== undefined) { this.angle = angle; }
if (makeSolid !== undefined) { this.makeSolid = makeSolid; }
}
/**
* Wire to extrude by rotating
Expand All @@ -3980,6 +4017,11 @@ export namespace OCCT {
* @step 1
*/
angle = 360;
/**
* Make solid of the result
* @default true
*/
makeSolid = true;
}

// Threading : Create Surfaces
Expand Down
1 change: 0 additions & 1 deletion packages/dev/occt/lib/services/base/booleans.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ export class BooleansService {

if (this.shapeGettersService.getNumSolidsInCompound(difference) === 1) {
const solid = this.shapeGettersService.getSolidFromCompound(difference, 0);
difference.delete();
difference = solid;
}

Expand Down
96 changes: 72 additions & 24 deletions packages/dev/occt/lib/services/base/operations.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -312,13 +312,13 @@ export class OperationsService {
});
bopalgoBuilder.Perform(new this.occ.Message_ProgressRange_1());
let shapes;
if(!inputs.nonDestructive){
if (!inputs.nonDestructive) {
const res = bopalgoBuilder.Modified(inputs.shape);
const shapeCompound = this.occ.BitByBitDev.BitListOfShapesToCompound(res);
shapes = this.shapeGettersService.getShapesOfCompound({shape: shapeCompound});
shapes = this.shapeGettersService.getShapesOfCompound({ shape: shapeCompound });
} else {
const res = bopalgoBuilder.Shape();
shapes = this.shapeGettersService.getShapesOfCompound({shape: res});
shapes = this.shapeGettersService.getShapesOfCompound({ shape: res });
}

return shapes;
Expand Down Expand Up @@ -399,7 +399,11 @@ export class OperationsService {
pipe.Add_1(inputs.shape, false, false);
pipe.Add_1(upperPolygon, false, false);
pipe.Build(new this.occ.Message_ProgressRange_1());
pipe.MakeSolid();

// default should be to make the solid for backwards compatibility
if (inputs.makeSolid || inputs.makeSolid === undefined) {
pipe.MakeSolid();
}

const pipeShape = pipe.Shape();
const result = this.converterService.getActualTypeOfShape(pipeShape);
Expand Down Expand Up @@ -430,30 +434,52 @@ export class OperationsService {
const wire = inputs.shape;
const shapesToPassThrough: TopoDS_Shape[] = [];
const edges = this.shapeGettersService.getEdges({ shape: wire });

// Check if the wire is closed
const isClosed = this.wiresService.isWireClosed({ shape: wire }); // Assuming such a method exists

edges.forEach((e, index) => {
const edgeStartPt = this.edgesService.startPointOnEdge({ shape: e });
const tangent = this.edgesService.tangentOnEdgeAtParam({ shape: e, param: 0 });
let tangentPreviousEdgeEnd: Inputs.Base.Vector3;
let averageTangentVec = tangent;

if (index > 0 && index < edges.length - 1) {
const previousEdge = edges[index - 1];
tangentPreviousEdgeEnd = this.edgesService.tangentOnEdgeAtParam({ shape: previousEdge, param: 1 });
averageTangentVec = [tangent[0] + tangentPreviousEdgeEnd[0] / 2, tangent[1] + tangentPreviousEdgeEnd[1] / 2, tangent[2] + tangentPreviousEdgeEnd[2] / 2];
if (edges.length > 1) { // Only average tangents if there’s more than one edge
if (index > 0 || (isClosed && index === 0)) {
const previousEdge = edges[(index - 1 + edges.length) % edges.length]; // Wrap around for closed wires
const tangentPreviousEdgeEnd = this.edgesService.tangentOnEdgeAtParam({ shape: previousEdge, param: 1 });
averageTangentVec = [
(tangent[0] + tangentPreviousEdgeEnd[0]) / 2,
(tangent[1] + tangentPreviousEdgeEnd[1]) / 2,
(tangent[2] + tangentPreviousEdgeEnd[2]) / 2
];
}
}
const ngon = this.wiresService.createNGonWire({ radius: inputs.radius, center: edgeStartPt, direction: averageTangentVec, nrCorners: inputs.nrCorners }) as TopoDS_Wire;

const ngon = this.wiresService.createNGonWire({
radius: inputs.radius,
center: edgeStartPt,
direction: averageTangentVec,
nrCorners: inputs.nrCorners
}) as TopoDS_Wire;
shapesToPassThrough.push(ngon);
if (index === edges.length - 1) {

// For open wires, add a final n-gon at the end of the last edge
if (!isClosed && index === edges.length - 1) {
const edgeEndPt = this.edgesService.endPointOnEdge({ shape: e });
const tangentEndPt = this.edgesService.tangentOnEdgeAtParam({ shape: e, param: 1 });
const ngon = this.wiresService.createNGonWire({ radius: inputs.radius, center: edgeEndPt, direction: tangentEndPt, nrCorners: inputs.nrCorners }) as TopoDS_Wire;
const ngon = this.wiresService.createNGonWire({
radius: inputs.radius,
center: edgeEndPt,
direction: tangentEndPt,
nrCorners: inputs.nrCorners
}) as TopoDS_Wire;
shapesToPassThrough.push(ngon);
}
});

const pipe = new this.occ.BRepOffsetAPI_MakePipeShell(wire);
shapesToPassThrough.forEach(s => {
pipe.Add_1(s, false, false);
pipe.Add_1(s, inputs.withContact === true ? true : false, inputs.withCorrection === true ? true : false);
});

pipe.Build(new this.occ.Message_ProgressRange_1());
Expand All @@ -469,30 +495,52 @@ export class OperationsService {
const wire = inputs.shape;
const shapesToPassThrough: TopoDS_Shape[] = [];
const edges = this.shapeGettersService.getEdges({ shape: wire });

// Check if the wire is closed
const isClosed = this.wiresService.isWireClosed({ shape: wire }); // Assuming such a method exists

edges.forEach((e, index) => {
const edgeStartPt = this.edgesService.startPointOnEdge({ shape: e });
const tangent = this.edgesService.tangentOnEdgeAtParam({ shape: e, param: 0 });
let tangentPreviousEdgeEnd: Inputs.Base.Vector3;
let averageTangentVec = tangent;

if (index > 0 && index < edges.length - 1) {
const previousEdge = edges[index - 1];
tangentPreviousEdgeEnd = this.edgesService.tangentOnEdgeAtParam({ shape: previousEdge, param: 1 });
averageTangentVec = [tangent[0] + tangentPreviousEdgeEnd[0] / 2, tangent[1] + tangentPreviousEdgeEnd[1] / 2, tangent[2] + tangentPreviousEdgeEnd[2] / 2];
if (edges.length > 1) { // Only average tangents if there’s more than one edge
if (index > 0 || (isClosed && index === 0)) {
const previousEdge = edges[(index - 1 + edges.length) % edges.length]; // Wrap around for closed wires
const tangentPreviousEdgeEnd = this.edgesService.tangentOnEdgeAtParam({ shape: previousEdge, param: 1 });
averageTangentVec = [
(tangent[0] + tangentPreviousEdgeEnd[0]) / 2,
(tangent[1] + tangentPreviousEdgeEnd[1]) / 2,
(tangent[2] + tangentPreviousEdgeEnd[2]) / 2
];
}
}
const circle = this.entitiesService.createCircle(inputs.radius, edgeStartPt, averageTangentVec, Inputs.OCCT.typeSpecificityEnum.wire) as TopoDS_Wire;

const circle = this.entitiesService.createCircle(
inputs.radius,
edgeStartPt,
averageTangentVec,
Inputs.OCCT.typeSpecificityEnum.wire
) as TopoDS_Wire;
shapesToPassThrough.push(circle);
if (index === edges.length - 1) {

// For open wires, add a final circle at the end of the last edge
if (!isClosed && index === edges.length - 1) {
const edgeEndPt = this.edgesService.endPointOnEdge({ shape: e });
const tangentEndPt = this.edgesService.tangentOnEdgeAtParam({ shape: e, param: 1 });
const line = this.entitiesService.createCircle(inputs.radius, edgeEndPt, tangentEndPt, Inputs.OCCT.typeSpecificityEnum.wire) as TopoDS_Wire;
shapesToPassThrough.push(line);
const circle = this.entitiesService.createCircle(
inputs.radius,
edgeEndPt,
tangentEndPt,
Inputs.OCCT.typeSpecificityEnum.wire
) as TopoDS_Wire;
shapesToPassThrough.push(circle);
}
});

const pipe = new this.occ.BRepOffsetAPI_MakePipeShell(wire);
shapesToPassThrough.forEach(s => {
pipe.Add_1(s, false, false);
pipe.Add_1(s, inputs.withContact === true ? true : false, inputs.withCorrection === true ? true : false);
});

pipe.Build(new this.occ.Message_ProgressRange_1());
Expand All @@ -506,7 +554,7 @@ export class OperationsService {

pipeWiresCylindrical(inputs: Inputs.OCCT.PipeWiresCylindricalDto<TopoDS_Wire>) {
return inputs.shapes.map(wire => {
return this.pipeWireCylindrical({ shape: wire, radius: inputs.radius });
return this.pipeWireCylindrical({ shape: wire, radius: inputs.radius, withContact: inputs.withContact, withCorrection: inputs.withCorrection });
});
}

Expand Down
Loading