@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/render.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as THREE from 'three';
2
- import { L as Look, a as LookPreset, M as MaterialAppearanceOptions } from './types-CdF9R3qA.js';
3
- export { b as LOOKS } from './types-CdF9R3qA.js';
2
+ import { L as Look, a as LookPreset, M as MaterialAppearanceOptions } from './types-DCuos3gI.js';
3
+ export { b as LOOKS } from './types-DCuos3gI.js';
4
4
  import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
5
5
 
6
6
  /**
@@ -95,10 +95,8 @@ type EnvironmentConfig = {
95
95
  backgroundColor?: THREE.Color | string;
96
96
  enableEnvironmentLighting?: boolean;
97
97
  /**
98
- * Defaults to `(0, 0, 1)` — Rhino's Z-up, not Three's native Y-up because geometry arrives in
99
- * Rhino's frame and is never rotated on ingress. Everything orientation-dependent derives from
100
- * this (view presets, default camera, sun, grid, floor, hemisphere light), but overriding it
101
- * reorients the viewer only — it does NOT rotate incoming geometry.
98
+ * Default `(0, 0, 1)` — Rhino's Z-up. Every orientation default derives from this (see `up-axis.ts`);
99
+ * overriding it reorients the viewer only, it does not rotate incoming geometry.
102
100
  */
103
101
  sceneUp?: THREE.Vector3;
104
102
  showEnvironment?: boolean;
@@ -142,26 +140,24 @@ type RenderConfig = {
142
140
  onDemand?: boolean;
143
141
  };
144
142
 
145
- /** Crisp boundary/crease edge overlays on meshes. See `addEdges`. */
143
+ /** Crisp boundary/crease edge overlays on meshes. Field rationale: see `EdgeOptions` in `edges/options.ts`. */
146
144
  type EdgesConfig = {
147
145
  /** Default false (opt-in). */
148
146
  enabled?: boolean;
149
- /** Omit (default) to derive each mesh's edge color from its own surface material, darkened by `darken`. */
150
147
  color?: THREE.ColorRepresentation;
151
148
  /** 0–1, default 0.75. Ignored when `color` is set. */
152
149
  darken?: number;
153
150
  /** CSS px. Default 1.5. */
154
151
  width?: number;
155
- /** Crease angle in degrees: keep edges where faces differ by more than this. Default 44. */
152
+ /** Degrees. Default 44. */
156
153
  thresholdAngle?: number;
157
- /** Fade an overlay out as its mesh shrinks on screen. Default true. */
154
+ /** Default true. */
158
155
  distanceFade?: boolean;
159
- /** Skip overlay extraction for meshes above this triangle count. Default 4M. */
156
+ /** Default 4M. */
160
157
  maxTriangles?: number;
161
- /** Overlays above this segment count render opaque (no distance fade). Default 2M. */
158
+ /** Default 2M. */
162
159
  maxSegments?: number;
163
- /** Meshes skipped for exceeding `maxTriangles` fall back to the screen-space edge-detection pass
164
- * (constant cost regardless of triangle count). Default true. */
160
+ /** Fall back to the screen-space edge-detection pass for meshes skipped by `maxTriangles`. Default true. */
165
161
  screenSpaceFallback?: boolean;
166
162
  };
