@selvajs/visualization 1.0.0-beta.0 → 1.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/parse.d.ts CHANGED
@@ -1,11 +1,7 @@
1
1
  import * as THREE from 'three';
2
- import { RhinoModule } from 'rhino3dm';
3
- import { M as MaterialAppearanceOptions } from './types-CdF9R3qA.js';
2
+ import { M as MaterialAppearanceOptions } from './types-DCuos3gI.js';
4
3
 
5
- /**
6
- * Structural, not nominal: satisfies `@selvajs/solve/client`'s `MeshPolicy<THREE.Object3D>`
7
- * without this package depending on solve.
8
- */
4
+ /** Structurally, not nominally, typed as `@selvajs/solve/client`'s `MeshPolicy<THREE.Object3D>` — avoids a dependency on solve. */
9
5
  declare const meshPolicy: {
10
6
  clone(meshes: THREE.Object3D[]): THREE.Object3D[];
11
7
  release(meshes: THREE.Object3D[]): void;
@@ -33,11 +29,9 @@ interface DisplayComputeResponse {
33
29
  modelunits: string;
34
30
  }
35
31
 
36
- /** Shared by meshes and items so pick/filter/label code treats them uniformly. No color/material — that's per-kind. */
37
32
  interface DisplayIdentity {
38
- /** Stable pick key: `${sourceComponentId}:${originalIndex}`. */
33
+ /** Stable pick key: `${sourceComponentId}:${originalIndex}`. Distinct from `name` so renaming doesn't change identity. */
39
34
  id: string;
40
- /** Distinct from {@link id} — renaming must not change identity. */
41
35
  name: string;
42
36
  layer: string;
43
37
  /** Arbitrary key-value pairs from the GH Metadata input. */
@@ -46,7 +40,7 @@ interface DisplayIdentity {
46
40
  interface DisplayItemBase extends DisplayIdentity {
47
41
  /** Hex/rgb/named color string, parsed by `parseColor`. Falls back to a viewer default. */
48
42
  color?: string;
49
- /** 01. Omitted means fully opaque. */
43
+ /** 0-1; omitted means fully opaque. */
50
44
  opacity?: number;
51
45
  }
52
46
  /** Rhino's Z-up frame and `{X,Y,Z}` casing. */
@@ -55,11 +49,18 @@ interface DisplayPosition {
55
49
  Y: number;
56
50
  Z: number;
57
51
  }
58
- /** Rhino-native JSON (`curve.ToNurbsCurve().ToJSON()`), tessellated to a fat `Line2` on decode. */
52
+ /** Rendered as a fat `Line2` straight from `points` — nothing decodes geometry in the browser. */
59
53
  interface DisplayCurve extends DisplayItemBase {
60
54
  kind: 'curve';
61
- json: string;
62
- /** Screen-space CSS px, constant regardless of zoom. Omitted viewer default. */
55
+ /**
56
+ * Backend-tessellated polyline, flat `[x,y,z, …]` in Rhino's Z-up frame.
57
+ *
58
+ * Typed as required even though the plugin still sends a legacy `json` field alongside it: a
59
+ * payload without `points` came from a Display component too old to render, and parsing throws
60
+ * rather than treating it as a shape this package supports.
61
+ */
62
+ points: number[];
63
+ /** Screen-space CSS px, constant regardless of zoom. Omitted uses the viewer default. */
63
64
  width?: number;
64
65
  }
65
66
  interface DisplayPoint extends DisplayItemBase {
@@ -104,7 +105,6 @@ interface MeshMetadata {
104
105
  metadata?: Record<string, string>;
105
106
  }
106
107
  interface MaterialGroup {
107
- /** Index into the batch's materials array. */
108
108
  materialId: number;
109
109
  meshes: MeshMetadata[];
110
110
  }
@@ -131,7 +131,7 @@ interface DisplayBatch {
131
131
  items?: DisplayItem[];
132
132
  }
133
133
  interface MeshBatchParsingOptions {
134
- /** Merge meshes with same material into single geometry. Defaults to true. */
134
+ /** Merge meshes sharing a material into a single geometry. Defaults to true. */
135
135
  mergeByMaterial?: boolean;
136
136
  debug?: boolean;
137
137
  /**
@@ -144,7 +144,7 @@ interface MeshBatchParsingOptions {
144
144
 
145
145
  interface MeshExtractionOptions {
146
146
  parsing?: MeshBatchParsingOptions;
147
- /** Apply scaling based on model units. Defaults to true. */
147
+ /** Scale geometry to model units. Defaults to true. */
148
148
  allowScaling?: boolean;
149
149
  /**
150
150
  * Drop geometry so its lowest point sits on the ground plane. **Defaults to `false`** — content
@@ -156,23 +156,18 @@ interface MeshExtractionOptions {
156
156
  /** Up axis for `allowAutoPosition` grounding. Defaults to `'z'` (Rhino's frame) — only set this
157
157
  * if the viewer is configured with a non-default `sceneUp`. */
158
158
  groundAxis?: 'x' | 'y' | 'z';
159
- /** rhino3dm instance for decoding curve display items — selva-compute doesn't own the WASM
160
- * instance, the host threads it in. Omit to skip curves (points still render). */
161
- rhino?: RhinoModule;
162
159
  debug?: boolean;
163
160
  }
164
161
 
165
162
  /**
166
163
  * Metres per model unit, keyed by Rhino `UnitSystem` name (the `modelunits` string on the compute
167
- * response). Imperial factors are the exact international definitions (1 in = 0.0254 m,
168
- * 1 ft = 0.3048 m, 1 mi = 1609.344 m). Units not in this table scale 1 and log a one-time warning
169
- * — see {@link getScaleFactor}.
164
+ * response). Imperial factors are the exact international definitions. Units missing from this
165
+ * table scale by 1 and log a one-time warning — see {@link getScaleFactor}.
170
166
  */
171
167
  declare const SCALE_FACTORS: Record<string, number>;
172
168
  /**
173
169
  * Extracts display meshes and items from a Grasshopper WebDisplay compute response: decompresses,
174
- * scales to meters, and optionally grounds them. Requires the VektorNode Rhino.Compute fork (see
175
- * root CLAUDE.md).
170
+ * scales to meters, and optionally grounds them. Requires the VektorNode Rhino.Compute fork.
176
171
  *
177
172
  * Synchronous internally (large batches block the UI for their duration); `async` only so the
178
173
  * shape can stay stable if parsing moves off-thread later.
@@ -181,7 +176,6 @@ declare const SCALE_FACTORS: Record<string, number>;
181
176
  */
182
177
  declare function getThreeMeshesFromComputeResponse(data: DisplayComputeResponse, options?: MeshExtractionOptions): Promise<THREE.Object3D[]>;
183
178
 
184
- /** Internal telemetry only (not exposed in public options). */
185
179
  interface ParseTelemetry {
186
180
  parseTime?: number;
187
181
  perfStart?: number;
@@ -190,19 +184,19 @@ interface ParseTelemetry {
190
184
  * Parses a DisplayBatch object and creates Three.js meshes from its mesh blob.
191
185
  *
192
186
  * Synchronous internally — `parseBinaryMeshBatch` does no IO, just typed-array views over the
193
- * blob. Stays `async` so callers don't have to change shape if parsing moves into a worker later.
187
+ * blob. Stays `async` so callers don't need to change shape if parsing moves into a worker later.
194
188
  *
195
189
  * @throws {VisualizationError} On a corrupt/truncated/unsupported mesh blob or malformed group metadata.
196
190
  */
197
191
  declare function parseMeshBatchObject(batch: DisplayBatch, options?: MeshBatchParsingOptions,
198
- /** @internal Timings threaded from an outer entry point; not a caller option. */
192
+ /** @internal Timings threaded from an outer entry point not a caller option. */
199
193
  telemetry?: ParseTelemetry): Promise<THREE.Mesh[]>;
200
194
  /**
201
195
  * Parses a raw binary mesh batch blob (SLVA wire format) and creates Three.js meshes.
202
196
  *
203
197
  * Use this entry point when the blob arrives as a binary WebSocket frame rather than inside a JSON
204
- * envelope. The blob is self-describing materials, groups, and `sourceComponentId` come from its
205
- * embedded metadata header.
198
+ * envelope the blob is self-describing, with materials, groups, and `sourceComponentId` coming
199
+ * from its embedded metadata header.
206
200
  *
207
201
  * @throws {VisualizationError} On a corrupt/truncated/unsupported mesh blob or malformed group metadata.
208
202
  */
@@ -210,26 +204,18 @@ declare function parseMeshBatchBlob(blob: ArrayBuffer | Uint8Array, options?: Me
210
204
 
211
205
  /**
212
206
  * Subscribed to the renderer's own report below, so no host wiring is needed; still exported for a
213
- * host embedding a foreign renderer that wants to set it directly.
207
+ * host embedding a foreign renderer that wants to set it directly. Applies to textures loaded from
208
+ * here on — textures already decoded keep the value they were given.
214
209
  */
215
210
  declare function setTextureAnisotropy(value: number): void;
216
211
 
217
212
  /**
218
- * Free every cross-solve GPU cache cached geometries, textures and edge segments.
213
+ * Builds THREE objects for the batch's non-mesh items.
219
214
  *
220
- * **You do not normally need this.** These caches register themselves for teardown, so the viewer's
221
- * `dispose()` already frees them once the last live viewer goes away. It is exported for the cases
222
- * that sit outside a viewer lifecycle: reclaiming memory under pressure, or a test isolating
223
- * module-level state.
224
- *
225
- * Safe to call repeatedly and with a viewer running — the caches simply repopulate on the next solve.
215
+ * @throws VisualizationError when a curve predates backend tessellation, so a stale definition
216
+ * surfaces as an actionable error instead of a scene quietly missing its curves. Every other
217
+ * unrenderable item is logged and skipped.
226
218
  */
227
- declare function releaseParseCaches(): void;
228
-
229
- interface DisplayItemParseOptions {
230
- /** Omit to skip curves; points still render. */
231
- rhino?: RhinoModule;
232
- }
233
- declare function parseDisplayItems(items: DisplayItem[] | undefined, options?: DisplayItemParseOptions): THREE.Object3D[];
219
+ declare function parseDisplayItems(items: DisplayItem[] | undefined): THREE.Object3D[];
234
220
 
235
- export { type DisplayBatch, type DisplayComputeResponse, type DisplayCurve, type DisplayDataItem, type DisplayIdentity, type DisplayItem, type DisplayItemBase, type DisplayItemParseOptions, type DisplayPoint, type DisplayPosition, type DisplayResponseValue, type MaterialGroup, type MeshBatchParsingOptions, type MeshExtractionOptions, type MeshMetadata, SCALE_FACTORS, type SerializableMaterial, getThreeMeshesFromComputeResponse, meshPolicy, parseDisplayItems, parseMeshBatchBlob, parseMeshBatchObject, releaseParseCaches, setTextureAnisotropy };
221
+ export { type DisplayBatch, type DisplayComputeResponse, type DisplayCurve, type DisplayDataItem, type DisplayIdentity, type DisplayItem, type DisplayItemBase, type DisplayPoint, type DisplayPosition, type DisplayResponseValue, type MaterialGroup, type MeshBatchParsingOptions, type MeshExtractionOptions, type MeshMetadata, SCALE_FACTORS, type SerializableMaterial, getThreeMeshesFromComputeResponse, meshPolicy, parseDisplayItems, parseMeshBatchBlob, parseMeshBatchObject, setTextureAnisotropy };
package/dist/parse.js CHANGED
@@ -1,10 +1,10 @@
1
- import{a as G,b as N,c as A,f as Be,k as Ie,l as De,m as Oe,n as $,o as Q,q as ee,r as Ue,u as He,v as Le}from"./chunk-EXAI6IC5.js";import"./chunk-5XGN7UAV.js";function bt(e){return e.map(t=>{let r=t.clone(!0),n=[];t.traverse(a=>n.push(a));let o=0;return r.traverse(a=>{let s=n[o++],u=a;if(!s.geometry)return;let i=s.geometry.clone();i.userData={...i.userData},delete i.userData[$],u.geometry=i}),r})}function Et(e){e.forEach(t=>Le(t,{materials:!1}))}var xt={clone:bt,release:Et};import*as de from"three";import{Line2 as Mt}from"three/addons/lines/Line2.js";import{LineGeometry as wt}from"three/addons/lines/LineGeometry.js";import{LineMaterial as Tt}from"three/addons/lines/LineMaterial.js";import*as _e from"three";var At="#ffffff";function te(e,t){let r=t??1;return{color:new _e.Color(e??At),transparent:r<1,opacity:r}}var Fe=12,Rt=4e-4,vt=12,St=.05,Ct=2;function Pe(e,t){if(!t)return A().warn("No rhino3dm instance provided; skipping curve display item."),null;let r=Bt(e.json,t);if(!r)return null;let n;try{n=It(r)}catch(l){return A().warn("Failed to tessellate curve display item; skipping.",l),null}finally{Y(r)}if(n.length<2)return null;let o=[];for(let l of n)o.push(l.x,l.y,l.z);let a=new wt;a.setPositions(o);let s=te(e.color,e.opacity),u=new Tt({color:s.color}),i=u;i.linewidth=e.width??Ct,i.transparent=s.transparent,i.opacity=s.opacity;let f=new Mt(a,u);return f.computeLineDistances(),f.name=e.name,f.userData={source:"compute",id:e.id,layer:e.layer,kind:"curve",metadata:e.metadata},f}function Y(e){e?.delete?.()}function Bt(e,t){try{let r=JSON.parse(e),n=t.CommonObject.decode(r);return n&&typeof n.pointAt=="function"?n:(Y(n),A().warn("Decoded display-item JSON is not a curve; skipping."),null)}catch(r){return A().warn("Failed to decode curve display item JSON:",r),null}}function It(e){let t=Dt(e);return t||Ot(e)}function Dt(e){if(!e.isPolyline())return null;let t=e.tryGetPolyline(),r=Array.isArray(t)?t[1]:t;if(!r||typeof r.count!="number"||r.count<2)return Y(r),null;let n=[];for(let o=0;o<r.count;o++){let a=r.get(o);n.push(new de.Vector3(a[0],a[1],a[2]))}return Y(r),n}function Ot(e){let t=e.domain,r=t[0],o=t[1]-r,a=l=>{let y=e.pointAt(l);return new de.Vector3(y[0],y[1],y[2])},s=Ut(e),u=r,i=a(r),f=[i];for(let l=0;l<Fe;l++){let y=r+o*(l+1)/Fe,b=a(y);me(u,i,y,b,a,s,vt,f),f.push(b),u=y,i=b}return f}function me(e,t,r,n,o,a,s,u){if(s<=0)return;let i=(e+r)/2,f=o(i),l=Lt(f,t,n),y=Ht(t,f,n);l<=a&&y<=St||(me(e,t,i,f,o,a,s-1,u),u.push(f),me(i,f,r,n,o,a,s-1,u))}function Ut(e){let t=e.getBoundingBox(),r=t.min,n=t.max;Y(t);let o=Math.hypot(n[0]-r[0],n[1]-r[1],n[2]-r[2]);return Math.max(o*Rt,1e-6)}function Ht(e,t,r){let n=t.x-e.x,o=t.y-e.y,a=t.z-e.z,s=r.x-t.x,u=r.y-t.y,i=r.z-t.z,f=Math.sqrt(n*n+o*o+a*a),l=Math.sqrt(s*s+u*u+i*i);if(f===0||l===0)return 0;let y=n*s+o*u+a*i,b=Math.max(-1,Math.min(1,y/(f*l)));return Math.acos(b)}function Lt(e,t,r){let n=r.x-t.x,o=r.y-t.y,a=r.z-t.z,s=n*n+o*o+a*a;if(s===0)return e.distanceTo(t);let u=e.x-t.x,i=e.y-t.y,f=e.z-t.z,l=Math.max(0,Math.min(1,(u*n+i*o+f*a)/s)),y=u-n*l,b=i-o*l,w=f-a*l;return Math.sqrt(y*y+b*b+w*w)}import*as P from"three";function Ve(e){let{position:t}=e;if(!t||typeof t.X!="number"||!Number.isFinite(t.X)||typeof t.Y!="number"||!Number.isFinite(t.Y)||typeof t.Z!="number"||!Number.isFinite(t.Z))return A().warn(`Skipping point display item with missing or non-finite position (id: ${String(e.id)}).`),null;let r=new P.BufferGeometry;r.setAttribute("position",new P.Float32BufferAttribute([t.X,t.Y,t.Z],3));let n=new P.PointsMaterial({...te(e.color,e.opacity),size:6,sizeAttenuation:!1}),o=new P.Points(r,n);return o.name=e.name,o.userData={source:"compute",id:e.id,layer:e.layer,kind:"point",metadata:e.metadata},o}function pe(e,t={}){if(!e||e.length===0)return[];let{rhino:r}=t,n=[];for(let o of e)switch(o.kind){case"curve":{let a=Pe(o,r);a&&n.push(a);break}case"point":{let a=Ve(o);a&&n.push(a);break}default:{let s=o;A().warn(`Skipping unknown display item kind: ${String(s.kind)}`);break}}return n}import*as V from"three";var ke=new Uint16Array(new Uint8Array([1,0]).buffer)[0]===1;import{inflateSync as _t}from"fflate";function Ge(e){return typeof e=="string"?Be(e):e instanceof Uint8Array?e:new Uint8Array(e)}function Ne(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 r=t.getUint32(4,!0),n=e.subarray(8),o=Math.max(n.byteLength*1032+1024,1<<20);if(r>o)throw I("SLVZ header declares an implausible uncompressed length",{uncompressedLen:r,deflatedBytes:n.byteLength,maxPlausibleLen:o});let a;try{a=_t(n,{out:new Uint8Array(r+1)})}catch(s){throw I(`Failed to inflate SLVZ blob: ${s instanceof Error?s.message:String(s)}`,{uncompressedLen:r,deflatedBytes:n.byteLength})}if(a.byteLength!==r)throw I("SLVZ payload inflated to a different size than the header declares.",{declaredLen:r,actualLen:a.byteLength,deflatedBytes:n.byteLength});return a}function je(e){if(typeof TextDecoder<"u")return new TextDecoder("utf-8").decode(e);if(typeof globalThis.Buffer<"u")return globalThis.Buffer.from(e).toString("utf-8");throw new N("No UTF-8 decoder available in this environment.",G.INVALID_STATE)}function $e(e,t,r){if(r===0)return new Int16Array(0);if(t%2===0)return new Int16Array(e,t,r);let n=new Uint8Array(r*2);return n.set(new Uint8Array(e,t,r*2)),new Int16Array(n.buffer)}function re(e,t,r){if(r===0)return new Float32Array(0);if(t%4===0)return new Float32Array(e,t,r);let n=new Uint8Array(r*4);return n.set(new Uint8Array(e,t,r*4)),new Float32Array(n.buffer)}function W(e,t,r){if(r===0)return new Uint16Array(0);if(t%2===0)return new Uint16Array(e,t,r);let n=new Uint8Array(r*2);return n.set(new Uint8Array(e,t,r*2)),new Uint16Array(n.buffer)}function ze(e,t,r){if(r===0)return new Uint32Array(0);if(t%4===0)return new Uint32Array(e,t,r);let n=new Uint8Array(r*4);return n.set(new Uint8Array(e,t,r*4)),new Uint32Array(n.buffer)}function Ye(e,t){if(e.length!==0&&!(e instanceof Uint16Array&&t>65535)){for(let r=0;r<e.length;r++)if(e[r]>=t)throw I("Index out of range of vertexCount.",{indexPosition:r,indexValue:e[r],vertexCount:t})}}function L(e){return e>>>1^-(e&1)}function We(e){let t=new Int16Array(e.length),r=0,n=0,o=0;for(let a=0;a<e.length;a+=3)r=r+L(e[a])<<16>>16,n=n+L(e[a+1])<<16>>16,o=o+L(e[a+2])<<16>>16,t[a]=r,t[a+1]=n,t[a+2]=o;return t}function Je(e){let t=new Uint16Array(e.length),r=0;for(let n=0;n<e.length;n++)r=r+L(e[n])&65535,t[n]=r;return t}function Xe(e){let t=new Uint32Array(e.length),r=0;for(let n=0;n<e.length;n++)r=r+L(e[n])>>>0,t[n]=r;return t}function I(e,t){return new N(e,G.VALIDATION_ERROR,{context:t})}var Ke=36;function qe(e,t,r,n,o){if(r+Ke>e.byteLength)throw I("Insufficient data to read UV chunk header.",{expectedBytes:Ke,availableBytes:e.byteLength-r,offset:r});let a=t.getUint32(r,!0);r+=4;let s=t.getFloat64(r,!0);r+=8;let u=t.getFloat64(r,!0);r+=8;let i=t.getFloat64(r,!0);r+=8;let f=t.getFloat64(r,!0);r+=8;let l=n*2,y=a===1,b=l*(y?4:2);if(r+b>e.byteLength)throw I("Insufficient data to read UV chunk.",{expectedBytes:b,availableBytes:e.byteLength-r,offset:r,uvFormat:a,vertexCount:n});let w=e.byteOffset+r,v;if(y)v=re(e.buffer,w,l).slice();else{let C=W(e.buffer,w,l);v=new Float32Array(l);let c=0,d=0;for(let p=0;p<l;p+=2)o?(c=c+L(C[p])&65535,d=d+L(C[p+1])&65535):(c=C[p],d=C[p+1]),v[p]=s+c*i,v[p+1]=u+d*f}return{uvs:v,offset:r+b}}function Ze(e,t,r,n){let o=r*3;if(t+o>e.byteLength)throw I("Insufficient data to read vertex-color chunk.",{expectedBytes:o,availableBytes:e.byteLength-t,offset:t,vertexCount:r});let a=e.subarray(t,t+o);if(!n)return a.slice();let s=new Uint8Array(o),u=0,i=0,f=0;for(let l=0;l<o;l+=3)u=u+L(a[l])&255,i=i+L(a[l+1])&255,f=f+L(a[l+2])&255,s[l]=u,s[l+1]=i,s[l+2]=f;return s}function he(e){let t=ge(e),r;t.isFloat32?r=t.vertexData:t.deltaEncoded?r=We(t.vertexData):r=t.vertexData;let n=t.indexData;return t.deltaEncoded&&(n=n instanceof Uint16Array?Je(n):Xe(n)),Ye(n,t.vertexCount),{metadata:t.metadata,flags:t.flags,vertices:r,indices:n,origin:t.origin,scale:t.scale,uvs:t.uvs,colors:t.colors}}function ge(e){if(!ke)throw new N("SLVA parsing requires a little-endian host: the zero-copy geometry readers view the wire bytes in host byte order.",G.ENVIRONMENT_ERROR);let t=Ne(Ge(e)),r=new DataView(t.buffer,t.byteOffset,t.byteLength);if(t.byteLength<12)throw I("Blob too small to contain SLVA header.",{expectedBytes:12,availableBytes:t.byteLength});let n=0,o=r.getUint32(n,!0);if(n+=4,o!==1096174675)throw I(`Invalid SLVA magic: 0x${o.toString(16)}`,{expectedMagic:`0x${1096174675 .toString(16)}`,actualMagic:`0x${o.toString(16)}`});let a=r.getUint32(n,!0);if(n+=4,a<1||a>3)throw I(`Unsupported SLVA version: ${a}`,{minSupportedVersion:1,maxSupportedVersion:3,actualVersion:a});let s=r.getUint32(n,!0);if(n+=4,n+s>t.byteLength)throw I("Insufficient data to read metadata JSON.",{expectedBytes:s,availableBytes:t.byteLength-n,offset:n});let u=t.subarray(n,n+s);n+=s;let i;try{i=JSON.parse(je(u))}catch(U){throw I(`Failed to parse metadata JSON: ${U instanceof Error?U.message:String(U)}`,{metadataLen:s})}if(n+56>t.byteLength)throw I("Insufficient data to read geometry header.",{expectedBytes:56,availableBytes:t.byteLength-n,offset:n});let f=r.getUint32(n,!0);n+=4;let l=r.getFloat64(n,!0);n+=8;let y=r.getFloat64(n,!0);n+=8;let b=r.getFloat64(n,!0);n+=8;let w=r.getFloat64(n,!0);n+=8;let v=r.getFloat64(n,!0);n+=8;let C=r.getFloat64(n,!0);n+=8;let c=r.getUint32(n,!0);n+=4;let d=(f&1)!==0,p=(f&4)!==0,m=c*3,S=m*(d?4:2);if(n+S>t.byteLength)throw I("Insufficient data to read vertices.",{expectedBytes:S,availableBytes:t.byteLength-n,offset:n,useFloat32:d,vertexCount:c});let T=t.byteOffset+n,g;if(d?g=re(t.buffer,T,m):p?g=W(t.buffer,T,m):g=$e(t.buffer,T,m),n+=S,n+4>t.byteLength)throw I("Insufficient data to read index count.",{expectedBytes:4,availableBytes:t.byteLength-n,offset:n});let x=r.getUint32(n,!0);n+=4;let R=(f&2)!==0,M=x*(R?2:4);if(n+M>t.byteLength)throw I("Insufficient data to read indices.",{expectedBytes:M,availableBytes:t.byteLength-n,offset:n,indexCount:x,useUint16Indices:R});let B=R?W(t.buffer,t.byteOffset+n,x):ze(t.buffer,t.byteOffset+n,x);n+=M;let D=null;if((f&8)!==0){let U=qe(t,r,n,c,p);D=U.uvs,n=U.offset}let H=null;return(f&16)!==0&&(H=Ze(t,n,c,p)),{metadata:i,flags:f,vertexData:g,indexData:B,isFloat32:d,deltaEncoded:p,vertexCount:c,origin:[l,y,b],scale:[w,v,C],uvs:D,colors:H}}var ot=256*1024*1024,ne=1024,_=new Map,oe=0;function at(e,t){let r=2166136261,n=o=>{r^=o,r=Math.imul(r,16777619)};for(let o=0;o<t.length;o++)n(t.charCodeAt(o));for(let o of e){if(!o){n(57005);continue}let a=o.byteLength;if(n(a),(o.byteOffset&3)===0&&(a&3)===0){let s=new Uint32Array(o.buffer,o.byteOffset,a>>2),u=Math.min(ne,s.length);for(let i=0;i<u;i++)n(s[i]);for(let i=Math.max(u,s.length-ne);i<s.length;i++)n(s[i])}else{let s=new Uint8Array(o.buffer,o.byteOffset,a),u=Math.min(ne*4,s.length);for(let i=0;i<u;i++)n(s[i]);for(let i=Math.max(u,s.length-ne*4);i<s.length;i++)n(s[i])}}return`${(r>>>0).toString(36)}:${e.length}`}function Gt(e){let t=e.index?.array.byteLength??0;for(let r of Object.values(e.attributes))t+=r.array.byteLength;return t}function J(e){let t=_.get(e);if(t)return _.delete(e),_.set(e,t),t.geometry}function X(e,t){let r=Gt(t);if(!(r>ot)&&!_.has(e))for(t.userData[$]=!0,_.set(e,{geometry:t,bytes:r}),oe+=r;oe>ot&&_.size>1;){let n=_.keys().next().value,o=_.get(n);_.delete(n),oe-=o.bytes,delete o.geometry.userData[$],o.geometry.dispose()}}ee(()=>Nt());function Nt(){for(let e of _.values())delete e.geometry.userData[$],e.geometry.dispose();_.clear(),oe=0}function jt(e){let{isFloat32:t,deltaEncoded:r,origin:n,scale:o,uvs:a,colors:s,jobs:u}=e,i=c=>c>>>1^-(c&1),f;if(t)f=e.vertexData;else{let c;if(r){let g=e.vertexData;c=new Int16Array(g.length);let x=0,R=0,E=0;for(let M=0;M<g.length;M+=3)x=x+i(g[M])<<16>>16,R=R+i(g[M+1])<<16>>16,E=E+i(g[M+2])<<16>>16,c[M]=x,c[M+1]=R,c[M+2]=E}else c=e.vertexData;f=new Float32Array(c.length);let d=n[0],p=n[1],m=n[2],h=o[0],S=o[1],T=o[2];for(let g=0;g<c.length;g+=3)f[g]=d+(c[g]+32767)*h,f[g+1]=p+(c[g+1]+32767)*S,f[g+2]=m+(c[g+2]+32767)*T}let l;if(r){let c=e.indexData;if(c instanceof Uint16Array){let d=new Uint16Array(c.length),p=0;for(let m=0;m<c.length;m++)p=p+i(c[m])&65535,d[m]=p;l=d}else{let d=new Uint32Array(c.length),p=0;for(let m=0;m<c.length;m++)p=p+i(c[m])>>>0,d[m]=p;l=d}}else l=e.indexData;let y=f.length/3;for(let c=0;c<l.length;c++)if(l[c]>=y)throw new Error(`Index ${l[c]} out of range of vertexCount ${y}`);let b=1024,w=(c,d)=>{let p=2166136261,m=h=>{p^=h,p=Math.imul(p,16777619)};for(let h=0;h<d.length;h++)m(d.charCodeAt(h));for(let h of c){if(!h){m(57005);continue}let S=h.byteLength;if(m(S),(h.byteOffset&3)===0&&(S&3)===0){let T=new Uint32Array(h.buffer,h.byteOffset,S>>2),g=Math.min(b,T.length);for(let x=0;x<g;x++)m(T[x]);for(let x=Math.max(g,T.length-b);x<T.length;x++)m(T[x])}else{let T=new Uint8Array(h.buffer,h.byteOffset,S),g=Math.min(b*4,T.length);for(let x=0;x<g;x++)m(T[x]);for(let x=Math.max(g,T.length-b*4);x<T.length;x++)m(T[x])}}return`${(p>>>0).toString(36)}:${c.length}`},v=(c,d)=>{let p=[],m=c;for(let h of d){m+=`|${h.vertexStart},${h.vertexCount},${h.indexStart},${h.indexCount}`;let S=h.vertexStart*3,T=S+h.vertexCount*3;p.push(f.subarray(S,T)),p.push(l.subarray(h.indexStart,h.indexStart+h.indexCount)),p.push(a?a.subarray(h.vertexStart*2,(h.vertexStart+h.vertexCount)*2):null),p.push(s?s.subarray(S,T):null)}return w(p,m)},C=[];for(let c of u){let d=0,p=0;for(let E of c.windows)d+=E.vertexCount,p+=E.indexCount;let m=new Float32Array(d*3),h=new Uint32Array(p),S=a?new Float32Array(d*2):null,T=s?new Uint8Array(d*3):null,g=0,x=0;for(let E of c.windows){let M=E.vertexStart*3;m.set(f.subarray(M,M+E.vertexCount*3),g*3),S&&a&&S.set(a.subarray(E.vertexStart*2,(E.vertexStart+E.vertexCount)*2),g*2),T&&s&&T.set(s.subarray(M,M+E.vertexCount*3),g*3);let B=E.vertexStart,D=E.vertexStart+E.vertexCount,H=g-E.vertexStart;for(let U=0;U<E.indexCount;U++){let k=l[E.indexStart+U];if(k<B||k>=D)throw new Error(`Index ${k} outside vertex window [${B}, ${D})`);h[x+U]=k+H}g+=E.vertexCount,x+=E.indexCount}let R=new Float32Array(d*3);for(let E=0;E<h.length;E+=3){let M=h[E]*3,B=h[E+1]*3,D=h[E+2]*3,H=m[D]-m[B],U=m[D+1]-m[B+1],k=m[D+2]-m[B+2],ve=m[M]-m[B],Se=m[M+1]-m[B+1],Ce=m[M+2]-m[B+2],le=U*Ce-k*Se,ue=k*ve-H*Ce,fe=H*Se-U*ve;R[M]+=le,R[M+1]+=ue,R[M+2]+=fe,R[B]+=le,R[B+1]+=ue,R[B+2]+=fe,R[D]+=le,R[D+1]+=ue,R[D+2]+=fe}for(let E=0;E<R.length;E+=3){let M=R[E],B=R[E+1],D=R[E+2],H=Math.sqrt(M*M+B*B+D*D)||1;R[E]=M/H,R[E+1]=B/H,R[E+2]=D/H}C.push({key:v(c.kind,c.windows),positions:m,normals:R,indices:h,uvs:S,colors:T})}return C}function st(){return[`const assemble = ${jt.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
- `)}var it=5e4,j,K=new Map,$t=1;function ct(){if(j!==void 0)return j;if(typeof Worker>"u"||typeof Blob>"u"||typeof URL>"u"||typeof URL.createObjectURL!="function")return j=null,null;try{let e=URL.createObjectURL(new Blob([st()],{type:"text/javascript"})),t=new Worker(e);t.onmessage=r=>{let{id:n,geometries:o,error:a}=r.data,s=K.get(n);s&&(K.delete(n),o?s.resolve(o):s.reject(new Error(a??"mesh assembly failed in worker")))},t.onerror=()=>{for(let r of K.values())r.reject(new Error("mesh assembly worker crashed"));K.clear(),t.terminate(),j=null},j=t}catch{j=null}return j}function lt(e,t,r){return new Promise((n,o)=>{let a=$t++;K.set(a,{resolve:n,reject:o}),e.postMessage({id:a,input:t},r)})}import*as z from"three";import*as ce from"three";var zt=64,Yt=256,F=new Map,q=new Map,ae=0,ie=class extends Error{constructor(t){super(`Texture load for ${t} resolved after clearTextureCache(); texture disposed.`),this.name="StaleTextureLoadError"}},se=1;function ut(e){se=Math.max(1,e);for(let t of F.values())t.anisotropy!==se&&(t.anisotropy=se,t.needsUpdate=!0)}He(ut);function ft(e,t){let r=Jt(t),n=F.get(r);if(n){F.delete(r),F.set(r,n),e.map=n,e.needsUpdate=!0;return}typeof document>"u"||qt(t,r).then(o=>{e.map=o,e.needsUpdate=!0}).catch(o=>{o instanceof ie||A().warn(`Failed to load material texture ${t}:`,o)})}ee(()=>Wt());function Wt(){ae++;for(let e of F.values())delete e.userData[Q],e.dispose();F.clear(),q.clear()}function Jt(e){return e.length<=Yt?e:`data-uri:${Xt(e).toString(16)}:${e.length}`}function Xt(e){let t=2166136261;for(let r=0;r<e.length;r++)t^=e.charCodeAt(r),t=Math.imul(t,16777619);return t>>>0}function Kt(e,t){for(t.userData[Q]=!0,F.set(e,t);F.size>zt;){let r=F.keys().next().value,n=F.get(r);F.delete(r),delete n.userData[Q],n.dispose()}}function qt(e,t){let r=q.get(t);if(!r){let n=ae;r=new Promise((o,a)=>{new ce.TextureLoader().load(e,s=>{if(n!==ae){s.dispose(),a(new ie(e));return}s.colorSpace=ce.SRGBColorSpace,s.anisotropy=se,Kt(t,s),q.delete(t),o(s)},void 0,s=>{n===ae&&q.delete(t),a(s)})}),q.set(t,r)}return r}var Zt=.5,Qt=.5,er=.3;function be(e,t){let r=Ie(e.color),n=t?.vertexColors??!1,o=t?.appearance,a=new z.MeshPhysicalMaterial({color:r,metalness:e.metalness,roughness:e.roughness,opacity:e.opacity,transparent:e.transparent,vertexColors:n,side:o?.cullBackfaces?z.FrontSide:z.DoubleSide,polygonOffset:!0,polygonOffsetFactor:.5,polygonOffsetUnits:.5,depthWrite:!0,depthTest:!0});return o?.envMapIntensity!=null&&(a.envMapIntensity=o.envMapIntensity),e.metalness>Zt&&(a.clearcoat=Qt,a.clearcoatRoughness=er),n&&tr(a),e.map&&ft(a,e.map),a}function tr(e){e.onBeforeCompile=t=>{t.vertexShader=t.vertexShader.replace("#include <color_vertex>",`#include <color_vertex>
1
+ import{a as F,b as _,c as v,f as ce,k as ue,l as fe,m as me,o as de,p as pe}from"./chunk-KRA5RVHM.js";import"./chunk-5XGN7UAV.js";function Xe(e){return e.map(t=>{let r=t.clone(!0),n=[];t.traverse(o=>n.push(o));let a=0;return r.traverse(o=>{let i=n[a++],c=o;i.geometry&&(c.geometry=i.geometry.clone())}),r})}function Ze(e){e.forEach(t=>pe(t,{materials:!1}))}var qe={clone:Xe,release:Ze};import{Line2 as Qe}from"three/addons/lines/Line2.js";import{LineGeometry as et}from"three/addons/lines/LineGeometry.js";import{LineMaterial as tt}from"three/addons/lines/LineMaterial.js";import*as ye from"three";var Ke="#ffffff";function z(e,t){let r=t??1;return{color:new ye.Color(e??Ke),transparent:r<1,opacity:r}}var rt=2,nt=6;function he(e){let t=ot(e);if(!t)return null;let r=new et;r.setPositions(t);let n=z(e.color,e.opacity),a=new tt({color:n.color}),o=a;o.linewidth=e.width??rt,o.transparent=n.transparent,o.opacity=n.opacity;let i=new Qe(r,a);return i.computeLineDistances(),i.name=e.name,i.userData={source:"compute",id:e.id,layer:e.layer,kind:"curve",metadata:e.metadata},i}function ot(e){if(!e.points)throw new _(`Curve display item '${e.id}' has no tessellated points. It was produced by an outdated Display component \u2014 upgrade it in Grasshopper (Solution \u2192 Upgrade obsolete components) and re-save the definition.`,F.INVALID_CONFIG,{context:{itemId:e.id,kind:e.kind}});return e.points.length>=nt?e.points:null}import*as H from"three";function be(e){let{position:t}=e;if(!t||typeof t.X!="number"||!Number.isFinite(t.X)||typeof t.Y!="number"||!Number.isFinite(t.Y)||typeof t.Z!="number"||!Number.isFinite(t.Z))return v().warn(`Skipping point display item with missing or non-finite position (id: ${String(e.id)}).`),null;let r=new H.BufferGeometry;r.setAttribute("position",new H.Float32BufferAttribute([t.X,t.Y,t.Z],3));let n=new H.PointsMaterial({...z(e.color,e.opacity),size:6,sizeAttenuation:!1}),a=new H.Points(r,n);return a.name=e.name,a.userData={source:"compute",id:e.id,layer:e.layer,kind:"point",metadata:e.metadata},a}function q(e){if(!e||e.length===0)return[];let t=[];for(let r of e)switch(r.kind){case"curve":{let n=he(r);n&&t.push(n);break}case"point":{let n=be(r);n&&t.push(n);break}default:{let a=r;v().warn(`Skipping unknown display item kind: ${String(a.kind)}`);break}}return t}import*as P from"three";var ge=new Uint16Array(new Uint8Array([1,0]).buffer)[0]===1;import{inflateSync as at}from"fflate";function Ae(e){return typeof e=="string"?ce(e):e instanceof Uint8Array?e:new Uint8Array(e)}function xe(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 r=t.getUint32(4,!0),n=e.subarray(8),a=Math.max(n.byteLength*1032+1024,1<<20);if(r>a)throw T("SLVZ header declares an implausible uncompressed length",{uncompressedLen:r,deflatedBytes:n.byteLength,maxPlausibleLen:a});let o;try{o=at(n,{out:new Uint8Array(r+1)})}catch(i){throw T(`Failed to inflate SLVZ blob: ${i instanceof Error?i.message:String(i)}`,{uncompressedLen:r,deflatedBytes:n.byteLength})}if(o.byteLength!==r)throw T("SLVZ payload inflated to a different size than the header declares.",{declaredLen:r,actualLen:o.byteLength,deflatedBytes:n.byteLength});return o}function Ee(e){if(typeof TextDecoder<"u")return new TextDecoder("utf-8").decode(e);if(typeof globalThis.Buffer<"u")return globalThis.Buffer.from(e).toString("utf-8");throw new _("No UTF-8 decoder available in this environment.",F.INVALID_STATE)}function we(e,t,r){if(r===0)return new Int16Array(0);if(t%2===0)return new Int16Array(e,t,r);let n=new Uint8Array(r*2);return n.set(new Uint8Array(e,t,r*2)),new Int16Array(n.buffer)}function W(e,t,r){if(r===0)return new Float32Array(0);if(t%4===0)return new Float32Array(e,t,r);let n=new Uint8Array(r*4);return n.set(new Uint8Array(e,t,r*4)),new Float32Array(n.buffer)}function V(e,t,r){if(r===0)return new Uint16Array(0);if(t%2===0)return new Uint16Array(e,t,r);let n=new Uint8Array(r*2);return n.set(new Uint8Array(e,t,r*2)),new Uint16Array(n.buffer)}function Me(e,t,r){if(r===0)return new Uint32Array(0);if(t%4===0)return new Uint32Array(e,t,r);let n=new Uint8Array(r*4);return n.set(new Uint8Array(e,t,r*4)),new Uint32Array(n.buffer)}function ve(e,t){if(e.length!==0&&!(e instanceof Uint16Array&&t>65535)){for(let r=0;r<e.length;r++)if(e[r]>=t)throw T("Index out of range of vertexCount.",{indexPosition:r,indexValue:e[r],vertexCount:t})}}function C(e){return e>>>1^-(e&1)}function Se(e){let t=new Int16Array(e.length),r=0,n=0,a=0;for(let o=0;o<e.length;o+=3)r=r+C(e[o])<<16>>16,n=n+C(e[o+1])<<16>>16,a=a+C(e[o+2])<<16>>16,t[o]=r,t[o+1]=n,t[o+2]=a;return t}function Te(e){let t=new Uint16Array(e.length),r=0;for(let n=0;n<e.length;n++)r=r+C(e[n])&65535,t[n]=r;return t}function Re(e){let t=new Uint32Array(e.length),r=0;for(let n=0;n<e.length;n++)r=r+C(e[n])>>>0,t[n]=r;return t}function T(e,t){return new _(e,F.VALIDATION_ERROR,{context:t})}var Be=36;function Ie(e,t,r,n,a){if(r+Be>e.byteLength)throw T("Insufficient data to read UV chunk header.",{expectedBytes:Be,availableBytes:e.byteLength-r,offset:r});let o=t.getUint32(r,!0);r+=4;let i=t.getFloat64(r,!0);r+=8;let c=t.getFloat64(r,!0);r+=8;let f=t.getFloat64(r,!0);r+=8;let m=t.getFloat64(r,!0);r+=8;let l=n*2,w=o===1,M=l*(w?4:2);if(r+M>e.byteLength)throw T("Insufficient data to read UV chunk.",{expectedBytes:M,availableBytes:e.byteLength-r,offset:r,uvFormat:o,vertexCount:n});let d=e.byteOffset+r,h;if(w)h=W(e.buffer,d,l).slice();else{let u=V(e.buffer,d,l);h=new Float32Array(l);let s=0,y=0;for(let x=0;x<l;x+=2)a?(s=s+C(u[x])&65535,y=y+C(u[x+1])&65535):(s=u[x],y=u[x+1]),h[x]=i+s*f,h[x+1]=c+y*m}return{uvs:h,offset:r+M}}function De(e,t,r,n){let a=r*3;if(t+a>e.byteLength)throw T("Insufficient data to read vertex-color chunk.",{expectedBytes:a,availableBytes:e.byteLength-t,offset:t,vertexCount:r});let o=e.subarray(t,t+a);if(!n)return o.slice();let i=new Uint8Array(a),c=0,f=0,m=0;for(let l=0;l<a;l+=3)c=c+C(o[l])&255,f=f+C(o[l+1])&255,m=m+C(o[l+2])&255,i[l]=c,i[l+1]=f,i[l+2]=m;return i}function Q(e){let t=ee(e),r;t.isFloat32?r=t.vertexData:t.deltaEncoded?r=Se(t.vertexData):r=t.vertexData;let n=t.indexData;return t.deltaEncoded&&(n=n instanceof Uint16Array?Te(n):Re(n)),ve(n,t.vertexCount),{metadata:t.metadata,flags:t.flags,vertices:r,indices:n,origin:t.origin,scale:t.scale,uvs:t.uvs,colors:t.colors}}function ee(e){if(!ge)throw new _("SLVA parsing requires a little-endian host: the zero-copy geometry readers view the wire bytes in host byte order.",F.ENVIRONMENT_ERROR);let t=xe(Ae(e)),r=new DataView(t.buffer,t.byteOffset,t.byteLength);if(t.byteLength<12)throw T("Blob too small to contain SLVA header.",{expectedBytes:12,availableBytes:t.byteLength});let n=0,a=r.getUint32(n,!0);if(n+=4,a!==1096174675)throw T(`Invalid SLVA magic: 0x${a.toString(16)}`,{expectedMagic:`0x${1096174675 .toString(16)}`,actualMagic:`0x${a.toString(16)}`});let o=r.getUint32(n,!0);if(n+=4,o<1||o>3)throw T(`Unsupported SLVA version: ${o}`,{minSupportedVersion:1,maxSupportedVersion:3,actualVersion:o});let i=r.getUint32(n,!0);if(n+=4,n+i>t.byteLength)throw T("Insufficient data to read metadata JSON.",{expectedBytes:i,availableBytes:t.byteLength-n,offset:n});let c=t.subarray(n,n+i);n+=i;let f;try{f=JSON.parse(Ee(c))}catch(L){throw T(`Failed to parse metadata JSON: ${L instanceof Error?L.message:String(L)}`,{metadataLen:i})}if(n+56>t.byteLength)throw T("Insufficient data to read geometry header.",{expectedBytes:56,availableBytes:t.byteLength-n,offset:n});let m=r.getUint32(n,!0);n+=4;let l=r.getFloat64(n,!0);n+=8;let w=r.getFloat64(n,!0);n+=8;let M=r.getFloat64(n,!0);n+=8;let d=r.getFloat64(n,!0);n+=8;let h=r.getFloat64(n,!0);n+=8;let u=r.getFloat64(n,!0);n+=8;let s=r.getUint32(n,!0);n+=4;let y=(m&1)!==0,x=(m&4)!==0,A=s*3,B=A*(y?4:2);if(n+B>t.byteLength)throw T("Insufficient data to read vertices.",{expectedBytes:B,availableBytes:t.byteLength-n,offset:n,useFloat32:y,vertexCount:s});let b=t.byteOffset+n,p;if(y?p=W(t.buffer,b,A):x?p=V(t.buffer,b,A):p=we(t.buffer,b,A),n+=B,n+4>t.byteLength)throw T("Insufficient data to read index count.",{expectedBytes:4,availableBytes:t.byteLength-n,offset:n});let E=r.getUint32(n,!0);n+=4;let S=(m&2)!==0,D=E*(S?2:4);if(n+D>t.byteLength)throw T("Insufficient data to read indices.",{expectedBytes:D,availableBytes:t.byteLength-n,offset:n,indexCount:E,useUint16Indices:S});let O=S?V(t.buffer,t.byteOffset+n,E):Me(t.buffer,t.byteOffset+n,E);n+=D;let U=null;if((m&8)!==0){let L=Ie(t,r,n,s,x);U=L.uvs,n=L.offset}let G=null;return(m&16)!==0&&(G=De(t,n,s,x)),{metadata:f,flags:m,vertexData:p,indexData:O,isFloat32:y,deltaEncoded:x,vertexCount:s,origin:[l,w,M],scale:[d,h,u],uvs:U,colors:G}}function ut(e){let{isFloat32:t,deltaEncoded:r,origin:n,scale:a,uvs:o,colors:i,jobs:c}=e,f=d=>d>>>1^-(d&1),m;if(t)m=e.vertexData;else{let d;if(r){let g=e.vertexData;d=new Int16Array(g.length);let B=0,b=0,p=0;for(let E=0;E<g.length;E+=3)B=B+f(g[E])<<16>>16,b=b+f(g[E+1])<<16>>16,p=p+f(g[E+2])<<16>>16,d[E]=B,d[E+1]=b,d[E+2]=p}else d=e.vertexData;m=new Float32Array(d.length);let h=n[0],u=n[1],s=n[2],y=a[0],x=a[1],A=a[2];for(let g=0;g<d.length;g+=3)m[g]=h+(d[g]+32767)*y,m[g+1]=u+(d[g+1]+32767)*x,m[g+2]=s+(d[g+2]+32767)*A}let l;if(r){let d=e.indexData;if(d instanceof Uint16Array){let h=new Uint16Array(d.length),u=0;for(let s=0;s<d.length;s++)u=u+f(d[s])&65535,h[s]=u;l=h}else{let h=new Uint32Array(d.length),u=0;for(let s=0;s<d.length;s++)u=u+f(d[s])>>>0,h[s]=u;l=h}}else l=e.indexData;let w=m.length/3;for(let d=0;d<l.length;d++)if(l[d]>=w)throw new Error(`Index ${l[d]} out of range of vertexCount ${w}`);let M=[];for(let d of c){let h=0,u=0;for(let p of d.windows)h+=p.vertexCount,u+=p.indexCount;let s=new Float32Array(h*3),y=new Uint32Array(u),x=o?new Float32Array(h*2):null,A=i?new Uint8Array(h*3):null,g=0,B=0;for(let p of d.windows){let E=p.vertexStart*3;s.set(m.subarray(E,E+p.vertexCount*3),g*3),x&&o&&x.set(o.subarray(p.vertexStart*2,(p.vertexStart+p.vertexCount)*2),g*2),A&&i&&A.set(i.subarray(E,E+p.vertexCount*3),g*3);let S=p.vertexStart,I=p.vertexStart+p.vertexCount,D=g-p.vertexStart;for(let O=0;O<p.indexCount;O++){let U=l[p.indexStart+O];if(U<S||U>=I)throw new Error(`Index ${U} outside vertex window [${S}, ${I})`);y[B+O]=U+D}g+=p.vertexCount,B+=p.indexCount}let b=new Float32Array(h*3);for(let p=0;p<y.length;p+=3){let E=y[p]*3,S=y[p+1]*3,I=y[p+2]*3,D=s[I]-s[S],O=s[I+1]-s[S+1],U=s[I+2]-s[S+2],G=s[E]-s[S],L=s[E+1]-s[S+1],le=s[E+2]-s[S+2],J=O*le-U*L,X=U*G-D*le,Z=D*L-O*G;b[E]+=J,b[E+1]+=X,b[E+2]+=Z,b[S]+=J,b[S+1]+=X,b[S+2]+=Z,b[I]+=J,b[I+1]+=X,b[I+2]+=Z}for(let p=0;p<b.length;p+=3){let E=b[p],S=b[p+1],I=b[p+2],D=Math.sqrt(E*E+S*S+I*I)||1;b[p]=E/D,b[p+1]=S/D,b[p+2]=I/D}M.push({positions:s,normals:b,indices:y,uvs:x,colors:A})}return M}function _e(){return[`const assemble = ${ut.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
+ `)}var He=5e4,k,j=new Map,ft=1;function Pe(){if(k!==void 0)return k;if(typeof Worker>"u"||typeof Blob>"u"||typeof URL>"u"||typeof URL.createObjectURL!="function")return k=null,null;try{let e=URL.createObjectURL(new Blob([_e()],{type:"text/javascript"})),t=new Worker(e);t.onmessage=r=>{let{id:n,geometries:a,error:o}=r.data,i=j.get(n);i&&(j.delete(n),a?i.resolve(a):i.reject(new Error(o??"mesh assembly failed in worker")))},t.onerror=()=>{for(let r of j.values())r.reject(new Error("mesh assembly worker crashed"));j.clear(),t.terminate(),k=null},k=t}catch{k=null}return k}function ke(e,t,r){return new Promise((n,a)=>{let o=ft++;j.set(o,{resolve:n,reject:a}),e.postMessage({id:o,input:t},r)})}import*as N from"three";import*as Y from"three";var Ne=1;function Ge(e){Ne=Math.max(1,e)}de(Ge);function Ve(e,t){typeof document>"u"||new Y.TextureLoader().load(t,r=>{r.colorSpace=Y.SRGBColorSpace,r.anisotropy=Ne,e.map=r,e.needsUpdate=!0},void 0,r=>{v().warn(`Failed to load material texture ${t}:`,r)})}var mt=.5,dt=.5,pt=.3;function te(e,t){let r=ue(e.color),n=t?.vertexColors??!1,a=t?.appearance,o=new N.MeshPhysicalMaterial({color:r,metalness:e.metalness,roughness:e.roughness,opacity:e.opacity,transparent:e.transparent,vertexColors:n,side:a?.cullBackfaces?N.FrontSide:N.DoubleSide,polygonOffset:!0,polygonOffsetFactor:.5,polygonOffsetUnits:.5,depthWrite:!0,depthTest:!0});return a?.envMapIntensity!=null&&(o.envMapIntensity=a.envMapIntensity),e.metalness>mt&&(o.clearcoat=dt,o.clearcoatRoughness=pt),n&&yt(o),e.map&&Ve(o,e.map),o}function yt(e){e.onBeforeCompile=t=>{t.vertexShader=t.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`)}}import*as O from"three";function Z(e,t){return new N(e,G.VALIDATION_ERROR,{context:t})}function Ee(e,t,r,n){for(let o of e){if(!Number.isInteger(o.materialId)||o.materialId<0||o.materialId>=t)throw Z("Group materialId out of range of the materials array.",{materialId:o.materialId,materialCount:t});for(let a of o.meshes){let s={vertexStart:a.vertexStart,vertexCount:a.vertexCount,indexStart:a.indexStart,indexCount:a.indexCount};for(let[u,i]of Object.entries(s))if(!Number.isInteger(i)||i<0)throw Z(`Mesh metadata field "${u}" must be a non-negative integer.`,{meshName:a.name,field:u,value:i});if(a.vertexStart+a.vertexCount>r)throw Z("Mesh vertex window exceeds the batch vertex buffer.",{meshName:a.name,vertexStart:a.vertexStart,vertexCount:a.vertexCount,totalVertexCount:r});if(a.indexStart+a.indexCount>n)throw Z("Mesh index window exceeds the batch index buffer.",{meshName:a.name,indexStart:a.indexStart,indexCount:a.indexCount,totalIndexCount:n})}}}function xe(e,t){return Z("Index references a vertex outside its mesh's vertex window.",{meshName:t.name,indexValue:e,vertexStart:t.vertexStart,vertexCount:t.vertexCount})}function Ae(e,t,r,n,o,a){let s=[],u=e;for(let i of t){u+=`|${i.vertexStart},${i.vertexCount},${i.indexStart},${i.indexCount}`;let f=i.vertexStart*3,l=f+i.vertexCount*3;s.push(r.subarray(f,l)),s.push(n.subarray(i.indexStart,i.indexStart+i.indexCount)),s.push(o?o.subarray(i.vertexStart*2,(i.vertexStart+i.vertexCount)*2):null),s.push(a?a.subarray(f,l):null)}return at(s,u)}function mt(e,t,r){let n=new Float32Array(e.length),o=t[0],a=t[1],s=t[2],u=r[0],i=r[1],f=r[2];for(let l=0;l<e.length;l+=3)n[l]=o+(e[l]+32767)*u,n[l+1]=a+(e[l+1]+32767)*i,n[l+2]=s+(e[l+2]+32767)*f;return n}function dt(e,t,r,n,o=null,a=null){let s=Ae("merged",e.meshes,t,r,o,a),u=J(s);if(!u){let i=0,f=0;for(let c of e.meshes)i+=c.vertexCount,f+=c.indexCount;let l=new Float32Array(i*3),y=new Uint32Array(f),b=o?new Float32Array(i*2):null,w=a?new Uint8Array(i*3):null,v=0,C=0;for(let c of e.meshes){let d=c.vertexStart*3,p=c.vertexCount*3;if(l.set(t.subarray(d,d+p),v*3),b&&o){let g=c.vertexStart*2;b.set(o.subarray(g,g+c.vertexCount*2),v*2)}w&&a&&w.set(a.subarray(d,d+p),v*3);let m=r.subarray(c.indexStart,c.indexStart+c.indexCount),h=v-c.vertexStart,S=c.vertexStart,T=c.vertexStart+c.vertexCount;for(let g=0;g<m.length;g++){let x=m[g];if(x<S||x>=T)throw xe(x,c);y[C+g]=x+h}v+=c.vertexCount,C+=c.indexCount}u=new O.BufferGeometry,u.setAttribute("position",new O.BufferAttribute(l,3)),u.setIndex(new O.BufferAttribute(y,1)),b&&u.setAttribute("uv",new O.BufferAttribute(b,2)),w&&u.setAttribute("color",new O.BufferAttribute(w,3,!0)),u.computeVertexNormals(),X(s,u)}return Me(u,e,n)}function Me(e,t,r){let n=new O.Mesh(e,r[t.materialId]),o=t.meshes[0],a=t.meshes.map(s=>s.name).filter(s=>s&&s.length>0);return n.name=a.length>0?a[0]:`merged_material_${t.materialId}`,n.castShadow=!0,n.receiveShadow=!0,n.userData={source:"compute",name:n.name,layer:o?.layer??"",originalIndex:o?.originalIndex??0,metadata:o?.metadata??{},mergedFrom:t.meshes.slice(1).map(s=>({name:s.name,layer:s.layer,originalIndex:s.originalIndex}))},n}function pt(e,t,r,n,o=null,a=null){let s=[];for(let u of e.meshes){let i=u.vertexStart*3,f=u.vertexCount*3,l=Ae("single",[u],t,r,o,a),y=J(l);if(!y){let b=t.slice(i,i+f),w=r.subarray(u.indexStart,u.indexStart+u.indexCount),v=new Uint32Array(w.length),C=u.vertexStart,c=u.vertexStart+u.vertexCount;for(let d=0;d<w.length;d++){let p=w[d];if(p<C||p>=c)throw xe(p,u);v[d]=p-C}if(y=new O.BufferGeometry,y.setAttribute("position",new O.BufferAttribute(b,3)),y.setIndex(new O.BufferAttribute(v,1)),o){let d=u.vertexStart*2,p=o.slice(d,d+u.vertexCount*2);y.setAttribute("uv",new O.BufferAttribute(p,2))}if(a){let d=a.slice(i,i+f);y.setAttribute("color",new O.BufferAttribute(d,3,!0))}y.computeVertexNormals(),X(l,y)}s.push(we(y,u,e,n))}return s}function we(e,t,r,n){let o=new O.Mesh(e,n[r.materialId]);return o.name=t.name,o.userData={source:"compute",name:t.name,layer:t.layer??"",originalIndex:t.originalIndex,metadata:t.metadata??{}},o.castShadow=!0,o.receiveShadow=!0,o}async function Te(e,t,r){let{mergeByMaterial:n=!0,debug:o=!1,material:a}=t??{},{parseTime:s=0,perfStart:u=o?performance.now():0}=r??{};if(!e.compressedData)return[];let i=await ht(e.compressedData,{mergeByMaterial:n,debug:o,material:a,fallback:{materials:e.materials,groups:e.groups,sourceComponentId:e.sourceComponentId}});if(i)return i;let f=performance.now(),l=he(e.compressedData),y=performance.now()-f,b=o?nr(e.compressedData):0;return yt(l,{mergeByMaterial:n,debug:o,material:a,parseTime:s,decodeTime:y,perfStart:u,blobBytes:b,fallback:{materials:e.materials,groups:e.groups,sourceComponentId:e.sourceComponentId}})}async function rr(e,t){let{mergeByMaterial:r=!0,debug:n=!1,material:o}=t??{},a=n?performance.now():0,s=await ht(e,{mergeByMaterial:r,debug:n,material:o});if(s)return s;let u=performance.now(),i=he(e),f=performance.now()-u,l=e.byteLength;return yt(i,{mergeByMaterial:r,debug:n,material:o,parseTime:0,decodeTime:f,perfStart:a,blobBytes:l})}function yt(e,t){let{mergeByMaterial:r,debug:n,material:o,parseTime:a,decodeTime:s,perfStart:u,blobBytes:i,fallback:f}=t,l=e.metadata.materials??f?.materials??[],y=e.metadata.groups??f?.groups??[],b=f?.sourceComponentId??e.metadata.sourceComponentId,w=(e.flags&1)!==0;Ee(y,l.length,e.vertices.length/3,e.indices.length);let v=w?e.vertices:mt(e.vertices,e.origin,e.scale);if(n){let m=e.vertices.byteLength+e.indices.byteLength;A().debug("Mesh Batch Stats:"),A().debug(` Materials: ${l.length} | Groups: ${y.length}`),A().debug(` Vertices: ${e.vertices.length/3} | Indices: ${e.indices.length}`),A().debug(` Format: ${w?"float32":"int16 quantized"}`),A().debug(` Blob: ${(i/1024/1024).toFixed(2)} MB | Geometry on wire: ${(m/1024/1024).toFixed(2)} MB`)}let C=performance.now(),c=l.map(m=>be(m,{vertexColors:e.colors!=null,appearance:o})),d=[];for(let m of y)if(r&&m.meshes.length>1){let h=dt(m,v,e.indices,c,e.uvs,e.colors);h.userData.sourceComponentId=b??null,d.push(h)}else{let h=pt(m,v,e.indices,c,e.uvs,e.colors);for(let S of h)S.userData.sourceComponentId=b??null;d.push(...h)}let p=performance.now()-C;if(n){let m=performance.now()-u;A().debug("Performance:"),a>0&&A().debug(` Parse JSON: ${a.toFixed(2)}ms`),A().debug(` Decode binary: ${s.toFixed(2)}ms`),A().debug(` Create Meshes: ${p.toFixed(2)}ms`),A().debug(` Total: ${m.toFixed(2)}ms`)}return Promise.resolve(d)}async function ht(e,t){if(typeof Worker>"u")return null;let r=ge(e);if(r.indexData.length/3<it)return null;let n=ct();if(!n)return null;let o=r.metadata.materials??t.fallback?.materials??[],a=r.metadata.groups??t.fallback?.groups??[],s=t.fallback?.sourceComponentId??r.metadata.sourceComponentId;Ee(a,o.length,r.vertexCount,r.indexData.length);let u=c=>({vertexStart:c.vertexStart,vertexCount:c.vertexCount,indexStart:c.indexStart,indexCount:c.indexCount}),i=[],f=[];for(let c of a)if(t.mergeByMaterial&&c.meshes.length>1)i.push({kind:"merged",windows:c.meshes.map(u)}),f.push({kind:"merged",group:c});else for(let d of c.meshes)i.push({kind:"single",windows:[u(d)]}),f.push({kind:"single",group:c,meshMeta:d});let l=r.vertexData.slice(),y=r.indexData.slice(),b=[l.buffer,y.buffer];r.uvs&&b.push(r.uvs.buffer),r.colors&&b.push(r.colors.buffer);let w;try{w=await lt(n,{vertexData:l,isFloat32:r.isFloat32,deltaEncoded:r.deltaEncoded,origin:r.origin,scale:r.scale,indexData:y,uvs:r.uvs,colors:r.colors,jobs:i},b)}catch(c){return A().warn("Mesh assembly worker failed; falling back to main-thread parse.",c),null}if(w.length!==i.length)return null;let v=o.map(c=>be(c,{vertexColors:r.colors!=null,appearance:t.material})),C=[];for(let c=0;c<w.length;c++){let d=w[c],p=f[c],m=J(d.key);m||(m=new V.BufferGeometry,m.setAttribute("position",new V.BufferAttribute(d.positions,3)),m.setAttribute("normal",new V.BufferAttribute(d.normals,3)),m.setIndex(new V.BufferAttribute(d.indices,1)),d.uvs&&m.setAttribute("uv",new V.BufferAttribute(d.uvs,2)),d.colors&&m.setAttribute("color",new V.BufferAttribute(d.colors,3,!0)),X(d.key,m));let h=p.kind==="merged"?Me(m,p.group,v):we(m,p.meshMeta,p.group,v);h.userData.sourceComponentId=s??null,C.push(h)}return t.debug&&A().debug(`Mesh batch assembled off-thread: ${C.length} meshes, ${r.indexData.length/3} triangles`),C}function nr(e){return Math.floor(e.length*3/4)}var Re={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:254e-10,Mils:254e-7,Inches:.0254,Feet:.3048,Yards:.9144,Miles:1609.344,NauticalMiles:1852},or="Display",ar="DisplayBatch";function sr(e){let t=e.split(".");return t.includes(or)||t.includes(ar)}var gt=new Set;async function ir(e,t){let r=performance.now(),n=[],{allowScaling:o=!0,allowAutoPosition:a=!1,groundAxis:s="z",rhino:u,debug:i=!1,parsing:f={}}=t??{};try{let l=o?cr(e.modelunits):1;return await lr(e,n,l,f,u,i),a&&dr(n,s),n}catch(l){throw pr(l,n),l}finally{i&&hr(r)}}function cr(e){let t=Re[e];return t!==void 0?t:(gt.has(e)||(gt.add(e),A().warn(`Unknown Rhino model unit "${e}" \u2014 geometry will not be scaled (factor 1). Known units: ${Object.keys(Re).join(", ")}.`)),1)}async function lr(e,t,r,n,o,a){for(let s of e.values){let u=s.InnerTree;for(let i in u){let f=u[i];f&&await ur(f,t,r,n,o,a)}}}async function ur(e,t,r,n,o,a){for(let s of e){if(!sr(s.type))continue;let u={mergeByMaterial:!0,debug:!1,...n},i=fr(s.data);if(!i){A().error("Error parsing display batch envelope: invalid JSON");continue}let f=await Te(i,u),l=pe(i.items,{rhino:o}),y=[...f,...l];if(r!==1)for(let b of y)b.scale.set(r,r,r);t.push(...y),a&&A().debug(`Extracted ${f.length} meshes and ${l.length} items from batch`)}}function fr(e){return typeof e=="string"?mr(e):e}function mr(e){try{return JSON.parse(e)}catch{return}}function dr(e,t){if(e.length===0)return;let r=Oe(e);De(e,r.min[t],t)}function pr(e,t){A().error("An unexpected error occurred:",e),yr(t)}function yr(e){for(let t of e){let r=t;r.geometry&&r.geometry.dispose(),r.material&&(Array.isArray(r.material)?r.material.forEach(n=>n.dispose()):r.material.dispose())}}function hr(e){let t=performance.now()-e;A().info("Time to process meshes:",`${t.toFixed(2)}ms`)}function gr(){Ue()}export{Re as SCALE_FACTORS,ir as getThreeMeshesFromComputeResponse,xt as meshPolicy,pe as parseDisplayItems,rr as parseMeshBatchBlob,Te as parseMeshBatchObject,gr as releaseParseCaches,ut as setTextureAnisotropy};
9
+ #endif`)}}import*as R from"three";function $(e,t){return new _(e,F.VALIDATION_ERROR,{context:t})}function re(e,t,r,n){for(let a of e){if(!Number.isInteger(a.materialId)||a.materialId<0||a.materialId>=t)throw $("Group materialId out of range of the materials array.",{materialId:a.materialId,materialCount:t});for(let o of a.meshes){let i={vertexStart:o.vertexStart,vertexCount:o.vertexCount,indexStart:o.indexStart,indexCount:o.indexCount};for(let[c,f]of Object.entries(i))if(!Number.isInteger(f)||f<0)throw $(`Mesh metadata field "${c}" must be a non-negative integer.`,{meshName:o.name,field:c,value:f});if(o.vertexStart+o.vertexCount>r)throw $("Mesh vertex window exceeds the batch vertex buffer.",{meshName:o.name,vertexStart:o.vertexStart,vertexCount:o.vertexCount,totalVertexCount:r});if(o.indexStart+o.indexCount>n)throw $("Mesh index window exceeds the batch index buffer.",{meshName:o.name,indexStart:o.indexStart,indexCount:o.indexCount,totalIndexCount:n})}}}function ne(e,t){return $("Index references a vertex outside its mesh's vertex window.",{meshName:t.name,indexValue:e,vertexStart:t.vertexStart,vertexCount:t.vertexCount})}function je(e,t,r){let n=new Float32Array(e.length),a=t[0],o=t[1],i=t[2],c=r[0],f=r[1],m=r[2];for(let l=0;l<e.length;l+=3)n[l]=a+(e[l]+32767)*c,n[l+1]=o+(e[l+1]+32767)*f,n[l+2]=i+(e[l+2]+32767)*m;return n}function $e(e,t,r,n,a=null,o=null){let i=0,c=0;for(let u of e.meshes)i+=u.vertexCount,c+=u.indexCount;let f=new Float32Array(i*3),m=new Uint32Array(c),l=a?new Float32Array(i*2):null,w=o?new Uint8Array(i*3):null,M=0,d=0;for(let u of e.meshes){let s=u.vertexStart*3,y=u.vertexCount*3;if(f.set(t.subarray(s,s+y),M*3),l&&a){let b=u.vertexStart*2;l.set(a.subarray(b,b+u.vertexCount*2),M*2)}w&&o&&w.set(o.subarray(s,s+y),M*3);let x=r.subarray(u.indexStart,u.indexStart+u.indexCount),A=M-u.vertexStart,g=u.vertexStart,B=u.vertexStart+u.vertexCount;for(let b=0;b<x.length;b++){let p=x[b];if(p<g||p>=B)throw ne(p,u);m[d+b]=p+A}M+=u.vertexCount,d+=u.indexCount}let h=new R.BufferGeometry;return h.setAttribute("position",new R.BufferAttribute(f,3)),h.setIndex(new R.BufferAttribute(m,1)),l&&h.setAttribute("uv",new R.BufferAttribute(l,2)),w&&h.setAttribute("color",new R.BufferAttribute(w,3,!0)),h.computeVertexNormals(),oe(h,e,n)}function oe(e,t,r){let n=new R.Mesh(e,r[t.materialId]),a=t.meshes[0],o=t.meshes.map(i=>i.name).filter(i=>i&&i.length>0);return n.name=o.length>0?o[0]:`merged_material_${t.materialId}`,n.castShadow=!0,n.receiveShadow=!0,n.userData={source:"compute",name:n.name,layer:a?.layer??"",originalIndex:a?.originalIndex??0,metadata:a?.metadata??{},mergedFrom:t.meshes.slice(1).map(i=>({name:i.name,layer:i.layer,originalIndex:i.originalIndex}))},n}function ze(e,t,r,n,a=null,o=null){let i=[];for(let c of e.meshes){let f=c.vertexStart*3,m=c.vertexCount*3,l=t.slice(f,f+m),w=r.subarray(c.indexStart,c.indexStart+c.indexCount),M=new Uint32Array(w.length),d=c.vertexStart,h=c.vertexStart+c.vertexCount;for(let s=0;s<w.length;s++){let y=w[s];if(y<d||y>=h)throw ne(y,c);M[s]=y-d}let u=new R.BufferGeometry;if(u.setAttribute("position",new R.BufferAttribute(l,3)),u.setIndex(new R.BufferAttribute(M,1)),a){let s=c.vertexStart*2,y=a.slice(s,s+c.vertexCount*2);u.setAttribute("uv",new R.BufferAttribute(y,2))}if(o){let s=o.slice(f,f+m);u.setAttribute("color",new R.BufferAttribute(s,3,!0))}u.computeVertexNormals(),i.push(ae(u,c,e,n))}return i}function ae(e,t,r,n){let a=new R.Mesh(e,n[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 se(e,t,r){let{mergeByMaterial:n=!0,debug:a=!1,material:o}=t??{},{parseTime:i=0,perfStart:c=a?performance.now():0}=r??{};if(!e.compressedData)return[];let f=await Ye(e.compressedData,{mergeByMaterial:n,debug:a,material:o,fallback:{materials:e.materials,groups:e.groups,sourceComponentId:e.sourceComponentId}});if(f)return f;let m=performance.now(),l=Q(e.compressedData),w=performance.now()-m,M=a?bt(e.compressedData):0;return We(l,{mergeByMaterial:n,debug:a,material:o,parseTime:i,decodeTime:w,perfStart:c,blobBytes:M,fallback:{materials:e.materials,groups:e.groups,sourceComponentId:e.sourceComponentId}})}async function ht(e,t){let{mergeByMaterial:r=!0,debug:n=!1,material:a}=t??{},o=n?performance.now():0,i=await Ye(e,{mergeByMaterial:r,debug:n,material:a});if(i)return i;let c=performance.now(),f=Q(e),m=performance.now()-c,l=e.byteLength;return We(f,{mergeByMaterial:r,debug:n,material:a,parseTime:0,decodeTime:m,perfStart:o,blobBytes:l})}function We(e,t){let{mergeByMaterial:r,debug:n,material:a,parseTime:o,decodeTime:i,perfStart:c,blobBytes:f,fallback:m}=t,l=e.metadata.materials??m?.materials??[],w=e.metadata.groups??m?.groups??[],M=m?.sourceComponentId??e.metadata.sourceComponentId,d=(e.flags&1)!==0;re(w,l.length,e.vertices.length/3,e.indices.length);let h=d?e.vertices:je(e.vertices,e.origin,e.scale);if(n){let A=e.vertices.byteLength+e.indices.byteLength;v().debug("Mesh Batch Stats:"),v().debug(` Materials: ${l.length} | Groups: ${w.length}`),v().debug(` Vertices: ${e.vertices.length/3} | Indices: ${e.indices.length}`),v().debug(` Format: ${d?"float32":"int16 quantized"}`),v().debug(` Blob: ${(f/1024/1024).toFixed(2)} MB | Geometry on wire: ${(A/1024/1024).toFixed(2)} MB`)}let u=performance.now(),s=l.map(A=>te(A,{vertexColors:e.colors!=null,appearance:a})),y=[];for(let A of w)if(r&&A.meshes.length>1){let g=$e(A,h,e.indices,s,e.uvs,e.colors);g.userData.sourceComponentId=M??null,y.push(g)}else{let g=ze(A,h,e.indices,s,e.uvs,e.colors);for(let B of g)B.userData.sourceComponentId=M??null;y.push(...g)}let x=performance.now()-u;if(n){let A=performance.now()-c;v().debug("Performance:"),o>0&&v().debug(` Parse JSON: ${o.toFixed(2)}ms`),v().debug(` Decode binary: ${i.toFixed(2)}ms`),v().debug(` Create Meshes: ${x.toFixed(2)}ms`),v().debug(` Total: ${A.toFixed(2)}ms`)}return Promise.resolve(y)}async function Ye(e,t){if(typeof Worker>"u")return null;let r=ee(e);if(r.indexData.length/3<He)return null;let n=Pe();if(!n)return null;let a=r.metadata.materials??t.fallback?.materials??[],o=r.metadata.groups??t.fallback?.groups??[],i=t.fallback?.sourceComponentId??r.metadata.sourceComponentId;re(o,a.length,r.vertexCount,r.indexData.length);let c=s=>({vertexStart:s.vertexStart,vertexCount:s.vertexCount,indexStart:s.indexStart,indexCount:s.indexCount}),f=[],m=[];for(let s of o)if(t.mergeByMaterial&&s.meshes.length>1)f.push({kind:"merged",windows:s.meshes.map(c)}),m.push({kind:"merged",group:s});else for(let y of s.meshes)f.push({kind:"single",windows:[c(y)]}),m.push({kind:"single",group:s,meshMeta:y});let l=r.vertexData.slice(),w=r.indexData.slice(),M=[l.buffer,w.buffer];r.uvs&&M.push(r.uvs.buffer),r.colors&&M.push(r.colors.buffer);let d;try{d=await ke(n,{vertexData:l,isFloat32:r.isFloat32,deltaEncoded:r.deltaEncoded,origin:r.origin,scale:r.scale,indexData:w,uvs:r.uvs,colors:r.colors,jobs:f},M)}catch(s){return v().warn("Mesh assembly worker failed; falling back to main-thread parse.",s),null}if(d.length!==f.length)return null;let h=a.map(s=>te(s,{vertexColors:r.colors!=null,appearance:t.material})),u=[];for(let s=0;s<d.length;s++){let y=d[s],x=m[s],A=new P.BufferGeometry;A.setAttribute("position",new P.BufferAttribute(y.positions,3)),A.setAttribute("normal",new P.BufferAttribute(y.normals,3)),A.setIndex(new P.BufferAttribute(y.indices,1)),y.uvs&&A.setAttribute("uv",new P.BufferAttribute(y.uvs,2)),y.colors&&A.setAttribute("color",new P.BufferAttribute(y.colors,3,!0));let g=x.kind==="merged"?oe(A,x.group,h):ae(A,x.meshMeta,x.group,h);g.userData.sourceComponentId=i??null,u.push(g)}return t.debug&&v().debug(`Mesh batch assembled off-thread: ${u.length} meshes, ${r.indexData.length/3} triangles`),u}function bt(e){return Math.floor(e.length*3/4)}var ie={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:254e-10,Mils:254e-7,Inches:.0254,Feet:.3048,Yards:.9144,Miles:1609.344,NauticalMiles:1852},gt="Display",At="DisplayBatch";function xt(e){let t=e.split(".");return t.includes(gt)||t.includes(At)}var Je=new Set;async function Et(e,t){let r=performance.now(),n=[],{allowScaling:a=!0,allowAutoPosition:o=!1,groundAxis:i="z",debug:c=!1,parsing:f={}}=t??{};try{let m=a?wt(e.modelunits):1;return await Mt(e,n,m,f,c),o&&Rt(n,i),n}catch(m){throw Bt(m,n),m}finally{c&&Dt(r)}}function wt(e){let t=ie[e];return t!==void 0?t:(Je.has(e)||(Je.add(e),v().warn(`Unknown Rhino model unit "${e}" \u2014 geometry will not be scaled (factor 1). Known units: ${Object.keys(ie).join(", ")}.`)),1)}async function Mt(e,t,r,n,a){for(let o of e.values){let i=o.InnerTree;for(let c in i){let f=i[c];f&&await vt(f,t,r,n,a)}}}async function vt(e,t,r,n,a){for(let o of e){if(!xt(o.type))continue;let i={mergeByMaterial:!0,debug:!1,...n},c=St(o.data);if(!c){v().error("Error parsing display batch envelope: invalid JSON");continue}let f=await se(c,i),m=q(c.items),l=[...f,...m];if(r!==1)for(let w of l)w.scale.set(r,r,r);t.push(...l),a&&v().debug(`Extracted ${f.length} meshes and ${m.length} items from batch`)}}function St(e){return typeof e=="string"?Tt(e):e}function Tt(e){try{return JSON.parse(e)}catch{return}}function Rt(e,t){if(e.length===0)return;let r=me(e);fe(e,r.min[t],t)}function Bt(e,t){v().error("An unexpected error occurred:",e),It(t)}function It(e){for(let t of e){let r=t;r.geometry&&r.geometry.dispose(),r.material&&(Array.isArray(r.material)?r.material.forEach(n=>n.dispose()):r.material.dispose())}}function Dt(e){let t=performance.now()-e;v().info("Time to process meshes:",`${t.toFixed(2)}ms`)}export{ie as SCALE_FACTORS,Et as getThreeMeshesFromComputeResponse,qe as meshPolicy,q as parseDisplayItems,ht as parseMeshBatchBlob,se as parseMeshBatchObject,Ge as setTextureAnisotropy};
10
10
  //# sourceMappingURL=parse.js.map