@bitbybit-dev/occt
Version:
Bit By Bit Developers CAD algorithms using OpenCascade Technology kernel. Run in Node and in Browser.
222 lines (221 loc) • 9.75 kB
JavaScript
export class OCCTIO {
constructor(occ, och) {
this.occ = occ;
this.och = och;
}
saveShapeSTEP(inputs) {
const shapeToUse = inputs.shape;
let adjustedShape;
if (inputs.adjustYtoZ) {
const rotatedShape = this.och.transformsService.rotate({ shape: inputs.shape, axis: [1, 0, 0], angle: -90 });
if (inputs.fromRightHanded) {
adjustedShape = rotatedShape;
}
else {
adjustedShape = this.och.transformsService.mirrorAlongNormal({ shape: rotatedShape, origin: [0, 0, 0], normal: [0, 0, 1] });
rotatedShape.delete();
}
}
const fileName = "x";
const writer = new this.occ.STEPControl_Writer_1();
let transferShape;
if (adjustedShape) {
transferShape = adjustedShape;
}
else {
transferShape = shapeToUse;
}
// Convert to a .STEP File
const messageProgress = new this.occ.Message_ProgressRange_1();
let transferResult;
try {
transferResult = writer.Transfer(transferShape, this.occ.STEPControl_StepModelType.STEPControl_AsIs, true, messageProgress);
}
catch (ex) {
throw (new Error("Failed when calling writer.Transfer."));
}
let result;
if (transferResult === this.occ.IFSelect_ReturnStatus.IFSelect_RetDone) {
// Write the STEP File to the virtual Emscripten Filesystem Temporarily
const writeResult = writer.Write(fileName);
if (writeResult === this.occ.IFSelect_ReturnStatus.IFSelect_RetDone) {
// Read the STEP File from the filesystem and clean up
const stepFileText = this.occ.FS.readFile("/" + fileName, { encoding: "utf8" });
this.occ.FS.unlink("/" + fileName);
// Return the contents of the STEP File
result = stepFileText;
}
else {
throw (new Error("Failed when writing step file."));
}
}
else {
throw (new Error("Failed when transfering to step writer."));
}
if (adjustedShape) {
adjustedShape.delete();
}
messageProgress.delete();
return result;
}
saveShapeStl(inputs) {
const shapeToUse = inputs.shape;
// This could be made optional...
// Clean cached triangulation data for the shape.
// This allows to get lower res models out of higher res that was once computed and cached.
this.occ.BRepTools.Clean(shapeToUse, true);
let adjustedShape;
if (inputs.adjustYtoZ) {
const rotatedShape = this.och.transformsService.rotate({ shape: inputs.shape, axis: [1, 0, 0], angle: -90 });
adjustedShape = this.och.transformsService.mirrorAlongNormal({ shape: rotatedShape, origin: [0, 0, 0], normal: [0, 0, 1] });
rotatedShape.delete();
}
const fileName = "x";
const writer = new this.occ.StlAPI_Writer();
let transferShape;
if (adjustedShape) {
transferShape = adjustedShape;
}
else {
transferShape = shapeToUse;
}
const messageProgress = new this.occ.Message_ProgressRange_1();
let result;
const incrementalMeshBuilder = new this.occ.BRepMesh_IncrementalMesh_2(transferShape, inputs.precision, false, 0.5, false);
// Write the STL File to the virtual Emscripten Filesystem Temporarily
const writeResult = writer.Write(transferShape, fileName, messageProgress);
if (writeResult) {
// Read the STL File from the filesystem and clean up
const stlFile = this.occ.FS.readFile("/" + fileName, { encoding: "utf8" });
this.occ.FS.unlink("/" + fileName);
// Return the contents of the STL File
result = stlFile;
}
else {
throw (new Error("Failed when writing stl file."));
}
if (adjustedShape) {
adjustedShape.delete();
}
messageProgress.delete();
if (incrementalMeshBuilder) {
incrementalMeshBuilder.Delete();
}
return result;
}
/** This function parses the ASCII contents of a `.STEP` or `.IGES`
* File as a Shape into the `externalShapes` dictionary.
*/
loadSTEPorIGES(inputs) {
const fileName = inputs.fileName;
const fileText = inputs.filetext;
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
this.occ.FS.createDataFile("/", `file.${fileType}`, fileText, true, true, true);
// Choose the correct OpenCascade file parsers to read the CAD file
let reader;
if (fileType === "step") {
reader = new this.occ.STEPControl_Reader_1();
}
else if (fileType === "iges") {
reader = new this.occ.IGESControl_Reader_1();
}
else {
console.error("opencascade can't parse this extension! (yet)");
return undefined;
}
const readResult = reader.ReadFile(`file.${fileType}`); // Read the file
if (readResult === this.occ.IFSelect_ReturnStatus.IFSelect_RetDone) {
// Translate all transferable roots to OpenCascade
const messageProgress = new this.occ.Message_ProgressRange_1();
reader.TransferRoots(messageProgress);
messageProgress.delete();
let stepShape = reader.OneShape();
let adjustedShape;
if (inputs.adjustZtoY) {
const mirroredShape = this.och.transformsService.mirrorAlongNormal({ shape: stepShape, origin: [0, 0, 0], normal: [0, 0, 1] });
adjustedShape = this.och.transformsService.rotate({ shape: mirroredShape, axis: [1, 0, 0], angle: 90 });
mirroredShape.delete();
}
// Out with the old, in with the new!
// Remove the file when we're done (otherwise we run into errors on reupload)
this.occ.FS.unlink(`/file.${fileType}`);
if (adjustedShape) {
stepShape.delete();
stepShape = adjustedShape;
}
return stepShape;
}
else {
console.error("Something in OCCT went wrong trying to read " + fileName);
}
return undefined;
}
// TODO WIP! This function parses the contents of a `.STEP` file as an assembly
// and returns the assembly structure. It's not finished yet and needs a lot of work.
// private parseStepAssembly(inputs: Inputs.OCCT.LoadStepOrIgesDto) {
// const fileName = inputs.fileName;
// const fileText = inputs.filetext;
// // Write file to virtual filesystem
// this.occ.FS.createDataFile("/", "step_file.step", fileText as string, true, true, true);
// try {
// // Create XCAF application and document
// const app = this.occ.XCAFApp_Application.GetApplication();
// const format = new this.occ.TCollection_ExtendedString_2("MDTV-XCAF", true);
// const docHandle = new this.occ.Handle_TDocStd_Document_1();
// app.get().NewDocument_2(format, docHandle);
// const doc = docHandle.get();
// // Use STEPCAFControl_Reader to read with full XCAF support
// const reader = new this.occ.STEPCAFControl_Reader_1();
// reader.SetColorMode(true); // Enable color reading
// reader.SetNameMode(true); // Enable name reading
// reader.SetLayerMode(true); // Enable layer reading
// reader.SetPropsMode(true); // Enable properties reading
// // Read the file
// const readResult = reader.ReadFile("step_file.step");
// if (readResult === this.occ.IFSelect_ReturnStatus.IFSelect_RetDone) {
// // Transfer to XCAF document
// const messageProgress = new this.occ.Message_ProgressRange_1();
// const transferResult = reader.Transfer_1(docHandle, messageProgress);
// messageProgress.delete();
// if (transferResult) {
// // Parse using the improved assembly parser
// // const assemblyStructure = this.ioAssembly.parseXCAFDocument(doc);
// // Clean up
// reader.delete();
// format.delete();
// docHandle.delete();
// this.occ.FS.unlink("/step_file.step");
// return {};
// } else {
// throw new Error("Failed to transfer STEP data to XCAF document");
// }
// } else {
// throw new Error("Failed to read STEP file");
// }
// } catch (error) {
// this.occ.FS.unlink("/step_file.step");
// throw error;
// }
// }
shapeToDxfPaths(inputs) {
return this.och.dxfService.shapeToDxfPaths(inputs);
}
dxfPathsWithLayer(inputs) {
return this.och.dxfService.dxfPathsWithLayer(inputs);
}
dxfCreate(inputs) {
return this.och.dxfService.dxfCreate(inputs);
}
}