@selvajs/visualization 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +82 -65
- package/dist/parse.cjs +3 -3
- package/dist/parse.cjs.map +1 -1
- package/dist/parse.d.cts +15 -17
- package/dist/parse.d.ts +15 -17
- package/dist/parse.js +3 -3
- package/dist/parse.js.map +1 -1
- package/dist/render.cjs +4 -4
- package/dist/render.cjs.map +1 -1
- package/dist/render.d.cts +60 -7
- package/dist/render.d.ts +60 -7
- package/dist/render.js +4 -4
- package/dist/render.js.map +1 -1
- package/dist/scene.cjs +1 -1
- package/dist/scene.cjs.map +1 -1
- package/dist/scene.d.cts +70 -3
- package/dist/scene.d.ts +70 -3
- package/dist/scene.js +1 -1
- package/dist/scene.js.map +1 -1
- package/dist/types-C0V-dIU-.d.cts +83 -0
- package/dist/types-C0V-dIU-.d.ts +83 -0
- package/package.json +5 -5
- package/dist/types-Di80Y609.d.cts +0 -34
- package/dist/types-Di80Y609.d.ts +0 -34
package/dist/render.d.cts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as MaterialAppearanceOptions, i as LookPreset, n as Look, r as LookMaterialOverride, t as LOOKS } from "./types-C0V-dIU-.cjs";
|
|
2
2
|
import * as THREE from "three";
|
|
3
3
|
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
|
|
4
|
+
import "three/addons/lines/LineSegments2.js";
|
|
4
5
|
import { CSS2DObject } from "three/addons/renderers/CSS2DRenderer.js";
|
|
5
6
|
//#region src/shared/errors.d.ts
|
|
6
7
|
/**
|
|
@@ -53,8 +54,10 @@ declare const DEFAULT_LOOK: Look;
|
|
|
53
54
|
* Single source of truth for both `applyDefaults` (construction) and `setLook` (runtime), so the two
|
|
54
55
|
* can't drift.
|
|
55
56
|
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
57
|
+
* Every shaded look pairs a key light with contact shading (GTAO), because image-based lighting on
|
|
58
|
+
* its own lights all faces of a box nearly equally — the result is a white silhouette with no
|
|
59
|
+
* readable form. GTAO is a full-screen pass and does cost frames; `xray` skips it since there are no
|
|
60
|
+
* opaque contacts left to shade.
|
|
58
61
|
*/
|
|
59
62
|
declare const LOOK_PRESETS: Record<Look, LookPreset>;
|
|
60
63
|
/** Baked at parse time (not toggleable at runtime). */
|
|
@@ -159,7 +162,9 @@ type EdgesConfig = {
|
|
|
159
162
|
maxTriangles?: number;
|
|
160
163
|
/** Default 2M. */
|
|
161
164
|
maxSegments?: number;
|
|
162
|
-
/**
|
|
165
|
+
/** Max overlays attached per apply, default 1500. Past it, meshes fall back to the edge pass. */
|
|
166
|
+
maxOverlays?: number;
|
|
167
|
+
/** Fall back to the screen-space edge-detection pass for meshes the overlay path skipped. Default true. */
|
|
163
168
|
screenSpaceFallback?: boolean;
|
|
164
169
|
};
|
|
165
170
|
type ControlsConfig = {
|
|
@@ -292,6 +297,51 @@ interface CameraController {
|
|
|
292
297
|
dispose(): void;
|
|
293
298
|
}
|
|
294
299
|
//#endregion
|
|
300
|
+
//#region src/render/edges/options.d.ts
|
|
301
|
+
/** Crisp boundary/crease edges overlaid on meshes. See the layer README for depth/perf strategy. */
|
|
302
|
+
interface EdgeOptions {
|
|
303
|
+
/** Default: each overlay derives its color from its own mesh's material (see {@link DEFAULT_EDGE_COLOR}). */
|
|
304
|
+
color?: THREE.ColorRepresentation;
|
|
305
|
+
/** How far to darken the derived edge color toward black, 0-1 (default 0.75). No-op when `color` is set. */
|
|
306
|
+
darken?: number;
|
|
307
|
+
/** Edge thickness in CSS px. Default 1.5. */
|
|
308
|
+
width?: number;
|
|
309
|
+
/** Crease angle in degrees; an edge survives only where its two faces differ by more. Default 44. */
|
|
310
|
+
thresholdAngle?: number;
|
|
311
|
+
/**
|
|
312
|
+
* Fade an overlay out as its own edges crowd together on screen (default true). Edges draw at
|
|
313
|
+
* constant pixel width, so dense edges (e.g. millimetre-pitch laminations on sheet goods) merge
|
|
314
|
+
* into a dark smear at normal zoom; fading by edge density rather than mesh size catches that
|
|
315
|
+
* while leaving sparsely-edged geometry fully drawn.
|
|
316
|
+
*/
|
|
317
|
+
distanceFade?: boolean;
|
|
318
|
+
/**
|
|
319
|
+
* Skip meshes above this triangle count entirely (default 4M) — extraction time is linear in
|
|
320
|
+
* triangles, and past this bound even the worker path burns seconds for a look the screen-space
|
|
321
|
+
* fallback approximates at constant cost. Skipped meshes are tagged
|
|
322
|
+
* `userData.edgesSkipped = 'triangle-cap'`.
|
|
323
|
+
*/
|
|
324
|
+
maxTriangles?: number;
|
|
325
|
+
/**
|
|
326
|
+
* Above this many extracted segments (default 2M), an overlay drops the distance fade and renders
|
|
327
|
+
* opaque instead — millions of blended fat-line quads are a fill-rate cliff; opaque ones aren't.
|
|
328
|
+
*/
|
|
329
|
+
maxSegments?: number;
|
|
330
|
+
/**
|
|
331
|
+
* Attach at most this many overlays per apply (default 1500); past it every remaining mesh is
|
|
332
|
+
* skipped and tagged `userData.edgesSkipped = 'overlay-budget'`, which switches on the
|
|
333
|
+
* screen-space fallback.
|
|
334
|
+
*
|
|
335
|
+
* This is the count cap, and it catches what {@link maxTriangles} structurally cannot. That one
|
|
336
|
+
* is per mesh, so it only ever sees one mesh at a time and a 20-triangle mesh always clears it —
|
|
337
|
+
* yet an IFC model arrives as thousands of such meshes, and each overlay is a separate
|
|
338
|
+
* `LineSegments2` with its own draw call and per-frame resolution uniform. Cost tracks the number
|
|
339
|
+
* of overlays, not the triangles inside any one of them: measured on a 6043-mesh IFC house, the
|
|
340
|
+
* overlays alone were 60% of a 99ms frame.
|
|
341
|
+
*/
|
|
342
|
+
maxOverlays?: number;
|
|
343
|
+
}
|
|
344
|
+
//#endregion
|
|
295
345
|
//#region src/render/grid.d.ts
|
|
296
346
|
interface Grid {
|
|
297
347
|
/** Tagged `userData.id = 'grid'` so pick/fit code skips it. */
|
|
@@ -458,8 +508,11 @@ interface ThreeViewer {
|
|
|
458
508
|
/**
|
|
459
509
|
* No-op unless `edges.enabled`. Extraction runs off-thread for large meshes, so overlays can
|
|
460
510
|
* attach a beat later; meshes over `edges.maxTriangles` fall back to the screen-space edge shader.
|
|
511
|
+
*
|
|
512
|
+
* `overrides` applies to this call only, leaving the viewer's configured edge options alone —
|
|
513
|
+
* a line-drawing look wants `distanceFade: false` without changing what a later toggle does.
|
|
461
514
|
*/
|
|
462
|
-
applyEdges: (root: THREE.Object3D) => void;
|
|
515
|
+
applyEdges: (root: THREE.Object3D, overrides?: Partial<EdgeOptions>) => void;
|
|
463
516
|
/**
|
|
464
517
|
* Prefer over `removeEdges` directly — also cancels in-flight async attaches and stands down the
|
|
465
518
|
* screen-space edge fallback if active.
|
|
@@ -481,7 +534,7 @@ interface ThreeViewer {
|
|
|
481
534
|
* Retunes lighting/material (tone mapping, fill, IBL, AO) only — never edges/grid. Overwrites
|
|
482
535
|
* any granular lighting dials set earlier with the preset's values.
|
|
483
536
|
*/
|
|
484
|
-
setLook: (look:
|
|
537
|
+
setLook: (look: Look) => void;
|
|
485
538
|
/**
|
|
486
539
|
* Raising `hemisphereIntensity` is the most effective way to lift shadowed surfaces a dark HDR
|
|
487
540
|
* leaves black. Lazily creates the hemisphere light if the viewer was built without one; `0` turns
|
|
@@ -553,5 +606,5 @@ declare function isOwnedBy(object: THREE.Object3D, id?: string): boolean;
|
|
|
553
606
|
/** Replaces scene content with `meshes`, rescales the camera frustum to fit, and (first call only) positions the camera/controls. */
|
|
554
607
|
declare function updateScene(scene: THREE.Scene, meshes: THREE.Object3D[], camera: THREE.PerspectiveCamera, controls: OrbitControls, initialPositionSet: boolean): void;
|
|
555
608
|
//#endregion
|
|
556
|
-
export { type CameraConfig, type CameraController, type CameraProjection, type ControlsConfig, DEFAULT_LOOK, type EdgesConfig, type EnvironmentConfig, type ErrorCode, ErrorCodes, type EventConfig, type FloorConfig, type GizmoConfig, type Grid, type GridConfig, LOOKS, LOOK_PRESETS, type LabelHandle, type LabelLayer, type LightingConfig, type Logger, type Look, type LookPreset, type MaterialAppearanceOptions, type MeasureConfig, type MeasureTool, type PointerTool, type RenderConfig, SOURCE_COMPUTE, SOURCE_USER, type ThreeInitializerOptions, type ThreeViewer, type ToolRegistration, type ToolRegistry, type ViewGizmo, type ViewPreset, VisualizationError, appIdFromSource, appSource, enableDebugLogging, getLogger, initThree, isHostOwned, isOwnedBy, materialAppearanceForLook, pickThreshold, pointerToNdc, setLogger, snapToVertex, updateScene };
|
|
609
|
+
export { type CameraConfig, type CameraController, type CameraProjection, type ControlsConfig, DEFAULT_LOOK, type EdgesConfig, type EnvironmentConfig, type ErrorCode, ErrorCodes, type EventConfig, type FloorConfig, type GizmoConfig, type Grid, type GridConfig, LOOKS, LOOK_PRESETS, type LabelHandle, type LabelLayer, type LightingConfig, type Logger, type Look, type LookMaterialOverride, type LookPreset, type MaterialAppearanceOptions, type MeasureConfig, type MeasureTool, type PointerTool, type RenderConfig, SOURCE_COMPUTE, SOURCE_USER, type ThreeInitializerOptions, type ThreeViewer, type ToolRegistration, type ToolRegistry, type ViewGizmo, type ViewPreset, VisualizationError, appIdFromSource, appSource, enableDebugLogging, getLogger, initThree, isHostOwned, isOwnedBy, materialAppearanceForLook, pickThreshold, pointerToNdc, setLogger, snapToVertex, updateScene };
|
|
557
610
|
//# sourceMappingURL=render.d.cts.map
|
package/dist/render.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as MaterialAppearanceOptions, i as LookPreset, n as Look, r as LookMaterialOverride, t as LOOKS } from "./types-C0V-dIU-.js";
|
|
2
2
|
import * as THREE from "three";
|
|
3
|
+
import { LineSegments2 } from "three/addons/lines/LineSegments2.js";
|
|
3
4
|
import { CSS2DObject } from "three/addons/renderers/CSS2DRenderer.js";
|
|
4
5
|
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
|
|
5
6
|
//#region src/shared/errors.d.ts
|
|
@@ -53,8 +54,10 @@ declare const DEFAULT_LOOK: Look;
|
|
|
53
54
|
* Single source of truth for both `applyDefaults` (construction) and `setLook` (runtime), so the two
|
|
54
55
|
* can't drift.
|
|
55
56
|
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
57
|
+
* Every shaded look pairs a key light with contact shading (GTAO), because image-based lighting on
|
|
58
|
+
* its own lights all faces of a box nearly equally — the result is a white silhouette with no
|
|
59
|
+
* readable form. GTAO is a full-screen pass and does cost frames; `xray` skips it since there are no
|
|
60
|
+
* opaque contacts left to shade.
|
|
58
61
|
*/
|
|
59
62
|
declare const LOOK_PRESETS: Record<Look, LookPreset>;
|
|
60
63
|
/** Baked at parse time (not toggleable at runtime). */
|
|
@@ -159,7 +162,9 @@ type EdgesConfig = {
|
|
|
159
162
|
maxTriangles?: number;
|
|
160
163
|
/** Default 2M. */
|
|
161
164
|
maxSegments?: number;
|
|
162
|
-
/**
|
|
165
|
+
/** Max overlays attached per apply, default 1500. Past it, meshes fall back to the edge pass. */
|
|
166
|
+
maxOverlays?: number;
|
|
167
|
+
/** Fall back to the screen-space edge-detection pass for meshes the overlay path skipped. Default true. */
|
|
163
168
|
screenSpaceFallback?: boolean;
|
|
164
169
|
};
|
|
165
170
|
type ControlsConfig = {
|
|
@@ -292,6 +297,51 @@ interface CameraController {
|
|
|
292
297
|
dispose(): void;
|
|
293
298
|
}
|
|
294
299
|
//#endregion
|
|
300
|
+
//#region src/render/edges/options.d.ts
|
|
301
|
+
/** Crisp boundary/crease edges overlaid on meshes. See the layer README for depth/perf strategy. */
|
|
302
|
+
interface EdgeOptions {
|
|
303
|
+
/** Default: each overlay derives its color from its own mesh's material (see {@link DEFAULT_EDGE_COLOR}). */
|
|
304
|
+
color?: THREE.ColorRepresentation;
|
|
305
|
+
/** How far to darken the derived edge color toward black, 0-1 (default 0.75). No-op when `color` is set. */
|
|
306
|
+
darken?: number;
|
|
307
|
+
/** Edge thickness in CSS px. Default 1.5. */
|
|
308
|
+
width?: number;
|
|
309
|
+
/** Crease angle in degrees; an edge survives only where its two faces differ by more. Default 44. */
|
|
310
|
+
thresholdAngle?: number;
|
|
311
|
+
/**
|
|
312
|
+
* Fade an overlay out as its own edges crowd together on screen (default true). Edges draw at
|
|
313
|
+
* constant pixel width, so dense edges (e.g. millimetre-pitch laminations on sheet goods) merge
|
|
314
|
+
* into a dark smear at normal zoom; fading by edge density rather than mesh size catches that
|
|
315
|
+
* while leaving sparsely-edged geometry fully drawn.
|
|
316
|
+
*/
|
|
317
|
+
distanceFade?: boolean;
|
|
318
|
+
/**
|
|
319
|
+
* Skip meshes above this triangle count entirely (default 4M) — extraction time is linear in
|
|
320
|
+
* triangles, and past this bound even the worker path burns seconds for a look the screen-space
|
|
321
|
+
* fallback approximates at constant cost. Skipped meshes are tagged
|
|
322
|
+
* `userData.edgesSkipped = 'triangle-cap'`.
|
|
323
|
+
*/
|
|
324
|
+
maxTriangles?: number;
|
|
325
|
+
/**
|
|
326
|
+
* Above this many extracted segments (default 2M), an overlay drops the distance fade and renders
|
|
327
|
+
* opaque instead — millions of blended fat-line quads are a fill-rate cliff; opaque ones aren't.
|
|
328
|
+
*/
|
|
329
|
+
maxSegments?: number;
|
|
330
|
+
/**
|
|
331
|
+
* Attach at most this many overlays per apply (default 1500); past it every remaining mesh is
|
|
332
|
+
* skipped and tagged `userData.edgesSkipped = 'overlay-budget'`, which switches on the
|
|
333
|
+
* screen-space fallback.
|
|
334
|
+
*
|
|
335
|
+
* This is the count cap, and it catches what {@link maxTriangles} structurally cannot. That one
|
|
336
|
+
* is per mesh, so it only ever sees one mesh at a time and a 20-triangle mesh always clears it —
|
|
337
|
+
* yet an IFC model arrives as thousands of such meshes, and each overlay is a separate
|
|
338
|
+
* `LineSegments2` with its own draw call and per-frame resolution uniform. Cost tracks the number
|
|
339
|
+
* of overlays, not the triangles inside any one of them: measured on a 6043-mesh IFC house, the
|
|
340
|
+
* overlays alone were 60% of a 99ms frame.
|
|
341
|
+
*/
|
|
342
|
+
maxOverlays?: number;
|
|
343
|
+
}
|
|
344
|
+
//#endregion
|
|
295
345
|
//#region src/render/grid.d.ts
|
|
296
346
|
interface Grid {
|
|
297
347
|
/** Tagged `userData.id = 'grid'` so pick/fit code skips it. */
|
|
@@ -458,8 +508,11 @@ interface ThreeViewer {
|
|
|
458
508
|
/**
|
|
459
509
|
* No-op unless `edges.enabled`. Extraction runs off-thread for large meshes, so overlays can
|
|
460
510
|
* attach a beat later; meshes over `edges.maxTriangles` fall back to the screen-space edge shader.
|
|
511
|
+
*
|
|
512
|
+
* `overrides` applies to this call only, leaving the viewer's configured edge options alone —
|
|
513
|
+
* a line-drawing look wants `distanceFade: false` without changing what a later toggle does.
|
|
461
514
|
*/
|
|
462
|
-
applyEdges: (root: THREE.Object3D) => void;
|
|
515
|
+
applyEdges: (root: THREE.Object3D, overrides?: Partial<EdgeOptions>) => void;
|
|
463
516
|
/**
|
|
464
517
|
* Prefer over `removeEdges` directly — also cancels in-flight async attaches and stands down the
|
|
465
518
|
* screen-space edge fallback if active.
|
|
@@ -481,7 +534,7 @@ interface ThreeViewer {
|
|
|
481
534
|
* Retunes lighting/material (tone mapping, fill, IBL, AO) only — never edges/grid. Overwrites
|
|
482
535
|
* any granular lighting dials set earlier with the preset's values.
|
|
483
536
|
*/
|
|
484
|
-
setLook: (look:
|
|
537
|
+
setLook: (look: Look) => void;
|
|
485
538
|
/**
|
|
486
539
|
* Raising `hemisphereIntensity` is the most effective way to lift shadowed surfaces a dark HDR
|
|
487
540
|
* leaves black. Lazily creates the hemisphere light if the viewer was built without one; `0` turns
|
|
@@ -553,5 +606,5 @@ declare function isOwnedBy(object: THREE.Object3D, id?: string): boolean;
|
|
|
553
606
|
/** Replaces scene content with `meshes`, rescales the camera frustum to fit, and (first call only) positions the camera/controls. */
|
|
554
607
|
declare function updateScene(scene: THREE.Scene, meshes: THREE.Object3D[], camera: THREE.PerspectiveCamera, controls: OrbitControls, initialPositionSet: boolean): void;
|
|
555
608
|
//#endregion
|
|
556
|
-
export { type CameraConfig, type CameraController, type CameraProjection, type ControlsConfig, DEFAULT_LOOK, type EdgesConfig, type EnvironmentConfig, type ErrorCode, ErrorCodes, type EventConfig, type FloorConfig, type GizmoConfig, type Grid, type GridConfig, LOOKS, LOOK_PRESETS, type LabelHandle, type LabelLayer, type LightingConfig, type Logger, type Look, type LookPreset, type MaterialAppearanceOptions, type MeasureConfig, type MeasureTool, type PointerTool, type RenderConfig, SOURCE_COMPUTE, SOURCE_USER, type ThreeInitializerOptions, type ThreeViewer, type ToolRegistration, type ToolRegistry, type ViewGizmo, type ViewPreset, VisualizationError, appIdFromSource, appSource, enableDebugLogging, getLogger, initThree, isHostOwned, isOwnedBy, materialAppearanceForLook, pickThreshold, pointerToNdc, setLogger, snapToVertex, updateScene };
|
|
609
|
+
export { type CameraConfig, type CameraController, type CameraProjection, type ControlsConfig, DEFAULT_LOOK, type EdgesConfig, type EnvironmentConfig, type ErrorCode, ErrorCodes, type EventConfig, type FloorConfig, type GizmoConfig, type Grid, type GridConfig, LOOKS, LOOK_PRESETS, type LabelHandle, type LabelLayer, type LightingConfig, type Logger, type Look, type LookMaterialOverride, type LookPreset, type MaterialAppearanceOptions, type MeasureConfig, type MeasureTool, type PointerTool, type RenderConfig, SOURCE_COMPUTE, SOURCE_USER, type ThreeInitializerOptions, type ThreeViewer, type ToolRegistration, type ToolRegistry, type ViewGizmo, type ViewPreset, VisualizationError, appIdFromSource, appSource, enableDebugLogging, getLogger, initThree, isHostOwned, isOwnedBy, materialAppearanceForLook, pickThreshold, pointerToNdc, setLogger, snapToVertex, updateScene };
|
|
557
610
|
//# sourceMappingURL=render.d.ts.map
|
package/dist/render.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{a as e,c as t,d as n,l as r,r as i,s as a,t as o,u as s}from"./gpu-dispose-Dkj-BKt4.js";import*as c from"three";import{Line2 as l}from"three/addons/lines/Line2.js";import{LineGeometry as u}from"three/addons/lines/LineGeometry.js";import{LineMaterial as d}from"three/addons/lines/LineMaterial.js";import{LineSegments2 as f}from"three/addons/lines/LineSegments2.js";import{LineSegmentsGeometry as p}from"three/addons/lines/LineSegmentsGeometry.js";import{CSS2DObject as m,CSS2DRenderer as h}from"three/addons/renderers/CSS2DRenderer.js";import{ViewHelper as g}from"three/addons/helpers/ViewHelper.js";import{EffectComposer as _}from"three/addons/postprocessing/EffectComposer.js";import{RenderPass as v}from"three/addons/postprocessing/RenderPass.js";import{GTAOPass as y}from"three/addons/postprocessing/GTAOPass.js";import{SMAAPass as b}from"three/addons/postprocessing/SMAAPass.js";import{OutputPass as x}from"three/addons/postprocessing/OutputPass.js";import{FullScreenQuad as S,Pass as C}from"three/addons/postprocessing/Pass.js";import{OrbitControls as w}from"three/addons/controls/OrbitControls.js";import{HDRLoader as T}from"three/addons/loaders/HDRLoader.js";const E=[`technical`,`studio`,`showcase`],D=`technical`,O={studio:{toneMapping:c.ACESFilmicToneMapping,toneMappingExposure:1,envMapIntensity:1,environmentIntensity:1,hemisphereIntensity:.75,ambientIntensity:.4,cullBackfaces:!1,ambientOcclusion:!1},technical:{toneMapping:c.NeutralToneMapping,toneMappingExposure:1,envMapIntensity:.9,environmentIntensity:1,hemisphereIntensity:.35,ambientIntensity:.25,cullBackfaces:!1,ambientOcclusion:!1},showcase:{toneMapping:c.ACESFilmicToneMapping,toneMappingExposure:1.15,envMapIntensity:1.4,environmentIntensity:1.25,hemisphereIntensity:.35,ambientIntensity:.15,cullBackfaces:!1,ambientOcclusion:!1}};function k(e){let t=O[e];return{envMapIntensity:t.envMapIntensity,cullBackfaces:t.cullBackfaces}}const A=`compute`,j=`user`,M=`app:`;function N(e){return`${M}${e}`}function P(e){return typeof e!=`string`||!e.startsWith(M)?null:e.slice(4)||null}function F(e){let t=e.userData?.source;return t===`user`||P(t)!==null}function ee(e,t){return t===void 0?F(e):e.userData?.source===N(t)}function I(e){let t=e.clone().normalize(),n=new c.Vector3(0,0,1),r=new c.Vector3(0,1,0),i=Math.abs(t.dot(n))>.9?r:n,a=new c.Vector3().crossVectors(i,t).normalize();return{up:t,forward:new c.Vector3().crossVectors(t,a).normalize(),right:a}}function L(e,t){let{forward:n,right:r,up:i}=I(e);return n.clone().multiplyScalar(-1).add(r.clone().multiplyScalar(-1)).add(i).normalize().multiplyScalar(t)}function R(e,t,n){let{forward:r,right:i,up:a}=I(e);return i.clone().multiplyScalar(t).add(r.clone().multiplyScalar(t)).add(a.clone().multiplyScalar(n))}function te(e){let t=e.clone().normalize(),n=new c.Vector3(0,1,0);if(t.dot(n)>.9999)return new c.Euler;if(t.dot(n)<-.9999)return new c.Euler(Math.PI,0,0);let r=new c.Quaternion().setFromUnitVectors(n,t);return new c.Euler().setFromQuaternion(r)}function ne(e){let t=Math.abs(e.x),n=Math.abs(e.y),r=Math.abs(e.z);return t>=n&&t>=r?`x`:n>=r?`y`:`z`}const z={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 re(t,n,r,i,a){if(W(t),n.length===0)return;n.forEach(e=>{t.add(e)});let o=e(n),s=o.getCenter(new c.Vector3),l=o.getSize(new c.Vector3),u=Math.max(l.x,l.y,l.z);if(u/Math.min(l.x||1,l.y||1,l.z||1)>z.SCALE_RATIO_THRESHOLD||u>z.HUGE_THRESHOLD?(r.near=u*z.NEAR_PLANE_FACTOR.TINY,r.far=u*z.FAR_PLANE_FACTOR.HUGE):u>z.LARGE_THRESHOLD?(r.near=u*z.NEAR_PLANE_FACTOR.SMALL,r.far=u*z.FAR_PLANE_FACTOR.LARGE):(r.near=Math.max(.01,u*z.NEAR_PLANE_FACTOR.NORMAL),r.far=Math.max(2e3,u*z.FAR_PLANE_FACTOR.NORMAL)),r.updateProjectionMatrix(),!a){let e=u*z.INITIAL_DISTANCE_MULTIPLIER;r.position.copy(s).add(L(r.up,e)),i.target.copy(s),i.update()}}const B=new Set([`grid`,`floor`,`label-layer`,`measure`]);function V(e){let t=e;for(;t;){if(typeof t.userData.id==`string`&&B.has(t.userData.id))return!0;t=t.parent}return!1}function H(e){e.updateMatrixWorld(!0);let t=new c.Box3;return e.traverse(e=>{let n=e;e.visible&&!V(e)&&n.geometry&&t.expandByObject(e)}),t}const U=new Set([`floor`,`grid`,`label-layer`]);function W(e){[...e.children].forEach(e=>{U.has(e.userData.id)||F(e)||(o(e),e.removeFromParent())})}function ie(e){let{up:t,forward:n,right:r}=I(e),i=n.clone().negate(),a=r.clone();return{top:t.clone(),bottom:t.clone().negate(),front:i.clone(),back:i.clone().negate(),right:a.clone(),left:a.clone().negate(),iso:i.clone().multiplyScalar(1.2).add(a.clone()).add(t.clone()).normalize()}}function ae(e){let{scene:t,perspective:n,controls:r,onActiveCameraChange:i}=e,a=(e.up??n.up).clone().normalize(),o=ie(a),s=new c.OrthographicCamera(-1,1,1,-1,n.near,n.far);s.up.copy(a);let l=`perspective`,u=n.aspect,d=()=>l===`perspective`?n:s,f=null,p=()=>{f?.cancel(),f=null},m=()=>{let e=(l===`orthographic`?s:n).position.distanceTo(r.target)*Math.tan(n.fov*Math.PI/360),t=e*u;s.left=-t,s.right=t,s.top=e,s.bottom=-e,s.near=n.near,s.far=n.far,s.updateProjectionMatrix()},h=e=>{if(e!==l){if(p(),e===`orthographic`)s.position.copy(n.position),s.up.copy(n.up),s.lookAt(r.target),s.zoom=1,m();else{let e=(s.top-s.bottom)/(2*s.zoom)/Math.tan(n.fov*Math.PI/360),t=s.position.clone().sub(r.target);t.lengthSq()<1e-12&&t.copy(a),t.normalize(),n.position.copy(r.target).add(t.multiplyScalar(e))}l=e,r.object=d(),r.update(),i(d())}},g=(e,t,i,o)=>{let c=n.fov*(Math.PI/180),u=t/(2*Math.tan(c/2))*1.5,h=oe(i,a),g=e.clone().add(h.clone().multiplyScalar(u)),_=d();l===`orthographic`&&(s.zoom=1),p(),o?f=se(_,r,g,e,()=>{l===`orthographic`&&m()}):(_.position.copy(g),r.target.copy(e),l===`orthographic`&&m(),r.update())},_=(e,n=!0)=>{let i=H(t),a=i.isEmpty()?r.target.clone():i.getCenter(new c.Vector3),o=i.isEmpty()?new c.Vector3(1,1,1):i.getSize(new c.Vector3),s=Math.max(o.x,o.y,o.z)||1;g(a,s,e,n)};return{getActiveCamera:d,getProjection:()=>l,setProjection:h,toggleProjection:()=>(h(l===`perspective`?`orthographic`:`perspective`),l),setView:(e,t=!0)=>{_(o[e],t)},setViewDirection:_,frameBounds:(e,t=!0)=>{if(e.isEmpty())return;let n=e.getCenter(new c.Vector3),i=e.getSize(new c.Vector3),a=Math.max(i.x,i.y,i.z)||1,s=d().position.clone().sub(r.target);s.lengthSq()<1e-12&&s.copy(o.iso),g(n,a,s.normalize(),t)},setRotateEnabled:e=>{r.enableRotate=e},isRotateEnabled:()=>r.enableRotate,updateAspect:(e,t)=>{u=t===0?u:e/t,l===`orthographic`&&m()},dispose:p}}function oe(e,t){let{up:n,forward:r}=I(t),i=e.clone().normalize();if(Math.abs(i.dot(n))<.9999)return e;let a=r.clone().negate(),o=.5*Math.PI/180;return i.multiplyScalar(Math.cos(o)).add(a.multiplyScalar(Math.sin(o))).normalize()}const G=e=>1-(1-e)**3;function se(e,t,n,r,i,a=250){let o=e.position.clone(),s=t.target.clone(),c=performance.now(),l=null,u=()=>{l=null;let d=G(Math.min((performance.now()-c)/a,1));e.position.lerpVectors(o,n,d),t.target.lerpVectors(s,r,d),i(),t.update(),d<1&&(l=requestAnimationFrame(u))};return l=requestAnimationFrame(u),{cancel:()=>{l!==null&&(cancelAnimationFrame(l),l=null)}}}function ce(e){let t=Math.floor(e.length/6);if(t===0)return 1/0;let n=Math.max(1,Math.ceil(t/4096)),r=[];for(let i=0;i<t;i+=n){let t=i*6,n=Math.hypot(e[t+3]-e[t],e[t+4]-e[t+1],e[t+5]-e[t+2]);n>0&&r.push(n)}return r.length===0?1/0:(r.sort((e,t)=>e-t),r[Math.min(r.length-1,Math.floor(r.length*.15))])}function le(e){let t=new p;return t.setPositions(e),{geometry:t,segmentCount:e.length/6,edgeSpacing:ce(e)}}function K(e,t,n){let r=1e4,i=67108864,a=Math.cos(Math.PI/180*n),o=e.length/3;if(o>=i)throw Error(`extractEdgeSegments: ${o} vertices exceeds 2^26 limit`);let s=new Float64Array(o),c=new Float64Array(o),l=new Float64Array(o);for(let t=0;t<o;t++)s[t]=Math.round(e[3*t]*r),c[t]=Math.round(e[3*t+1]*r),l[t]=Math.round(e[3*t+2]*r);let u=16;for(;u<o*2;)u<<=1;let d=u-1,f=new Int32Array(u).fill(-1),p=new Int32Array(o);for(let e=0;e<o;e++){let t=(Math.imul(s[e]|0,73856093)^Math.imul(c[e]|0,19349663)^Math.imul(l[e]|0,83492791))&d;for(;;){let n=f[t];if(n===-1){f[t]=e,p[e]=e;break}if(s[n]===s[e]&&c[n]===c[e]&&l[n]===l[e]){p[e]=n;break}t=t+1&d}}let m=new Float32Array(4096),h=0,g=(t,n)=>{if(h+6>m.length){let e=new Float32Array(m.length*2);e.set(m),m=e}m[h++]=e[3*t],m[h++]=e[3*t+1],m[h++]=e[3*t+2],m[h++]=e[3*n],m[h++]=e[3*n+1],m[h++]=e[3*n+2]},_=new Map,v=[],y=[],b=[],x=(t?t.length:o)/3;for(let n=0;n<x;n++){let r=t?t[3*n]:3*n,o=t?t[3*n+1]:3*n+1,s=t?t[3*n+2]:3*n+2,c=p[r],l=p[o],u=p[s];if(c===l||l===u||u===c)continue;let d=e[3*s]-e[3*o],f=e[3*s+1]-e[3*o+1],m=e[3*s+2]-e[3*o+2],h=e[3*r]-e[3*o],x=e[3*r+1]-e[3*o+1],S=e[3*r+2]-e[3*o+2],C=f*S-m*x,w=m*h-d*S,T=d*x-f*h,E=C*C+w*w+T*T;if(E>0){let e=1/Math.sqrt(E);C*=e,w*=e,T*=e}else C=0,w=0,T=0;for(let e=0;e<3;e++){let t,n,d,f;e===0?(t=r,n=o,d=c,f=l):e===1?(t=o,n=s,d=l,f=u):(t=s,n=r,d=u,f=c);let p=f*i+d,m=_.get(p);if(m!==void 0&&m!==-1)C*b[3*m]+w*b[3*m+1]+T*b[3*m+2]<=a&&g(t,n),_.set(p,-1);else{let e=d*i+f;if(!_.has(e)){let r=v.length;_.set(e,r),v.push(t),y.push(n),b.push(C,w,T)}}}}for(let e of _.values())e!==-1&&g(v[e],y[e]);return m.slice(0,h)}function ue(){return[`const extract = ${K.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
|
-
`)}const de=`edge-overlay`;function fe(e){return{forcedColor:e.color==null?null:new c.Color(e.color),darken:c.MathUtils.clamp(e.darken??.75,0,1),width:e.width??1.5,thresholdAngle:e.thresholdAngle??44,distanceFade:e.distanceFade??!0,maxTriangles:e.maxTriangles??4e6,maxSegments:e.maxSegments??2e6}}function
|
|
1
|
+
import{a as e,c as t,d as n,l as r,r as i,s as a,t as o,u as s}from"./gpu-dispose-Dkj-BKt4.js";import*as c from"three";import{Line2 as l}from"three/addons/lines/Line2.js";import{LineGeometry as u}from"three/addons/lines/LineGeometry.js";import{LineMaterial as d}from"three/addons/lines/LineMaterial.js";import{LineSegments2 as f}from"three/addons/lines/LineSegments2.js";import{LineSegmentsGeometry as p}from"three/addons/lines/LineSegmentsGeometry.js";import{CSS2DObject as m,CSS2DRenderer as h}from"three/addons/renderers/CSS2DRenderer.js";import{ViewHelper as g}from"three/addons/helpers/ViewHelper.js";import{EffectComposer as _}from"three/addons/postprocessing/EffectComposer.js";import{RenderPass as v}from"three/addons/postprocessing/RenderPass.js";import{GTAOPass as y}from"three/addons/postprocessing/GTAOPass.js";import{SMAAPass as b}from"three/addons/postprocessing/SMAAPass.js";import{OutputPass as x}from"three/addons/postprocessing/OutputPass.js";import{FullScreenQuad as S,Pass as C}from"three/addons/postprocessing/Pass.js";import{OrbitControls as w}from"three/addons/controls/OrbitControls.js";import{HDRLoader as T}from"three/addons/loaders/HDRLoader.js";const E=[`technical`,`studio`,`showcase`,`arctic`,`xray`,`lineart`,`wireframe`],D=`technical`,O={studio:{toneMapping:c.ACESFilmicToneMapping,toneMappingExposure:1,envMapIntensity:1,environmentIntensity:.85,hemisphereIntensity:.5,ambientIntensity:.25,cullBackfaces:!1,ambientOcclusion:!0,sunlightIntensity:1.6},technical:{toneMapping:c.NeutralToneMapping,toneMappingExposure:1,envMapIntensity:.55,environmentIntensity:.6,hemisphereIntensity:.25,ambientIntensity:.15,cullBackfaces:!1,ambientOcclusion:!0,sunlightIntensity:2.2},showcase:{toneMapping:c.ACESFilmicToneMapping,toneMappingExposure:1.15,envMapIntensity:1.4,environmentIntensity:1,hemisphereIntensity:.2,ambientIntensity:.1,cullBackfaces:!1,ambientOcclusion:!0,sunlightIntensity:2.6},arctic:{toneMapping:c.NeutralToneMapping,toneMappingExposure:1.05,envMapIntensity:.85,environmentIntensity:1.1,hemisphereIntensity:.3,ambientIntensity:.15,cullBackfaces:!1,ambientOcclusion:!0,sunlightIntensity:2,materialOverride:{color:15659509,metalness:0,roughness:.75}},xray:{toneMapping:c.NeutralToneMapping,toneMappingExposure:1.3,envMapIntensity:.4,environmentIntensity:.8,hemisphereIntensity:.6,ambientIntensity:.6,cullBackfaces:!1,ambientOcclusion:!1,sunlightIntensity:.6,materialOverride:{color:10470632,metalness:0,roughness:.9,opacity:.28,depthWrite:!1}},lineart:{toneMapping:c.NeutralToneMapping,toneMappingExposure:1,envMapIntensity:1,environmentIntensity:1,hemisphereIntensity:.6,ambientIntensity:3.2,cullBackfaces:!1,ambientOcclusion:!1,sunlightIntensity:0,requiresEdges:!0,materialOverride:{color:16251130,metalness:0,roughness:1}},wireframe:{toneMapping:c.NeutralToneMapping,toneMappingExposure:1,envMapIntensity:1,environmentIntensity:1,hemisphereIntensity:.4,ambientIntensity:2,cullBackfaces:!1,ambientOcclusion:!1,sunlightIntensity:0,materialOverride:{color:2830648,metalness:0,roughness:1,wireframe:!0}}};function k(e){let t=O[e];return{envMapIntensity:t.envMapIntensity,cullBackfaces:t.cullBackfaces}}const A=`compute`,j=`user`,M=`app:`;function N(e){return`${M}${e}`}function P(e){return typeof e!=`string`||!e.startsWith(M)?null:e.slice(4)||null}function F(e){let t=e.userData?.source;return t===`user`||P(t)!==null}function ee(e,t){return t===void 0?F(e):e.userData?.source===N(t)}function I(e){let t=e.clone().normalize(),n=new c.Vector3(0,0,1),r=new c.Vector3(0,1,0),i=Math.abs(t.dot(n))>.9?r:n,a=new c.Vector3().crossVectors(i,t).normalize();return{up:t,forward:new c.Vector3().crossVectors(t,a).normalize(),right:a}}function L(e,t){let{forward:n,right:r,up:i}=I(e);return n.clone().multiplyScalar(-1).add(r.clone().multiplyScalar(-1)).add(i).normalize().multiplyScalar(t)}function R(e,t,n){let{forward:r,right:i,up:a}=I(e);return i.clone().multiplyScalar(t).add(r.clone().multiplyScalar(t)).add(a.clone().multiplyScalar(n))}function te(e){let t=e.clone().normalize(),n=new c.Vector3(0,1,0);if(t.dot(n)>.9999)return new c.Euler;if(t.dot(n)<-.9999)return new c.Euler(Math.PI,0,0);let r=new c.Quaternion().setFromUnitVectors(n,t);return new c.Euler().setFromQuaternion(r)}function ne(e){let t=Math.abs(e.x),n=Math.abs(e.y),r=Math.abs(e.z);return t>=n&&t>=r?`x`:n>=r?`y`:`z`}const z={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 re(t,n,r,i,a){if(W(t),n.length===0)return;n.forEach(e=>{t.add(e)});let o=e(n),s=o.getCenter(new c.Vector3),l=o.getSize(new c.Vector3),u=Math.max(l.x,l.y,l.z);if(u/Math.min(l.x||1,l.y||1,l.z||1)>z.SCALE_RATIO_THRESHOLD||u>z.HUGE_THRESHOLD?(r.near=u*z.NEAR_PLANE_FACTOR.TINY,r.far=u*z.FAR_PLANE_FACTOR.HUGE):u>z.LARGE_THRESHOLD?(r.near=u*z.NEAR_PLANE_FACTOR.SMALL,r.far=u*z.FAR_PLANE_FACTOR.LARGE):(r.near=Math.max(.01,u*z.NEAR_PLANE_FACTOR.NORMAL),r.far=Math.max(2e3,u*z.FAR_PLANE_FACTOR.NORMAL)),r.updateProjectionMatrix(),!a){let e=u*z.INITIAL_DISTANCE_MULTIPLIER;r.position.copy(s).add(L(r.up,e)),i.target.copy(s),i.update()}}const B=new Set([`grid`,`floor`,`label-layer`,`measure`]);function V(e){let t=e;for(;t;){if(typeof t.userData.id==`string`&&B.has(t.userData.id))return!0;t=t.parent}return!1}function H(e){e.updateMatrixWorld(!0);let t=new c.Box3;return e.traverse(e=>{let n=e;e.visible&&!V(e)&&n.geometry&&t.expandByObject(e)}),t}const U=new Set([`floor`,`grid`,`label-layer`]);function W(e){[...e.children].forEach(e=>{U.has(e.userData.id)||F(e)||(o(e),e.removeFromParent())})}function ie(e){let{up:t,forward:n,right:r}=I(e),i=n.clone().negate(),a=r.clone();return{top:t.clone(),bottom:t.clone().negate(),front:i.clone(),back:i.clone().negate(),right:a.clone(),left:a.clone().negate(),iso:i.clone().multiplyScalar(1.2).add(a.clone()).add(t.clone()).normalize()}}function ae(e){let{scene:t,perspective:n,controls:r,onActiveCameraChange:i}=e,a=(e.up??n.up).clone().normalize(),o=ie(a),s=new c.OrthographicCamera(-1,1,1,-1,n.near,n.far);s.up.copy(a);let l=`perspective`,u=n.aspect,d=()=>l===`perspective`?n:s,f=null,p=()=>{f?.cancel(),f=null},m=()=>{let e=(l===`orthographic`?s:n).position.distanceTo(r.target)*Math.tan(n.fov*Math.PI/360),t=e*u;s.left=-t,s.right=t,s.top=e,s.bottom=-e,s.near=n.near,s.far=n.far,s.updateProjectionMatrix()},h=e=>{if(e!==l){if(p(),e===`orthographic`)s.position.copy(n.position),s.up.copy(n.up),s.lookAt(r.target),s.zoom=1,m();else{let e=(s.top-s.bottom)/(2*s.zoom)/Math.tan(n.fov*Math.PI/360),t=s.position.clone().sub(r.target);t.lengthSq()<1e-12&&t.copy(a),t.normalize(),n.position.copy(r.target).add(t.multiplyScalar(e))}l=e,r.object=d(),r.update(),i(d())}},g=(e,t,i,o)=>{let c=n.fov*(Math.PI/180),u=t/(2*Math.tan(c/2))*1.5,h=oe(i,a),g=e.clone().add(h.clone().multiplyScalar(u)),_=d();l===`orthographic`&&(s.zoom=1),p(),o?f=se(_,r,g,e,()=>{l===`orthographic`&&m()}):(_.position.copy(g),r.target.copy(e),l===`orthographic`&&m(),r.update())},_=(e,n=!0)=>{let i=H(t),a=i.isEmpty()?r.target.clone():i.getCenter(new c.Vector3),o=i.isEmpty()?new c.Vector3(1,1,1):i.getSize(new c.Vector3),s=Math.max(o.x,o.y,o.z)||1;g(a,s,e,n)};return{getActiveCamera:d,getProjection:()=>l,setProjection:h,toggleProjection:()=>(h(l===`perspective`?`orthographic`:`perspective`),l),setView:(e,t=!0)=>{_(o[e],t)},setViewDirection:_,frameBounds:(e,t=!0)=>{if(e.isEmpty())return;let n=e.getCenter(new c.Vector3),i=e.getSize(new c.Vector3),a=Math.max(i.x,i.y,i.z)||1,s=d().position.clone().sub(r.target);s.lengthSq()<1e-12&&s.copy(o.iso),g(n,a,s.normalize(),t)},setRotateEnabled:e=>{r.enableRotate=e},isRotateEnabled:()=>r.enableRotate,updateAspect:(e,t)=>{u=t===0?u:e/t,l===`orthographic`&&m()},dispose:p}}function oe(e,t){let{up:n,forward:r}=I(t),i=e.clone().normalize();if(Math.abs(i.dot(n))<.9999)return e;let a=r.clone().negate(),o=.5*Math.PI/180;return i.multiplyScalar(Math.cos(o)).add(a.multiplyScalar(Math.sin(o))).normalize()}const G=e=>1-(1-e)**3;function se(e,t,n,r,i,a=250){let o=e.position.clone(),s=t.target.clone(),c=performance.now(),l=null,u=()=>{l=null;let d=G(Math.min((performance.now()-c)/a,1));e.position.lerpVectors(o,n,d),t.target.lerpVectors(s,r,d),i(),t.update(),d<1&&(l=requestAnimationFrame(u))};return l=requestAnimationFrame(u),{cancel:()=>{l!==null&&(cancelAnimationFrame(l),l=null)}}}function ce(e){let t=Math.floor(e.length/6);if(t===0)return 1/0;let n=Math.max(1,Math.ceil(t/4096)),r=[];for(let i=0;i<t;i+=n){let t=i*6,n=Math.hypot(e[t+3]-e[t],e[t+4]-e[t+1],e[t+5]-e[t+2]);n>0&&r.push(n)}return r.length===0?1/0:(r.sort((e,t)=>e-t),r[Math.min(r.length-1,Math.floor(r.length*.15))])}function le(e){let t=new p;return t.setPositions(e),{geometry:t,segmentCount:e.length/6,edgeSpacing:ce(e)}}function K(e,t,n){let r=1e4,i=67108864,a=Math.cos(Math.PI/180*n),o=e.length/3;if(o>=i)throw Error(`extractEdgeSegments: ${o} vertices exceeds 2^26 limit`);let s=new Float64Array(o),c=new Float64Array(o),l=new Float64Array(o);for(let t=0;t<o;t++)s[t]=Math.round(e[3*t]*r),c[t]=Math.round(e[3*t+1]*r),l[t]=Math.round(e[3*t+2]*r);let u=16;for(;u<o*2;)u<<=1;let d=u-1,f=new Int32Array(u).fill(-1),p=new Int32Array(o);for(let e=0;e<o;e++){let t=(Math.imul(s[e]|0,73856093)^Math.imul(c[e]|0,19349663)^Math.imul(l[e]|0,83492791))&d;for(;;){let n=f[t];if(n===-1){f[t]=e,p[e]=e;break}if(s[n]===s[e]&&c[n]===c[e]&&l[n]===l[e]){p[e]=n;break}t=t+1&d}}let m=new Float32Array(4096),h=0,g=(t,n)=>{if(h+6>m.length){let e=new Float32Array(m.length*2);e.set(m),m=e}m[h++]=e[3*t],m[h++]=e[3*t+1],m[h++]=e[3*t+2],m[h++]=e[3*n],m[h++]=e[3*n+1],m[h++]=e[3*n+2]},_=new Map,v=[],y=[],b=[],x=(t?t.length:o)/3;for(let n=0;n<x;n++){let r=t?t[3*n]:3*n,o=t?t[3*n+1]:3*n+1,s=t?t[3*n+2]:3*n+2,c=p[r],l=p[o],u=p[s];if(c===l||l===u||u===c)continue;let d=e[3*s]-e[3*o],f=e[3*s+1]-e[3*o+1],m=e[3*s+2]-e[3*o+2],h=e[3*r]-e[3*o],x=e[3*r+1]-e[3*o+1],S=e[3*r+2]-e[3*o+2],C=f*S-m*x,w=m*h-d*S,T=d*x-f*h,E=C*C+w*w+T*T;if(E>0){let e=1/Math.sqrt(E);C*=e,w*=e,T*=e}else C=0,w=0,T=0;for(let e=0;e<3;e++){let t,n,d,f;e===0?(t=r,n=o,d=c,f=l):e===1?(t=o,n=s,d=l,f=u):(t=s,n=r,d=u,f=c);let p=f*i+d,m=_.get(p);if(m!==void 0&&m!==-1)C*b[3*m]+w*b[3*m+1]+T*b[3*m+2]<=a&&g(t,n),_.set(p,-1);else{let e=d*i+f;if(!_.has(e)){let r=v.length;_.set(e,r),v.push(t),y.push(n),b.push(C,w,T)}}}}for(let e of _.values())e!==-1&&g(v[e],y[e]);return m.slice(0,h)}function ue(){return[`const extract = ${K.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
|
+
`)}const de=`edge-overlay`;function fe(e){return{forcedColor:e.color==null?null:new c.Color(e.color),darken:c.MathUtils.clamp(e.darken??.75,0,1),width:e.width??1.5,thresholdAngle:e.thresholdAngle??44,distanceFade:e.distanceFade??!0,maxTriangles:e.maxTriangles??4e6,maxSegments:e.maxSegments??2e6,maxOverlays:e.maxOverlays??1500}}function pe(e){let t=e.getAttribute(`position`);return t?(e.index?e.index.count:t.count)/3:0}function me(e){let t=e.getAttribute(`position`);if(!t||t.isInterleavedBufferAttribute||t.itemSize!==3||!(t.array instanceof Float32Array)||t.count>=67108864)return null;let n=e.index;return n&&!(n.array instanceof Uint32Array)&&!(n.array instanceof Uint16Array)?null:{positions:t.array,index:n?n.array:null}}function he(e,t){let n=4096,r=2166136261,i=e=>{r^=e,r=Math.imul(r,16777619)},a=new Uint32Array(e.positions.buffer,e.positions.byteOffset,e.positions.length),o=Math.min(n,a.length);for(let e=0;e<o;e++)i(a[e]);for(let e=Math.max(o,a.length-n);e<a.length;e++)i(a[e]);let s=0;if(e.index){s=e.index.length;let t=Math.min(n,s);for(let n=0;n<t;n++)i(e.index[n]);for(let r=Math.max(t,s-n);r<s;r++)i(e.index[r])}return`${t}:${e.positions.length}:${s}:${r>>>0}`}function ge(e,t){let n=new c.EdgesGeometry(e,t),r=n.attributes.position?n.attributes.position.array:new Float32Array;return n.dispose(),r}function _e(e,t){let n=me(e);return n?K(n.positions,n.index,t):ge(e,t)}let q;const J=new Map;let ve=1;function ye(){if(q!==void 0)return q;if(typeof Worker>`u`||typeof Blob>`u`||typeof URL>`u`||typeof URL.createObjectURL!=`function`)return q=null,null;try{let e=URL.createObjectURL(new Blob([ue()],{type:`text/javascript`})),t=new Worker(e);t.onmessage=e=>{let{id:t,segments:n,error:r}=e.data,i=J.get(t);i&&(J.delete(t),n?i.resolve(n):i.reject(Error(r??`edge extraction failed in worker`)))},t.onerror=()=>{for(let e of J.values())e.reject(Error(`edge extraction worker crashed`));J.clear(),t.terminate(),q=null},q=t}catch{q=null}return q}function be(e,t,n){return new Promise((r,i)=>{let a=ve++;J.set(a,{resolve:r,reject:i});let o=t.positions.slice(),s=t.index?t.index.slice():null,c=[o.buffer];s&&c.push(s.buffer),e.postMessage({id:a,positions:o,index:s,thresholdAngle:n},c)})}const Y=new Map;function xe(e,t){let n=me(e);if(!n||pe(e)<25e3)return Promise.resolve(_e(e,t));let r=he(n,t),i=Y.get(r);if(i)return i;let a=ye();if(!a)return Promise.resolve(_e(e,t));let o=be(a,n,t).catch(()=>K(n.positions,n.index,t)).finally(()=>{Y.delete(r)});return Y.set(r,o),o}function Se(e,t){let n=(Array.isArray(e.material)?e.material[0]:e.material)?.color;return n?n.clone().multiplyScalar(1-t):new c.Color(2236962)}var Ce=class{options;byKey=new Map;constructor(e){this.options=e}for(e,t){let n=this.options.forcedColor??Se(e,this.options.darken),r=n.getHex()*2+ +!!t,i=this.byKey.get(r);return i||(i=we(n,this.options.width,t),this.byKey.set(r,i)),i}disposeUnused(e){let t=new Set(e.map(e=>e.material));for(let e of this.byKey.values())t.has(e)||e.dispose()}};function we(e,t,n){let r=new d({color:e});return r.linewidth=t,r.polygonOffset=!0,r.polygonOffsetFactor=0,r.polygonOffsetUnits=-1,n&&(r.transparent=!0),r}function Te(e,t,n){let r=new f(e.geometry,t);return r.userData.kind=de,r.raycast=()=>{},n&&ke(r,e.edgeSpacing),r}const Ee=new c.Vector3,De=new c.Vector3;function Oe(e,t,n){e.geometry.boundingSphere||e.geometry.computeBoundingSphere();let r=e.geometry.boundingSphere;if(!r)return 1/0;if(t.isPerspectiveCamera){let i=t;Ee.copy(r.center).applyMatrix4(e.matrixWorld);let a=De.setFromMatrixPosition(t.matrixWorld).distanceTo(Ee);if(a<=r.radius*e.matrixWorld.getMaxScaleOnAxis())return 1/0;let o=Math.tan(c.MathUtils.degToRad(i.fov)*.5),s=2*a*o;return s>0?n/s:1/0}if(t.isOrthographicCamera){let e=t,r=(e.top-e.bottom)/e.zoom;return r>0?n/r:1/0}return 1/0}function ke(e,t){e.onBeforeRender=(n,r,i)=>{f.prototype.onBeforeRender.call(e,n);let a=e.material,o=t*Oe(e,i,a.resolution.y);a.opacity=c.MathUtils.clamp((o-1)/3,0,1)}}function Ae(e){return e.userData?.kind===de}function je(e,t){let n=[],r=0;e.traverse(e=>{if(e instanceof c.Mesh&&e.userData.id!==`floor`&&e.userData.id!==`grid`&&e.userData.kind!==`edge-overlay`){if(e.children.some(e=>e.userData?.kind===`edge-overlay`)){r++;return}if(e.geometry){if(pe(e.geometry)>t.maxTriangles){e.userData.edgesSkipped=`triangle-cap`;return}n.push(e)}}});let i=Math.max(0,t.maxOverlays-r),a=n.slice(0,i);for(let e of a)delete e.userData.edgesSkipped;for(let e of n.slice(i))e.userData.edgesSkipped=`overlay-budget`;return n.length>i&&console.debug(`[edges] overlay budget reached: ${n.length} meshes want overlays, ${i} allowed — the rest fall back to the screen-space edge pass.`),a}function Me(e,t,n,r){let i=r.distanceFade&&t.segmentCount<=r.maxSegments,a=Te(t,n.for(e,i),i);return e.add(a),a}const Ne=new WeakMap;function X(e){return Ne.get(e)??0}function Pe(e,t){for(let n=e;n;n=n.parent)if(n===t)return!0;return!1}async function Fe(e,t={}){let n=fe(t),r=new Ce(n),i=X(e),a=[],o=je(e,n).map(async t=>{let o=await xe(t.geometry,n.thresholdAngle);X(e)===i&&Pe(t,e)&&(t.children.some(e=>e.userData?.kind===`edge-overlay`)||a.push(Me(t,le(o),r,n)))});return await Promise.all(o),r.disposeUnused(a),a}function Ie(e){Ne.set(e,X(e)+1);let t=[];e.traverse(e=>{e instanceof f&&Ae(e)&&t.push(e)});let n=new Set;for(let e of t)e.geometry.dispose(),n.add(e.material),e.removeFromParent();return n.forEach(e=>e.dispose()),t.length}function Le(e){if(!(e>0)||!Number.isFinite(e))return 1;let t=10**Math.floor(Math.log10(e)),n=e/t;return(n>=5?5:n>=2?2:1)*t}function Re(e={}){let{cellSize:t=1,majorEvery:n=10,cellColor:r=8947848,majorColor:i=4473924,fadeDistance:a=100,plane:o=`y`}=e,s=o===`y`?new c.Vector2(0,2):o===`z`?new c.Vector2(0,1):new c.Vector2(1,2),l=2.5,u=new c.PlaneGeometry(1,1);o===`y`?u.rotateX(-Math.PI/2):o===`x`&&u.rotateY(Math.PI/2);let d=new c.ShaderMaterial({vertexShader:`
|
|
3
3
|
varying vec3 vWorldPos;
|
|
4
4
|
void main() {
|
|
5
5
|
vec4 world = modelMatrix * vec4(position, 1.0);
|
|
@@ -50,7 +50,7 @@ import{a as e,c as t,d as n,l as r,r as i,s as a,t as o,u as s}from"./gpu-dispos
|
|
|
50
50
|
if (alpha < 0.001) discard;
|
|
51
51
|
gl_FragColor = vec4(color, alpha);
|
|
52
52
|
}
|
|
53
|
-
`,transparent:!0,depthWrite:!1,side:c.DoubleSide,uniforms:{uAxes:{value:s},uCell:{value:t},uMajor:{value:n},uCellColor:{value:new c.Color(r)},uMajorColor:{value:new c.Color(i)},uCenter:{value:new c.Vector3},uFade:{value:a}}}),f=new c.Mesh(u,d);f.name=`grid`,f.userData.id=`grid`,f.renderOrder=-1;let p=a,m=a*l,h=new c.Vector3;return{object:f,update:e=>{o===`y`?(f.position.set(e.x,0,e.z),h.set(e.x,0,e.z)):o===`z`?(f.position.set(e.x,e.y,0),h.set(e.x,e.y,0)):(f.position.set(0,e.y,e.z),h.set(0,e.y,e.z)),d.uniforms.uCenter.value.copy(h),f.scale.setScalar(m)},fitToContent:e=>{if(e.isEmpty())return;let t=e.getSize(new c.Vector3),n=(e,t)=>t===0?e.x:t===1?e.y:e.z,r=Math.max(n(t,s.x),n(t,s.y));!(r>0)||!Number.isFinite(r)||(d.uniforms.uCell.value=Ie(r/20),p=r*2,d.uniforms.uFade.value=p,m=p*l)},setVisible:e=>{f.visible=e},dispose:()=>{f.removeFromParent(),u.dispose(),d.dispose()}}}function Re(e,t){let n=new h,r=n.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};n.setSize(i.width,i.height);let a=new c.Group;a.name=`label-layer`,a.userData.id=`label-layer`,t.add(a);let o=new Set;return{addLabel:(e,t,n)=>{let r=document.createElement(`div`);r.textContent=e,n?r.className=n:Object.assign(r.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`}),r.style.pointerEvents=`none`;let i=new m(r);return i.position.copy(t),a.add(i),o.add(i),{object:i,setPosition:e=>i.position.copy(e),setText:e=>{r.textContent=e},remove:()=>{i.removeFromParent(),r.remove(),o.delete(i)}}},render:(e,t)=>n.render(e,t),setSize:(e,t)=>n.setSize(e,t),dispose:()=>{o.forEach(e=>{e.removeFromParent(),e.element.remove()}),o.clear(),a.removeFromParent(),r.remove()}}}const ze=.015,Be={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 Ve(e){let t=e&&Be[e]||Be.Meters;return e=>`${(e/t.metersPerUnit).toPrecision(3)} ${t.suffix}`}function He(e,t){if(e.isOrthographicCamera){let t=e;return Math.abs(t.top-t.bottom)/(t.zoom||1)*ze}return((t?e.position.distanceTo(t):e.position.length())||1)*ze}function Ue(e){let t=e.object;if(t instanceof c.Mesh)return e.face?[e.face.a,e.face.b,e.face.c]:null;if(t instanceof c.Points)return e.index==null?null:[e.index];if(t instanceof c.Line){if(e.index==null)return null;let n=t.geometry.index;return n?e.index+1>=n.count?null:[n.getX(e.index),n.getX(e.index+1)]:[e.index,e.index+1]}return null}function We(e,t,n,r){let i=e.point.clone(),a=e.object,o=Ue(e);if(!o||!a.geometry)return i;let s=a.geometry.attributes.position;if(!s)return i;let l=e=>{let r=e.clone().project(t);return new c.Vector2((r.x+1)/2*n.width,(1-r.y)/2*n.height)},u=l(i),d=i,f=r;for(let e of o){if(e>=s.count)continue;let t=new c.Vector3().fromBufferAttribute(s,e).applyMatrix4(a.matrixWorld),n=l(t).distanceTo(u);n<f&&(f=n,d=t)}return d}function Ge(e){let{canvas:t,scene:n,getActiveCamera:r,getViewTarget:i,labelLayer:a,options:o={}}=e,s=o.snapPixels??12,f=new c.Color(o.color??16763904),p=Ve(o.displayUnit),m=o.format??((e,t)=>`${p(e)}\nΔx ${p(t.x)} Δy ${p(t.y)} Δz ${p(t.z)}`),h=new c.Raycaster,g=new c.Vector2,_=!1,v=[],y=[],b=null,x=null,S=new c.PointsMaterial({color:f,size:8,sizeAttenuation:!1,depthTest:!1}),C=new c.PointsMaterial({color:f,size:11,sizeAttenuation:!1,depthTest:!1,transparent:!0,opacity:.5}),w=null,T=e=>{if(!e){w&&(w.visible=!1);return}if(!w){let e=new c.BufferGeometry;e.setAttribute(`position`,new c.Float32BufferAttribute([0,0,0],3)),w=new c.Points(e,C),w.renderOrder=1e3,w.userData.id=`measure`,w.raycast=()=>{},n.add(w)}w.position.copy(e),w.visible=!0},E=e=>{let t=new c.BufferGeometry;t.setAttribute(`position`,new c.Float32BufferAttribute([e.x,e.y,e.z],3));let r=new c.Points(t,S);return r.renderOrder=999,r.userData.id=`measure`,r.raycast=()=>{},n.add(r),r},D=()=>{v.length=0,y.forEach(e=>{e.geometry.dispose(),e.removeFromParent()}),y.length=0,b&&=(b.geometry.dispose(),b.material.dispose(),b.removeFromParent(),null),x?.remove(),x=null},O=()=>{if(v.length!==2)return;let[e,t]=v,r=new u;r.setPositions([e.x,e.y,e.z,t.x,t.y,t.z]);let i=new d({color:f});i.linewidth=2,i.depthTest=!1,b=new l(r,i),b.renderOrder=998,b.userData.id=`measure`,b.raycast=()=>{},n.add(b);let s=e.clone().add(t).multiplyScalar(.5),p=new c.Vector3(Math.abs(t.x-e.x),Math.abs(t.y-e.y),Math.abs(t.z-e.z));x=a.addLabel(m(e.distanceTo(t),p),s,o.labelClassName)},k=e=>{let a=t.getBoundingClientRect();g.x=(e.clientX-a.left)/a.width*2-1,g.y=-((e.clientY-a.top)/a.height)*2+1;let o=r();h.setFromCamera(g,o);let c=He(o,i?.());h.params.Line.threshold=c,h.params.Points.threshold=c;let l=h.intersectObjects(n.children,!0).filter(e=>e.object.userData.id!==`measure`&&e.object.userData.id!==`grid`);return l.length===0?null:We(l[0],o,{width:a.width,height:a.height},s)},A=null,j=0,M=()=>{j&&=(cancelAnimationFrame(j),0),A=null};return{setEnabled:e=>{_=e,e||(M(),D(),T(null))},isEnabled:()=>_,handleClick:e=>{if(!_)return!1;v.length===2&&D();let t=k(e);return t===null||(v.push(t),y.push(E(t)),v.length===2&&O(),!0)},handleMove:e=>{_&&(A=e,!j&&(j=requestAnimationFrame(()=>{j=0;let e=A;A=null,!(!_||!e)&&T(k(e))})))},clear:D,dispose:()=>{M(),D(),w&&=(w.geometry.dispose(),w.removeFromParent(),null),S.dispose(),C.dispose()}}}const Ke=[];function qe({camera:e,scene:t,groundNormals:n=()=>Ke}){let r=e.near,i=e.near,a=new c.Vector3,o=new c.Vector3;return{update:()=>{e.near!==i&&(r=e.near);let s=H(t),l=r;if(!s.isEmpty()){let t=s.getSize(o).length()*.5,i=e.position.distanceTo(s.getCenter(a))-t;for(let t of n())i=Math.min(i,Math.abs(e.position.dot(t)));l=c.MathUtils.clamp(i*.5,r,e.far*.01)}Math.abs(l-i)>i*.05&&(e.near=l,e.updateProjectionMatrix(),i=l)}}}function Je(){let e=[],t=null,n=()=>e.sort((e,t)=>t.priority-e.priority),r=t=>e.findIndex(e=>e.id===t),i=n=>{let i=r(n);i!==-1&&(e.splice(i,1),t===n&&(t=null))};return{register:({id:t,tool:r,priority:a=0})=>(i(t),e.push({id:t,tool:r,priority:a}),n(),()=>i(t)),unregister:i,get:t=>e[r(t)]?.tool??null,setActive:n=>{t=n;for(let t of e)t.tool.setEnabled?.(t.id===n)},getActive:()=>t,handleClick:t=>{for(let n of[...e])if(n.tool.handleClick(t))return!0;return!1},handleMove:t=>{for(let n of[...e])n.tool.handleMove?.(t)}}}function Ye(e,t){let n=t.getBoundingClientRect();return{x:(e.clientX-n.left)/n.width*2-1,y:-((e.clientY-n.top)/n.height)*2+1}}function Xe(e){let{camera:t,domElement:n,controller:r}=e,i=new g(t,n);i.setLabels(`X`,`Y`,`Z`);let a=!0,o=new c.Raycaster,s=new c.OrthographicCamera(-2,2,2,-2,0,4);s.position.set(0,0,2),s.updateMatrixWorld();let l={posX:new c.Vector3(1,0,0),negX:new c.Vector3(-1,0,0),posY:new c.Vector3(0,1,0),negY:new c.Vector3(0,-1,0),posZ:new c.Vector3(0,0,1),negZ:new c.Vector3(0,0,-1)},u=e=>{let r=n.getBoundingClientRect(),a=r.left+n.offsetWidth-128-i.location.right,u=r.top+n.offsetHeight-128-i.location.bottom,d=new c.Vector2((e.clientX-a)/128*2-1,-((e.clientY-u)/128)*2+1);if(Math.abs(d.x)>1||Math.abs(d.y)>1)return null;i.quaternion.copy(t.quaternion).invert(),i.updateMatrixWorld(),o.setFromCamera(d,s);let f=o.intersectObjects(i.children,!1);for(let e of f){let t=e.object.userData?.type;if(typeof t==`string`&&t in l)return t}return null};return{render:e=>{if(!a)return;let t=e.autoClear;e.autoClear=!1,i.render(e),e.autoClear=t},handleClick:e=>{if(!a)return!1;let t=u(e);return t?(r.getProjection()===`orthographic`&&r.setProjection(`perspective`),r.setViewDirection(l[t],!1),!0):!1},setVisible:e=>{a=e},isVisible:()=>a,dispose:()=>i.dispose()}}function Ze(e,t,n,r,i,a,o,s,l,u,d,f,p,m,h=!0){let g=null,_=performance.now(),v=!0,y=0,b=new c.Matrix4,x=new c.Matrix4,S=null,C=()=>{v=!0},w=e=>{e.updateMatrixWorld();let t=S!==e||!b.equals(e.matrixWorld)||!x.equals(e.projectionMatrix);return t&&(S=e,b.copy(e.matrixWorld),x.copy(e.projectionMatrix)),t},T=e.domElement,E=[`pointerdown`,`pointerup`,`wheel`];if(h)for(let e of E)T.addEventListener(e,C,{passive:!0});let D=()=>{let{width:t,height:r}=o();if(t===0||r===0)return;let a=Math.floor(t*s),c=Math.floor(r*s);(e.domElement.width!==a||e.domElement.height!==c)&&(e.setPixelRatio(s),e.setSize(t,r,!1),n.aspect=t/r,n.updateProjectionMatrix(),i.updateAspect(t,r),f?.()?.setSize(t,r,s),p?.setSize(t,r),C())},O=(n,r)=>{let i=f?.();i?(i.setCamera(n),i.render(r)):e.render(t,n),p&&p.render(t,n),d&&d.render(e)},k=()=>{O(r(),0)},A=function(){g=requestAnimationFrame(A);let e=performance.now(),t=(e-_)/1e3;_=e,D(),(a.enableDamping||a.autoRotate)&&a.update(),u&&u.update(r().position),m&&m.update(),l?.(t);let n=r();if(h){if(!(v||w(n)||e-y>=500))return;v=!1,y=e}O(n,t)};return{animate:A,dispose:()=>{if(g!==null&&(cancelAnimationFrame(g),g=null),h)for(let e of E)T.removeEventListener(e,C)},invalidate:C,renderNow:k}}const Q=new c.Vector3(0,0,1);function Qe(e){let t=e.sceneScale||`m`,n={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}}[t],r=e.look??`technical`,i=O[r];return{sceneScale:t,look:r,camera:{position:e.camera?.position||L(e.environment?.sceneUp??Q,n.cameraDistance*Math.sqrt(3)),fov:e.camera?.fov||20,near:e.camera?.near||n.near,far:e.camera?.far||n.far,target:e.camera?.target||new c.Vector3(0,0,0),dynamicNear:e.camera?.dynamicNear??!0},lighting:{enableSunlight:e.lighting?.enableSunlight??!0,sunlightIntensity:e.lighting?.sunlightIntensity??1,sunlightPosition:e.lighting?.sunlightPosition||R(e.environment?.sceneUp??Q,n.lightDistance,n.lightHeight),ambientLightColor:e.lighting?.ambientLightColor||new c.Color(4210752),ambientLightIntensity:e.lighting?.ambientLightIntensity??i.ambientIntensity,sunlightColor:e.lighting?.sunlightColor||16777215,enableHemisphereLight:e.lighting?.enableHemisphereLight??i.hemisphereIntensity>0,hemisphereSkyColor:e.lighting?.hemisphereSkyColor??14673663,hemisphereGroundColor:e.lighting?.hemisphereGroundColor??7036754,hemisphereIntensity:e.lighting?.hemisphereIntensity??i.hemisphereIntensity},environment:{hdrPath:e.environment?.hdrPath||`/baseHDR.hdr`,backgroundColor:e.environment?.backgroundColor||new c.Color(15790320),enableEnvironmentLighting:e.environment?.enableEnvironmentLighting??!0,sceneUp:e.environment?.sceneUp||Q,showEnvironment:e.environment?.showEnvironment??!1,environmentIntensity:e.environment?.environmentIntensity??i.environmentIntensity},floor:{enabled:e.floor?.enabled??!1,size:e.floor?.size||n.floorSize,color:e.floor?.color||new c.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??i.toneMapping,toneMappingExposure:e.render?.toneMappingExposure??i.toneMappingExposure,preserveDrawingBuffer:e.render?.preserveDrawingBuffer??!1,ambientOcclusion:e.render?.ambientOcclusion??i.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||n.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??ne(e.environment?.sceneUp??Q)},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 $e(e){let{scene:t,renderer:n,lights:r,config:i,pipeline:a,requestRender:o}=e,s=i.look,l=e=>{e.ambientIntensity!==void 0&&(r.ambient.intensity=e.ambientIntensity),e.hemisphereIntensity!==void 0&&!r.hemisphere&&e.hemisphereIntensity>0&&(r.hemisphere=new c.HemisphereLight(e.hemisphereSkyColor??i.lighting.hemisphereSkyColor,e.hemisphereGroundColor??i.lighting.hemisphereGroundColor,e.hemisphereIntensity),r.hemisphere.position.copy(i.environment.sceneUp??Q),t.add(r.hemisphere)),r.hemisphere&&(e.hemisphereIntensity!==void 0&&(r.hemisphere.intensity=e.hemisphereIntensity),e.hemisphereSkyColor!==void 0&&r.hemisphere.color.set(e.hemisphereSkyColor),e.hemisphereGroundColor!==void 0&&r.hemisphere.groundColor.set(e.hemisphereGroundColor)),o()},u=e=>{i.environment.environmentIntensity=e,t.environmentIntensity=e,o()};return{setFillLights:l,setEnvironmentIntensity:u,setToneMappingExposure:e=>{i.render.toneMappingExposure=e,n.toneMappingExposure=e,a.get()&&a.rebuild()},setAoIntensity:e=>{i.render.aoIntensity=e,a.get()&&a.rebuild()},setLook:e=>{let r=O[e];s=e,n.toneMapping=r.toneMapping,n.toneMappingExposure=r.toneMappingExposure,i.render.toneMapping=r.toneMapping,i.render.toneMappingExposure=r.toneMappingExposure,l({hemisphereIntensity:r.hemisphereIntensity,ambientIntensity:r.ambientIntensity}),u(r.environmentIntensity);let c=a.get()!==null;a.setAmbientOcclusion(r.ambientOcclusion),c&&a.rebuild(),t.traverse(e=>{if(e.userData.source!==`compute`)return;let t=e,n=Array.isArray(t.material)?t.material:t.material?[t.material]:[];for(let e of n)`envMapIntensity`in e&&(e.envMapIntensity=r.envMapIntensity)}),o()},getMaterialAppearance:()=>k(s)}}function et(e,t){let n=t.parentElement,r=n?n.clientWidth:window.innerWidth,i=n?n.clientHeight:window.innerHeight,a=new c.PerspectiveCamera(e.camera.fov,r/i,e.camera.near,e.camera.far),o=e.camera.position;return o&&a.position.set(o.x,o.y,o.z),a}function tt(e){let t=new c.Scene;return t.background=(typeof e.environment.backgroundColor==`string`?new c.Color(e.environment.backgroundColor):e.environment.backgroundColor)||null,t}function nt(e,t){o(e,t),e.environment?.dispose(),e.background instanceof c.Texture&&e.background.dispose()}const $={uniforms:{tDiffuse:{value:null},tNormal:{value:null},tDepth:{value:null},uResolution:{value:new c.Vector2(1,1)},uColor:{value:new c.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
|
+
`,transparent:!0,depthWrite:!1,side:c.DoubleSide,uniforms:{uAxes:{value:s},uCell:{value:t},uMajor:{value:n},uCellColor:{value:new c.Color(r)},uMajorColor:{value:new c.Color(i)},uCenter:{value:new c.Vector3},uFade:{value:a}}}),f=new c.Mesh(u,d);f.name=`grid`,f.userData.id=`grid`,f.renderOrder=-1;let p=a,m=a*l,h=new c.Vector3;return{object:f,update:e=>{o===`y`?(f.position.set(e.x,0,e.z),h.set(e.x,0,e.z)):o===`z`?(f.position.set(e.x,e.y,0),h.set(e.x,e.y,0)):(f.position.set(0,e.y,e.z),h.set(0,e.y,e.z)),d.uniforms.uCenter.value.copy(h),f.scale.setScalar(m)},fitToContent:e=>{if(e.isEmpty())return;let t=e.getSize(new c.Vector3),n=(e,t)=>t===0?e.x:t===1?e.y:e.z,r=Math.max(n(t,s.x),n(t,s.y));!(r>0)||!Number.isFinite(r)||(d.uniforms.uCell.value=Le(r/20),p=r*2,d.uniforms.uFade.value=p,m=p*l)},setVisible:e=>{f.visible=e},dispose:()=>{f.removeFromParent(),u.dispose(),d.dispose()}}}function ze(e,t){let n=new h,r=n.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};n.setSize(i.width,i.height);let a=new c.Group;a.name=`label-layer`,a.userData.id=`label-layer`,t.add(a);let o=new Set;return{addLabel:(e,t,n)=>{let r=document.createElement(`div`);r.textContent=e,n?r.className=n:Object.assign(r.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`}),r.style.pointerEvents=`none`;let i=new m(r);return i.position.copy(t),a.add(i),o.add(i),{object:i,setPosition:e=>i.position.copy(e),setText:e=>{r.textContent=e},remove:()=>{i.removeFromParent(),r.remove(),o.delete(i)}}},render:(e,t)=>n.render(e,t),setSize:(e,t)=>n.setSize(e,t),dispose:()=>{o.forEach(e=>{e.removeFromParent(),e.element.remove()}),o.clear(),a.removeFromParent(),r.remove()}}}const Be=.015,Ve={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 He(e){let t=e&&Ve[e]||Ve.Meters;return e=>`${(e/t.metersPerUnit).toPrecision(3)} ${t.suffix}`}function Ue(e,t){if(e.isOrthographicCamera){let t=e;return Math.abs(t.top-t.bottom)/(t.zoom||1)*Be}return((t?e.position.distanceTo(t):e.position.length())||1)*Be}function We(e){let t=e.object;if(t instanceof c.Mesh)return e.face?[e.face.a,e.face.b,e.face.c]:null;if(t instanceof c.Points)return e.index==null?null:[e.index];if(t instanceof c.Line){if(e.index==null)return null;let n=t.geometry.index;return n?e.index+1>=n.count?null:[n.getX(e.index),n.getX(e.index+1)]:[e.index,e.index+1]}return null}function Ge(e,t,n,r){let i=e.point.clone(),a=e.object,o=We(e);if(!o||!a.geometry)return i;let s=a.geometry.attributes.position;if(!s)return i;let l=e=>{let r=e.clone().project(t);return new c.Vector2((r.x+1)/2*n.width,(1-r.y)/2*n.height)},u=l(i),d=i,f=r;for(let e of o){if(e>=s.count)continue;let t=new c.Vector3().fromBufferAttribute(s,e).applyMatrix4(a.matrixWorld),n=l(t).distanceTo(u);n<f&&(f=n,d=t)}return d}function Ke(e){let{canvas:t,scene:n,getActiveCamera:r,getViewTarget:i,labelLayer:a,options:o={}}=e,s=o.snapPixels??12,f=new c.Color(o.color??16763904),p=He(o.displayUnit),m=o.format??((e,t)=>`${p(e)}\nΔx ${p(t.x)} Δy ${p(t.y)} Δz ${p(t.z)}`),h=new c.Raycaster,g=new c.Vector2,_=!1,v=[],y=[],b=null,x=null,S=new c.PointsMaterial({color:f,size:8,sizeAttenuation:!1,depthTest:!1}),C=new c.PointsMaterial({color:f,size:11,sizeAttenuation:!1,depthTest:!1,transparent:!0,opacity:.5}),w=null,T=e=>{if(!e){w&&(w.visible=!1);return}if(!w){let e=new c.BufferGeometry;e.setAttribute(`position`,new c.Float32BufferAttribute([0,0,0],3)),w=new c.Points(e,C),w.renderOrder=1e3,w.userData.id=`measure`,w.raycast=()=>{},n.add(w)}w.position.copy(e),w.visible=!0},E=e=>{let t=new c.BufferGeometry;t.setAttribute(`position`,new c.Float32BufferAttribute([e.x,e.y,e.z],3));let r=new c.Points(t,S);return r.renderOrder=999,r.userData.id=`measure`,r.raycast=()=>{},n.add(r),r},D=()=>{v.length=0,y.forEach(e=>{e.geometry.dispose(),e.removeFromParent()}),y.length=0,b&&=(b.geometry.dispose(),b.material.dispose(),b.removeFromParent(),null),x?.remove(),x=null},O=()=>{if(v.length!==2)return;let[e,t]=v,r=new u;r.setPositions([e.x,e.y,e.z,t.x,t.y,t.z]);let i=new d({color:f});i.linewidth=2,i.depthTest=!1,b=new l(r,i),b.renderOrder=998,b.userData.id=`measure`,b.raycast=()=>{},n.add(b);let s=e.clone().add(t).multiplyScalar(.5),p=new c.Vector3(Math.abs(t.x-e.x),Math.abs(t.y-e.y),Math.abs(t.z-e.z));x=a.addLabel(m(e.distanceTo(t),p),s,o.labelClassName)},k=e=>{let a=t.getBoundingClientRect();g.x=(e.clientX-a.left)/a.width*2-1,g.y=-((e.clientY-a.top)/a.height)*2+1;let o=r();h.setFromCamera(g,o);let c=Ue(o,i?.());h.params.Line.threshold=c,h.params.Points.threshold=c;let l=h.intersectObjects(n.children,!0).filter(e=>e.object.userData.id!==`measure`&&e.object.userData.id!==`grid`);return l.length===0?null:Ge(l[0],o,{width:a.width,height:a.height},s)},A=null,j=0,M=()=>{j&&=(cancelAnimationFrame(j),0),A=null};return{setEnabled:e=>{_=e,e||(M(),D(),T(null))},isEnabled:()=>_,handleClick:e=>{if(!_)return!1;v.length===2&&D();let t=k(e);return t===null||(v.push(t),y.push(E(t)),v.length===2&&O(),!0)},handleMove:e=>{_&&(A=e,!j&&(j=requestAnimationFrame(()=>{j=0;let e=A;A=null,!(!_||!e)&&T(k(e))})))},clear:D,dispose:()=>{M(),D(),w&&=(w.geometry.dispose(),w.removeFromParent(),null),S.dispose(),C.dispose()}}}const qe=[];function Je({camera:e,scene:t,groundNormals:n=()=>qe}){let r=e.near,i=e.near,a=new c.Vector3,o=new c.Vector3;return{update:()=>{e.near!==i&&(r=e.near);let s=H(t),l=r;if(!s.isEmpty()){let t=s.getSize(o).length()*.5,i=e.position.distanceTo(s.getCenter(a))-t;for(let t of n())i=Math.min(i,Math.abs(e.position.dot(t)));l=c.MathUtils.clamp(i*.5,r,e.far*.01)}Math.abs(l-i)>i*.05&&(e.near=l,e.updateProjectionMatrix(),i=l)}}}function Ye(){let e=[],t=null,n=()=>e.sort((e,t)=>t.priority-e.priority),r=t=>e.findIndex(e=>e.id===t),i=n=>{let i=r(n);i!==-1&&(e.splice(i,1),t===n&&(t=null))};return{register:({id:t,tool:r,priority:a=0})=>(i(t),e.push({id:t,tool:r,priority:a}),n(),()=>i(t)),unregister:i,get:t=>e[r(t)]?.tool??null,setActive:n=>{t=n;for(let t of e)t.tool.setEnabled?.(t.id===n)},getActive:()=>t,handleClick:t=>{for(let n of[...e])if(n.tool.handleClick(t))return!0;return!1},handleMove:t=>{for(let n of[...e])n.tool.handleMove?.(t)}}}function Xe(e,t){let n=t.getBoundingClientRect();return{x:(e.clientX-n.left)/n.width*2-1,y:-((e.clientY-n.top)/n.height)*2+1}}function Ze(e){let{camera:t,domElement:n,controller:r}=e,i=new g(t,n);i.setLabels(`X`,`Y`,`Z`);let a=!0,o=new c.Raycaster,s=new c.OrthographicCamera(-2,2,2,-2,0,4);s.position.set(0,0,2),s.updateMatrixWorld();let l={posX:new c.Vector3(1,0,0),negX:new c.Vector3(-1,0,0),posY:new c.Vector3(0,1,0),negY:new c.Vector3(0,-1,0),posZ:new c.Vector3(0,0,1),negZ:new c.Vector3(0,0,-1)},u=e=>{let r=n.getBoundingClientRect(),a=r.left+n.offsetWidth-128-i.location.right,u=r.top+n.offsetHeight-128-i.location.bottom,d=new c.Vector2((e.clientX-a)/128*2-1,-((e.clientY-u)/128)*2+1);if(Math.abs(d.x)>1||Math.abs(d.y)>1)return null;i.quaternion.copy(t.quaternion).invert(),i.updateMatrixWorld(),o.setFromCamera(d,s);let f=o.intersectObjects(i.children,!1);for(let e of f){let t=e.object.userData?.type;if(typeof t==`string`&&t in l)return t}return null};return{render:e=>{if(!a)return;let t=e.autoClear;e.autoClear=!1,i.render(e),e.autoClear=t},handleClick:e=>{if(!a)return!1;let t=u(e);return t?(r.getProjection()===`orthographic`&&r.setProjection(`perspective`),r.setViewDirection(l[t],!1),!0):!1},setVisible:e=>{a=e},isVisible:()=>a,dispose:()=>i.dispose()}}function Qe(e,t,n,r,i,a,o,s,l,u,d,f,p,m,h=!0){let g=null,_=performance.now(),v=!0,y=0,b=new c.Matrix4,x=new c.Matrix4,S=null,C=()=>{v=!0},w=e=>{e.updateMatrixWorld();let t=S!==e||!b.equals(e.matrixWorld)||!x.equals(e.projectionMatrix);return t&&(S=e,b.copy(e.matrixWorld),x.copy(e.projectionMatrix)),t},T=e.domElement,E=[`pointerdown`,`pointerup`,`wheel`];if(h)for(let e of E)T.addEventListener(e,C,{passive:!0});let D=()=>{let{width:t,height:r}=o();if(t===0||r===0)return;let a=Math.floor(t*s),c=Math.floor(r*s);(e.domElement.width!==a||e.domElement.height!==c)&&(e.setPixelRatio(s),e.setSize(t,r,!1),n.aspect=t/r,n.updateProjectionMatrix(),i.updateAspect(t,r),f?.()?.setSize(t,r,s),p?.setSize(t,r),C())},O=(n,r)=>{let i=f?.();i?(i.setCamera(n),i.render(r)):e.render(t,n),p&&p.render(t,n),d&&d.render(e)},k=()=>{O(r(),0)},A=function(){g=requestAnimationFrame(A);let e=performance.now(),t=(e-_)/1e3;_=e,D(),(a.enableDamping||a.autoRotate)&&a.update(),u&&u.update(r().position),m&&m.update(),l?.(t);let n=r();if(h){if(!(v||w(n)||e-y>=500))return;v=!1,y=e}O(n,t)};return{animate:A,dispose:()=>{if(g!==null&&(cancelAnimationFrame(g),g=null),h)for(let e of E)T.removeEventListener(e,C)},invalidate:C,renderNow:k}}const Z=new c.Vector3(0,0,1);function $e(e){let t=e.sceneScale||`m`,n={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}}[t],r=e.look??`technical`,i=O[r];return{sceneScale:t,look:r,camera:{position:e.camera?.position||L(e.environment?.sceneUp??Z,n.cameraDistance*Math.sqrt(3)),fov:e.camera?.fov||20,near:e.camera?.near||n.near,far:e.camera?.far||n.far,target:e.camera?.target||new c.Vector3(0,0,0),dynamicNear:e.camera?.dynamicNear??!0},lighting:{enableSunlight:e.lighting?.enableSunlight??!0,sunlightIntensity:e.lighting?.sunlightIntensity??i.sunlightIntensity,sunlightPosition:e.lighting?.sunlightPosition||R(e.environment?.sceneUp??Z,n.lightDistance,n.lightHeight),ambientLightColor:e.lighting?.ambientLightColor||new c.Color(4210752),ambientLightIntensity:e.lighting?.ambientLightIntensity??i.ambientIntensity,sunlightColor:e.lighting?.sunlightColor||16777215,enableHemisphereLight:e.lighting?.enableHemisphereLight??i.hemisphereIntensity>0,hemisphereSkyColor:e.lighting?.hemisphereSkyColor??14673663,hemisphereGroundColor:e.lighting?.hemisphereGroundColor??7036754,hemisphereIntensity:e.lighting?.hemisphereIntensity??i.hemisphereIntensity},environment:{hdrPath:e.environment?.hdrPath||`/baseHDR.hdr`,backgroundColor:e.environment?.backgroundColor||new c.Color(15790320),enableEnvironmentLighting:e.environment?.enableEnvironmentLighting??!0,sceneUp:e.environment?.sceneUp||Z,showEnvironment:e.environment?.showEnvironment??!1,environmentIntensity:e.environment?.environmentIntensity??i.environmentIntensity},floor:{enabled:e.floor?.enabled??!1,size:e.floor?.size||n.floorSize,color:e.floor?.color||new c.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??i.toneMapping,toneMappingExposure:e.render?.toneMappingExposure??i.toneMappingExposure,preserveDrawingBuffer:e.render?.preserveDrawingBuffer??!1,ambientOcclusion:e.render?.ambientOcclusion??i.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||n.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??ne(e.environment?.sceneUp??Z)},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,maxOverlays:e.edges?.maxOverlays,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}}const Q=`__selvaLookBaseline`;function et(e,t){e.color?.setHex(t.color),e.metalness!==void 0&&(e.metalness=t.metalness),e.roughness!==void 0&&(e.roughness=t.roughness),e.opacity=t.opacity,e.transparent=t.transparent,e.depthWrite=t.depthWrite,e.wireframe!==void 0&&(e.wireframe=t.wireframe)}function tt(e){let t=e[Q];t&&(et(e,t),delete e[Q])}function nt(e,t){let n=e;if(!t){tt(n),n.needsUpdate=!0;return}n[Q]?et(n,n[Q]):n[Q]={color:n.color?.getHex()??16777215,metalness:n.metalness??0,roughness:n.roughness??1,opacity:n.opacity,transparent:n.transparent,depthWrite:n.depthWrite,wireframe:n.wireframe??!1},t.color!==void 0&&n.color?.setHex(t.color),t.metalness!==void 0&&n.metalness!==void 0&&(n.metalness=t.metalness),t.roughness!==void 0&&n.roughness!==void 0&&(n.roughness=t.roughness),t.opacity!==void 0&&(n.opacity=t.opacity,n.transparent=t.opacity<1),t.depthWrite!==void 0&&(n.depthWrite=t.depthWrite),t.wireframe!==void 0&&n.wireframe!==void 0&&(n.wireframe=t.wireframe),n.needsUpdate=!0}function rt(e){let{scene:t,renderer:n,lights:r,config:i,pipeline:a,requestRender:o}=e,s=i.look,l=e=>{e.ambientIntensity!==void 0&&(r.ambient.intensity=e.ambientIntensity),e.hemisphereIntensity!==void 0&&!r.hemisphere&&e.hemisphereIntensity>0&&(r.hemisphere=new c.HemisphereLight(e.hemisphereSkyColor??i.lighting.hemisphereSkyColor,e.hemisphereGroundColor??i.lighting.hemisphereGroundColor,e.hemisphereIntensity),r.hemisphere.position.copy(i.environment.sceneUp??Z),t.add(r.hemisphere)),r.hemisphere&&(e.hemisphereIntensity!==void 0&&(r.hemisphere.intensity=e.hemisphereIntensity),e.hemisphereSkyColor!==void 0&&r.hemisphere.color.set(e.hemisphereSkyColor),e.hemisphereGroundColor!==void 0&&r.hemisphere.groundColor.set(e.hemisphereGroundColor)),o()},u=e=>{i.environment.environmentIntensity=e,t.environmentIntensity=e,o()};return{setFillLights:l,setEnvironmentIntensity:u,setToneMappingExposure:e=>{i.render.toneMappingExposure=e,n.toneMappingExposure=e,a.get()&&a.rebuild()},setAoIntensity:e=>{i.render.aoIntensity=e,a.get()&&a.rebuild()},setLook:e=>{let c=O[e];s=e,n.toneMapping=c.toneMapping,n.toneMappingExposure=c.toneMappingExposure,i.render.toneMapping=c.toneMapping,i.render.toneMappingExposure=c.toneMappingExposure,l({hemisphereIntensity:c.hemisphereIntensity,ambientIntensity:c.ambientIntensity}),u(c.environmentIntensity),r.sun&&(r.sun.intensity=c.sunlightIntensity,i.lighting.sunlightIntensity=c.sunlightIntensity);let d=a.get()!==null;a.setAmbientOcclusion(c.ambientOcclusion),d&&a.rebuild(),t.traverse(e=>{if(e.userData.source!==`compute`)return;let t=e,n=Array.isArray(t.material)?t.material:t.material?[t.material]:[];for(let e of n)`envMapIntensity`in e&&(e.envMapIntensity=c.envMapIntensity),nt(e,c.materialOverride)}),o()},getMaterialAppearance:()=>k(s)}}function it(e,t){let n=t.parentElement,r=n?n.clientWidth:window.innerWidth,i=n?n.clientHeight:window.innerHeight,a=new c.PerspectiveCamera(e.camera.fov,r/i,e.camera.near,e.camera.far),o=e.camera.position;return o&&a.position.set(o.x,o.y,o.z),a}function at(e){let t=new c.Scene;return t.background=(typeof e.environment.backgroundColor==`string`?new c.Color(e.environment.backgroundColor):e.environment.backgroundColor)||null,t}function ot(e,t){o(e,t),e.environment?.dispose(),e.background instanceof c.Texture&&e.background.dispose()}const $={uniforms:{tDiffuse:{value:null},tNormal:{value:null},tDepth:{value:null},uResolution:{value:new c.Vector2(1,1)},uColor:{value:new c.Color(2236962)},uOpacity:{value:1},uNormalThreshold:{value:.4},uDepthThreshold:{value:.02},uThickness:{value:1},uNear:{value:.1},uFar:{value:1e3},uPerspective:{value:1}},vertexShader:`
|
|
54
54
|
varying vec2 vUv;
|
|
55
55
|
void main() {
|
|
56
56
|
vUv = uv;
|
|
@@ -104,5 +104,5 @@ import{a as e,c as t,d as n,l as r,r as i,s as a,t as o,u as s}from"./gpu-dispos
|
|
|
104
104
|
float edge = max(depthEdge, normalEdge) * uOpacity;
|
|
105
105
|
gl_FragColor = vec4(mix(color.rgb, uColor, edge), color.a);
|
|
106
106
|
}
|
|
107
|
-
`};var rt=class extends C{camera;scene;normalMaterial;edgeMaterial;fsQuad;normalTarget=null;width;height;constructor(e,t,n,r,i={}){super(),this.scene=e,this.camera=t,this.width=Math.max(1,n),this.height=Math.max(1,r),this.normalMaterial=new c.MeshNormalMaterial,this.normalMaterial.blending=c.NoBlending,this.edgeMaterial=new c.ShaderMaterial({uniforms:c.UniformsUtils.clone($.uniforms),vertexShader:$.vertexShader,fragmentShader:$.fragmentShader});let a=this.edgeMaterial.uniforms;a.uColor.value=new c.Color(i.color??2236962),a.uOpacity.value=i.opacity??1,a.uNormalThreshold.value=i.normalThreshold??.4,a.uDepthThreshold.value=i.depthThreshold??.02,a.uThickness.value=i.thickness??1,this.fsQuad=new S(this.edgeMaterial),this.needsSwap=!0}acquireNormalTarget(){if(!this.normalTarget){let e=new c.DepthTexture(this.width,this.height);this.normalTarget=new c.WebGLRenderTarget(this.width,this.height,{minFilter:c.NearestFilter,magFilter:c.NearestFilter,depthTexture:e})}return this.normalTarget}setSize(e,t){this.width=Math.max(1,e),this.height=Math.max(1,t),this.normalTarget?.setSize(this.width,this.height)}render(e,t,n){let r=this.acquireNormalTarget(),i=e.getRenderTarget(),a=e.autoClear,o=e.getClearColor(new c.Color),s=e.getClearAlpha(),l=this.scene.overrideMaterial;e.setRenderTarget(r),e.setClearColor(7829503,1),e.autoClear=!0,this.scene.overrideMaterial=this.normalMaterial,e.render(this.scene,this.camera),this.scene.overrideMaterial=l,e.setClearColor(o,s),e.autoClear=a;let u=this.edgeMaterial.uniforms;u.tDiffuse.value=n.texture,u.tNormal.value=r.texture,u.tDepth.value=r.depthTexture,u.uResolution.value.set(this.width,this.height);let d=this.camera;u.uPerspective.value=+!!d.isPerspectiveCamera,u.uNear.value=this.camera.near??.1,u.uFar.value=this.camera.far??1e3,e.setRenderTarget(this.renderToScreen?null:t),this.fsQuad.render(e),e.setRenderTarget(i)}dispose(){this.normalTarget?.dispose(),this.normalMaterial.dispose(),this.edgeMaterial.dispose(),this.fsQuad.dispose()}};function it(e,t,n,r,i,a){let o=new _(e),s=new v(t,n);o.addPass(s);let c=null;(a.ambientOcclusion??!0)&&(c=new y(t,n,r,i),c.blendIntensity=a.aoIntensity??1,c.updateGtaoMaterial({screenSpaceRadius:!0}),o.addPass(c));let l=new rt(t,n,r,i,typeof a.edgeDetection==`object`?a.edgeDetection:{});l.enabled=!!a.edgeDetection,o.addPass(l);let u=new b;o.addPass(u);let d=new x;o.addPass(d),e.toneMapping=a.toneMapping,e.toneMappingExposure=a.toneMappingExposure;let f=a.aoPixelRatio??1;return o.setSize(r,i),{render:e=>o.render(e),setSize:(e,t,n)=>{o.setPixelRatio(Math.min(n,f)),o.setSize(e,t)},setCamera:e=>{if(s.camera=e,l.camera=e,!c)return;c.camera=e;let t=+!!e.isPerspectiveCamera;c.gtaoMaterial.defines.PERSPECTIVE_CAMERA!==t&&(c.gtaoMaterial.defines.PERSPECTIVE_CAMERA=t,c.gtaoMaterial.needsUpdate=!0)},setEdgeDetection:e=>{l.enabled=e},edgeDetectionEnabled:()=>l.enabled,dispose:()=>{o.dispose(),c?.dispose(),l.dispose(),u.dispose(),d.dispose()}}}function at(e){let{renderer:t,scene:n,getActiveCamera:r,getCanvasSize:i,pixelRatio:a,config:o,requestRender:s}=e,l=null,u=!!o.render.ambientOcclusion,d=!1,f=!1,p=e=>{let{width:s,height:l}=i(),u=it(t,n,r(),Math.max(1,s),Math.max(1,l),{toneMapping:o.render.toneMapping??c.NeutralToneMapping,toneMappingExposure:o.render.toneMappingExposure??1,ambientOcclusion:e,aoIntensity:o.render.aoIntensity,aoPixelRatio:o.render.aoPixelRatio,edgeDetection:!1});return u.setSize(Math.max(1,s),Math.max(1,l),a),u},m=()=>{if(!(u||d)){l?.dispose(),l=null,s();return}(!l||f!==u)&&(l?.dispose(),l=p(u),f=u),l.setEdgeDetection(d),s()};return{get:()=>l,sync:m,rebuild:()=>{l?.dispose(),l=null,m()},setAmbientOcclusion:e=>{u=e,m()},setEdgeFallback:e=>{e!==d&&(d=e,m())},isEdgeFallbackActive:()=>d,dispose:()=>{l?.dispose(),l=null}}}function ot(e,t,n){let r=new w(e,t),i=n.camera.target;return i&&r.target.set(i.x,i.y,i.z),r.enableDamping=n.controls.enableDamping||!1,r.dampingFactor=n.controls.dampingFactor||.05,r.autoRotate=n.controls.autoRotate||!1,r.autoRotateSpeed=n.controls.autoRotateSpeed||.5,r.enableZoom=n.controls.enableZoom??!0,r.enablePan=n.controls.enablePan??!0,r.minDistance=n.controls.minDistance||.001,r.maxDistance=n.controls.maxDistance||1/0,r.screenSpacePanning=!1,r.maxPolarAngle=Math.PI,r.update(),r}function st(e,n,r,i){r.environment.enableEnvironmentLighting?new T().load(r.environment.hdrPath||`/baseHDR.hdr`,function(a){if(i()){a.dispose();return}if(!a?.image){t().warn(`HDR loaded without image data; skipping environment map.`),a?.dispose(),r.events.onReady?.();return}a.mapping=c.EquirectangularReflectionMapping;let o=new c.PMREMGenerator(n);o.compileEquirectangularShader();let s=o.fromEquirectangular(a).texture;o.dispose(),e.environment=s,e.environmentIntensity=r.environment.environmentIntensity??1;let l=te(r.environment.sceneUp??Q);e.environmentRotation.copy(l),r.environment.showEnvironment?(e.background=a,e.backgroundRotation.copy(l)):a.dispose(),r.events.onReady?.()},void 0,function(e){i()||(t().warn(`HDR texture could not be loaded, falling back to basic lighting:`,e),r.events.onReady?.())}):r.events.onReady?.()}function ct(e,t){let n=t.floor.size,r=new c.PlaneGeometry(n,n),i=typeof t.floor.color==`string`?new c.Color(t.floor.color):t.floor.color,a=new c.MeshStandardMaterial({color:i,roughness:t.floor.roughness,metalness:t.floor.metalness,side:c.DoubleSide}),o=new c.Mesh(r,a);o.userData.id=`floor`,o.name=`floor`;let s=(t.environment?.sceneUp||Q).clone().normalize();o.quaternion.setFromUnitVectors(new c.Vector3(0,0,1),s),o.position.set(0,0,0),t.floor.receiveShadow&&t.render.enableShadows&&(o.receiveShadow=!0),e.add(o)}function lt(e,n,r,i){let a=new Set,o=new Map,s=new c.Raycaster,l=new c.Vector2,u=new c.Vector2,d=()=>r.getActiveCamera(),f=e=>{let t=e;for(;t;){if(!t.visible)return!1;t=t.parent}return!0},p=()=>{let e=H(n);if(e.isEmpty()){t().warn(`No objects to fit to view`);return}r.frameBounds(e,!1)},m=typeof i.events.selectionColor==`string`?new c.Color(i.events.selectionColor):i.events.selectionColor instanceof c.Color?i.events.selectionColor:new c.Color(`#ff0000`),h=()=>{a.forEach(e=>{let t=e;if(o.has(e)){let r=o.get(e),i=t.material;i instanceof c.Material?i.dispose():Array.isArray(i)&&i.forEach(e=>e.dispose()),t.material=r,o.delete(e);let a=e;for(;a.parent;)a=a.parent;a!==n&&(r instanceof c.Material?r.dispose():r.forEach(e=>e.dispose()))}}),a.clear()},g=e=>{let t=e;if(!(t.material instanceof c.Material))return!1;o.set(e,t.material);let n=t.material.clone();return e instanceof c.Mesh&&`emissive`in n?n.emissive=m.clone():`color`in n&&(n.color=m.clone()),t.material=n,!0},_=()=>{let e=H(n),t=e.isEmpty()?1:e.getSize(new c.Vector3).length();s.params.Points.threshold=t*.01},v=e=>{u.set(e.clientX,e.clientY)},y=t=>{let r=new c.Vector2(t.clientX,t.clientY);if(u.distanceTo(r)>5)return;let o=e.getBoundingClientRect();l.x=(t.clientX-o.left)/o.width*2-1,l.y=-((t.clientY-o.top)/o.height)*2+1,_(),s.setFromCamera(l,d());let p=s.intersectObjects(n.children,!0).filter(e=>f(e.object));if(p.length>0){let e=p[0].object;a.has(e)||(h(),a.add(e),g(e),i.events?.onObjectSelected?.(e),e instanceof c.Mesh&&Object.keys(e.userData).length>0&&i.events?.onMeshMetadataClicked?.(e.userData))}else h(),i.events?.onBackgroundClicked?.({x:l.x,y:l.y})},b=t=>{let a=e.getBoundingClientRect();l.x=(t.clientX-a.left)/a.width*2-1,l.y=-((t.clientY-a.top)/a.height)*2+1,_(),s.setFromCamera(l,d());let o=s.intersectObjects(n.children,!0).filter(e=>f(e.object));if(o.length===0)return;let u=o[0].object;if(i.events?.onMeshDoubleClicked?.(u),!i.events?.enableDoubleClickZoom)return;let p=new c.Box3().setFromObject(u);p.isEmpty()||r.frameBounds(p,!0)},x=e=>{if(i.events?.enableKeyboardControls)switch(e.key.toLowerCase()){case`f`:e.preventDefault(),p();break;case`escape`:e.preventDefault(),h();break;case` `:e.preventDefault(),p()}};return i.events?.enableClickToFocus&&(e.addEventListener(`mousedown`,v),e.addEventListener(`click`,y),e.addEventListener(`dblclick`,b)),i.events?.enableKeyboardControls&&(e.setAttribute(`tabindex`,`0`),e.addEventListener(`keydown`,x)),{dispose:()=>{e.removeEventListener(`mousedown`,v),e.removeEventListener(`click`,y),e.removeEventListener(`dblclick`,b),e.removeEventListener(`keydown`,x),h()},fitToView:p,clearSelection:h}}function ut(e,t){let n=new c.AmbientLight(t.lighting.ambientLightColor,t.lighting.ambientLightIntensity);e.add(n);let r=null;if(t.lighting.enableHemisphereLight){r=new c.HemisphereLight(t.lighting.hemisphereSkyColor,t.lighting.hemisphereGroundColor,t.lighting.hemisphereIntensity);let n=t.environment.sceneUp??Q;r.position.copy(n),e.add(r)}if(!t.lighting.enableSunlight)return{ambient:n,hemisphere:r,sun:null};let i=new c.DirectionalLight(t.lighting.sunlightColor??16777215,t.lighting.sunlightIntensity),a=t.lighting.sunlightPosition;return a&&i.position.set(a.x,a.y,a.z),t.render.enableShadows?(i.castShadow=!0,i.shadow.mapSize.width=t.render.shadowMapSize||2048,i.shadow.mapSize.height=t.render.shadowMapSize||2048,i.shadow.bias=-1e-4,i.shadow.normalBias=.02,i.shadow.radius=4,e.add(i),e.add(i.target),{ambient:n,hemisphere:r,sun:i}):(e.add(i),{ambient:n,hemisphere:r,sun:null})}function dt(e,t){if(t.isEmpty())return;let n=t.getCenter(new c.Vector3),r=t.getSize(new c.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(n),e.target.updateMatrixWorld();let a=e.position.distanceTo(n);i.near=Math.max(r*.01,a-r),i.far=a+r,i.updateProjectionMatrix()}function ft(e,t,n){let r=new c.WebGLRenderer({antialias:t.render.antialias,canvas:e,alpha:!0,powerPreference:`high-performance`,preserveDrawingBuffer:t.render.preserveDrawingBuffer,logarithmicDepthBuffer:!1}),i=e.parentElement,a=i?i.clientWidth:window.innerWidth,o=i?i.clientHeight:window.innerHeight;return i&&(e.style.width=`100%`,e.style.height=`100%`,e.style.display=`block`),r.setSize(a,o,!1),r.setPixelRatio(n),t.render.enableShadows&&(r.shadowMap.enabled=!0,r.shadowMap.type=c.VSMShadowMap),r.toneMapping=t.render.toneMapping,r.toneMappingExposure=t.render.toneMappingExposure??1,r.outputColorSpace=c.SRGBColorSpace,r.sortObjects=!0,r}const pt=function(e,t){let n=Qe(t||{}),r=n.environment?.sceneUp||Q,a=n.render.pixelRatio??Math.min(window.devicePixelRatio,2),s=tt(n),l=et(n,e);l.up.copy(r);let u=ft(e,n,a);i(u.capabilities.getMaxAnisotropy()),t?.onMaxAnisotropy?.(u.capabilities.getMaxAnisotropy());let d=ot(l,e,n),f=ae({scene:s,perspective:l,controls:d,onActiveCameraChange:()=>{},up:r}),p=()=>f.getActiveCamera(),m=!1;st(s,u,n,()=>m);let h=ut(s,n),g=h.sun,_=()=>{g&&dt(g,H(s))};n.floor?.enabled&&ct(s,n);let v=n.floor?.enabled?s.children.find(e=>e.userData.id===`floor`)??null:null,y=n.grid.enabled?Le({cellSize:n.grid.cellSize,majorEvery:n.grid.majorEvery,cellColor:n.grid.cellColor,majorColor:n.grid.majorColor,fadeDistance:n.grid.fadeDistance,plane:n.grid.plane}):null;y&&s.add(y.object);let b=()=>{y&&y.fitToContent(H(s))},x=n.gizmo.enabled?Xe({camera:l,domElement:e,controller:f}):null,S=n.grid.plane??ne(r),C=new c.Vector3(+(S===`x`),+(S===`y`),+(S===`z`)),w=r.clone().normalize(),T=n.camera.dynamicNear?qe({camera:l,scene:s,groundNormals:()=>{let e=[];return y?.object.visible&&e.push(C),n.floor.enabled&&v?.visible&&e.push(w),e}}):null,E=Re(e.parentElement??e,s),D=n.measure.enabled?Ge({canvas:e,scene:s,getActiveCamera:p,labelLayer:E,options:{snapPixels:n.measure.snapPixels,color:n.measure.color,labelClassName:n.measure.labelClassName,displayUnit:n.measure.displayUnit,format:n.measure.format}}):null,O=n.events.enableEventHandlers===!1?{dispose:()=>{},fitToView:()=>{},clearSelection:()=>{}}:lt(e,s,f,n),k=Je();D&&k.register({id:`measure`,tool:D,priority:0}),x&&k.register({id:`gizmo`,tool:x,priority:-100});let A=0,M=0,P=e=>{A=e.clientX,M=e.clientY},F=e=>Math.hypot(e.clientX-A,e.clientY-M)>5,I=e=>{F(e)||k.handleClick(e)&&e.stopImmediatePropagation()};e.addEventListener(`mousedown`,P,{capture:!0}),e.addEventListener(`click`,I,{capture:!0});let L=e=>k.handleMove(e);e.addEventListener(`mousemove`,L,{passive:!0});let R=()=>{},te=e=>{Pe(e,{color:n.edges.color,darken:n.edges.darken,width:n.edges.width,thresholdAngle:n.edges.thresholdAngle,distanceFade:n.edges.distanceFade,maxTriangles:n.edges.maxTriangles,maxSegments:n.edges.maxSegments}).then(()=>{z(e),R()})},z=e=>{if(n.edges.screenSpaceFallback===!1)return;let t=!1;e.traverse(e=>{e.userData?.edgesSkipped===`triangle-cap`&&(t=!0)}),U.setEdgeFallback(t)},re=e=>{Fe(e),U.setEdgeFallback(!1),R()},B=e.parentElement,V=()=>B?{width:B.clientWidth,height:B.clientHeight}:{width:window.innerWidth,height:window.innerHeight},U=at({renderer:u,scene:s,getActiveCamera:p,getCanvasSize:V,pixelRatio:a,config:n,requestRender:()=>R()});U.sync();let W=$e({scene:s,renderer:u,lights:h,config:n,pipeline:U,requestRender:()=>R()}),{animate:ie,dispose:oe,invalidate:G,renderNow:se}=Ze(u,s,l,p,f,d,V,a,n.events.onFrame,y,x,()=>U.get(),E,T,n.render.onDemand??!0);return R=G,ie(),s.up.set(r.x,r.y,r.z),_(),b(),{scene:s,camera:l,controls:d,renderer:u,cameraController:f,grid:y,gizmo:x,measureTool:D,labelLayer:E,tools:k,applyEdges:te,clearEdges:re,invalidate:G,captureImage:(e=`image/png`,t)=>(se(),new Promise(n=>u.domElement.toBlob(n,e,t))),setAmbientOcclusion:U.setAmbientOcclusion,setLook:W.setLook,setFillLights:W.setFillLights,setEnvironmentIntensity:W.setEnvironmentIntensity,setToneMappingExposure:W.setToneMappingExposure,setAoIntensity:W.setAoIntensity,getMaterialAppearance:W.getMaterialAppearance,updateShadowBounds:_,updateGridScale:b,dispose:()=>{m||(m=!0,oe(),O.dispose(),e.removeEventListener(`mousedown`,P,{capture:!0}),e.removeEventListener(`click`,I,{capture:!0}),e.removeEventListener(`mousemove`,L),D?.dispose(),E?.dispose(),x?.dispose(),y?.dispose(),U.dispose(),f.dispose(),d.dispose(),u.dispose(),u.forceContextLoss(),nt(s))},fitToView:O.fitToView,clearSelection:O.clearSelection,addUserGeometry:(e,t)=>{e.userData.source=t===void 0?j:N(t),s.add(e),R()},removeUserGeometry:e=>{e.removeFromParent(),o(e),R()},clearUserGeometry:e=>{s.children.filter(t=>ee(t,e)).forEach(e=>{e.removeFromParent(),o(e)}),R()}}};export{D as DEFAULT_LOOK,s as ErrorCodes,E as LOOKS,O as LOOK_PRESETS,A as SOURCE_COMPUTE,j as SOURCE_USER,n as VisualizationError,P as appIdFromSource,N as appSource,a as enableDebugLogging,t as getLogger,pt as initThree,F as isHostOwned,ee as isOwnedBy,k as materialAppearanceForLook,He as pickThreshold,Ye as pointerToNdc,r as setLogger,We as snapToVertex,re as updateScene};
|
|
107
|
+
`};var st=class extends C{camera;scene;normalMaterial;edgeMaterial;fsQuad;normalTarget=null;width;height;constructor(e,t,n,r,i={}){super(),this.scene=e,this.camera=t,this.width=Math.max(1,n),this.height=Math.max(1,r),this.normalMaterial=new c.MeshNormalMaterial,this.normalMaterial.blending=c.NoBlending,this.edgeMaterial=new c.ShaderMaterial({uniforms:c.UniformsUtils.clone($.uniforms),vertexShader:$.vertexShader,fragmentShader:$.fragmentShader});let a=this.edgeMaterial.uniforms;a.uColor.value=new c.Color(i.color??2236962),a.uOpacity.value=i.opacity??1,a.uNormalThreshold.value=i.normalThreshold??.4,a.uDepthThreshold.value=i.depthThreshold??.02,a.uThickness.value=i.thickness??1,this.fsQuad=new S(this.edgeMaterial),this.needsSwap=!0}acquireNormalTarget(){if(!this.normalTarget){let e=new c.DepthTexture(this.width,this.height);this.normalTarget=new c.WebGLRenderTarget(this.width,this.height,{minFilter:c.NearestFilter,magFilter:c.NearestFilter,depthTexture:e})}return this.normalTarget}setSize(e,t){this.width=Math.max(1,e),this.height=Math.max(1,t),this.normalTarget?.setSize(this.width,this.height)}render(e,t,n){let r=this.acquireNormalTarget(),i=e.getRenderTarget(),a=e.autoClear,o=e.getClearColor(new c.Color),s=e.getClearAlpha(),l=this.scene.overrideMaterial;e.setRenderTarget(r),e.setClearColor(7829503,1),e.autoClear=!0,this.scene.overrideMaterial=this.normalMaterial,e.render(this.scene,this.camera),this.scene.overrideMaterial=l,e.setClearColor(o,s),e.autoClear=a;let u=this.edgeMaterial.uniforms;u.tDiffuse.value=n.texture,u.tNormal.value=r.texture,u.tDepth.value=r.depthTexture,u.uResolution.value.set(this.width,this.height);let d=this.camera;u.uPerspective.value=+!!d.isPerspectiveCamera,u.uNear.value=this.camera.near??.1,u.uFar.value=this.camera.far??1e3,e.setRenderTarget(this.renderToScreen?null:t),this.fsQuad.render(e),e.setRenderTarget(i)}dispose(){this.normalTarget?.dispose(),this.normalMaterial.dispose(),this.edgeMaterial.dispose(),this.fsQuad.dispose()}};function ct(e,t,n,r,i,a){let o=new _(e),s=new v(t,n);o.addPass(s);let c=null;(a.ambientOcclusion??!0)&&(c=new y(t,n,r,i),c.blendIntensity=a.aoIntensity??1,c.updateGtaoMaterial({screenSpaceRadius:!0}),o.addPass(c));let l=new st(t,n,r,i,typeof a.edgeDetection==`object`?a.edgeDetection:{});l.enabled=!!a.edgeDetection,o.addPass(l);let u=new b;o.addPass(u);let d=new x;o.addPass(d),e.toneMapping=a.toneMapping,e.toneMappingExposure=a.toneMappingExposure;let f=a.aoPixelRatio??1;return o.setSize(r,i),{render:e=>o.render(e),setSize:(e,t,n)=>{o.setPixelRatio(Math.min(n,f)),o.setSize(e,t)},setCamera:e=>{if(s.camera=e,l.camera=e,!c)return;c.camera=e;let t=+!!e.isPerspectiveCamera;c.gtaoMaterial.defines.PERSPECTIVE_CAMERA!==t&&(c.gtaoMaterial.defines.PERSPECTIVE_CAMERA=t,c.gtaoMaterial.needsUpdate=!0)},setEdgeDetection:e=>{l.enabled=e},edgeDetectionEnabled:()=>l.enabled,dispose:()=>{o.dispose(),c?.dispose(),l.dispose(),u.dispose(),d.dispose()}}}function lt(e){let{renderer:t,scene:n,getActiveCamera:r,getCanvasSize:i,pixelRatio:a,config:o,requestRender:s}=e,l=null,u=!!o.render.ambientOcclusion,d=!1,f=!1,p=e=>{let{width:s,height:l}=i(),u=ct(t,n,r(),Math.max(1,s),Math.max(1,l),{toneMapping:o.render.toneMapping??c.NeutralToneMapping,toneMappingExposure:o.render.toneMappingExposure??1,ambientOcclusion:e,aoIntensity:o.render.aoIntensity,aoPixelRatio:o.render.aoPixelRatio,edgeDetection:!1});return u.setSize(Math.max(1,s),Math.max(1,l),a),u},m=()=>{if(!(u||d)){l?.dispose(),l=null,s();return}(!l||f!==u)&&(l?.dispose(),l=p(u),f=u),l.setEdgeDetection(d),s()};return{get:()=>l,sync:m,rebuild:()=>{l?.dispose(),l=null,m()},setAmbientOcclusion:e=>{u=e,m()},setEdgeFallback:e=>{e!==d&&(d=e,m())},isEdgeFallbackActive:()=>d,dispose:()=>{l?.dispose(),l=null}}}function ut(e,t,n){let r=new w(e,t),i=n.camera.target;return i&&r.target.set(i.x,i.y,i.z),r.enableDamping=n.controls.enableDamping||!1,r.dampingFactor=n.controls.dampingFactor||.05,r.autoRotate=n.controls.autoRotate||!1,r.autoRotateSpeed=n.controls.autoRotateSpeed||.5,r.enableZoom=n.controls.enableZoom??!0,r.enablePan=n.controls.enablePan??!0,r.minDistance=n.controls.minDistance||.001,r.maxDistance=n.controls.maxDistance||1/0,r.screenSpacePanning=!1,r.maxPolarAngle=Math.PI,r.update(),r}function dt(e,n,r,i){r.environment.enableEnvironmentLighting?new T().load(r.environment.hdrPath||`/baseHDR.hdr`,function(a){if(i()){a.dispose();return}if(!a?.image){t().warn(`HDR loaded without image data; skipping environment map.`),a?.dispose(),r.events.onReady?.();return}a.mapping=c.EquirectangularReflectionMapping;let o=new c.PMREMGenerator(n);o.compileEquirectangularShader();let s=o.fromEquirectangular(a).texture;o.dispose(),e.environment=s,e.environmentIntensity=r.environment.environmentIntensity??1;let l=te(r.environment.sceneUp??Z);e.environmentRotation.copy(l),r.environment.showEnvironment?(e.background=a,e.backgroundRotation.copy(l)):a.dispose(),r.events.onReady?.()},void 0,function(e){i()||(t().warn(`HDR texture could not be loaded, falling back to basic lighting:`,e),r.events.onReady?.())}):r.events.onReady?.()}function ft(e,t){let n=t.floor.size,r=new c.PlaneGeometry(n,n),i=typeof t.floor.color==`string`?new c.Color(t.floor.color):t.floor.color,a=new c.MeshStandardMaterial({color:i,roughness:t.floor.roughness,metalness:t.floor.metalness,side:c.DoubleSide}),o=new c.Mesh(r,a);o.userData.id=`floor`,o.name=`floor`;let s=(t.environment?.sceneUp||Z).clone().normalize();o.quaternion.setFromUnitVectors(new c.Vector3(0,0,1),s),o.position.set(0,0,0),t.floor.receiveShadow&&t.render.enableShadows&&(o.receiveShadow=!0),e.add(o)}function pt(e){let t=e.userData?.members;return Array.isArray(t)&&t.length>0?t:null}function mt(e){let t=pt(e.object);if(!t||e.faceIndex==null)return null;let n=e.faceIndex*3,r=0,i=t.length-1;for(;r<=i;){let e=r+i>>1,a=t[e];if(a.indexStart==null||a.indexCount==null)return null;if(n<a.indexStart)i=e-1;else if(n>=a.indexStart+a.indexCount)r=e+1;else return{member:a,index:e}}return null}function ht(e,t){let n=new c.Box3,r=e.geometry.getIndex(),i=e.geometry.getAttribute(`position`);if(!r||!i||t.indexStart==null||t.indexCount==null)return n;e.updateMatrixWorld();let a=new c.Vector3,o=Math.min(t.indexStart+t.indexCount,r.count);for(let s=t.indexStart;s<o;s++)a.fromBufferAttribute(i,r.getX(s)).applyMatrix4(e.matrixWorld),n.expandByPoint(a);return n}function gt(e,t,n){if(t.indexStart==null||t.indexCount==null)return()=>{};let r=e.material,i=e.geometry.groups.map(e=>({...e})),a=e.geometry.getIndex()?.count??0;e.geometry.clearGroups(),e.geometry.addGroup(0,t.indexStart,0),e.geometry.addGroup(t.indexStart,t.indexCount,1);let o=t.indexStart+t.indexCount;return e.geometry.addGroup(o,Math.max(0,a-o),0),e.material=[Array.isArray(r)?r[0]:r,n],()=>{e.geometry.clearGroups();for(let t of i)e.geometry.addGroup(t.start,t.count,t.materialIndex);e.material=r}}function _t(e,t,n){if(n&&`emissive`in e){let n=e;n.emissive=t.clone(),n.emissiveIntensity=.6,n.color.lerp(t,.75),n.metalness=Math.min(n.metalness,.2),n.opacity<1&&(n.opacity=1,n.transparent=!1,n.depthWrite=!0);return}`color`in e&&(e.color=t.clone())}function vt(e,n,r,i){let a=new Set,o=new Map,s=null,l=null,u=null,d=new c.Raycaster,f=new c.Vector2,p=new c.Vector2,m=()=>r.getActiveCamera(),h=e=>{let t=e;for(;t;){if(!t.visible)return!1;t=t.parent}return!0},g=()=>{let e=H(n);if(e.isEmpty()){t().warn(`No objects to fit to view`);return}r.frameBounds(e,!1)},_=typeof i.events.selectionColor==`string`?new c.Color(i.events.selectionColor):i.events.selectionColor instanceof c.Color?i.events.selectionColor:new c.Color(`#ff0000`),v=()=>{s&&(s(),s=null,u?.dispose(),u=null),a.forEach(e=>{let t=e;if(o.has(e)){let r=o.get(e),i=t.material;i instanceof c.Material?i.dispose():Array.isArray(i)&&i.forEach(e=>e.dispose()),t.material=r,o.delete(e);let a=e;for(;a.parent;)a=a.parent;a!==n&&(r instanceof c.Material?r.dispose():r.forEach(e=>e.dispose()))}}),a.clear(),l=null},y=(e,t)=>{let n=e;if(!(n.material instanceof c.Material))return!1;let r=n.material.clone();return _t(r,_,e instanceof c.Mesh),t&&e instanceof c.Mesh?(u=r,s=gt(e,t,r),!0):(o.set(e,n.material),n.material=r,!0)},b=null,x=-1,S=()=>{if(b===null||n.children.length!==x){let e=H(n);b=e.isEmpty()?1:e.getSize(new c.Vector3).length(),x=n.children.length}d.params.Points.threshold=b*.01},C=(t,r)=>{let i=e.getBoundingClientRect();f.x=(t-i.left)/i.width*2-1,f.y=-((r-i.top)/i.height)*2+1,S(),d.setFromCamera(f,m());for(let e of d.intersectObjects(n.children,!0))if(h(e.object)&&!V(e.object))return e;return null},w=e=>{p.set(e.clientX,e.clientY)},T=e=>{let t=new c.Vector2(e.clientX,e.clientY);if(p.distanceTo(t)>5)return;let n=C(e.clientX,e.clientY);if(!n){v(),i.events?.onBackgroundClicked?.({x:f.x,y:f.y});return}let r=n.object,o=mt(n),s=o?.index??null;a.has(r)&&s===l||(v(),a.add(r),l=s,y(r,o?.member??null),i.events?.onObjectSelected?.(r),o?i.events?.onMeshMetadataClicked?.({source:r.userData?.source,name:o.member.name,layer:o.member.layer,trackingKey:o.member.trackingKey,metadata:o.member.metadata}):r instanceof c.Mesh&&Object.keys(r.userData).length>0&&i.events?.onMeshMetadataClicked?.(r.userData))},E=e=>{let t=C(e.clientX,e.clientY);if(!t)return;let n=t.object;if(i.events?.onMeshDoubleClicked?.(n),!i.events?.enableDoubleClickZoom)return;let a=mt(t),o=a&&n instanceof c.Mesh?ht(n,a.member):new c.Box3().setFromObject(n);o.isEmpty()||r.frameBounds(o,!0)},D=e=>{if(i.events?.enableKeyboardControls)switch(e.key.toLowerCase()){case`f`:e.preventDefault(),g();break;case`escape`:e.preventDefault(),v();break;case` `:e.preventDefault(),g()}};return i.events?.enableClickToFocus&&(e.addEventListener(`mousedown`,w),e.addEventListener(`click`,T),e.addEventListener(`dblclick`,E)),i.events?.enableKeyboardControls&&(e.setAttribute(`tabindex`,`0`),e.addEventListener(`keydown`,D)),{dispose:()=>{e.removeEventListener(`mousedown`,w),e.removeEventListener(`click`,T),e.removeEventListener(`dblclick`,E),e.removeEventListener(`keydown`,D),v()},fitToView:g,clearSelection:v}}function yt(e,t){let n=new c.AmbientLight(t.lighting.ambientLightColor,t.lighting.ambientLightIntensity);e.add(n);let r=null;if(t.lighting.enableHemisphereLight){r=new c.HemisphereLight(t.lighting.hemisphereSkyColor,t.lighting.hemisphereGroundColor,t.lighting.hemisphereIntensity);let n=t.environment.sceneUp??Z;r.position.copy(n),e.add(r)}if(!t.lighting.enableSunlight)return{ambient:n,hemisphere:r,sun:null};let i=new c.DirectionalLight(t.lighting.sunlightColor??16777215,t.lighting.sunlightIntensity),a=t.lighting.sunlightPosition;return a&&i.position.set(a.x,a.y,a.z),t.render.enableShadows?(i.castShadow=!0,i.shadow.mapSize.width=t.render.shadowMapSize||2048,i.shadow.mapSize.height=t.render.shadowMapSize||2048,i.shadow.bias=-1e-4,i.shadow.normalBias=.02,i.shadow.radius=4,e.add(i),e.add(i.target),{ambient:n,hemisphere:r,sun:i}):(e.add(i),{ambient:n,hemisphere:r,sun:null})}function bt(e,t){if(t.isEmpty())return;let n=t.getCenter(new c.Vector3),r=t.getSize(new c.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(n),e.target.updateMatrixWorld();let a=e.position.distanceTo(n);i.near=Math.max(r*.01,a-r),i.far=a+r,i.updateProjectionMatrix()}function xt(e,t,n){let r=new c.WebGLRenderer({antialias:t.render.antialias,canvas:e,alpha:!0,powerPreference:`high-performance`,preserveDrawingBuffer:t.render.preserveDrawingBuffer,logarithmicDepthBuffer:!1}),i=e.parentElement,a=i?i.clientWidth:window.innerWidth,o=i?i.clientHeight:window.innerHeight;return i&&(e.style.width=`100%`,e.style.height=`100%`,e.style.display=`block`),r.setSize(a,o,!1),r.setPixelRatio(n),t.render.enableShadows&&(r.shadowMap.enabled=!0,r.shadowMap.type=c.VSMShadowMap),r.toneMapping=t.render.toneMapping,r.toneMappingExposure=t.render.toneMappingExposure??1,r.outputColorSpace=c.SRGBColorSpace,r.sortObjects=!0,r}const St=function(e,t){let n=$e(t||{}),r=n.environment?.sceneUp||Z,a=n.render.pixelRatio??Math.min(window.devicePixelRatio,2),s=at(n),l=it(n,e);l.up.copy(r);let u=xt(e,n,a);i(u.capabilities.getMaxAnisotropy()),t?.onMaxAnisotropy?.(u.capabilities.getMaxAnisotropy());let d=ut(l,e,n),f=ae({scene:s,perspective:l,controls:d,onActiveCameraChange:()=>{},up:r}),p=()=>f.getActiveCamera(),m=!1;dt(s,u,n,()=>m);let h=yt(s,n),g=h.sun,_=()=>{g&&bt(g,H(s))};n.floor?.enabled&&ft(s,n);let v=n.floor?.enabled?s.children.find(e=>e.userData.id===`floor`)??null:null,y=n.grid.enabled?Re({cellSize:n.grid.cellSize,majorEvery:n.grid.majorEvery,cellColor:n.grid.cellColor,majorColor:n.grid.majorColor,fadeDistance:n.grid.fadeDistance,plane:n.grid.plane}):null;y&&s.add(y.object);let b=()=>{y&&y.fitToContent(H(s))},x=n.gizmo.enabled?Ze({camera:l,domElement:e,controller:f}):null,S=n.grid.plane??ne(r),C=new c.Vector3(+(S===`x`),+(S===`y`),+(S===`z`)),w=r.clone().normalize(),T=n.camera.dynamicNear?Je({camera:l,scene:s,groundNormals:()=>{let e=[];return y?.object.visible&&e.push(C),n.floor.enabled&&v?.visible&&e.push(w),e}}):null,E=ze(e.parentElement??e,s),D=n.measure.enabled?Ke({canvas:e,scene:s,getActiveCamera:p,labelLayer:E,options:{snapPixels:n.measure.snapPixels,color:n.measure.color,labelClassName:n.measure.labelClassName,displayUnit:n.measure.displayUnit,format:n.measure.format}}):null,O=n.events.enableEventHandlers===!1?{dispose:()=>{},fitToView:()=>{},clearSelection:()=>{}}:vt(e,s,f,n),k=Ye();D&&k.register({id:`measure`,tool:D,priority:0}),x&&k.register({id:`gizmo`,tool:x,priority:-100});let A=0,M=0,P=e=>{A=e.clientX,M=e.clientY},F=e=>Math.hypot(e.clientX-A,e.clientY-M)>5,I=e=>{F(e)||k.handleClick(e)&&e.stopImmediatePropagation()};e.addEventListener(`mousedown`,P,{capture:!0}),e.addEventListener(`click`,I,{capture:!0});let L=e=>k.handleMove(e);e.addEventListener(`mousemove`,L,{passive:!0});let R=()=>{},te=(e,t)=>{Fe(e,{color:n.edges.color,darken:n.edges.darken,width:n.edges.width,thresholdAngle:n.edges.thresholdAngle,distanceFade:n.edges.distanceFade,maxTriangles:n.edges.maxTriangles,maxSegments:n.edges.maxSegments,maxOverlays:n.edges.maxOverlays,...t}).then(()=>{z(e),R()})},z=e=>{if(n.edges.screenSpaceFallback===!1)return;let t=!1;e.traverse(e=>{let n=e.userData?.edgesSkipped;(n===`triangle-cap`||n===`overlay-budget`)&&(t=!0)}),U.setEdgeFallback(t)},re=e=>{Ie(e),U.setEdgeFallback(!1),R()},B=e.parentElement,V=()=>B?{width:B.clientWidth,height:B.clientHeight}:{width:window.innerWidth,height:window.innerHeight},U=lt({renderer:u,scene:s,getActiveCamera:p,getCanvasSize:V,pixelRatio:a,config:n,requestRender:()=>R()});U.sync();let W=rt({scene:s,renderer:u,lights:h,config:n,pipeline:U,requestRender:()=>R()}),{animate:ie,dispose:oe,invalidate:G,renderNow:se}=Qe(u,s,l,p,f,d,V,a,n.events.onFrame,y,x,()=>U.get(),E,T,n.render.onDemand??!0);return R=G,ie(),s.up.set(r.x,r.y,r.z),_(),b(),{scene:s,camera:l,controls:d,renderer:u,cameraController:f,grid:y,gizmo:x,measureTool:D,labelLayer:E,tools:k,applyEdges:te,clearEdges:re,invalidate:G,captureImage:(e=`image/png`,t)=>(se(),new Promise(n=>u.domElement.toBlob(n,e,t))),setAmbientOcclusion:U.setAmbientOcclusion,setLook:W.setLook,setFillLights:W.setFillLights,setEnvironmentIntensity:W.setEnvironmentIntensity,setToneMappingExposure:W.setToneMappingExposure,setAoIntensity:W.setAoIntensity,getMaterialAppearance:W.getMaterialAppearance,updateShadowBounds:_,updateGridScale:b,dispose:()=>{m||(m=!0,oe(),O.dispose(),e.removeEventListener(`mousedown`,P,{capture:!0}),e.removeEventListener(`click`,I,{capture:!0}),e.removeEventListener(`mousemove`,L),D?.dispose(),E?.dispose(),x?.dispose(),y?.dispose(),U.dispose(),f.dispose(),d.dispose(),u.dispose(),u.forceContextLoss(),ot(s))},fitToView:O.fitToView,clearSelection:O.clearSelection,addUserGeometry:(e,t)=>{e.userData.source=t===void 0?j:N(t),s.add(e),R()},removeUserGeometry:e=>{e.removeFromParent(),o(e),R()},clearUserGeometry:e=>{s.children.filter(t=>ee(t,e)).forEach(e=>{e.removeFromParent(),o(e)}),R()}}};export{D as DEFAULT_LOOK,s as ErrorCodes,E as LOOKS,O as LOOK_PRESETS,A as SOURCE_COMPUTE,j as SOURCE_USER,n as VisualizationError,P as appIdFromSource,N as appSource,a as enableDebugLogging,t as getLogger,St as initThree,F as isHostOwned,ee as isOwnedBy,k as materialAppearanceForLook,Ue as pickThreshold,Xe as pointerToNdc,r as setLogger,Ge as snapToVertex,re as updateScene};
|
|
108
108
|
//# sourceMappingURL=render.js.map
|