167
163
  type ControlsConfig = {
@@ -232,9 +228,9 @@ type ThreeInitializerOptions = {
232
228
  measure?: MeasureConfig;
233
229
  events?: EventConfig;
234
230
  /**
235
- * Called once at init with the GPU's max anisotropy. **Not needed for sharp textures**the
236
- * parse layer's texture cache subscribes to this value itself via a shared sink. This hook is
237
- * only for hosts doing their own texture work on top.
231
+ * Called once at init with the GPU's max anisotropy. Not needed for sharp textures — `parse/`'s
232
+ * texture cache subscribes to this value on its own (see README's render↔parse seam). Only for
233
+ * hosts doing their own texture work.
238
234
  */
239
235
  onMaxAnisotropy?: (value: number) => void;
240
236
  };
@@ -267,8 +263,8 @@ type EventConfig = {
267
263
  * render loop renders, resize reshapes, and the raycaster picks with — {@link getActiveCamera} is
268
264
  * the one source of truth for all four call sites.
269
265
  *
270
- * Orthographic shadows perspective (same position/target, frustum derived from perspective FOV +
271
- * distance) so switching doesn't visually jump.
266
+ * Orthographic mirrors perspective's position/target with a frustum derived from perspective's FOV
267
+ * and distance, so switching projections doesn't visually jump.
272
268
  */
273
269
  type ViewPreset = 'top' | 'bottom' | 'front' | 'back' | 'left' | 'right' | 'iso';
274
270
  type CameraProjection = 'perspective' | 'orthographic';
@@ -311,9 +307,9 @@ interface Grid {
311
307
  * Two-click distance measurement. Click a point, click a second, read the distance off a label on
312
308
  * the connecting line; a third click starts fresh.
313
309
  *
314
- * Picking snaps to the nearest vertex of the struck triangle within {@link MeasureOptions.snapPixels}
315
- * so measurements land exactly on vertices rather than wherever the ray happened to hit — a cheap
316
- * local snap (three candidate vertices, no spatial index).
310
+ * Picking snaps to the nearest vertex within {@link MeasureOptions.snapPixels} so measurements
311
+ * land exactly on vertices rather than wherever the ray happened to hit — a cheap local snap
312
+ * against the struck primitive's own vertices, no spatial index.
317
313
  *
318
314
  * Dormant until {@link MeasureTool.setEnabled}(true). While enabled it intercepts clicks (caller
319
315
  * forwards them and swallows the event when {@link MeasureTool.handleClick} returns true) so
@@ -331,16 +327,16 @@ interface MeasureTool {
331
327
  }
332
328
 
333
329
  /**
334
- * Corner nav-cube/axis gizmo. Uses three's {@link ViewHelper} only as the rendered widget, NOT its
330
+ * Corner nav-cube/axis gizmo. Uses three's {@link ViewHelper} only as the rendered widget, not its
335
331
  * click→animate behavior: ViewHelper's snap assumes Y-up and animates straight onto the up axis,
336
- * which rolls the view and jitters the gizmo at the pole in our Z-up scene. Instead we hit-test the
337
- * axis sprites ourselves and drive the viewer's up-aware camera controller, which snaps instantly
338
- * with a pole nudge so the orbit basis never degenerates.
332
+ * which rolls the view and jitters the gizmo at the pole in a Z-up scene. Instead this hit-tests
333
+ * the axis sprites directly and drives the viewer's up-aware camera controller, which snaps
334
+ * instantly with a pole nudge so the orbit basis never degenerates.
339
335
  *
340
- * A click frames the current orbit target (not the world origin), and flips the viewer back to
341
- * perspective first if it's in orthographic mode (the cube is inherently a 3D-orientation tool).
336
+ * A click frames the current orbit target (not the world origin) and switches back to perspective
337
+ * first if orthographic the cube is a 3D-orientation tool.
342
338
  *
343
- * Caller contract (mirrors ViewHelper's own): call {@link ViewGizmo.render} *after* the main scene
339
+ * Caller contract (mirrors ViewHelper's own): call {@link ViewGizmo.render} after the main scene
344
340
  * render each frame, and forward pointer clicks to {@link ViewGizmo.handleClick}.
345
341
  */
346
342
  interface ViewGizmo {
@@ -360,17 +356,16 @@ interface ThreeViewer {
360
356
  cameraController: CameraController;
361
357
  grid: Grid | null;
362
358
  gizmo: ViewGizmo | null;
363
- /** Null unless `measure.enabled`; `setEnabled(true)` to use. */
359
+ /** Null unless `measure.enabled`. */
364
360
  measureTool: MeasureTool | null;
365
361
  /**
366
- * Attach edge overlays to meshes under `root` (no-op unless `edges.enabled`). Large-mesh
367
- * extraction runs off-thread, so overlays may attach a beat later; meshes over
368
- * `edges.maxTriangles` are skipped and (by default) covered by the screen-space edge fallback.
362
+ * No-op unless `edges.enabled`. Extraction runs off-thread for large meshes, so overlays can
363
+ * attach a beat later; meshes over `edges.maxTriangles` fall back to the screen-space edge shader.
369
364
  */
370
365
  applyEdges: (root: THREE.Object3D) => void;
371
366
  /**
372
- * Prefer over calling `removeEdges` directly — also cancels in-flight async attaches and stands
373
- * down the screen-space fallback if active.
367
+ * Prefer over `removeEdges` directly — also cancels in-flight async attaches and stands down the
368
+ * screen-space edge fallback if active.
374
369
  */
375
370
  clearEdges: (root: THREE.Object3D) => void;
376
371
  /**
@@ -380,14 +375,14 @@ interface ThreeViewer {
380
375
  invalidate: () => void;
381
376
  setAmbientOcclusion: (enabled: boolean) => void;
382
377
  /**
383
- * Retunes lighting/material only (tone mapping, fill, IBL, AO) — never edges/grid. Overwrites
384
- * any granular lighting dials set earlier.
378
+ * Retunes lighting/material (tone mapping, fill, IBL, AO) only — never edges/grid. Overwrites
379
+ * any granular lighting dials set earlier with the preset's values.
385
380
  */
386
381
  setLook: (look: 'studio' | 'technical' | 'showcase') => void;
387
382
  /**
388
- * Raising `hemisphereIntensity` is the most effective way to lift shadowed/under-facing surfaces
389
- * a dark HDR leaves black; a positive value lazily creates the hemisphere light if the viewer was
390
- * built without one, `0` switches it off.
383
+ * Raising `hemisphereIntensity` is the most effective way to lift shadowed surfaces a dark HDR
384
+ * leaves black. Lazily creates the hemisphere light if the viewer was built without one; `0` turns
385
+ * it back off.
391
386
  */
392
387
  setFillLights: (opts: {
393
388
  hemisphereIntensity?: number;
@@ -412,10 +407,7 @@ interface ThreeViewer {
412
407
  dispose: () => void;
413
408
  fitToView: () => void;
414
409
  clearSelection: () => void;
415
- /**
416
- * Tagged `userData.source = 'user'` so it survives `updateScene` solves instead of being cleared
417
- * with compute content, and counts as normal content for fit-to-view framing.
418
- */
410
+ /** Tagged `userData.source = 'user'` so it survives `updateScene` solves and counts for fit-to-view. */
419
411
  addUserGeometry: (object: THREE.Object3D) => void;
420
412
  removeUserGeometry: (object: THREE.Object3D) => void;
421
413
  /** Removes and disposes everything added via `addUserGeometry`. */
package/dist/render.js CHANGED
@@ -1,12 +1,12 @@
1
- import{a as Kt,b as Yt,c as me,d as Zt,e as $t,g as Qt,h as Le,i as Ee,j as Oe,m as Ge,p as Fe,q as Ue,s as Be,t as We,v as se}from"./chunk-EXAI6IC5.js";import{a as X}from"./chunk-5XGN7UAV.js";import*as Ut from"three";import*as ne from"three";import*as he from"three";import*as K from"three";function fe(e){let n=e.clone().normalize(),t=new K.Vector3(0,0,1),r=new K.Vector3(0,1,0),i=Math.abs(n.dot(t))>.9?r:t,o=new K.Vector3().crossVectors(i,n).normalize(),a=new K.Vector3().crossVectors(n,o).normalize();return{up:n,forward:a,right:o}}function ye(e,n){let{forward:t,right:r,up:i}=fe(e);return t.clone().multiplyScalar(-1).add(r.clone().multiplyScalar(-1)).add(i).normalize().multiplyScalar(n)}function qe(e,n,t){let{forward:r,right:i,up:o}=fe(e);return i.clone().multiplyScalar(n).add(r.clone().multiplyScalar(n)).add(o.clone().multiplyScalar(t))}function Xe(e){let n=e.clone().normalize(),t=new K.Vector3(0,1,0);if(n.dot(t)>.9999)return new K.Euler;if(n.dot(t)<-.9999)return new K.Euler(Math.PI,0,0);let r=new K.Quaternion().setFromUnitVectors(t,n);return new K.Euler().setFromQuaternion(r)}function xe(e){let n=Math.abs(e.x),t=Math.abs(e.y),r=Math.abs(e.z);return n>=t&&n>=r?"x":t>=r?"y":"z"}var $={HUGE_THRESHOLD:1e4,LARGE_THRESHOLD:1e3,SCALE_RATIO_THRESHOLD:100,NEAR_PLANE_FACTOR:{TINY:1e-4,SMALL:.001,NORMAL:.01},FAR_PLANE_FACTOR:{HUGE:100,LARGE:50,NORMAL:20},INITIAL_DISTANCE_MULTIPLIER:4};function Jt(e,n,t,r,i){if(nr(e),n.length===0)return;n.forEach(f=>{e.add(f)});let o=Ge(n),a=o.getCenter(new he.Vector3),s=o.getSize(new he.Vector3),l=Math.max(s.x,s.y,s.z);if(l/Math.min(s.x||1,s.y||1,s.z||1)>$.SCALE_RATIO_THRESHOLD||l>$.HUGE_THRESHOLD?(t.near=l*$.NEAR_PLANE_FACTOR.TINY,t.far=l*$.FAR_PLANE_FACTOR.HUGE):l>$.LARGE_THRESHOLD?(t.near=l*$.NEAR_PLANE_FACTOR.SMALL,t.far=l*$.FAR_PLANE_FACTOR.LARGE):(t.near=Math.max(.01,l*$.NEAR_PLANE_FACTOR.NORMAL),t.far=Math.max(2e3,l*$.FAR_PLANE_FACTOR.NORMAL)),t.updateProjectionMatrix(),!i){let f=l*$.INITIAL_DISTANCE_MULTIPLIER;t.position.copy(a).add(ye(t.up,f)),r.target.copy(a),r.update()}}var er=new Set(["grid","floor","label-layer","measure"]);function tr(e){let n=e;for(;n;){if(typeof n.userData.id=="string"&&er.has(n.userData.id))return!0;n=n.parent}return!1}function Q(e){e.updateMatrixWorld(!0);let n=new he.Box3;return e.traverse(t=>{let r=t;t.visible&&!tr(t)&&r.geometry&&n.expandByObject(t)}),n}var rr=new Set(["floor","grid","label-layer"]);function nr(e){[...e.children].forEach(t=>{rr.has(t.userData.id)||t.userData.source!=="user"&&(se(t),t.removeFromParent())})}function or(e){let{up:n,forward:t,right:r}=fe(e),i=t.clone().negate(),o=r.clone();return{top:n.clone(),bottom:n.clone().negate(),front:i.clone(),back:i.clone().negate(),right:o.clone(),left:o.clone().negate(),iso:i.clone().multiplyScalar(1.2).add(o.clone()).add(n.clone()).normalize()}}function Ke(e){let{scene:n,perspective:t,controls:r,onActiveCameraChange:i}=e,o=(e.up??t.up).clone().normalize(),a=or(o),s=new ne.OrthographicCamera(-1,1,1,-1,t.near,t.far);s.up.copy(o);let l="perspective",m=t.aspect,f=()=>l==="perspective"?t:s,E=null,g=()=>{E?.cancel(),E=null},u=()=>{let R=(l==="orthographic"?s:t).position.distanceTo(r.target)*Math.tan(t.fov*Math.PI/360),T=R*m;s.left=-T,s.right=T,s.top=R,s.bottom=-R,s.near=t.near,s.far=t.far,s.updateProjectionMatrix()},p=d=>{if(d!==l){if(g(),d==="orthographic")s.position.copy(t.position),s.up.copy(t.up),s.lookAt(r.target),s.zoom=1,u();else{let R=(s.top-s.bottom)/(2*s.zoom)/Math.tan(t.fov*Math.PI/360),T=s.position.clone().sub(r.target);T.lengthSq()<1e-12&&T.copy(o),T.normalize(),t.position.copy(r.target).add(T.multiplyScalar(R))}l=d,r.object=f(),r.update(),i(f())}},h=(d,c,R,T)=>{let x=t.fov*(Math.PI/180),M=c/(2*Math.tan(x/2))*1.5,P=ir(R,o),L=d.clone().add(P.clone().multiplyScalar(M)),Y=f();l==="orthographic"&&(s.zoom=1),g(),T?E=sr(Y,r,L,d,()=>{l==="orthographic"&&u()}):(Y.position.copy(L),r.target.copy(d),l==="orthographic"&&u(),r.update())},C=(d,c=!0)=>{let R=Q(n),T=R.isEmpty()?r.target.clone():R.getCenter(new ne.Vector3),x=R.isEmpty()?new ne.Vector3(1,1,1):R.getSize(new ne.Vector3),M=Math.max(x.x,x.y,x.z)||1;h(T,M,d,c)};return{getActiveCamera:f,getProjection:()=>l,setProjection:p,toggleProjection:()=>(p(l==="perspective"?"orthographic":"perspective"),l),setView:(d,c=!0)=>{C(a[d],c)},setViewDirection:C,frameBounds:(d,c=!0)=>{if(d.isEmpty())return;let R=d.getCenter(new ne.Vector3),T=d.getSize(new ne.Vector3),x=Math.max(T.x,T.y,T.z)||1,M=f().position.clone().sub(r.target);M.lengthSq()<1e-12&&M.copy(a.iso),h(R,x,M.normalize(),c)},setRotateEnabled:d=>{r.enableRotate=d},isRotateEnabled:()=>r.enableRotate,updateAspect:(d,c)=>{m=c===0?m:d/c,l==="orthographic"&&u()},dispose:g}}function ir(e,n){let{up:t,forward:r}=fe(n),i=e.clone().normalize();if(Math.abs(i.dot(t))<.9999)return e;let o=r.clone().negate(),a=.5*Math.PI/180;return i.multiplyScalar(Math.cos(a)).add(o.multiplyScalar(Math.sin(a))).normalize()}var ar=e=>1-Math.pow(1-e,3);function sr(e,n,t,r,i,o=250){let a=e.position.clone(),s=n.target.clone(),l=performance.now(),m=null,f=()=>{m=null;let E=ar(Math.min((performance.now()-l)/o,1));e.position.lerpVectors(a,t,E),n.target.lerpVectors(s,r,E),i(),n.update(),E<1&&(m=requestAnimationFrame(f))};return m=requestAnimationFrame(f),{cancel:()=>{m!==null&&(cancelAnimationFrame(m),m=null)}}}import*as mt from"three";import{LineSegments2 as Sr}from"three/addons/lines/LineSegments2.js";import{LineSegmentsGeometry as lr}from"three/addons/lines/LineSegmentsGeometry.js";var cr=.15,dr=4096;function ur(e){let n=Math.floor(e.length/6);if(n===0)return 1/0;let t=Math.max(1,Math.ceil(n/dr)),r=[];for(let i=0;i<n;i+=t){let o=i*6,a=Math.hypot(e[o+3]-e[o],e[o+4]-e[o+1],e[o+5]-e[o+2]);a>0&&r.push(a)}return r.length===0?1/0:(r.sort((i,o)=>i-o),r[Math.min(r.length-1,Math.floor(r.length*cr))])}function Ye(e){let n=new lr;return n.setPositions(e),{geometry:n,segmentCount:e.length/6,edgeSpacing:ur(e)}}import*as nt from"three";function He(e,n,t){let o=Math.cos(Math.PI/180*t),a=e.length/3;if(a>=67108864)throw new Error(`extractEdgeSegments: ${a} vertices exceeds 2^26 limit`);let s=new Float64Array(a),l=new Float64Array(a),m=new Float64Array(a);for(let c=0;c<a;c++)s[c]=Math.round(e[3*c]*1e4),l[c]=Math.round(e[3*c+1]*1e4),m[c]=Math.round(e[3*c+2]*1e4);let f=16;for(;f<a*2;)f<<=1;let E=f-1,g=new Int32Array(f).fill(-1),u=new Int32Array(a);for(let c=0;c<a;c++){let R=(Math.imul(s[c]|0,73856093)^Math.imul(l[c]|0,19349663)^Math.imul(m[c]|0,83492791))&E;for(;;){let T=g[R];if(T===-1){g[R]=c,u[c]=c;break}if(s[T]===s[c]&&l[T]===l[c]&&m[T]===m[c]){u[c]=T;break}R=R+1&E}}let p=new Float32Array(4096),h=0,C=(c,R)=>{if(h+6>p.length){let T=new Float32Array(p.length*2);T.set(p),p=T}p[h++]=e[3*c],p[h++]=e[3*c+1],p[h++]=e[3*c+2],p[h++]=e[3*R],p[h++]=e[3*R+1],p[h++]=e[3*R+2]},b=new Map,A=[],S=[],I=[],d=(n?n.length:a)/3;for(let c=0;c<d;c++){let R=n?n[3*c]:3*c,T=n?n[3*c+1]:3*c+1,x=n?n[3*c+2]:3*c+2,M=u[R],P=u[T],L=u[x];if(M===P||P===L||L===M)continue;let Y=e[3*x]-e[3*T],w=e[3*x+1]-e[3*T+1],k=e[3*x+2]-e[3*T+2],v=e[3*R]-e[3*T],y=e[3*R+1]-e[3*T+1],z=e[3*R+2]-e[3*T+2],j=w*z-k*y,V=k*v-Y*z,G=Y*y-w*v,be=j*j+V*V+G*G;if(be>0){let Z=1/Math.sqrt(be);j*=Z,V*=Z,G*=Z}else j=0,V=0,G=0;for(let Z=0;Z<3;Z++){let ee,re,U,q;Z===0?(ee=R,re=T,U=M,q=P):Z===1?(ee=T,re=x,U=P,q=L):(ee=x,re=R,U=L,q=M);let ve=q*67108864+U,ie=b.get(ve);if(ie!==void 0&&ie!==-1)j*I[3*ie]+V*I[3*ie+1]+G*I[3*ie+2]<=o&&C(ee,re),b.set(ve,-1);else{let ue=U*67108864+q;if(!b.has(ue)){let Pe=A.length;b.set(ue,Pe),A.push(ee),S.push(re),I.push(j,V,G)}}}}for(let c of b.values())c!==-1&&C(A[c],S[c]);return p.slice(0,h)}function Ze(){return[`const extract = ${He.toString()};`,"self.onmessage = (event) => {"," const { id, positions, index, thresholdAngle } = event.data;"," try {"," const segments = extract(positions, index, thresholdAngle);"," self.postMessage({ id, segments }, [segments.buffer]);"," } catch (error) {"," self.postMessage({ id, error: String((error && error.message) || error) });"," }","};"].join(`
2
- `)}import*as Ce from"three";var le="edge-overlay",we="triangle-cap",$e=2236962,mr=1.5,pr=44,Er=.75,fr=4e6,hr=2e6,Qe=25e3,Ie=128*1024*1024,Je=4,ke=1,et=0,tt=-1;function rt(e){return{forcedColor:e.color!=null?new Ce.Color(e.color):null,darken:Ce.MathUtils.clamp(e.darken??Er,0,1),width:e.width??mr,thresholdAngle:e.thresholdAngle??pr,distanceFade:e.distanceFade??!0,maxTriangles:e.maxTriangles??fr,maxSegments:e.maxSegments??hr}}function Me(e){let n=e.getAttribute("position");return n?(e.index?e.index.count:n.count)/3:0}function ot(e){let n=e.getAttribute("position");if(!n||n.isInterleavedBufferAttribute||n.itemSize!==3||!(n.array instanceof Float32Array)||n.count>=67108864)return null;let t=e.index;return t&&!(t.array instanceof Uint32Array)&&!(t.array instanceof Uint16Array)?null:{positions:n.array,index:t?t.array:null}}function it(e,n){let r=2166136261,i=l=>{r^=l,r=Math.imul(r,16777619)},o=new Uint32Array(e.positions.buffer,e.positions.byteOffset,e.positions.length),a=Math.min(4096,o.length);for(let l=0;l<a;l++)i(o[l]);for(let l=Math.max(a,o.length-4096);l<o.length;l++)i(o[l]);let s=0;if(e.index){s=e.index.length;let l=Math.min(4096,s);for(let m=0;m<l;m++)i(e.index[m]);for(let m=Math.max(l,s-4096);m<s;m++)i(e.index[m])}return`${n}:${e.positions.length}:${s}:${r>>>0}`}var J=new Map,ge=0;Ue(()=>{J.clear(),ge=0});function at(e){let n=J.get(e);return n&&(J.delete(e),J.set(e,n)),n}function st(e,n){if(n.byteLength>Ie)return;let t=J.get(e);for(t&&(ge-=t.byteLength,J.delete(e)),J.set(e,n),ge+=n.byteLength;ge>Ie;){let r=J.keys().next().value;ge-=J.get(r).byteLength,J.delete(r)}}function Rr(e,n){let t=new nt.EdgesGeometry(e,n),r=t.attributes.position?t.attributes.position.array:new Float32Array(0);return t.dispose(),r}function _e(e,n){let t=ot(e);if(!t)return Rr(e,n);let r=it(t,n),i=at(r);if(i)return i;let o=He(t.positions,t.index,n);return st(r,o),o}var ce,Re=new Map,Tr=1;function br(){if(ce!==void 0)return ce;if(typeof Worker>"u"||typeof Blob>"u"||typeof URL>"u"||typeof URL.createObjectURL!="function")return ce=null,null;try{let e=URL.createObjectURL(new Blob([Ze()],{type:"text/javascript"})),n=new Worker(e);n.onmessage=t=>{let{id:r,segments:i,error:o}=t.data,a=Re.get(r);a&&(Re.delete(r),i?a.resolve(i):a.reject(new Error(o??"edge extraction failed in worker")))},n.onerror=()=>{for(let t of Re.values())t.reject(new Error("edge extraction worker crashed"));Re.clear(),n.terminate(),ce=null},ce=n}catch{ce=null}return ce}function vr(e,n,t){return new Promise((r,i)=>{let o=Tr++;Re.set(o,{resolve:r,reject:i});let a=n.positions.slice(),s=n.index?n.index.slice():null,l=[a.buffer];s&&l.push(s.buffer),e.postMessage({id:o,positions:a,index:s,thresholdAngle:t},l)})}var ze=new Map;function lt(e,n){let t=ot(e);if(!t||Me(e)<Qe)return Promise.resolve(_e(e,n));let r=it(t,n),i=at(r);if(i)return Promise.resolve(i);let o=ze.get(r);if(o)return o;let a=br();if(!a)return Promise.resolve(_e(e,n));let s=vr(a,t,n).catch(()=>He(t.positions,t.index,n)).then(l=>(st(r,l),l)).finally(()=>{ze.delete(r)});return ze.set(r,s),s}import*as oe from"three";import{LineMaterial as yr}from"three/addons/lines/LineMaterial.js";import{LineSegments2 as dt}from"three/addons/lines/LineSegments2.js";function xr(e,n){let r=(Array.isArray(e.material)?e.material[0]:e.material)?.color;return r?r.clone().multiplyScalar(1-n):new oe.Color($e)}var Se=class{constructor(n){X(this,"options",n);X(this,"byKey",new Map)}for(n,t){let r=this.options.forcedColor??xr(n,this.options.darken),i=r.getHex()*2+(t?1:0),o=this.byKey.get(i);return o||(o=Hr(r,this.options.width,t),this.byKey.set(i,o)),o}disposeUnused(n){let t=new Set(n.map(r=>r.material));for(let r of this.byKey.values())t.has(r)||r.dispose()}};function Hr(e,n,t){let r=new yr({color:e});return r.linewidth=n,r.polygonOffset=!0,r.polygonOffsetFactor=et,r.polygonOffsetUnits=tt,t&&(r.transparent=!0),r}function ut(e,n,t){let r=new dt(e.geometry,n);return r.userData.kind=le,r.raycast=()=>{},t&&Mr(r,e.edgeSpacing),r}var ct=new oe.Vector3,Cr=new oe.Vector3;function wr(e,n,t){e.geometry.boundingSphere||e.geometry.computeBoundingSphere();let r=e.geometry.boundingSphere;if(!r)return 1/0;if(n.isPerspectiveCamera){let i=n;ct.copy(r.center).applyMatrix4(e.matrixWorld);let o=Cr.setFromMatrixPosition(n.matrixWorld).distanceTo(ct),a=r.radius*e.matrixWorld.getMaxScaleOnAxis();if(o<=a)return 1/0;let s=Math.tan(oe.MathUtils.degToRad(i.fov)*.5),l=2*o*s;return l>0?t/l:1/0}if(n.isOrthographicCamera){let i=n,o=(i.top-i.bottom)/i.zoom;return o>0?t/o:1/0}return 1/0}function Mr(e,n){e.onBeforeRender=(t,r,i)=>{dt.prototype.onBeforeRender.call(e,t);let o=e.material,a=wr(e,i,o.resolution.y),s=n*a;o.opacity=oe.MathUtils.clamp((s-ke)/(Je-ke),0,1)}}function Dr(e){return e.userData?.kind===le}function Ar(e,n){let t=[];return e.traverse(r=>{if(r instanceof mt.Mesh&&!(r.userData.id==="floor"||r.userData.id==="grid")&&r.userData.kind!==le&&!r.children.some(i=>i.userData?.kind===le)&&r.geometry){if(Me(r.geometry)>n){r.userData.edgesSkipped=we,console.debug(`[edges] skipping mesh over triangle cap (${Me(r.geometry)} > ${n})`);return}delete r.userData.edgesSkipped,t.push(r)}}),t}function Pr(e,n,t,r){let i=r.distanceFade&&n.segmentCount<=r.maxSegments,o=ut(n,t.for(e,i),i);return e.add(o),o}var pt=new WeakMap;function Ve(e){return pt.get(e)??0}function Lr(e,n){for(let t=e;t;t=t.parent)if(t===n)return!0;return!1}async function Et(e,n={}){let t=rt(n),r=new Se(t),i=Ve(e),o=[],a=Ar(e,t.maxTriangles).map(async s=>{let l=await lt(s.geometry,t.thresholdAngle);Ve(e)===i&&Lr(s,e)&&(s.children.some(m=>m.userData?.kind===le)||o.push(Pr(s,Ye(l),r,t)))});return await Promise.all(a),r.disposeUnused(o),o}function ft(e){pt.set(e,Ve(e)+1);let n=[];e.traverse(r=>{r instanceof Sr&&Dr(r)&&n.push(r)});let t=new Set;for(let r of n)r.geometry.dispose(),t.add(r.material),r.removeFromParent();return t.forEach(r=>r.dispose()),n.length}import*as _ from"three";function Or(e){if(!(e>0)||!Number.isFinite(e))return 1;let n=Math.floor(Math.log10(e)),t=Math.pow(10,n),r=e/t;return(r>=5?5:r>=2?2:1)*t}var Fr=`
1
+ import{a as Vt,b as _t,c as de,d as jt,e as Nt,g as Gt,h as Ae,i as pe,j as Pe,m as Ve,n as _e,p as ae}from"./chunk-KRA5RVHM.js";import{a as Y}from"./chunk-5XGN7UAV.js";import*as Ft from"three";import*as re from"three";import*as fe from"three";import*as Z from"three";function Ee(e){let n=e.clone().normalize(),t=new Z.Vector3(0,0,1),r=new Z.Vector3(0,1,0),i=Math.abs(n.dot(t))>.9?r:t,o=new Z.Vector3().crossVectors(i,n).normalize(),a=new Z.Vector3().crossVectors(n,o).normalize();return{up:n,forward:a,right:o}}function be(e,n){let{forward:t,right:r,up:i}=Ee(e);return t.clone().multiplyScalar(-1).add(r.clone().multiplyScalar(-1)).add(i).normalize().multiplyScalar(n)}function je(e,n,t){let{forward:r,right:i,up:o}=Ee(e);return i.clone().multiplyScalar(n).add(r.clone().multiplyScalar(n)).add(o.clone().multiplyScalar(t))}function Ne(e){let n=e.clone().normalize(),t=new Z.Vector3(0,1,0);if(n.dot(t)>.9999)return new Z.Euler;if(n.dot(t)<-.9999)return new Z.Euler(Math.PI,0,0);let r=new Z.Quaternion().setFromUnitVectors(t,n);return new Z.Euler().setFromQuaternion(r)}function ve(e){let n=Math.abs(e.x),t=Math.abs(e.y),r=Math.abs(e.z);return n>=t&&n>=r?"x":t>=r?"y":"z"}var $={HUGE_THRESHOLD:1e4,LARGE_THRESHOLD:1e3,SCALE_RATIO_THRESHOLD:100,NEAR_PLANE_FACTOR:{TINY:1e-4,SMALL:.001,NORMAL:.01},FAR_PLANE_FACTOR:{HUGE:100,LARGE:50,NORMAL:20},INITIAL_DISTANCE_MULTIPLIER:4};function Ut(e,n,t,r,i){if(Xt(e),n.length===0)return;n.forEach(f=>{e.add(f)});let o=Ve(n),a=o.getCenter(new fe.Vector3),l=o.getSize(new fe.Vector3),s=Math.max(l.x,l.y,l.z);if(s/Math.min(l.x||1,l.y||1,l.z||1)>$.SCALE_RATIO_THRESHOLD||s>$.HUGE_THRESHOLD?(t.near=s*$.NEAR_PLANE_FACTOR.TINY,t.far=s*$.FAR_PLANE_FACTOR.HUGE):s>$.LARGE_THRESHOLD?(t.near=s*$.NEAR_PLANE_FACTOR.SMALL,t.far=s*$.FAR_PLANE_FACTOR.LARGE):(t.near=Math.max(.01,s*$.NEAR_PLANE_FACTOR.NORMAL),t.far=Math.max(2e3,s*$.FAR_PLANE_FACTOR.NORMAL)),t.updateProjectionMatrix(),!i){let f=s*$.INITIAL_DISTANCE_MULTIPLIER;t.position.copy(a).add(be(t.up,f)),r.target.copy(a),r.update()}}var Bt=new Set(["grid","floor","label-layer","measure"]);function Wt(e){let n=e;for(;n;){if(typeof n.userData.id=="string"&&Bt.has(n.userData.id))return!0;n=n.parent}return!1}function Q(e){e.updateMatrixWorld(!0);let n=new fe.Box3;return e.traverse(t=>{let r=t;t.visible&&!Wt(t)&&r.geometry&&n.expandByObject(t)}),n}var qt=new Set(["floor","grid","label-layer"]);function Xt(e){[...e.children].forEach(t=>{qt.has(t.userData.id)||t.userData.source!=="user"&&(ae(t),t.removeFromParent())})}function Kt(e){let{up:n,forward:t,right:r}=Ee(e),i=t.clone().negate(),o=r.clone();return{top:n.clone(),bottom:n.clone().negate(),front:i.clone(),back:i.clone().negate(),right:o.clone(),left:o.clone().negate(),iso:i.clone().multiplyScalar(1.2).add(o.clone()).add(n.clone()).normalize()}}function Ge(e){let{scene:n,perspective:t,controls:r,onActiveCameraChange:i}=e,o=(e.up??t.up).clone().normalize(),a=Kt(o),l=new re.OrthographicCamera(-1,1,1,-1,t.near,t.far);l.up.copy(o);let s="perspective",u=t.aspect,f=()=>s==="perspective"?t:l,E=null,g=()=>{E?.cancel(),E=null},m=()=>{let R=(s==="orthographic"?l:t).position.distanceTo(r.target)*Math.tan(t.fov*Math.PI/360),T=R*u;l.left=-T,l.right=T,l.top=R,l.bottom=-R,l.near=t.near,l.far=t.far,l.updateProjectionMatrix()},p=d=>{if(d!==s){if(g(),d==="orthographic")l.position.copy(t.position),l.up.copy(t.up),l.lookAt(r.target),l.zoom=1,m();else{let R=(l.top-l.bottom)/(2*l.zoom)/Math.tan(t.fov*Math.PI/360),T=l.position.clone().sub(r.target);T.lengthSq()<1e-12&&T.copy(o),T.normalize(),t.position.copy(r.target).add(T.multiplyScalar(R))}s=d,r.object=f(),r.update(),i(f())}},h=(d,c,R,T)=>{let v=t.fov*(Math.PI/180),C=c/(2*Math.tan(v/2))*1.5,_=Yt(R,o),F=d.clone().add(_.clone().multiplyScalar(C)),q=f();s==="orthographic"&&(l.zoom=1),g(),T?E=$t(q,r,F,d,()=>{s==="orthographic"&&m()}):(q.position.copy(F),r.target.copy(d),s==="orthographic"&&m(),r.update())},H=(d,c=!0)=>{let R=Q(n),T=R.isEmpty()?r.target.clone():R.getCenter(new re.Vector3),v=R.isEmpty()?new re.Vector3(1,1,1):R.getSize(new re.Vector3),C=Math.max(v.x,v.y,v.z)||1;h(T,C,d,c)};return{getActiveCamera:f,getProjection:()=>s,setProjection:p,toggleProjection:()=>(p(s==="perspective"?"orthographic":"perspective"),s),setView:(d,c=!0)=>{H(a[d],c)},setViewDirection:H,frameBounds:(d,c=!0)=>{if(d.isEmpty())return;let R=d.getCenter(new re.Vector3),T=d.getSize(new re.Vector3),v=Math.max(T.x,T.y,T.z)||1,C=f().position.clone().sub(r.target);C.lengthSq()<1e-12&&C.copy(a.iso),h(R,v,C.normalize(),c)},setRotateEnabled:d=>{r.enableRotate=d},isRotateEnabled:()=>r.enableRotate,updateAspect:(d,c)=>{u=c===0?u:d/c,s==="orthographic"&&m()},dispose:g}}function Yt(e,n){let{up:t,forward:r}=Ee(n),i=e.clone().normalize();if(Math.abs(i.dot(t))<.9999)return e;let o=r.clone().negate(),a=.5*Math.PI/180;return i.multiplyScalar(Math.cos(a)).add(o.multiplyScalar(Math.sin(a))).normalize()}var Zt=e=>1-Math.pow(1-e,3);function $t(e,n,t,r,i,o=250){let a=e.position.clone(),l=n.target.clone(),s=performance.now(),u=null,f=()=>{u=null;let E=Zt(Math.min((performance.now()-s)/o,1));e.position.lerpVectors(a,t,E),n.target.lerpVectors(l,r,E),i(),n.update(),E<1&&(u=requestAnimationFrame(f))};return u=requestAnimationFrame(f),{cancel:()=>{u!==null&&(cancelAnimationFrame(u),u=null)}}}import*as nt from"three";import{LineSegments2 as Tr}from"three/addons/lines/LineSegments2.js";import{LineSegmentsGeometry as Qt}from"three/addons/lines/LineSegmentsGeometry.js";var Jt=.15,er=4096;function tr(e){let n=Math.floor(e.length/6);if(n===0)return 1/0;let t=Math.max(1,Math.ceil(n/er)),r=[];for(let i=0;i<n;i+=t){let o=i*6,a=Math.hypot(e[o+3]-e[o],e[o+4]-e[o+1],e[o+5]-e[o+2]);a>0&&r.push(a)}return r.length===0?1/0:(r.sort((i,o)=>i-o),r[Math.min(r.length-1,Math.floor(r.length*Jt))])}function Ue(e){let n=new Qt;return n.setPositions(e),{geometry:n,segmentCount:e.length/6,edgeSpacing:tr(e)}}import*as $e from"three";function ye(e,n,t){let o=Math.cos(Math.PI/180*t),a=e.length/3;if(a>=67108864)throw new Error(`extractEdgeSegments: ${a} vertices exceeds 2^26 limit`);let l=new Float64Array(a),s=new Float64Array(a),u=new Float64Array(a);for(let c=0;c<a;c++)l[c]=Math.round(e[3*c]*1e4),s[c]=Math.round(e[3*c+1]*1e4),u[c]=Math.round(e[3*c+2]*1e4);let f=16;for(;f<a*2;)f<<=1;let E=f-1,g=new Int32Array(f).fill(-1),m=new Int32Array(a);for(let c=0;c<a;c++){let R=(Math.imul(l[c]|0,73856093)^Math.imul(s[c]|0,19349663)^Math.imul(u[c]|0,83492791))&E;for(;;){let T=g[R];if(T===-1){g[R]=c,m[c]=c;break}if(l[T]===l[c]&&s[T]===s[c]&&u[T]===u[c]){m[c]=T;break}R=R+1&E}}let p=new Float32Array(4096),h=0,H=(c,R)=>{if(h+6>p.length){let T=new Float32Array(p.length*2);T.set(p),p=T}p[h++]=e[3*c],p[h++]=e[3*c+1],p[h++]=e[3*c+2],p[h++]=e[3*R],p[h++]=e[3*R+1],p[h++]=e[3*R+2]},x=new Map,S=[],A=[],V=[],d=(n?n.length:a)/3;for(let c=0;c<d;c++){let R=n?n[3*c]:3*c,T=n?n[3*c+1]:3*c+1,v=n?n[3*c+2]:3*c+2,C=m[R],_=m[T],F=m[v];if(C===_||_===F||F===C)continue;let q=e[3*v]-e[3*T],M=e[3*v+1]-e[3*T+1],O=e[3*v+2]-e[3*T+2],y=e[3*R]-e[3*T],b=e[3*R+1]-e[3*T+1],I=e[3*R+2]-e[3*T+2],k=M*I-O*b,N=O*y-q*I,G=q*b-M*y,Re=k*k+N*N+G*G;if(Re>0){let X=1/Math.sqrt(Re);k*=X,N*=X,G*=X}else k=0,N=0,G=0;for(let X=0;X<3;X++){let ee,U,K,oe;X===0?(ee=R,U=T,K=C,oe=_):X===1?(ee=T,U=v,K=_,oe=F):(ee=v,U=R,K=F,oe=C);let Te=oe*67108864+K,te=x.get(Te);if(te!==void 0&&te!==-1)k*V[3*te]+N*V[3*te+1]+G*V[3*te+2]<=o&&H(ee,U),x.set(Te,-1);else{let me=K*67108864+oe;if(!x.has(me)){let De=S.length;x.set(me,De),S.push(ee),A.push(U),V.push(k,N,G)}}}}for(let c of x.values())c!==-1&&H(S[c],A[c]);return p.slice(0,h)}function Be(){return[`const extract = ${ye.toString()};`,"self.onmessage = (event) => {"," const { id, positions, index, thresholdAngle } = event.data;"," try {"," const segments = extract(positions, index, thresholdAngle);"," self.postMessage({ id, segments }, [segments.buffer]);"," } catch (error) {"," self.postMessage({ id, error: String((error && error.message) || error) });"," }","};"].join(`
2
+ `)}import*as xe from"three";var se="edge-overlay",He="triangle-cap",We=2236962,rr=1.5,nr=44,or=.75,ir=4e6,ar=2e6,qe=25e3,Xe=4,Le=1,Ke=0,Ye=-1;function Ze(e){return{forcedColor:e.color!=null?new xe.Color(e.color):null,darken:xe.MathUtils.clamp(e.darken??or,0,1),width:e.width??rr,thresholdAngle:e.thresholdAngle??nr,distanceFade:e.distanceFade??!0,maxTriangles:e.maxTriangles??ir,maxSegments:e.maxSegments??ar}}function Ce(e){let n=e.getAttribute("position");return n?(e.index?e.index.count:n.count)/3:0}function Qe(e){let n=e.getAttribute("position");if(!n||n.isInterleavedBufferAttribute||n.itemSize!==3||!(n.array instanceof Float32Array)||n.count>=67108864)return null;let t=e.index;return t&&!(t.array instanceof Uint32Array)&&!(t.array instanceof Uint16Array)?null:{positions:n.array,index:t?t.array:null}}function lr(e,n){let r=2166136261,i=s=>{r^=s,r=Math.imul(r,16777619)},o=new Uint32Array(e.positions.buffer,e.positions.byteOffset,e.positions.length),a=Math.min(4096,o.length);for(let s=0;s<a;s++)i(o[s]);for(let s=Math.max(a,o.length-4096);s<o.length;s++)i(o[s]);let l=0;if(e.index){l=e.index.length;let s=Math.min(4096,l);for(let u=0;u<s;u++)i(e.index[u]);for(let u=Math.max(s,l-4096);u<l;u++)i(e.index[u])}return`${n}:${e.positions.length}:${l}:${r>>>0}`}function cr(e,n){let t=new $e.EdgesGeometry(e,n),r=t.attributes.position?t.attributes.position.array:new Float32Array(0);return t.dispose(),r}function Fe(e,n){let t=Qe(e);return t?ye(t.positions,t.index,n):cr(e,n)}var le,he=new Map,dr=1;function ur(){if(le!==void 0)return le;if(typeof Worker>"u"||typeof Blob>"u"||typeof URL>"u"||typeof URL.createObjectURL!="function")return le=null,null;try{let e=URL.createObjectURL(new Blob([Be()],{type:"text/javascript"})),n=new Worker(e);n.onmessage=t=>{let{id:r,segments:i,error:o}=t.data,a=he.get(r);a&&(he.delete(r),i?a.resolve(i):a.reject(new Error(o??"edge extraction failed in worker")))},n.onerror=()=>{for(let t of he.values())t.reject(new Error("edge extraction worker crashed"));he.clear(),n.terminate(),le=null},le=n}catch{le=null}return le}function mr(e,n,t){return new Promise((r,i)=>{let o=dr++;he.set(o,{resolve:r,reject:i});let a=n.positions.slice(),l=n.index?n.index.slice():null,s=[a.buffer];l&&s.push(l.buffer),e.postMessage({id:o,positions:a,index:l,thresholdAngle:t},s)})}var Oe=new Map;function Je(e,n){let t=Qe(e);if(!t||Ce(e)<qe)return Promise.resolve(Fe(e,n));let r=lr(t,n),i=Oe.get(r);if(i)return i;let o=ur();if(!o)return Promise.resolve(Fe(e,n));let a=mr(o,t,n).catch(()=>ye(t.positions,t.index,n)).finally(()=>{Oe.delete(r)});return Oe.set(r,a),a}import*as ne from"three";import{LineMaterial as pr}from"three/addons/lines/LineMaterial.js";import{LineSegments2 as tt}from"three/addons/lines/LineSegments2.js";function Er(e,n){let r=(Array.isArray(e.material)?e.material[0]:e.material)?.color;return r?r.clone().multiplyScalar(1-n):new ne.Color(We)}var we=class{constructor(n){Y(this,"options",n);Y(this,"byKey",new Map)}for(n,t){let r=this.options.forcedColor??Er(n,this.options.darken),i=r.getHex()*2+(t?1:0),o=this.byKey.get(i);return o||(o=fr(r,this.options.width,t),this.byKey.set(i,o)),o}disposeUnused(n){let t=new Set(n.map(r=>r.material));for(let r of this.byKey.values())t.has(r)||r.dispose()}};function fr(e,n,t){let r=new pr({color:e});return r.linewidth=n,r.polygonOffset=!0,r.polygonOffsetFactor=Ke,r.polygonOffsetUnits=Ye,t&&(r.transparent=!0),r}function rt(e,n,t){let r=new tt(e.geometry,n);return r.userData.kind=se,r.raycast=()=>{},t&&Rr(r,e.edgeSpacing),r}var et=new ne.Vector3,hr=new ne.Vector3;function gr(e,n,t){e.geometry.boundingSphere||e.geometry.computeBoundingSphere();let r=e.geometry.boundingSphere;if(!r)return 1/0;if(n.isPerspectiveCamera){let i=n;et.copy(r.center).applyMatrix4(e.matrixWorld);let o=hr.setFromMatrixPosition(n.matrixWorld).distanceTo(et),a=r.radius*e.matrixWorld.getMaxScaleOnAxis();if(o<=a)return 1/0;let l=Math.tan(ne.MathUtils.degToRad(i.fov)*.5),s=2*o*l;return s>0?t/s:1/0}if(n.isOrthographicCamera){let i=n,o=(i.top-i.bottom)/i.zoom;return o>0?t/o:1/0}return 1/0}function Rr(e,n){e.onBeforeRender=(t,r,i)=>{tt.prototype.onBeforeRender.call(e,t);let o=e.material,a=gr(e,i,o.resolution.y),l=n*a;o.opacity=ne.MathUtils.clamp((l-Le)/(Xe-Le),0,1)}}function br(e){return e.userData?.kind===se}function vr(e,n){let t=[];return e.traverse(r=>{if(r instanceof nt.Mesh&&!(r.userData.id==="floor"||r.userData.id==="grid")&&r.userData.kind!==se&&!r.children.some(i=>i.userData?.kind===se)&&r.geometry){if(Ce(r.geometry)>n){r.userData.edgesSkipped=He,console.debug(`[edges] skipping mesh over triangle cap (${Ce(r.geometry)} > ${n})`);return}delete r.userData.edgesSkipped,t.push(r)}}),t}function yr(e,n,t,r){let i=r.distanceFade&&n.segmentCount<=r.maxSegments,o=rt(n,t.for(e,i),i);return e.add(o),o}var ot=new WeakMap;function Ie(e){return ot.get(e)??0}function xr(e,n){for(let t=e;t;t=t.parent)if(t===n)return!0;return!1}async function it(e,n={}){let t=Ze(n),r=new we(t),i=Ie(e),o=[],a=vr(e,t.maxTriangles).map(async l=>{let s=await Je(l.geometry,t.thresholdAngle);Ie(e)===i&&xr(l,e)&&(l.children.some(u=>u.userData?.kind===se)||o.push(yr(l,Ue(s),r,t)))});return await Promise.all(a),r.disposeUnused(o),o}function at(e){ot.set(e,Ie(e)+1);let n=[];e.traverse(r=>{r instanceof Tr&&br(r)&&n.push(r)});let t=new Set;for(let r of n)r.geometry.dispose(),t.add(r.material),r.removeFromParent();return t.forEach(r=>r.dispose()),n.length}import*as z from"three";function Hr(e){if(!(e>0)||!Number.isFinite(e))return 1;let n=Math.floor(Math.log10(e)),t=Math.pow(10,n),r=e/t;return(r>=5?5:r>=2?2:1)*t}var Cr=`
3
3
  varying vec3 vWorldPos;
4
4
  void main() {
5
5
  vec4 world = modelMatrix * vec4(position, 1.0);
6
6
  vWorldPos = world.xyz;
7
7
  gl_Position = projectionMatrix * viewMatrix * world;
8
8
  }
9
- `,Ir=`
9
+ `,wr=`
10
10
  precision highp float;
11
11
  varying vec3 vWorldPos;
12
12
 
@@ -18,8 +18,7 @@ import{a as Kt,b as Yt,c as me,d as Zt,e as $t,g as Qt,h as Le,i as Ee,j as Oe,m
18
18
  uniform vec3 uCenter; // fade center (camera position projected onto the plane)
19
19
  uniform float uFade;
20
20
 
21
- // Antialiased grid line intensity for a given spacing, using screen-space derivatives so lines
22
- // stay ~1px regardless of zoom (the standard "pristine grid" technique).
21
+ // Screen-space derivatives keep grid lines ~1px regardless of zoom ("pristine grid" technique).
23
22
  float gridLine(vec2 coord, float spacing) {
24
23
  vec2 c = coord / spacing;
25
24
  vec2 d = fwidth(c);
@@ -51,8 +50,8 @@ import{a as Kt,b as Yt,c as me,d as Zt,e as $t,g as Qt,h as Le,i as Ee,j as Oe,m
51
50
  if (alpha < 0.001) discard;
52
51
  gl_FragColor = vec4(color, alpha);
53
52
  }
54
- `;function ht(e={}){let{cellSize:n=1,majorEvery:t=10,cellColor:r=8947848,majorColor:i=4473924,fadeDistance:o=100,plane:a="y"}=e,s=a==="y"?new _.Vector2(0,2):a==="z"?new _.Vector2(0,1):new _.Vector2(1,2),l=2.5,m=new _.PlaneGeometry(1,1);a==="y"?m.rotateX(-Math.PI/2):a==="x"&&m.rotateY(Math.PI/2);let f=new _.ShaderMaterial({vertexShader:Fr,fragmentShader:Ir,transparent:!0,depthWrite:!1,side:_.DoubleSide,uniforms:{uAxes:{value:s},uCell:{value:n},uMajor:{value:t},uCellColor:{value:new _.Color(r)},uMajorColor:{value:new _.Color(i)},uCenter:{value:new _.Vector3},uFade:{value:o}}}),E=new _.Mesh(m,f);E.name="grid",E.userData.id="grid",E.renderOrder=-1;let g=o,u=o*l,p=new _.Vector3;return{object:E,update:h=>{a==="y"?(E.position.set(h.x,0,h.z),p.set(h.x,0,h.z)):a==="z"?(E.position.set(h.x,h.y,0),p.set(h.x,h.y,0)):(E.position.set(0,h.y,h.z),p.set(0,h.y,h.z)),f.uniforms.uCenter.value.copy(p),E.scale.setScalar(u)},fitToContent:h=>{if(h.isEmpty())return;let C=h.getSize(new _.Vector3),b=(I,d)=>d===0?I.x:d===1?I.y:I.z,A=Math.max(b(C,s.x),b(C,s.y));if(!(A>0)||!Number.isFinite(A))return;let S=20;f.uniforms.uCell.value=Or(A/S),g=A*2,f.uniforms.uFade.value=g,u=g*l},setVisible:h=>{E.visible=h},dispose:()=>{E.removeFromParent(),m.dispose(),f.dispose()}}}import*as gt from"three";import{CSS2DRenderer as kr,CSS2DObject as zr}from"three/addons/renderers/CSS2DRenderer.js";function Rt(e,n){let t=new kr,r=t.domElement;r.style.position="absolute",r.style.top="0",r.style.left="0",r.style.overflow="hidden",r.style.pointerEvents="none",r.style.zIndex="30",getComputedStyle(e).position==="static"&&(e.style.position="relative"),e.appendChild(r);let i={width:e.clientWidth||1,height:e.clientHeight||1};t.setSize(i.width,i.height);let o=new gt.Group;o.name="label-layer",o.userData.id="label-layer",n.add(o);let a=new Set;return{addLabel:(l,m,f)=>{let E=document.createElement("div");E.textContent=l,f?E.className=f:Object.assign(E.style,{padding:"2px 6px",borderRadius:"4px",background:"rgba(20, 20, 20, 0.78)",color:"#fff",font:"12px/1.3 system-ui, sans-serif",whiteSpace:"pre",textAlign:"center",userSelect:"none"}),E.style.pointerEvents="none";let g=new zr(E);return g.position.copy(m),o.add(g),a.add(g),{object:g,setPosition:u=>g.position.copy(u),setText:u=>{E.textContent=u},remove:()=>{g.removeFromParent(),E.remove(),a.delete(g)}}},render:(l,m)=>t.render(l,m),setSize:(l,m)=>t.setSize(l,m),dispose:()=>{a.forEach(l=>{l.removeFromParent(),l.element.remove()}),a.clear(),o.removeFromParent(),r.remove()}}}import*as D from"three";import{Line2 as _r}from"three/addons/lines/Line2.js";import{LineGeometry as Vr}from"three/addons/lines/LineGeometry.js";import{LineMaterial as jr}from"three/addons/lines/LineMaterial.js";var Nr=12,Gr=16763904,Tt=.015,bt={Millimeters:{metersPerUnit:1/1e3,suffix:"mm"},Centimeters:{metersPerUnit:1/100,suffix:"cm"},Meters:{metersPerUnit:1,suffix:"m"},Inches:{metersPerUnit:1/39.37,suffix:"in"},Feet:{metersPerUnit:1/3.28084,suffix:"ft"}};function Ur(e){let n=e&&bt[e]||bt.Meters;return t=>`${(t/n.metersPerUnit).toPrecision(3)} ${n.suffix}`}function Br(e,n){if(e.isOrthographicCamera){let r=e;return Math.abs(r.top-r.bottom)/(r.zoom||1)*Tt}return((n?e.position.distanceTo(n):e.position.length())||1)*Tt}function Wr(e){let n=e.object;if(n instanceof D.Mesh)return e.face?[e.face.a,e.face.b,e.face.c]:null;if(n instanceof D.Points)return e.index!=null?[e.index]:null;if(n instanceof D.Line){if(e.index==null)return null;let t=n.geometry.index;return t?e.index+1>=t.count?null:[t.getX(e.index),t.getX(e.index+1)]:[e.index,e.index+1]}return null}function qr(e,n,t,r){let i=e.point.clone(),o=e.object,a=Wr(e);if(!a||!o.geometry)return i;let s=o.geometry.attributes.position;if(!s)return i;let l=g=>{let u=g.clone().project(n);return new D.Vector2((u.x+1)/2*t.width,(1-u.y)/2*t.height)},m=l(i),f=i,E=r;for(let g of a){if(g>=s.count)continue;let p=new D.Vector3().fromBufferAttribute(s,g).applyMatrix4(o.matrixWorld),h=l(p).distanceTo(m);h<E&&(E=h,f=p)}return f}function vt(e){let{canvas:n,scene:t,getActiveCamera:r,getViewTarget:i,labelLayer:o,options:a={}}=e,s=a.snapPixels??Nr,l=new D.Color(a.color??Gr),m=Ur(a.displayUnit),f=(v,y)=>`${m(v)}
55
- \u0394x ${m(y.x)} \u0394y ${m(y.y)} \u0394z ${m(y.z)}`,E=a.format??f,g=new D.Raycaster,u=new D.Vector2,p=!1,h=[],C=[],b=null,A=null,S=new D.PointsMaterial({color:l,size:8,sizeAttenuation:!1,depthTest:!1}),I=new D.PointsMaterial({color:l,size:11,sizeAttenuation:!1,depthTest:!1,transparent:!0,opacity:.5}),d=null,c=v=>{if(!v){d&&(d.visible=!1);return}if(!d){let y=new D.BufferGeometry;y.setAttribute("position",new D.Float32BufferAttribute([0,0,0],3)),d=new D.Points(y,I),d.renderOrder=1e3,d.userData.id="measure",d.raycast=()=>{},t.add(d)}d.position.copy(v),d.visible=!0},R=v=>{let y=new D.BufferGeometry;y.setAttribute("position",new D.Float32BufferAttribute([v.x,v.y,v.z],3));let z=new D.Points(y,S);return z.renderOrder=999,z.userData.id="measure",z.raycast=()=>{},t.add(z),z},T=()=>{h.length=0,C.forEach(v=>{v.geometry.dispose(),v.removeFromParent()}),C.length=0,b&&(b.geometry.dispose(),b.material.dispose(),b.removeFromParent(),b=null),A?.remove(),A=null},x=()=>{if(h.length!==2)return;let[v,y]=h,z=new Vr;z.setPositions([v.x,v.y,v.z,y.x,y.y,y.z]);let j=new jr({color:l});j.linewidth=2,j.depthTest=!1,b=new _r(z,j),b.renderOrder=998,b.userData.id="measure",b.raycast=()=>{},t.add(b);let V=v.clone().add(y).multiplyScalar(.5),G=new D.Vector3(Math.abs(y.x-v.x),Math.abs(y.y-v.y),Math.abs(y.z-v.z));A=o.addLabel(E(v.distanceTo(y),G),V,a.labelClassName)},M=v=>{let y=n.getBoundingClientRect();u.x=(v.clientX-y.left)/y.width*2-1,u.y=-((v.clientY-y.top)/y.height)*2+1;let z=r();g.setFromCamera(u,z);let j=Br(z,i?.());g.params.Line.threshold=j,g.params.Points.threshold=j;let V=g.intersectObjects(t.children,!0).filter(G=>G.object.userData.id!=="measure"&&G.object.userData.id!=="grid");return V.length===0?null:qr(V[0],z,{width:y.width,height:y.height},s)},P=null,L=0,Y=()=>{L&&(cancelAnimationFrame(L),L=0),P=null};return{setEnabled:v=>{p=v,v||(Y(),T(),c(null))},isEnabled:()=>p,handleClick:v=>{if(!p)return!1;h.length===2&&T();let y=M(v);return y===null||(h.push(y),C.push(R(y)),h.length===2&&x()),!0},handleMove:v=>{p&&(P=v,!L&&(L=requestAnimationFrame(()=>{L=0;let y=P;P=null,!(!p||!y)&&c(M(y))})))},clear:T,dispose:()=>{Y(),T(),d&&(d.geometry.dispose(),d.removeFromParent(),d=null),S.dispose(),I.dispose()}}}import*as Te from"three";var Xr=.5,Kr=.01,Yr=.05,Zr=[];function yt({camera:e,scene:n,groundNormals:t=()=>Zr}){let r=e.near,i=e.near,o=new Te.Vector3,a=new Te.Vector3;return{update:()=>{e.near!==i&&(r=e.near);let l=Q(n),m=r;if(!l.isEmpty()){let f=l.getSize(a).length()*.5,E=e.position.distanceTo(l.getCenter(o))-f;for(let g of t())E=Math.min(E,Math.abs(e.position.dot(g)));m=Te.MathUtils.clamp(E*Xr,r,e.far*Kr)}Math.abs(m-i)>i*Yr&&(e.near=m,e.updateProjectionMatrix(),i=m)}}}import*as B from"three";import{ViewHelper as $r}from"three/addons/helpers/ViewHelper.js";function xt(e){let{camera:n,domElement:t,controller:r}=e,i=new $r(n,t);i.setLabels("X","Y","Z");let o=!0,a=128,s=new B.Raycaster,l=new B.OrthographicCamera(-2,2,2,-2,0,4);l.position.set(0,0,2),l.updateMatrixWorld();let m={posX:new B.Vector3(1,0,0),negX:new B.Vector3(-1,0,0),posY:new B.Vector3(0,1,0),negY:new B.Vector3(0,-1,0),posZ:new B.Vector3(0,0,1),negZ:new B.Vector3(0,0,-1)},f=g=>{let u=t.getBoundingClientRect(),p=u.left+t.offsetWidth-a-i.location.right,h=u.top+t.offsetHeight-a-i.location.bottom,C=new B.Vector2((g.clientX-p)/a*2-1,-((g.clientY-h)/a)*2+1);if(Math.abs(C.x)>1||Math.abs(C.y)>1)return null;i.quaternion.copy(n.quaternion).invert(),i.updateMatrixWorld(),s.setFromCamera(C,l);let b=s.intersectObjects(i.children,!1);for(let A of b){let S=A.object.userData?.type;if(typeof S=="string"&&S in m)return S}return null};return{render:g=>{if(!o)return;let u=g.autoClear;g.autoClear=!1,i.render(g),g.autoClear=u},handleClick:g=>{if(!o)return!1;let u=f(g);return u?(r.getProjection()==="orthographic"&&r.setProjection("perspective"),r.setViewDirection(m[u],!1),!0):!1},setVisible:g=>{o=g},isVisible:()=>o,dispose:()=>i.dispose()}}import*as je from"three";function Ht(e,n,t,r,i,o,a,s,l,m,f,E,g,u,p=!0){let h=null,C=performance.now(),b=!0,A=0,S=500,I=new je.Matrix4,d=new je.Matrix4,c=null,R=()=>{b=!0},T=w=>{w.updateMatrixWorld();let k=c!==w||!I.equals(w.matrixWorld)||!d.equals(w.projectionMatrix);return k&&(c=w,I.copy(w.matrixWorld),d.copy(w.projectionMatrix)),k},x=e.domElement,M=["pointerdown","pointerup","wheel"];if(p)for(let w of M)x.addEventListener(w,R,{passive:!0});let P=()=>{let{width:w,height:k}=a();if(w===0||k===0)return;let v=Math.floor(w*s),y=Math.floor(k*s);(e.domElement.width!==v||e.domElement.height!==y)&&(e.setPixelRatio(s),e.setSize(w,k,!1),t.aspect=w/k,t.updateProjectionMatrix(),i.updateAspect(w,k),E?.()?.setSize(w,k,s),g?.setSize(w,k),R())},L=function(){h=requestAnimationFrame(L);let w=performance.now(),k=(w-C)/1e3;C=w,P(),(o.enableDamping||o.autoRotate)&&o.update(),m&&m.update(r().position),u&&u.update(),l?.(k);let v=r();if(p){if(!(b||T(v)||w-A>=S))return;b=!1,A=w}let y=E?.();y?(y.setCamera(v),y.render(k)):e.render(n,v),g&&g.render(n,v),f&&f.render(e)};return{animate:L,dispose:()=>{if(h!==null&&(cancelAnimationFrame(h),h=null),p)for(let w of M)x.removeEventListener(w,R)},invalidate:R}}import*as wt from"three";import*as de from"three";var W=new de.Vector3(0,0,1);function Ct(e){let n=e.sceneScale||"m",r={mm:{cameraDistance:20,near:.1,far:2e3,floorSize:100,lightDistance:10,lightHeight:20,minDistance:.1,shadowSize:100,scaleFactor:1e3},cm:{cameraDistance:20,near:.1,far:2e3,floorSize:100,lightDistance:25,lightHeight:50,minDistance:.1,shadowSize:100,scaleFactor:100},m:{cameraDistance:10,near:.01,far:2e3,floorSize:50,lightDistance:25,lightHeight:50,minDistance:.001,shadowSize:100,scaleFactor:1},inches:{cameraDistance:15,near:.1,far:2e3,floorSize:80,lightDistance:20,lightHeight:40,minDistance:.1,shadowSize:80,scaleFactor:39.37},feet:{cameraDistance:8,near:.1,far:2e3,floorSize:40,lightDistance:15,lightHeight:30,minDistance:.1,shadowSize:60,scaleFactor:3.28084}}[n],i=e.look??Le,o=Ee[i];return{sceneScale:n,look:i,camera:{position:e.camera?.position||ye(e.environment?.sceneUp??W,r.cameraDistance*Math.sqrt(3)),fov:e.camera?.fov||20,near:e.camera?.near||r.near,far:e.camera?.far||r.far,target:e.camera?.target||new de.Vector3(0,0,0),dynamicNear:e.camera?.dynamicNear??!0},lighting:{enableSunlight:e.lighting?.enableSunlight??!0,sunlightIntensity:e.lighting?.sunlightIntensity??1,sunlightPosition:e.lighting?.sunlightPosition||qe(e.environment?.sceneUp??W,r.lightDistance,r.lightHeight),ambientLightColor:e.lighting?.ambientLightColor||new de.Color(4210752),ambientLightIntensity:e.lighting?.ambientLightIntensity??o.ambientIntensity,sunlightColor:e.lighting?.sunlightColor||16777215,enableHemisphereLight:e.lighting?.enableHemisphereLight??o.hemisphereIntensity>0,hemisphereSkyColor:e.lighting?.hemisphereSkyColor??14673663,hemisphereGroundColor:e.lighting?.hemisphereGroundColor??7036754,hemisphereIntensity:e.lighting?.hemisphereIntensity??o.hemisphereIntensity},environment:{hdrPath:e.environment?.hdrPath||"/baseHDR.hdr",backgroundColor:e.environment?.backgroundColor||new de.Color(15790320),enableEnvironmentLighting:e.environment?.enableEnvironmentLighting??!0,sceneUp:e.environment?.sceneUp||W,showEnvironment:e.environment?.showEnvironment??!1,environmentIntensity:e.environment?.environmentIntensity??o.environmentIntensity},floor:{enabled:e.floor?.enabled??!1,size:e.floor?.size||r.floorSize,color:e.floor?.color||new de.Color(8421504),roughness:e.floor?.roughness??.7,metalness:e.floor?.metalness??0,receiveShadow:e.floor?.receiveShadow??!0},render:{enableShadows:e.render?.enableShadows??!0,shadowMapSize:e.render?.shadowMapSize||2048,antialias:e.render?.antialias??!0,pixelRatio:e.render?.pixelRatio||Math.min(window.devicePixelRatio,2),toneMapping:e.render?.toneMapping??o.toneMapping,toneMappingExposure:e.render?.toneMappingExposure??o.toneMappingExposure,preserveDrawingBuffer:e.render?.preserveDrawingBuffer??!1,ambientOcclusion:e.render?.ambientOcclusion??o.ambientOcclusion,aoIntensity:e.render?.aoIntensity??1,aoPixelRatio:e.render?.aoPixelRatio??1,onDemand:e.render?.onDemand??!0},controls:{enableDamping:e.controls?.enableDamping??!1,dampingFactor:e.controls?.dampingFactor||.05,autoRotate:e.controls?.autoRotate??!1,autoRotateSpeed:e.controls?.autoRotateSpeed||.5,enableZoom:e.controls?.enableZoom??!0,enablePan:e.controls?.enablePan??!0,minDistance:e.controls?.minDistance||r.minDistance,maxDistance:e.controls?.maxDistance||1/0},grid:{enabled:e.grid?.enabled??!1,cellSize:e.grid?.cellSize??1,majorEvery:e.grid?.majorEvery??10,cellColor:e.grid?.cellColor??8947848,majorColor:e.grid?.majorColor??4473924,fadeDistance:e.grid?.fadeDistance??100,plane:e.grid?.plane??xe(e.environment?.sceneUp??W)},gizmo:{enabled:e.gizmo?.enabled??!1},edges:{enabled:e.edges?.enabled??!1,color:e.edges?.color,darken:e.edges?.darken,width:e.edges?.width??1.5,thresholdAngle:e.edges?.thresholdAngle??44,distanceFade:e.edges?.distanceFade??!0,maxTriangles:e.edges?.maxTriangles,maxSegments:e.edges?.maxSegments,screenSpaceFallback:e.edges?.screenSpaceFallback},measure:{enabled:e.measure?.enabled??!1,snapPixels:e.measure?.snapPixels,color:e.measure?.color,labelClassName:e.measure?.labelClassName,displayUnit:e.measure?.displayUnit,format:e.measure?.format},events:{onBackgroundClicked:e.events?.onBackgroundClicked,onObjectSelected:e.events?.onObjectSelected,onMeshMetadataClicked:e.events?.onMeshMetadataClicked,onMeshDoubleClicked:e.events?.onMeshDoubleClicked,selectionColor:e.events?.selectionColor||"#ff0000",enableEventHandlers:e.events?.enableEventHandlers??!0,enableKeyboardControls:e.events?.enableKeyboardControls??!0,enableClickToFocus:e.events?.enableClickToFocus??!0,enableDoubleClickZoom:e.events?.enableDoubleClickZoom??!0,onReady:e.events?.onReady,onFrame:e.events?.onFrame},onMaxAnisotropy:e.onMaxAnisotropy}}function Mt(e){let{scene:n,renderer:t,lights:r,config:i,pipeline:o,requestRender:a}=e,s=i.look,l=u=>{u.ambientIntensity!==void 0&&(r.ambient.intensity=u.ambientIntensity),u.hemisphereIntensity!==void 0&&!r.hemisphere&&u.hemisphereIntensity>0&&(r.hemisphere=new wt.HemisphereLight(u.hemisphereSkyColor??i.lighting.hemisphereSkyColor,u.hemisphereGroundColor??i.lighting.hemisphereGroundColor,u.hemisphereIntensity),r.hemisphere.position.copy(i.environment.sceneUp??W),n.add(r.hemisphere)),r.hemisphere&&(u.hemisphereIntensity!==void 0&&(r.hemisphere.intensity=u.hemisphereIntensity),u.hemisphereSkyColor!==void 0&&r.hemisphere.color.set(u.hemisphereSkyColor),u.hemisphereGroundColor!==void 0&&r.hemisphere.groundColor.set(u.hemisphereGroundColor)),a()},m=u=>{i.environment.environmentIntensity=u,n.environmentIntensity=u,a()};return{setFillLights:l,setEnvironmentIntensity:m,setToneMappingExposure:u=>{i.render.toneMappingExposure=u,t.toneMappingExposure=u,o.get()&&o.rebuild()},setAoIntensity:u=>{i.render.aoIntensity=u,o.get()&&o.rebuild()},setLook:u=>{let p=Ee[u];s=u,t.toneMapping=p.toneMapping,t.toneMappingExposure=p.toneMappingExposure,i.render.toneMapping=p.toneMapping,i.render.toneMappingExposure=p.toneMappingExposure,l({hemisphereIntensity:p.hemisphereIntensity,ambientIntensity:p.ambientIntensity}),m(p.environmentIntensity);let h=o.get()!==null;o.setAmbientOcclusion(p.ambientOcclusion),h&&o.rebuild(),n.traverse(C=>{if(C.userData.source!=="compute")return;let b=C,A=Array.isArray(b.material)?b.material:b.material?[b.material]:[];for(let S of A)"envMapIntensity"in S&&(S.envMapIntensity=p.envMapIntensity)}),a()},getMaterialAppearance:()=>Oe(s)}}import*as St from"three";function Dt(e,n){let t=n.parentElement,r=t?t.clientWidth:window.innerWidth,i=t?t.clientHeight:window.innerHeight,o=new St.PerspectiveCamera(e.camera.fov,r/i,e.camera.near,e.camera.far),a=e.camera.position;return a&&o.position.set(a.x,a.y,a.z),o}import*as De from"three";function At(e){let n=new De.Scene,t=typeof e.environment.backgroundColor=="string"?new De.Color(e.environment.backgroundColor):e.environment.backgroundColor;return n.background=t||null,n}import*as Pt from"three";function Lt(e,n){se(e,n),Fe(e.environment??void 0)&&e.environment?.dispose(),e.background instanceof Pt.Texture&&Fe(e.background)&&e.background.dispose()}import*as Ft from"three";import{EffectComposer as en}from"three/addons/postprocessing/EffectComposer.js";import{RenderPass as tn}from"three/addons/postprocessing/RenderPass.js";import{GTAOPass as rn}from"three/addons/postprocessing/GTAOPass.js";import{SMAAPass as nn}from"three/addons/postprocessing/SMAAPass.js";import{OutputPass as on}from"three/addons/postprocessing/OutputPass.js";import*as O from"three";import{Pass as Qr,FullScreenQuad as Jr}from"three/addons/postprocessing/Pass.js";var Ne={uniforms:{tDiffuse:{value:null},tNormal:{value:null},tDepth:{value:null},uResolution:{value:new O.Vector2(1,1)},uColor:{value:new O.Color(2236962)},uOpacity:{value:1},uNormalThreshold:{value:.4},uDepthThreshold:{value:.02},uThickness:{value:1},uNear:{value:.1},uFar:{value:1e3},uPerspective:{value:1}},vertexShader:`
53
+ `;function st(e={}){let{cellSize:n=1,majorEvery:t=10,cellColor:r=8947848,majorColor:i=4473924,fadeDistance:o=100,plane:a="y"}=e,l=a==="y"?new z.Vector2(0,2):a==="z"?new z.Vector2(0,1):new z.Vector2(1,2),s=2.5,u=new z.PlaneGeometry(1,1);a==="y"?u.rotateX(-Math.PI/2):a==="x"&&u.rotateY(Math.PI/2);let f=new z.ShaderMaterial({vertexShader:Cr,fragmentShader:wr,transparent:!0,depthWrite:!1,side:z.DoubleSide,uniforms:{uAxes:{value:l},uCell:{value:n},uMajor:{value:t},uCellColor:{value:new z.Color(r)},uMajorColor:{value:new z.Color(i)},uCenter:{value:new z.Vector3},uFade:{value:o}}}),E=new z.Mesh(u,f);E.name="grid",E.userData.id="grid",E.renderOrder=-1;let g=o,m=o*s,p=new z.Vector3;return{object:E,update:h=>{a==="y"?(E.position.set(h.x,0,h.z),p.set(h.x,0,h.z)):a==="z"?(E.position.set(h.x,h.y,0),p.set(h.x,h.y,0)):(E.position.set(0,h.y,h.z),p.set(0,h.y,h.z)),f.uniforms.uCenter.value.copy(p),E.scale.setScalar(m)},fitToContent:h=>{if(h.isEmpty())return;let H=h.getSize(new z.Vector3),x=(V,d)=>d===0?V.x:d===1?V.y:V.z,S=Math.max(x(H,l.x),x(H,l.y));if(!(S>0)||!Number.isFinite(S))return;let A=20;f.uniforms.uCell.value=Hr(S/A),g=S*2,f.uniforms.uFade.value=g,m=g*s},setVisible:h=>{E.visible=h},dispose:()=>{E.removeFromParent(),u.dispose(),f.dispose()}}}import*as lt from"three";import{CSS2DRenderer as Mr,CSS2DObject as Sr}from"three/addons/renderers/CSS2DRenderer.js";function ct(e,n){let t=new Mr,r=t.domElement;r.style.position="absolute",r.style.top="0",r.style.left="0",r.style.overflow="hidden",r.style.pointerEvents="none",r.style.zIndex="30",getComputedStyle(e).position==="static"&&(e.style.position="relative"),e.appendChild(r);let i={width:e.clientWidth||1,height:e.clientHeight||1};t.setSize(i.width,i.height);let o=new lt.Group;o.name="label-layer",o.userData.id="label-layer",n.add(o);let a=new Set;return{addLabel:(s,u,f)=>{let E=document.createElement("div");E.textContent=s,f?E.className=f:Object.assign(E.style,{padding:"2px 6px",borderRadius:"4px",background:"rgba(20, 20, 20, 0.78)",color:"#fff",font:"12px/1.3 system-ui, sans-serif",whiteSpace:"pre",textAlign:"center",userSelect:"none"}),E.style.pointerEvents="none";let g=new Sr(E);return g.position.copy(u),o.add(g),a.add(g),{object:g,setPosition:m=>g.position.copy(m),setText:m=>{E.textContent=m},remove:()=>{g.removeFromParent(),E.remove(),a.delete(g)}}},render:(s,u)=>t.render(s,u),setSize:(s,u)=>t.setSize(s,u),dispose:()=>{a.forEach(s=>{s.removeFromParent(),s.element.remove()}),a.clear(),o.removeFromParent(),r.remove()}}}import*as D from"three";import{Line2 as Dr}from"three/addons/lines/Line2.js";import{LineGeometry as Ar}from"three/addons/lines/LineGeometry.js";import{LineMaterial as Pr}from"three/addons/lines/LineMaterial.js";var Lr=12,Or=16763904,dt=.015,ut={Millimeters:{metersPerUnit:1/1e3,suffix:"mm"},Centimeters:{metersPerUnit:1/100,suffix:"cm"},Meters:{metersPerUnit:1,suffix:"m"},Inches:{metersPerUnit:1/39.37,suffix:"in"},Feet:{metersPerUnit:1/3.28084,suffix:"ft"}};function Fr(e){let n=e&&ut[e]||ut.Meters;return t=>`${(t/n.metersPerUnit).toPrecision(3)} ${n.suffix}`}function Ir(e,n){if(e.isOrthographicCamera){let r=e;return Math.abs(r.top-r.bottom)/(r.zoom||1)*dt}return((n?e.position.distanceTo(n):e.position.length())||1)*dt}function kr(e){let n=e.object;if(n instanceof D.Mesh)return e.face?[e.face.a,e.face.b,e.face.c]:null;if(n instanceof D.Points)return e.index!=null?[e.index]:null;if(n instanceof D.Line){if(e.index==null)return null;let t=n.geometry.index;return t?e.index+1>=t.count?null:[t.getX(e.index),t.getX(e.index+1)]:[e.index,e.index+1]}return null}function zr(e,n,t,r){let i=e.point.clone(),o=e.object,a=kr(e);if(!a||!o.geometry)return i;let l=o.geometry.attributes.position;if(!l)return i;let s=g=>{let m=g.clone().project(n);return new D.Vector2((m.x+1)/2*t.width,(1-m.y)/2*t.height)},u=s(i),f=i,E=r;for(let g of a){if(g>=l.count)continue;let p=new D.Vector3().fromBufferAttribute(l,g).applyMatrix4(o.matrixWorld),h=s(p).distanceTo(u);h<E&&(E=h,f=p)}return f}function mt(e){let{canvas:n,scene:t,getActiveCamera:r,getViewTarget:i,labelLayer:o,options:a={}}=e,l=a.snapPixels??Lr,s=new D.Color(a.color??Or),u=Fr(a.displayUnit),f=(y,b)=>`${u(y)}
54
+ \u0394x ${u(b.x)} \u0394y ${u(b.y)} \u0394z ${u(b.z)}`,E=a.format??f,g=new D.Raycaster,m=new D.Vector2,p=!1,h=[],H=[],x=null,S=null,A=new D.PointsMaterial({color:s,size:8,sizeAttenuation:!1,depthTest:!1}),V=new D.PointsMaterial({color:s,size:11,sizeAttenuation:!1,depthTest:!1,transparent:!0,opacity:.5}),d=null,c=y=>{if(!y){d&&(d.visible=!1);return}if(!d){let b=new D.BufferGeometry;b.setAttribute("position",new D.Float32BufferAttribute([0,0,0],3)),d=new D.Points(b,V),d.renderOrder=1e3,d.userData.id="measure",d.raycast=()=>{},t.add(d)}d.position.copy(y),d.visible=!0},R=y=>{let b=new D.BufferGeometry;b.setAttribute("position",new D.Float32BufferAttribute([y.x,y.y,y.z],3));let I=new D.Points(b,A);return I.renderOrder=999,I.userData.id="measure",I.raycast=()=>{},t.add(I),I},T=()=>{h.length=0,H.forEach(y=>{y.geometry.dispose(),y.removeFromParent()}),H.length=0,x&&(x.geometry.dispose(),x.material.dispose(),x.removeFromParent(),x=null),S?.remove(),S=null},v=()=>{if(h.length!==2)return;let[y,b]=h,I=new Ar;I.setPositions([y.x,y.y,y.z,b.x,b.y,b.z]);let k=new Pr({color:s});k.linewidth=2,k.depthTest=!1,x=new Dr(I,k),x.renderOrder=998,x.userData.id="measure",x.raycast=()=>{},t.add(x);let N=y.clone().add(b).multiplyScalar(.5),G=new D.Vector3(Math.abs(b.x-y.x),Math.abs(b.y-y.y),Math.abs(b.z-y.z));S=o.addLabel(E(y.distanceTo(b),G),N,a.labelClassName)},C=y=>{let b=n.getBoundingClientRect();m.x=(y.clientX-b.left)/b.width*2-1,m.y=-((y.clientY-b.top)/b.height)*2+1;let I=r();g.setFromCamera(m,I);let k=Ir(I,i?.());g.params.Line.threshold=k,g.params.Points.threshold=k;let N=g.intersectObjects(t.children,!0).filter(G=>G.object.userData.id!=="measure"&&G.object.userData.id!=="grid");return N.length===0?null:zr(N[0],I,{width:b.width,height:b.height},l)},_=null,F=0,q=()=>{F&&(cancelAnimationFrame(F),F=0),_=null};return{setEnabled:y=>{p=y,y||(q(),T(),c(null))},isEnabled:()=>p,handleClick:y=>{if(!p)return!1;h.length===2&&T();let b=C(y);return b===null||(h.push(b),H.push(R(b)),h.length===2&&v()),!0},handleMove:y=>{p&&(_=y,!F&&(F=requestAnimationFrame(()=>{F=0;let b=_;_=null,!(!p||!b)&&c(C(b))})))},clear:T,dispose:()=>{q(),T(),d&&(d.geometry.dispose(),d.removeFromParent(),d=null),A.dispose(),V.dispose()}}}import*as ge from"three";var Vr=.5,_r=.01,jr=.05,Nr=[];function pt({camera:e,scene:n,groundNormals:t=()=>Nr}){let r=e.near,i=e.near,o=new ge.Vector3,a=new ge.Vector3;return{update:()=>{e.near!==i&&(r=e.near);let s=Q(n),u=r;if(!s.isEmpty()){let f=s.getSize(a).length()*.5,E=e.position.distanceTo(s.getCenter(o))-f;for(let g of t())E=Math.min(E,Math.abs(e.position.dot(g)));u=ge.MathUtils.clamp(E*Vr,r,e.far*_r)}Math.abs(u-i)>i*jr&&(e.near=u,e.updateProjectionMatrix(),i=u)}}}import*as B from"three";import{ViewHelper as Gr}from"three/addons/helpers/ViewHelper.js";function Et(e){let{camera:n,domElement:t,controller:r}=e,i=new Gr(n,t);i.setLabels("X","Y","Z");let o=!0,a=128,l=new B.Raycaster,s=new B.OrthographicCamera(-2,2,2,-2,0,4);s.position.set(0,0,2),s.updateMatrixWorld();let u={posX:new B.Vector3(1,0,0),negX:new B.Vector3(-1,0,0),posY:new B.Vector3(0,1,0),negY:new B.Vector3(0,-1,0),posZ:new B.Vector3(0,0,1),negZ:new B.Vector3(0,0,-1)},f=g=>{let m=t.getBoundingClientRect(),p=m.left+t.offsetWidth-a-i.location.right,h=m.top+t.offsetHeight-a-i.location.bottom,H=new B.Vector2((g.clientX-p)/a*2-1,-((g.clientY-h)/a)*2+1);if(Math.abs(H.x)>1||Math.abs(H.y)>1)return null;i.quaternion.copy(n.quaternion).invert(),i.updateMatrixWorld(),l.setFromCamera(H,s);let x=l.intersectObjects(i.children,!1);for(let S of x){let A=S.object.userData?.type;if(typeof A=="string"&&A in u)return A}return null};return{render:g=>{if(!o)return;let m=g.autoClear;g.autoClear=!1,i.render(g),g.autoClear=m},handleClick:g=>{if(!o)return!1;let m=f(g);return m?(r.getProjection()==="orthographic"&&r.setProjection("perspective"),r.setViewDirection(u[m],!1),!0):!1},setVisible:g=>{o=g},isVisible:()=>o,dispose:()=>i.dispose()}}import*as ke from"three";function ft(e,n,t,r,i,o,a,l,s,u,f,E,g,m,p=!0){let h=null,H=performance.now(),x=!0,S=0,A=500,V=new ke.Matrix4,d=new ke.Matrix4,c=null,R=()=>{x=!0},T=M=>{M.updateMatrixWorld();let O=c!==M||!V.equals(M.matrixWorld)||!d.equals(M.projectionMatrix);return O&&(c=M,V.copy(M.matrixWorld),d.copy(M.projectionMatrix)),O},v=e.domElement,C=["pointerdown","pointerup","wheel"];if(p)for(let M of C)v.addEventListener(M,R,{passive:!0});let _=()=>{let{width:M,height:O}=a();if(M===0||O===0)return;let y=Math.floor(M*l),b=Math.floor(O*l);(e.domElement.width!==y||e.domElement.height!==b)&&(e.setPixelRatio(l),e.setSize(M,O,!1),t.aspect=M/O,t.updateProjectionMatrix(),i.updateAspect(M,O),E?.()?.setSize(M,O,l),g?.setSize(M,O),R())},F=function(){h=requestAnimationFrame(F);let M=performance.now(),O=(M-H)/1e3;H=M,_(),(o.enableDamping||o.autoRotate)&&o.update(),u&&u.update(r().position),m&&m.update(),s?.(O);let y=r();if(p){if(!(x||T(y)||M-S>=A))return;x=!1,S=M}let b=E?.();b?(b.setCamera(y),b.render(O)):e.render(n,y),g&&g.render(n,y),f&&f.render(e)};return{animate:F,dispose:()=>{if(h!==null&&(cancelAnimationFrame(h),h=null),p)for(let M of C)v.removeEventListener(M,R)},invalidate:R}}import*as gt from"three";import*as ce from"three";var W=new ce.Vector3(0,0,1);function ht(e){let n=e.sceneScale||"m",r={mm:{cameraDistance:20,near:.1,far:2e3,floorSize:100,lightDistance:10,lightHeight:20,minDistance:.1,shadowSize:100,scaleFactor:1e3},cm:{cameraDistance:20,near:.1,far:2e3,floorSize:100,lightDistance:25,lightHeight:50,minDistance:.1,shadowSize:100,scaleFactor:100},m:{cameraDistance:10,near:.01,far:2e3,floorSize:50,lightDistance:25,lightHeight:50,minDistance:.001,shadowSize:100,scaleFactor:1},inches:{cameraDistance:15,near:.1,far:2e3,floorSize:80,lightDistance:20,lightHeight:40,minDistance:.1,shadowSize:80,scaleFactor:39.37},feet:{cameraDistance:8,near:.1,far:2e3,floorSize:40,lightDistance:15,lightHeight:30,minDistance:.1,shadowSize:60,scaleFactor:3.28084}}[n],i=e.look??Ae,o=pe[i];return{sceneScale:n,look:i,camera:{position:e.camera?.position||be(e.environment?.sceneUp??W,r.cameraDistance*Math.sqrt(3)),fov:e.camera?.fov||20,near:e.camera?.near||r.near,far:e.camera?.far||r.far,target:e.camera?.target||new ce.Vector3(0,0,0),dynamicNear:e.camera?.dynamicNear??!0},lighting:{enableSunlight:e.lighting?.enableSunlight??!0,sunlightIntensity:e.lighting?.sunlightIntensity??1,sunlightPosition:e.lighting?.sunlightPosition||je(e.environment?.sceneUp??W,r.lightDistance,r.lightHeight),ambientLightColor:e.lighting?.ambientLightColor||new ce.Color(4210752),ambientLightIntensity:e.lighting?.ambientLightIntensity??o.ambientIntensity,sunlightColor:e.lighting?.sunlightColor||16777215,enableHemisphereLight:e.lighting?.enableHemisphereLight??o.hemisphereIntensity>0,hemisphereSkyColor:e.lighting?.hemisphereSkyColor??14673663,hemisphereGroundColor:e.lighting?.hemisphereGroundColor??7036754,hemisphereIntensity:e.lighting?.hemisphereIntensity??o.hemisphereIntensity},environment:{hdrPath:e.environment?.hdrPath||"/baseHDR.hdr",backgroundColor:e.environment?.backgroundColor||new ce.Color(15790320),enableEnvironmentLighting:e.environment?.enableEnvironmentLighting??!0,sceneUp:e.environment?.sceneUp||W,showEnvironment:e.environment?.showEnvironment??!1,environmentIntensity:e.environment?.environmentIntensity??o.environmentIntensity},floor:{enabled:e.floor?.enabled??!1,size:e.floor?.size||r.floorSize,color:e.floor?.color||new ce.Color(8421504),roughness:e.floor?.roughness??.7,metalness:e.floor?.metalness??0,receiveShadow:e.floor?.receiveShadow??!0},render:{enableShadows:e.render?.enableShadows??!0,shadowMapSize:e.render?.shadowMapSize||2048,antialias:e.render?.antialias??!0,pixelRatio:e.render?.pixelRatio||Math.min(window.devicePixelRatio,2),toneMapping:e.render?.toneMapping??o.toneMapping,toneMappingExposure:e.render?.toneMappingExposure??o.toneMappingExposure,preserveDrawingBuffer:e.render?.preserveDrawingBuffer??!1,ambientOcclusion:e.render?.ambientOcclusion??o.ambientOcclusion,aoIntensity:e.render?.aoIntensity??1,aoPixelRatio:e.render?.aoPixelRatio??1,onDemand:e.render?.onDemand??!0},controls:{enableDamping:e.controls?.enableDamping??!1,dampingFactor:e.controls?.dampingFactor||.05,autoRotate:e.controls?.autoRotate??!1,autoRotateSpeed:e.controls?.autoRotateSpeed||.5,enableZoom:e.controls?.enableZoom??!0,enablePan:e.controls?.enablePan??!0,minDistance:e.controls?.minDistance||r.minDistance,maxDistance:e.controls?.maxDistance||1/0},grid:{enabled:e.grid?.enabled??!1,cellSize:e.grid?.cellSize??1,majorEvery:e.grid?.majorEvery??10,cellColor:e.grid?.cellColor??8947848,majorColor:e.grid?.majorColor??4473924,fadeDistance:e.grid?.fadeDistance??100,plane:e.grid?.plane??ve(e.environment?.sceneUp??W)},gizmo:{enabled:e.gizmo?.enabled??!1},edges:{enabled:e.edges?.enabled??!1,color:e.edges?.color,darken:e.edges?.darken,width:e.edges?.width??1.5,thresholdAngle:e.edges?.thresholdAngle??44,distanceFade:e.edges?.distanceFade??!0,maxTriangles:e.edges?.maxTriangles,maxSegments:e.edges?.maxSegments,screenSpaceFallback:e.edges?.screenSpaceFallback},measure:{enabled:e.measure?.enabled??!1,snapPixels:e.measure?.snapPixels,color:e.measure?.color,labelClassName:e.measure?.labelClassName,displayUnit:e.measure?.displayUnit,format:e.measure?.format},events:{onBackgroundClicked:e.events?.onBackgroundClicked,onObjectSelected:e.events?.onObjectSelected,onMeshMetadataClicked:e.events?.onMeshMetadataClicked,onMeshDoubleClicked:e.events?.onMeshDoubleClicked,selectionColor:e.events?.selectionColor||"#ff0000",enableEventHandlers:e.events?.enableEventHandlers??!0,enableKeyboardControls:e.events?.enableKeyboardControls??!0,enableClickToFocus:e.events?.enableClickToFocus??!0,enableDoubleClickZoom:e.events?.enableDoubleClickZoom??!0,onReady:e.events?.onReady,onFrame:e.events?.onFrame},onMaxAnisotropy:e.onMaxAnisotropy}}function Rt(e){let{scene:n,renderer:t,lights:r,config:i,pipeline:o,requestRender:a}=e,l=i.look,s=m=>{m.ambientIntensity!==void 0&&(r.ambient.intensity=m.ambientIntensity),m.hemisphereIntensity!==void 0&&!r.hemisphere&&m.hemisphereIntensity>0&&(r.hemisphere=new gt.HemisphereLight(m.hemisphereSkyColor??i.lighting.hemisphereSkyColor,m.hemisphereGroundColor??i.lighting.hemisphereGroundColor,m.hemisphereIntensity),r.hemisphere.position.copy(i.environment.sceneUp??W),n.add(r.hemisphere)),r.hemisphere&&(m.hemisphereIntensity!==void 0&&(r.hemisphere.intensity=m.hemisphereIntensity),m.hemisphereSkyColor!==void 0&&r.hemisphere.color.set(m.hemisphereSkyColor),m.hemisphereGroundColor!==void 0&&r.hemisphere.groundColor.set(m.hemisphereGroundColor)),a()},u=m=>{i.environment.environmentIntensity=m,n.environmentIntensity=m,a()};return{setFillLights:s,setEnvironmentIntensity:u,setToneMappingExposure:m=>{i.render.toneMappingExposure=m,t.toneMappingExposure=m,o.get()&&o.rebuild()},setAoIntensity:m=>{i.render.aoIntensity=m,o.get()&&o.rebuild()},setLook:m=>{let p=pe[m];l=m,t.toneMapping=p.toneMapping,t.toneMappingExposure=p.toneMappingExposure,i.render.toneMapping=p.toneMapping,i.render.toneMappingExposure=p.toneMappingExposure,s({hemisphereIntensity:p.hemisphereIntensity,ambientIntensity:p.ambientIntensity}),u(p.environmentIntensity);let h=o.get()!==null;o.setAmbientOcclusion(p.ambientOcclusion),h&&o.rebuild(),n.traverse(H=>{if(H.userData.source!=="compute")return;let x=H,S=Array.isArray(x.material)?x.material:x.material?[x.material]:[];for(let A of S)"envMapIntensity"in A&&(A.envMapIntensity=p.envMapIntensity)}),a()},getMaterialAppearance:()=>Pe(l)}}import*as Tt from"three";function bt(e,n){let t=n.parentElement,r=t?t.clientWidth:window.innerWidth,i=t?t.clientHeight:window.innerHeight,o=new Tt.PerspectiveCamera(e.camera.fov,r/i,e.camera.near,e.camera.far),a=e.camera.position;return a&&o.position.set(a.x,a.y,a.z),o}import*as Me from"three";function vt(e){let n=new Me.Scene,t=typeof e.environment.backgroundColor=="string"?new Me.Color(e.environment.backgroundColor):e.environment.backgroundColor;return n.background=t||null,n}import*as yt from"three";function xt(e,n){ae(e,n),e.environment?.dispose(),e.background instanceof yt.Texture&&e.background.dispose()}import*as Ct from"three";import{EffectComposer as Wr}from"three/addons/postprocessing/EffectComposer.js";import{RenderPass as qr}from"three/addons/postprocessing/RenderPass.js";import{GTAOPass as Xr}from"three/addons/postprocessing/GTAOPass.js";import{SMAAPass as Kr}from"three/addons/postprocessing/SMAAPass.js";import{OutputPass as Yr}from"three/addons/postprocessing/OutputPass.js";import*as P from"three";import{Pass as Ur,FullScreenQuad as Br}from"three/addons/postprocessing/Pass.js";var ze={uniforms:{tDiffuse:{value:null},tNormal:{value:null},tDepth:{value:null},uResolution:{value:new P.Vector2(1,1)},uColor:{value:new P.Color(2236962)},uOpacity:{value:1},uNormalThreshold:{value:.4},uDepthThreshold:{value:.02},uThickness:{value:1},uNear:{value:.1},uFar:{value:1e3},uPerspective:{value:1}},vertexShader:`
56
55
  varying vec2 vUv;
57
56
  void main() {
58
57
  vUv = uv;
@@ -91,8 +90,8 @@ import{a as Kt,b as Yt,c as me,d as Zt,e as $t,g as Qt,h as Le,i as Ee,j as Oe,m
91
90
  float z2 = viewZOf(texture2D(tDepth, vUv + offsetB).x);
92
91
  float z3 = viewZOf(texture2D(tDepth, vUv - offsetB).x);
93
92
  float zCenter = viewZOf(texture2D(tDepth, vUv).x);
94
- // Normalized by center depth, not absolute Z: keeps the response scale-invariant across
95
- // the viewer's mm-to-m scenes (an absolute threshold would be noise far away, blind up close).
93
+ // Normalized by center depth, not absolute Z: keeps the response scale-invariant (an
94
+ // absolute threshold would be noise far away, blind up close).
96
95
  float depthDelta = (abs(z0 - z1) + abs(z2 - z3)) / max(abs(zCenter), 1e-6);
97
96
  float depthEdge = step(uDepthThreshold, depthDelta);
98
97
 
@@ -106,5 +105,5 @@ import{a as Kt,b as Yt,c as me,d as Zt,e as $t,g as Qt,h as Le,i as Ee,j as Oe,m
106
105
  float edge = max(depthEdge, normalEdge) * uOpacity;
107
106
  gl_FragColor = vec4(mix(color.rgb, uColor, edge), color.a);
108
107
  }
109
- `},Ae=class extends Qr{constructor(t,r,i,o,a={}){super();X(this,"camera");X(this,"scene");X(this,"normalMaterial");X(this,"edgeMaterial");X(this,"fsQuad");X(this,"normalTarget",null);X(this,"width");X(this,"height");this.scene=t,this.camera=r,this.width=Math.max(1,i),this.height=Math.max(1,o),this.normalMaterial=new O.MeshNormalMaterial,this.normalMaterial.blending=O.NoBlending,this.edgeMaterial=new O.ShaderMaterial({uniforms:O.UniformsUtils.clone(Ne.uniforms),vertexShader:Ne.vertexShader,fragmentShader:Ne.fragmentShader});let s=this.edgeMaterial.uniforms;s.uColor.value=new O.Color(a.color??2236962),s.uOpacity.value=a.opacity??1,s.uNormalThreshold.value=a.normalThreshold??.4,s.uDepthThreshold.value=a.depthThreshold??.02,s.uThickness.value=a.thickness??1,this.fsQuad=new Jr(this.edgeMaterial),this.needsSwap=!0}acquireNormalTarget(){if(!this.normalTarget){let t=new O.DepthTexture(this.width,this.height);this.normalTarget=new O.WebGLRenderTarget(this.width,this.height,{minFilter:O.NearestFilter,magFilter:O.NearestFilter,depthTexture:t})}return this.normalTarget}setSize(t,r){this.width=Math.max(1,t),this.height=Math.max(1,r),this.normalTarget?.setSize(this.width,this.height)}render(t,r,i){let o=this.acquireNormalTarget(),a=t.getRenderTarget(),s=t.autoClear,l=t.getClearColor(new O.Color),m=t.getClearAlpha(),f=this.scene.overrideMaterial;t.setRenderTarget(o),t.setClearColor(7829503,1),t.autoClear=!0,this.scene.overrideMaterial=this.normalMaterial,t.render(this.scene,this.camera),this.scene.overrideMaterial=f,t.setClearColor(l,m),t.autoClear=s;let E=this.edgeMaterial.uniforms;E.tDiffuse.value=i.texture,E.tNormal.value=o.texture,E.tDepth.value=o.depthTexture,E.uResolution.value.set(this.width,this.height);let g=this.camera;E.uPerspective.value=g.isPerspectiveCamera?1:0,E.uNear.value=this.camera.near??.1,E.uFar.value=this.camera.far??1e3,t.setRenderTarget(this.renderToScreen?null:r),this.fsQuad.render(t),t.setRenderTarget(a)}dispose(){this.normalTarget?.dispose(),this.normalMaterial.dispose(),this.edgeMaterial.dispose(),this.fsQuad.dispose()}};function Ot(e,n,t,r,i,o){let a=new en(e),s=new tn(n,t);a.addPass(s);let l=null;(o.ambientOcclusion??!0)&&(l=new rn(n,t,r,i),l.blendIntensity=o.aoIntensity??1,l.updateGtaoMaterial({screenSpaceRadius:!0}),a.addPass(l));let m=typeof o.edgeDetection=="object"?o.edgeDetection:{},f=new Ae(n,t,r,i,m);f.enabled=!!o.edgeDetection,a.addPass(f);let E=new nn;a.addPass(E);let g=new on;a.addPass(g),e.toneMapping=o.toneMapping,e.toneMappingExposure=o.toneMappingExposure;let u=o.aoPixelRatio??1;return a.setSize(r,i),{render:p=>a.render(p),setSize:(p,h,C)=>{a.setPixelRatio(Math.min(C,u)),a.setSize(p,h)},setCamera:p=>{if(s.camera=p,f.camera=p,!l)return;l.camera=p;let h=p.isPerspectiveCamera?1:0;l.gtaoMaterial.defines.PERSPECTIVE_CAMERA!==h&&(l.gtaoMaterial.defines.PERSPECTIVE_CAMERA=h,l.gtaoMaterial.needsUpdate=!0)},setEdgeDetection:p=>{f.enabled=p},edgeDetectionEnabled:()=>f.enabled,dispose:()=>{a.dispose(),l?.dispose(),f.dispose(),E.dispose(),g.dispose()}}}function It(e){let{renderer:n,scene:t,getActiveCamera:r,getCanvasSize:i,pixelRatio:o,config:a,requestRender:s}=e,l=null,m=!!a.render.ambientOcclusion,f=!1,E=!1,g=p=>{let{width:h,height:C}=i(),b=Ot(n,t,r(),Math.max(1,h),Math.max(1,C),{toneMapping:a.render.toneMapping??Ft.NeutralToneMapping,toneMappingExposure:a.render.toneMappingExposure??1,ambientOcclusion:p,aoIntensity:a.render.aoIntensity,aoPixelRatio:a.render.aoPixelRatio,edgeDetection:!1});return b.setSize(Math.max(1,h),Math.max(1,C),o),b},u=()=>{if(!(m||f)){l?.dispose(),l=null,s();return}(!l||E!==m)&&(l?.dispose(),l=g(m),E=m),l.setEdgeDetection(f),s()};return{get:()=>l,sync:u,rebuild:()=>{l?.dispose(),l=null,u()},setAmbientOcclusion:p=>{m=p,u()},setEdgeFallback:p=>{p!==f&&(f=p,u())},isEdgeFallbackActive:()=>f,dispose:()=>{l?.dispose(),l=null}}}import{OrbitControls as an}from"three/addons/controls/OrbitControls.js";function kt(e,n,t){let r=new an(e,n),i=t.camera.target;return i&&r.target.set(i.x,i.y,i.z),r.enableDamping=t.controls.enableDamping||!1,r.dampingFactor=t.controls.dampingFactor||.05,r.autoRotate=t.controls.autoRotate||!1,r.autoRotateSpeed=t.controls.autoRotateSpeed||.5,r.enableZoom=t.controls.enableZoom??!0,r.enablePan=t.controls.enablePan??!0,r.minDistance=t.controls.minDistance||.001,r.maxDistance=t.controls.maxDistance||1/0,r.screenSpacePanning=!1,r.maxPolarAngle=Math.PI,r.update(),r}import*as N from"three";import{HDRLoader as sn}from"three/addons/loaders/HDRLoader.js";function zt(e,n,t,r){t.environment.enableEnvironmentLighting?new sn().load(t.environment.hdrPath||"/baseHDR.hdr",function(i){if(r()){i.dispose();return}if(!i?.image){me().warn("HDR loaded without image data; skipping environment map."),i?.dispose(),t.events.onReady?.();return}i.mapping=N.EquirectangularReflectionMapping;let o=new N.PMREMGenerator(n);o.compileEquirectangularShader();let a=o.fromEquirectangular(i).texture;o.dispose(),e.environment=a,e.environmentIntensity=t.environment.environmentIntensity??1;let s=Xe(t.environment.sceneUp??W);e.environmentRotation.copy(s),t.environment.showEnvironment?(e.background=i,e.backgroundRotation.copy(s)):i.dispose(),t.events.onReady?.()},void 0,function(i){r()||(me().warn("HDR texture could not be loaded, falling back to basic lighting:",i),t.events.onReady?.())}):t.events.onReady?.()}function _t(e,n){let t=n.floor.size,r=new N.PlaneGeometry(t,t),i=typeof n.floor.color=="string"?new N.Color(n.floor.color):n.floor.color,o=new N.MeshStandardMaterial({color:i,roughness:n.floor.roughness,metalness:n.floor.metalness,side:N.DoubleSide}),a=new N.Mesh(r,o);a.userData.id="floor",a.name="floor";let s=(n.environment?.sceneUp||W).clone().normalize();a.quaternion.setFromUnitVectors(new N.Vector3(0,0,1),s),a.position.set(0,0,0),n.floor.receiveShadow&&n.render.enableShadows&&(a.receiveShadow=!0),e.add(a)}import*as F from"three";function Vt(e,n,t,r){let i=new Set,o=new Map,a=new F.Raycaster,s=new F.Vector2,l=new F.Vector2,m=()=>t.getActiveCamera(),f=d=>{let c=d;for(;c;){if(!c.visible)return!1;c=c.parent}return!0},E=()=>{let d=Q(n);if(d.isEmpty()){me().warn("No objects to fit to view");return}t.frameBounds(d,!1)},g=typeof r.events.selectionColor=="string"?new F.Color(r.events.selectionColor):r.events.selectionColor instanceof F.Color?r.events.selectionColor:new F.Color("#ff0000"),u=()=>{i.forEach(d=>{let c=d;if(o.has(d)){let R=o.get(d),T=c.material;T instanceof F.Material?T.dispose():Array.isArray(T)&&T.forEach(M=>M.dispose()),c.material=R,o.delete(d);let x=d;for(;x.parent;)x=x.parent;x!==n&&(R instanceof F.Material?R.dispose():R.forEach(M=>M.dispose()))}}),i.clear()},p=d=>{let c=d;if(!(c.material instanceof F.Material))return!1;o.set(d,c.material);let R=c.material.clone();return d instanceof F.Mesh&&"emissive"in R?R.emissive=g.clone():"color"in R&&(R.color=g.clone()),c.material=R,!0},h=()=>{let d=Q(n),c=d.isEmpty()?1:d.getSize(new F.Vector3).length();a.params.Points.threshold=c*.01},C=d=>{l.set(d.clientX,d.clientY)},b=d=>{let c=new F.Vector2(d.clientX,d.clientY);if(l.distanceTo(c)>5)return;let R=e.getBoundingClientRect();s.x=(d.clientX-R.left)/R.width*2-1,s.y=-((d.clientY-R.top)/R.height)*2+1,h(),a.setFromCamera(s,m());let T=a.intersectObjects(n.children,!0).filter(x=>f(x.object));if(T.length>0){let x=T[0].object;i.has(x)||(u(),i.add(x),p(x),r.events?.onObjectSelected?.(x),x instanceof F.Mesh&&Object.keys(x.userData).length>0&&r.events?.onMeshMetadataClicked?.(x.userData))}else u(),r.events?.onBackgroundClicked?.({x:s.x,y:s.y})},A=d=>{let c=e.getBoundingClientRect();s.x=(d.clientX-c.left)/c.width*2-1,s.y=-((d.clientY-c.top)/c.height)*2+1,h(),a.setFromCamera(s,m());let R=a.intersectObjects(n.children,!0).filter(M=>f(M.object));if(R.length===0)return;let T=R[0].object;if(r.events?.onMeshDoubleClicked?.(T),!r.events?.enableDoubleClickZoom)return;let x=new F.Box3().setFromObject(T);x.isEmpty()||t.frameBounds(x,!0)},S=d=>{if(r.events?.enableKeyboardControls)switch(d.key.toLowerCase()){case"f":d.preventDefault(),E();break;case"escape":d.preventDefault(),u();break;case" ":d.preventDefault(),E();break}};return r.events?.enableClickToFocus&&(e.addEventListener("mousedown",C),e.addEventListener("click",b),e.addEventListener("dblclick",A)),r.events?.enableKeyboardControls&&(e.setAttribute("tabindex","0"),e.addEventListener("keydown",S)),{dispose:()=>{e.removeEventListener("mousedown",C),e.removeEventListener("click",b),e.removeEventListener("dblclick",A),e.removeEventListener("keydown",S),u()},fitToView:E,clearSelection:u}}import*as te from"three";function jt(e,n){let t=new te.AmbientLight(n.lighting.ambientLightColor,n.lighting.ambientLightIntensity);e.add(t);let r=null;if(n.lighting.enableHemisphereLight){r=new te.HemisphereLight(n.lighting.hemisphereSkyColor,n.lighting.hemisphereGroundColor,n.lighting.hemisphereIntensity);let a=n.environment.sceneUp??W;r.position.copy(a),e.add(r)}if(!n.lighting.enableSunlight)return{ambient:t,hemisphere:r,sun:null};let i=new te.DirectionalLight(n.lighting.sunlightColor??16777215,n.lighting.sunlightIntensity),o=n.lighting.sunlightPosition;return o&&i.position.set(o.x,o.y,o.z),n.render.enableShadows?(i.castShadow=!0,i.shadow.mapSize.width=n.render.shadowMapSize||2048,i.shadow.mapSize.height=n.render.shadowMapSize||2048,i.shadow.bias=-1e-4,i.shadow.normalBias=.02,i.shadow.radius=4,e.add(i),e.add(i.target),{ambient:t,hemisphere:r,sun:i}):(e.add(i),{ambient:t,hemisphere:r,sun:null})}function Nt(e,n){if(n.isEmpty())return;let t=n.getCenter(new te.Vector3),r=n.getSize(new te.Vector3).length()*.5*1.2,i=e.shadow.camera;i.left=-r,i.right=r,i.top=r,i.bottom=-r,e.target.position.copy(t),e.target.updateMatrixWorld();let o=e.position.distanceTo(t);i.near=Math.max(r*.01,o-r),i.far=o+r,i.updateProjectionMatrix()}import*as pe from"three";function Gt(e,n,t){let r=new pe.WebGLRenderer({antialias:n.render.antialias,canvas:e,alpha:!0,powerPreference:"high-performance",preserveDrawingBuffer:n.render.preserveDrawingBuffer,logarithmicDepthBuffer:!1}),i=e.parentElement,o=i?i.clientWidth:window.innerWidth,a=i?i.clientHeight:window.innerHeight;return i&&(e.style.width="100%",e.style.height="100%",e.style.display="block"),r.setSize(o,a,!1),r.setPixelRatio(t),n.render.enableShadows&&(r.shadowMap.enabled=!0,r.shadowMap.type=pe.VSMShadowMap),r.toneMapping=n.render.toneMapping,r.toneMappingExposure=n.render.toneMappingExposure??1,r.outputColorSpace=pe.SRGBColorSpace,r.sortObjects=!0,r}var ln=function(e,n){let t=Ct(n||{}),r=t.environment?.sceneUp||W,i=t.render.pixelRatio??Math.min(window.devicePixelRatio,2),o=At(t),a=Dt(t,e);a.up.copy(r);let s=Gt(e,t,i);We(s.capabilities.getMaxAnisotropy()),n?.onMaxAnisotropy?.(s.capabilities.getMaxAnisotropy());let l=Be(),m=kt(a,e,t),f=Ke({scene:o,perspective:a,controls:m,onActiveCameraChange:()=>{},up:r}),E=()=>f.getActiveCamera(),g=!1;zt(o,s,t,()=>g);let u=jt(o,t),p=u.sun,h=()=>{p&&Nt(p,Q(o))};t.floor?.enabled&&_t(o,t);let C=t.floor?.enabled?o.children.find(H=>H.userData.id==="floor")??null:null,b=t.grid.enabled?ht({cellSize:t.grid.cellSize,majorEvery:t.grid.majorEvery,cellColor:t.grid.cellColor,majorColor:t.grid.majorColor,fadeDistance:t.grid.fadeDistance,plane:t.grid.plane}):null;b&&o.add(b.object);let A=()=>{b&&b.fitToContent(Q(o))},S=t.gizmo.enabled?xt({camera:a,domElement:e,controller:f}):null,I=t.grid.plane??xe(r),d=new Ut.Vector3(I==="x"?1:0,I==="y"?1:0,I==="z"?1:0),c=r.clone().normalize(),R=()=>{let H=[];return b?.object.visible&&H.push(d),t.floor.enabled&&C?.visible&&H.push(c),H},T=t.camera.dynamicNear?yt({camera:a,scene:o,groundNormals:R}):null,x=e.parentElement??e,M=t.measure.enabled?Rt(x,o):null,P=t.measure.enabled&&M?vt({canvas:e,scene:o,getActiveCamera:E,labelLayer:M,options:{snapPixels:t.measure.snapPixels,color:t.measure.color,labelClassName:t.measure.labelClassName,displayUnit:t.measure.displayUnit,format:t.measure.format}}):null,L=t.events.enableEventHandlers!==!1?Vt(e,o,f,t):{dispose:()=>{},fitToView:()=>{},clearSelection:()=>{}},Y=5,w=0,k=0,v=H=>{w=H.clientX,k=H.clientY},y=H=>Math.hypot(H.clientX-w,H.clientY-k)>Y,z=H=>{if(!y(H)){if(P?.handleClick(H)){H.stopImmediatePropagation();return}S?.handleClick(H)&&H.stopImmediatePropagation()}};(S||P)&&(e.addEventListener("mousedown",v,{capture:!0}),e.addEventListener("click",z,{capture:!0}));let j=H=>P?.handleMove(H);P&&e.addEventListener("mousemove",j,{passive:!0});let V=()=>{},G=H=>{Et(H,{color:t.edges.color,darken:t.edges.darken,width:t.edges.width,thresholdAngle:t.edges.thresholdAngle,distanceFade:t.edges.distanceFade,maxTriangles:t.edges.maxTriangles,maxSegments:t.edges.maxSegments}).then(()=>{be(H),V()})},be=H=>{if(t.edges.screenSpaceFallback===!1)return;let ae=!1;H.traverse(Xt=>{Xt.userData?.edgesSkipped===we&&(ae=!0)}),U.setEdgeFallback(ae)},Z=H=>{ft(H),U.setEdgeFallback(!1),V()},ee=e.parentElement,re=()=>ee?{width:ee.clientWidth,height:ee.clientHeight}:{width:window.innerWidth,height:window.innerHeight},U=It({renderer:s,scene:o,getActiveCamera:E,getCanvasSize:re,pixelRatio:i,config:t,requestRender:()=>V()});U.sync();let q=Mt({scene:o,renderer:s,lights:u,config:t,pipeline:U,requestRender:()=>V()}),{animate:ve,dispose:ie,invalidate:ue}=Ht(s,o,a,E,f,m,re,i,t.events.onFrame,b,S,()=>U.get(),M,T,t.render.onDemand??!0);V=ue,ve(),o.up.set(r.x,r.y,r.z),h(),A();let Pe=H=>{H.userData.source="user",o.add(H)},Bt=H=>{H.removeFromParent(),se(H)},Wt=()=>{o.children.filter(ae=>ae.userData.source==="user").forEach(ae=>{ae.removeFromParent(),se(ae)})},qt=()=>{g||(g=!0,ie(),L.dispose(),(S||P)&&(e.removeEventListener("mousedown",v,{capture:!0}),e.removeEventListener("click",z,{capture:!0})),P&&e.removeEventListener("mousemove",j),P?.dispose(),M?.dispose(),S?.dispose(),b?.dispose(),U.dispose(),f.dispose(),m.dispose(),s.dispose(),s.forceContextLoss(),Lt(o),l())};return{scene:o,camera:a,controls:m,renderer:s,cameraController:f,grid:b,gizmo:S,measureTool:P,applyEdges:G,clearEdges:Z,invalidate:ue,setAmbientOcclusion:U.setAmbientOcclusion,setLook:q.setLook,setFillLights:q.setFillLights,setEnvironmentIntensity:q.setEnvironmentIntensity,setToneMappingExposure:q.setToneMappingExposure,setAoIntensity:q.setAoIntensity,getMaterialAppearance:q.getMaterialAppearance,updateShadowBounds:h,updateGridScale:A,dispose:qt,fitToView:L.fitToView,clearSelection:L.clearSelection,addUserGeometry:Pe,removeUserGeometry:Bt,clearUserGeometry:Wt}};export{Le as DEFAULT_LOOK,Kt as ErrorCodes,Qt as LOOKS,Ee as LOOK_PRESETS,Yt as VisualizationError,$t as enableDebugLogging,me as getLogger,ln as initThree,Oe as materialAppearanceForLook,Zt as setLogger,Jt as updateScene};
108
+ `},Se=class extends Ur{constructor(t,r,i,o,a={}){super();Y(this,"camera");Y(this,"scene");Y(this,"normalMaterial");Y(this,"edgeMaterial");Y(this,"fsQuad");Y(this,"normalTarget",null);Y(this,"width");Y(this,"height");this.scene=t,this.camera=r,this.width=Math.max(1,i),this.height=Math.max(1,o),this.normalMaterial=new P.MeshNormalMaterial,this.normalMaterial.blending=P.NoBlending,this.edgeMaterial=new P.ShaderMaterial({uniforms:P.UniformsUtils.clone(ze.uniforms),vertexShader:ze.vertexShader,fragmentShader:ze.fragmentShader});let l=this.edgeMaterial.uniforms;l.uColor.value=new P.Color(a.color??2236962),l.uOpacity.value=a.opacity??1,l.uNormalThreshold.value=a.normalThreshold??.4,l.uDepthThreshold.value=a.depthThreshold??.02,l.uThickness.value=a.thickness??1,this.fsQuad=new Br(this.edgeMaterial),this.needsSwap=!0}acquireNormalTarget(){if(!this.normalTarget){let t=new P.DepthTexture(this.width,this.height);this.normalTarget=new P.WebGLRenderTarget(this.width,this.height,{minFilter:P.NearestFilter,magFilter:P.NearestFilter,depthTexture:t})}return this.normalTarget}setSize(t,r){this.width=Math.max(1,t),this.height=Math.max(1,r),this.normalTarget?.setSize(this.width,this.height)}render(t,r,i){let o=this.acquireNormalTarget(),a=t.getRenderTarget(),l=t.autoClear,s=t.getClearColor(new P.Color),u=t.getClearAlpha(),f=this.scene.overrideMaterial;t.setRenderTarget(o),t.setClearColor(7829503,1),t.autoClear=!0,this.scene.overrideMaterial=this.normalMaterial,t.render(this.scene,this.camera),this.scene.overrideMaterial=f,t.setClearColor(s,u),t.autoClear=l;let E=this.edgeMaterial.uniforms;E.tDiffuse.value=i.texture,E.tNormal.value=o.texture,E.tDepth.value=o.depthTexture,E.uResolution.value.set(this.width,this.height);let g=this.camera;E.uPerspective.value=g.isPerspectiveCamera?1:0,E.uNear.value=this.camera.near??.1,E.uFar.value=this.camera.far??1e3,t.setRenderTarget(this.renderToScreen?null:r),this.fsQuad.render(t),t.setRenderTarget(a)}dispose(){this.normalTarget?.dispose(),this.normalMaterial.dispose(),this.edgeMaterial.dispose(),this.fsQuad.dispose()}};function Ht(e,n,t,r,i,o){let a=new Wr(e),l=new qr(n,t);a.addPass(l);let s=null;(o.ambientOcclusion??!0)&&(s=new Xr(n,t,r,i),s.blendIntensity=o.aoIntensity??1,s.updateGtaoMaterial({screenSpaceRadius:!0}),a.addPass(s));let u=typeof o.edgeDetection=="object"?o.edgeDetection:{},f=new Se(n,t,r,i,u);f.enabled=!!o.edgeDetection,a.addPass(f);let E=new Kr;a.addPass(E);let g=new Yr;a.addPass(g),e.toneMapping=o.toneMapping,e.toneMappingExposure=o.toneMappingExposure;let m=o.aoPixelRatio??1;return a.setSize(r,i),{render:p=>a.render(p),setSize:(p,h,H)=>{a.setPixelRatio(Math.min(H,m)),a.setSize(p,h)},setCamera:p=>{if(l.camera=p,f.camera=p,!s)return;s.camera=p;let h=p.isPerspectiveCamera?1:0;s.gtaoMaterial.defines.PERSPECTIVE_CAMERA!==h&&(s.gtaoMaterial.defines.PERSPECTIVE_CAMERA=h,s.gtaoMaterial.needsUpdate=!0)},setEdgeDetection:p=>{f.enabled=p},edgeDetectionEnabled:()=>f.enabled,dispose:()=>{a.dispose(),s?.dispose(),f.dispose(),E.dispose(),g.dispose()}}}function wt(e){let{renderer:n,scene:t,getActiveCamera:r,getCanvasSize:i,pixelRatio:o,config:a,requestRender:l}=e,s=null,u=!!a.render.ambientOcclusion,f=!1,E=!1,g=p=>{let{width:h,height:H}=i(),x=Ht(n,t,r(),Math.max(1,h),Math.max(1,H),{toneMapping:a.render.toneMapping??Ct.NeutralToneMapping,toneMappingExposure:a.render.toneMappingExposure??1,ambientOcclusion:p,aoIntensity:a.render.aoIntensity,aoPixelRatio:a.render.aoPixelRatio,edgeDetection:!1});return x.setSize(Math.max(1,h),Math.max(1,H),o),x},m=()=>{if(!(u||f)){s?.dispose(),s=null,l();return}(!s||E!==u)&&(s?.dispose(),s=g(u),E=u),s.setEdgeDetection(f),l()};return{get:()=>s,sync:m,rebuild:()=>{s?.dispose(),s=null,m()},setAmbientOcclusion:p=>{u=p,m()},setEdgeFallback:p=>{p!==f&&(f=p,m())},isEdgeFallbackActive:()=>f,dispose:()=>{s?.dispose(),s=null}}}import{OrbitControls as Zr}from"three/addons/controls/OrbitControls.js";function Mt(e,n,t){let r=new Zr(e,n),i=t.camera.target;return i&&r.target.set(i.x,i.y,i.z),r.enableDamping=t.controls.enableDamping||!1,r.dampingFactor=t.controls.dampingFactor||.05,r.autoRotate=t.controls.autoRotate||!1,r.autoRotateSpeed=t.controls.autoRotateSpeed||.5,r.enableZoom=t.controls.enableZoom??!0,r.enablePan=t.controls.enablePan??!0,r.minDistance=t.controls.minDistance||.001,r.maxDistance=t.controls.maxDistance||1/0,r.screenSpacePanning=!1,r.maxPolarAngle=Math.PI,r.update(),r}import*as j from"three";import{HDRLoader as $r}from"three/addons/loaders/HDRLoader.js";function St(e,n,t,r){t.environment.enableEnvironmentLighting?new $r().load(t.environment.hdrPath||"/baseHDR.hdr",function(i){if(r()){i.dispose();return}if(!i?.image){de().warn("HDR loaded without image data; skipping environment map."),i?.dispose(),t.events.onReady?.();return}i.mapping=j.EquirectangularReflectionMapping;let o=new j.PMREMGenerator(n);o.compileEquirectangularShader();let a=o.fromEquirectangular(i).texture;o.dispose(),e.environment=a,e.environmentIntensity=t.environment.environmentIntensity??1;let l=Ne(t.environment.sceneUp??W);e.environmentRotation.copy(l),t.environment.showEnvironment?(e.background=i,e.backgroundRotation.copy(l)):i.dispose(),t.events.onReady?.()},void 0,function(i){r()||(de().warn("HDR texture could not be loaded, falling back to basic lighting:",i),t.events.onReady?.())}):t.events.onReady?.()}function Dt(e,n){let t=n.floor.size,r=new j.PlaneGeometry(t,t),i=typeof n.floor.color=="string"?new j.Color(n.floor.color):n.floor.color,o=new j.MeshStandardMaterial({color:i,roughness:n.floor.roughness,metalness:n.floor.metalness,side:j.DoubleSide}),a=new j.Mesh(r,o);a.userData.id="floor",a.name="floor";let l=(n.environment?.sceneUp||W).clone().normalize();a.quaternion.setFromUnitVectors(new j.Vector3(0,0,1),l),a.position.set(0,0,0),n.floor.receiveShadow&&n.render.enableShadows&&(a.receiveShadow=!0),e.add(a)}import*as L from"three";function At(e,n,t,r){let i=new Set,o=new Map,a=new L.Raycaster,l=new L.Vector2,s=new L.Vector2,u=()=>t.getActiveCamera(),f=d=>{let c=d;for(;c;){if(!c.visible)return!1;c=c.parent}return!0},E=()=>{let d=Q(n);if(d.isEmpty()){de().warn("No objects to fit to view");return}t.frameBounds(d,!1)},g=typeof r.events.selectionColor=="string"?new L.Color(r.events.selectionColor):r.events.selectionColor instanceof L.Color?r.events.selectionColor:new L.Color("#ff0000"),m=()=>{i.forEach(d=>{let c=d;if(o.has(d)){let R=o.get(d),T=c.material;T instanceof L.Material?T.dispose():Array.isArray(T)&&T.forEach(C=>C.dispose()),c.material=R,o.delete(d);let v=d;for(;v.parent;)v=v.parent;v!==n&&(R instanceof L.Material?R.dispose():R.forEach(C=>C.dispose()))}}),i.clear()},p=d=>{let c=d;if(!(c.material instanceof L.Material))return!1;o.set(d,c.material);let R=c.material.clone();return d instanceof L.Mesh&&"emissive"in R?R.emissive=g.clone():"color"in R&&(R.color=g.clone()),c.material=R,!0},h=()=>{let d=Q(n),c=d.isEmpty()?1:d.getSize(new L.Vector3).length();a.params.Points.threshold=c*.01},H=d=>{s.set(d.clientX,d.clientY)},x=d=>{let c=new L.Vector2(d.clientX,d.clientY);if(s.distanceTo(c)>5)return;let R=e.getBoundingClientRect();l.x=(d.clientX-R.left)/R.width*2-1,l.y=-((d.clientY-R.top)/R.height)*2+1,h(),a.setFromCamera(l,u());let T=a.intersectObjects(n.children,!0).filter(v=>f(v.object));if(T.length>0){let v=T[0].object;i.has(v)||(m(),i.add(v),p(v),r.events?.onObjectSelected?.(v),v instanceof L.Mesh&&Object.keys(v.userData).length>0&&r.events?.onMeshMetadataClicked?.(v.userData))}else m(),r.events?.onBackgroundClicked?.({x:l.x,y:l.y})},S=d=>{let c=e.getBoundingClientRect();l.x=(d.clientX-c.left)/c.width*2-1,l.y=-((d.clientY-c.top)/c.height)*2+1,h(),a.setFromCamera(l,u());let R=a.intersectObjects(n.children,!0).filter(C=>f(C.object));if(R.length===0)return;let T=R[0].object;if(r.events?.onMeshDoubleClicked?.(T),!r.events?.enableDoubleClickZoom)return;let v=new L.Box3().setFromObject(T);v.isEmpty()||t.frameBounds(v,!0)},A=d=>{if(r.events?.enableKeyboardControls)switch(d.key.toLowerCase()){case"f":d.preventDefault(),E();break;case"escape":d.preventDefault(),m();break;case" ":d.preventDefault(),E();break}};return r.events?.enableClickToFocus&&(e.addEventListener("mousedown",H),e.addEventListener("click",x),e.addEventListener("dblclick",S)),r.events?.enableKeyboardControls&&(e.setAttribute("tabindex","0"),e.addEventListener("keydown",A)),{dispose:()=>{e.removeEventListener("mousedown",H),e.removeEventListener("click",x),e.removeEventListener("dblclick",S),e.removeEventListener("keydown",A),m()},fitToView:E,clearSelection:m}}import*as J from"three";function Pt(e,n){let t=new J.AmbientLight(n.lighting.ambientLightColor,n.lighting.ambientLightIntensity);e.add(t);let r=null;if(n.lighting.enableHemisphereLight){r=new J.HemisphereLight(n.lighting.hemisphereSkyColor,n.lighting.hemisphereGroundColor,n.lighting.hemisphereIntensity);let a=n.environment.sceneUp??W;r.position.copy(a),e.add(r)}if(!n.lighting.enableSunlight)return{ambient:t,hemisphere:r,sun:null};let i=new J.DirectionalLight(n.lighting.sunlightColor??16777215,n.lighting.sunlightIntensity),o=n.lighting.sunlightPosition;return o&&i.position.set(o.x,o.y,o.z),n.render.enableShadows?(i.castShadow=!0,i.shadow.mapSize.width=n.render.shadowMapSize||2048,i.shadow.mapSize.height=n.render.shadowMapSize||2048,i.shadow.bias=-1e-4,i.shadow.normalBias=.02,i.shadow.radius=4,e.add(i),e.add(i.target),{ambient:t,hemisphere:r,sun:i}):(e.add(i),{ambient:t,hemisphere:r,sun:null})}function Lt(e,n){if(n.isEmpty())return;let t=n.getCenter(new J.Vector3),r=n.getSize(new J.Vector3).length()*.5*1.2,i=e.shadow.camera;i.left=-r,i.right=r,i.top=r,i.bottom=-r,e.target.position.copy(t),e.target.updateMatrixWorld();let o=e.position.distanceTo(t);i.near=Math.max(r*.01,o-r),i.far=o+r,i.updateProjectionMatrix()}import*as ue from"three";function Ot(e,n,t){let r=new ue.WebGLRenderer({antialias:n.render.antialias,canvas:e,alpha:!0,powerPreference:"high-performance",preserveDrawingBuffer:n.render.preserveDrawingBuffer,logarithmicDepthBuffer:!1}),i=e.parentElement,o=i?i.clientWidth:window.innerWidth,a=i?i.clientHeight:window.innerHeight;return i&&(e.style.width="100%",e.style.height="100%",e.style.display="block"),r.setSize(o,a,!1),r.setPixelRatio(t),n.render.enableShadows&&(r.shadowMap.enabled=!0,r.shadowMap.type=ue.VSMShadowMap),r.toneMapping=n.render.toneMapping,r.toneMappingExposure=n.render.toneMappingExposure??1,r.outputColorSpace=ue.SRGBColorSpace,r.sortObjects=!0,r}var Qr=function(e,n){let t=ht(n||{}),r=t.environment?.sceneUp||W,i=t.render.pixelRatio??Math.min(window.devicePixelRatio,2),o=vt(t),a=bt(t,e);a.up.copy(r);let l=Ot(e,t,i);_e(l.capabilities.getMaxAnisotropy()),n?.onMaxAnisotropy?.(l.capabilities.getMaxAnisotropy());let s=Mt(a,e,t),u=Ge({scene:o,perspective:a,controls:s,onActiveCameraChange:()=>{},up:r}),f=()=>u.getActiveCamera(),E=!1;St(o,l,t,()=>E);let g=Pt(o,t),m=g.sun,p=()=>{m&&Lt(m,Q(o))};t.floor?.enabled&&Dt(o,t);let h=t.floor?.enabled?o.children.find(w=>w.userData.id==="floor")??null:null,H=t.grid.enabled?st({cellSize:t.grid.cellSize,majorEvery:t.grid.majorEvery,cellColor:t.grid.cellColor,majorColor:t.grid.majorColor,fadeDistance:t.grid.fadeDistance,plane:t.grid.plane}):null;H&&o.add(H.object);let x=()=>{H&&H.fitToContent(Q(o))},S=t.gizmo.enabled?Et({camera:a,domElement:e,controller:u}):null,A=t.grid.plane??ve(r),V=new Ft.Vector3(A==="x"?1:0,A==="y"?1:0,A==="z"?1:0),d=r.clone().normalize(),c=()=>{let w=[];return H?.object.visible&&w.push(V),t.floor.enabled&&h?.visible&&w.push(d),w},R=t.camera.dynamicNear?pt({camera:a,scene:o,groundNormals:c}):null,T=e.parentElement??e,v=t.measure.enabled?ct(T,o):null,C=t.measure.enabled&&v?mt({canvas:e,scene:o,getActiveCamera:f,labelLayer:v,options:{snapPixels:t.measure.snapPixels,color:t.measure.color,labelClassName:t.measure.labelClassName,displayUnit:t.measure.displayUnit,format:t.measure.format}}):null,_=t.events.enableEventHandlers!==!1?At(e,o,u,t):{dispose:()=>{},fitToView:()=>{},clearSelection:()=>{}},F=5,q=0,M=0,O=w=>{q=w.clientX,M=w.clientY},y=w=>Math.hypot(w.clientX-q,w.clientY-M)>F,b=w=>{if(!y(w)){if(C?.handleClick(w)){w.stopImmediatePropagation();return}S?.handleClick(w)&&w.stopImmediatePropagation()}};(S||C)&&(e.addEventListener("mousedown",O,{capture:!0}),e.addEventListener("click",b,{capture:!0}));let I=w=>C?.handleMove(w);C&&e.addEventListener("mousemove",I,{passive:!0});let k=()=>{},N=w=>{it(w,{color:t.edges.color,darken:t.edges.darken,width:t.edges.width,thresholdAngle:t.edges.thresholdAngle,distanceFade:t.edges.distanceFade,maxTriangles:t.edges.maxTriangles,maxSegments:t.edges.maxSegments}).then(()=>{G(w),k()})},G=w=>{if(t.edges.screenSpaceFallback===!1)return;let ie=!1;w.traverse(zt=>{zt.userData?.edgesSkipped===He&&(ie=!0)}),U.setEdgeFallback(ie)},Re=w=>{at(w),U.setEdgeFallback(!1),k()},X=e.parentElement,ee=()=>X?{width:X.clientWidth,height:X.clientHeight}:{width:window.innerWidth,height:window.innerHeight},U=wt({renderer:l,scene:o,getActiveCamera:f,getCanvasSize:ee,pixelRatio:i,config:t,requestRender:()=>k()});U.sync();let K=Rt({scene:o,renderer:l,lights:g,config:t,pipeline:U,requestRender:()=>k()}),{animate:oe,dispose:Te,invalidate:te}=ft(l,o,a,f,u,s,ee,i,t.events.onFrame,H,S,()=>U.get(),v,R,t.render.onDemand??!0);k=te,oe(),o.up.set(r.x,r.y,r.z),p(),x();let me=w=>{w.userData.source="user",o.add(w)},De=w=>{w.removeFromParent(),ae(w)},It=()=>{o.children.filter(ie=>ie.userData.source==="user").forEach(ie=>{ie.removeFromParent(),ae(ie)})},kt=()=>{E||(E=!0,Te(),_.dispose(),(S||C)&&(e.removeEventListener("mousedown",O,{capture:!0}),e.removeEventListener("click",b,{capture:!0})),C&&e.removeEventListener("mousemove",I),C?.dispose(),v?.dispose(),S?.dispose(),H?.dispose(),U.dispose(),u.dispose(),s.dispose(),l.dispose(),l.forceContextLoss(),xt(o))};return{scene:o,camera:a,controls:s,renderer:l,cameraController:u,grid:H,gizmo:S,measureTool:C,applyEdges:N,clearEdges:Re,invalidate:te,setAmbientOcclusion:U.setAmbientOcclusion,setLook:K.setLook,setFillLights:K.setFillLights,setEnvironmentIntensity:K.setEnvironmentIntensity,setToneMappingExposure:K.setToneMappingExposure,setAoIntensity:K.setAoIntensity,getMaterialAppearance:K.getMaterialAppearance,updateShadowBounds:p,updateGridScale:x,dispose:kt,fitToView:_.fitToView,clearSelection:_.clearSelection,addUserGeometry:me,removeUserGeometry:De,clearUserGeometry:It}};export{Ae as DEFAULT_LOOK,Vt as ErrorCodes,Gt as LOOKS,pe as LOOK_PRESETS,_t as VisualizationError,Nt as enableDebugLogging,de as getLogger,Qr as initThree,Pe as materialAppearanceForLook,jt as setLogger,Ut as updateScene};
110
109
  //# sourceMappingURL=render.js.map