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

[WIP] Upgrade to Embind Bindings #12

Open
wants to merge 23 commits into
base: feat-typescript
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
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
4 changes: 2 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,11 @@

<!-- Speed up loading by prefetching URLs here -->
<link rel="prefetch" href="./js/CADWorker/CascadeStudioShapeToMesh.js">
<link rel="prefetch" href="./node_modules/opencascade.js/dist/oc.d.ts">
<link rel="prefetch" href="./node_modules/opencascade.js/dist/opencascade.full.d.ts">
<link rel="prefetch" href="./node_modules/three/build/three.d.ts">
<link rel="prefetch" href="./node_modules/typescript/lib/lib.es5.d.ts">
<link rel="prefetch" href="./node_modules/typescript/lib/lib.webworker.d.ts">
<link rel="prefetch" href="./node_modules/opencascade.js/dist/opencascade.wasm.js">
<link rel="prefetch" href="./node_modules/opencascade.js/dist/opencascade.full.js">
<link rel="prefetch" href="./node_modules/monaco-editor/min/vs/language/typescript/tsMode.js">
<link rel="prefetch" href="./node_modules/typescript/bin/typescript.min.js">
<link rel="prefetch" href="./node_modules/monaco-editor/min/vs/basic-languages/typescript/typescript.js">
Expand Down
8 changes: 4 additions & 4 deletions js/CADWorker/CascadeStudioFileUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ function importSTEPorIGES(fileName, fileText) {
let stepShape = reader.OneShape(); // Obtain the results of translation in one OCCT shape

// Add to the externalShapes dictionary
externalShapes[fileName] = new oc.TopoDS_Shape(stepShape);
externalShapes[fileName] = new oc.BRepBuilderAPI_Copy_2(stepShape, true, false).Shape();
externalShapes[fileName].hash = stringToHash(fileName);
console.log("Shape Import complete! Use sceneShapes.push(externalShapes['"+fileName+"']); to add it to the scene!");

Expand All @@ -98,17 +98,17 @@ function importSTL(fileName, fileText) {

// Choose the correct OpenCascade file parsers to read the STL file
var reader = new oc.StlAPI_Reader();
let readShape = new oc.TopoDS_Shape ();
let readShape = new oc.TopoDS_Shape();

if (reader.Read(readShape, fileName)) {
console.log(fileName + " loaded successfully! Converting to OCC now...");

// Convert Shell to Solid as is expected
let solidSTL = new oc.BRepBuilderAPI_MakeSolid();
solidSTL.Add(new oc.TopoDS_Shape(readShape));
solidSTL.Add(new oc.BRepBuilderAPI_Copy_2(readShape, true, false).Shape());

// Add to the externalShapes dictionary
externalShapes[fileName] = new oc.TopoDS_Shape(solidSTL.Solid());
externalShapes[fileName] = new oc.BRepBuilderAPI_Copy_2(solidSTL.Solid(), true, false).Shape();
externalShapes[fileName].hash = stringToHash(fileName);
console.log("Shape Import complete! Use sceneShapes.push(externalShapes['" + fileName + "']); to see it!");

Expand Down
71 changes: 51 additions & 20 deletions js/CADWorker/CascadeStudioMainWorker.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ console.error = function (err, url, line, colno, errorObj) {
importScripts(
//'../../node_modules/three/build/three.min.js',
'./CascadeStudioShapeToMesh.js',
'../../node_modules/opencascade.js/dist/opencascade.wasm.js',
'../../node_modules/opentype.js/dist/opentype.min.js',
'../../node_modules/typescript/bin/typescript.min.js',
'../../node_modules/potpack/index.js');
Expand All @@ -42,6 +41,8 @@ function ImportLibrary(urls, forceReload) {
importedLibraries[url] = ts.transpileModule(response.target.responseText,
{ compilerOptions: { module: ts.ModuleKind.CommonJS } }).outputText;
eval.call(null, importedLibraries[url]);
//let importedLibrary = new Function(importedLibraries[url]);
//importedLibrary.call(null,[]);
postMessage({ "type": "addLibrary", payload: { url: url, contents: response.target.responseText } });
} else {
console.error("Could not find library at this URL! URL: "+ response.target.responseURL +", Status Code: "+response.target.status);
Expand Down Expand Up @@ -71,26 +72,56 @@ preloadedFonts.forEach((fontURL) => {

// Load the full Open Cascade Web Assembly Module
var messageHandlers = {};
new opencascade({
locateFile(path) {
if (path.endsWith('.wasm')) {
return "../../node_modules/opencascade.js/dist/opencascade.wasm.wasm";
}
return path;
}
}).then((openCascade) => {
// Register the "OpenCascade" WebAssembly Module under the shorthand "oc"
oc = openCascade;

// Ping Pong Messages Back and Forth based on their registration in messageHandlers
onmessage = function (e) {
let response = messageHandlers[e.data.type](e.data.payload);
if (response) { postMessage({ "type": e.data.type, payload: response }); };
}
fetch('../../node_modules/opencascade.js/dist/opencascade.full.js')
.then(response => response.text())
.then((data) => {

// Patch in an intelligible overload finding mechanism
data = data.replace("classType.registeredClass.constructor_body[argCount-1]=function constructor_body()",
`classType.registeredClass.argTypes = argTypes;
classType.registeredClass.constructor_body[argCount-1]=function constructor_body()`);
data = data.replace('throw new BindingError(name+" has no accessible constructor")',
`let message = name + " overload not specified! Consider using one of these overloads: ";
let matches = Object.values(registeredPointers).filter((item) => (item.pointerType && item.pointerType.name.includes(legalFunctionName+"_")));
for(let ii = 0; ii < matches.length; ii++){
message += matches[ii].pointerType.name.slice(0, -1) + "(";
let argTypes = matches[ii].pointerType.registeredClass.argTypes;
for(let jj = 1; jj < argTypes.length; jj++){
message += argTypes[jj].name + ", ";
}
if(argTypes.length > 1) { message = message.slice(0, -2); }
message += "), ";
}
throw new BindingError(message.slice(0, -2));`);

// Remove this export line from the end so it works in browsers
data = data.split("export default Module;")[0];

// Import the Javascript from a blob URL
importScripts(URL.createObjectURL(new Blob([data], { type: 'text/javascript' })));
//console.log("Actually start loading CAD Kernel...");
new Module({
locateFile(path) {
if (path.endsWith('.wasm')) {
return "../../node_modules/opencascade.js/dist/opencascade.full.wasm";
}
return path;
}
}).then((openCascade) => {
// Register the "OpenCascade" WebAssembly Module under the shorthand "oc"
oc = openCascade;

// Ping Pong Messages Back and Forth based on their registration in messageHandlers
onmessage = function (e) {
let response = messageHandlers[e.data.type](e.data.payload);
if (response) { postMessage({ "type": e.data.type, payload: response }); };
}

// Initial Evaluation after everything has been loaded...
postMessage({ type: "startupCallback" });
});
});

// Initial Evaluation after everything has been loaded...
postMessage({ type: "startupCallback" });
});

/** This function evaluates `payload.code` (the contents of the Editor Window)
* and sets the GUI State. */
Expand Down
52 changes: 26 additions & 26 deletions js/CADWorker/CascadeStudioShapeToMesh.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
function LengthOfCurve(geomAdaptor, UMin, UMax, segments = 5) {
let point1 = [0.0, 0.0, 0.0], point2 = [0.0, 0.0, 0.0],
arcLength = 0, gpPnt = new oc.gp_Pnt();
arcLength = 0, gpPnt = new oc.gp_Pnt_1();
for (let s = UMin; s <= UMax; s += (UMax - UMin) / segments){
geomAdaptor.D0(s, gpPnt);
point1[0] = gpPnt.X(); point1[1] = gpPnt.Y(); point1[2] = gpPnt.Z();
Expand All @@ -17,20 +17,20 @@ function LengthOfCurve(geomAdaptor, UMin, UMax, segments = 5) {

function ShapeToMesh(shape, maxDeviation, fullShapeEdgeHashes, fullShapeFaceHashes) {
let facelist = [], edgeList = [];
try {
shape = new oc.TopoDS_Shape(shape);
//try {
//shape = new oc.BRepBuilderAPI_Copy_2(shape, true, false).Shape();

// Set up the Incremental Mesh builder, with a precision
new oc.BRepMesh_IncrementalMesh(shape, maxDeviation, false, maxDeviation * 5);
new oc.BRepMesh_IncrementalMesh_2(shape, maxDeviation, false, maxDeviation * 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;
ForEachFace(shape, (faceIndex, myFace) => {
let aLocation = new oc.TopLoc_Location();
let myT = oc.BRep_Tool.prototype.Triangulation(myFace, aLocation);
let aLocation = new oc.TopLoc_Location_1();
let myT = oc.BRep_Tool.Triangulation(myFace, aLocation);
if (myT.IsNull()) { console.error("Encountered Null Face!"); argCache = {}; return; }

let this_face = {
Expand All @@ -42,7 +42,7 @@ function ShapeToMesh(shape, maxDeviation, fullShapeEdgeHashes, fullShapeFaceHash
face_index: fullShapeFaceHashes[myFace.HashCode(100000000)]
};

let pc = new oc.Poly_Connect(myT);
let pc = new oc.Poly_Connect_2(myT);
let Nodes = myT.get().Nodes();

// Write vertex buffer
Expand All @@ -55,7 +55,7 @@ function ShapeToMesh(shape, maxDeviation, fullShapeEdgeHashes, fullShapeFaceHash
}

// 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 @@ -75,11 +75,11 @@ function ShapeToMesh(shape, maxDeviation, fullShapeEdgeHashes, fullShapeFaceHash
}

// Compute the Arclengths of the Isoparametric Curves of the face
let surface = oc.BRep_Tool.prototype.Surface(myFace).get();
let surface = oc.BRep_Tool.Surface_2(myFace).get();
let UIso_Handle = surface.UIso(UMin + ((UMax - UMin) * 0.5));
let VIso_Handle = surface.VIso(VMin + ((VMax - VMin) * 0.5));
let UAdaptor = new oc.GeomAdaptor_Curve(VIso_Handle);
let VAdaptor = new oc.GeomAdaptor_Curve(UIso_Handle);
let UAdaptor = new oc.GeomAdaptor_Curve_2(VIso_Handle);
let VAdaptor = new oc.GeomAdaptor_Curve_2(UIso_Handle);
uv_boxes.push({
w: LengthOfCurve(UAdaptor, UMin, UMax),
h: LengthOfCurve(VAdaptor, VMin, VMax),
Expand All @@ -101,17 +101,16 @@ function ShapeToMesh(shape, maxDeviation, fullShapeEdgeHashes, fullShapeFaceHash
}

// Write normal buffer
let myNormal = new oc.TColgp_Array1OfDir(Nodes.Lower(), Nodes.Upper());
let SST = new oc.StdPrs_ToolTriangulatedShape();
SST.Normal(myFace, pc, myNormal);
let myNormal = new oc.TColgp_Array1OfDir_2(Nodes.Lower(), Nodes.Upper());
oc.StdPrs_ToolTriangulatedShape.Normal(myFace, 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(aLocation.Transformation());
this_face.normal_coord[(i * 3)+ 0] = d.X();
this_face.normal_coord[(i * 3)+ 1] = d.Y();
this_face.normal_coord[(i * 3)+ 2] = d.Z();
}

// Write triangle buffer
let triangles = myT.get().Triangles();
this_face.tri_indexes = new Array(triangles.Length() * 3);
Expand All @@ -121,7 +120,7 @@ function ShapeToMesh(shape, maxDeviation, fullShapeEdgeHashes, fullShapeFaceHash
let n1 = t.Value(1);
let n2 = t.Value(2);
let n3 = t.Value(3);
if(orient !== oc.TopAbs_FORWARD) {
if(orient !== oc.TopAbs_Orientation.TopAbs_FORWARD) {
let tmp = n1;
n1 = n2;
n2 = tmp;
Expand All @@ -145,7 +144,7 @@ function ShapeToMesh(shape, maxDeviation, fullShapeEdgeHashes, fullShapeFaceHash
edge_index: -1
};

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

// write vertex buffer
Expand Down Expand Up @@ -203,9 +202,9 @@ function ShapeToMesh(shape, maxDeviation, fullShapeEdgeHashes, fullShapeFaceHash
edge_index: -1
};

let aLocation = new oc.TopLoc_Location();
let adaptorCurve = new oc.BRepAdaptor_Curve(myEdge);
let tangDef = new oc.GCPnts_TangentialDeflection(adaptorCurve, maxDeviation, 0.1);
let aLocation = new oc.TopLoc_Location_1();
let adaptorCurve = new oc.BRepAdaptor_Curve_2(myEdge);
let tangDef = new oc.GCPnts_TangentialDeflection_2(adaptorCurve, maxDeviation, 0.1, 2, 1.0e-9, 1.0e-7);

// write vertex buffer
this_edge.vertex_coord = new Array(tangDef.NbPoints() * 3);
Expand All @@ -223,12 +222,13 @@ function ShapeToMesh(shape, maxDeviation, fullShapeEdgeHashes, fullShapeFaceHash
}
});

} catch(err) {
setTimeout(() => {
err.message = "INTERNAL OPENCASCADE ERROR DURING GENERATE: " + err.message;
throw err;
}, 0);
}
//}// catch (err) {
// throw err;
// //setTimeout(() => {
// // //err.message = "INTERNAL OPENCASCADE ERROR DURING GENERATE: " + err.message;
// // throw err;
// //}, 0);
//}

return [facelist, edgeList];
}
Loading