UNPKG

@shopware-ag/dive

Version:

Shopware Spatial Framework

516 lines (515 loc) 15.1 kB
var k = Object.defineProperty; var F = (_, r, s) => r in _ ? k(_, r, { enumerable: !0, configurable: !0, writable: !0, value: s }) : _[r] = s; var h = (_, r, s) => F(_, typeof r != "symbol" ? r + "" : r, s); import { GLTFLoader as x } from "three/examples/jsm/loaders/GLTFLoader.js"; import { USDLoader as G } from "three/examples/jsm/loaders/USDLoader.js"; import { S as B } from "./FileTypes-Ck6z0LqE.mjs"; import { Group as C, BufferGeometry as W, BufferAttribute as O, MeshStandardMaterial as v, Mesh as j } from "three/webgpu"; import "three/examples/jsm/loaders/HDRLoader.js"; import "three/tsl"; import { g as H, i as z } from "./isFileTypeSupported-DPjSWSnx.mjs"; import { F as P, P as M } from "./parse-error-DfOPyLWM.mjs"; import { DRACOLoader as Y } from "three/examples/jsm/loaders/DRACOLoader.js"; import { A as S } from "./AssetCache-w3B0LIUw.mjs"; function J() { let _, r; onmessage = function(e) { const n = e.data; switch (n.type) { case "init": _ = n.decoderConfig, r = new Promise(function(i) { _.onModuleLoaded = function(f) { i({ draco: f }); }, DracoDecoderModule(_); }); break; case "decode": const c = n.buffer, d = n.taskConfig; r.then((i) => { const f = i.draco, a = new f.Decoder(); try { const l = s( f, a, new Int8Array(c), d ), p = l.attributes.map( (m) => m.array.buffer ); l.index && p.push(l.index.array.buffer), self.postMessage( { type: "decode", id: n.id, geometry: l }, p ); } catch (l) { console.error(l), self.postMessage({ type: "error", id: n.id, error: l.message }); } finally { f.destroy(a); } }); break; } }; function s(e, n, c, d) { const i = d.attributeIDs, f = d.attributeTypes; let a, l; const p = n.GetEncodedGeometryType(c); if (p === e.TRIANGULAR_MESH) a = new e.Mesh(), l = n.DecodeArrayToMesh( c, c.byteLength, a ); else if (p === e.POINT_CLOUD) a = new e.PointCloud(), l = n.DecodeArrayToPointCloud( c, c.byteLength, a ); else throw new Error("THREE.DRACOLoader: Unexpected geometry type."); if (!l.ok() || a.ptr === 0) throw new Error( "THREE.DRACOLoader: Decoding failed: " + l.error_msg() ); const m = { index: null, attributes: [] }; for (const g in i) { const E = self[f[g]]; let w, A; if (d.useUniqueIDs) A = i[g], w = n.GetAttributeByUniqueId( a, A ); else { if (A = n.GetAttributeId( a, e[i[g]] ), A === -1) continue; w = n.GetAttribute(a, A); } const y = o( e, n, a, g, E, w ); g === "color" && (y.vertexColorSpace = d.vertexColorSpace), m.attributes.push(y); } return p === e.TRIANGULAR_MESH && (m.index = t(e, n, a)), e.destroy(a), m; } function t(e, n, c) { const i = c.num_faces() * 3, f = i * 4, a = e._malloc(f); n.GetTrianglesUInt32Array(c, f, a); const l = new Uint32Array( e.HEAPF32.buffer, a, i ).slice(); return e._free(a), { array: l, itemSize: 1 }; } function o(e, n, c, d, i, f) { const a = c.num_points(), l = f.num_components(), p = u(e, i), m = l * i.BYTES_PER_ELEMENT, g = Math.ceil(m / 4) * 4, E = g / i.BYTES_PER_ELEMENT, w = a * m, A = a * g, y = e._malloc(w); n.GetAttributeDataArrayForAllPoints( c, f, p, w, y ); const R = new i( e.HEAPF32.buffer, y, w / i.BYTES_PER_ELEMENT ); let D; if (m === g) D = R.slice(); else { D = new i( A / i.BYTES_PER_ELEMENT ); let I = 0; for (let T = 0, N = R.length; T < N; T += l) { for (let L = 0; L < l; L++) D[I + L] = R[T + L]; I += E; } } return e._free(y), { name: d, count: a, itemSize: l, array: D, stride: E }; } function u(e, n) { switch (n) { case Float32Array: return e.DT_FLOAT32; case Int8Array: return e.DT_INT8; case Int16Array: return e.DT_INT16; case Int32Array: return e.DT_INT32; case Uint8Array: return e.DT_UINT8; case Uint16Array: return e.DT_UINT16; case Uint32Array: return e.DT_UINT32; } } } const b = { LOAD_DRACO_JS_DECODER: async () => (await import("three/examples/jsm/libs/draco/draco_decoder.js?raw")).default, LOAD_DRACO_WASM_WRAPPER: async () => (await import("three/examples/jsm/libs/draco/draco_wasm_wrapper.js?raw")).default, LOAD_DRACO_WASM_DECODER: async () => { const _ = (await import("three/examples/jsm/libs/draco/draco_decoder.wasm?url")).default; return await (await fetch(_)).arrayBuffer(); } }; class $ extends Y { constructor() { super(...arguments); h(this, "decoderPending", null); h(this, "decoderConfig", { type: "js", wasmBinary: null }); h(this, "workerSourceURL", ""); } async _initDecoder() { if (this.decoderPending) return this.decoderPending; const s = typeof WebAssembly != "object" || this.decoderConfig.type === "js", t = []; return s ? t.push( b.LOAD_DRACO_JS_DECODER() ) : (t.push( b.LOAD_DRACO_WASM_WRAPPER() ), t.push( b.LOAD_DRACO_WASM_DECODER() )), this.decoderPending = Promise.all(t).then( (o) => { const u = o[0]; s || (this.decoderConfig.wasmBinary = o[1]); const e = J.toString(), n = [ "/* draco decoder */", u, "", "/* worker */", e.substring(e.indexOf("{") + 1, e.lastIndexOf("}")) ].join(` `); this.workerSourceURL = URL.createObjectURL(new Blob([n])); } ), this.decoderPending; } } function q() { let _ = null, r = null; const s = [ [ /'CONFIG_CONTROL_DESIGN'\s*\)/g, "'AP203_CONFIGURATION_CONTROLLED_3D_DESIGN_OF_MECHANICAL_PARTS_AND_ASSEMBLIES_MIM_LF')" ], [ /'AP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF\.\s*\{[\s\S]*?\}\s*'/g, "'AP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF'" ] ]; function t() { return _ || (_ = occtimportjs({ // eslint-disable-line no-undef locateFile: function() { return r; } })), _; } function o(e) { for (var n = new TextDecoder("utf-8", { fatal: !1 }), c = new TextEncoder(), d = n.decode(e), i = 0; i < s.length; i++) { var f = s[i][0], a = s[i][1]; d = d.replace(f, a); } return new Uint8Array(c.encode(d)); } function u(e, n) { var c = o(n); try { var d = e.ReadStepFile(c, null); if (d.success && d.root) return d; } catch { } try { return e.ReadStepFile(n, null); } catch { return { success: !1, root: { meshes: [], children: [] }, meshes: [] }; } } onmessage = async function(e) { var n = e.data; switch (n.type) { case "init": r = n.wasmUrl; break; case "parse": try { var c = await t(), d = new Uint8Array(n.buffer), i = n.fileType, f; if (i === "step" || i === "stp" ? f = u(c, d) : f = c.ReadIgesFile(d, null), !f.success || !f.root) { self.postMessage({ type: "error", id: n.id, error: "Failed to parse CAD file" }); return; } self.postMessage({ type: "result", id: n.id, result: f }); } catch (a) { self.postMessage({ type: "error", id: n.id, error: a instanceof Error ? a.message : String(a) }); } break; } }; } const U = { LOAD_OCCT_JS: async () => (await import("./occt-import-js-D-bjjBtk.mjs")).default, LOAD_OCCT_WASM_URL: async () => (await import("./occt-import-js-ekuHaP1Z.mjs")).default }; class V { constructor() { h(this, "_workerPending", null); h(this, "_worker", null); h(this, "_nextId", 0); h(this, "_pending", /* @__PURE__ */ new Map()); } /** * Create (or return existing) blob-URL worker. * Loads occt-import-js JS as raw text, concatenates with STEPWorker * function body, and creates a classic (non-module) worker. */ _getWorker() { return this._workerPending ? this._workerPending : (this._workerPending = (async () => { const [ r, s ] = await Promise.all([ U.LOAD_OCCT_JS(), U.LOAD_OCCT_WASM_URL() ]), t = q.toString(), o = [ "/* occt-import-js */", r, "", "/* step worker */", t.substring(t.indexOf("{") + 1, t.lastIndexOf("}")) ].join(` `), u = URL.createObjectURL(new Blob([o])), e = new Worker(u), n = new URL(s, window.location.href).href; return e.postMessage({ type: "init", wasmUrl: n }), e.onmessage = (c) => { const { type: d, id: i, result: f, error: a } = c.data, l = this._pending.get(i); if (l) if (this._pending.delete(i), d === "result") try { l.resolve(this._buildScene(f)); } catch (p) { l.reject( p instanceof Error ? p : new Error(String(p)) ); } else l.reject(new Error(a ?? "Worker error")); }, e.onerror = (c) => { for (const [ , { reject: d } ] of this._pending) d(new Error(c.message ?? "Worker error")); this._pending.clear(); }, this._worker = e, e; })(), this._workerPending); } /** * Parse STEP or IGES file content and return a Three.js Object3D */ async parseAsync(r, s) { const t = this._nextId++, o = await this._getWorker(); return new Promise((u, e) => { this._pending.set(t, { resolve: u, reject: e }); const n = r.slice(0); o.postMessage({ type: "parse", id: t, buffer: n, fileType: s }, [ n ]); }); } /** * Dispose the worker. Call when the loader is no longer needed. */ dispose() { if (this._worker) { for (const [ , { reject: r } ] of this._pending) r(new Error("STEPLoader disposed")); this._pending.clear(), this._worker.terminate(), this._worker = null, this._workerPending = null; } } _buildScene(r) { const s = new C(); return s.name = r.root.name ?? "CAD Model", this._buildNode(r.root, r.meshes, s), s.rotation.x = -Math.PI / 2, s.rotation.z = Math.PI / 2, s; } _buildNode(r, s, t) { const o = new C(); o.name = r.name ?? "Part"; for (const u of r.meshes) { const e = s[u]; if (e != null && e.attributes) { const n = this._createMesh(e); o.add(n); } } for (const u of r.children) this._buildNode(u, s, o); t.add(o); } _createMesh(r) { var d, i; const { position: s, normal: t } = r.attributes, o = r.index ?? r.attributes.index, u = new W(); u.setAttribute( "position", new O(new Float32Array(s.array), 3) ), (d = t == null ? void 0 : t.array) != null && d.length ? u.setAttribute( "normal", new O(new Float32Array(t.array), 3) ) : u.computeVertexNormals(), (i = o == null ? void 0 : o.array) != null && i.length && u.setIndex( new O(new Uint32Array(o.array), 1) ); const e = r.color, n = new v({ metalness: 0.3, roughness: 0.6 }); e && e.length >= 3 ? n.color.setRGB(e[0], e[1], e[2]) : n.color.setHex(13421772); const c = new j(u, n); return c.name = r.name ?? "Mesh", c.castShadow = !0, c.receiveShadow = !0, c; } } class ae { constructor() { h(this, "_gltfLoader"); h(this, "_usdLoader"); h(this, "_stepLoader"); const r = new $(); r.setDecoderConfig({ type: "wasm" }), this._gltfLoader = new x(), this._gltfLoader.setDRACOLoader(r), this._usdLoader = new G(), this._stepLoader = new V(); } async load(r, s) { let t; if (s) t = s; else if (t = H(r), t.length === 0 && (t = await this._detectFileTypeFromContent(r), t.length === 0)) throw new P( "No file extension found in URI", "" ); if (!z(t)) throw new P( `Unsupported file type: ${t}. Supported types: ${B.join(", ")}`, t ); const o = S.read(r); if (o) return o.arrayBuffer ? this._parse(o.arrayBuffer, t) : o.promise.then((n) => this._parse(n, t)); const e = await S.create(r).load(); return this._parse(e, t); } /** * Detects file type from content (magic bytes) * @param uri - The URI to load and detect * @returns The detected file extension or empty string if detection fails */ async _detectFileTypeFromContent(r) { try { const s = S.read(r); let t; s ? s.arrayBuffer ? t = s.arrayBuffer : t = await s.promise : t = await S.create(r).load(); const o = new Uint8Array(t); return o.length >= 12 && String.fromCharCode( o[0], o[1], o[2], o[3] ) === "glTF" ? o[12] === 0 ? "glb" : "gltf" : o.length >= 4 && o[0] === 80 && // 'P' o[1] === 75 && // 'K' (o[2] === 3 || o[2] === 5) && (o[3] === 4 || o[3] === 6) ? "usdz" : o.length >= 20 && new TextDecoder("ascii").decode( o.subarray(0, 20) ).startsWith("ISO-10303-21") ? "step" : o.length >= 80 && o[72] === 83 ? "iges" : ""; } catch { return ""; } } /** * parse function for the chunk * @param arrayBuffer - the array buffer to parse, will be provided within the chunk * @param type - the file type of the array buffer * @returns the parsed object, will be stored within the chunk */ async _parse(r, s) { try { switch (s) { case "glb": case "gltf": { const t = await this._gltfLoader.parseAsync( r, "" ); return t.scene.animations = t.animations, t.scene; } case "usdz": { const t = this._usdLoader.parse(r); return t.animations = [], t; } case "step": case "stp": { const t = await this._stepLoader.parseAsync( r, s ); return t.animations = [], t; } case "iges": case "igs": { const t = await this._stepLoader.parseAsync( r, s ); return t.animations = [], t; } } } catch (t) { throw t instanceof Error ? new M( `Failed to parse ${s} file: ${t.message}`, t ) : new M(`Failed to parse ${s} file`); } } } export { ae as A, J as D, $ as a };