@selvajs/visualization 1.6.0-beta.1 → 1.6.0-beta.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/gpu-dispose-BKp7iijv.js +355 -0
  2. package/dist/gpu-dispose-BKp7iijv.js.map +1 -0
  3. package/dist/gpu-dispose-Cxu3dFmA.cjs +469 -0
  4. package/dist/gpu-dispose-Cxu3dFmA.cjs.map +1 -0
  5. package/dist/gpu-ownership-ADRZBxxs.cjs +102 -0
  6. package/dist/gpu-ownership-ADRZBxxs.cjs.map +1 -0
  7. package/dist/gpu-ownership-Bs9l7hrU.js +40 -0
  8. package/dist/gpu-ownership-Bs9l7hrU.js.map +1 -0
  9. package/dist/index.js +1 -1
  10. package/dist/merged-draw-CO4rr2Co.js +129 -0
  11. package/dist/merged-draw-CO4rr2Co.js.map +1 -0
  12. package/dist/merged-draw-ma_2r4N8.cjs +171 -0
  13. package/dist/merged-draw-ma_2r4N8.cjs.map +1 -0
  14. package/dist/parse.cjs +2789 -11
  15. package/dist/parse.cjs.map +1 -1
  16. package/dist/parse.d.cts +15 -18
  17. package/dist/parse.d.ts +15 -18
  18. package/dist/parse.js +2780 -11
  19. package/dist/parse.js.map +1 -1
  20. package/dist/render.cjs +4302 -6
  21. package/dist/render.cjs.map +1 -1
  22. package/dist/render.d.cts +62 -43
  23. package/dist/render.d.ts +62 -43
  24. package/dist/render.js +4281 -6
  25. package/dist/render.js.map +1 -1
  26. package/dist/scene.cjs +343 -1
  27. package/dist/scene.cjs.map +1 -1
  28. package/dist/scene.d.cts +0 -12
  29. package/dist/scene.d.ts +0 -12
  30. package/dist/scene.js +336 -1
  31. package/dist/scene.js.map +1 -1
  32. package/dist/{types-DjPelPRM.d.ts → types-DW_qU4-Y.d.cts} +22 -5
  33. package/dist/{types-DjPelPRM.d.cts → types-DW_qU4-Y.d.ts} +22 -5
  34. package/package.json +18 -11
  35. package/dist/gpu-dispose-Dich0oW7.js +0 -2
  36. package/dist/gpu-dispose-Dich0oW7.js.map +0 -1
  37. package/dist/gpu-dispose-GZmNW-gK.cjs +0 -2
  38. package/dist/gpu-dispose-GZmNW-gK.cjs.map +0 -1
  39. package/dist/merged-draw-B75jHIzV.cjs +0 -2
  40. package/dist/merged-draw-B75jHIzV.cjs.map +0 -1
  41. package/dist/merged-draw-BPhBYH-v.js +0 -2
  42. package/dist/merged-draw-BPhBYH-v.js.map +0 -1
  43. package/dist/rolldown-runtime-BocRIvOZ.cjs +0 -1
package/dist/render.d.cts CHANGED
@@ -1,9 +1,9 @@
1
- import { a as MaterialAppearanceOptions, i as LookPreset, n as Look, r as LookMaterialOverride, t as LOOKS } from "./types-DjPelPRM.cjs";
1
+ import { a as LookPreset, i as LookMaterialOverride, n as LOOKS, o as MaterialAppearanceOptions, r as Look, t as BloomOptions } from "./types-DW_qU4-Y.cjs";
2
2
  import * as THREE from "three";
3
3
  import { OrbitControls } from "three/addons/controls/OrbitControls.js";
4
4
  import "three/addons/lines/LineSegments2.js";
5
5
  import { CSS2DObject } from "three/addons/renderers/CSS2DRenderer.js";
