import { inspectSldprt } from "../../native-sldprt/index.mjs"; import { recognizeMeshFeatures } from "../../mesh-features/index.mjs"; import type { MeshFeatureReport } from "../../mesh-features/index.mjs"; import { analyzeStep } from "../../cad-features/index.mjs"; import { OcctKernel } from "occt-wasm"; import wasmUrl from "occt-wasm/dist/occt-wasm.wasm?url"; import { recognizeMeshDepthFeatures } from "../../mesh-depth-features/index.mjs"; import { depthMeshes,type Analysis } from "./types"; function addDepth(analysis:Analysis):Analysis{ try{return{...analysis,depth_features:recognizeMeshDepthFeatures(depthMeshes(analysis),{source:analysis.report.source,geometry_basis:analysis.mode==="native_cache"?"saved_native_display":"step_tessellation"})};} catch(error){return{...analysis,depth_error:`Depth recognition was not completed: ${error instanceof Error?error.message:"unsupported geometry"}. No replacement features were substituted.`};} } self.onmessage=async(event:MessageEvent<{filename:string;bytes:ArrayBuffer;kernelBytes?:ArrayBuffer;kernelName?:string}>)=>{ try{ const {filename,bytes}=event.data; if(!(bytes instanceof ArrayBuffer)||bytes.byteLength===0||bytes.byteLength>20*1024*1024)throw new Error("Model must be between 1 byte and 20 MiB."); if(/\.sldprt$/i.test(filename)){ const report=await inspectSldprt(new Uint8Array(bytes),{filename}); let cache_features:MeshFeatureReport; try{cache_features=recognizeMeshFeatures(report.meshes);}catch(error){cache_features={schema_version:"mesh-features-1.0",features:[],surfaces:[],unclassified_mesh_ids:report.meshes.map(m=>m.id),limitations:[`Display geometry decoded, but feature fitting was not completed: ${error instanceof Error?error.message:"unsupported mesh"}`],machine_release:{eligible:false,reasons:["Feature fitting unavailable."]}};} self.postMessage({ok:true,result:addDepth({mode:"native_cache",report,cache_features})}); }else if(/\.(?:step|stp)$/i.test(filename)){ const digest=await crypto.subtle.digest("SHA-256",bytes),sha256=Array.from(new Uint8Array(digest)).map(n=>n.toString(16).padStart(2,"0")).join(""); const replacement=event.data.kernelBytes; if(replacement&&(!(replacement instanceof ArrayBuffer)||replacement.byteLength>32*1024*1024||replacement.byteLength<8))throw new Error("Replacement kernel must be a compatible WASM binary, at most 32 MiB."); const kernel=await OcctKernel.init({wasm:replacement??wasmUrl}); try{const report=analyzeStep(kernel,new Uint8Array(bytes),{filename,sha256,byte_length:bytes.byteLength});const kernel_source=replacement?{kind:"user_replacement",filename:event.data.kernelName,sha256:Array.from(new Uint8Array(await crypto.subtle.digest("SHA-256",replacement))).map(n=>n.toString(16).padStart(2,"0")).join("")}: {kind:"bundled",package:"occt-wasm@3.4.0"};self.postMessage({ok:true,result:addDepth({mode:"step_brep",report,kernel_source})});}finally{kernel[Symbol.dispose]();} }else throw new Error("Choose a STEP/STP solid or a supported SLDPRT file. Images and PDFs are supplementary evidence, not 3D geometry."); }catch(error){self.postMessage({ok:false,error:error instanceof Error?error.message:"3D analysis failed; no geometry was substituted."});} };