
Thu, 06/02/2022 - 11:58
Forums:
Hello,
I am currently using Opencascade.js for converting STEP files to GLB format. But in a web viewer mesh number and draw calls are too high.
How can I reduce mesh number? I guess I need to change paramters of BRepMesh_IncrementalMesh_2 but I couldnt find the correct way.
I referenced this code:
https://draw.sview.ru/xde-export-step2gltf/
You cand find the code snippet below.
Thank you very much.
import fs from 'fs';
import path from 'path';
import initOpenCascade from 'opencascade.js/dist/node.js';
const loadSTEPorIGES = async (openCascade, file, fileName) => {
const fileText = fs.readFileSync(file.path, 'utf8');
const fileType = (() => {
switch (fileName.toLowerCase().split(".").pop()) {
case "step":
case "stp":
return "step";
case "iges":
case "igs":
return "iges";
default:
return undefined;
}
})();
// Writes the uploaded file to Emscripten's Virtual Filesystem
openCascade.FS.createDataFile("/", `file.${fileType}`, fileText, true, true);
// Choose the correct OpenCascade file parsers to read the CAD file
var reader = null;
if (fileType === "step") {
reader = new openCascade.STEPCAFControl_Reader_1();
} else if (fileType === "iges") {
reader = new openCascade.IGESCAFControl_Reader_1();
} else { console.error("opencascade.js can't parse this extension! (yet)"); }
const readResult = reader.ReadFile(`file.${fileType}`); // Read the file
if (readResult === openCascade.IFSelect_ReturnStatus.IFSelect_RetDone) {
console.log("file loaded successfully! Converting to OCC now...");
//const numRootsTransferred = reader.TransferRoots(new openCascade.Message_ProgressRange_1()); // Translate all transferable roots to OpenCascade
// Create a document add our shapes
const doc = new openCascade.TDocStd_Document(new openCascade.TCollection_ExtendedString_1());
if (fileType === "step") {
if (!reader.Transfer_1(new openCascade.Handle_TDocStd_Document_2(doc), new openCascade.Message_ProgressRange_1())) throw new Error();
} else {
if (!reader.Transfer(new openCascade.Handle_TDocStd_Document_2(doc), new openCascade.Message_ProgressRange_1())) throw new Error();
}
// Obtain the results of translation in one OCCT shape
console.log(fileName + " converted successfully! Triangulating now...");
return visualizeShapes(openCascade, doc, fileName, fileType);
} else {
console.error("Something in OCCT went wrong trying to read " + fileName);
}
};
function visualizeDoc(oc, doc, fileName, fileType) {
const justName = path.parse(fileName).name;
// Export a GLB file (this will also perform the meshing)
const cafWriter = new oc.RWGltf_CafWriter(new oc.TCollection_AsciiString_2(`./${justName}.glb`), true);
cafWriter.Perform_2(new oc.Handle_TDocStd_Document_2(doc), new oc.TColStd_IndexedDataMapOfStringString_1(), new oc.Message_ProgressRange_1());
// Out with the old, in with the new!
console.log(fileName + " triangulated and added to the scene!");
// Remove the file when we're done (otherwise we run into errors on reupload)
oc.FS.unlink(`/file.${fileType}`);
// Read the GLB file from the virtual file system
const glbFile = oc.FS.readFile(`./${justName}.glb`, { encoding: "binary" });
const fileObj = { file: glbFile, filename: fileName };
return fileObj;
}
function visualizeShapes(oc, doc, fileName, fileType) {
const aRootLabels = new oc.TDF_LabelSequence_1();
const aCompound = new oc.TopoDS_Compound();
const shapeTool = oc.XCAFDoc_DocumentTool.ShapeTool(doc.Main()).get();
shapeTool.GetFreeShapes(aRootLabels);
const BRepBuilder = new oc.BRep_Builder();
BRepBuilder.MakeCompound(aCompound);
for (let i = 1; i <= aRootLabels.Length(); i++) {
const aRootShape = new oc.TopoDS_Shape();
const aRootLabel = aRootLabels.Value(i);
if (oc.XCAFDoc_ShapeTool.GetShape_1(aRootLabel, aRootShape)) {
BRepBuilder.Add(aCompound, aRootShape);
}
}
const aDrawer = new oc.Prs3d_Drawer();
const BoundBox = new oc.Bnd_Box_1();
oc.BRepBndLib.Add(aCompound, BoundBox, false);
const anAlgo = new oc.BRepMesh_IncrementalMesh_2(aCompound, oc.Prs3d.GetDeflection_2(BoundBox, aDrawer.MaximalChordialDeviation(), aDrawer.DeviationCoefficient()), false, (20.0 * Math.PI / 180.0), true);
anAlgo.Perform_1(new oc.Message_ProgressRange_1());
console.log("hey");
// Return our visualized document
return visualizeDoc(oc, doc, fileName, fileType);
}
const convertSTEPorIGES = async (file) => {
const openCascade = await initOpenCascade();
return loadSTEPorIGES(openCascade, file, file.filename);
}
export default convertSTEPorIGES;
Thu, 06/02/2022 - 16:31
Number of meshes, draw calls, and parameters of BRepMesh_IncrementalMesh are three subjects that have no overlapping:
Fri, 06/03/2022 - 10:56
Hello Kirill,
First of all thank you for your detailed answer.
I am using Microsoft's BabylonJs as web engine. This is the aim of this STEP2GLB conversion. Mostly users upload assembly files and I use transform nodes of parts and attach gizmos to parts. So they can move the parts of assembly.
So I need speed more than visual quality.
I am trying to merging all child meshes of parts while importing to BabylonJs. But it would be way better finding a way while writing file with OCC.
Fri, 06/03/2022 - 11:31
As I have mentioned, you may try option RWGltf_CafWriter::ToMergeFaces() at first and see if it makes any difference in case of your web engine.
Fri, 06/03/2022 - 11:46
Yes I tried to try it first after your message. I just couldn't set ToMergeFaces to true in OpenCascadeJS. :(
I will let you know the result if i can.
Tue, 06/07/2022 - 04:17
Hello,Taking this topic to ask a question, I have a Step file, which contains 4 parts. After importing and exporting into a Gltf file, they are merged into one. I don't know if you encounter this problem again....