@ifc-lite/geometry 7.5.2 → 7.6.0

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.
Files changed (67) hide show
  1. package/dist/analytic-descriptions.d.ts +54 -0
  2. package/dist/analytic-descriptions.d.ts.map +1 -0
  3. package/dist/analytic-descriptions.js +5 -0
  4. package/dist/analytic-descriptions.js.map +1 -0
  5. package/dist/byte-streaming-prepass-result.d.ts +3 -0
  6. package/dist/byte-streaming-prepass-result.d.ts.map +1 -1
  7. package/dist/geometry-coordinate.d.ts.map +1 -1
  8. package/dist/geometry-coordinate.js +3 -0
  9. package/dist/geometry-coordinate.js.map +1 -1
  10. package/dist/geometry-parallel.d.ts.map +1 -1
  11. package/dist/geometry-parallel.js +12 -41
  12. package/dist/geometry-parallel.js.map +1 -1
  13. package/dist/geometry.worker.d.ts +3 -0
  14. package/dist/geometry.worker.d.ts.map +1 -1
  15. package/dist/geometry.worker.js +16 -6
  16. package/dist/geometry.worker.js.map +1 -1
  17. package/dist/ifc-lite-bridge.d.ts +10 -16
  18. package/dist/ifc-lite-bridge.d.ts.map +1 -1
  19. package/dist/ifc-lite-bridge.js +13 -16
  20. package/dist/ifc-lite-bridge.js.map +1 -1
  21. package/dist/index.d.ts +11 -16
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +20 -23
  24. package/dist/index.js.map +1 -1
  25. package/dist/mesh-specular.d.ts +15 -0
  26. package/dist/mesh-specular.d.ts.map +1 -0
  27. package/dist/mesh-specular.js +20 -0
  28. package/dist/mesh-specular.js.map +1 -0
  29. package/dist/packed-instanced-decoder.d.ts +9 -0
  30. package/dist/packed-instanced-decoder.d.ts.map +1 -1
  31. package/dist/packed-instanced-decoder.js +12 -1
  32. package/dist/packed-instanced-decoder.js.map +1 -1
  33. package/dist/remesh/index.d.ts +7 -0
  34. package/dist/remesh/index.d.ts.map +1 -0
  35. package/dist/remesh/index.js +10 -0
  36. package/dist/remesh/index.js.map +1 -0
  37. package/dist/remesh/remesh-client.d.ts +60 -0
  38. package/dist/remesh/remesh-client.d.ts.map +1 -0
  39. package/dist/remesh/remesh-client.js +131 -0
  40. package/dist/remesh/remesh-client.js.map +1 -0
  41. package/dist/remesh/remesh-core.d.ts +96 -0
  42. package/dist/remesh/remesh-core.d.ts.map +1 -0
  43. package/dist/remesh/remesh-core.js +94 -0
  44. package/dist/remesh/remesh-core.js.map +1 -0
  45. package/dist/remesh/remesh-protocol.d.ts +50 -0
  46. package/dist/remesh/remesh-protocol.d.ts.map +1 -0
  47. package/dist/remesh/remesh-protocol.js +32 -0
  48. package/dist/remesh/remesh-protocol.js.map +1 -0
  49. package/dist/remesh/remesh.worker.d.ts +2 -0
  50. package/dist/remesh/remesh.worker.d.ts.map +1 -0
  51. package/dist/remesh/remesh.worker.js +102 -0
  52. package/dist/remesh/remesh.worker.js.map +1 -0
  53. package/dist/shard-style-merge.d.ts +27 -0
  54. package/dist/shard-style-merge.d.ts.map +1 -0
  55. package/dist/shard-style-merge.js +54 -0
  56. package/dist/shard-style-merge.js.map +1 -0
  57. package/dist/style-finishes.d.ts +25 -0
  58. package/dist/style-finishes.d.ts.map +1 -0
  59. package/dist/style-finishes.js +32 -0
  60. package/dist/style-finishes.js.map +1 -0
  61. package/dist/types.d.ts +11 -0
  62. package/dist/types.d.ts.map +1 -1
  63. package/dist/types.js.map +1 -1
  64. package/dist/worker-prepass-source.d.ts +9 -0
  65. package/dist/worker-prepass-source.d.ts.map +1 -1
  66. package/dist/worker-prepass-source.js.map +1 -1
  67. package/package.json +10 -5
