@ifc-lite/viewer 1.17.2 → 1.17.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +30 -29
- package/.turbo/turbo-typecheck.log +1 -42
- package/CHANGELOG.md +9 -0
- package/dist/assets/arrow-DJf2ErbF.js +20 -0
- package/dist/assets/basketViewActivator-aojwdomq.js +1 -0
- package/dist/assets/bcf-D5-QWGO9.js +281 -0
- package/dist/assets/{browser-BDShTXzi.js → browser-CKs-FY1P.js} +1 -1
- package/dist/assets/drawing-2d-gWfpdfYe.js +257 -0
- package/dist/assets/epsg-index.generated-BjJrt_0S.js +1 -0
- package/dist/assets/exporters-C_6J153K.js +79896 -0
- package/dist/assets/geometry.worker-Nz9_YIqh.js +1 -0
- package/dist/assets/ids-B4jTqB1O.js +1 -0
- package/dist/assets/{ifc-lite_bg-FNRmpSvM.wasm → ifc-lite_bg-eSkBTizQ.wasm} +0 -0
- package/dist/assets/index-jhBr1wbn.js +101666 -0
- package/dist/assets/index-pbE7itQS.css +1 -0
- package/dist/assets/lens-CSASnhAL.js +1 -0
- package/dist/assets/maplibre-gl-BpvwNKKy.js +811 -0
- package/dist/assets/{native-bridge-Crsb7TKz.js → native-bridge-DSIyEYXG.js} +6 -4
- package/dist/assets/{arrow2-bb-jcVEo.js → parquet-CEXmQNRO.js} +2 -2
- package/dist/assets/sandbox-B79eavQ3.js +5933 -0
- package/dist/assets/server-client-D3bUPJJc.js +626 -0
- package/dist/assets/wasm-bridge-B0J07fZZ.js +1 -0
- package/dist/assets/zip-B-jFFAGa.js +12 -0
- package/dist/index.html +11 -2
- package/package.json +24 -19
- package/src/components/viewer/ExportChangesButton.tsx +18 -3
- package/src/components/viewer/ExportDialog.tsx +16 -3
- package/src/components/viewer/HierarchyPanel.tsx +6 -6
- package/src/components/viewer/PropertiesPanel.tsx +96 -60
- package/src/components/viewer/Section2DPanel.tsx +3 -2
- package/src/components/viewer/ViewportContainer.tsx +5 -4
- package/src/components/viewer/hierarchy/treeDataBuilder.ts +2 -1
- package/src/components/viewer/properties/EpsgLookupDialog.tsx +418 -0
- package/src/components/viewer/properties/GeoreferencingPanel.tsx +591 -0
- package/src/components/viewer/properties/LocationMap.tsx +289 -0
- package/src/components/viewer/properties/ModelMetadataPanel.tsx +3 -70
- package/src/hooks/bcfIdLookup.ts +13 -11
- package/src/hooks/ids/idsColorSystem.ts +3 -8
- package/src/hooks/useIDS.ts +31 -16
- package/src/hooks/useIfcFederation.ts +2 -2
- package/src/lib/geo/kmz-exporter.ts +112 -0
- package/src/lib/geo/reproject.ts +244 -0
- package/src/lib/lens/adapter.ts +3 -1
- package/src/main.tsx +1 -0
- package/src/sdk/adapters/export-adapter.ts +14 -1
- package/src/sdk/adapters/viewer-adapter.ts +5 -9
- package/src/sdk/adapters/visibility-adapter.ts +6 -9
- package/src/store/basketVisibleSet.ts +3 -4
- package/src/store/globalId.ts +79 -0
- package/src/store/index.ts +1 -0
- package/src/store/slices/mutationSlice.ts +178 -0
- package/src/store/slices/pinboardSlice.ts +4 -8
- package/vite.config.ts +17 -0
- package/dist/assets/Arrow.dom-BhOg9lpn.js +0 -20
- package/dist/assets/arrow2_bg-BlXl-cSQ.js +0 -1
- package/dist/assets/basketViewActivator-BRG5DBmM.js +0 -1
- package/dist/assets/geometry.worker-kgiT_Qhh.js +0 -1
- package/dist/assets/index-B1Ecw4AU.js +0 -189756
- package/dist/assets/index-Ba4eoTe7.css +0 -1
- package/dist/assets/index-CrgYBjTn.js +0 -229
- package/dist/assets/module-6F3E5H7Y-tx0BadV3.js +0 -6
- package/dist/assets/wasm-bridge-mJUhb7uk.js +0 -1
|
@@ -0,0 +1,626 @@
|
|
|
1
|
+
import { _ as de, __tla as __tla_0 } from "./exporters-C_6J153K.js";
|
|
2
|
+
let We, je;
|
|
3
|
+
let __tla = Promise.all([
|
|
4
|
+
(()=>{
|
|
5
|
+
try {
|
|
6
|
+
return __tla_0;
|
|
7
|
+
} catch {}
|
|
8
|
+
})()
|
|
9
|
+
]).then(async ()=>{
|
|
10
|
+
let Ae = !1, fe = null;
|
|
11
|
+
async function _e() {
|
|
12
|
+
if (Ae && fe) return fe;
|
|
13
|
+
console.log("[parquet-decoder] Starting WASM initialization...");
|
|
14
|
+
let n;
|
|
15
|
+
try {
|
|
16
|
+
if (n = await de(()=>import("./parquet-CEXmQNRO.js").then((e)=>e.a), []), console.log("[parquet-decoder] Imported ESM build"), typeof n.default == "function") {
|
|
17
|
+
console.log("[parquet-decoder] Calling ESM init to load WASM...");
|
|
18
|
+
const o = (await de(()=>import("./parquet-CEXmQNRO.js").then((r)=>r.b), [])).default;
|
|
19
|
+
console.log("[parquet-decoder] Loading WASM from:", o), await n.default(o), console.log("[parquet-decoder] ESM WASM initialized");
|
|
20
|
+
}
|
|
21
|
+
if (typeof n.readParquet == "function") return fe = n, Ae = !0, console.log("[parquet-decoder] ESM build ready with readParquet"), n;
|
|
22
|
+
console.warn("[parquet-decoder] ESM build initialized but readParquet not found");
|
|
23
|
+
} catch (e) {
|
|
24
|
+
console.warn("[parquet-decoder] ESM import failed:", e);
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
if (n = await de(()=>import("./parquet-CEXmQNRO.js").then((e)=>e.a), []), typeof n.default == "function") {
|
|
28
|
+
console.log("[parquet-decoder] Trying web init with node_modules path...");
|
|
29
|
+
const e = [
|
|
30
|
+
"/node_modules/parquet-wasm/esm/arrow2_bg.wasm",
|
|
31
|
+
"./node_modules/parquet-wasm/esm/arrow2_bg.wasm"
|
|
32
|
+
];
|
|
33
|
+
for (const o of e)try {
|
|
34
|
+
const r = await fetch(o);
|
|
35
|
+
if (r.ok && (console.log("[parquet-decoder] Found WASM at:", o), await n.default(r), typeof n.readParquet == "function")) return fe = n, Ae = !0, console.log("[parquet-decoder] Web init successful"), n;
|
|
36
|
+
} catch {}
|
|
37
|
+
}
|
|
38
|
+
} catch (e) {
|
|
39
|
+
console.warn("[parquet-decoder] Web init failed:", e);
|
|
40
|
+
}
|
|
41
|
+
throw new Error("parquet-wasm: Could not load WASM module. Ensure parquet-wasm is installed and WASM files are accessible.");
|
|
42
|
+
}
|
|
43
|
+
async function ve(n) {
|
|
44
|
+
const e = await _e(), o = new DataView(n);
|
|
45
|
+
let r = 0;
|
|
46
|
+
const a = o.getUint32(r, !0);
|
|
47
|
+
r += 4;
|
|
48
|
+
const t = new Uint8Array(n, r, a);
|
|
49
|
+
r += a;
|
|
50
|
+
const i = o.getUint32(r, !0);
|
|
51
|
+
r += 4;
|
|
52
|
+
const l = new Uint8Array(n, r, i);
|
|
53
|
+
r += i;
|
|
54
|
+
const c = o.getUint32(r, !0);
|
|
55
|
+
r += 4;
|
|
56
|
+
const m = new Uint8Array(n, r, c), y = e.readParquet(t), f = e.readParquet(l), b = e.readParquet(m), u = await de(()=>import("./arrow-DJf2ErbF.js").then((_)=>_.A), []), d = u.tableFromIPC(y.intoIPCStream()), q = u.tableFromIPC(f.intoIPCStream()), $ = u.tableFromIPC(b.intoIPCStream()), E = d.getChild("express_id")?.toArray(), C = d.getChild("ifc_type"), S = d.getChild("vertex_start")?.toArray(), F = d.getChild("vertex_count")?.toArray(), T = d.getChild("index_start")?.toArray(), x = d.getChild("index_count")?.toArray(), D = d.getChild("color_r")?.toArray(), I = d.getChild("color_g")?.toArray(), v = d.getChild("color_b")?.toArray(), P = d.getChild("color_a")?.toArray(), w = q.getChild("x")?.toArray(), K = q.getChild("y")?.toArray(), N = q.getChild("z")?.toArray(), z = q.getChild("nx")?.toArray(), G = q.getChild("ny")?.toArray(), R = q.getChild("nz")?.toArray(), X = $.getChild("i0")?.toArray(), O = $.getChild("i1")?.toArray(), H = $.getChild("i2")?.toArray(), ae = E.length, L = new Array(ae);
|
|
57
|
+
for(let _ = 0; _ < ae; _++){
|
|
58
|
+
const ne = S[_], J = F[_], me = T[_], se = x[_], Y = new Float32Array(J * 3);
|
|
59
|
+
for(let h = 0; h < J; h++){
|
|
60
|
+
const g = ne + h;
|
|
61
|
+
Y[h * 3] = w[g], Y[h * 3 + 1] = K[g], Y[h * 3 + 2] = N[g];
|
|
62
|
+
}
|
|
63
|
+
const k = new Float32Array(J * 3);
|
|
64
|
+
for(let h = 0; h < J; h++){
|
|
65
|
+
const g = ne + h;
|
|
66
|
+
k[h * 3] = z[g], k[h * 3 + 1] = G[g], k[h * 3 + 2] = R[g];
|
|
67
|
+
}
|
|
68
|
+
const ie = se / 3, Z = me / 3, V = new Uint32Array(se);
|
|
69
|
+
for(let h = 0; h < ie; h++){
|
|
70
|
+
const g = Z + h;
|
|
71
|
+
V[h * 3] = X[g], V[h * 3 + 1] = O[g], V[h * 3 + 2] = H[g];
|
|
72
|
+
}
|
|
73
|
+
L[_] = {
|
|
74
|
+
express_id: E[_],
|
|
75
|
+
ifc_type: C?.get(_) ?? "Unknown",
|
|
76
|
+
positions: Y,
|
|
77
|
+
normals: k,
|
|
78
|
+
indices: V,
|
|
79
|
+
color: [
|
|
80
|
+
D[_],
|
|
81
|
+
I[_],
|
|
82
|
+
v[_],
|
|
83
|
+
P[_]
|
|
84
|
+
]
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
return L;
|
|
88
|
+
}
|
|
89
|
+
async function ge() {
|
|
90
|
+
try {
|
|
91
|
+
return await _e(), !0;
|
|
92
|
+
} catch (n) {
|
|
93
|
+
return console.warn("[parquet-decoder] Parquet WASM initialization failed:", n), !1;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
async function Re(n, e = 1e4) {
|
|
97
|
+
const o = await _e(), r = await de(()=>import("./arrow-DJf2ErbF.js").then((M)=>M.A), []), a = new DataView(n);
|
|
98
|
+
let t = 0;
|
|
99
|
+
const i = a.getUint8(t);
|
|
100
|
+
if (t += 1, i !== 2) throw new Error(`Unsupported optimized Parquet version: ${i}`);
|
|
101
|
+
const l = a.getUint8(t);
|
|
102
|
+
t += 1;
|
|
103
|
+
const c = (l & 1) !== 0, m = a.getUint32(t, !0);
|
|
104
|
+
t += 4;
|
|
105
|
+
const y = a.getUint32(t, !0);
|
|
106
|
+
t += 4;
|
|
107
|
+
const f = a.getUint32(t, !0);
|
|
108
|
+
t += 4;
|
|
109
|
+
const b = a.getUint32(t, !0);
|
|
110
|
+
t += 4;
|
|
111
|
+
const u = a.getUint32(t, !0);
|
|
112
|
+
t += 4;
|
|
113
|
+
const d = new Uint8Array(n, t, m);
|
|
114
|
+
t += m;
|
|
115
|
+
const q = new Uint8Array(n, t, y);
|
|
116
|
+
t += y;
|
|
117
|
+
const $ = new Uint8Array(n, t, f);
|
|
118
|
+
t += f;
|
|
119
|
+
const E = new Uint8Array(n, t, b);
|
|
120
|
+
t += b;
|
|
121
|
+
const C = new Uint8Array(n, t, u), S = o.readParquet(d), F = o.readParquet(q), T = o.readParquet($), x = o.readParquet(E), D = o.readParquet(C), I = r.tableFromIPC(S.intoIPCStream()), v = r.tableFromIPC(F.intoIPCStream()), P = r.tableFromIPC(T.intoIPCStream()), w = r.tableFromIPC(x.intoIPCStream()), K = r.tableFromIPC(D.intoIPCStream()), N = I.getChild("entity_id")?.toArray(), z = I.getChild("ifc_type"), G = I.getChild("mesh_index")?.toArray(), R = I.getChild("material_index")?.toArray(), X = v.getChild("vertex_offset")?.toArray(), O = v.getChild("vertex_count")?.toArray(), H = v.getChild("index_offset")?.toArray(), ae = v.getChild("index_count")?.toArray(), L = P.getChild("r")?.toArray(), _ = P.getChild("g")?.toArray(), ne = P.getChild("b")?.toArray(), J = P.getChild("a")?.toArray(), me = w.getChild("x")?.toArray(), se = w.getChild("y")?.toArray(), Y = w.getChild("z")?.toArray(), k = c ? w.getChild("nx")?.toArray() : null, ie = c ? w.getChild("ny")?.toArray() : null, Z = c ? w.getChild("nz")?.toArray() : null, V = K.getChild("i")?.toArray(), h = N.length, g = new Array(h), p = 1 / e;
|
|
122
|
+
for(let M = 0; M < h; M++){
|
|
123
|
+
const ce = G[M], ee = R[M], pe = X[ce], te = O[ce], he = H[ce], le = ae[ce], re = new Float32Array(te * 3);
|
|
124
|
+
for(let A = 0; A < te; A++){
|
|
125
|
+
const W = pe + A;
|
|
126
|
+
re[A * 3] = me[W] * p, re[A * 3 + 1] = se[W] * p, re[A * 3 + 2] = Y[W] * p;
|
|
127
|
+
}
|
|
128
|
+
let B;
|
|
129
|
+
if (c && k && ie && Z) {
|
|
130
|
+
B = new Float32Array(te * 3);
|
|
131
|
+
for(let A = 0; A < te; A++){
|
|
132
|
+
const W = pe + A;
|
|
133
|
+
B[A * 3] = k[W], B[A * 3 + 1] = ie[W], B[A * 3 + 2] = Z[W];
|
|
134
|
+
}
|
|
135
|
+
} else B = Ve(re, V.slice(he, he + le));
|
|
136
|
+
const ue = new Uint32Array(le);
|
|
137
|
+
for(let A = 0; A < le; A++)ue[A] = V[he + A];
|
|
138
|
+
g[M] = {
|
|
139
|
+
express_id: N[M],
|
|
140
|
+
ifc_type: z?.get(M) ?? "Unknown",
|
|
141
|
+
positions: re,
|
|
142
|
+
normals: B,
|
|
143
|
+
indices: ue,
|
|
144
|
+
color: [
|
|
145
|
+
L[ee] / 255,
|
|
146
|
+
_[ee] / 255,
|
|
147
|
+
ne[ee] / 255,
|
|
148
|
+
J[ee] / 255
|
|
149
|
+
]
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
return g;
|
|
153
|
+
}
|
|
154
|
+
function Ve(n, e) {
|
|
155
|
+
const o = n.length / 3, r = new Float32Array(o * 3).fill(0), a = e.length / 3;
|
|
156
|
+
for(let t = 0; t < a; t++){
|
|
157
|
+
const i = e[t * 3], l = e[t * 3 + 1], c = e[t * 3 + 2], m = n[i * 3], y = n[i * 3 + 1], f = n[i * 3 + 2], b = n[l * 3], u = n[l * 3 + 1], d = n[l * 3 + 2], q = n[c * 3], $ = n[c * 3 + 1], E = n[c * 3 + 2], C = b - m, S = u - y, F = d - f, T = q - m, x = $ - y, D = E - f, I = S * D - F * x, v = F * T - C * D, P = C * x - S * T;
|
|
158
|
+
r[i * 3] += I, r[i * 3 + 1] += v, r[i * 3 + 2] += P, r[l * 3] += I, r[l * 3 + 1] += v, r[l * 3 + 2] += P, r[c * 3] += I, r[c * 3 + 1] += v, r[c * 3 + 2] += P;
|
|
159
|
+
}
|
|
160
|
+
for(let t = 0; t < o; t++){
|
|
161
|
+
const i = r[t * 3], l = r[t * 3 + 1], c = r[t * 3 + 2], m = Math.sqrt(i * i + l * l + c * c);
|
|
162
|
+
m > 0 && (r[t * 3] /= m, r[t * 3 + 1] /= m, r[t * 3 + 2] /= m);
|
|
163
|
+
}
|
|
164
|
+
return r;
|
|
165
|
+
}
|
|
166
|
+
async function be(n) {
|
|
167
|
+
const e = n instanceof File ? n.stream() : new Blob([
|
|
168
|
+
n
|
|
169
|
+
]).stream(), o = new CompressionStream("gzip"), r = e.pipeThrough(o);
|
|
170
|
+
return new Response(r).blob();
|
|
171
|
+
}
|
|
172
|
+
async function Fe(n) {
|
|
173
|
+
const e = n instanceof File ? await n.arrayBuffer() : n, o = await crypto.subtle.digest("SHA-256", e);
|
|
174
|
+
return Array.from(new Uint8Array(o)).map((r)=>r.toString(16).padStart(2, "0")).join("");
|
|
175
|
+
}
|
|
176
|
+
We = class {
|
|
177
|
+
constructor(e){
|
|
178
|
+
this.baseUrl = e.baseUrl.replace(/\/$/, ""), this.timeout = e.timeout ?? 3e5;
|
|
179
|
+
}
|
|
180
|
+
async health() {
|
|
181
|
+
const e = await fetch(`${this.baseUrl}/api/v1/health`, {
|
|
182
|
+
signal: AbortSignal.timeout(this.timeout)
|
|
183
|
+
});
|
|
184
|
+
if (!e.ok) throw await this.handleError(e);
|
|
185
|
+
return e.json();
|
|
186
|
+
}
|
|
187
|
+
async parse(e) {
|
|
188
|
+
const o = await be(e), r = e instanceof File ? e.name : "model.ifc", a = new FormData;
|
|
189
|
+
a.append("file", o, r);
|
|
190
|
+
const t = await fetch(`${this.baseUrl}/api/v1/parse`, {
|
|
191
|
+
method: "POST",
|
|
192
|
+
body: a,
|
|
193
|
+
signal: AbortSignal.timeout(this.timeout)
|
|
194
|
+
});
|
|
195
|
+
if (!t.ok) throw await this.handleError(t);
|
|
196
|
+
return t.json();
|
|
197
|
+
}
|
|
198
|
+
async parseParquet(e) {
|
|
199
|
+
if (!await ge()) throw new Error("Parquet parsing requires parquet-wasm and apache-arrow. Install them with: npm install parquet-wasm apache-arrow");
|
|
200
|
+
const r = performance.now(), a = await Fe(e), t = performance.now() - r;
|
|
201
|
+
console.log(`[client] Computed file hash in ${t.toFixed(0)}ms: ${a.substring(0, 16)}...`);
|
|
202
|
+
const i = performance.now(), l = await fetch(`${this.baseUrl}/api/v1/cache/check/${a}`, {
|
|
203
|
+
method: "GET",
|
|
204
|
+
signal: AbortSignal.timeout(5e3)
|
|
205
|
+
}), c = performance.now() - i;
|
|
206
|
+
return l.ok ? (console.log(`[client] Cache HIT (check: ${c.toFixed(0)}ms) - skipping upload`), this.fetchCachedGeometry(a)) : (console.log(`[client] Cache MISS (check: ${c.toFixed(0)}ms) - uploading file`), this.uploadAndProcessParquet(e, a));
|
|
207
|
+
}
|
|
208
|
+
async parseParquetStream(e, o) {
|
|
209
|
+
if (!await ge()) throw new Error("Parquet streaming requires parquet-wasm and apache-arrow. Install them with: npm install parquet-wasm apache-arrow");
|
|
210
|
+
const a = e instanceof File ? e.size : e.byteLength, t = e instanceof File ? e.name : "model.ifc", i = performance.now(), l = await Fe(e), c = performance.now() - i;
|
|
211
|
+
console.log(`[client] Stream: computed hash in ${c.toFixed(0)}ms: ${l.substring(0, 16)}...`);
|
|
212
|
+
const m = performance.now(), y = await fetch(`${this.baseUrl}/api/v1/cache/check/${l}`, {
|
|
213
|
+
method: "GET",
|
|
214
|
+
signal: AbortSignal.timeout(5e3)
|
|
215
|
+
}), f = performance.now() - m;
|
|
216
|
+
if (y.ok) {
|
|
217
|
+
console.log(`[client] Stream: Cache HIT (check: ${f.toFixed(0)}ms) - fetching cached geometry`);
|
|
218
|
+
const x = await this.fetchCachedGeometry(l), D = performance.now();
|
|
219
|
+
return o({
|
|
220
|
+
meshes: x.meshes,
|
|
221
|
+
batch_number: 1,
|
|
222
|
+
decode_time_ms: performance.now() - D
|
|
223
|
+
}), {
|
|
224
|
+
cache_key: x.cache_key,
|
|
225
|
+
total_meshes: x.meshes.length,
|
|
226
|
+
stats: x.stats,
|
|
227
|
+
metadata: x.metadata
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
console.log(`[client] Stream: Cache MISS (check: ${f.toFixed(0)}ms) - starting stream for ${t} (${(a / 1024 / 1024).toFixed(1)}MB)`);
|
|
231
|
+
const b = new FormData;
|
|
232
|
+
b.append("file", e instanceof File ? e : new Blob([
|
|
233
|
+
e
|
|
234
|
+
]), t);
|
|
235
|
+
const u = performance.now(), d = await fetch(`${this.baseUrl}/api/v1/parse/parquet-stream`, {
|
|
236
|
+
method: "POST",
|
|
237
|
+
body: b,
|
|
238
|
+
signal: AbortSignal.timeout(this.timeout)
|
|
239
|
+
});
|
|
240
|
+
if (!d.ok) throw await this.handleError(d);
|
|
241
|
+
if (!d.body) throw new Error("No response body for streaming");
|
|
242
|
+
const q = d.body.getReader(), $ = new TextDecoder;
|
|
243
|
+
let E = "", C = "", S = 0, F = null, T = null;
|
|
244
|
+
for(;;){
|
|
245
|
+
const { done: x, value: D } = await q.read();
|
|
246
|
+
if (x) break;
|
|
247
|
+
E += $.decode(D, {
|
|
248
|
+
stream: !0
|
|
249
|
+
});
|
|
250
|
+
const I = E.split(`
|
|
251
|
+
`);
|
|
252
|
+
E = I.pop() || "";
|
|
253
|
+
for (const v of I){
|
|
254
|
+
if (!v.startsWith("data:")) continue;
|
|
255
|
+
const P = v.slice(5).trim();
|
|
256
|
+
if (P) try {
|
|
257
|
+
const w = JSON.parse(P);
|
|
258
|
+
switch(w.type){
|
|
259
|
+
case "start":
|
|
260
|
+
C = w.cache_key, console.log(`[client] Stream started: ${w.total_estimate} entities, cache_key: ${C.substring(0, 16)}...`);
|
|
261
|
+
break;
|
|
262
|
+
case "progress":
|
|
263
|
+
break;
|
|
264
|
+
case "batch":
|
|
265
|
+
{
|
|
266
|
+
const N = performance.now(), z = atob(w.data), G = new Uint8Array(z.length);
|
|
267
|
+
for(let O = 0; O < z.length; O++)G[O] = z.charCodeAt(O);
|
|
268
|
+
const R = await ve(G.buffer), X = performance.now() - N;
|
|
269
|
+
S += R.length, console.log(`[client] Batch #${w.batch_number}: ${R.length} meshes, decode: ${X.toFixed(0)}ms`), o({
|
|
270
|
+
meshes: R,
|
|
271
|
+
batch_number: w.batch_number,
|
|
272
|
+
decode_time_ms: X
|
|
273
|
+
});
|
|
274
|
+
break;
|
|
275
|
+
}
|
|
276
|
+
case "complete":
|
|
277
|
+
F = w.stats, T = w.metadata;
|
|
278
|
+
const K = performance.now() - u;
|
|
279
|
+
console.log(`[client] Stream complete: ${S} meshes in ${K.toFixed(0)}ms`);
|
|
280
|
+
break;
|
|
281
|
+
case "error":
|
|
282
|
+
throw new Error(`Stream error: ${w.message}`);
|
|
283
|
+
}
|
|
284
|
+
} catch (w) {
|
|
285
|
+
if (w instanceof SyntaxError) console.warn("[client] Failed to parse SSE event:", P);
|
|
286
|
+
else throw w;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
if (!F || !T) throw new Error("Stream ended without complete event");
|
|
291
|
+
return {
|
|
292
|
+
cache_key: C,
|
|
293
|
+
total_meshes: S,
|
|
294
|
+
stats: F,
|
|
295
|
+
metadata: T
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
async fetchCachedGeometry(e) {
|
|
299
|
+
const o = performance.now(), r = await fetch(`${this.baseUrl}/api/v1/cache/geometry/${e}`, {
|
|
300
|
+
method: "GET",
|
|
301
|
+
signal: AbortSignal.timeout(this.timeout)
|
|
302
|
+
});
|
|
303
|
+
if (!r.ok) throw await this.handleError(r);
|
|
304
|
+
const a = performance.now() - o;
|
|
305
|
+
console.log(`[client] Fetched cached geometry in ${a.toFixed(0)}ms`);
|
|
306
|
+
const t = r.headers.get("X-IFC-Metadata");
|
|
307
|
+
if (!t) throw new Error("Missing X-IFC-Metadata header in cached geometry response");
|
|
308
|
+
const i = JSON.parse(t), l = await r.arrayBuffer(), c = l.byteLength;
|
|
309
|
+
return this.parseParquetResponse(l, i, c);
|
|
310
|
+
}
|
|
311
|
+
async uploadAndProcessParquet(e, o) {
|
|
312
|
+
const r = e instanceof File ? e.size : e.byteLength, a = e instanceof File ? e.name : "model.ifc", t = this.baseUrl.includes("localhost") || this.baseUrl.includes("127.0.0.1"), i = r > 50 * 1024 * 1024 || t;
|
|
313
|
+
let l;
|
|
314
|
+
if (i) console.log(`[client] Skipping compression (file: ${(r / 1024 / 1024).toFixed(1)}MB, localhost: ${t})`), l = e instanceof File ? e : new Blob([
|
|
315
|
+
e
|
|
316
|
+
]);
|
|
317
|
+
else {
|
|
318
|
+
const $ = performance.now();
|
|
319
|
+
l = await be(e), console.log(`[client] Compressed in ${(performance.now() - $).toFixed(0)}ms: ${(r / 1024 / 1024).toFixed(1)}MB → ${(l.size / 1024 / 1024).toFixed(1)}MB`);
|
|
320
|
+
}
|
|
321
|
+
const c = new FormData;
|
|
322
|
+
c.append("file", l, a);
|
|
323
|
+
const m = performance.now(), y = await fetch(`${this.baseUrl}/api/v1/parse/parquet`, {
|
|
324
|
+
method: "POST",
|
|
325
|
+
body: c,
|
|
326
|
+
signal: AbortSignal.timeout(this.timeout)
|
|
327
|
+
}), f = performance.now() - m;
|
|
328
|
+
if (console.log(`[client] Upload and processing completed in ${f.toFixed(0)}ms`), !y.ok) throw await this.handleError(y);
|
|
329
|
+
const b = y.headers.get("X-IFC-Metadata");
|
|
330
|
+
if (!b) throw new Error("Missing X-IFC-Metadata header in Parquet response");
|
|
331
|
+
const u = JSON.parse(b);
|
|
332
|
+
u.cache_key !== o && console.warn(`[client] Cache key mismatch: expected ${o.substring(0, 16)}..., got ${u.cache_key.substring(0, 16)}...`);
|
|
333
|
+
const d = await y.arrayBuffer(), q = d.byteLength;
|
|
334
|
+
return this.parseParquetResponse(d, u, q);
|
|
335
|
+
}
|
|
336
|
+
async parseParquetResponse(e, o, r) {
|
|
337
|
+
const a = new DataView(e);
|
|
338
|
+
let t = 0;
|
|
339
|
+
const i = a.getUint32(0, !0), l = i > 0 && i < e.byteLength && i < e.byteLength - 4;
|
|
340
|
+
let c, m;
|
|
341
|
+
if (l) {
|
|
342
|
+
const u = i;
|
|
343
|
+
if (t += 4, u > e.byteLength || u === 0 || t + u > e.byteLength) throw new Error(`Invalid geometry length: ${u}, buffer size: ${e.byteLength}, offset: ${t}`);
|
|
344
|
+
if (c = e.slice(t, t + u), t += u, t < e.byteLength) {
|
|
345
|
+
const d = a.getUint32(t, !0);
|
|
346
|
+
t += 4, d > 0 && t + d <= e.byteLength && (m = e.slice(t, t + d));
|
|
347
|
+
}
|
|
348
|
+
} else console.log("[client] Detected old format (no wrapper), using entire payload as geometry"), c = e, m = void 0;
|
|
349
|
+
const y = performance.now(), f = await ve(c), b = performance.now() - y;
|
|
350
|
+
return {
|
|
351
|
+
cache_key: o.cache_key,
|
|
352
|
+
meshes: f,
|
|
353
|
+
mesh_coordinate_space: o.mesh_coordinate_space,
|
|
354
|
+
site_transform: o.site_transform,
|
|
355
|
+
building_transform: o.building_transform,
|
|
356
|
+
metadata: o.metadata,
|
|
357
|
+
stats: o.stats,
|
|
358
|
+
parquet_stats: {
|
|
359
|
+
payload_size: r,
|
|
360
|
+
decode_time_ms: Math.round(b)
|
|
361
|
+
},
|
|
362
|
+
data_model: m
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
async fetchDataModel(e, o = 10) {
|
|
366
|
+
let r = 100;
|
|
367
|
+
for(let a = 0; a < o; a++)try {
|
|
368
|
+
const t = await fetch(`${this.baseUrl}/api/v1/parse/data-model/${e}`, {
|
|
369
|
+
method: "GET",
|
|
370
|
+
signal: AbortSignal.timeout(3e4)
|
|
371
|
+
});
|
|
372
|
+
if (t.status === 200) {
|
|
373
|
+
const i = await t.arrayBuffer();
|
|
374
|
+
return console.log(`[client] Data model fetched: ${(i.byteLength / 1024 / 1024).toFixed(2)}MB`), i;
|
|
375
|
+
} else if (t.status === 202) console.log(`[client] Data model still processing (attempt ${a + 1}/${o}), waiting ${r}ms...`), await new Promise((i)=>setTimeout(i, r)), r = Math.min(r * 1.5, 2e3);
|
|
376
|
+
else {
|
|
377
|
+
if (t.status === 404) return console.warn(`[client] Data model not found for cache key: ${e}`), null;
|
|
378
|
+
throw new Error(`Unexpected response status: ${t.status}`);
|
|
379
|
+
}
|
|
380
|
+
} catch (t) {
|
|
381
|
+
if (a === o - 1) return console.error("[client] Failed to fetch data model:", t), null;
|
|
382
|
+
await new Promise((i)=>setTimeout(i, r)), r = Math.min(r * 1.5, 2e3);
|
|
383
|
+
}
|
|
384
|
+
return console.warn("[client] Data model fetch timed out after max retries"), null;
|
|
385
|
+
}
|
|
386
|
+
async isParquetSupported() {
|
|
387
|
+
return ge();
|
|
388
|
+
}
|
|
389
|
+
async parseParquetOptimized(e) {
|
|
390
|
+
if (!await ge()) throw new Error("Parquet parsing requires parquet-wasm and apache-arrow. Install them with: npm install parquet-wasm apache-arrow");
|
|
391
|
+
const r = await be(e), a = e instanceof File ? e.name : "model.ifc", t = new FormData;
|
|
392
|
+
t.append("file", r, a);
|
|
393
|
+
const i = await fetch(`${this.baseUrl}/api/v1/parse/parquet/optimized`, {
|
|
394
|
+
method: "POST",
|
|
395
|
+
body: t,
|
|
396
|
+
signal: AbortSignal.timeout(this.timeout)
|
|
397
|
+
});
|
|
398
|
+
if (!i.ok) throw await this.handleError(i);
|
|
399
|
+
const l = i.headers.get("X-IFC-Metadata");
|
|
400
|
+
if (!l) throw new Error("Missing X-IFC-Metadata header in optimized Parquet response");
|
|
401
|
+
const c = JSON.parse(l), m = await i.arrayBuffer(), y = m.byteLength, f = performance.now(), b = await Re(m, c.vertex_multiplier), u = performance.now() - f;
|
|
402
|
+
return {
|
|
403
|
+
cache_key: c.cache_key,
|
|
404
|
+
meshes: b,
|
|
405
|
+
mesh_coordinate_space: c.mesh_coordinate_space,
|
|
406
|
+
site_transform: c.site_transform,
|
|
407
|
+
building_transform: c.building_transform,
|
|
408
|
+
metadata: c.metadata,
|
|
409
|
+
stats: c.stats,
|
|
410
|
+
optimization_stats: c.optimization_stats,
|
|
411
|
+
parquet_stats: {
|
|
412
|
+
payload_size: y,
|
|
413
|
+
decode_time_ms: Math.round(u)
|
|
414
|
+
}
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
async *parseStream(e) {
|
|
418
|
+
const o = new FormData, r = e instanceof File ? e : new Blob([
|
|
419
|
+
e
|
|
420
|
+
], {
|
|
421
|
+
type: "application/octet-stream"
|
|
422
|
+
});
|
|
423
|
+
o.append("file", r, e instanceof File ? e.name : "model.ifc");
|
|
424
|
+
const a = await fetch(`${this.baseUrl}/api/v1/parse/stream`, {
|
|
425
|
+
method: "POST",
|
|
426
|
+
body: o,
|
|
427
|
+
headers: {
|
|
428
|
+
Accept: "text/event-stream"
|
|
429
|
+
}
|
|
430
|
+
});
|
|
431
|
+
if (!a.ok) throw await this.handleError(a);
|
|
432
|
+
if (!a.body) throw new Error("Response body is null");
|
|
433
|
+
const t = a.body.getReader(), i = new TextDecoder;
|
|
434
|
+
let l = "";
|
|
435
|
+
try {
|
|
436
|
+
for(;;){
|
|
437
|
+
const { done: c, value: m } = await t.read();
|
|
438
|
+
if (c) break;
|
|
439
|
+
l += i.decode(m, {
|
|
440
|
+
stream: !0
|
|
441
|
+
});
|
|
442
|
+
const y = l.split(`
|
|
443
|
+
|
|
444
|
+
`);
|
|
445
|
+
l = y.pop() || "";
|
|
446
|
+
for (const f of y)if (f.startsWith("data: ")) try {
|
|
447
|
+
yield JSON.parse(f.slice(6));
|
|
448
|
+
} catch {}
|
|
449
|
+
}
|
|
450
|
+
if (l.startsWith("data: ")) try {
|
|
451
|
+
yield JSON.parse(l.slice(6));
|
|
452
|
+
} catch {}
|
|
453
|
+
} finally{
|
|
454
|
+
t.releaseLock();
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
async getMetadata(e) {
|
|
458
|
+
const o = new FormData;
|
|
459
|
+
o.append("file", e instanceof File ? e : new Blob([
|
|
460
|
+
e
|
|
461
|
+
]), e instanceof File ? e.name : "model.ifc");
|
|
462
|
+
const r = await fetch(`${this.baseUrl}/api/v1/parse/metadata`, {
|
|
463
|
+
method: "POST",
|
|
464
|
+
body: o,
|
|
465
|
+
signal: AbortSignal.timeout(3e4)
|
|
466
|
+
});
|
|
467
|
+
if (!r.ok) throw await this.handleError(r);
|
|
468
|
+
return r.json();
|
|
469
|
+
}
|
|
470
|
+
async getCached(e) {
|
|
471
|
+
const o = await fetch(`${this.baseUrl}/api/v1/cache/${e}`, {
|
|
472
|
+
signal: AbortSignal.timeout(this.timeout)
|
|
473
|
+
});
|
|
474
|
+
if (o.status === 404) return null;
|
|
475
|
+
if (!o.ok) throw await this.handleError(o);
|
|
476
|
+
return o.json();
|
|
477
|
+
}
|
|
478
|
+
async handleError(e) {
|
|
479
|
+
try {
|
|
480
|
+
const o = await e.json();
|
|
481
|
+
return new Error(`Server error (${o.code}): ${o.error}`);
|
|
482
|
+
} catch {
|
|
483
|
+
return new Error(`Server error: ${e.status} ${e.statusText}`);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
};
|
|
487
|
+
je = async function(n) {
|
|
488
|
+
const e = await _e(), o = await de(()=>import("./arrow-DJf2ErbF.js").then((s)=>s.A), []), r = new DataView(n);
|
|
489
|
+
let a = 0;
|
|
490
|
+
const t = r.getUint32(a, !0);
|
|
491
|
+
a += 4;
|
|
492
|
+
const i = new Uint8Array(n, a, t);
|
|
493
|
+
a += t;
|
|
494
|
+
const l = r.getUint32(a, !0);
|
|
495
|
+
a += 4;
|
|
496
|
+
const c = new Uint8Array(n, a, l);
|
|
497
|
+
a += l;
|
|
498
|
+
const m = r.getUint32(a, !0);
|
|
499
|
+
a += 4;
|
|
500
|
+
const y = new Uint8Array(n, a, m);
|
|
501
|
+
a += m;
|
|
502
|
+
const f = r.getUint32(a, !0);
|
|
503
|
+
a += 4;
|
|
504
|
+
const b = new Uint8Array(n, a, f);
|
|
505
|
+
a += f;
|
|
506
|
+
const u = r.getUint32(a, !0);
|
|
507
|
+
a += 4;
|
|
508
|
+
const d = new Uint8Array(n, a, u), q = e.readParquet(i), $ = e.readParquet(c), E = e.readParquet(b), C = o.tableFromIPC(q.intoIPCStream()), S = o.tableFromIPC($.intoIPCStream()), F = o.tableFromIPC(E.intoIPCStream()), T = C.getChild("entity_id")?.toArray(), x = C.getChild("has_geometry")?.toArray(), D = C.getChild("type_name")?.toArray(), I = C.getChild("global_id")?.toArray(), v = C.getChild("name")?.toArray(), P = C.getChild("description")?.toArray(), w = C.getChild("object_type")?.toArray(), K = T.length, N = new Map;
|
|
509
|
+
for(let s = 0; s < K; s++)N.set(T[s], {
|
|
510
|
+
entity_id: T[s],
|
|
511
|
+
type_name: D[s] ?? "",
|
|
512
|
+
global_id: I[s] || void 0,
|
|
513
|
+
name: v[s] || void 0,
|
|
514
|
+
description: P?.[s] || void 0,
|
|
515
|
+
object_type: w?.[s] || void 0,
|
|
516
|
+
has_geometry: x[s] !== 0
|
|
517
|
+
});
|
|
518
|
+
const z = S.getChild("pset_id")?.toArray(), G = S.getChild("pset_name")?.toArray(), R = S.getChild("property_name")?.toArray(), X = S.getChild("property_value")?.toArray(), O = S.getChild("property_type")?.toArray(), H = new Map;
|
|
519
|
+
for(let s = 0; s < z.length; s++){
|
|
520
|
+
const U = z[s];
|
|
521
|
+
H.has(U) || H.set(U, {
|
|
522
|
+
pset_id: U,
|
|
523
|
+
pset_name: G[s] ?? "",
|
|
524
|
+
properties: []
|
|
525
|
+
}), H.get(U).properties.push({
|
|
526
|
+
property_name: R[s] ?? "",
|
|
527
|
+
property_value: X[s] ?? "",
|
|
528
|
+
property_type: O[s] ?? ""
|
|
529
|
+
});
|
|
530
|
+
}
|
|
531
|
+
const ae = e.readParquet(y), L = o.tableFromIPC(ae.intoIPCStream()), _ = L.getChild("qset_id")?.toArray(), ne = L.getChild("qset_name")?.toArray(), J = L.getChild("method_of_measurement")?.toArray(), me = L.getChild("quantity_name")?.toArray(), se = L.getChild("quantity_value")?.toArray(), Y = L.getChild("quantity_type")?.toArray(), k = new Map;
|
|
532
|
+
for(let s = 0; s < _.length; s++){
|
|
533
|
+
const U = _[s];
|
|
534
|
+
k.has(U) || k.set(U, {
|
|
535
|
+
qset_id: U,
|
|
536
|
+
qset_name: ne[s] ?? "",
|
|
537
|
+
method_of_measurement: J[s] || void 0,
|
|
538
|
+
quantities: []
|
|
539
|
+
}), k.get(U).quantities.push({
|
|
540
|
+
quantity_name: me[s] ?? "",
|
|
541
|
+
quantity_value: se[s] ?? 0,
|
|
542
|
+
quantity_type: Y[s] ?? ""
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
const ie = F.getChild("rel_type")?.toArray(), Z = F.getChild("relating_id")?.toArray(), V = F.getChild("related_id")?.toArray(), h = new Array(Z.length);
|
|
546
|
+
for(let s = 0; s < Z.length; s++)h[s] = {
|
|
547
|
+
rel_type: ie[s] ?? "",
|
|
548
|
+
relating_id: Z[s],
|
|
549
|
+
related_id: V[s]
|
|
550
|
+
};
|
|
551
|
+
const g = new DataView(d.buffer, d.byteOffset, d.byteLength);
|
|
552
|
+
let p = 0;
|
|
553
|
+
const M = g.getUint32(p, !0);
|
|
554
|
+
p += 4;
|
|
555
|
+
const ce = new Uint8Array(d.buffer, d.byteOffset + p, M);
|
|
556
|
+
p += M;
|
|
557
|
+
const ee = g.getUint32(p, !0);
|
|
558
|
+
p += 4;
|
|
559
|
+
const pe = new Uint8Array(d.buffer, d.byteOffset + p, ee);
|
|
560
|
+
p += ee;
|
|
561
|
+
const te = g.getUint32(p, !0);
|
|
562
|
+
p += 4;
|
|
563
|
+
const he = new Uint8Array(d.buffer, d.byteOffset + p, te);
|
|
564
|
+
p += te;
|
|
565
|
+
const le = g.getUint32(p, !0);
|
|
566
|
+
p += 4;
|
|
567
|
+
const re = new Uint8Array(d.buffer, d.byteOffset + p, le);
|
|
568
|
+
p += le;
|
|
569
|
+
const B = g.getUint32(p, !0);
|
|
570
|
+
p += 4;
|
|
571
|
+
const ue = new Uint8Array(d.buffer, d.byteOffset + p, B);
|
|
572
|
+
p += B;
|
|
573
|
+
const A = g.getUint32(p, !0), W = e.readParquet(ce), j = o.tableFromIPC(W.intoIPCStream()), Ce = j.getChild("entity_id")?.toArray(), Te = j.getChild("parent_id")?.toArray(), Ue = j.getChild("level")?.toArray(), $e = j.getChild("path")?.toArray(), Ee = j.getChild("type_name")?.toArray(), De = j.getChild("name")?.toArray(), ke = j.getChild("elevation")?.toArray(), qe = j.getChild("children_ids"), Se = j.getChild("element_ids"), xe = Ce.length, Pe = new Array(xe);
|
|
574
|
+
for(let s = 0; s < xe; s++){
|
|
575
|
+
let U = [], oe = [];
|
|
576
|
+
if (qe) {
|
|
577
|
+
const Q = qe.get(s);
|
|
578
|
+
Q && (U = [
|
|
579
|
+
...Q.toArray()
|
|
580
|
+
]);
|
|
581
|
+
}
|
|
582
|
+
if (Se) {
|
|
583
|
+
const Q = Se.get(s);
|
|
584
|
+
Q && (oe = [
|
|
585
|
+
...Q.toArray()
|
|
586
|
+
]);
|
|
587
|
+
}
|
|
588
|
+
Pe[s] = {
|
|
589
|
+
entity_id: Ce[s],
|
|
590
|
+
parent_id: Te[s] ?? 0,
|
|
591
|
+
level: Ue[s],
|
|
592
|
+
path: $e[s] ?? "",
|
|
593
|
+
type_name: Ee[s] ?? "",
|
|
594
|
+
name: De[s] || void 0,
|
|
595
|
+
elevation: ke[s] ?? void 0,
|
|
596
|
+
children_ids: U,
|
|
597
|
+
element_ids: oe
|
|
598
|
+
};
|
|
599
|
+
}
|
|
600
|
+
const ye = (s)=>{
|
|
601
|
+
const U = e.readParquet(s), oe = o.tableFromIPC(U.intoIPCStream()), Q = oe.getChild("element_id")?.toArray(), Ne = oe.getChild("spatial_id")?.toArray(), Ie = new Map;
|
|
602
|
+
for(let we = 0; we < Q.length; we++)Ie.set(Q[we], Ne[we]);
|
|
603
|
+
return Ie;
|
|
604
|
+
}, [Me, Le, ze, Oe] = [
|
|
605
|
+
ye(pe),
|
|
606
|
+
ye(he),
|
|
607
|
+
ye(re),
|
|
608
|
+
ye(ue)
|
|
609
|
+
];
|
|
610
|
+
return {
|
|
611
|
+
entities: N,
|
|
612
|
+
propertySets: H,
|
|
613
|
+
quantitySets: k,
|
|
614
|
+
relationships: h,
|
|
615
|
+
spatialHierarchy: {
|
|
616
|
+
nodes: Pe,
|
|
617
|
+
project_id: A,
|
|
618
|
+
element_to_storey: Me,
|
|
619
|
+
element_to_building: Le,
|
|
620
|
+
element_to_site: ze,
|
|
621
|
+
element_to_space: Oe
|
|
622
|
+
}
|
|
623
|
+
};
|
|
624
|
+
};
|
|
625
|
+
});
|
|
626
|
+
export { We as I, je as d, __tla };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{I as f,a as d}from"./exporters-C_6J153K.js";import"./bcf-D5-QWGO9.js";import"./zip-B-jFFAGa.js";class z{bridge;initialized=!1;constructor(){this.bridge=new f}async init(){this.initialized||(await this.bridge.init(),this.initialized=!0)}isInitialized(){return this.initialized}async processGeometry(r){this.initialized||await this.init(),performance.now();const i=new d(this.bridge.getApi(),r),n=i.collectMeshes(),s=i.getBuildingRotation();performance.now();let e=0,o=0;for(const c of n)e+=c.positions.length/3,o+=c.indices.length/3;return{meshes:n,totalVertices:e,totalTriangles:o,coordinateInfo:{originShift:{x:0,y:0,z:0},originalBounds:{min:{x:0,y:0,z:0},max:{x:0,y:0,z:0}},shiftedBounds:{min:{x:0,y:0,z:0},max:{x:0,y:0,z:0}},hasLargeCoordinates:!1,buildingRotation:s}}}async processGeometryStreaming(r,i){this.initialized||await this.init();const n=performance.now(),s=new d(this.bridge.getApi(),r);let e=0,o=0,a=0;try{for await(const t of s.collectMeshesStreaming(50)){if(t&&typeof t=="object"&&"type"in t&&t.type==="colorUpdate")continue;const l=t;e+=l.length;for(const m of l)o+=m.positions.length/3,a+=m.indices.length/3;i.onBatch?.({meshes:l,progress:{processed:e,total:e,currentType:"processing"}})}}catch(t){throw i.onError?.(t instanceof Error?t:new Error(String(t))),t}const h=performance.now()-n,g={totalMeshes:e,totalVertices:o,totalTriangles:a,parseTimeMs:h*.3,geometryTimeMs:h*.7};return i.onComplete?.(g),g}getApi(){return this.bridge.getApi()}}export{z as WasmBridge};
|