Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEAT] Upgrade opencascade.js to 2.0 #7

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
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
15 changes: 11 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"bundledDependencies": false,
"dependencies": {
"leapjs": "^1.1.1",
"opencascade.js": "github:zalo/opencascade.js",
"opencascade.js": "2.0.0-beta.03aec7f",
"potpack": "^1.0.1",
"three": "^0.129.0"
},
Expand Down
61 changes: 30 additions & 31 deletions src/Backend/OpenCascadeMesher.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,34 +14,34 @@
* limitations under the License.
*/

//import oc from '../../node_modules/opencascade.js/dist/opencascade.wasm.module.js';
//import potpack from '../../node_modules/potpack/index.mjs';
importScripts('../../node_modules/potpack/index.js');
import * as oc from '../../node_modules/opencascade.js/dist/opencascade.full.js';
import potpack from '../../node_modules/potpack/index.mjs';
//importScripts('../../node_modules/potpack/index.js');

/** This is the CAD Engine Worker Thread, where all the real work happens */
class OpenCascadeMesher {

/** Initialize the CAD Meshing System
* @param {oc} oc The OpenCascade Context */
* @param {oc.OpenCascadeInstance} oc The OpenCascade Context */
constructor(oc) {
this.oc = oc;
}

/** Iterate over all the faces in this shape, calling `callback` on each one. */
ForEachFace(shape, callback) {
let face_index = 0;
if (!this.faceExplorer) { this.faceExplorer = new this.oc.TopExp_Explorer(shape, this.oc.TopAbs_FACE); }
for (this.faceExplorer.Init(shape, this.oc.TopAbs_FACE); this.faceExplorer.More(); this.faceExplorer.Next()) {
callback(face_index++, this.oc.TopoDS.prototype.Face(this.faceExplorer.Current()));
if (!this.faceExplorer) { this.faceExplorer = new this.oc.TopExp_Explorer_1(); }//shape, this.oc.TopAbs_FACE, this.oc.TopAbs_SHAPE); }
for (this.faceExplorer.Init(shape, this.oc.TopAbs_ShapeEnum.TopAbs_FACE, this.oc.TopAbs_ShapeEnum.TopAbs_SHAPE); this.faceExplorer.More(); this.faceExplorer.Next()) {
callback(face_index++, this.oc.TopoDS.Face_1(this.faceExplorer.Current()));
}
}

/** Iterate over all the UNIQUE indices and edges in this shape, calling `callback` on each one. */
ForEachEdge(shape, callback) {
let edgeHashes = {}; let edgeIndex = 0;
if (!this.edgeExplorer) { this.edgeExplorer = new this.oc.TopExp_Explorer(shape, this.oc.TopAbs_EDGE); }
for (this.edgeExplorer.Init(shape, this.oc.TopAbs_EDGE); this.edgeExplorer.More(); this.edgeExplorer.Next()) {
let edge = this.oc.TopoDS.prototype.Edge(this.edgeExplorer.Current());
if (!this.edgeExplorer) { this.edgeExplorer = new this.oc.TopExp_Explorer_1(); }//shape, this.oc.TopAbs_EDGE, this.oc.TopAbs_SHAPE); }
for (this.edgeExplorer.Init(shape, this.oc.TopAbs_ShapeEnum.TopAbs_EDGE, this.oc.TopAbs_ShapeEnum.TopAbs_SHAPE); this.edgeExplorer.More(); this.edgeExplorer.Next()) {
let edge = this.oc.TopoDS.Edge_1(this.edgeExplorer.Current());

// Edge explorer visits every edge twice;
// hash them to ensure visiting only once
Expand All @@ -55,7 +55,7 @@ class OpenCascadeMesher {
}

LengthOfCurve(geomAdaptor, UMin, UMax, segments = 5) {
let point1 = [0, 0, 0], point2 = [0, 0, 0], arcLength = 0, gpPnt = new this.oc.gp_Pnt();
let point1 = [0, 0, 0], point2 = [0, 0, 0], arcLength = 0, gpPnt = new this.oc.gp_Pnt_1();
for (let s = UMin; s <= UMax; s += (UMax - UMin) / segments) {
geomAdaptor.D0(s, gpPnt);
point1 = [gpPnt.X(), gpPnt.Y(), gpPnt.Z()];
Expand All @@ -75,24 +75,24 @@ class OpenCascadeMesher {
* @param {oc.TopoDS_Shape} shape OpenCascade Shape
* @param {number} maxDeviation */
shapeToMesh(shape, maxDeviation) {
if (!shape || shape.IsNull()) { console.error("Shape is null or undefined!"); return null; }
if (!shape || !shape.IsNull || shape.IsNull()) { console.error("Shape is null or undefined!"); return null; }
let facelist = [], edgeList = []; let corrupt = false;
try {
//shape = new this.oc.TopoDS_Shape(shape);
let fullShapeEdgeHashes = {};
Object.assign(fullShapeEdgeHashes, this.ForEachEdge(shape, (index, edge) => { }));

// Set up the Incremental Mesh builder, with a precision
this.incrementalMesh = new this.oc.BRepMesh_IncrementalMesh(shape, maxDeviation, false, 0.5);
this.incrementalMesh = new this.oc.BRepMesh_IncrementalMesh_2(shape, maxDeviation, false, 0.5, false);

// Construct the edge hashes to assign proper indices to the edges
let fullShapeEdgeHashes2 = {};

// Iterate through the faces and triangulate each one
let triangulations = []; let uv_boxes = []; let curFace = 0;
this.ForEachFace(shape, (faceIndex, myFace) => {
if (!this.aLocation) { this.aLocation = new this.oc.TopLoc_Location(); }
let myT = this.oc.BRep_Tool.prototype.Triangulation(myFace, this.aLocation);
if (!this.aLocation) { this.aLocation = new this.oc.TopLoc_Location_1(); }
let myT = this.oc.BRep_Tool.Triangulation(myFace, this.aLocation);
if (myT.IsNull()) { console.error("Encountered Null Face!"); corrupt = true; }

let this_face = {
Expand All @@ -109,7 +109,7 @@ class OpenCascadeMesher {
VMin: 0, VMax: 0
};

if (!this.pc) { this.pc = new this.oc.Poly_Connect(myT); } else { this.pc.Load(myT); }
if (!this.pc) { this.pc = new this.oc.Poly_Connect_2(myT); } else { this.pc.Load(myT); }
let Nodes = myT.get().Nodes();

// Write vertex buffer
Expand All @@ -128,7 +128,7 @@ class OpenCascadeMesher {
this_face.average[2] /= Nodes.Length();

// Write UV buffer
let orient = myFace.Orientation();
let orient = myFace.Orientation_1();
if (myT.get().HasUVNodes()) {
// Get UV Bounds
let UMin = 0, UMax = 0, VMin = 0, VMax = 0;
Expand All @@ -152,17 +152,17 @@ class OpenCascadeMesher {
this_face.VMin = VMin; this_face.VMax = VMax;

// Compute the Arclengths of the Isoparametric Curves of the face
let surfaceHandle = this.oc.BRep_Tool.prototype.Surface(myFace);
let surfaceHandle = this.oc.BRep_Tool.Surface_2(myFace);
let surface = surfaceHandle.get();
let UIso_Handle = surface.UIso(UMin + ((UMax - UMin) * 0.5));
let VIso_Handle = surface.VIso(VMin + ((VMax - VMin) * 0.5));
if (!this.adaptorCurve) {
this.adaptorCurve = new this.oc.GeomAdaptor_Curve(VIso_Handle);
this.adaptorCurve = new this.oc.GeomAdaptor_Curve_2(VIso_Handle);
} else {
this.adaptorCurve.Load(VIso_Handle);
this.adaptorCurve.Load_1(VIso_Handle);
}
let w = this.LengthOfCurve(this.adaptorCurve, UMin, UMax);
this.adaptorCurve.Load(UIso_Handle);
this.adaptorCurve.Load_1(UIso_Handle);
let h = this.LengthOfCurve(this.adaptorCurve, VMin, VMax);
uv_boxes.push({w: w, h: h, index: curFace });

Expand All @@ -173,13 +173,13 @@ class OpenCascadeMesher {

x = ((x - UMin) / (UMax - UMin));
y = ((y - VMin) / (VMax - VMin));
if (orient !== this.oc.TopAbs_FORWARD) { x = 1.0 - x; }
if (orient !== this.oc.TopAbs_Orientation.TopAbs_FORWARD) { x = 1.0 - x; }

this_face.uv_coord[(i * 2) + 0] = x;
this_face.uv_coord[(i * 2) + 1] = y;
}

let planarChecker = new this.oc.GeomLib_IsPlanarSurface(surfaceHandle);
let planarChecker = new this.oc.GeomLib_IsPlanarSurface(surfaceHandle, 0.00001);
this_face.is_planar = planarChecker.IsPlanar();
this.oc._free(planarChecker);
}
Expand All @@ -189,9 +189,8 @@ class OpenCascadeMesher {
let normalArrayKey = Nodes.Lower() + ", " + Nodes.Upper();
let myNormal = null;
if (this.normalArrays[normalArrayKey]) { myNormal = this.normalArrays[normalArrayKey]; } else {
myNormal = new this.oc.TColgp_Array1OfDir(Nodes.Lower(), Nodes.Upper()); }
if (!this.SST) { this.SST = new this.oc.StdPrs_ToolTriangulatedShape(); }
this.SST.Normal(myFace, this.pc, myNormal);
myNormal = new this.oc.TColgp_Array1OfDir_2(Nodes.Lower(), Nodes.Upper()); }
this.oc.StdPrs_ToolTriangulatedShape.Normal(myFace, this.pc, myNormal);
this_face.normal_coord = new Array(myNormal.Length() * 3);
for (let i = 0; i < myNormal.Length(); i++) {
let d = myNormal.Value(i + 1).Transformed(this.aLocation.Transformation());
Expand All @@ -207,7 +206,7 @@ class OpenCascadeMesher {
for (let nt = 1; nt <= myT.get().NbTriangles(); nt++) {
let t = triangles.Value(nt);
let n1 = t.Value(1), n2 = t.Value(2), n3 = t.Value(3);
if (orient !== this.oc.TopAbs_FORWARD) {
if (orient !== this.oc.TopAbs_Orientation.TopAbs_FORWARD) {
let tmp = n1;
n1 = n2;
n2 = tmp;
Expand All @@ -231,7 +230,7 @@ class OpenCascadeMesher {
edge_index: -1
};

let myP = this.oc.BRep_Tool.prototype.PolygonOnTriangulation(myEdge, myT, this.aLocation);
let myP = this.oc.BRep_Tool.PolygonOnTriangulation_1(myEdge, myT, this.aLocation);
let edgeNodes = myP.get().Nodes();

// write vertex buffer
Expand Down Expand Up @@ -291,12 +290,12 @@ class OpenCascadeMesher {
};

if (!this.brepAdaptorCurve) {
this.brepAdaptorCurve = new this.oc.BRepAdaptor_Curve(myEdge);
this.brepAdaptorCurve = new this.oc.BRepAdaptor_Curve_2(myEdge);
} else {
this.brepAdaptorCurve.Initialize(myEdge);
}
if (!this.tangDef) {
this.tangDef = new this.oc.GCPnts_TangentialDeflection(this.brepAdaptorCurve, maxDeviation, 0.1);
this.tangDef = new this.oc.GCPnts_TangentialDeflection_2(this.brepAdaptorCurve, maxDeviation, 0.1, 2, 1.0e-9, 1.0e-7);
} else {
this.tangDef.Initialize(this.brepAdaptorCurve, maxDeviation, 0.1);
}
Expand Down Expand Up @@ -331,4 +330,4 @@ class OpenCascadeMesher {
}
}

//export { OpenCascadeMesher };
export { OpenCascadeMesher };
4 changes: 2 additions & 2 deletions src/Backend/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ class LeapShapeEngine {

// Initialize the OpenCascade Worker Thread
if (typeof ESBUILD !== 'undefined') {
this.worker = new Worker(new URL( './Backend/mainWorker.js', import.meta.url )/*, { type: "module" }*/);
this.worker = new Worker(new URL( './Backend/mainWorker.js', import.meta.url ), { type: "module" });
} else {
this.worker = new Worker('../src/Backend/mainWorker.js'/*, { type: "module" }*/);
this.worker = new Worker('../src/Backend/mainWorker.js', { type: "module" });
}

// Ping Pong Messages Back and Forth based on their registration in messageHandlers
Expand Down
12 changes: 7 additions & 5 deletions src/Backend/mainWorker.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@

// Leave these next 4 lines exactly as they are. The comments are toggled for ESBuild
//import url from "../../node_modules/opencascade.js/dist/opencascade.wasm.wasm";
//import opencascade from '../../node_modules/opencascade.js/dist/opencascade.wasm.module.js';
//import { OpenCascadeMesher } from './OpenCascadeMesher.js';
importScripts('../../node_modules/opencascade.js/dist/opencascade.wasm.js', './OpenCascadeMesher.js');
//import opencascade from '../../node_modules/opencascade.js/dist/opencascade.full.js';
//importScripts('./OpenCascadeMesher.js');
import opencascade, * as oc from '../../node_modules/opencascade.js/dist/opencascade.full.js';
import { OpenCascadeMesher } from './OpenCascadeMesher.js';

/** This is the CAD Engine Worker Thread, where all the real work happens */
class LeapShapeEngineWorker {
Expand All @@ -32,7 +33,7 @@ class LeapShapeEngineWorker {
new opencascade({
locateFile(path) {
if (path.endsWith('.wasm')) {
return (typeof ESBUILD !== 'undefined') ? "."+url : "../../node_modules/opencascade.js/dist/opencascade.wasm.wasm";
return (typeof ESBUILD !== 'undefined') ? "."+url : "../../node_modules/opencascade.js/dist/opencascade.full.wasm";
}
return path;
}
Expand Down Expand Up @@ -74,6 +75,7 @@ class LeapShapeEngineWorker {
}
let op = this.backendFunctions[payload.shapeFunction];

/** @type {oc.TopoDS_Shape} */
let shape = null;
try {
shape = op(...payload.shapeArguments);
Expand All @@ -82,7 +84,7 @@ class LeapShapeEngineWorker {
return { name: payload.name, payload: shape };
} else {
// Otherwise Convert the Shape to a Mesh + Metadata
if (!shape || shape.IsNull()) { console.error("Shape is null"); console.error(shape); }
if (!shape || !shape.IsNull || shape.IsNull()) { console.error("Shape is null"); console.error(shape); }
let meshData = this.mesher.shapeToMesh(shape, this.resolution, {}, {});
if (meshData) { this.shapes[payload.name] = shape; }
return { name: payload.name, payload: meshData };
Expand Down
12 changes: 6 additions & 6 deletions src/Frontend/Tools/BoxTool.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/

import * as THREE from '../../../node_modules/three/build/three.module.js';
import oc from '../../../node_modules/opencascade.js/dist/opencascade.wasm.module.js';
import * as oc from '../../../node_modules/opencascade.js/dist/opencascade.full.js';
import { Tools } from './Tools.js';
import { InteractionRay } from '../Input/Input.js';
import { Grid } from './General/Grid.js';
Expand Down Expand Up @@ -257,23 +257,23 @@ class BoxTool {
let hitAnObject = hitObjectName in this.shapes;

// Construct the Box Shape
let boxPlane = new this.oc.gp_Ax2(new this.oc.gp_Pnt(x, y, z), new this.oc.gp_Dir(nx, ny, nz), new this.oc.gp_Dir(vx, vy, vz));
let shape = new this.oc.BRepPrimAPI_MakeBox(boxPlane, Math.abs(length), Math.abs(width), Math.abs(height)).Shape();
let boxPlane = new this.oc.gp_Ax2_2(new this.oc.gp_Pnt_3(x, y, z), new this.oc.gp_Dir_4(nx, ny, nz), new this.oc.gp_Dir_4(vx, vy, vz));
let shape = new this.oc.BRepPrimAPI_MakeBox_5(boxPlane, Math.abs(length), Math.abs(width), Math.abs(height)).Shape();

if (!shape || shape.IsNull()) { console.error("BRepPrimAPI_MakeBox did not like its arguments!"); }
if (!shape || !shape.IsNull || shape.IsNull()) { console.error("BRepPrimAPI_MakeBox did not like its arguments!"); }

// If we hit an object, let's CSG this Box to it
if (hitAnObject && height > 0) {
// The Height is Positive, let's Union
let hitObject = this.shapes[hitObjectName];
let unionOp = new this.oc.BRepAlgoAPI_Fuse(hitObject, shape);
let unionOp = new this.oc.BRepAlgoAPI_Fuse_3(hitObject, shape);
unionOp.SetFuzzyValue(0.0000001);
unionOp.Build();
return unionOp.Shape();
} else if (hitAnObject && height < 0) {
// The Height is Negative, let's Subtract
let hitObject = this.shapes[hitObjectName];
let differenceOp = new this.oc.BRepAlgoAPI_Cut(hitObject, shape);
let differenceOp = new this.oc.BRepAlgoAPI_Cut_3(hitObject, shape);
differenceOp.SetFuzzyValue(0.0000001);
differenceOp.Build();
return differenceOp.Shape();
Expand Down
2 changes: 1 addition & 1 deletion src/Frontend/Tools/CleanEdgesTool.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/

import * as THREE from '../../../node_modules/three/build/three.module.js';
import oc from '../../../node_modules/opencascade.js/dist/opencascade.wasm.module.js';
import * as oc from '../../../node_modules/opencascade.js/dist/opencascade.full.js';
import { Tools } from './Tools.js';
import { InteractionRay } from '../Input/Input.js';
import { snapToGrid } from './General/ToolUtils.js';
Expand Down
2 changes: 1 addition & 1 deletion src/Frontend/Tools/CopyTool.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/

import * as THREE from '../../../node_modules/three/build/three.module.js';
import oc from '../../../node_modules/opencascade.js/dist/opencascade.wasm.module.js';
import * as oc from '../../../node_modules/opencascade.js/dist/opencascade.full.js';
import { Tools } from './Tools.js';
import { InteractionRay } from '../Input/Input.js';
import { snapToGrid } from './General/ToolUtils.js';
Expand Down
Loading