UNPKG

@bitbybit-dev/occt

Version:

Bit By Bit Developers CAD algorithms using OpenCascade Technology kernel. Run in Node and in Browser.

456 lines (455 loc) 28.3 kB
import * as Inputs from "../api/inputs"; 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(); let transferShape; if (adjustedShape) { transferShape = adjustedShape; } else { transferShape = shapeToUse; } // Convert to a .STEP File let transferResult; try { transferResult = writer.Transfer(transferShape, this.occ.STEPControl_StepModelType.AsIs); } catch (ex) { throw (new Error("Failed when calling writer.Transfer.")); } let result; if (transferResult === this.occ.IFSelect_ReturnStatus.RetDone) { // Write the STEP File to the virtual Emscripten Filesystem Temporarily const writeResult = writer.Write(fileName); if (writeResult === this.occ.IFSelect_ReturnStatus.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(); } 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); 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; } let result; const incrementalMeshBuilder = new this.occ.BRepMesh_IncrementalMesh(transferShape, inputs.precision, false, 0.5, false); // Write the STL File to the virtual Emscripten Filesystem Temporarily const writeResult = writer.Write(transferShape, fileName); 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(); } if (incrementalMeshBuilder) { incrementalMeshBuilder.delete(); } return result; } /** This function parses the contents of a `.STEP` or `.IGES` file as a Shape. * * Accepts: * - string: for plain text files (.step, .stp, .iges, .igs) * - ArrayBuffer: for compressed files (.stpz, .igz) or binary content */ loadSTEPorIGES(inputs) { const fileName = inputs.fileName; const fileText = inputs.filetext; const extension = fileName.toLowerCase().split(".").pop(); // Determine file type based on extension const fileType = (() => { switch (extension) { case "step": case "stp": case "stpz": // Compressed STEP return "step"; case "iges": case "igs": case "igz": // Compressed IGES return "iges"; default: return undefined; } })(); if (!fileType) { console.error("opencascade can't parse this extension!"); return undefined; } // Check if input is binary (ArrayBuffer) - use binary functions const isBinaryInput = fileText instanceof ArrayBuffer; let stepShape; if (isBinaryInput) { // Use binary functions for compressed files or binary content const uint8Array = new Uint8Array(fileText); if (fileType === "step") { stepShape = this.occ.ReadSTEPFromBinary(uint8Array); } else if (fileType === "iges") { stepShape = this.occ.ReadIGESFromBinary(uint8Array); } if (!stepShape || stepShape.IsNull()) { console.error("Failed to read " + fileType.toUpperCase() + " file: " + fileName); return undefined; } } else { // Use traditional file-based approach for text files this.occ.FS.createDataFile("/", `file.${fileType}`, fileText, true, true, true); let reader; if (fileType === "step") { reader = new this.occ.STEPControl_Reader(); } else { reader = new this.occ.IGESControl_Reader(); } const readResult = reader.ReadFile(`file.${fileType}`); if (readResult === this.occ.IFSelect_ReturnStatus.RetDone) { reader.TransferRoots(); stepShape = reader.OneShape(); this.occ.FS.unlink(`/file.${fileType}`); } else { console.error("Something in OCCT went wrong trying to read " + fileName); this.occ.FS.unlink(`/file.${fileType}`); return undefined; } } // Apply coordinate system adjustment if requested let adjustedShape; if (inputs.adjustZtoY && stepShape) { 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(); } if (adjustedShape) { stepShape === null || stepShape === void 0 ? void 0 : stepShape.delete(); return adjustedShape; } return stepShape; } shapeToDxfPaths(inputs) { return this.och.dxfService.shapeToDxfPaths(inputs); } dxfPathsWithLayer(inputs) { return this.och.dxfService.dxfPathsWithLayer(inputs); } dxfCreate(inputs) { return this.och.dxfService.dxfCreate(inputs); } /** * Convert a STEP file to glTF format (binary GLB). * * Uses OCCT's native RWGltf_CafWriter for fast conversion with full preservation of: * - Assembly hierarchy (as glTF node tree) * - Instance/product names * - Surface colors and materials * - Transformations * * The coordinate system is automatically converted from OCCT (Z-up) to glTF (Y-up). * * Note: File/Blob inputs must be converted to ArrayBuffer before calling this method. * The worker layer handles this conversion automatically. * * @param inputs - STEP file content and mesh precision settings. Accepts string, ArrayBuffer, or Uint8Array. * @returns GLB binary data as Uint8Array (can be used directly with Three.js, Babylon.js, etc.) */ convertStepToGltf(inputs) { var _a, _b, _c, _d, _e; try { const stepData = inputs.stepData; let result; const meshPrecision = (_a = inputs.meshPrecision) !== null && _a !== void 0 ? _a : 0.005; const meshAngle = (_b = inputs.meshAngle) !== null && _b !== void 0 ? _b : 0.5; const meshRelative = (_c = inputs.meshRelative) !== null && _c !== void 0 ? _c : true; const internalVerticesMode = (_d = inputs.internalVerticesMode) !== null && _d !== void 0 ? _d : false; const controlSurfaceDeflection = (_e = inputs.controlSurfaceDeflection) !== null && _e !== void 0 ? _e : false; // Check if input is binary (Uint8Array or ArrayBuffer) - use for STEP-Z compressed files if (stepData instanceof Uint8Array) { result = this.occ.ConvertStepToGltfFromBinary(stepData, meshPrecision, meshAngle, meshRelative, internalVerticesMode, controlSurfaceDeflection, -1); } else if (stepData instanceof ArrayBuffer) { // ArrayBuffer needs to be wrapped as Uint8Array result = this.occ.ConvertStepToGltfFromBinary(new Uint8Array(stepData), meshPrecision, meshAngle, meshRelative, internalVerticesMode, controlSurfaceDeflection, -1); } else if (typeof stepData === "string") { // String input - plain text STEP files result = this.occ.ConvertStepToGltfFromMemory(stepData, meshPrecision, meshAngle, meshRelative, internalVerticesMode, controlSurfaceDeflection, -1); } else { // File or Blob - should have been converted by worker layer throw new Error("File/Blob must be converted to ArrayBuffer before calling this method. Use the worker layer for automatic conversion."); } if (result.length === 0) { throw new Error("Failed to convert STEP to glTF"); } return result; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); throw new Error(`STEP to glTF conversion failed: ${errorMessage}`); } } /** * Convert a STEP file to glTF format with full control over all options. * * This advanced method allows fine-grained control over: * - STEP reading options (colors, names, materials, layers, props) * - Mesh generation options (deflection, angle, parallel, threshold) * - glTF export options (merge faces, indices, naming, transforms) * * Use this for performance tuning - disable features you don't need for faster processing. * * @param inputs - Advanced options including STEP data, mesh settings, and glTF export settings. * @returns GLB binary data as Uint8Array */ convertStepToGltfAdvanced(inputs) { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35; try { const stepData = inputs.stepData; let result; // Convert enum string values to OCCT numeric values const nodeNameFormatNum = this.gltfNameFormatEnumToOcct((_a = inputs.nodeNameFormat) !== null && _a !== void 0 ? _a : Inputs.OCCT.gltfNameFormatEnum.instance); const meshNameFormatNum = this.gltfNameFormatEnumToOcct((_b = inputs.meshNameFormat) !== null && _b !== void 0 ? _b : Inputs.OCCT.gltfNameFormatEnum.instance); const transformFormatNum = this.gltfTransformFormatEnumToOcct((_c = inputs.transformFormat) !== null && _c !== void 0 ? _c : Inputs.OCCT.gltfTransformFormatEnum.compact); // Check if input is binary (Uint8Array or ArrayBuffer) - use for STEP-Z compressed files if (stepData instanceof Uint8Array) { result = this.occ.ConvertStepToGltfFromBinaryAdvanced(stepData, (_d = inputs.readColors) !== null && _d !== void 0 ? _d : true, (_e = inputs.readNames) !== null && _e !== void 0 ? _e : true, (_f = inputs.readMaterials) !== null && _f !== void 0 ? _f : true, (_g = inputs.readLayers) !== null && _g !== void 0 ? _g : false, (_h = inputs.readProps) !== null && _h !== void 0 ? _h : false, (_j = inputs.meshDeflection) !== null && _j !== void 0 ? _j : 0.005, (_k = inputs.meshAngle) !== null && _k !== void 0 ? _k : 0.5, (_l = inputs.meshParallel) !== null && _l !== void 0 ? _l : true, (_m = inputs.meshRelative) !== null && _m !== void 0 ? _m : true, (_o = inputs.internalVerticesMode) !== null && _o !== void 0 ? _o : false, (_p = inputs.controlSurfaceDeflection) !== null && _p !== void 0 ? _p : false, (_q = inputs.faceCountThreshold) !== null && _q !== void 0 ? _q : -1, (_r = inputs.mergeFaces) !== null && _r !== void 0 ? _r : true, (_s = inputs.splitIndices16) !== null && _s !== void 0 ? _s : true, (_t = inputs.parallelWrite) !== null && _t !== void 0 ? _t : true, (_u = inputs.embedTextures) !== null && _u !== void 0 ? _u : true, (_v = inputs.forceUVExport) !== null && _v !== void 0 ? _v : false, nodeNameFormatNum, meshNameFormatNum, transformFormatNum, (_w = inputs.adjustZtoY) !== null && _w !== void 0 ? _w : true, (_x = inputs.scale) !== null && _x !== void 0 ? _x : 1.0); } else if (stepData instanceof ArrayBuffer) { // ArrayBuffer needs to be wrapped as Uint8Array result = this.occ.ConvertStepToGltfFromBinaryAdvanced(new Uint8Array(stepData), (_y = inputs.readColors) !== null && _y !== void 0 ? _y : true, (_z = inputs.readNames) !== null && _z !== void 0 ? _z : true, (_0 = inputs.readMaterials) !== null && _0 !== void 0 ? _0 : true, (_1 = inputs.readLayers) !== null && _1 !== void 0 ? _1 : false, (_2 = inputs.readProps) !== null && _2 !== void 0 ? _2 : false, (_3 = inputs.meshDeflection) !== null && _3 !== void 0 ? _3 : 0.005, (_4 = inputs.meshAngle) !== null && _4 !== void 0 ? _4 : 0.5, (_5 = inputs.meshParallel) !== null && _5 !== void 0 ? _5 : true, (_6 = inputs.meshRelative) !== null && _6 !== void 0 ? _6 : true, (_7 = inputs.internalVerticesMode) !== null && _7 !== void 0 ? _7 : false, (_8 = inputs.controlSurfaceDeflection) !== null && _8 !== void 0 ? _8 : false, (_9 = inputs.faceCountThreshold) !== null && _9 !== void 0 ? _9 : -1, (_10 = inputs.mergeFaces) !== null && _10 !== void 0 ? _10 : true, (_11 = inputs.splitIndices16) !== null && _11 !== void 0 ? _11 : true, (_12 = inputs.parallelWrite) !== null && _12 !== void 0 ? _12 : true, (_13 = inputs.embedTextures) !== null && _13 !== void 0 ? _13 : true, (_14 = inputs.forceUVExport) !== null && _14 !== void 0 ? _14 : false, nodeNameFormatNum, meshNameFormatNum, transformFormatNum, (_15 = inputs.adjustZtoY) !== null && _15 !== void 0 ? _15 : true, (_16 = inputs.scale) !== null && _16 !== void 0 ? _16 : 1.0); } else if (typeof stepData === "string") { // String input - cannot use ConvertStepToGltfFromBinaryAdvanced, convert to Uint8Array const encoder = new TextEncoder(); const binaryData = encoder.encode(stepData); result = this.occ.ConvertStepToGltfFromBinaryAdvanced(binaryData, (_17 = inputs.readColors) !== null && _17 !== void 0 ? _17 : true, (_18 = inputs.readNames) !== null && _18 !== void 0 ? _18 : true, (_19 = inputs.readMaterials) !== null && _19 !== void 0 ? _19 : true, (_20 = inputs.readLayers) !== null && _20 !== void 0 ? _20 : false, (_21 = inputs.readProps) !== null && _21 !== void 0 ? _21 : false, (_22 = inputs.meshDeflection) !== null && _22 !== void 0 ? _22 : 0.005, (_23 = inputs.meshAngle) !== null && _23 !== void 0 ? _23 : 0.5, (_24 = inputs.meshParallel) !== null && _24 !== void 0 ? _24 : true, (_25 = inputs.meshRelative) !== null && _25 !== void 0 ? _25 : true, (_26 = inputs.internalVerticesMode) !== null && _26 !== void 0 ? _26 : false, (_27 = inputs.controlSurfaceDeflection) !== null && _27 !== void 0 ? _27 : false, (_28 = inputs.faceCountThreshold) !== null && _28 !== void 0 ? _28 : -1, (_29 = inputs.mergeFaces) !== null && _29 !== void 0 ? _29 : true, (_30 = inputs.splitIndices16) !== null && _30 !== void 0 ? _30 : true, (_31 = inputs.parallelWrite) !== null && _31 !== void 0 ? _31 : true, (_32 = inputs.embedTextures) !== null && _32 !== void 0 ? _32 : true, (_33 = inputs.forceUVExport) !== null && _33 !== void 0 ? _33 : false, nodeNameFormatNum, meshNameFormatNum, transformFormatNum, (_34 = inputs.adjustZtoY) !== null && _34 !== void 0 ? _34 : true, (_35 = inputs.scale) !== null && _35 !== void 0 ? _35 : 1.0); } else { // File or Blob - should have been converted by worker layer throw new Error("File/Blob must be converted to ArrayBuffer before calling this method. Use the worker layer for automatic conversion."); } if (result.length === 0) { throw new Error("Failed to convert STEP to glTF"); } return result; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); throw new Error(`STEP to glTF advanced conversion failed: ${errorMessage}`); } } /** * Convert a STEP file to glTF format (binary GLB) with explicit Draco * geometry compression settings. * * Same conversion path as `convertStepToGltf` but exposes the Draco knobs * supported by the underlying native function. * * @param inputs - STEP file content, mesh precision settings, and Draco knobs. * @returns GLB binary data as Uint8Array */ convertStepToGltfWithDraco(inputs) { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o; try { const stepData = inputs.stepData; let binaryData; if (stepData instanceof Uint8Array) { binaryData = stepData; } else if (stepData instanceof ArrayBuffer) { binaryData = new Uint8Array(stepData); } else if (typeof stepData === "string") { binaryData = new TextEncoder().encode(stepData); } else { throw new Error("File/Blob must be converted to ArrayBuffer before calling this method. Use the worker layer for automatic conversion."); } const result = this.occ.ConvertStepToGltfFromBinaryWithDraco(binaryData, (_a = inputs.meshPrecision) !== null && _a !== void 0 ? _a : 0.005, (_b = inputs.meshAngle) !== null && _b !== void 0 ? _b : 0.5, (_c = inputs.meshRelative) !== null && _c !== void 0 ? _c : true, (_d = inputs.internalVerticesMode) !== null && _d !== void 0 ? _d : false, (_e = inputs.controlSurfaceDeflection) !== null && _e !== void 0 ? _e : false, -1, (_f = inputs.useDraco) !== null && _f !== void 0 ? _f : true, (_g = inputs.dracoCompressionLevel) !== null && _g !== void 0 ? _g : 7, (_h = inputs.dracoQuantizePositionBits) !== null && _h !== void 0 ? _h : 14, (_j = inputs.dracoQuantizeNormalBits) !== null && _j !== void 0 ? _j : 10, (_k = inputs.dracoQuantizeTexcoordBits) !== null && _k !== void 0 ? _k : 12, (_l = inputs.dracoQuantizeColorBits) !== null && _l !== void 0 ? _l : 8, (_m = inputs.dracoQuantizeGenericBits) !== null && _m !== void 0 ? _m : 12, (_o = inputs.dracoUnifiedQuantization) !== null && _o !== void 0 ? _o : false); if (result.length === 0) { throw new Error("Failed to convert STEP to glTF"); } return result; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); throw new Error(`STEP to glTF (Draco) conversion failed: ${errorMessage}`); } } /** * Convert a STEP file to glTF format with full control over all reading, meshing * and writer options, plus explicit Draco geometry compression settings. * * Same conversion path as `convertStepToGltfAdvanced` but exposes the 8 Draco * knobs. * * @param inputs - Advanced options including STEP data, mesh settings, glTF * export settings and Draco knobs. * @returns GLB binary data as Uint8Array */ convertStepToGltfAdvancedWithDraco(inputs) { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5; try { const stepData = inputs.stepData; let binaryData; if (stepData instanceof Uint8Array) { binaryData = stepData; } else if (stepData instanceof ArrayBuffer) { binaryData = new Uint8Array(stepData); } else if (typeof stepData === "string") { binaryData = new TextEncoder().encode(stepData); } else { throw new Error("File/Blob must be converted to ArrayBuffer before calling this method. Use the worker layer for automatic conversion."); } const nodeNameFormatNum = this.gltfNameFormatEnumToOcct((_a = inputs.nodeNameFormat) !== null && _a !== void 0 ? _a : Inputs.OCCT.gltfNameFormatEnum.instance); const meshNameFormatNum = this.gltfNameFormatEnumToOcct((_b = inputs.meshNameFormat) !== null && _b !== void 0 ? _b : Inputs.OCCT.gltfNameFormatEnum.instance); const transformFormatNum = this.gltfTransformFormatEnumToOcct((_c = inputs.transformFormat) !== null && _c !== void 0 ? _c : Inputs.OCCT.gltfTransformFormatEnum.compact); const result = this.occ.ConvertStepToGltfFromBinaryAdvancedWithDraco(binaryData, (_d = inputs.readColors) !== null && _d !== void 0 ? _d : true, (_e = inputs.readNames) !== null && _e !== void 0 ? _e : true, (_f = inputs.readMaterials) !== null && _f !== void 0 ? _f : true, (_g = inputs.readLayers) !== null && _g !== void 0 ? _g : false, (_h = inputs.readProps) !== null && _h !== void 0 ? _h : false, (_j = inputs.meshDeflection) !== null && _j !== void 0 ? _j : 0.005, (_k = inputs.meshAngle) !== null && _k !== void 0 ? _k : 0.5, (_l = inputs.meshParallel) !== null && _l !== void 0 ? _l : true, (_m = inputs.meshRelative) !== null && _m !== void 0 ? _m : true, (_o = inputs.internalVerticesMode) !== null && _o !== void 0 ? _o : false, (_p = inputs.controlSurfaceDeflection) !== null && _p !== void 0 ? _p : false, (_q = inputs.faceCountThreshold) !== null && _q !== void 0 ? _q : -1, (_r = inputs.mergeFaces) !== null && _r !== void 0 ? _r : true, (_s = inputs.splitIndices16) !== null && _s !== void 0 ? _s : true, (_t = inputs.parallelWrite) !== null && _t !== void 0 ? _t : true, (_u = inputs.embedTextures) !== null && _u !== void 0 ? _u : true, (_v = inputs.forceUVExport) !== null && _v !== void 0 ? _v : false, nodeNameFormatNum, meshNameFormatNum, transformFormatNum, (_w = inputs.adjustZtoY) !== null && _w !== void 0 ? _w : true, (_x = inputs.scale) !== null && _x !== void 0 ? _x : 1.0, (_y = inputs.useDraco) !== null && _y !== void 0 ? _y : true, (_z = inputs.dracoCompressionLevel) !== null && _z !== void 0 ? _z : 7, (_0 = inputs.dracoQuantizePositionBits) !== null && _0 !== void 0 ? _0 : 14, (_1 = inputs.dracoQuantizeNormalBits) !== null && _1 !== void 0 ? _1 : 10, (_2 = inputs.dracoQuantizeTexcoordBits) !== null && _2 !== void 0 ? _2 : 12, (_3 = inputs.dracoQuantizeColorBits) !== null && _3 !== void 0 ? _3 : 8, (_4 = inputs.dracoQuantizeGenericBits) !== null && _4 !== void 0 ? _4 : 12, (_5 = inputs.dracoUnifiedQuantization) !== null && _5 !== void 0 ? _5 : false); if (result.length === 0) { throw new Error("Failed to convert STEP to glTF"); } return result; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); throw new Error(`STEP to glTF advanced (Draco) conversion failed: ${errorMessage}`); } } /** * Parse a STEP file and return the assembly structure as JSON. * * Uses OCCT's native XCAFPrs_DocumentExplorer for efficient traversal. * Runs entirely in C++ for maximum performance. * * Note: File/Blob inputs must be converted to ArrayBuffer before calling this method. * The worker layer handles this conversion automatically. * * Returns an object containing an array of nodes with: * - id: Unique path identifier for each node * - name: Part or assembly name * - isAssembly: Whether this is an assembly node (has children) * - visible: Visibility flag * - colorRgba: Surface colorRgba (if set) with r, g, b, a components * - transform: 4x4 transformation matrix in column-major order (if not identity) * * @param inputs - STEP file content. Accepts string, ArrayBuffer, or Uint8Array. * @returns Parsed assembly structure */ parseStepToJson(inputs) { try { const stepData = inputs.stepData; let jsonString; // Check if input is binary (Uint8Array or ArrayBuffer) - use for STEP-Z compressed files if (stepData instanceof Uint8Array) { jsonString = this.occ.ParseStepAssemblyToJsonFromBinary(stepData); } else if (stepData instanceof ArrayBuffer) { // ArrayBuffer needs to be wrapped as Uint8Array jsonString = this.occ.ParseStepAssemblyToJsonFromBinary(new Uint8Array(stepData)); } else if (typeof stepData === "string") { // String input - plain text STEP files jsonString = this.occ.ParseStepAssemblyToJsonFromMemory(stepData); } else { // File or Blob - should have been converted by worker layer throw new Error("File/Blob must be converted to ArrayBuffer before calling this method. Use the worker layer for automatic conversion."); } // Parse JSON result const result = JSON.parse(jsonString); return result; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); return { version: "1.0", nodes: [], error: `STEP assembly parsing failed: ${errorMessage}` }; } } /** * Convert gltfNameFormatEnum string to OCCT numeric value. */ gltfNameFormatEnumToOcct(format) { switch (format) { case Inputs.OCCT.gltfNameFormatEnum.empty: return 0; case Inputs.OCCT.gltfNameFormatEnum.product: return 1; case Inputs.OCCT.gltfNameFormatEnum.instance: return 2; case Inputs.OCCT.gltfNameFormatEnum.instanceOrProduct: return 3; case Inputs.OCCT.gltfNameFormatEnum.productOrInstance: return 4; case Inputs.OCCT.gltfNameFormatEnum.productAndInstance: return 5; case Inputs.OCCT.gltfNameFormatEnum.productAndInstanceAndOcaf: return 6; default: return 2; // Default to instance } } /** * Convert gltfTransformFormatEnum string to OCCT numeric value. */ gltfTransformFormatEnumToOcct(format) { switch (format) { case Inputs.OCCT.gltfTransformFormatEnum.compact: return 0; case Inputs.OCCT.gltfTransformFormatEnum.mat4: return 1; case Inputs.OCCT.gltfTransformFormatEnum.trs: return 2; default: return 0; } } }