6
- //#region src/shared/errors.d.ts
6
+ import "three/addons/postprocessing/Pass.js";
7
7
  /**
8
8
  * Errors for the visualization package. Replaces `@selvajs/compute`'s `RhinoComputeError`, which
9
9
  * mis-named failures on paths (e.g. the plugin WebSocket) that never touch Rhino.Compute. `code`
@@ -30,8 +30,6 @@ export declare class VisualizationError extends Error {
30
30
  originalError?: Error;
31
31
  });
32
32
  }
33
- //#endregion
34
- //#region src/shared/logger.d.ts
35
33
  /**
36
34
  * Logging facility for the visualization package. Deliberately local rather than imported from
37
35
  * `@selvajs/compute` (logging isn't a compute concern). Mirrors compute's logger shape so a host
@@ -46,8 +44,6 @@ interface Logger {
46
44
  export declare function getLogger(): Logger;
47
45
  export declare function setLogger(logger: Logger | Console | null): void;
48
46
  export declare function enableDebugLogging(): void;
49
- //#endregion
50
- //#region src/shared/looks.d.ts
51
47
  /** The look applied when the caller passes no `look` option. */
52
48
  export declare const DEFAULT_LOOK: Look;
53
49
  /**
@@ -62,8 +58,6 @@ export declare const DEFAULT_LOOK: Look;
62
58
  export declare const LOOK_PRESETS: Record<Look, LookPreset>;
63
59
  /** Baked at parse time (not toggleable at runtime). */
64
60
  export declare function materialAppearanceForLook(look: Look): MaterialAppearanceOptions;
