@ifc-lite/geometry 1.16.6 → 1.18.1
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/dist/geometry-controller.worker.d.ts +4 -0
- package/dist/geometry-controller.worker.d.ts.map +1 -0
- package/dist/geometry-controller.worker.js +349 -0
- package/dist/geometry-controller.worker.js.map +1 -0
- package/dist/geometry-parallel.d.ts +55 -13
- package/dist/geometry-parallel.d.ts.map +1 -1
- package/dist/geometry-parallel.js +507 -134
- package/dist/geometry-parallel.js.map +1 -1
- package/dist/geometry.worker.d.ts +89 -3
- package/dist/geometry.worker.d.ts.map +1 -1
- package/dist/geometry.worker.js +337 -72
- package/dist/geometry.worker.js.map +1 -1
- package/dist/ifc-lite-bridge.d.ts +25 -0
- package/dist/ifc-lite-bridge.d.ts.map +1 -1
- package/dist/ifc-lite-bridge.js +49 -0
- package/dist/ifc-lite-bridge.js.map +1 -1
- package/dist/ifc-lite-mesh-collector.d.ts +28 -1
- package/dist/ifc-lite-mesh-collector.d.ts.map +1 -1
- package/dist/ifc-lite-mesh-collector.js +48 -1
- package/dist/ifc-lite-mesh-collector.js.map +1 -1
- package/dist/index.d.ts +49 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +46 -21
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +40 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/watchdog.d.ts +27 -0
- package/dist/watchdog.d.ts.map +1 -0
- package/dist/watchdog.js +35 -0
- package/dist/watchdog.js.map +1 -0
- package/dist/worker-count.d.ts +52 -0
- package/dist/worker-count.d.ts.map +1 -0
- package/dist/worker-count.js +89 -0
- package/dist/worker-count.js.map +1 -0
- package/package.json +5 -4
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { GeometryWorkerInitMessage, GeometryWorkerProcessMessage, GeometryWorkerStreamStartMessage, GeometryWorkerStreamChunkMessage, GeometryWorkerStreamEndMessage, GeometryWorkerSetStylesMessage, GeometryWorkerSetEntityIndexMessage, GeometryWorkerSetMergeLayersMessage, GeometryWorkerPrePassMessage, GeometryWorkerBatchMessage, GeometryWorkerCompleteMessage, GeometryWorkerErrorMessage, GeometryWorkerMemoryMessage } from './geometry.worker.js';
|
|
2
|
+
export type GeometryControllerRequest = GeometryWorkerInitMessage | GeometryWorkerProcessMessage | GeometryWorkerStreamStartMessage | GeometryWorkerStreamChunkMessage | GeometryWorkerStreamEndMessage | GeometryWorkerSetStylesMessage | GeometryWorkerSetEntityIndexMessage | GeometryWorkerSetMergeLayersMessage | GeometryWorkerPrePassMessage;
|
|
3
|
+
export type GeometryControllerResponse = GeometryWorkerBatchMessage | GeometryWorkerCompleteMessage | GeometryWorkerErrorMessage | GeometryWorkerMemoryMessage;
|
|
4
|
+
//# sourceMappingURL=geometry-controller.worker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"geometry-controller.worker.d.ts","sourceRoot":"","sources":["../src/geometry-controller.worker.ts"],"names":[],"mappings":"AAqCA,OAAO,KAAK,EACV,yBAAyB,EACzB,4BAA4B,EAC5B,gCAAgC,EAChC,gCAAgC,EAChC,8BAA8B,EAC9B,8BAA8B,EAC9B,mCAAmC,EACnC,mCAAmC,EACnC,4BAA4B,EAC5B,0BAA0B,EAC1B,6BAA6B,EAC7B,0BAA0B,EAC1B,2BAA2B,EAC5B,MAAM,sBAAsB,CAAC;AAG9B,MAAM,MAAM,yBAAyB,GACjC,yBAAyB,GACzB,4BAA4B,GAC5B,gCAAgC,GAChC,gCAAgC,GAChC,8BAA8B,GAC9B,8BAA8B,GAC9B,mCAAmC,GACnC,mCAAmC,GACnC,4BAA4B,CAAC;AAEjC,MAAM,MAAM,0BAA0B,GAClC,0BAA0B,GAC1B,6BAA6B,GAC7B,0BAA0B,GAC1B,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
/**
|
|
5
|
+
* Single-controller geometry worker (Phase 2 of single-controller-rayon-design.md).
|
|
6
|
+
*
|
|
7
|
+
* Replaces the N-independent-Web-Workers pool. ONE WASM instance with
|
|
8
|
+
* an internal rayon thread pool of (navigator.hardwareConcurrency - 1)
|
|
9
|
+
* helper threads. All `processGeometryBatchParallel` work happens
|
|
10
|
+
* inside this worker; rayon's `par_iter` distributes per-entity work
|
|
11
|
+
* across the helpers via shared memory.
|
|
12
|
+
*
|
|
13
|
+
* Message protocol is INTENTIONALLY identical to `geometry.worker.js`
|
|
14
|
+
* so the host (`geometry-parallel.ts`) can swap implementations behind
|
|
15
|
+
* a feature flag without changing the dispatch / event-collection
|
|
16
|
+
* code. The controller accepts the same set: `init`, `stream-start`,
|
|
17
|
+
* `stream-chunk`, `stream-end`, `set-styles`, `set-entity-index`.
|
|
18
|
+
*
|
|
19
|
+
* Why this matters: the per-worker entity-index FxHashMap (~600 MB
|
|
20
|
+
* per worker on the 986 MB test file) was triplicated across 3
|
|
21
|
+
* workers. Single controller holds ONE copy. Total peakWasm should
|
|
22
|
+
* drop from ~5.3 GB to ~3 GB. Plus rayon work-stealing replaces
|
|
23
|
+
* the contention pattern that capped useful workers at 3 even on
|
|
24
|
+
* 10-core hosts.
|
|
25
|
+
*/
|
|
26
|
+
// Import the THREADED bundle. The viewer's vite.config.ts maps
|
|
27
|
+
// `@ifc-lite/wasm-threaded` to `packages/wasm-threaded/pkg/ifc-lite.js`.
|
|
28
|
+
// (See vite.config.ts alias added by Phase 2 wiring.)
|
|
29
|
+
import init, { initSync, IfcAPI, initThreadPool } from '@ifc-lite/wasm-threaded';
|
|
30
|
+
let api = null;
|
|
31
|
+
let threadPoolReady = false;
|
|
32
|
+
/**
|
|
33
|
+
* Cached merge-layers flag (issue #540). The host may post
|
|
34
|
+
* `set-merge-layers` BEFORE `init`, so we remember the latest value
|
|
35
|
+
* and re-apply once the threaded IfcAPI is constructed.
|
|
36
|
+
*/
|
|
37
|
+
let mergeLayersFlag = false;
|
|
38
|
+
let mergeLayersApplied = false;
|
|
39
|
+
function applyMergeLayersToApi() {
|
|
40
|
+
if (!api || mergeLayersApplied)
|
|
41
|
+
return;
|
|
42
|
+
const merging = api;
|
|
43
|
+
if (typeof merging.setMergeLayers === 'function') {
|
|
44
|
+
merging.setMergeLayers(mergeLayersFlag);
|
|
45
|
+
}
|
|
46
|
+
mergeLayersApplied = true;
|
|
47
|
+
}
|
|
48
|
+
let activeSession = null;
|
|
49
|
+
function viewSharedBytes(sharedBuffer) {
|
|
50
|
+
return new Uint8Array(sharedBuffer);
|
|
51
|
+
}
|
|
52
|
+
function materialiseSharedBytes(sharedBuffer) {
|
|
53
|
+
const local = new Uint8Array(sharedBuffer.byteLength);
|
|
54
|
+
local.set(new Uint8Array(sharedBuffer));
|
|
55
|
+
return local;
|
|
56
|
+
}
|
|
57
|
+
function startSession(input) {
|
|
58
|
+
return {
|
|
59
|
+
sharedBuffer: input.sharedBuffer,
|
|
60
|
+
localBytes: viewSharedBytes(input.sharedBuffer),
|
|
61
|
+
sabFallbackTaken: false,
|
|
62
|
+
unitScale: input.unitScale,
|
|
63
|
+
rtcX: input.rtcX, rtcY: input.rtcY, rtcZ: input.rtcZ,
|
|
64
|
+
needsShift: input.needsShift,
|
|
65
|
+
voidKeys: input.voidKeys,
|
|
66
|
+
voidCounts: input.voidCounts,
|
|
67
|
+
voidValues: input.voidValues,
|
|
68
|
+
styleIds: input.styleIds,
|
|
69
|
+
styleColors: input.styleColors,
|
|
70
|
+
pendingMeshes: [],
|
|
71
|
+
pendingTransfers: [],
|
|
72
|
+
totalMeshesEmitted: 0,
|
|
73
|
+
cumulativeMeshBytes: 0,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function flushPending(session) {
|
|
77
|
+
if (session.pendingMeshes.length === 0)
|
|
78
|
+
return;
|
|
79
|
+
const meshes = session.pendingMeshes;
|
|
80
|
+
const transfers = session.pendingTransfers;
|
|
81
|
+
session.pendingMeshes = [];
|
|
82
|
+
session.pendingTransfers = [];
|
|
83
|
+
session.totalMeshesEmitted += meshes.length;
|
|
84
|
+
self.postMessage({ type: 'batch', meshes }, transfers);
|
|
85
|
+
}
|
|
86
|
+
function collectMeshes(session, collection) {
|
|
87
|
+
for (let i = 0; i < collection.length; i++) {
|
|
88
|
+
const mesh = collection.get(i);
|
|
89
|
+
if (!mesh)
|
|
90
|
+
continue;
|
|
91
|
+
const positions = new Float32Array(mesh.positions);
|
|
92
|
+
const normals = new Float32Array(mesh.normals);
|
|
93
|
+
const indices = new Uint32Array(mesh.indices);
|
|
94
|
+
session.pendingMeshes.push({
|
|
95
|
+
expressId: mesh.expressId,
|
|
96
|
+
ifcType: mesh.ifcType,
|
|
97
|
+
positions, normals, indices,
|
|
98
|
+
color: [mesh.color[0], mesh.color[1], mesh.color[2], mesh.color[3]],
|
|
99
|
+
});
|
|
100
|
+
session.pendingTransfers.push(positions.buffer, normals.buffer, indices.buffer);
|
|
101
|
+
session.cumulativeMeshBytes += positions.byteLength + normals.byteLength + indices.byteLength;
|
|
102
|
+
mesh.free();
|
|
103
|
+
}
|
|
104
|
+
collection.free();
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Run one chunk through the rayon-parallel batch entry. Same binary-
|
|
108
|
+
* split recovery as the N-worker path: if WASM rejects the whole slice
|
|
109
|
+
* (typical: SAB-view incompatible with this runtime), fall back to a
|
|
110
|
+
* materialised copy; on per-entity failure, halve and retry.
|
|
111
|
+
*/
|
|
112
|
+
async function processBatchParallel(session, jobs) {
|
|
113
|
+
const numJobs = Math.floor(jobs.length / 3);
|
|
114
|
+
if (numJobs === 0)
|
|
115
|
+
return;
|
|
116
|
+
try {
|
|
117
|
+
if (!api) {
|
|
118
|
+
throw new Error('controller API not initialised before stream-chunk');
|
|
119
|
+
}
|
|
120
|
+
const collection = api.processGeometryBatchParallel(session.localBytes, jobs, session.unitScale, session.rtcX, session.rtcY, session.rtcZ, session.needsShift, session.voidKeys, session.voidCounts, session.voidValues, session.styleIds, session.styleColors);
|
|
121
|
+
collectMeshes(session, collection);
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
const msg = err.message;
|
|
125
|
+
if (!session.sabFallbackTaken && session.localBytes.buffer instanceof SharedArrayBuffer) {
|
|
126
|
+
session.sabFallbackTaken = true;
|
|
127
|
+
console.warn(`[controller] processGeometryBatchParallel rejected SAB view (${msg}), copying`);
|
|
128
|
+
session.localBytes = materialiseSharedBytes(session.sharedBuffer);
|
|
129
|
+
await processBatchParallel(session, jobs);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
if (numJobs === 1) {
|
|
133
|
+
console.warn(`[controller] skipping entity #${jobs[0]}: ${msg}`);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
console.warn(`[controller] batch of ${numJobs} entities failed (${msg}), splitting…`);
|
|
137
|
+
const mid = Math.floor(numJobs / 2) * 3;
|
|
138
|
+
await processBatchParallel(session, jobs.slice(0, mid));
|
|
139
|
+
await processBatchParallel(session, jobs.slice(mid));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Run a slice in STREAM_BATCH_SIZE chunks, flushing after each. Same
|
|
144
|
+
* cadence as the N-worker path so downstream React/render code sees
|
|
145
|
+
* familiar timing.
|
|
146
|
+
*/
|
|
147
|
+
const STREAM_BATCH_SIZE = 1_000_000;
|
|
148
|
+
async function processSliceStreaming(session, jobsFlat) {
|
|
149
|
+
const totalJobs = Math.floor(jobsFlat.length / 3);
|
|
150
|
+
for (let jobOffset = 0; jobOffset < totalJobs; jobOffset += STREAM_BATCH_SIZE) {
|
|
151
|
+
const start = jobOffset * 3;
|
|
152
|
+
const end = Math.min(start + STREAM_BATCH_SIZE * 3, jobsFlat.length);
|
|
153
|
+
await processBatchParallel(session, jobsFlat.slice(start, end));
|
|
154
|
+
flushPending(session);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
function emitSessionEnd(session) {
|
|
158
|
+
flushPending(session);
|
|
159
|
+
// Memory snapshot — single WASM heap (vs N-worker pool sums).
|
|
160
|
+
let wasmHeapBytes = 0;
|
|
161
|
+
try {
|
|
162
|
+
const memJs = api?.getMemory();
|
|
163
|
+
const buf = memJs?.buffer;
|
|
164
|
+
wasmHeapBytes = buf?.byteLength ?? 0;
|
|
165
|
+
}
|
|
166
|
+
catch { /* memory probe is best-effort */ }
|
|
167
|
+
self.postMessage({
|
|
168
|
+
type: 'memory',
|
|
169
|
+
wasmHeapBytes,
|
|
170
|
+
meshBytes: session.cumulativeMeshBytes,
|
|
171
|
+
});
|
|
172
|
+
self.postMessage({
|
|
173
|
+
type: 'complete',
|
|
174
|
+
totalMeshes: session.totalMeshesEmitted,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Tail-promise serialiser — copied from `geometry.worker.js`. Web
|
|
179
|
+
* Worker `onmessage` is fire-and-forget; without serialisation, an
|
|
180
|
+
* async handler for `stream-start` (which awaits init() + initThreadPool)
|
|
181
|
+
* can be overtaken by a synchronous `stream-chunk` handler that
|
|
182
|
+
* dispatches before the session is ready.
|
|
183
|
+
*/
|
|
184
|
+
let messageTail = Promise.resolve();
|
|
185
|
+
self.onmessage = (rawEvent) => {
|
|
186
|
+
const e = rawEvent;
|
|
187
|
+
messageTail = messageTail.then(async () => {
|
|
188
|
+
try {
|
|
189
|
+
if (e.data.type === 'init') {
|
|
190
|
+
if (e.data.wasmModule) {
|
|
191
|
+
initSync({ module_or_path: e.data.wasmModule });
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
await init();
|
|
195
|
+
}
|
|
196
|
+
api = new IfcAPI();
|
|
197
|
+
mergeLayersApplied = false;
|
|
198
|
+
applyMergeLayersToApi();
|
|
199
|
+
// Spin up the rayon thread pool. Per the design (and upstream
|
|
200
|
+
// guidance from issue #36), call from inside this worker (NOT
|
|
201
|
+
// main thread) to dodge the Atomics.wait deadlock that fires
|
|
202
|
+
// when initThreadPool runs on the main thread.
|
|
203
|
+
//
|
|
204
|
+
// Thread count: hardwareConcurrency - 1 to leave one core for
|
|
205
|
+
// main-thread render. Wrap with retry-25ms-backoff x5 in case
|
|
206
|
+
// we hit transient deadlocks anyway.
|
|
207
|
+
const cores = (typeof navigator !== 'undefined'
|
|
208
|
+
? (navigator.hardwareConcurrency ?? 4)
|
|
209
|
+
: 4);
|
|
210
|
+
const targetThreads = Math.max(1, cores - 1);
|
|
211
|
+
let lastInitErr = null;
|
|
212
|
+
for (let attempt = 1; attempt <= 5; attempt++) {
|
|
213
|
+
try {
|
|
214
|
+
const t0 = performance.now();
|
|
215
|
+
await initThreadPool(targetThreads);
|
|
216
|
+
console.log(`[controller] rayon pool ready (${targetThreads} threads, attempt ${attempt}) @ ${Math.round(performance.now() - t0)}ms`);
|
|
217
|
+
threadPoolReady = true;
|
|
218
|
+
lastInitErr = null;
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
catch (err) {
|
|
222
|
+
lastInitErr = err;
|
|
223
|
+
console.warn(`[controller] initThreadPool attempt ${attempt} failed:`, err);
|
|
224
|
+
if (attempt < 5) {
|
|
225
|
+
await new Promise((r) => setTimeout(r, 25));
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
if (!threadPoolReady) {
|
|
230
|
+
// Surface the failure as an error message back to the host
|
|
231
|
+
// instead of silently posting `ready` and then hanging on
|
|
232
|
+
// the first par_iter call. The host's processParallel will
|
|
233
|
+
// see this and reject the load with a clear cause.
|
|
234
|
+
const errMsg = lastInitErr instanceof Error
|
|
235
|
+
? lastInitErr.message
|
|
236
|
+
: String(lastInitErr ?? 'unknown initThreadPool failure');
|
|
237
|
+
self.postMessage({
|
|
238
|
+
type: 'error',
|
|
239
|
+
message: `controller: initThreadPool failed after 5 attempts: ${errMsg}`,
|
|
240
|
+
});
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
// Phase 2 microbenchmark — run a CPU-pure parallel task to
|
|
244
|
+
// measure rayon's actual speedup on this hardware. Helps
|
|
245
|
+
// distinguish "rayon is broken" vs "our workload doesn't fit
|
|
246
|
+
// rayon" when stream tail is slow.
|
|
247
|
+
try {
|
|
248
|
+
const benchApi = api;
|
|
249
|
+
if (typeof benchApi.benchmarkPureCpuParallelism === 'function') {
|
|
250
|
+
// 9 tasks → one per helper thread — best case for scaling.
|
|
251
|
+
benchApi.benchmarkPureCpuParallelism(9);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
catch (err) {
|
|
255
|
+
console.warn('[controller] microbench failed:', err);
|
|
256
|
+
}
|
|
257
|
+
self.postMessage({ type: 'ready' });
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
if (e.data.type === 'stream-start') {
|
|
261
|
+
// The thread pool MUST be ready before we accept stream
|
|
262
|
+
// messages — `processGeometryBatchParallel` calls par_iter
|
|
263
|
+
// which would silently run on the calling thread (slow
|
|
264
|
+
// serial fallback) if the pool isn't initialized. Refuse
|
|
265
|
+
// and surface a clear error so the host can fall back.
|
|
266
|
+
if (!api || !threadPoolReady) {
|
|
267
|
+
throw new Error('controller: stream-start before init/threadPool ready — host must wait for {type:"ready"} before dispatching');
|
|
268
|
+
}
|
|
269
|
+
activeSession = startSession({
|
|
270
|
+
sharedBuffer: e.data.sharedBuffer,
|
|
271
|
+
unitScale: e.data.unitScale,
|
|
272
|
+
rtcX: e.data.rtcX, rtcY: e.data.rtcY, rtcZ: e.data.rtcZ,
|
|
273
|
+
needsShift: e.data.needsShift,
|
|
274
|
+
voidKeys: e.data.voidKeys,
|
|
275
|
+
voidCounts: e.data.voidCounts,
|
|
276
|
+
voidValues: e.data.voidValues,
|
|
277
|
+
styleIds: e.data.styleIds,
|
|
278
|
+
styleColors: e.data.styleColors,
|
|
279
|
+
});
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
if (e.data.type === 'stream-chunk') {
|
|
283
|
+
if (!activeSession || !api || !threadPoolReady) {
|
|
284
|
+
throw new Error('controller: stream-chunk before init/stream-start');
|
|
285
|
+
}
|
|
286
|
+
await processSliceStreaming(activeSession, e.data.jobsFlat);
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
if (e.data.type === 'stream-end') {
|
|
290
|
+
if (!activeSession)
|
|
291
|
+
return;
|
|
292
|
+
emitSessionEnd(activeSession);
|
|
293
|
+
activeSession = null;
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
if (e.data.type === 'set-styles') {
|
|
297
|
+
if (!activeSession)
|
|
298
|
+
return;
|
|
299
|
+
activeSession.styleIds = e.data.styleIds;
|
|
300
|
+
activeSession.styleColors = e.data.styleColors;
|
|
301
|
+
activeSession.voidKeys = e.data.voidKeys;
|
|
302
|
+
activeSession.voidCounts = e.data.voidCounts;
|
|
303
|
+
activeSession.voidValues = e.data.voidValues;
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
if (e.data.type === 'set-merge-layers') {
|
|
307
|
+
// Cache the requested merge-layers flag (issue #540). The
|
|
308
|
+
// host may post this BEFORE `init` (rare but legal); if so
|
|
309
|
+
// we just hold onto the value and the `init` branch above
|
|
310
|
+
// applies it to the newly-constructed API.
|
|
311
|
+
mergeLayersFlag = e.data.enabled === true;
|
|
312
|
+
mergeLayersApplied = false;
|
|
313
|
+
applyMergeLayersToApi();
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
if (e.data.type === 'set-entity-index') {
|
|
317
|
+
if (!api) {
|
|
318
|
+
// Should never happen — host always sends `init` first and
|
|
319
|
+
// waits for `ready`. If we hit this, it indicates a host
|
|
320
|
+
// sequencing bug; surface clearly rather than silently
|
|
321
|
+
// initializing a fresh API (which would skip thread-pool
|
|
322
|
+
// setup and break later par_iter calls).
|
|
323
|
+
throw new Error('controller: set-entity-index before init — host must wait for {type:"ready"} before dispatching');
|
|
324
|
+
}
|
|
325
|
+
// Eager FxHashMap build — happens during the styles wait so
|
|
326
|
+
// by the time stream-chunk arrives the cache is hot.
|
|
327
|
+
api.setEntityIndex(e.data.ids, e.data.starts, e.data.lengths);
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
// process / prepass-* message types are NOT handled by the
|
|
331
|
+
// controller path — those are pre-pass-only contracts that stay
|
|
332
|
+
// on the existing pre-pass worker (geometry.worker.js). The
|
|
333
|
+
// controller is for stream-chunk dispatch only.
|
|
334
|
+
console.warn(`[controller] ignoring unhandled message type: ${e.data.type}`);
|
|
335
|
+
}
|
|
336
|
+
catch (err) {
|
|
337
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
338
|
+
console.error('[controller] handler error:', err);
|
|
339
|
+
self.postMessage({
|
|
340
|
+
type: 'error',
|
|
341
|
+
message: msg,
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
};
|
|
346
|
+
// Mark threadPoolReady reachable to silence potential unused warning
|
|
347
|
+
// when the future Phase 3 code references it for back-pressure.
|
|
348
|
+
void threadPoolReady;
|
|
349
|
+
//# sourceMappingURL=geometry-controller.worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"geometry-controller.worker.js","sourceRoot":"","sources":["../src/geometry-controller.worker.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,23 +1,65 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Multi-worker parallel geometry processing.
|
|
2
|
+
* Multi-worker parallel geometry processing with streaming pre-pass.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* Architecture:
|
|
5
|
+
* 1. Spawn a single "pre-pass" worker that runs the WASM streaming
|
|
6
|
+
* scanner. The scanner walks the file once and emits:
|
|
7
|
+
* - `meta` once, when RTC + unit are resolved (~1-2 % of scan)
|
|
8
|
+
* - `jobs` repeatedly, every ~50 K entities
|
|
9
|
+
* - `complete` once, when the scan finishes
|
|
10
|
+
* 2. On `meta`: spawn N geometry process workers (memory-budget-aware
|
|
11
|
+
* count) and send each a `stream-start` so they hold the metadata
|
|
12
|
+
* before any chunk arrives.
|
|
13
|
+
* 3. On each `jobs` chunk: round-robin the chunk to a worker via
|
|
14
|
+
* `stream-chunk`. Workers process and emit `batch` messages.
|
|
15
|
+
* 4. On `complete`: send `stream-end` to each worker so they emit
|
|
16
|
+
* their final `batch`/`memory`/`complete`.
|
|
17
|
+
*
|
|
18
|
+
* Net effect for a 1 GB file: time-to-first-batch drops from ~17 s
|
|
19
|
+
* (full pre-pass + worker spawn + first batch) to ~3-5 s (pre-pass
|
|
20
|
+
* scans first 100 K bytes → meta → first chunk → first batch).
|
|
8
21
|
*/
|
|
9
22
|
import type { CoordinateHandler } from './coordinate-handler.js';
|
|
10
23
|
import type { StreamingGeometryEvent } from './index.js';
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
24
|
+
export interface ProcessParallelOptions {
|
|
25
|
+
/**
|
|
26
|
+
* Fires when the streaming pre-pass finishes building the entity index
|
|
27
|
+
* (after styles), with SAB-backed Uint32Array views over the shared
|
|
28
|
+
* column buffers. The parser worker uses this to skip its own
|
|
29
|
+
* `scanEntitiesFastBytes` call (~10 s on 1 GB files under WASM
|
|
30
|
+
* contention with the geometry workers).
|
|
31
|
+
*/
|
|
32
|
+
onEntityIndex?: (ids: Uint32Array, starts: Uint32Array, lengths: Uint32Array) => void;
|
|
33
|
+
/**
|
|
34
|
+
* Phase 2 of single-controller-rayon-design.md — when true, spawn ONE
|
|
35
|
+
* controller worker that runs `processGeometryBatchParallel` with
|
|
36
|
+
* an internal rayon thread pool, instead of the N-independent-worker
|
|
37
|
+
* pool. The host can opt in via `localStorage.getItem('ifc-lite:single-controller')`
|
|
38
|
+
* (set in `useIfcLoader.ts`). Same input/output contract; the
|
|
39
|
+
* controller mirrors `geometry.worker.ts`'s message protocol so this
|
|
40
|
+
* file's dispatch loop is unchanged.
|
|
41
|
+
*
|
|
42
|
+
* Trade-offs documented in the design doc:
|
|
43
|
+
* - peakWasm should drop ~5.3 GB → ~3 GB (one heap, not three).
|
|
44
|
+
* - Stream tail should drop on rayon-friendly hosts (10+ cores).
|
|
45
|
+
* - Falls back silently to N-worker path if the threaded WASM
|
|
46
|
+
* bundle fails to load (no COI, Safari, etc.).
|
|
47
|
+
*/
|
|
48
|
+
useSingleController?: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Issue #540 — "Merge Multilayer Walls" load-time toggle. When
|
|
51
|
+
* `true`, the geometry workers' IfcAPI receive
|
|
52
|
+
* `setMergeLayers(true)` before the first stream-chunk lands, so
|
|
53
|
+
* Revit-style multilayer-wall part meshes are suppressed at the
|
|
54
|
+
* Rust layer. Default `false` keeps existing behaviour.
|
|
55
|
+
*/
|
|
56
|
+
mergeLayers?: boolean;
|
|
57
|
+
}
|
|
18
58
|
export declare function processParallel(buffer: Uint8Array, coordinator: CoordinateHandler, sharedRtcOffset?: {
|
|
19
59
|
x: number;
|
|
20
60
|
y: number;
|
|
21
61
|
z: number;
|
|
22
|
-
}
|
|
62
|
+
},
|
|
63
|
+
/** Optional pre-allocated SAB the caller already shares with another worker. */
|
|
64
|
+
existingSab?: SharedArrayBuffer, options?: ProcessParallelOptions): AsyncGenerator<StreamingGeometryEvent>;
|
|
23
65
|
//# sourceMappingURL=geometry-parallel.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geometry-parallel.d.ts","sourceRoot":"","sources":["../src/geometry-parallel.ts"],"names":[],"mappings":"AAIA
|
|
1
|
+
{"version":3,"file":"geometry-parallel.d.ts","sourceRoot":"","sources":["../src/geometry-parallel.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAUzD,MAAM,WAAW,sBAAsB;IACrC;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,CACd,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,WAAW,KACjB,IAAI,CAAC;IACV;;;;;;;;;;;;;;OAcG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wBAAuB,eAAe,CACpC,MAAM,EAAE,UAAU,EAClB,WAAW,EAAE,iBAAiB,EAC9B,eAAe,CAAC,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE;AACrD,gFAAgF;AAChF,WAAW,CAAC,EAAE,iBAAiB,EAC/B,OAAO,CAAC,EAAE,sBAAsB,GAC/B,cAAc,CAAC,sBAAsB,CAAC,CA4kBxC"}
|