@selvajs/visualization 1.0.1 → 1.2.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.
- package/README.md +80 -75
- package/dist/parse.cjs +3 -3
- package/dist/parse.cjs.map +1 -1
- package/dist/parse.d.cts +15 -17
- package/dist/parse.d.ts +15 -17
- package/dist/parse.js +3 -3
- package/dist/parse.js.map +1 -1
- package/dist/render.cjs +4 -4
- package/dist/render.cjs.map +1 -1
- package/dist/render.d.cts +66 -7
- package/dist/render.d.ts +66 -7
- package/dist/render.js +4 -4
- package/dist/render.js.map +1 -1
- package/dist/scene.cjs +1 -1
- package/dist/scene.cjs.map +1 -1
- package/dist/scene.d.cts +74 -9
- package/dist/scene.d.ts +74 -9
- package/dist/scene.js +1 -1
- package/dist/scene.js.map +1 -1
- package/dist/types-C0V-dIU-.d.cts +83 -0
- package/dist/types-C0V-dIU-.d.ts +83 -0
- package/package.json +6 -6
- package/dist/types-Di80Y609.d.cts +0 -34
- package/dist/types-Di80Y609.d.ts +0 -34
package/README.md
CHANGED
|
@@ -1,105 +1,98 @@
|
|
|
1
1
|
# `@selvajs/visualization`
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
no Svelte, no runes, `three` as a peer dep. Consumers build their own UI over it.
|
|
3
|
+
Show Rhino/Grasshopper geometry in a browser, with Three.js.
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
No Svelte, no React, no DOM widgets — you get a viewer and a parser, and you build your own UI on
|
|
6
|
+
top. `three` is a peer dep: your app owns the copy.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
## Install
|
|
9
9
|
|
|
10
|
+
```bash
|
|
11
|
+
pnpm add @selvajs/visualization three
|
|
10
12
|
```
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
|
|
14
|
+
## The whole thing in one example
|
|
15
|
+
|
|
16
|
+
Two calls: build a viewer on a canvas, then put parsed geometry into it.
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
import { initThree, updateScene } from '@selvajs/visualization/render';
|
|
20
|
+
import { getThreeObjectsFromComputeResponse } from '@selvajs/visualization/parse';
|
|
21
|
+
|
|
22
|
+
const viewer = initThree(canvas, {
|
|
23
|
+
look: 'technical',
|
|
24
|
+
grid: { enabled: true },
|
|
25
|
+
edges: { enabled: true }
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// `response` is what Rhino.Compute returned for your definition.
|
|
29
|
+
const objects = await getThreeObjectsFromComputeResponse(response);
|
|
30
|
+
updateScene(viewer.scene, objects, viewer.camera, viewer.controls, false);
|
|
31
|
+
viewer.applyEdges(viewer.scene);
|
|
32
|
+
|
|
33
|
+
viewer.dispose(); // when the canvas goes away — frees the GL context, not just its objects
|
|
18
34
|
```
|
|
19
35
|
|
|
20
|
-
|
|
21
|
-
stayed behind is the three.js mesh ownership policy solve's result memo needs but deliberately
|
|
22
|
-
doesn't know: `meshPolicy` in [`parse/mesh-policy.ts`](./src/parse/mesh-policy.ts).
|
|
36
|
+
That is the full path: **compute response → THREE objects → scene**.
|
|
23
37
|
|
|
24
|
-
|
|
25
|
-
layer import siblings by relative path; other layers import the barrel. That way a layer's internals
|
|
26
|
-
can be refactored freely without touching consumers.
|
|
38
|
+
## The three parts
|
|
27
39
|
|
|
28
|
-
|
|
40
|
+
Each is its own import path, so a bundler can drop the ones you don't use.
|
|
29
41
|
|
|
30
|
-
|
|
42
|
+
| Import | What it gives you |
|
|
43
|
+
| ------------------------------- | -------------------------------------------------------------------- |
|
|
44
|
+
| `@selvajs/visualization/parse` | backend payload → THREE meshes, curves, points |
|
|
45
|
+
| `@selvajs/visualization/render` | the viewer: camera, lights, grid, edges, gizmo, measure, render loop |
|
|
46
|
+
| `@selvajs/visualization/scene` | an object list over a live scene: layers, visibility, selection |
|
|
31
47
|
|
|
32
48
|
```ts
|
|
33
|
-
import {
|
|
34
|
-
import { initThree,
|
|
49
|
+
import { getThreeObjectsFromComputeResponse } from '@selvajs/visualization/parse';
|
|
50
|
+
import { initThree, type ThreeViewer } from '@selvajs/visualization/render';
|
|
35
51
|
import { createSceneOutliner } from '@selvajs/visualization/scene';
|
|
36
52
|
```
|
|
37
53
|
|
|
38
|
-
|
|
39
|
-
consumers need (`VisualizationError`, the logger seam, the look vocabulary) are re-exported from
|
|
40
|
-
`/render`. The root `.` entrypoint re-exports nothing on purpose: importing from a layer keeps the
|
|
41
|
-
layering enforced by the import graph rather than merely documented.
|
|
42
|
-
|
|
43
|
-
### The API is deliberately minimal
|
|
54
|
+
There is no root (`.`) export on purpose — always import from one of the three.
|
|
44
55
|
|
|
45
|
-
|
|
56
|
+
Each folder has its own README: [parse](./src/parse/README.md), [render](./src/render/README.md),
|
|
57
|
+
[scene](./src/scene/README.md).
|
|
46
58
|
|
|
47
|
-
|
|
48
|
-
tool, render pipeline and the camera's near-clip fitting, and returns the live instances on
|
|
49
|
-
[`ThreeViewer`](./src/render/scene-setup/viewer.ts). Configure them through
|
|
50
|
-
`ThreeInitializerOptions`, reach them through the viewer (`viewer.grid`, `viewer.measureTool`,
|
|
51
|
-
`viewer.applyEdges`, …). The factories themselves are internal — their handle _types_ are exported
|
|
52
|
-
so hosts can annotate what they hold.
|
|
53
|
-
- **`createSceneOutliner` composes the scene layer.** Content filtering, layer grouping, visibility
|
|
54
|
-
and selection state are reachable via `outliner.visibility` / `.selection` / `.layerGroups()`.
|
|
55
|
-
- **The SLVA binary wire format is private.** Magics, version gates, flag bits and the low-level
|
|
56
|
-
binary parser are implementation details of `parseBinaryMeshBatch*` and change without a major bump.
|
|
59
|
+
## How the parts relate
|
|
57
60
|
|
|
58
|
-
|
|
59
|
-
a
|
|
61
|
+
```
|
|
62
|
+
scene/ reads a live scene ─┐
|
|
63
|
+
render/ owns the scene ├─ siblings: none imports another
|
|
64
|
+
parse/ builds the content ─┘
|
|
65
|
+
↓ all three use
|
|
66
|
+
shared/ errors, logging, looks, colour + GPU helpers [internal, not published]
|
|
67
|
+
```
|
|
60
68
|
|
|
61
|
-
`
|
|
62
|
-
|
|
63
|
-
[`src/scene/README.md`](./src/scene/README.md).
|
|
69
|
+
`render/` puts geometry in the scene; `parse/` makes that geometry; `scene/` only looks at what is
|
|
70
|
+
there. A host app wires them together — that's the point.
|
|
64
71
|
|
|
65
|
-
|
|
72
|
+
`shared/` is internal. The bits you'd want from it (`VisualizationError`, `setLogger`, `LOOKS`) are
|
|
73
|
+
re-exported from `/render`.
|
|
66
74
|
|
|
67
|
-
|
|
68
|
-
(edge overlays, the screen-space edge pass, AO, the measure tool) can actually be checked, since
|
|
69
|
-
jsdom has no WebGL.
|
|
75
|
+
## Run the demos
|
|
70
76
|
|
|
71
77
|
```bash
|
|
72
78
|
pnpm example # http://localhost:5173
|
|
73
79
|
```
|
|
74
80
|
|
|
75
|
-
|
|
76
|
-
`.slvm` mesh file through the same parse + `updateScene` calls `Viewer.svelte` makes), and **Display Items**
|
|
77
|
-
(a GH compute response through `getThreeMeshesFromComputeResponse`).
|
|
81
|
+
Five pages, ordered so you can work down them:
|
|
78
82
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
1. **Getting Started** — the smallest real app, with no harness around it. Its source is the example
|
|
84
|
+
above, fleshed out; read it first.
|
|
85
|
+
2. **Display Items** — what actually comes out of a GH compute response.
|
|
86
|
+
3. **Outliner** — an object-list panel over a live scene: layers, search, hide/show, selection.
|
|
87
|
+
4. **Viewer — Full API** — every `initThree` control on one panel.
|
|
88
|
+
5. **Mesh File** — a `.slvm` through the exact calls the Selva app makes, for checking the look 1:1.
|
|
83
89
|
|
|
84
|
-
|
|
90
|
+
This is also the only place the GPU parts — edge overlays, ambient occlusion, the measure tool — can
|
|
91
|
+
be checked at all; the test suite runs in jsdom, which has no WebGL.
|
|
85
92
|
|
|
86
|
-
|
|
87
|
-
dependency. It owns its
|
|
88
|
-
own errors ([`shared/errors.ts`](./src/shared/errors.ts)), logging
|
|
89
|
-
([`shared/logger.ts`](./src/shared/logger.ts)) and base64 decoding
|
|
90
|
-
([`shared/encoding.ts`](./src/shared/encoding.ts)) rather than importing them from
|
|
91
|
-
`@selvajs/compute`, so mesh conversion and the viewer work for a consumer with neither Selva nor
|
|
92
|
-
Rhino.Compute.
|
|
93
|
+
## Logging
|
|
93
94
|
|
|
94
|
-
|
|
95
|
-
[`parse/webdisplay/response-envelope.ts`](./src/parse/webdisplay/response-envelope.ts) as **only the
|
|
96
|
-
fields the parser reads**, not as a named import. Compute's `GrasshopperComputeResponse` has more
|
|
97
|
-
fields and still satisfies it, so neither package has to depend on the other.
|
|
98
|
-
|
|
99
|
-
### Unified logging
|
|
100
|
-
|
|
101
|
-
The package logs nothing by default. To route its output into a host's logger — including
|
|
102
|
-
`@selvajs/compute`'s, so both packages share a sink:
|
|
95
|
+
Silent by default. To send its logs wherever your app's logs go:
|
|
103
96
|
|
|
104
97
|
```ts
|
|
105
98
|
import { setLogger } from '@selvajs/visualization/render';
|
|
@@ -108,7 +101,19 @@ import { getLogger } from '@selvajs/compute/core';
|
|
|
108
101
|
setLogger(getLogger());
|
|
109
102
|
```
|
|
110
103
|
|
|
111
|
-
##
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
104
|
+
## Notes for contributors
|
|
105
|
+
|
|
106
|
+
- **Layers depend downward only.** `parse/`, `render/` and `scene/` never import each other; all
|
|
107
|
+
three may import `shared/`. Where a file belongs follows from what it depends on.
|
|
108
|
+
- **A layer's `index.ts` is its only cross-layer import surface.** Inside a layer, import siblings
|
|
109
|
+
by relative path.
|
|
110
|
+
- **The API stays minimal.** A published symbol is a promise to keep it. `initThree` builds the
|
|
111
|
+
toolkit and hands back live instances on `viewer` (`viewer.grid`, `viewer.measureTool`, …), so
|
|
112
|
+
those factories stay unexported. The SLVA binary format is private to `parseMeshBatch*`.
|
|
113
|
+
- **No Selva dependencies.** Only `fflate`, plus `three` as a peer dep. Errors, logging and base64
|
|
114
|
+
live in `shared/` rather than coming from `@selvajs/compute`, so the viewer works for someone with
|
|
115
|
+
neither Selva nor Rhino.Compute. The compute response shape is declared structurally in
|
|
116
|
+
[`parse/webdisplay/response-envelope.ts`](./src/parse/webdisplay/response-envelope.ts).
|
|
117
|
+
- **The solve session is not here** — it lives in `@selvajs/solve/client`. What stayed behind is the
|
|
118
|
+
mesh-ownership policy that solve's result memo needs but doesn't want to know about:
|
|
119
|
+
[`parse/mesh-policy.ts`](./src/parse/mesh-policy.ts).
|
package/dist/parse.cjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./rolldown-runtime-BocRIvOZ.cjs"),t=require("./gpu-dispose-DrN-ryj5.cjs");let n=require("three");n=e.t(n,1);let r=require("three/addons/lines/Line2.js"),i=require("three/addons/lines/LineGeometry.js"),a=require("three/addons/lines/LineMaterial.js"),o=require("fflate");function s(){let e=globalThis.Buffer;return typeof e==`function`?e:void 0}function c(e){let n=e.replace(/[\t\n\f\r ]/g,``);if(n.length%4==0&&(n=n.replace(/={1,2}$/,``)),n.length%4==1||!/^[A-Za-z0-9+/]*$/.test(n))throw new t.d(`Invalid base64 input.`,t.u.ENCODING_ERROR,{context:{inputLength:e.length}});let r=s();if(r)return new Uint8Array(r.from(n,`base64`));if(typeof globalThis.atob==`function`){let e=globalThis.atob(n),t=new Uint8Array(e.length);for(let n=0;n<e.length;n++)t[n]=e.charCodeAt(n)&255;return t}throw new t.d(`Base64 decoding not supported in this environment.`,t.u.INVALID_STATE,{context:{environmentInfo:`atob or Buffer not available`}})}function l(e){return e.map(e=>{let t=e.clone(!0),n=[];e.traverse(e=>n.push(e));let r=0;return t.traverse(e=>{let t=n[r++],i=e;t.geometry&&(i.geometry=t.geometry.clone())}),t})}function u(e){e.forEach(e=>t.t(e,{materials:!1}))}const d={clone:l,release:u};function f(e,t){let r=t??1;return{color:new n.Color(e??`#ffffff`),transparent:r<1,opacity:r}}function p(e){let t=m(e);if(!t)return null;let n=new i.LineGeometry;n.setPositions(t);let o=f(e.color,e.opacity),s=new a.LineMaterial({color:o.color}),c=s;c.linewidth=e.width??2,c.transparent=o.transparent,c.opacity=o.opacity;let l=new r.Line2(n,s);return l.computeLineDistances(),l.name=e.name,l.userData={source:`compute`,id:e.id,layer:e.layer,kind:`curve`,metadata:e.metadata},l}function m(e){if(!e.points)throw new t.d(`Curve display item '${e.id}' has no tessellated points. It was produced by an outdated Display component — upgrade it in Grasshopper (Solution → Upgrade obsolete components) and re-save the definition.`,t.u.INVALID_CONFIG,{context:{itemId:e.id,kind:e.kind}});return e.points.length>=6?e.points:null}function h(e){let{position:r}=e;if(!r||typeof r.X!=`number`||!Number.isFinite(r.X)||typeof r.Y!=`number`||!Number.isFinite(r.Y)||typeof r.Z!=`number`||!Number.isFinite(r.Z))return t.c().warn(`Skipping point display item with missing or non-finite position (id: ${String(e.id)}).`),null;let i=new n.BufferGeometry;i.setAttribute(`position`,new n.Float32BufferAttribute([r.X,r.Y,r.Z],3));let a=new n.PointsMaterial({...f(e.color,e.opacity),size:6,sizeAttenuation:!1}),o=new n.Points(i,a);return o.name=e.name,o.userData={source:`compute`,id:e.id,layer:e.layer,kind:`point`,metadata:e.metadata},o}function g(e){if(!e||e.length===0)return[];let n=[];for(let r of e)switch(r.kind){case`curve`:{let e=p(r);e&&n.push(e);break}case`point`:{let e=h(r);e&&n.push(e);break}default:{let e=r;t.c().warn(`Skipping unknown display item kind: ${String(e.kind)}`);break}}return n}const _=new Uint16Array(new Uint8Array([1,0]).buffer)[0]===1;function v(e){return typeof e==`string`?c(e):e instanceof Uint8Array?e:new Uint8Array(e)}function y(e){if(e.byteLength<8)return e;let t=new DataView(e.buffer,e.byteOffset,e.byteLength);if(t.getUint32(0,!0)!==1515605075)return e;let n=t.getUint32(4,!0),r=e.subarray(8),i=Math.max(r.byteLength*1032+1024,1<<20);if(n>i)throw k(`SLVZ header declares an implausible uncompressed length`,{uncompressedLen:n,deflatedBytes:r.byteLength,maxPlausibleLen:i});let a;try{a=(0,o.inflateSync)(r,{out:new Uint8Array(n+1)})}catch(e){throw k(`Failed to inflate SLVZ blob: ${e instanceof Error?e.message:String(e)}`,{uncompressedLen:n,deflatedBytes:r.byteLength})}if(a.byteLength!==n)throw k(`SLVZ payload inflated to a different size than the header declares.`,{declaredLen:n,actualLen:a.byteLength,deflatedBytes:r.byteLength});return a}function b(e){if(typeof TextDecoder<`u`)return new TextDecoder(`utf-8`).decode(e);if(globalThis.Buffer!==void 0)return globalThis.Buffer.from(e).toString(`utf-8`);throw new t.d(`No UTF-8 decoder available in this environment.`,t.u.INVALID_STATE)}function x(e,t,n){if(n===0)return new Int16Array;if(t%2==0)return new Int16Array(e,t,n);let r=new Uint8Array(n*2);return r.set(new Uint8Array(e,t,n*2)),new Int16Array(r.buffer)}function S(e,t,n){if(n===0)return new Float32Array;if(t%4==0)return new Float32Array(e,t,n);let r=new Uint8Array(n*4);return r.set(new Uint8Array(e,t,n*4)),new Float32Array(r.buffer)}function C(e,t,n){if(n===0)return new Uint16Array;if(t%2==0)return new Uint16Array(e,t,n);let r=new Uint8Array(n*2);return r.set(new Uint8Array(e,t,n*2)),new Uint16Array(r.buffer)}function ee(e,t,n){if(n===0)return new Uint32Array;if(t%4==0)return new Uint32Array(e,t,n);let r=new Uint8Array(n*4);return r.set(new Uint8Array(e,t,n*4)),new Uint32Array(r.buffer)}function w(e,t){if(e.length!==0&&!(e instanceof Uint16Array&&t>65535)){for(let n=0;n<e.length;n++)if(e[n]>=t)throw k(`Index out of range of vertexCount.`,{indexPosition:n,indexValue:e[n],vertexCount:t})}}function T(e){return e>>>1^-(e&1)}function E(e){let t=new Int16Array(e.length),n=0,r=0,i=0;for(let a=0;a<e.length;a+=3)n=n+T(e[a])<<16>>16,r=r+T(e[a+1])<<16>>16,i=i+T(e[a+2])<<16>>16,t[a]=n,t[a+1]=r,t[a+2]=i;return t}function D(e){let t=new Uint16Array(e.length),n=0;for(let r=0;r<e.length;r++)n=n+T(e[r])&65535,t[r]=n;return t}function O(e){let t=new Uint32Array(e.length),n=0;for(let r=0;r<e.length;r++)n=n+T(e[r])>>>0,t[r]=n;return t}function k(e,n){return new t.d(e,t.u.VALIDATION_ERROR,{context:n})}function te(e,t,n,r,i){if(n+36>e.byteLength)throw k(`Insufficient data to read UV chunk header.`,{expectedBytes:36,availableBytes:e.byteLength-n,offset:n});let a=t.getUint32(n,!0);n+=4;let o=t.getFloat64(n,!0);n+=8;let s=t.getFloat64(n,!0);n+=8;let c=t.getFloat64(n,!0);n+=8;let l=t.getFloat64(n,!0);n+=8;let u=r*2,d=a===1,f=u*(d?4:2);if(n+f>e.byteLength)throw k(`Insufficient data to read UV chunk.`,{expectedBytes:f,availableBytes:e.byteLength-n,offset:n,uvFormat:a,vertexCount:r});let p=e.byteOffset+n,m;if(d)m=S(e.buffer,p,u).slice();else{let t=C(e.buffer,p,u);m=new Float32Array(u);let n=0,r=0;for(let e=0;e<u;e+=2)i?(n=n+T(t[e])&65535,r=r+T(t[e+1])&65535):(n=t[e],r=t[e+1]),m[e]=o+n*c,m[e+1]=s+r*l}return{uvs:m,offset:n+f}}function ne(e,t,n,r){let i=n*3;if(t+i>e.byteLength)throw k(`Insufficient data to read vertex-color chunk.`,{expectedBytes:i,availableBytes:e.byteLength-t,offset:t,vertexCount:n});let a=e.subarray(t,t+i);if(!r)return a.slice();let o=new Uint8Array(i),s=0,c=0,l=0;for(let e=0;e<i;e+=3)s=s+T(a[e])&255,c=c+T(a[e+1])&255,l=l+T(a[e+2])&255,o[e]=s,o[e+1]=c,o[e+2]=l;return o}function A(e){let t=j(e),n;n=t.isFloat32?t.vertexData:t.deltaEncoded?E(t.vertexData):t.vertexData;let r=t.indexData;return t.deltaEncoded&&(r=r instanceof Uint16Array?D(r):O(r)),w(r,t.vertexCount),{metadata:t.metadata,flags:t.flags,vertices:n,indices:r,origin:t.origin,scale:t.scale,uvs:t.uvs,colors:t.colors}}function j(e){if(!_)throw new t.d(`SLVA parsing requires a little-endian host: the zero-copy geometry readers view the wire bytes in host byte order.`,t.u.ENVIRONMENT_ERROR);let n=y(v(e)),r=new DataView(n.buffer,n.byteOffset,n.byteLength);if(n.byteLength<12)throw k(`Blob too small to contain SLVA header.`,{expectedBytes:12,availableBytes:n.byteLength});let i=0,a=r.getUint32(i,!0);if(i+=4,a!==1096174675)throw k(`Invalid SLVA magic: 0x${a.toString(16)}`,{expectedMagic:`0x41564c53`,actualMagic:`0x${a.toString(16)}`});let o=r.getUint32(i,!0);if(i+=4,o<1||o>3)throw k(`Unsupported SLVA version: ${o}`,{minSupportedVersion:1,maxSupportedVersion:3,actualVersion:o});let s=r.getUint32(i,!0);if(i+=4,i+s>n.byteLength)throw k(`Insufficient data to read metadata JSON.`,{expectedBytes:s,availableBytes:n.byteLength-i,offset:i});let c=n.subarray(i,i+s);i+=s;let l;try{l=JSON.parse(b(c))}catch(e){throw k(`Failed to parse metadata JSON: ${e instanceof Error?e.message:String(e)}`,{metadataLen:s})}if(i+56>n.byteLength)throw k(`Insufficient data to read geometry header.`,{expectedBytes:56,availableBytes:n.byteLength-i,offset:i});let u=r.getUint32(i,!0);i+=4;let d=r.getFloat64(i,!0);i+=8;let f=r.getFloat64(i,!0);i+=8;let p=r.getFloat64(i,!0);i+=8;let m=r.getFloat64(i,!0);i+=8;let h=r.getFloat64(i,!0);i+=8;let g=r.getFloat64(i,!0);i+=8;let w=r.getUint32(i,!0);i+=4;let T=!!(u&1),E=!!(u&4),D=w*3,O=D*(T?4:2);if(i+O>n.byteLength)throw k(`Insufficient data to read vertices.`,{expectedBytes:O,availableBytes:n.byteLength-i,offset:i,useFloat32:T,vertexCount:w});let A=n.byteOffset+i,j;if(j=T?S(n.buffer,A,D):E?C(n.buffer,A,D):x(n.buffer,A,D),i+=O,i+4>n.byteLength)throw k(`Insufficient data to read index count.`,{expectedBytes:4,availableBytes:n.byteLength-i,offset:i});let M=r.getUint32(i,!0);i+=4;let N=!!(u&2),P=M*(N?2:4);if(i+P>n.byteLength)throw k(`Insufficient data to read indices.`,{expectedBytes:P,availableBytes:n.byteLength-i,offset:i,indexCount:M,useUint16Indices:N});let F=N?C(n.buffer,n.byteOffset+i,M):ee(n.buffer,n.byteOffset+i,M);i+=P;let I=null;if(u&8){let e=te(n,r,i,w,E);I=e.uvs,i=e.offset}let L=null;return u&16&&(L=ne(n,i,w,E)),{metadata:l,flags:u,vertexData:j,indexData:F,isFloat32:T,deltaEncoded:E,vertexCount:w,origin:[d,f,p],scale:[m,h,g],uvs:I,colors:L}}function M(e){let{isFloat32:t,deltaEncoded:n,origin:r,scale:i,uvs:a,colors:o,jobs:s}=e,c=e=>e>>>1^-(e&1),l;if(t)l=e.vertexData;else{let t;if(n){let n=e.vertexData;t=new Int16Array(n.length);let r=0,i=0,a=0;for(let e=0;e<n.length;e+=3)r=r+c(n[e])<<16>>16,i=i+c(n[e+1])<<16>>16,a=a+c(n[e+2])<<16>>16,t[e]=r,t[e+1]=i,t[e+2]=a}else t=e.vertexData;l=new Float32Array(t.length);let a=r[0],o=r[1],s=r[2],u=i[0],d=i[1],f=i[2];for(let e=0;e<t.length;e+=3)l[e]=a+(t[e]+32767)*u,l[e+1]=o+(t[e+1]+32767)*d,l[e+2]=s+(t[e+2]+32767)*f}let u;if(n){let t=e.indexData;if(t instanceof Uint16Array){let e=new Uint16Array(t.length),n=0;for(let r=0;r<t.length;r++)n=n+c(t[r])&65535,e[r]=n;u=e}else{let e=new Uint32Array(t.length),n=0;for(let r=0;r<t.length;r++)n=n+c(t[r])>>>0,e[r]=n;u=e}}else u=e.indexData;let d=l.length/3;for(let e=0;e<u.length;e++)if(u[e]>=d)throw Error(`Index ${u[e]} out of range of vertexCount ${d}`);let f=[];for(let e of s){let t=0,n=0;for(let r of e.windows)t+=r.vertexCount,n+=r.indexCount;let r=new Float32Array(t*3),i=new Uint32Array(n),s=a?new Float32Array(t*2):null,c=o?new Uint8Array(t*3):null,d=0,p=0;for(let t of e.windows){let e=t.vertexStart*3;r.set(l.subarray(e,e+t.vertexCount*3),d*3),s&&a&&s.set(a.subarray(t.vertexStart*2,(t.vertexStart+t.vertexCount)*2),d*2),c&&o&&c.set(o.subarray(e,e+t.vertexCount*3),d*3);let n=t.vertexStart,f=t.vertexStart+t.vertexCount,m=d-t.vertexStart;for(let e=0;e<t.indexCount;e++){let r=u[t.indexStart+e];if(r<n||r>=f)throw Error(`Index ${r} outside vertex window [${n}, ${f})`);i[p+e]=r+m}d+=t.vertexCount,p+=t.indexCount}let m=new Float32Array(t*3);for(let e=0;e<i.length;e+=3){let t=i[e]*3,n=i[e+1]*3,a=i[e+2]*3,o=r[a]-r[n],s=r[a+1]-r[n+1],c=r[a+2]-r[n+2],l=r[t]-r[n],u=r[t+1]-r[n+1],d=r[t+2]-r[n+2],f=s*d-c*u,p=c*l-o*d,h=o*u-s*l;m[t]+=f,m[t+1]+=p,m[t+2]+=h,m[n]+=f,m[n+1]+=p,m[n+2]+=h,m[a]+=f,m[a+1]+=p,m[a+2]+=h}for(let e=0;e<m.length;e+=3){let t=m[e],n=m[e+1],r=m[e+2],i=Math.sqrt(t*t+n*n+r*r)||1;m[e]=t/i,m[e+1]=n/i,m[e+2]=r/i}f.push({positions:r,normals:m,indices:i,uvs:s,colors:c})}return f}function N(){return[`const assemble = ${M.toString()};`,`self.onmessage = (event) => {`,` const { id, input } = event.data;`,` try {`,` const geometries = assemble(input);`,` const transfer = [];`,` for (const g of geometries) {`,` transfer.push(g.positions.buffer, g.normals.buffer, g.indices.buffer);`,` if (g.uvs) transfer.push(g.uvs.buffer);`,` if (g.colors) transfer.push(g.colors.buffer);`,` }`,` self.postMessage({ id, geometries }, transfer);`,` } catch (error) {`,` self.postMessage({ id, error: String((error && error.message) || error) });`,` }`,`};`].join(`
|
|
2
|
-
`)}let
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./rolldown-runtime-BocRIvOZ.cjs"),t=require("./gpu-dispose-DrN-ryj5.cjs");let n=require("three");n=e.t(n,1);let r=require("three/addons/lines/Line2.js"),i=require("three/addons/lines/LineGeometry.js"),a=require("three/addons/lines/LineMaterial.js"),o=require("fflate");function s(){let e=globalThis.Buffer;return typeof e==`function`?e:void 0}function c(e){let n=e.replace(/[\t\n\f\r ]/g,``);if(n.length%4==0&&(n=n.replace(/={1,2}$/,``)),n.length%4==1||!/^[A-Za-z0-9+/]*$/.test(n))throw new t.d(`Invalid base64 input.`,t.u.ENCODING_ERROR,{context:{inputLength:e.length}});let r=s();if(r)return new Uint8Array(r.from(n,`base64`));if(typeof globalThis.atob==`function`){let e=globalThis.atob(n),t=new Uint8Array(e.length);for(let n=0;n<e.length;n++)t[n]=e.charCodeAt(n)&255;return t}throw new t.d(`Base64 decoding not supported in this environment.`,t.u.INVALID_STATE,{context:{environmentInfo:`atob or Buffer not available`}})}function l(e){return e.map(e=>{let t=e.clone(!0),n=[];e.traverse(e=>n.push(e));let r=0;return t.traverse(e=>{let t=n[r++],i=e;t.geometry&&(i.geometry=t.geometry.clone())}),t})}function u(e){e.forEach(e=>t.t(e,{materials:!1}))}const d={clone:l,release:u};function f(e,t){let r=t??1;return{color:new n.Color(e??`#ffffff`),transparent:r<1,opacity:r}}function p(e){let t=m(e);if(!t)return null;let n=new i.LineGeometry;n.setPositions(t);let o=f(e.color,e.opacity),s=new a.LineMaterial({color:o.color}),c=s;c.linewidth=e.width??2,c.transparent=o.transparent,c.opacity=o.opacity;let l=new r.Line2(n,s);return l.computeLineDistances(),l.name=e.name,l.userData={source:`compute`,id:e.id,layer:e.layer,kind:`curve`,metadata:e.metadata},l}function m(e){if(!e.points)throw new t.d(`Curve display item '${e.id}' has no tessellated points. It was produced by an outdated Display component — upgrade it in Grasshopper (Solution → Upgrade obsolete components) and re-save the definition.`,t.u.INVALID_CONFIG,{context:{itemId:e.id,kind:e.kind}});return e.points.length>=6?e.points:null}function h(e){let{position:r}=e;if(!r||typeof r.X!=`number`||!Number.isFinite(r.X)||typeof r.Y!=`number`||!Number.isFinite(r.Y)||typeof r.Z!=`number`||!Number.isFinite(r.Z))return t.c().warn(`Skipping point display item with missing or non-finite position (id: ${String(e.id)}).`),null;let i=new n.BufferGeometry;i.setAttribute(`position`,new n.Float32BufferAttribute([r.X,r.Y,r.Z],3));let a=new n.PointsMaterial({...f(e.color,e.opacity),size:6,sizeAttenuation:!1}),o=new n.Points(i,a);return o.name=e.name,o.userData={source:`compute`,id:e.id,layer:e.layer,kind:`point`,metadata:e.metadata},o}function g(e){if(!e||e.length===0)return[];let n=[];for(let r of e)switch(r.kind){case`curve`:{let e=p(r);e&&n.push(e);break}case`point`:{let e=h(r);e&&n.push(e);break}default:{let e=r;t.c().warn(`Skipping unknown display item kind: ${String(e.kind)}`);break}}return n}const _=new Uint16Array(new Uint8Array([1,0]).buffer)[0]===1;function v(e){return typeof e==`string`?c(e):e instanceof Uint8Array?e:new Uint8Array(e)}function y(e){if(e.byteLength<8)return e;let t=new DataView(e.buffer,e.byteOffset,e.byteLength);if(t.getUint32(0,!0)!==1515605075)return e;let n=t.getUint32(4,!0),r=e.subarray(8),i=Math.max(r.byteLength*1032+1024,1<<20);if(n>i)throw M(`SLVZ header declares an implausible uncompressed length`,{uncompressedLen:n,deflatedBytes:r.byteLength,maxPlausibleLen:i});let a;try{a=(0,o.inflateSync)(r,{out:new Uint8Array(n+1)})}catch(e){throw M(`Failed to inflate SLVZ blob: ${e instanceof Error?e.message:String(e)}`,{uncompressedLen:n,deflatedBytes:r.byteLength})}if(a.byteLength!==n)throw M(`SLVZ payload inflated to a different size than the header declares.`,{declaredLen:n,actualLen:a.byteLength,deflatedBytes:r.byteLength});return a}function b(e){if(typeof TextDecoder<`u`)return new TextDecoder(`utf-8`).decode(e);if(globalThis.Buffer!==void 0)return globalThis.Buffer.from(e).toString(`utf-8`);throw new t.d(`No UTF-8 decoder available in this environment.`,t.u.INVALID_STATE)}function x(e,t,n){if(n===0)return new Int16Array;if(t%2==0)return new Int16Array(e,t,n);let r=new Uint8Array(n*2);return r.set(new Uint8Array(e,t,n*2)),new Int16Array(r.buffer)}function S(e,t,n){if(n===0)return new Float32Array;if(t%4==0)return new Float32Array(e,t,n);let r=new Uint8Array(n*4);return r.set(new Uint8Array(e,t,n*4)),new Float32Array(r.buffer)}function C(e,t,n){if(n===0)return new Uint16Array;if(t%2==0)return new Uint16Array(e,t,n);let r=new Uint8Array(n*2);return r.set(new Uint8Array(e,t,n*2)),new Uint16Array(r.buffer)}function ee(e,t,n){if(n===0)return new Uint32Array;if(t%4==0)return new Uint32Array(e,t,n);let r=new Uint8Array(n*4);return r.set(new Uint8Array(e,t,n*4)),new Uint32Array(r.buffer)}function w(e,t){if(e.length!==0&&!(e instanceof Uint16Array&&t>65535)){for(let n=0;n<e.length;n++)if(e[n]>=t)throw M(`Index out of range of vertexCount.`,{indexPosition:n,indexValue:e[n],vertexCount:t})}}function T(e){return e>>>1^-(e&1)}function E(e){let t=new Int16Array(e.length),n=0,r=0,i=0;for(let a=0;a<e.length;a+=3)n=n+T(e[a])<<16>>16,r=r+T(e[a+1])<<16>>16,i=i+T(e[a+2])<<16>>16,t[a]=n,t[a+1]=r,t[a+2]=i;return t}function D(e,t){let n=new Int16Array(t*3),r=t,i=0,a=0,o=0;for(let t=0;t<r;t++)i=i+T(e[t]|e[r*3+t]<<8)<<16>>16,a=a+T(e[r+t]|e[r*4+t]<<8)<<16>>16,o=o+T(e[r*2+t]|e[r*5+t]<<8)<<16>>16,n[t*3]=i,n[t*3+1]=a,n[t*3+2]=o;return n}function O(e,t){let n=new Uint16Array(t),r=0;for(let i=0;i<t;i++)r=r+T(e[i]|e[t+i]<<8)&65535,n[i]=r;return n}function k(e,t){let n=new Uint32Array(t),r=0;for(let i=0;i<t;i++){let a=(e[i]|e[t+i]<<8|e[t*2+i]<<16|e[t*3+i]<<24)>>>0;r=r+T(a)>>>0,n[i]=r}return n}function A(e){let t=new Uint16Array(e.length),n=0;for(let r=0;r<e.length;r++)n=n+T(e[r])&65535,t[r]=n;return t}function j(e){let t=new Uint32Array(e.length),n=0;for(let r=0;r<e.length;r++)n=n+T(e[r])>>>0,t[r]=n;return t}function M(e,n){return new t.d(e,t.u.VALIDATION_ERROR,{context:n})}function te(e,t,n,r,i,a=!1){if(n+36>e.byteLength)throw M(`Insufficient data to read UV chunk header.`,{expectedBytes:36,availableBytes:e.byteLength-n,offset:n});let o=t.getUint32(n,!0);n+=4;let s=t.getFloat64(n,!0);n+=8;let c=t.getFloat64(n,!0);n+=8;let l=t.getFloat64(n,!0);n+=8;let u=t.getFloat64(n,!0);n+=8;let d=r*2,f=o===1,p=d*(f?4:2);if(n+p>e.byteLength)throw M(`Insufficient data to read UV chunk.`,{expectedBytes:p,availableBytes:e.byteLength-n,offset:n,uvFormat:o,vertexCount:r});let m=e.byteOffset+n,h;if(f)h=S(e.buffer,m,d).slice();else if(a){let t=e.subarray(n,n+p),i=r;h=new Float32Array(d);let a=0,o=0;for(let e=0;e<i;e++)a=a+T(t[e]|t[i*2+e]<<8)&65535,o=o+T(t[i+e]|t[i*3+e]<<8)&65535,h[e*2]=s+a*l,h[e*2+1]=c+o*u}else{let t=C(e.buffer,m,d);h=new Float32Array(d);let n=0,r=0;for(let e=0;e<d;e+=2)i?(n=n+T(t[e])&65535,r=r+T(t[e+1])&65535):(n=t[e],r=t[e+1]),h[e]=s+n*l,h[e+1]=c+r*u}return{uvs:h,offset:n+p}}function ne(e,t,n,r){let i=n*3;if(t+i>e.byteLength)throw M(`Insufficient data to read vertex-color chunk.`,{expectedBytes:i,availableBytes:e.byteLength-t,offset:t,vertexCount:n});let a=e.subarray(t,t+i);if(!r)return a.slice();let o=new Uint8Array(i),s=0,c=0,l=0;for(let e=0;e<i;e+=3)s=s+T(a[e])&255,c=c+T(a[e+1])&255,l=l+T(a[e+2])&255,o[e]=s,o[e+1]=c,o[e+2]=l;return o}function re(e){return e.byteLength>=4&&new DataView(e.buffer,e.byteOffset,4).getUint32(0,!0)===1297501267}function ie(e){let t=N(e),n=null,r=null,i=null,a=[];for(let{type:e,payload:o}of t)switch(e){case 1297040711:n=o;break;case 1279410516:r=y(o);break;case 1280590157:i=b(o);break;case 1381516628:a.push(o)}if(n===null)throw M(`SLVM container has no GEOM chunk.`,{chunkCount:t.length});if(r===null)throw M(`SLVM container has no TABL chunk.`,{chunkCount:t.length});let{groups:o}=I(r),s=L(i,a);return{geometryBlob:n,metadata:{materials:s,groups:o}}}function N(e){let t=new DataView(e.buffer,e.byteOffset,e.byteLength);if(e.byteLength<12||t.getUint32(0,!0)!==1297501267)throw M(`Not an SLVM container (bad magic).`,{byteLength:e.byteLength});let n=t.getUint32(4,!0);if(n!==3)throw M(`Unsupported SLVM version: ${n}`,{expectedVersion:3});let r=t.getUint32(8,!0),i=[],a=12;for(let n=0;n<r;n++){if(a+8>e.byteLength)throw M(`Truncated SLVM chunk header.`,{offset:a,chunkIndex:n});let r=t.getUint32(a,!0),o=t.getUint32(a+4,!0);if(a+=8,a+o>e.byteLength)throw M(`Truncated SLVM chunk payload.`,{offset:a,chunkIndex:n,byteLen:o});i.push({type:r,payload:e.subarray(a,a+o)}),a+=o+(4-o%4)%4}return i}function P(e){let t=0,n=0;for(;;){if(e.pos>=e.bytes.byteLength||n>28)throw M(`Malformed varint in SLVM table.`,{pos:e.pos});let r=e.bytes[e.pos++];if(t|=(r&127)<<n,!(r&128))return t>>>0;n+=7}}function F(e,t,n){let r=e.bytes[e.pos++],i=Array(t);switch(r){case 0:i.fill(``);break;case 1:for(let e=0;e<t;e++)i[e]=String(e+1);break;case 2:for(let r=0;r<t;r++)i[r]=n[P(e)]??``;break;default:throw M(`Unknown SLVM string column mode: ${r}`,{pos:e.pos})}return i}function I(e){let t={bytes:e,pos:0},n=P(t),r=P(t),i=P(t),a=n+r+i,o=P(t),s=Array(o);for(let n=0;n<o;n++){let r=P(t);s[n]=b(e.subarray(t.pos,t.pos+r)),t.pos+=r}let c=Array(n),l=Array(n);for(let e=0;e<n;e++)c[e]=P(t),l[e]=P(t);for(let e=0;e<r;e++)P(t);let u=P(t),d=[];for(let e=0;e<u;e++)d.push({materialId:P(t),meshCount:P(t)});let f=F(t,a,s),p=F(t,a,s),m=Array(a),h=P(t);for(let e=0;e<h;e++){let e=s[P(t)]??``,n=P(t),r=Array(n),i=0;for(let e=0;e<n;e++)i+=P(t),r[e]=i;for(let i=0;i<n;i++){let n=s[P(t)]??``,a=r[i];(m[a]??={})[e]=n}}let g=d.length>0||n===0?d:[{materialId:0,meshCount:n}],_=[],v=0,y=0,x=0;for(let e of g){let t=[];for(let r=0;r<e.meshCount&&v<n;r++,v++){let e=m[v],n=e?.id;e!==void 0&&delete e.id,t.push({id:n,name:f[v],layer:p[v],vertexCount:c[v],indexCount:l[v]*3,vertexStart:y,indexStart:x,metadata:e??{}}),y+=c[v],x+=l[v]*3}_.push({materialId:e.materialId,meshes:t})}return{groups:_}}function L(e,t){if(e===null)return[];let n;try{n=JSON.parse(e).materials??[]}catch(t){throw M(`Failed to parse SLVM materials JSON: ${t instanceof Error?t.message:String(t)}`,{byteLength:e.length})}for(let e of n)if(e.map?.startsWith(`slvm:tex:`)){let n=t[Number(e.map.slice(9))];n!==void 0&&(e.map=R(n))}return n}function R(e){let t={bytes:e,pos:0},n=P(t),r=b(e.subarray(t.pos,t.pos+n)),i=e.subarray(t.pos+n),a=``,o=32768;for(let e=0;e<i.byteLength;e+=o)a+=String.fromCharCode(...i.subarray(e,e+o));return`data:${r};base64,${btoa(a)}`}function z(e){let t=B(e),n;n=t.isFloat32?t.vertexData:t.planarByteSplit?D(t.vertexData,t.vertexCount):t.deltaEncoded?E(t.vertexData):t.vertexData;let r;if(t.planarByteSplit){let e=t.indexData;r=t.uint16Indices?O(e,e.length/2):k(e,e.length/4)}else r=t.deltaEncoded?t.indexData instanceof Uint16Array?A(t.indexData):j(t.indexData):t.indexData;return w(r,t.vertexCount),{metadata:t.metadata,flags:t.flags,vertices:n,indices:r,origin:t.origin,scale:t.scale,uvs:t.uvs,colors:t.colors}}function B(e){if(!_)throw new t.d(`SLVA parsing requires a little-endian host: the zero-copy geometry readers view the wire bytes in host byte order.`,t.u.ENVIRONMENT_ERROR);let n=v(e);if(re(n)){let e=ie(n),t=B(e.geometryBlob);return t.metadata=e.metadata,t}let r=y(n),i=new DataView(r.buffer,r.byteOffset,r.byteLength);if(r.byteLength<12)throw M(`Blob too small to contain SLVA header.`,{expectedBytes:12,availableBytes:r.byteLength});let a=0,o=i.getUint32(a,!0);if(a+=4,o!==1096174675)throw M(`Invalid SLVA magic: 0x${o.toString(16)}`,{expectedMagic:`0x41564c53`,actualMagic:`0x${o.toString(16)}`});let s=i.getUint32(a,!0);if(a+=4,s<1||s>4)throw M(`Unsupported SLVA version: ${s}`,{minSupportedVersion:1,maxSupportedVersion:4,actualVersion:s});let c=i.getUint32(a,!0);if(a+=4,a+c>r.byteLength)throw M(`Insufficient data to read metadata JSON.`,{expectedBytes:c,availableBytes:r.byteLength-a,offset:a});let l=r.subarray(a,a+c);a+=c;let u;try{u=c===0?{}:JSON.parse(b(l))}catch(e){throw M(`Failed to parse metadata JSON: ${e instanceof Error?e.message:String(e)}`,{metadataLen:c})}if(a+56>r.byteLength)throw M(`Insufficient data to read geometry header.`,{expectedBytes:56,availableBytes:r.byteLength-a,offset:a});let d=i.getUint32(a,!0);a+=4;let f=i.getFloat64(a,!0);a+=8;let p=i.getFloat64(a,!0);a+=8;let m=i.getFloat64(a,!0);a+=8;let h=i.getFloat64(a,!0);a+=8;let g=i.getFloat64(a,!0);a+=8;let w=i.getFloat64(a,!0);a+=8;let T=i.getUint32(a,!0);a+=4;let E=!!(d&1),D=!!(d&4),O=!!(d&32),k=T*3,A=k*(E?4:2);if(a+A>r.byteLength)throw M(`Insufficient data to read vertices.`,{expectedBytes:A,availableBytes:r.byteLength-a,offset:a,useFloat32:E,vertexCount:T});let j=r.byteOffset+a,N;if(N=E?S(r.buffer,j,k):O?r.subarray(a,a+A):D?C(r.buffer,j,k):x(r.buffer,j,k),a+=A,a+4>r.byteLength)throw M(`Insufficient data to read index count.`,{expectedBytes:4,availableBytes:r.byteLength-a,offset:a});let P=i.getUint32(a,!0);a+=4;let F=!!(d&2),I=P*(F?2:4);if(a+I>r.byteLength)throw M(`Insufficient data to read indices.`,{expectedBytes:I,availableBytes:r.byteLength-a,offset:a,indexCount:P,useUint16Indices:F});let L=O?r.subarray(a,a+I):F?C(r.buffer,r.byteOffset+a,P):ee(r.buffer,r.byteOffset+a,P);a+=I;let R=null;if(d&8){let e=te(r,i,a,T,D,O);R=e.uvs,a=e.offset}let z=null;return d&16&&(z=ne(r,a,T,D)),{metadata:u,flags:d,vertexData:N,indexData:L,isFloat32:E,deltaEncoded:D,planarByteSplit:O,uint16Indices:F,vertexCount:T,origin:[f,p,m],scale:[h,g,w],uvs:R,colors:z}}function ae(e){let{isFloat32:t,deltaEncoded:n,planarByteSplit:r,uint16Indices:i,origin:a,scale:o,uvs:s,colors:c,jobs:l}=e,u=e=>e>>>1^-(e&1),d;if(t)d=e.vertexData;else{let t;if(r){let n=e.vertexData,r=n.length/6;t=new Int16Array(r*3);let i=0,a=0,o=0;for(let e=0;e<r;e++)i=i+u(n[e]|n[r*3+e]<<8)<<16>>16,a=a+u(n[r+e]|n[r*4+e]<<8)<<16>>16,o=o+u(n[r*2+e]|n[r*5+e]<<8)<<16>>16,t[e*3]=i,t[e*3+1]=a,t[e*3+2]=o}else if(n){let n=e.vertexData;t=new Int16Array(n.length);let r=0,i=0,a=0;for(let e=0;e<n.length;e+=3)r=r+u(n[e])<<16>>16,i=i+u(n[e+1])<<16>>16,a=a+u(n[e+2])<<16>>16,t[e]=r,t[e+1]=i,t[e+2]=a}else t=e.vertexData;d=new Float32Array(t.length);let i=a[0],s=a[1],c=a[2],l=o[0],f=o[1],p=o[2];for(let e=0;e<t.length;e+=3)d[e]=i+(t[e]+32767)*l,d[e+1]=s+(t[e+1]+32767)*f,d[e+2]=c+(t[e+2]+32767)*p}let f;if(r){let t=e.indexData;if(i){let e=t.length/2,n=new Uint16Array(e),r=0;for(let i=0;i<e;i++)r=r+u(t[i]|t[e+i]<<8)&65535,n[i]=r;f=n}else{let e=t.length/4,n=new Uint32Array(e),r=0;for(let i=0;i<e;i++){let a=(t[i]|t[e+i]<<8|t[e*2+i]<<16|t[e*3+i]<<24)>>>0;r=r+u(a)>>>0,n[i]=r}f=n}}else if(n){let t=e.indexData;if(t instanceof Uint16Array){let e=new Uint16Array(t.length),n=0;for(let r=0;r<t.length;r++)n=n+u(t[r])&65535,e[r]=n;f=e}else{let e=new Uint32Array(t.length),n=0;for(let r=0;r<t.length;r++)n=n+u(t[r])>>>0,e[r]=n;f=e}}else f=e.indexData;let p=d.length/3;for(let e=0;e<f.length;e++)if(f[e]>=p)throw Error(`Index ${f[e]} out of range of vertexCount ${p}`);let m=[];for(let e of l){let t=0,n=0;for(let r of e.windows)t+=r.vertexCount,n+=r.indexCount;let r=new Float32Array(t*3),i=new Uint32Array(n),a=s?new Float32Array(t*2):null,o=c?new Uint8Array(t*3):null,l=0,u=0;for(let t of e.windows){let e=t.vertexStart*3;r.set(d.subarray(e,e+t.vertexCount*3),l*3),a&&s&&a.set(s.subarray(t.vertexStart*2,(t.vertexStart+t.vertexCount)*2),l*2),o&&c&&o.set(c.subarray(e,e+t.vertexCount*3),l*3);let n=t.vertexStart,p=t.vertexStart+t.vertexCount,m=l-t.vertexStart;for(let e=0;e<t.indexCount;e++){let r=f[t.indexStart+e];if(r<n||r>=p)throw Error(`Index ${r} outside vertex window [${n}, ${p})`);i[u+e]=r+m}l+=t.vertexCount,u+=t.indexCount}let p=new Float32Array(t*3);for(let e=0;e<i.length;e+=3){let t=i[e]*3,n=i[e+1]*3,a=i[e+2]*3,o=r[a]-r[n],s=r[a+1]-r[n+1],c=r[a+2]-r[n+2],l=r[t]-r[n],u=r[t+1]-r[n+1],d=r[t+2]-r[n+2],f=s*d-c*u,m=c*l-o*d,h=o*u-s*l;p[t]+=f,p[t+1]+=m,p[t+2]+=h,p[n]+=f,p[n+1]+=m,p[n+2]+=h,p[a]+=f,p[a+1]+=m,p[a+2]+=h}for(let e=0;e<p.length;e+=3){let t=p[e],n=p[e+1],r=p[e+2],i=Math.sqrt(t*t+n*n+r*r)||1;p[e]=t/i,p[e+1]=n/i,p[e+2]=r/i}m.push({positions:r,normals:p,indices:i,uvs:a,colors:o})}return m}function oe(){return[`const assemble = ${ae.toString()};`,`self.onmessage = (event) => {`,` const { id, input } = event.data;`,` try {`,` const geometries = assemble(input);`,` const transfer = [];`,` for (const g of geometries) {`,` transfer.push(g.positions.buffer, g.normals.buffer, g.indices.buffer);`,` if (g.uvs) transfer.push(g.uvs.buffer);`,` if (g.colors) transfer.push(g.colors.buffer);`,` }`,` self.postMessage({ id, geometries }, transfer);`,` } catch (error) {`,` self.postMessage({ id, error: String((error && error.message) || error) });`,` }`,`};`].join(`
|
|
2
|
+
`)}let V;const H=new Map;let se=1;function ce(){if(V!==void 0)return V;if(typeof Worker>`u`||typeof Blob>`u`||typeof URL>`u`||typeof URL.createObjectURL!=`function`)return V=null,null;try{let e=URL.createObjectURL(new Blob([oe()],{type:`text/javascript`})),t=new Worker(e);t.onmessage=e=>{let{id:t,geometries:n,error:r}=e.data,i=H.get(t);i&&(H.delete(t),n?i.resolve(n):i.reject(Error(r??`mesh assembly failed in worker`)))},t.onerror=()=>{for(let e of H.values())e.reject(Error(`mesh assembly worker crashed`));H.clear(),t.terminate(),V=null},V=t}catch{V=null}return V}function le(e,t,n){return new Promise((r,i)=>{let a=se++;H.set(a,{resolve:r,reject:i}),e.postMessage({id:a,input:t},n)})}let U=1;function W(e){U=Math.max(1,e)}t.n(W);function ue(e,r){typeof document>`u`||new n.TextureLoader().load(r,t=>{t.colorSpace=n.SRGBColorSpace,t.anisotropy=U,e.map=t,e.needsUpdate=!0},void 0,e=>{t.c().warn(`Failed to load material texture ${r}:`,e)})}function G(e,r){let i=t.o(e.color),a=r?.vertexColors??!1,o=r?.appearance,s=new n.MeshPhysicalMaterial({color:i,metalness:e.metalness,roughness:e.roughness,opacity:e.opacity,transparent:e.transparent,vertexColors:a,side:o?.cullBackfaces?n.FrontSide:n.DoubleSide,polygonOffset:!0,polygonOffsetFactor:.5,polygonOffsetUnits:.5,depthWrite:!0,depthTest:!0});return o?.envMapIntensity!=null&&(s.envMapIntensity=o.envMapIntensity),e.metalness>.5&&(s.clearcoat=.5,s.clearcoatRoughness=.3),a&&de(s),e.map&&ue(s,e.map),s}function de(e){e.onBeforeCompile=e=>{e.vertexShader=e.vertexShader.replace(`#include <color_vertex>`,`#include <color_vertex>
|
|
3
3
|
#if defined( USE_COLOR ) || defined( USE_COLOR_ALPHA )
|
|
4
4
|
vColor.rgb = mix(
|
|
5
5
|
vColor.rgb / 12.92,
|
|
6
6
|
pow( ( vColor.rgb + 0.055 ) / 1.055, vec3( 2.4 ) ),
|
|
7
7
|
step( vec3( 0.04045 ), vColor.rgb )
|
|
8
8
|
);
|
|
9
|
-
#endif`)}}function V(e,n){return new t.d(e,t.u.VALIDATION_ERROR,{context:n})}function H(e,t,n,r){for(let i of e){if(!Number.isInteger(i.materialId)||i.materialId<0||i.materialId>=t)throw V(`Group materialId out of range of the materials array.`,{materialId:i.materialId,materialCount:t});for(let e of i.meshes){let t={vertexStart:e.vertexStart,vertexCount:e.vertexCount,indexStart:e.indexStart,indexCount:e.indexCount};for(let[n,r]of Object.entries(t))if(!Number.isInteger(r)||r<0)throw V(`Mesh metadata field "${n}" must be a non-negative integer.`,{meshName:e.name,field:n,value:r});if(e.vertexStart+e.vertexCount>n)throw V(`Mesh vertex window exceeds the batch vertex buffer.`,{meshName:e.name,vertexStart:e.vertexStart,vertexCount:e.vertexCount,totalVertexCount:n});if(e.indexStart+e.indexCount>r)throw V(`Mesh index window exceeds the batch index buffer.`,{meshName:e.name,indexStart:e.indexStart,indexCount:e.indexCount,totalIndexCount:r})}}}function U(e,t){return V(`Index references a vertex outside its mesh's vertex window.`,{meshName:t.name,indexValue:e,vertexStart:t.vertexStart,vertexCount:t.vertexCount})}function oe(e,t,n){let r=new Float32Array(e.length),i=t[0],a=t[1],o=t[2],s=n[0],c=n[1],l=n[2];for(let t=0;t<e.length;t+=3)r[t]=i+(e[t]+32767)*s,r[t+1]=a+(e[t+1]+32767)*c,r[t+2]=o+(e[t+2]+32767)*l;return r}function W(e,t,r,i,a=null,o=null){let s=0,c=0;for(let t of e.meshes)s+=t.vertexCount,c+=t.indexCount;let l=new Float32Array(s*3),u=new Uint32Array(c),d=a?new Float32Array(s*2):null,f=o?new Uint8Array(s*3):null,p=0,m=0;for(let n of e.meshes){let e=n.vertexStart*3,i=n.vertexCount*3;if(l.set(t.subarray(e,e+i),p*3),d&&a){let e=n.vertexStart*2;d.set(a.subarray(e,e+n.vertexCount*2),p*2)}f&&o&&f.set(o.subarray(e,e+i),p*3);let s=r.subarray(n.indexStart,n.indexStart+n.indexCount),c=p-n.vertexStart,h=n.vertexStart,g=n.vertexStart+n.vertexCount;for(let e=0;e<s.length;e++){let t=s[e];if(t<h||t>=g)throw U(t,n);u[m+e]=t+c}p+=n.vertexCount,m+=n.indexCount}let h=new n.BufferGeometry;return h.setAttribute(`position`,new n.BufferAttribute(l,3)),h.setIndex(new n.BufferAttribute(u,1)),d&&h.setAttribute(`uv`,new n.BufferAttribute(d,2)),f&&h.setAttribute(`color`,new n.BufferAttribute(f,3,!0)),h.computeVertexNormals(),G(h,e,i)}function G(e,t,r){let i=new n.Mesh(e,r[t.materialId]),a=t.meshes[0],o=t.meshes.map(e=>e.name).filter(e=>e&&e.length>0);return i.name=o.length>0?o[0]:`merged_material_${t.materialId}`,i.castShadow=!0,i.receiveShadow=!0,i.userData={source:`compute`,name:i.name,layer:a?.layer??``,originalIndex:a?.originalIndex??0,mergedIndices:t.meshes.map(e=>e.originalIndex).sort((e,t)=>e-t),metadata:a?.metadata??{},mergedFrom:t.meshes.slice(1).map(e=>({name:e.name,layer:e.layer,originalIndex:e.originalIndex}))},i}function K(e,t,r,i,a=null,o=null){let s=[];for(let c of e.meshes){let l=c.vertexStart*3,u=c.vertexCount*3,d=t.slice(l,l+u),f=r.subarray(c.indexStart,c.indexStart+c.indexCount),p=new Uint32Array(f.length),m=c.vertexStart,h=c.vertexStart+c.vertexCount;for(let e=0;e<f.length;e++){let t=f[e];if(t<m||t>=h)throw U(t,c);p[e]=t-m}let g=new n.BufferGeometry;if(g.setAttribute(`position`,new n.BufferAttribute(d,3)),g.setIndex(new n.BufferAttribute(p,1)),a){let e=c.vertexStart*2,t=a.slice(e,e+c.vertexCount*2);g.setAttribute(`uv`,new n.BufferAttribute(t,2))}if(o){let e=o.slice(l,l+u);g.setAttribute(`color`,new n.BufferAttribute(e,3,!0))}g.computeVertexNormals(),s.push(q(g,c,e,i))}return s}function q(e,t,r,i){let a=new n.Mesh(e,i[r.materialId]);return a.name=t.name,a.userData={source:`compute`,name:t.name,layer:t.layer??``,originalIndex:t.originalIndex,metadata:t.metadata??{}},a.castShadow=!0,a.receiveShadow=!0,a}async function J(e,t,n){let{mergeByMaterial:r=!0,debug:i=!1,material:a}=t??{},{parseTime:o=0,perfStart:s=i?performance.now():0}=n??{};if(!e.compressedData)return[];let c=await X(e.compressedData,{mergeByMaterial:r,debug:i,material:a,fallback:{materials:e.materials,groups:e.groups,sourceComponentId:e.sourceComponentId}});if(c)return c;let l=performance.now();return Y(A(e.compressedData),{mergeByMaterial:r,debug:i,material:a,parseTime:o,decodeTime:performance.now()-l,perfStart:s,blobBytes:i?ce(e.compressedData):0,fallback:{materials:e.materials,groups:e.groups,sourceComponentId:e.sourceComponentId}})}async function se(e,t){let{mergeByMaterial:n=!0,debug:r=!1,material:i}=t??{},a=r?performance.now():0,o=await X(e,{mergeByMaterial:n,debug:r,material:i});if(o)return o;let s=performance.now(),c=A(e),l=performance.now()-s,u=e.byteLength;return Y(c,{mergeByMaterial:n,debug:r,material:i,parseTime:0,decodeTime:l,perfStart:a,blobBytes:u})}function Y(e,n){let{mergeByMaterial:r,debug:i,material:a,parseTime:o,decodeTime:s,perfStart:c,blobBytes:l,fallback:u}=n,d=e.metadata.materials??u?.materials??[],f=e.metadata.groups??u?.groups??[],p=u?.sourceComponentId??e.metadata.sourceComponentId,m=!!(e.flags&1);H(f,d.length,e.vertices.length/3,e.indices.length);let h=m?e.vertices:oe(e.vertices,e.origin,e.scale);if(i){let n=e.vertices.byteLength+e.indices.byteLength;t.c().debug(`Mesh Batch Stats:`),t.c().debug(` Materials: ${d.length} | Groups: ${f.length}`),t.c().debug(` Vertices: ${e.vertices.length/3} | Indices: ${e.indices.length}`),t.c().debug(` Format: ${m?`float32`:`int16 quantized`}`),t.c().debug(` Blob: ${(l/1024/1024).toFixed(2)} MB | Geometry on wire: ${(n/1024/1024).toFixed(2)} MB`)}let g=performance.now(),_=d.map(t=>B(t,{vertexColors:e.colors!=null,appearance:a})),v=[];for(let t of f)if(r&&t.meshes.length>1){let n=W(t,h,e.indices,_,e.uvs,e.colors);p&&(n.userData.sourceComponentId=p),v.push(n)}else{let n=K(t,h,e.indices,_,e.uvs,e.colors);if(p)for(let e of n)e.userData.sourceComponentId=p;v.push(...n)}let y=performance.now()-g;if(i){let e=performance.now()-c;t.c().debug(`Performance:`),o>0&&t.c().debug(` Parse JSON: ${o.toFixed(2)}ms`),t.c().debug(` Decode binary: ${s.toFixed(2)}ms`),t.c().debug(` Create Meshes: ${y.toFixed(2)}ms`),t.c().debug(` Total: ${e.toFixed(2)}ms`)}return Promise.resolve(v)}async function X(e,r){if(typeof Worker>`u`)return null;let i=j(e);if(i.indexData.length/3<5e4)return null;let a=L();if(!a)return null;let o=i.metadata.materials??r.fallback?.materials??[],s=i.metadata.groups??r.fallback?.groups??[],c=r.fallback?.sourceComponentId??i.metadata.sourceComponentId;H(s,o.length,i.vertexCount,i.indexData.length);let l=e=>({vertexStart:e.vertexStart,vertexCount:e.vertexCount,indexStart:e.indexStart,indexCount:e.indexCount}),u=[],d=[];for(let e of s)if(r.mergeByMaterial&&e.meshes.length>1)u.push({kind:`merged`,windows:e.meshes.map(l)}),d.push({kind:`merged`,group:e});else for(let t of e.meshes)u.push({kind:`single`,windows:[l(t)]}),d.push({kind:`single`,group:e,meshMeta:t});let f=i.vertexData.slice(),p=i.indexData.slice(),m=[f.buffer,p.buffer];i.uvs&&m.push(i.uvs.buffer),i.colors&&m.push(i.colors.buffer);let h;try{h=await re(a,{vertexData:f,isFloat32:i.isFloat32,deltaEncoded:i.deltaEncoded,origin:i.origin,scale:i.scale,indexData:p,uvs:i.uvs,colors:i.colors,jobs:u},m)}catch(e){return t.c().warn(`Mesh assembly worker failed; falling back to main-thread parse.`,e),null}if(h.length!==u.length)return null;let g=o.map(e=>B(e,{vertexColors:i.colors!=null,appearance:r.material})),_=[];for(let e=0;e<h.length;e++){let t=h[e],r=d[e],i=new n.BufferGeometry;i.setAttribute(`position`,new n.BufferAttribute(t.positions,3)),i.setAttribute(`normal`,new n.BufferAttribute(t.normals,3)),i.setIndex(new n.BufferAttribute(t.indices,1)),t.uvs&&i.setAttribute(`uv`,new n.BufferAttribute(t.uvs,2)),t.colors&&i.setAttribute(`color`,new n.BufferAttribute(t.colors,3,!0));let a=r.kind===`merged`?G(i,r.group,g):q(i,r.meshMeta,r.group,g);c&&(a.userData.sourceComponentId=c),_.push(a)}return r.debug&&t.c().debug(`Mesh batch assembled off-thread: ${_.length} meshes, ${i.indexData.length/3} triangles`),_}function ce(e){return Math.floor(e.length*3/4)}const Z={Angstroms:1e-10,Nanometers:1e-9,Microns:1e-6,Millimeters:.001,Centimeters:.01,Decimeters:.1,Meters:1,Dekameters:10,Hectometers:100,Kilometers:1e3,Megameters:1e6,Gigameters:1e9,Microinches:2.54e-8,Mils:254e-7,Inches:.0254,Feet:.3048,Yards:.9144,Miles:1609.344,NauticalMiles:1852};function le(e){let t=e.split(`.`);return t.includes(`Display`)||t.includes(`DisplayBatch`)}const Q=new Set;async function ue(e,t){let n=performance.now(),r=[],{allowScaling:i=!0,allowAutoPosition:a=!1,groundAxis:o=`z`,debug:s=!1,parsing:c={}}=t??{};try{return await fe(e,r,i?de(e.modelunits):1,c,s),a&&he(r,o),r}catch(e){throw ge(e,r),e}finally{s&&ve(n)}}function de(e){let n=Z[e];return n===void 0?(Q.has(e)||(Q.add(e),t.c().warn(`Unknown Rhino model unit "${e}" — geometry will not be scaled (factor 1). Known units: ${Object.keys(Z).join(`, `)}.`)),1):n}async function fe(e,t,n,r,i){for(let a of e.values){let e=a.InnerTree;for(let a in e){let o=e[a];o&&await pe(o,t,n,r,i)}}}async function pe(e,n,r,i,a){for(let o of e){if(!le(o.type))continue;let e={mergeByMaterial:!0,debug:!1,...i},s=me(o.data);if(!s){t.c().error(`Error parsing display batch envelope: invalid JSON`);continue}let c=await J(s,e),l=g(s.items),u=[...c,...l];if(r!==1)for(let e of u)e.scale.set(r,r,r);n.push(...u),a&&t.c().debug(`Extracted ${c.length} meshes and ${l.length} items from batch`)}}function me(e){return typeof e==`string`?$(e):e}function $(e){try{return JSON.parse(e)}catch{return}}function he(e,n){if(e.length===0)return;let r=t.a(e);t.i(e,r.min[n],n)}function ge(e,n){t.c().error(`An unexpected error occurred:`,e),_e(n)}function _e(e){for(let t of e){let e=t;e.geometry&&e.geometry.dispose(),e.material&&(Array.isArray(e.material)?e.material.forEach(e=>e.dispose()):e.material.dispose())}}function ve(e){let n=performance.now()-e;t.c().info(`Time to process meshes:`,`${n.toFixed(2)}ms`)}exports.SCALE_FACTORS=Z,exports.getThreeMeshesFromComputeResponse=ue,exports.meshPolicy=d,exports.parseDisplayItems=g,exports.parseMeshBatchBlob=se,exports.parseMeshBatchObject=J,exports.setTextureAnisotropy=z;
|
|
9
|
+
#endif`)}}function K(e,n){return new t.d(e,t.u.VALIDATION_ERROR,{context:n})}function q(e,t,n,r){for(let i of e){if(!Number.isInteger(i.materialId)||i.materialId<0||i.materialId>=t)throw K(`Group materialId out of range of the materials array.`,{materialId:i.materialId,materialCount:t});for(let e of i.meshes){let t={vertexStart:e.vertexStart,vertexCount:e.vertexCount,indexStart:e.indexStart,indexCount:e.indexCount};for(let[n,r]of Object.entries(t))if(!Number.isInteger(r)||r<0)throw K(`Mesh metadata field "${n}" must be a non-negative integer.`,{meshName:e.name,field:n,value:r});if(e.vertexStart+e.vertexCount>n)throw K(`Mesh vertex window exceeds the batch vertex buffer.`,{meshName:e.name,vertexStart:e.vertexStart,vertexCount:e.vertexCount,totalVertexCount:n});if(e.indexStart+e.indexCount>r)throw K(`Mesh index window exceeds the batch index buffer.`,{meshName:e.name,indexStart:e.indexStart,indexCount:e.indexCount,totalIndexCount:r})}}}function J(e,t){return K(`Index references a vertex outside its mesh's vertex window.`,{meshName:t.name,indexValue:e,vertexStart:t.vertexStart,vertexCount:t.vertexCount})}function fe(e,t,n){let r=new Float32Array(e.length),i=t[0],a=t[1],o=t[2],s=n[0],c=n[1],l=n[2];for(let t=0;t<e.length;t+=3)r[t]=i+(e[t]+32767)*s,r[t+1]=a+(e[t+1]+32767)*c,r[t+2]=o+(e[t+2]+32767)*l;return r}function Y(e){let t=new Map;for(let n of e.meshes){let e=n.layer??``,r=t.get(e);r||(r=[],t.set(e,r)),r.push(n)}return[...t.values()].map(t=>({materialId:e.materialId,meshes:t}))}function pe(e,t,r,i,a=null,o=null){let s=0,c=0;for(let t of e.meshes)s+=t.vertexCount,c+=t.indexCount;let l=new Float32Array(s*3),u=new Uint32Array(c),d=a?new Float32Array(s*2):null,f=o?new Uint8Array(s*3):null,p=0,m=0;for(let n of e.meshes){let e=n.vertexStart*3,i=n.vertexCount*3;if(l.set(t.subarray(e,e+i),p*3),d&&a){let e=n.vertexStart*2;d.set(a.subarray(e,e+n.vertexCount*2),p*2)}f&&o&&f.set(o.subarray(e,e+i),p*3);let s=r.subarray(n.indexStart,n.indexStart+n.indexCount),c=p-n.vertexStart,h=n.vertexStart,g=n.vertexStart+n.vertexCount;for(let e=0;e<s.length;e++){let t=s[e];if(t<h||t>=g)throw J(t,n);u[m+e]=t+c}p+=n.vertexCount,m+=n.indexCount}let h=new n.BufferGeometry;return h.setAttribute(`position`,new n.BufferAttribute(l,3)),h.setIndex(new n.BufferAttribute(u,1)),d&&h.setAttribute(`uv`,new n.BufferAttribute(d,2)),f&&h.setAttribute(`color`,new n.BufferAttribute(f,3,!0)),h.computeVertexNormals(),X(h,e,i)}function me(e){let t=[],n=0;for(let r of e.meshes)t.push({trackingKey:r.id,name:r.name,layer:r.layer,metadata:r.metadata??{},indexStart:n,indexCount:r.indexCount}),n+=r.indexCount;return t}function X(e,t,r){let i=new n.Mesh(e,r[t.materialId]),a=t.meshes[0],o=t.meshes.map(e=>e.name).filter(e=>e&&e.length>0);return i.name=o.length>0?o[0]:`merged_material_${t.materialId}`,i.castShadow=!0,i.receiveShadow=!0,i.userData={source:`compute`,name:i.name,layer:a?.layer??``,metadata:a?.metadata??{},members:me(t)},i}function he(e,t,r,i,a=null,o=null){let s=[];for(let c of e.meshes){let l=c.vertexStart*3,u=c.vertexCount*3,d=t.slice(l,l+u),f=r.subarray(c.indexStart,c.indexStart+c.indexCount),p=new Uint32Array(f.length),m=c.vertexStart,h=c.vertexStart+c.vertexCount;for(let e=0;e<f.length;e++){let t=f[e];if(t<m||t>=h)throw J(t,c);p[e]=t-m}let g=new n.BufferGeometry;if(g.setAttribute(`position`,new n.BufferAttribute(d,3)),g.setIndex(new n.BufferAttribute(p,1)),a){let e=c.vertexStart*2,t=a.slice(e,e+c.vertexCount*2);g.setAttribute(`uv`,new n.BufferAttribute(t,2))}if(o){let e=o.slice(l,l+u);g.setAttribute(`color`,new n.BufferAttribute(e,3,!0))}g.computeVertexNormals(),s.push(Z(g,c,e,i))}return s}function Z(e,t,r,i){let a=new n.Mesh(e,i[r.materialId]);return a.name=t.name,a.userData={source:`compute`,name:t.name,layer:t.layer??``,trackingKey:t.id,metadata:t.metadata??{}},a.castShadow=!0,a.receiveShadow=!0,a}async function ge(e,t,n){let{mergeByMaterial:r=!0,debug:i=!1,material:a}=t??{},{parseTime:o=0,perfStart:s=i?performance.now():0}=n??{};if(!e.compressedData)return[];let c=await xe(e.compressedData,{mergeByMaterial:r,debug:i,material:a,fallback:{materials:e.materials,groups:e.groups}});if(c)return c;let l=performance.now();return be(z(e.compressedData),{mergeByMaterial:r,debug:i,material:a,parseTime:o,decodeTime:performance.now()-l,perfStart:s,blobBytes:i?Se(e.compressedData):0,fallback:{materials:e.materials,groups:e.groups}})}async function _e(e,t){let{mergeByMaterial:n=!0,debug:r=!1,material:i}=t??{},a=r?performance.now():0,o=await xe(e,{mergeByMaterial:n,debug:r,material:i});if(o)return o;let s=performance.now(),c=z(e),l=performance.now()-s,u=e.byteLength;return be(c,{mergeByMaterial:n,debug:r,material:i,parseTime:0,decodeTime:l,perfStart:a,blobBytes:u})}let ve=!1;function ye(e,n){if(e||ve)return;let r=0;for(let e of n)r+=e.meshes.length;r<1e3||(ve=!0,t.c().warn(`Parsing ${r} meshes with mergeByMaterial: false — each becomes its own THREE object, and render cost scales with object count. Drop the option to merge by material (the default); per-object identity survives it via userData.members.`))}function be(e,n){let{mergeByMaterial:r,debug:i,material:a,parseTime:o,decodeTime:s,perfStart:c,blobBytes:l,fallback:u}=n,d=e.metadata.materials??u?.materials??[],f=e.metadata.groups??u?.groups??[],p=!!(e.flags&1);q(f,d.length,e.vertices.length/3,e.indices.length);let m=p?e.vertices:fe(e.vertices,e.origin,e.scale);if(i){let n=e.vertices.byteLength+e.indices.byteLength;t.c().debug(`Mesh Batch Stats:`),t.c().debug(` Materials: ${d.length} | Groups: ${f.length}`),t.c().debug(` Vertices: ${e.vertices.length/3} | Indices: ${e.indices.length}`),t.c().debug(` Format: ${p?`float32`:`int16 quantized`}`),t.c().debug(` Blob: ${(l/1024/1024).toFixed(2)} MB | Geometry on wire: ${(n/1024/1024).toFixed(2)} MB`)}ye(r,f);let h=performance.now(),g=d.map(t=>G(t,{vertexColors:e.colors!=null,appearance:a})),_=[],v=r?f.flatMap(Y):f;for(let t of v)if(r&&t.meshes.length>1){let n=pe(t,m,e.indices,g,e.uvs,e.colors);_.push(n)}else{let n=he(t,m,e.indices,g,e.uvs,e.colors);_.push(...n)}let y=performance.now()-h;if(i){let e=performance.now()-c;t.c().debug(`Performance:`),o>0&&t.c().debug(` Parse JSON: ${o.toFixed(2)}ms`),t.c().debug(` Decode binary: ${s.toFixed(2)}ms`),t.c().debug(` Create Meshes: ${y.toFixed(2)}ms`),t.c().debug(` Total: ${e.toFixed(2)}ms`)}return Promise.resolve(_)}async function xe(e,r){if(typeof Worker>`u`)return null;let i=B(e),a=i.planarByteSplit?i.indexData.length/(i.uint16Indices?2:4):i.indexData.length;if(a/3<5e4)return null;let o=ce();if(!o)return null;let s=i.metadata.materials??r.fallback?.materials??[],c=i.metadata.groups??r.fallback?.groups??[];q(c,s.length,i.vertexCount,a);let l=e=>({vertexStart:e.vertexStart,vertexCount:e.vertexCount,indexStart:e.indexStart,indexCount:e.indexCount}),u=[],d=[],f=r.mergeByMaterial?c.flatMap(Y):c;for(let e of f)if(r.mergeByMaterial&&e.meshes.length>1)u.push({kind:`merged`,windows:e.meshes.map(l)}),d.push({kind:`merged`,group:e});else for(let t of e.meshes)u.push({kind:`single`,windows:[l(t)]}),d.push({kind:`single`,group:e,meshMeta:t});let p=i.vertexData.slice(),m=i.indexData.slice(),h=[p.buffer,m.buffer];i.uvs&&h.push(i.uvs.buffer),i.colors&&h.push(i.colors.buffer);let g;try{g=await le(o,{vertexData:p,isFloat32:i.isFloat32,deltaEncoded:i.deltaEncoded,planarByteSplit:i.planarByteSplit,uint16Indices:i.uint16Indices,origin:i.origin,scale:i.scale,indexData:m,uvs:i.uvs,colors:i.colors,jobs:u},h)}catch(e){return t.c().warn(`Mesh assembly worker failed; falling back to main-thread parse.`,e),null}if(g.length!==u.length)return null;let _=s.map(e=>G(e,{vertexColors:i.colors!=null,appearance:r.material})),v=[];for(let e=0;e<g.length;e++){let t=g[e],r=d[e],i=new n.BufferGeometry;i.setAttribute(`position`,new n.BufferAttribute(t.positions,3)),i.setAttribute(`normal`,new n.BufferAttribute(t.normals,3)),i.setIndex(new n.BufferAttribute(t.indices,1)),t.uvs&&i.setAttribute(`uv`,new n.BufferAttribute(t.uvs,2)),t.colors&&i.setAttribute(`color`,new n.BufferAttribute(t.colors,3,!0));let a=r.kind===`merged`?X(i,r.group,_):Z(i,r.meshMeta,r.group,_);v.push(a)}return r.debug&&t.c().debug(`Mesh batch assembled off-thread: ${v.length} meshes, ${a/3} triangles`),v}function Se(e){return Math.floor(e.length*3/4)}const Q={Angstroms:1e-10,Nanometers:1e-9,Microns:1e-6,Millimeters:.001,Centimeters:.01,Decimeters:.1,Meters:1,Dekameters:10,Hectometers:100,Kilometers:1e3,Megameters:1e6,Gigameters:1e9,Microinches:2.54e-8,Mils:254e-7,Inches:.0254,Feet:.3048,Yards:.9144,Miles:1609.344,NauticalMiles:1852};function Ce(e){let t=e.split(`.`);return t.includes(`Display`)||t.includes(`DisplayBatch`)}const $=new Set;async function we(e,t){let n=performance.now(),r=[],{allowScaling:i=!0,allowAutoPosition:a=!1,groundAxis:o=`z`,debug:s=!1,parsing:c={}}=t??{};try{return await Ee(e,r,i?Te(e.modelunits):1,c,s),a&&Ae(r,o),r}catch(e){throw je(e,r),e}finally{s&&Ne(n)}}function Te(e){let n=Q[e];return n===void 0?($.has(e)||($.add(e),t.c().warn(`Unknown Rhino model unit "${e}" — geometry will not be scaled (factor 1). Known units: ${Object.keys(Q).join(`, `)}.`)),1):n}async function Ee(e,t,n,r,i){for(let a of e.values){let e=a.InnerTree;for(let a in e){let o=e[a];o&&await De(o,t,n,r,i)}}}async function De(e,n,r,i,a){for(let o of e){if(!Ce(o.type))continue;let e={debug:!1,...i,mergeByMaterial:i.mergeByMaterial??!0},s=Oe(o.data);if(!s){t.c().error(`Error parsing display batch envelope: invalid JSON`);continue}let c=await ge(s,e),l=g(s.items),u=[...c,...l];if(r!==1)for(let e of u)e.scale.set(r,r,r);n.push(...u),a&&t.c().debug(`Extracted ${c.length} meshes and ${l.length} items from batch`)}}function Oe(e){return typeof e==`string`?ke(e):e}function ke(e){try{return JSON.parse(e)}catch{return}}function Ae(e,n){if(e.length===0)return;let r=t.a(e);t.i(e,r.min[n],n)}function je(e,n){t.c().error(`An unexpected error occurred:`,e),Me(n)}function Me(e){for(let t of e){let e=t;e.geometry&&e.geometry.dispose(),e.material&&(Array.isArray(e.material)?e.material.forEach(e=>e.dispose()):e.material.dispose())}}function Ne(e){let n=performance.now()-e;t.c().info(`Time to process meshes:`,`${n.toFixed(2)}ms`)}exports.SCALE_FACTORS=Q,exports.getThreeObjectsFromComputeResponse=we,exports.meshPolicy=d,exports.parseDisplayItems=g,exports.parseMeshBatchBlob=_e,exports.parseMeshBatchObject=ge,exports.setTextureAnisotropy=W;
|
|
10
10
|
//# sourceMappingURL=parse.cjs.map
|