65
- //#endregion
66
- //#region src/render/types.d.ts
67
61
  type CameraConfig = {
68
62
  position?: THREE.Vector3;
69
63
  fov?: number;
@@ -128,8 +122,26 @@ type RenderConfig = {
128
122
  toneMapping?: THREE.ToneMapping;
129
123
  toneMappingExposure?: number;
130
124
  preserveDrawingBuffer?: boolean;
125
+ /**
126
+ * Cuts what the look's `lowPower` fields name; only `night` has any. Default: on for a touch
127
+ * device with a phone-sized screen. Set it to force the tier on or off.
128
+ */
129
+ lowPower?: boolean;
130
+ /**
131
+ * Frames averaged while the camera rests, for soft shadows and clean edges. Needs the composer,
132
+ * so looks without AO or bloom skip it. Costs nothing while orbiting. Default 32, or 0 on a
133
+ * `lowPower` device; 0 turns it off.
134
+ */
135
+ idleRefineFrames?: number;
136
+ /**
137
+ * Orbit frames slower than this fade ambient occlusion out while the camera moves, its largest
138
+ * cost. Needs `idleRefineFrames` to fade back in. Default 22. 0 always does; `Infinity` never does.
139
+ */
140
+ lightOrbitFrameMs?: number;
131
141
  /** Default false — switches rendering from `renderer.render` to an EffectComposer, which costs more. */
132
142
  ambientOcclusion?: boolean;
143
+ /** Glow around emissive parts. The look decides; `night` sets it. */
144
+ bloom?: BloomOptions;
133
145
  /** AO strength 0–1 when {@link RenderConfig.ambientOcclusion} is on. Default 1. */
134
146
  aoIntensity?: number;
135
147
  /**
@@ -158,7 +170,7 @@ type EdgesConfig = {
158
170
  thresholdAngle?: number;
159
171
  /** Default true. */
160
172
  distanceFade?: boolean;
161
- /** Default 4M. */
173
+ /** Default 8M. */
162
174
  maxTriangles?: number;
163
175
  /** Default 2M. */
164
176
  maxSegments?: number;
@@ -262,8 +274,6 @@ type EventConfig = {
262
274
  /** Fires every animation frame, after controls update and before render. */
263
275
  onFrame?: (delta: number) => void;
264
276
  };
265
- //#endregion
266
- //#region src/render/camera-controller.d.ts
267
277
  /**
268
278
  * Runtime camera control: preset views, perspective⇄orthographic toggle, rotate lock.
269
279
  *
@@ -296,8 +306,6 @@ interface CameraController {
296
306
  /** Cancel any in-flight camera tween. Call on viewer teardown so ticks can't touch disposed controls. */
297
307
  dispose(): void;
298
308
  }
299
- //#endregion
300
- //#region src/render/edges/options.d.ts
301
309
  /** Crisp boundary/crease edges overlaid on meshes. See the layer README for depth/perf strategy. */
302
310
  interface EdgeOptions {
303
311
  /** Default: each overlay derives its color from its own mesh's material (see {@link DEFAULT_EDGE_COLOR}). */
@@ -316,9 +324,9 @@ interface EdgeOptions {
316
324
  */
317
325
  distanceFade?: boolean;
318
326
  /**
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
327
+ * Skip meshes above this triangle count entirely (default 8M). Extraction time and memory are
328
+ * linear in triangles: 8M is about 0.7 s in the worker and a few hundred MB of scratch, and past it
329
+ * the screen-space fallback approximates the look at constant cost. Skipped meshes are tagged
322
330
  * `userData.edgesSkipped = 'triangle-cap'`.
323
331
  */
324
332
  maxTriangles?: number;
@@ -341,8 +349,6 @@ interface EdgeOptions {
341
349
  */
342
350
  maxOverlays?: number;
343
351
  }
344
- //#endregion
345
- //#region src/render/grid.d.ts
346
352
  interface Grid {
347
353
  /** Tagged `userData.id = 'grid'` so pick/fit code skips it. */
348
354
  readonly object: THREE.Mesh;
@@ -356,8 +362,6 @@ interface Grid {
356
362
  setVisible(visible: boolean): void;
357
363
  dispose(): void;
358
364
  }
359
- //#endregion
360
- //#region src/render/label-layer.d.ts
361
365
  interface LabelHandle {
362
366
  readonly object: CSS2DObject;
363
367
  setPosition(position: THREE.Vector3): void;
@@ -371,15 +375,14 @@ interface LabelLayer {
371
375
  setSize(width: number, height: number): void;
372
376
  dispose(): void;
373
377
  }
374
- //#endregion
375
- //#region src/render/measure.d.ts
376
378
  /**
377
- * Two-click distance measurement. Click a point, click a second, read the distance off a label on
378
- * the connecting line; a third click starts fresh.
379
+ * Point-to-point distance measurement. Click a start point; a rubber band and live readout follow
380
+ * the cursor until the second click commits it. Committed measurements stay until Escape (which
381
+ * first drops an unfinished start point) or until the tool is disabled.
379
382
  *
380
- * Picking snaps to the nearest vertex within {@link MeasureOptions.snapPixels} so measurements
381
- * land exactly on vertices rather than wherever the ray happened to hit — a cheap local snap
382
- * against the struck primitive's own vertices, no spatial index.
383
+ * Picking snaps to the nearest vertex of the struck triangle, segment or point within
384
+ * {@link MeasureOptions.snapPixels}; the hover marker turns solid when it has snapped. Meshes are
385
+ * picked through a BVH (`scene-pick.ts`), so hovering stays cheap on large models.
383
386
  *
384
387
  * Dormant until {@link MeasureTool.setEnabled}(true). While enabled it intercepts clicks (caller
385
388
  * forwards them and swallows the event when {@link MeasureTool.handleClick} returns true) so
@@ -390,8 +393,10 @@ interface MeasureTool {
390
393
  isEnabled(): boolean;
391
394
  /** Returns true if the tool consumed the click (caller should not also select). */
392
395
  handleClick(event: MouseEvent): boolean;
393
- /** Preview the next snap point via a ghost marker. No-op when disabled; never consumes the event. */
396
+ /** Preview the next snap point and the rubber band. No-op when disabled; never consumes the event. */
394
397
  handleMove(event: MouseEvent): void;
398
+ /** Drops the unfinished start point, or every measurement when there is none. Bound to Escape. */
399
+ cancel(): void;
395
400
  clear(): void;
396
401
  dispose(): void;
397
402
  }
@@ -409,8 +414,6 @@ export declare function snapToVertex(hit: THREE.Intersection, camera: THREE.Came
409
414
  width: number;
410
415
  height: number;
411
416
  }, snapPixels: number): THREE.Vector3;
412
- //#endregion
413
- //#region src/render/tool-registry.d.ts
414
417
  /**
415
418
  * A tool that can claim canvas pointer input.
416
419
  *
@@ -463,8 +466,6 @@ export declare function pointerToNdc(event: MouseEvent, canvas: HTMLCanvasElemen
463
466
  x: number;
464
467
  y: number;
465
468
  };
466
- //#endregion
467
- //#region src/render/view-gizmo.d.ts
468
469
  /**
469
470
  * Corner nav-cube/axis gizmo. Uses three's {@link ViewHelper} only as the rendered widget, not its
470
471
  * click→animate behavior: ViewHelper's snap assumes Y-up and animates straight onto the up axis,
@@ -486,8 +487,18 @@ interface ViewGizmo {
486
487
  isVisible(): boolean;
487
488
  dispose(): void;
488
489
  }
489
- //#endregion
490
- //#region src/render/scene-setup/viewer.d.ts
490
+ type SetLookOptions = {
491
+ /**
492
+ * Skips the sync, which walks every glowing part. The caller runs `syncEmissiveLights()` itself
493
+ * once visibility settles.
494
+ */
495
+ deferEmissiveLights?: boolean;
496
+ };
497
+ /** One thing to select: a whole object, or one member of a merged mesh. */
498
+ interface SelectionTarget {
499
+ object: THREE.Object3D;
500
+ memberIndex: number | null;
501
+ }
491
502
  interface ThreeViewer {
492
503
  scene: THREE.Scene;
493
504
  camera: THREE.PerspectiveCamera;
@@ -534,7 +545,12 @@ interface ThreeViewer {
534
545
  * Retunes lighting/material (tone mapping, fill, IBL, AO) only — never edges/grid. Overwrites
535
546
  * any granular lighting dials set earlier with the preset's values.
536
547
  */
537
- setLook: (look: Look) => void;
548
+ setLook: (look: Look, options?: SetLookOptions) => void;
549
+ /**
550
+ * Call after showing or hiding objects, solve output included: a look that lights the scene from
551
+ * glowing parts reads what is drawn when it runs, so a hidden lamp would keep shining.
552
+ */
553
+ syncEmissiveLights: () => void;
538
554
  /**
539
555
  * Raising `hemisphereIntensity` is the most effective way to lift shadowed surfaces a dark HDR
540
556
  * leaves black. Lazily creates the hemisphere light if the viewer was built without one; `0` turns
@@ -563,6 +579,16 @@ interface ThreeViewer {
563
579
  dispose: () => void;
564
580
  fitToView: () => void;
565
581
  clearSelection: () => void;
582
+ /**
583
+ * Selects from outside the viewport (an outliner's rows), replacing any current selection and
584
+ * firing no events. `[]` drops a selection made here and leaves one made by a canvas click.
585
+ */
586
+ selectEntries: (targets: SelectionTarget[]) => void;
587
+ /**
588
+ * Tints one object, or one member of a merged mesh, as a preview (an outliner row under the
589
+ * pointer), lighter than a selection. `null` clears it. A selected object keeps its selection tint.
590
+ */
591
+ setHover: (object: THREE.Object3D | null, memberIndex?: number | null) => void;
566
592
  /**
567
593
  * Adds host-owned geometry that survives `updateScene` solves and counts for fit-to-view.
568
594
  * Pass `appId` to scope it to one app (`userData.source = 'app:<id>'`) so `clearUserGeometry`
@@ -575,11 +601,7 @@ interface ThreeViewer {
575
601
  /** Removes and disposes geometry added via `addUserGeometry` — one app's, or all of it. */
576
602
  clearUserGeometry: (appId?: string) => void;
577
603
  }
578
- //#endregion
579
- //#region src/render/scene-setup/init-three.d.ts
580
604
  export declare const initThree: (canvas: HTMLCanvasElement, options?: ThreeInitializerOptions) => ThreeViewer;
581
- //#endregion
582
- //#region src/render/scene-ownership.d.ts
583
605
  /** Geometry produced by a solve. Replaced wholesale on the next one. */
584
606
  export declare const SOURCE_COMPUTE = "compute";
585
607
  /**
@@ -601,10 +623,7 @@ export declare function isHostOwned(object: THREE.Object3D): boolean;
601
623
  * `clearUserGeometry()` does.
602
624
  */
603
625
  export declare function isOwnedBy(object: THREE.Object3D, id?: string): boolean;
604
- //#endregion
605
- //#region src/render/three-helpers.d.ts
606
626
  /** Replaces scene content with `meshes`, rescales the camera frustum to fit, and (first call only) positions the camera/controls. */
607
627
  export declare function updateScene(scene: THREE.Scene, meshes: THREE.Object3D[], camera: THREE.PerspectiveCamera, controls: OrbitControls, initialPositionSet: boolean): void;
608
- //#endregion
609
- export { type CameraConfig, type CameraController, type CameraProjection, type ControlsConfig, type EdgesConfig, type EnvironmentConfig, type ErrorCode, type EventConfig, type FloorConfig, type GizmoConfig, type Grid, type GridConfig, LOOKS, type LabelHandle, type LabelLayer, type LightingConfig, type Logger, type Look, type LookMaterialOverride, type LookPreset, type MaterialAppearanceOptions, type MeasureConfig, type MeasureTool, type PointerTool, type RenderConfig, type ThreeInitializerOptions, type ThreeViewer, type ToolRegistration, type ToolRegistry, type ViewGizmo, type ViewPreset };
628
+ export { type CameraConfig, type CameraController, type CameraProjection, type ControlsConfig, type EdgesConfig, type EnvironmentConfig, type ErrorCode, type EventConfig, type FloorConfig, type GizmoConfig, type Grid, type GridConfig, LOOKS, type LabelHandle, type LabelLayer, type LightingConfig, type Logger, type Look, type LookMaterialOverride, type LookPreset, type MaterialAppearanceOptions, type MeasureConfig, type MeasureTool, type PointerTool, type RenderConfig, type SetLookOptions, type ThreeInitializerOptions, type ThreeViewer, type ToolRegistration, type ToolRegistry, type ViewGizmo, type ViewPreset };
610
629
  //# sourceMappingURL=render.d.cts.map
package/dist/render.d.ts CHANGED
@@ -1,9 +1,9 @@
1
- import { a as MaterialAppearanceOptions, i as LookPreset, n as Look, r as LookMaterialOverride, t as LOOKS } from "./types-DjPelPRM.js";
1
+ import { a as LookPreset, i as LookMaterialOverride, n as LOOKS, o as MaterialAppearanceOptions, r as Look, t as BloomOptions } from "./types-DW_qU4-Y.js";
2
2
  import * as THREE from "three";
3
3
  import { LineSegments2 } from "three/addons/lines/LineSegments2.js";
4
4
  import { CSS2DObject } from "three/addons/renderers/CSS2DRenderer.js";
5
+ import { Pass } from "three/addons/postprocessing/Pass.js";
5
6
  import { OrbitControls } from "three/addons/controls/OrbitControls.js";
6
- //#region src/shared/errors.d.ts
7
7
  /**
8
8
  * Errors for the visualization package. Replaces `@selvajs/compute`'s `RhinoComputeError`, which
9
9
  * mis-named failures on paths (e.g. the plugin WebSocket) that never touch Rhino.Compute. `code`
@@ -30,8 +30,6 @@ export declare class VisualizationError extends Error {
30
30
  originalError?: Error;
31
31
  });
32
32
  }
33
- //#endregion
34
- //#region src/shared/logger.d.ts
35
33
  /**
36
34
  * Logging facility for the visualization package. Deliberately local rather than imported from
37
35
  * `@selvajs/compute` (logging isn't a compute concern). Mirrors compute's logger shape so a host
@@ -46,8 +44,6 @@ interface Logger {
46
44
  export declare function getLogger(): Logger;
47
45
  export declare function setLogger(logger: Logger | Console | null): void;
48
46
  export declare function enableDebugLogging(): void;
49
- //#endregion
50
- //#region src/shared/looks.d.ts
51
47
  /** The look applied when the caller passes no `look` option. */
52
48
  export declare const DEFAULT_LOOK: Look;
53
49
  /**
@@ -62,8 +58,6 @@ export declare const DEFAULT_LOOK: Look;
62
58
  export declare const LOOK_PRESETS: Record<Look, LookPreset>;
63
59
  /** Baked at parse time (not toggleable at runtime). */
64
60
  export declare function materialAppearanceForLook(look: Look): MaterialAppearanceOptions;
65
- //#endregion
66
- //#region src/render/types.d.ts
67
61
  type CameraConfig = {
68
62
  position?: THREE.Vector3;
69
63
  fov?: number;
@@ -128,8 +122,26 @@ type RenderConfig = {
128
122
  toneMapping?: THREE.ToneMapping;
129
123
  toneMappingExposure?: number;
130
124
  preserveDrawingBuffer?: boolean;
125
+ /**
126
+ * Cuts what the look's `lowPower` fields name; only `night` has any. Default: on for a touch
127
+ * device with a phone-sized screen. Set it to force the tier on or off.
128
+ */
129
+ lowPower?: boolean;
130
+ /**
131
+ * Frames averaged while the camera rests, for soft shadows and clean edges. Needs the composer,
132
+ * so looks without AO or bloom skip it. Costs nothing while orbiting. Default 32, or 0 on a
133
+ * `lowPower` device; 0 turns it off.
134
+ */
135
+ idleRefineFrames?: number;
136
+ /**
137
+ * Orbit frames slower than this fade ambient occlusion out while the camera moves, its largest
138
+ * cost. Needs `idleRefineFrames` to fade back in. Default 22. 0 always does; `Infinity` never does.
139
+ */
140
+ lightOrbitFrameMs?: number;
131
141
  /** Default false — switches rendering from `renderer.render` to an EffectComposer, which costs more. */
132
142
  ambientOcclusion?: boolean;
143
+ /** Glow around emissive parts. The look decides; `night` sets it. */
144
+ bloom?: BloomOptions;
133
145
  /** AO strength 0–1 when {@link RenderConfig.ambientOcclusion} is on. Default 1. */
134
146
  aoIntensity?: number;
135
147
  /**
@@ -158,7 +170,7 @@ type EdgesConfig = {
158
170
  thresholdAngle?: number;
159
171
  /** Default true. */
160
172
  distanceFade?: boolean;
161
- /** Default 4M. */
173
+ /** Default 8M. */
162
174
  maxTriangles?: number;
163
175
  /** Default 2M. */
164
176
  maxSegments?: number;
@@ -262,8 +274,6 @@ type EventConfig = {
262
274
  /** Fires every animation frame, after controls update and before render. */
263
275
  onFrame?: (delta: number) => void;
264
276
  };
265
- //#endregion
266
- //#region src/render/camera-controller.d.ts
267
277
  /**
268
278
  * Runtime camera control: preset views, perspective⇄orthographic toggle, rotate lock.
269
279
  *
@@ -296,8 +306,6 @@ interface CameraController {
296
306
  /** Cancel any in-flight camera tween. Call on viewer teardown so ticks can't touch disposed controls. */
297
307
  dispose(): void;
298
308
  }
299
- //#endregion
300
- //#region src/render/edges/options.d.ts
301
309
  /** Crisp boundary/crease edges overlaid on meshes. See the layer README for depth/perf strategy. */
302
310
  interface EdgeOptions {
303
311
  /** Default: each overlay derives its color from its own mesh's material (see {@link DEFAULT_EDGE_COLOR}). */
@@ -316,9 +324,9 @@ interface EdgeOptions {
316
324
  */
317
325
  distanceFade?: boolean;
318
326
  /**
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
327
+ * Skip meshes above this triangle count entirely (default 8M). Extraction time and memory are
328
+ * linear in triangles: 8M is about 0.7 s in the worker and a few hundred MB of scratch, and past it
329
+ * the screen-space fallback approximates the look at constant cost. Skipped meshes are tagged
322
330
  * `userData.edgesSkipped = 'triangle-cap'`.
323
331
  */
324
332
  maxTriangles?: number;
@@ -341,8 +349,6 @@ interface EdgeOptions {
341
349
  */
342
350
  maxOverlays?: number;
343
351
  }
344
- //#endregion
345
- //#region src/render/grid.d.ts
346
352
  interface Grid {
347
353
  /** Tagged `userData.id = 'grid'` so pick/fit code skips it. */
348
354
  readonly object: THREE.Mesh;
@@ -356,8 +362,6 @@ interface Grid {
356
362
  setVisible(visible: boolean): void;
357
363
  dispose(): void;
358
364
  }
359
- //#endregion
360
- //#region src/render/label-layer.d.ts
361
365
  interface LabelHandle {
362
366
  readonly object: CSS2DObject;
363
367
  setPosition(position: THREE.Vector3): void;
@@ -371,15 +375,14 @@ interface LabelLayer {
371
375
  setSize(width: number, height: number): void;
372
376
  dispose(): void;
373
377
  }
374
- //#endregion
375
- //#region src/render/measure.d.ts
376
378
  /**
377
- * Two-click distance measurement. Click a point, click a second, read the distance off a label on
378
- * the connecting line; a third click starts fresh.
379
+ * Point-to-point distance measurement. Click a start point; a rubber band and live readout follow
380
+ * the cursor until the second click commits it. Committed measurements stay until Escape (which
381
+ * first drops an unfinished start point) or until the tool is disabled.
379
382
  *
380
- * Picking snaps to the nearest vertex within {@link MeasureOptions.snapPixels} so measurements
381
- * land exactly on vertices rather than wherever the ray happened to hit — a cheap local snap
382
- * against the struck primitive's own vertices, no spatial index.
383
+ * Picking snaps to the nearest vertex of the struck triangle, segment or point within
384
+ * {@link MeasureOptions.snapPixels}; the hover marker turns solid when it has snapped. Meshes are
385
+ * picked through a BVH (`scene-pick.ts`), so hovering stays cheap on large models.
383
386
  *
384
387
  * Dormant until {@link MeasureTool.setEnabled}(true). While enabled it intercepts clicks (caller
385
388
  * forwards them and swallows the event when {@link MeasureTool.handleClick} returns true) so
@@ -390,8 +393,10 @@ interface MeasureTool {
390
393
  isEnabled(): boolean;
391
394
  /** Returns true if the tool consumed the click (caller should not also select). */
392
395
  handleClick(event: MouseEvent): boolean;
393
- /** Preview the next snap point via a ghost marker. No-op when disabled; never consumes the event. */
396
+ /** Preview the next snap point and the rubber band. No-op when disabled; never consumes the event. */
394
397
  handleMove(event: MouseEvent): void;
398
+ /** Drops the unfinished start point, or every measurement when there is none. Bound to Escape. */
399
+ cancel(): void;
395
400
  clear(): void;
396
401
  dispose(): void;
397
402
  }
@@ -409,8 +414,6 @@ export declare function snapToVertex(hit: THREE.Intersection, camera: THREE.Came
409
414
  width: number;
410
415
  height: number;
411
416
  }, snapPixels: number): THREE.Vector3;
412
- //#endregion
413
- //#region src/render/tool-registry.d.ts
414
417
  /**
415
418
  * A tool that can claim canvas pointer input.
416
419
  *
@@ -463,8 +466,6 @@ export declare function pointerToNdc(event: MouseEvent, canvas: HTMLCanvasElemen
463
466
  x: number;
464
467
  y: number;
465
468
  };
466
- //#endregion
467
- //#region src/render/view-gizmo.d.ts
468
469
  /**
469
470
  * Corner nav-cube/axis gizmo. Uses three's {@link ViewHelper} only as the rendered widget, not its
470
471
  * click→animate behavior: ViewHelper's snap assumes Y-up and animates straight onto the up axis,
@@ -486,8 +487,18 @@ interface ViewGizmo {
486
487
  isVisible(): boolean;
487
488
  dispose(): void;
488
489
  }
489
- //#endregion
490
- //#region src/render/scene-setup/viewer.d.ts
490
+ type SetLookOptions = {
491
+ /**
492
+ * Skips the sync, which walks every glowing part. The caller runs `syncEmissiveLights()` itself
493
+ * once visibility settles.
494
+ */
495
+ deferEmissiveLights?: boolean;
496
+ };
497
+ /** One thing to select: a whole object, or one member of a merged mesh. */
498
+ interface SelectionTarget {
499
+ object: THREE.Object3D;
500
+ memberIndex: number | null;
501
+ }
491
502
  interface ThreeViewer {
492
503
  scene: THREE.Scene;
493
504
  camera: THREE.PerspectiveCamera;
@@ -534,7 +545,12 @@ interface ThreeViewer {
534
545
  * Retunes lighting/material (tone mapping, fill, IBL, AO) only — never edges/grid. Overwrites
535
546
  * any granular lighting dials set earlier with the preset's values.
536
547
  */
537
- setLook: (look: Look) => void;
548
+ setLook: (look: Look, options?: SetLookOptions) => void;
549
+ /**
550
+ * Call after showing or hiding objects, solve output included: a look that lights the scene from
551
+ * glowing parts reads what is drawn when it runs, so a hidden lamp would keep shining.
552
+ */
553
+ syncEmissiveLights: () => void;
538
554
  /**
539
555
  * Raising `hemisphereIntensity` is the most effective way to lift shadowed surfaces a dark HDR
540
556
  * leaves black. Lazily creates the hemisphere light if the viewer was built without one; `0` turns
@@ -563,6 +579,16 @@ interface ThreeViewer {
563
579
  dispose: () => void;
564
580
  fitToView: () => void;
565
581
  clearSelection: () => void;
582
+ /**
583
+ * Selects from outside the viewport (an outliner's rows), replacing any current selection and
584
+ * firing no events. `[]` drops a selection made here and leaves one made by a canvas click.
585
+ */
586
+ selectEntries: (targets: SelectionTarget[]) => void;
587
+ /**
588
+ * Tints one object, or one member of a merged mesh, as a preview (an outliner row under the
589
+ * pointer), lighter than a selection. `null` clears it. A selected object keeps its selection tint.
590
+ */
591
+ setHover: (object: THREE.Object3D | null, memberIndex?: number | null) => void;
566
592
  /**
567
593
  * Adds host-owned geometry that survives `updateScene` solves and counts for fit-to-view.
568
594
  * Pass `appId` to scope it to one app (`userData.source = 'app:<id>'`) so `clearUserGeometry`
@@ -575,11 +601,7 @@ interface ThreeViewer {
575
601
  /** Removes and disposes geometry added via `addUserGeometry` — one app's, or all of it. */
576
602
  clearUserGeometry: (appId?: string) => void;
577
603
  }
578
- //#endregion
579
- //#region src/render/scene-setup/init-three.d.ts
580
604
  export declare const initThree: (canvas: HTMLCanvasElement, options?: ThreeInitializerOptions) => ThreeViewer;
581
- //#endregion
582
- //#region src/render/scene-ownership.d.ts
583
605
  /** Geometry produced by a solve. Replaced wholesale on the next one. */
584
606
  export declare const SOURCE_COMPUTE = "compute";
585
607
  /**
@@ -601,10 +623,7 @@ export declare function isHostOwned(object: THREE.Object3D): boolean;
601
623
  * `clearUserGeometry()` does.
602
624
  */
603
625
  export declare function isOwnedBy(object: THREE.Object3D, id?: string): boolean;
604
- //#endregion
605
- //#region src/render/three-helpers.d.ts
606
626
  /** Replaces scene content with `meshes`, rescales the camera frustum to fit, and (first call only) positions the camera/controls. */
607
627
  export declare function updateScene(scene: THREE.Scene, meshes: THREE.Object3D[], camera: THREE.PerspectiveCamera, controls: OrbitControls, initialPositionSet: boolean): void;
608
- //#endregion
609
- export { type CameraConfig, type CameraController, type CameraProjection, type ControlsConfig, type EdgesConfig, type EnvironmentConfig, type ErrorCode, type EventConfig, type FloorConfig, type GizmoConfig, type Grid, type GridConfig, LOOKS, type LabelHandle, type LabelLayer, type LightingConfig, type Logger, type Look, type LookMaterialOverride, type LookPreset, type MaterialAppearanceOptions, type MeasureConfig, type MeasureTool, type PointerTool, type RenderConfig, type ThreeInitializerOptions, type ThreeViewer, type ToolRegistration, type ToolRegistry, type ViewGizmo, type ViewPreset };
628
+ export { type CameraConfig, type CameraController, type CameraProjection, type ControlsConfig, type EdgesConfig, type EnvironmentConfig, type ErrorCode, type EventConfig, type FloorConfig, type GizmoConfig, type Grid, type GridConfig, LOOKS, type LabelHandle, type LabelLayer, type LightingConfig, type Logger, type Look, type LookMaterialOverride, type LookPreset, type MaterialAppearanceOptions, type MeasureConfig, type MeasureTool, type PointerTool, type RenderConfig, type SetLookOptions, type ThreeInitializerOptions, type ThreeViewer, type ToolRegistration, type ToolRegistry, type ViewGizmo, type ViewPreset };
610
629
  //# sourceMappingURL=render.d.ts.map