@@ -0,0 +1,131 @@
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
+ const DEFAULT_REQUEST_TIMEOUT_MS = 30_000;
5
+ export class RemeshClient {
6
+ worker;
7
+ timeoutMs;
8
+ pending = new Map();
9
+ nextRequestId = 1;
10
+ /** Why the client can no longer answer: disposed, or its worker died. */
11
+ dead = null;
12
+ constructor(worker, timeoutMs) {
13
+ this.worker = worker;
14
+ this.timeoutMs = timeoutMs;
15
+ }
16
+ /** False once disposed or once its worker failed; create a new client then. */
17
+ get alive() {
18
+ return this.dead === null;
19
+ }
20
+ /** Spawn the worker and resolve once its engine is instantiated. */
21
+ static async create(config, options = {}) {
22
+ const worker = options.createWorker?.()
23
+ ?? new Worker(new URL('./remesh.worker.js', import.meta.url), { type: 'module' });
24
+ const client = new RemeshClient(worker, options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS);
25
+ try {
26
+ await client.start(config, options);
27
+ }
28
+ catch (error) {
29
+ client.dispose();
30
+ throw error;
31
+ }
32
+ return client;
33
+ }
34
+ start(config, options) {
35
+ return new Promise((resolve, reject) => {
36
+ this.worker.onmessage = (event) => {
37
+ const message = event.data;
38
+ if (message.type === 'ready') {
39
+ this.worker.onmessage = (next) => this.settle(next.data);
40
+ resolve();
41
+ }
42
+ else if (message.type === 'init-error') {
43
+ reject(new Error(`Re-mesh engine failed to start: ${message.message}`));
44
+ }
45
+ };
46
+ this.worker.onerror = (event) => {
47
+ const error = new Error(`Re-mesh worker failed: ${event.message}`);
48
+ reject(error);
49
+ this.kill(error);
50
+ };
51
+ this.worker.onmessageerror = () => this.kill(new Error('Re-mesh worker sent a message that could not be read'));
52
+ this.post({ type: 'init', config, wasmModule: options.wasmModule, wasmUrl: options.wasmUrl });
53
+ });
54
+ }
55
+ /**
56
+ * Mesh `request.targets` from `request.buffer`. The buffer's memory is
57
+ * TRANSFERRED to the worker when it spans a whole `ArrayBuffer`, so the
58
+ * caller must not read it afterwards.
59
+ */
60
+ remesh(request) {
61
+ const { buffer } = request;
62
+ const transfer = buffer.buffer instanceof ArrayBuffer
63
+ && buffer.byteOffset === 0 && buffer.byteLength === buffer.buffer.byteLength
64
+ ? [buffer.buffer]
65
+ : [];
66
+ return this.request((requestId) => ({ type: 'remesh', requestId, request }), transfer);
67
+ }
68
+ /**
69
+ * The style wire a whole-file pre-pass resolves for `source`, for a model
70
+ * whose load did not keep one. The source is COPIED to the worker (the
71
+ * caller's model still owns it), and the pre-pass cache is released after.
72
+ */
73
+ styleWire(source) {
74
+ return this.request((requestId) => ({ type: 'style-wire', requestId, source }));
75
+ }
76
+ request(message, transfer = []) {
77
+ if (this.dead)
78
+ return Promise.reject(this.dead);
79
+ const requestId = this.nextRequestId++;
80
+ return new Promise((resolve, reject) => {
81
+ const timer = setTimeout(() => this.kill(new Error(`Re-mesh worker did not answer within ${this.timeoutMs} ms`)), this.timeoutMs);
82
+ const settle = (fn) => (value) => { clearTimeout(timer); fn(value); };
83
+ this.pending.set(requestId, {
84
+ resolve: settle(resolve),
85
+ reject: settle(reject),
86
+ });
87
+ this.post(message(requestId), transfer);
88
+ });
89
+ }
90
+ /** Change the load toggles; applies to every request sent after this call. */
91
+ setConfig(config) {
92
+ if (this.dead)
93
+ return;
94
+ this.post({ type: 'config', config });
95
+ }
96
+ /** Terminate the worker and reject whatever is still in flight. Idempotent. */
97
+ dispose() {
98
+ this.kill(new Error('RemeshClient is disposed'));
99
+ }
100
+ /** Mark the client dead (first reason wins), stop the worker, reject everything pending. */
101
+ kill(reason) {
102
+ if (this.dead)
103
+ return;
104
+ this.dead = reason;
105
+ this.worker.terminate();
106
+ this.failAll(reason);
107
+ }
108
+ post(message, transfer = []) {
109
+ this.worker.postMessage(message, transfer);
110
+ }
111
+ settle(message) {
112
+ if (message.type === 'ready' || message.type === 'init-error')
113
+ return;
114
+ const pending = this.pending.get(message.requestId);
115
+ if (!pending)
116
+ return;
117
+ this.pending.delete(message.requestId);
118
+ if (message.type === 'result')
119
+ pending.resolve(message.result);
120
+ else if (message.type === 'style-wire')
121
+ pending.resolve(message.wire);
122
+ else
123
+ pending.reject(new Error(`Re-mesh failed: ${message.message}`));
124
+ }
125
+ failAll(error) {
126
+ for (const pending of this.pending.values())
127
+ pending.reject(error);
128
+ this.pending.clear();
129
+ }
130
+ }
131
+ //# sourceMappingURL=remesh-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remesh-client.js","sourceRoot":"","sources":["../../src/remesh/remesh-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Re-mesh a few elements from a subgraph buffer (#6232 WP1): the body of
3
+ * `remesh.worker.ts`, kept free of the wasm import so the real-wasm contract
4
+ * test (`scripts/lib/wasm-remesh-contracts.mjs`) runs this exact code.
5
+ *
6
+ * It calls the same wasm entry points as the load path
7
+ * (`buildPrePassOnce` → `processGeometryBatch` → `convertMeshCollectionToBatch`),
8
+ * with two inputs pinned to the model's load: the RTC frame the model was
9
+ * meshed in, and the style wire resolved from the whole file. The subgraph
10
+ * cannot produce either (styles are not in it, and the RTC detector would
11
+ * pick a different anchor from a handful of entities).
12
+ */
13
+ import type { MeshCollection } from '@ifc-lite/wasm';
14
+ import type { RtcFrame } from '../rtc-frame.js';
15
+ import type { MeshData, TessellationQuality } from '../types.js';
16
+ /**
17
+ * The load-time toggles that change mesh output. Mirror the model's load, or
18
+ * a re-meshed element disagrees with its neighbours.
19
+ */
20
+ export interface RemeshConfig {
21
+ mergeLayers: boolean;
22
+ /** `null` keeps the engine default (`medium`), as on load. */
23
+ tessellationQuality: TessellationQuality | null;
24
+ skipSmallCuts: boolean;
25
+ /** The engine default is on; the load path never turns it off. */
26
+ rectParamFastPath: boolean;
27
+ }
28
+ export interface RemeshRequest {
29
+ /** A standalone STEP buffer (`serializeEntitySubgraph` in `@ifc-lite/export`). */
30
+ buffer: Uint8Array;
31
+ /** Express ids to mesh; other products in the buffer are context only. */
32
+ targets: Uint32Array;
33
+ /** The frame the model was meshed in on load. */
34
+ frame: RtcFrame;
35
+ /** Load-time style wire (item or element id → RGBA, 4 bytes each). */
36
+ styleIds: Uint32Array;
37
+ styleColors: Uint8Array;
38
+ materialElementIds?: Uint32Array;
39
+ materialColorCounts?: Uint32Array;
40
+ materialColors?: Uint8Array;
41
+ }
42
+ /**
43
+ * The style and material colour wire a whole-file pre-pass resolves: what a
44
+ * re-mesh request must carry, since a subgraph holds no styles.
45
+ */
46
+ export interface StyleWire {
47
+ styleIds: Uint32Array;
48
+ styleColors: Uint8Array;
49
+ materialElementIds: Uint32Array;
50
+ materialColorCounts: Uint32Array;
51
+ materialColors: Uint8Array;
52
+ }
53
+ export interface RemeshResult {
54
+ meshes: MeshData[];
55
+ csgFailures: number;
56
+ ms: {
57
+ prepass: number;
58
+ produce: number;
59
+ };
60
+ }
61
+ /** The slice of `IfcAPI` the re-mesh path calls. */
62
+ export interface RemeshApi {
63
+ buildPrePassOnce(data: Uint8Array): unknown;
64
+ processGeometryBatch(data: Uint8Array, jobs: Uint32Array, unitScale: number, rtcX: number, rtcY: number, rtcZ: number, needsShift: boolean, voidKeys: Uint32Array, voidCounts: Uint32Array, voidValues: Uint32Array, styleIds: Uint32Array, styleColors: Uint8Array, planeAngleToRadians?: number | null, materialElementIds?: Uint32Array | null, materialColorCounts?: Uint32Array | null, materialColors?: Uint8Array | null): MeshCollection;
65
+ clearPrePassCache(): void;
66
+ setMergeLayers(enabled: boolean): void;
67
+ setTessellationQuality(level?: string | null): void;
68
+ setSkipSmallCuts(on: boolean): void;
69
+ setRectParamFastPath(enabled: boolean): void;
70
+ }
71
+ /** Apply every config field, so a changed field can never be left stale. */
72
+ export declare function applyRemeshConfig(api: RemeshApi, config: RemeshConfig): void;
73
+ /** Keep the `(id, start, end)` job triplets whose id is a target. */
74
+ export declare function filterJobsToTargets(jobs: Uint32Array, targets: Uint32Array): Uint32Array;
75
+ /**
76
+ * Narrow the model's style wire to the ids a subgraph holds. The engine
77
+ * builds a colour map from every entry it is sent, so sending a large model's
78
+ * whole wire costs a map build per re-mesh. The wire is keyed by item and
79
+ * element ids, and both are in the subgraph when they matter.
80
+ */
81
+ export declare function filterStyleWire(styleIds: Uint32Array, styleColors: Uint8Array, keep: ReadonlySet<number>): {
82
+ styleIds: Uint32Array;
83
+ styleColors: Uint8Array;
84
+ };
85
+ /**
86
+ * Pre-pass the subgraph, mesh the targets in the load frame, and release the
87
+ * pre-pass cache on every exit (the per-content caches are keyed to this
88
+ * buffer and would otherwise leak into the next request).
89
+ */
90
+ export declare function remeshOnApi(api: RemeshApi, req: RemeshRequest, now?: () => number): RemeshResult;
91
+ /**
92
+ * Pre-pass a whole model once and keep only its style wire, releasing the
93
+ * pre-pass cache. Copies each array so nothing aliases the wasm heap.
94
+ */
95
+ export declare function styleWireOnApi(api: RemeshApi, source: Uint8Array): StyleWire;
96
+ //# sourceMappingURL=remesh-core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remesh-core.d.ts","sourceRoot":"","sources":["../../src/remesh/remesh-core.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,94 @@
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
+ import { convertMeshCollectionToBatch } from '../geometry-coordinate.js';
5
+ /** Apply every config field, so a changed field can never be left stale. */
6
+ export function applyRemeshConfig(api, config) {
7
+ api.setMergeLayers(config.mergeLayers);
8
+ api.setTessellationQuality(config.tessellationQuality);
9
+ api.setSkipSmallCuts(config.skipSmallCuts);
10
+ api.setRectParamFastPath(config.rectParamFastPath);
11
+ }
12
+ /** Keep the `(id, start, end)` job triplets whose id is a target. */
13
+ export function filterJobsToTargets(jobs, targets) {
14
+ const wanted = new Set(targets);
15
+ const kept = [];
16
+ for (let i = 0; i + 2 < jobs.length; i += 3) {
17
+ if (wanted.has(jobs[i]))
18
+ kept.push(jobs[i], jobs[i + 1], jobs[i + 2]);
19
+ }
20
+ return Uint32Array.from(kept);
21
+ }
22
+ /**
23
+ * Narrow the model's style wire to the ids a subgraph holds. The engine
24
+ * builds a colour map from every entry it is sent, so sending a large model's
25
+ * whole wire costs a map build per re-mesh. The wire is keyed by item and
26
+ * element ids, and both are in the subgraph when they matter.
27
+ */
28
+ export function filterStyleWire(styleIds, styleColors, keep) {
29
+ const ids = [];
30
+ const colors = [];
31
+ for (let i = 0; i < styleIds.length; i++) {
32
+ if (!keep.has(styleIds[i]))
33
+ continue;
34
+ ids.push(styleIds[i]);
35
+ for (let c = 0; c < 4; c++)
36
+ colors.push(styleColors[i * 4 + c]);
37
+ }
38
+ return { styleIds: Uint32Array.from(ids), styleColors: Uint8Array.from(colors) };
39
+ }
40
+ /**
41
+ * Pre-pass the subgraph, mesh the targets in the load frame, and release the
42
+ * pre-pass cache on every exit (the per-content caches are keyed to this
43
+ * buffer and would otherwise leak into the next request).
44
+ */
45
+ export function remeshOnApi(api, req, now = () => performance.now()) {
46
+ const start = now();
47
+ try {
48
+ // Inside the `try`: a pre-pass that throws part-way may already have
49
+ // cached this buffer's index, which the next request must not inherit.
50
+ const prePass = api.buildPrePassOnce(req.buffer);
51
+ const prepassDone = now();
52
+ const jobs = filterJobsToTargets(prePass.jobs ?? new Uint32Array(), req.targets);
53
+ if (jobs.length === 0) {
54
+ return { meshes: [], csgFailures: 0, ms: { prepass: prepassDone - start, produce: 0 } };
55
+ }
56
+ const { frame } = req;
57
+ const collection = api.processGeometryBatch(req.buffer, jobs, prePass.unitScale, frame.x, frame.y, frame.z, frame.needsShift, prePass.voidKeys, prePass.voidCounts, prePass.voidValues, req.styleIds, req.styleColors, prePass.planeAngleToRadians, req.materialElementIds, req.materialColorCounts, req.materialColors);
58
+ // Read before conversion: `convertMeshCollectionToBatch` frees the collection.
59
+ let csgFailures;
60
+ try {
61
+ const diagnostics = collection.diagnostics;
62
+ csgFailures = diagnostics?.totalCsgFailures ?? 0;
63
+ }
64
+ catch (error) {
65
+ collection.free();
66
+ throw error;
67
+ }
68
+ const meshes = convertMeshCollectionToBatch(collection);
69
+ return { meshes, csgFailures, ms: { prepass: prepassDone - start, produce: now() - prepassDone } };
70
+ }
71
+ finally {
72
+ api.clearPrePassCache();
73
+ }
74
+ }
75
+ /**
76
+ * Pre-pass a whole model once and keep only its style wire, releasing the
77
+ * pre-pass cache. Copies each array so nothing aliases the wasm heap.
78
+ */
79
+ export function styleWireOnApi(api, source) {
80
+ try {
81
+ const prePass = api.buildPrePassOnce(source);
82
+ return {
83
+ styleIds: prePass.styleIds.slice(),
84
+ styleColors: prePass.styleColors.slice(),
85
+ materialElementIds: prePass.materialElementIds?.slice() ?? new Uint32Array(),
86
+ materialColorCounts: prePass.materialColorCounts?.slice() ?? new Uint32Array(),
87
+ materialColors: prePass.materialColors?.slice() ?? new Uint8Array(),
88
+ };
89
+ }
90
+ finally {
91
+ api.clearPrePassCache();
92
+ }
93
+ }
94
+ //# sourceMappingURL=remesh-core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remesh-core.js","sourceRoot":"","sources":["../../src/remesh/remesh-core.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAgB/D,OAAO,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AAuEzE,4EAA4E;AAC5E,MAAM,UAAU,iBAAiB,CAAC,GAAc,EAAE,MAAoB;IACpE,GAAG,CAAC,cAAc,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IACvC,GAAG,CAAC,sBAAsB,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IACvD,GAAG,CAAC,gBAAgB,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAC3C,GAAG,CAAC,oBAAoB,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;AACrD,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,mBAAmB,CAAC,IAAiB,EAAE,OAAoB;IACzE,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;IAChC,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5C,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAChC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAqB,EACrB,WAAuB,EACvB,IAAyB;IAEzB,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YAAE,SAAS;QACrC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YAAE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,WAAW,EAAE,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;AACnF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,GAAc,EAAE,GAAkB,EAAE,MAAoB,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;IACzG,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC;IACpB,IAAI,CAAC;QACH,qEAAqE;QACrE,uEAAuE;QACvE,MAAM,OAAO,GAAG,GAAG,CAAC,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAA+B,CAAC;QAC/E,MAAM,WAAW,GAAG,GAAG,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,mBAAmB,CAAC,OAAO,CAAC,IAAI,IAAI,IAAI,WAAW,EAAE,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QACjF,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,WAAW,GAAG,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1F,CAAC;QACD,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC;QACtB,MAAM,UAAU,GAAG,GAAG,CAAC,oBAAoB,CACzC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,SAAS,EACnC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,EAC3C,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,UAAU,EACxD,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,WAAW,EAAE,OAAO,CAAC,mBAAmB,EAC1D,GAAG,CAAC,kBAAkB,EAAE,GAAG,CAAC,mBAAmB,EAAE,GAAG,CAAC,cAAc,CACpE,CAAC;QACF,+EAA+E;QAC/E,IAAI,WAAmB,CAAC;QACxB,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,UAAU,CAAC,WAAwD,CAAC;YACxF,WAAW,GAAG,WAAW,EAAE,gBAAgB,IAAI,CAAC,CAAC;QACnD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,UAAU,CAAC,IAAI,EAAE,CAAC;YAClB,MAAM,KAAK,CAAC;QACd,CAAC;QACD,MAAM,MAAM,GAAG,4BAA4B,CAAC,UAAU,CAAC,CAAC;QACxD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,WAAW,GAAG,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,WAAW,EAAE,EAAE,CAAC;IACrG,CAAC;YAAS,CAAC;QACT,GAAG,CAAC,iBAAiB,EAAE,CAAC;IAC1B,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,GAAc,EAAE,MAAkB;IAC/D,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,GAAG,CAAC,gBAAgB,CAAC,MAAM,CAA+B,CAAC;QAC3E,OAAO;YACL,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,KAAK,EAAE;YAClC,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC,KAAK,EAAE;YACxC,kBAAkB,EAAE,OAAO,CAAC,kBAAkB,EAAE,KAAK,EAAE,IAAI,IAAI,WAAW,EAAE;YAC5E,mBAAmB,EAAE,OAAO,CAAC,mBAAmB,EAAE,KAAK,EAAE,IAAI,IAAI,WAAW,EAAE;YAC9E,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,KAAK,EAAE,IAAI,IAAI,UAAU,EAAE;SACpE,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,GAAG,CAAC,iBAAiB,EAAE,CAAC;IAC1B,CAAC;AACH,CAAC"}
@@ -0,0 +1,50 @@
1
+ /** Messages between `RemeshClient` and `remesh.worker.ts` (#6232 WP1). */
2
+ import type { MeshData } from '../types.js';
3
+ import type { RemeshConfig, RemeshRequest, RemeshResult, StyleWire } from './remesh-core.js';
4
+ export type RemeshWorkerInbound = {
5
+ type: 'init';
6
+ config: RemeshConfig;
7
+ wasmModule?: WebAssembly.Module;
8
+ wasmUrl?: string;
9
+ } | {
10
+ type: 'config';
11
+ config: RemeshConfig;
12
+ } | {
13
+ type: 'remesh';
14
+ requestId: number;
15
+ request: RemeshRequest;
16
+ } | {
17
+ type: 'style-wire';
18
+ requestId: number;
19
+ source: Uint8Array;
20
+ };
21
+ export type RemeshWorkerOutbound = {
22
+ type: 'ready';
23
+ } | {
24
+ type: 'init-error';
25
+ message: string;
26
+ } | {
27
+ type: 'result';
28
+ requestId: number;
29
+ result: RemeshResult;
30
+ } | {
31
+ type: 'style-wire';
32
+ requestId: number;
33
+ wire: StyleWire;
34
+ } | {
35
+ type: 'error';
36
+ requestId: number;
37
+ message: string;
38
+ };
39
+ /** The large per-mesh buffers, moved rather than copied across the boundary. */
40
+ export declare function meshTransferables(meshes: readonly MeshData[]): ArrayBuffer[];
41
+ /** The wire's buffers, moved back to the caller. */
42
+ export declare function styleWireTransferables(wire: StyleWire): ArrayBuffer[];
43
+ /**
44
+ * Run `handle` for each message strictly in order. A handler that rejects is
45
+ * reported to `onError` and the queue moves on: chaining the next message
46
+ * onto a rejected promise would skip every later message for the life of the
47
+ * worker, so its callers would wait forever.
48
+ */
49
+ export declare function serialQueue<T>(handle: (message: T) => Promise<void>, onError: (error: unknown) => void): (message: T) => void;
50
+ //# sourceMappingURL=remesh-protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remesh-protocol.d.ts","sourceRoot":"","sources":["../../src/remesh/remesh-protocol.ts"],"names":[],"mappings":"AAIA,0EAA0E;AAE1E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7F,MAAM,MAAM,mBAAmB,GAC3B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,YAAY,CAAC;IAAC,UAAU,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GACzF;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,YAAY,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,aAAa,CAAA;CAAE,GAC7D;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,UAAU,CAAA;CAAE,CAAC;AAElE,MAAM,MAAM,oBAAoB,GAC5B;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACvC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,YAAY,CAAA;CAAE,GAC3D;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,SAAS,CAAA;CAAE,GAC1D;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1D,gFAAgF;AAChF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,QAAQ,EAAE,GAAG,WAAW,EAAE,CAQ5E;AAED,oDAAoD;AACpD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,SAAS,GAAG,WAAW,EAAE,CAGrE;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAC3B,MAAM,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,EACrC,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAChC,CAAC,OAAO,EAAE,CAAC,KAAK,IAAI,CAKtB"}
@@ -0,0 +1,32 @@
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
+ /** The large per-mesh buffers, moved rather than copied across the boundary. */
5
+ export function meshTransferables(meshes) {
6
+ const buffers = new Set();
7
+ for (const mesh of meshes) {
8
+ for (const view of [mesh.positions, mesh.normals, mesh.indices, mesh.uvs]) {
9
+ if (view && view.buffer instanceof ArrayBuffer)
10
+ buffers.add(view.buffer);
11
+ }
12
+ }
13
+ return [...buffers];
14
+ }
15
+ /** The wire's buffers, moved back to the caller. */
16
+ export function styleWireTransferables(wire) {
17
+ return [wire.styleIds, wire.styleColors, wire.materialElementIds, wire.materialColorCounts, wire.materialColors]
18
+ .flatMap((view) => (view.buffer instanceof ArrayBuffer ? [view.buffer] : []));
19
+ }
20
+ /**
21
+ * Run `handle` for each message strictly in order. A handler that rejects is
22
+ * reported to `onError` and the queue moves on: chaining the next message
23
+ * onto a rejected promise would skip every later message for the life of the
24
+ * worker, so its callers would wait forever.
25
+ */
26
+ export function serialQueue(handle, onError) {
27
+ let tail = Promise.resolve();
28
+ return (message) => {
29
+ tail = tail.then(() => handle(message)).catch(onError);
30
+ };
31
+ }
32
+ //# sourceMappingURL=remesh-protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remesh-protocol.js","sourceRoot":"","sources":["../../src/remesh/remesh-protocol.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAoB/D,gFAAgF;AAChF,MAAM,UAAU,iBAAiB,CAAC,MAA2B;IAC3D,MAAM,OAAO,GAAG,IAAI,GAAG,EAAe,CAAC;IACvC,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAC1B,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1E,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,YAAY,WAAW;gBAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AACtB,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,sBAAsB,CAAC,IAAe;IACpD,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,kBAAkB,EAAE,IAAI,CAAC,mBAAmB,EAAE,IAAI,CAAC,cAAc,CAAC;SAC7G,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,YAAY,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAClF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CACzB,MAAqC,EACrC,OAAiC;IAEjC,IAAI,IAAI,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;IAC5C,OAAO,CAAC,OAAO,EAAE,EAAE;QACjB,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACzD,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=remesh.worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remesh.worker.d.ts","sourceRoot":"","sources":["../../src/remesh/remesh.worker.ts"],"names":[],"mappings":""}
@@ -0,0 +1,102 @@
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
+ * Long-lived re-mesh worker (#6232 WP1). Instantiates the wasm engine ONCE,
6
+ * then meshes subgraph buffers on request with `remeshOnApi`. Messages are
7
+ * handled strictly in order, so a `config` posted between two requests
8
+ * applies to the second and not the first.
9
+ *
10
+ * A wasm trap poisons only the `IfcAPI` that took it: that handle is dropped
11
+ * and the next request gets a fresh one with the current config.
12
+ */
13
+ import init, { initSync, IfcAPI } from '@ifc-lite/wasm';
14
+ import { initWasmWithRetry } from '../wasm-init-retry.js';
15
+ import { freeWasmInstanceQuietly } from '../wasm-instance-free.js';
16
+ import { applyRemeshConfig, remeshOnApi, styleWireOnApi } from './remesh-core.js';
17
+ import { meshTransferables, serialQueue, styleWireTransferables, } from './remesh-protocol.js';
18
+ const scope = self;
19
+ let config = null;
20
+ let api = null;
21
+ function post(message, transfer = []) {
22
+ scope.postMessage(message, transfer);
23
+ }
24
+ function errorMessage(error) {
25
+ return error instanceof Error ? error.message : String(error);
26
+ }
27
+ function currentApi() {
28
+ if (!config)
29
+ throw new Error('remesh worker used before init');
30
+ if (api)
31
+ return api;
32
+ const fresh = new IfcAPI();
33
+ try {
34
+ applyRemeshConfig(fresh, config);
35
+ }
36
+ catch (error) {
37
+ freeWasmInstanceQuietly(fresh);
38
+ throw error;
39
+ }
40
+ api = fresh;
41
+ return fresh;
42
+ }
43
+ async function handle(message) {
44
+ switch (message.type) {
45
+ case 'init': {
46
+ config = message.config;
47
+ try {
48
+ if (message.wasmModule)
49
+ initSync({ module: message.wasmModule });
50
+ else
51
+ await initWasmWithRetry(() => init(message.wasmUrl), { label: 'remesh.worker' });
52
+ currentApi();
53
+ post({ type: 'ready' });
54
+ }
55
+ catch (error) {
56
+ post({ type: 'init-error', message: errorMessage(error) });
57
+ }
58
+ return;
59
+ }
60
+ case 'config': {
61
+ config = message.config;
62
+ try {
63
+ if (api)
64
+ applyRemeshConfig(api, config);
65
+ }
66
+ catch (error) {
67
+ // No request to answer yet: drop the half-configured handle, so the
68
+ // next request rebuilds it and reports this same failure to its caller.
69
+ console.error('[remesh.worker] config rejected:', errorMessage(error));
70
+ freeWasmInstanceQuietly(api);
71
+ api = null;
72
+ }
73
+ return;
74
+ }
75
+ case 'remesh':
76
+ case 'style-wire': {
77
+ try {
78
+ if (message.type === 'remesh') {
79
+ const result = remeshOnApi(currentApi(), message.request);
80
+ post({ type: 'result', requestId: message.requestId, result }, meshTransferables(result.meshes));
81
+ }
82
+ else {
83
+ const wire = styleWireOnApi(currentApi(), message.source);
84
+ post({ type: 'style-wire', requestId: message.requestId, wire }, styleWireTransferables(wire));
85
+ }
86
+ }
87
+ catch (error) {
88
+ if (error instanceof WebAssembly.RuntimeError) {
89
+ freeWasmInstanceQuietly(api);
90
+ api = null;
91
+ }
92
+ post({ type: 'error', requestId: message.requestId, message: errorMessage(error) });
93
+ }
94
+ return;
95
+ }
96
+ }
97
+ }
98
+ // `handle` answers every request itself; this only guards the queue against
99
+ // an escape it did not anticipate, which would otherwise stall it for good.
100
+ const enqueue = serialQueue(handle, (error) => console.error('[remesh.worker] unhandled:', errorMessage(error)));
101
+ scope.onmessage = (event) => enqueue(event.data);
102
+ //# sourceMappingURL=remesh.worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remesh.worker.js","sourceRoot":"","sources":["../../src/remesh/remesh.worker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /** One worker's shard-resolved styled-item slice (`resolveStyledItemsShard`). */
2
+ export interface StylesSlice {
3
+ orphanIds: Uint32Array;
4
+ orphanColors: Float32Array;
5
+ geomIds: Uint32Array;
6
+ geomColors: Float32Array;
7
+ /** #5582 `[metallic, roughness]` per geometry id; absent from an older wasm. */
8
+ geomFinishes?: Float32Array;
9
+ error?: string;
10
+ }
11
+ /** The merged columns `finalizePrepassStyles` consumes. */
12
+ export interface MergedShardStyles {
13
+ orphanIds: Uint32Array;
14
+ orphanColors: Float32Array;
15
+ geomIds: Uint32Array;
16
+ geomColors: Float32Array;
17
+ /** Two floats per `geomIds` entry, NaN where a slice carried no finish. */
18
+ geomFinishes: Float32Array;
19
+ }
20
+ /**
21
+ * Merge the shard-resolved style maps IN SLICE ORDER with first-wins per id,
22
+ * reproducing the serial resolver's file-order precedence. A geometry id's
23
+ * finish comes from the same slice as its colour, so the winner's colour and
24
+ * finish can never come from two different styled items.
25
+ */
26
+ export declare function mergeShardStyleSlices(slices: readonly (StylesSlice | null)[]): MergedShardStyles;
27
+ //# sourceMappingURL=shard-style-merge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shard-style-merge.d.ts","sourceRoot":"","sources":["../src/shard-style-merge.ts"],"names":[],"mappings":"AAIA,iFAAiF;AACjF,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,WAAW,CAAC;IAAC,YAAY,EAAE,YAAY,CAAC;IACnD,OAAO,EAAE,WAAW,CAAC;IAAC,UAAU,EAAE,YAAY,CAAC;IAC/C,gFAAgF;IAChF,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,2DAA2D;AAC3D,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,WAAW,CAAC;IAAC,YAAY,EAAE,YAAY,CAAC;IACnD,OAAO,EAAE,WAAW,CAAC;IAAC,UAAU,EAAE,YAAY,CAAC;IAC/C,2EAA2E;IAC3E,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,EAAE,GAAG,iBAAiB,CAkChG"}
@@ -0,0 +1,54 @@
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
+ * Merge the shard-resolved style maps IN SLICE ORDER with first-wins per id,
6
+ * reproducing the serial resolver's file-order precedence. A geometry id's
7
+ * finish comes from the same slice as its colour, so the winner's colour and
8
+ * finish can never come from two different styled items.
9
+ */
10
+ export function mergeShardStyleSlices(slices) {
11
+ const orphanSeen = new Set();
12
+ const geomSeen = new Set();
13
+ const orphanWin = [];
14
+ const geomWin = [];
15
+ for (const slice of slices) {
16
+ if (!slice)
17
+ continue;
18
+ if (slice.error)
19
+ console.warn(`[stream][shard] style slice failed (degraded colours possible): ${slice.error}`);
20
+ for (let i = 0; i < slice.orphanIds.length; i++) {
21
+ const id = slice.orphanIds[i];
22
+ if (!orphanSeen.has(id)) {
23
+ orphanSeen.add(id);
24
+ orphanWin.push([id, slice, i]);
25
+ }
26
+ }
27
+ for (let i = 0; i < slice.geomIds.length; i++) {
28
+ const id = slice.geomIds[i];
29
+ if (!geomSeen.has(id)) {
30
+ geomSeen.add(id);
31
+ geomWin.push([id, slice, i]);
32
+ }
33
+ }
34
+ }
35
+ const orphanIds = new Uint32Array(orphanWin.length);
36
+ const orphanColors = new Float32Array(orphanWin.length * 4);
37
+ orphanWin.forEach(([id, slice, i], k) => {
38
+ orphanIds[k] = id;
39
+ orphanColors.set(slice.orphanColors.subarray(i * 4, i * 4 + 4), k * 4);
40
+ });
41
+ const geomIds = new Uint32Array(geomWin.length);
42
+ const geomColors = new Float32Array(geomWin.length * 4);
43
+ const geomFinishes = new Float32Array(geomWin.length * 2).fill(NaN);
44
+ geomWin.forEach(([id, slice, i], k) => {
45
+ geomIds[k] = id;
46
+ geomColors.set(slice.geomColors.subarray(i * 4, i * 4 + 4), k * 4);
47
+ // Length-guarded: a short or missing finish column leaves this id NaN.
48
+ const finishes = slice.geomFinishes;
49
+ if (finishes && i * 2 + 1 < finishes.length)
50
+ geomFinishes.set(finishes.subarray(i * 2, i * 2 + 2), k * 2);
51
+ });
52
+ return { orphanIds, orphanColors, geomIds, geomColors, geomFinishes };
53
+ }
54
+ //# sourceMappingURL=shard-style-merge.js.map