@selvajs/visualization 1.0.0-beta.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/LICENSE +21 -0
- package/README.md +113 -0
- package/dist/chunk-5XGN7UAV.js +2 -0
- package/dist/chunk-5XGN7UAV.js.map +1 -0
- package/dist/chunk-AQJPVUH3.cjs +2 -0
- package/dist/chunk-AQJPVUH3.cjs.map +1 -0
- package/dist/chunk-BYLIBOAU.cjs +2 -0
- package/dist/chunk-BYLIBOAU.cjs.map +1 -0
- package/dist/chunk-EXAI6IC5.js +2 -0
- package/dist/chunk-EXAI6IC5.js.map +1 -0
- package/dist/index.cjs +1 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -0
- package/dist/parse.cjs +10 -0
- package/dist/parse.cjs.map +1 -0
- package/dist/parse.d.cts +235 -0
- package/dist/parse.d.ts +235 -0
- package/dist/parse.js +10 -0
- package/dist/parse.js.map +1 -0
- package/dist/render.cjs +110 -0
- package/dist/render.cjs.map +1 -0
- package/dist/render.d.cts +430 -0
- package/dist/render.d.ts +430 -0
- package/dist/render.js +110 -0
- package/dist/render.js.map +1 -0
- package/dist/scene.cjs +2 -0
- package/dist/scene.cjs.map +1 -0
- package/dist/scene.d.cts +110 -0
- package/dist/scene.d.ts +110 -0
- package/dist/scene.js +2 -0
- package/dist/scene.js.map +1 -0
- package/dist/types-CdF9R3qA.d.cts +41 -0
- package/dist/types-CdF9R3qA.d.ts +41 -0
- package/package.json +115 -0
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import { L as Look, a as LookPreset, M as MaterialAppearanceOptions } from './types-CdF9R3qA.cjs';
|
|
3
|
+
export { b as LOOKS } from './types-CdF9R3qA.cjs';
|
|
4
|
+
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Errors for the visualization package. Replaces `@selvajs/compute`'s `RhinoComputeError`, which
|
|
8
|
+
* mis-named failures on paths (e.g. the plugin WebSocket) that never touch Rhino.Compute. `code`
|
|
9
|
+
* values match compute's so existing catch-sites keep working.
|
|
10
|
+
*/
|
|
11
|
+
declare const ErrorCodes: {
|
|
12
|
+
/** Structural check failed: bad magic bytes, out-of-window index, malformed metadata. */
|
|
13
|
+
readonly VALIDATION_ERROR: "VALIDATION_ERROR";
|
|
14
|
+
readonly INVALID_STATE: "INVALID_STATE";
|
|
15
|
+
/** No `DecompressionStream`, no WebGL context, etc. */
|
|
16
|
+
readonly ENVIRONMENT_ERROR: "ENVIRONMENT_ERROR";
|
|
17
|
+
readonly INVALID_CONFIG: "INVALID_CONFIG";
|
|
18
|
+
/** Base64 input could not be decoded. */
|
|
19
|
+
readonly ENCODING_ERROR: "ENCODING_ERROR";
|
|
20
|
+
readonly UNKNOWN_ERROR: "UNKNOWN_ERROR";
|
|
21
|
+
};
|
|
22
|
+
type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];
|
|
23
|
+
declare class VisualizationError extends Error {
|
|
24
|
+
readonly code: ErrorCode;
|
|
25
|
+
readonly context?: Record<string, unknown>;
|
|
26
|
+
readonly originalError?: Error;
|
|
27
|
+
constructor(message: string, code?: ErrorCode, options?: {
|
|
28
|
+
context?: Record<string, unknown>;
|
|
29
|
+
originalError?: Error;
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Logging facility for the visualization package. Deliberately local rather than imported from
|
|
35
|
+
* `@selvajs/compute` (logging isn't a compute concern). Mirrors compute's logger shape so a host
|
|
36
|
+
* wanting one sink for both can call `setLogger(computeLogger.getLogger())`.
|
|
37
|
+
*/
|
|
38
|
+
interface Logger {
|
|
39
|
+
debug(message: string, ...args: unknown[]): void;
|
|
40
|
+
info(message: string, ...args: unknown[]): void;
|
|
41
|
+
warn(message: string, ...args: unknown[]): void;
|
|
42
|
+
error(message: string, ...args: unknown[]): void;
|
|
43
|
+
}
|
|
44
|
+
declare function getLogger(): Logger;
|
|
45
|
+
declare function setLogger(logger: Logger | Console | null): void;
|
|
46
|
+
declare function enableDebugLogging(): void;
|
|
47
|
+
|
|
48
|
+
/** The look applied when the caller passes no `look` option. */
|
|
49
|
+
declare const DEFAULT_LOOK: Look;
|
|
50
|
+
/**
|
|
51
|
+
* Single source of truth for both `applyDefaults` (construction) and `setLook` (runtime), so the two
|
|
52
|
+
* can't drift.
|
|
53
|
+
*
|
|
54
|
+
* `ambientOcclusion: false` on every look: GTAO is a heavy full-screen pass, so it stays opt-in
|
|
55
|
+
* (`render.ambientOcclusion` or `setAmbientOcclusion(true)`) rather than costing every viewer 60fps.
|
|
56
|
+
*/
|
|
57
|
+
declare const LOOK_PRESETS: Record<Look, LookPreset>;
|
|
58
|
+
/** Baked at parse time (not toggleable at runtime). */
|
|
59
|
+
declare function materialAppearanceForLook(look: Look): MaterialAppearanceOptions;
|
|
60
|
+
|
|
61
|
+
type CameraConfig = {
|
|
62
|
+
position?: THREE.Vector3;
|
|
63
|
+
fov?: number;
|
|
64
|
+
near?: number;
|
|
65
|
+
far?: number;
|
|
66
|
+
target?: THREE.Vector3;
|
|
67
|
+
/**
|
|
68
|
+
* Refit the near plane to the camera↔content gap every frame (default true) — recovers
|
|
69
|
+
* depth-buffer precision when zoomed out, preventing distant z-fighting. `near` is only ever
|
|
70
|
+
* raised, never lowered below the configured value.
|
|
71
|
+
*/
|
|
72
|
+
dynamicNear?: boolean;
|
|
73
|
+
};
|
|
74
|
+
type LightingConfig = {
|
|
75
|
+
enableSunlight?: boolean;
|
|
76
|
+
sunlightIntensity?: number;
|
|
77
|
+
sunlightPosition?: THREE.Vector3;
|
|
78
|
+
ambientLightColor?: THREE.Color;
|
|
79
|
+
ambientLightIntensity?: number;
|
|
80
|
+
sunlightColor?: THREE.Color | number;
|
|
81
|
+
/**
|
|
82
|
+
* Direction-aware fill (sky color above, ground color below) so surfaces facing away from the
|
|
83
|
+
* sun don't collapse to black under a dark HDR. Default false — enabling it shifts the look.
|
|
84
|
+
*/
|
|
85
|
+
enableHemisphereLight?: boolean;
|
|
86
|
+
/** Default white. */
|
|
87
|
+
hemisphereSkyColor?: THREE.Color | number;
|
|
88
|
+
/** Default a mid grey. */
|
|
89
|
+
hemisphereGroundColor?: THREE.Color | number;
|
|
90
|
+
/** Default 0.6. Only applies when {@link LightingConfig.enableHemisphereLight}. */
|
|
91
|
+
hemisphereIntensity?: number;
|
|
92
|
+
};
|
|
93
|
+
type EnvironmentConfig = {
|
|
94
|
+
hdrPath?: string;
|
|
95
|
+
backgroundColor?: THREE.Color | string;
|
|
96
|
+
enableEnvironmentLighting?: boolean;
|
|
97
|
+
/**
|
|
98
|
+
* Defaults to `(0, 0, 1)` — Rhino's Z-up, not Three's native Y-up — because geometry arrives in
|
|
99
|
+
* Rhino's frame and is never rotated on ingress. Everything orientation-dependent derives from
|
|
100
|
+
* this (view presets, default camera, sun, grid, floor, hemisphere light), but overriding it
|
|
101
|
+
* reorients the viewer only — it does NOT rotate incoming geometry.
|
|
102
|
+
*/
|
|
103
|
+
sceneUp?: THREE.Vector3;
|
|
104
|
+
showEnvironment?: boolean;
|
|
105
|
+
/**
|
|
106
|
+
* Multiplier on the HDR's image-based lighting contribution — normalizes brightness across HDRs
|
|
107
|
+
* of differing exposure. Default 1 (unchanged look).
|
|
108
|
+
*/
|
|
109
|
+
environmentIntensity?: number;
|
|
110
|
+
};
|
|
111
|
+
type FloorConfig = {
|
|
112
|
+
enabled?: boolean;
|
|
113
|
+
size?: number;
|
|
114
|
+
color?: THREE.Color | string;
|
|
115
|
+
roughness?: number;
|
|
116
|
+
metalness?: number;
|
|
117
|
+
receiveShadow?: boolean;
|
|
118
|
+
};
|
|
119
|
+
type RenderConfig = {
|
|
120
|
+
enableShadows?: boolean;
|
|
121
|
+
shadowMapSize?: number;
|
|
122
|
+
antialias?: boolean;
|
|
123
|
+
pixelRatio?: number;
|
|
124
|
+
toneMapping?: THREE.ToneMapping;
|
|
125
|
+
toneMappingExposure?: number;
|
|
126
|
+
preserveDrawingBuffer?: boolean;
|
|
127
|
+
/** Default false — switches rendering from `renderer.render` to an EffectComposer, which costs more. */
|
|
128
|
+
ambientOcclusion?: boolean;
|
|
129
|
+
/** AO strength 0–1 when {@link RenderConfig.ambientOcclusion} is on. Default 1. */
|
|
130
|
+
aoIntensity?: number;
|
|
131
|
+
/**
|
|
132
|
+
* DPR cap for AO buffers — AO is low-frequency, so sampling below display DPR is nearly invisible
|
|
133
|
+
* but much cheaper (a DPR-2 display would otherwise push 4× the pixels through GTAO's per-pixel
|
|
134
|
+
* sample loop). Default 1; only relevant when AO is enabled.
|
|
135
|
+
*/
|
|
136
|
+
aoPixelRatio?: number;
|
|
137
|
+
/**
|
|
138
|
+
* Render only on change (camera motion, invalidate(), pointer input, resize) plus a ~500ms safety
|
|
139
|
+
* repaint, instead of every frame. Default true — cuts idle GPU/battery use. Set false to restore
|
|
140
|
+
* a continuous loop.
|
|
141
|
+
*/
|
|
142
|
+
onDemand?: boolean;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
/** Crisp boundary/crease edge overlays on meshes. See `addEdges`. */
|
|
146
|
+
type EdgesConfig = {
|
|
147
|
+
/** Default false (opt-in). */
|
|
148
|
+
enabled?: boolean;
|
|
149
|
+
/** Omit (default) to derive each mesh's edge color from its own surface material, darkened by `darken`. */
|
|
150
|
+
color?: THREE.ColorRepresentation;
|
|
151
|
+
/** 0–1, default 0.75. Ignored when `color` is set. */
|
|
152
|
+
darken?: number;
|
|
153
|
+
/** CSS px. Default 1.5. */
|
|
154
|
+
width?: number;
|
|
155
|
+
/** Crease angle in degrees: keep edges where faces differ by more than this. Default 44. */
|
|
156
|
+
thresholdAngle?: number;
|
|
157
|
+
/** Fade an overlay out as its mesh shrinks on screen. Default true. */
|
|
158
|
+
distanceFade?: boolean;
|
|
159
|
+
/** Skip overlay extraction for meshes above this triangle count. Default 4M. */
|
|
160
|
+
maxTriangles?: number;
|
|
161
|
+
/** Overlays above this segment count render opaque (no distance fade). Default 2M. */
|
|
162
|
+
maxSegments?: number;
|
|
163
|
+
/** Meshes skipped for exceeding `maxTriangles` fall back to the screen-space edge-detection pass
|
|
164
|
+
* (constant cost regardless of triangle count). Default true. */
|
|
165
|
+
screenSpaceFallback?: boolean;
|
|
166
|
+
};
|
|
167
|
+
type ControlsConfig = {
|
|
168
|
+
enableDamping?: boolean;
|
|
169
|
+
dampingFactor?: number;
|
|
170
|
+
autoRotate?: boolean;
|
|
171
|
+
autoRotateSpeed?: number;
|
|
172
|
+
enableZoom?: boolean;
|
|
173
|
+
enablePan?: boolean;
|
|
174
|
+
minDistance?: number;
|
|
175
|
+
maxDistance?: number;
|
|
176
|
+
};
|
|
177
|
+
/** Infinite distance-fading reference grid. See `createGrid`. */
|
|
178
|
+
type GridConfig = {
|
|
179
|
+
/** Default false (opt-in). */
|
|
180
|
+
enabled?: boolean;
|
|
181
|
+
/** World units (meters). Default 1. */
|
|
182
|
+
cellSize?: number;
|
|
183
|
+
/** Minor cells per major line. Default 10. */
|
|
184
|
+
majorEvery?: number;
|
|
185
|
+
cellColor?: THREE.ColorRepresentation;
|
|
186
|
+
majorColor?: THREE.ColorRepresentation;
|
|
187
|
+
/** World radius at which the grid fully fades. Default 100. */
|
|
188
|
+
fadeDistance?: number;
|
|
189
|
+
/**
|
|
190
|
+
* Axis the grid lies perpendicular to. Defaults to whichever axis `sceneUp` points along
|
|
191
|
+
* (`'z'` unless `sceneUp` is overridden); set explicitly to force an orientation that ignores it.
|
|
192
|
+
*/
|
|
193
|
+
plane?: 'x' | 'y' | 'z';
|
|
194
|
+
};
|
|
195
|
+
/** Corner nav-cube/axis gizmo that snaps to preset views. See `createViewGizmo`. */
|
|
196
|
+
type GizmoConfig = {
|
|
197
|
+
/** Default false (opt-in). */
|
|
198
|
+
enabled?: boolean;
|
|
199
|
+
};
|
|
200
|
+
/** Two-click distance measurement tool. See `createMeasureTool`. */
|
|
201
|
+
type MeasureConfig = {
|
|
202
|
+
/** Default false. Only builds the tool; start measuring via `measureTool.setEnabled(true)` on the init result. */
|
|
203
|
+
enabled?: boolean;
|
|
204
|
+
/** Snap to a vertex within this many screen px. Default 12. */
|
|
205
|
+
snapPixels?: number;
|
|
206
|
+
/** Default yellow. */
|
|
207
|
+
color?: THREE.ColorRepresentation;
|
|
208
|
+
/** CSS class for the distance label. */
|
|
209
|
+
labelClassName?: string;
|
|
210
|
+
/** Scene is in meters; pass the response's `modelunits` to convert the label (e.g. "25.0 mm"). Default meters. Ignored if `format` is set. */
|
|
211
|
+
displayUnit?: string;
|
|
212
|
+
/** Receives the straight-line `distance` and per-axis `delta`. Default renders the total plus a Δx/Δy/Δz breakdown. */
|
|
213
|
+
format?: (distance: number, delta: THREE.Vector3) => string;
|
|
214
|
+
};
|
|
215
|
+
type ThreeInitializerOptions = {
|
|
216
|
+
sceneScale?: 'mm' | 'cm' | 'm' | 'inches' | 'feet';
|
|
217
|
+
/**
|
|
218
|
+
* Seeds lighting/material defaults (tone mapping, AO, IBL strength, hemisphere fill); explicit
|
|
219
|
+
* `lighting`/`environment`/`render` options still win. Does NOT touch edges/grid. Default
|
|
220
|
+
* 'technical'. Re-apply later via the init result's `setLook`.
|
|
221
|
+
*/
|
|
222
|
+
look?: Look;
|
|
223
|
+
camera?: CameraConfig;
|
|
224
|
+
lighting?: LightingConfig;
|
|
225
|
+
environment?: EnvironmentConfig;
|
|
226
|
+
floor?: FloorConfig;
|
|
227
|
+
render?: RenderConfig;
|
|
228
|
+
controls?: ControlsConfig;
|
|
229
|
+
grid?: GridConfig;
|
|
230
|
+
gizmo?: GizmoConfig;
|
|
231
|
+
edges?: EdgesConfig;
|
|
232
|
+
measure?: MeasureConfig;
|
|
233
|
+
events?: EventConfig;
|
|
234
|
+
/**
|
|
235
|
+
* Called once at init with the GPU's max anisotropy. **Not needed for sharp textures** — the
|
|
236
|
+
* parse layer's texture cache subscribes to this value itself via a shared sink. This hook is
|
|
237
|
+
* only for hosts doing their own texture work on top.
|
|
238
|
+
*/
|
|
239
|
+
onMaxAnisotropy?: (value: number) => void;
|
|
240
|
+
};
|
|
241
|
+
type EventConfig = {
|
|
242
|
+
onBackgroundClicked?: (event: {
|
|
243
|
+
x: number;
|
|
244
|
+
y: number;
|
|
245
|
+
}) => void;
|
|
246
|
+
onObjectSelected?: (object: THREE.Object3D) => void;
|
|
247
|
+
/** Receives the clicked mesh's `userData`; only fires for meshes with non-empty `userData`. */
|
|
248
|
+
onMeshMetadataClicked?: (metadata: Record<string, unknown>) => void;
|
|
249
|
+
onMeshDoubleClicked?: (object: THREE.Object3D) => void;
|
|
250
|
+
/** Default red (#ff0000). */
|
|
251
|
+
selectionColor?: THREE.Color | string;
|
|
252
|
+
/** Enable all event handlers (click/selection/metadata). Default true. */
|
|
253
|
+
enableEventHandlers?: boolean;
|
|
254
|
+
enableKeyboardControls?: boolean;
|
|
255
|
+
enableClickToFocus?: boolean;
|
|
256
|
+
/** Default true. */
|
|
257
|
+
enableDoubleClickZoom?: boolean;
|
|
258
|
+
onReady?: () => void;
|
|
259
|
+
/** Fires every animation frame, after controls update and before render. */
|
|
260
|
+
onFrame?: (delta: number) => void;
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Runtime camera control: preset views, perspective⇄orthographic toggle, rotate lock.
|
|
265
|
+
*
|
|
266
|
+
* Centralized because projection switching swaps the camera object that OrbitControls drives, the
|
|
267
|
+
* render loop renders, resize reshapes, and the raycaster picks with — {@link getActiveCamera} is
|
|
268
|
+
* the one source of truth for all four call sites.
|
|
269
|
+
*
|
|
270
|
+
* Orthographic shadows perspective (same position/target, frustum derived from perspective FOV +
|
|
271
|
+
* distance) so switching doesn't visually jump.
|
|
272
|
+
*/
|
|
273
|
+
type ViewPreset = 'top' | 'bottom' | 'front' | 'back' | 'left' | 'right' | 'iso';
|
|
274
|
+
type CameraProjection = 'perspective' | 'orthographic';
|
|
275
|
+
interface CameraController {
|
|
276
|
+
/** Swaps identity on {@link setProjection}. */
|
|
277
|
+
getActiveCamera(): THREE.Camera;
|
|
278
|
+
getProjection(): CameraProjection;
|
|
279
|
+
setProjection(projection: CameraProjection): void;
|
|
280
|
+
toggleProjection(): CameraProjection;
|
|
281
|
+
setView(preset: ViewPreset, animate?: boolean): void;
|
|
282
|
+
/**
|
|
283
|
+
* Frame current content from an explicit world-space direction (target → camera) instead of a
|
|
284
|
+
* named preset — used by the nav-cube, whose clicked axis is a world axis.
|
|
285
|
+
*/
|
|
286
|
+
setViewDirection(direction: THREE.Vector3, animate?: boolean): void;
|
|
287
|
+
/** Frame a world-space box from the current view direction. No-op on an empty box. */
|
|
288
|
+
frameBounds(box: THREE.Box3, animate?: boolean): void;
|
|
289
|
+
setRotateEnabled(enabled: boolean): void;
|
|
290
|
+
isRotateEnabled(): boolean;
|
|
291
|
+
updateAspect(width: number, height: number): void;
|
|
292
|
+
/** Cancel any in-flight camera tween. Call on viewer teardown so ticks can't touch disposed controls. */
|
|
293
|
+
dispose(): void;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
interface Grid {
|
|
297
|
+
/** Tagged `userData.id = 'grid'` so pick/fit code skips it. */
|
|
298
|
+
readonly object: THREE.Mesh;
|
|
299
|
+
/** Re-centers the fade on the camera so the grid feels infinite as you move. Call per frame. */
|
|
300
|
+
update(cameraPosition: THREE.Vector3): void;
|
|
301
|
+
/**
|
|
302
|
+
* Rescales cell spacing and fade radius to the content's extent, so a 3-unit or 3000-unit part
|
|
303
|
+
* both get sensible cells. No-op for empty/degenerate bounds.
|
|
304
|
+
*/
|
|
305
|
+
fitToContent(bounds: THREE.Box3): void;
|
|
306
|
+
setVisible(visible: boolean): void;
|
|
307
|
+
dispose(): void;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Two-click distance measurement. Click a point, click a second, read the distance off a label on
|
|
312
|
+
* the connecting line; a third click starts fresh.
|
|
313
|
+
*
|
|
314
|
+
* Picking snaps to the nearest vertex of the struck triangle within {@link MeasureOptions.snapPixels}
|
|
315
|
+
* so measurements land exactly on vertices rather than wherever the ray happened to hit — a cheap
|
|
316
|
+
* local snap (three candidate vertices, no spatial index).
|
|
317
|
+
*
|
|
318
|
+
* Dormant until {@link MeasureTool.setEnabled}(true). While enabled it intercepts clicks (caller
|
|
319
|
+
* forwards them and swallows the event when {@link MeasureTool.handleClick} returns true) so
|
|
320
|
+
* measuring doesn't also select objects.
|
|
321
|
+
*/
|
|
322
|
+
interface MeasureTool {
|
|
323
|
+
setEnabled(enabled: boolean): void;
|
|
324
|
+
isEnabled(): boolean;
|
|
325
|
+
/** Returns true if the tool consumed the click (caller should not also select). */
|
|
326
|
+
handleClick(event: MouseEvent): boolean;
|
|
327
|
+
/** Preview the next snap point via a ghost marker. No-op when disabled; never consumes the event. */
|
|
328
|
+
handleMove(event: MouseEvent): void;
|
|
329
|
+
clear(): void;
|
|
330
|
+
dispose(): void;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Corner nav-cube/axis gizmo. Uses three's {@link ViewHelper} only as the rendered widget, NOT its
|
|
335
|
+
* click→animate behavior: ViewHelper's snap assumes Y-up and animates straight onto the up axis,
|
|
336
|
+
* which rolls the view and jitters the gizmo at the pole in our Z-up scene. Instead we hit-test the
|
|
337
|
+
* axis sprites ourselves and drive the viewer's up-aware camera controller, which snaps instantly
|
|
338
|
+
* with a pole nudge so the orbit basis never degenerates.
|
|
339
|
+
*
|
|
340
|
+
* A click frames the current orbit target (not the world origin), and flips the viewer back to
|
|
341
|
+
* perspective first if it's in orthographic mode (the cube is inherently a 3D-orientation tool).
|
|
342
|
+
*
|
|
343
|
+
* Caller contract (mirrors ViewHelper's own): call {@link ViewGizmo.render} *after* the main scene
|
|
344
|
+
* render each frame, and forward pointer clicks to {@link ViewGizmo.handleClick}.
|
|
345
|
+
*/
|
|
346
|
+
interface ViewGizmo {
|
|
347
|
+
render(renderer: THREE.WebGLRenderer): void;
|
|
348
|
+
/** Returns true if it hit the gizmo (and a view change started). */
|
|
349
|
+
handleClick(event: MouseEvent): boolean;
|
|
350
|
+
setVisible(visible: boolean): void;
|
|
351
|
+
isVisible(): boolean;
|
|
352
|
+
dispose(): void;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
interface ThreeViewer {
|
|
356
|
+
scene: THREE.Scene;
|
|
357
|
+
camera: THREE.PerspectiveCamera;
|
|
358
|
+
controls: OrbitControls;
|
|
359
|
+
renderer: THREE.WebGLRenderer;
|
|
360
|
+
cameraController: CameraController;
|
|
361
|
+
grid: Grid | null;
|
|
362
|
+
gizmo: ViewGizmo | null;
|
|
363
|
+
/** Null unless `measure.enabled`; `setEnabled(true)` to use. */
|
|
364
|
+
measureTool: MeasureTool | null;
|
|
365
|
+
/**
|
|
366
|
+
* Attach edge overlays to meshes under `root` (no-op unless `edges.enabled`). Large-mesh
|
|
367
|
+
* extraction runs off-thread, so overlays may attach a beat later; meshes over
|
|
368
|
+
* `edges.maxTriangles` are skipped and (by default) covered by the screen-space edge fallback.
|
|
369
|
+
*/
|
|
370
|
+
applyEdges: (root: THREE.Object3D) => void;
|
|
371
|
+
/**
|
|
372
|
+
* Prefer over calling `removeEdges` directly — also cancels in-flight async attaches and stands
|
|
373
|
+
* down the screen-space fallback if active.
|
|
374
|
+
*/
|
|
375
|
+
clearEdges: (root: THREE.Object3D) => void;
|
|
376
|
+
/**
|
|
377
|
+
* Request a repaint from the on-demand render loop. Built-in setters and input invalidate
|
|
378
|
+
* automatically; call this after mutating the scene externally. No-op when `render.onDemand` is false.
|
|
379
|
+
*/
|
|
380
|
+
invalidate: () => void;
|
|
381
|
+
setAmbientOcclusion: (enabled: boolean) => void;
|
|
382
|
+
/**
|
|
383
|
+
* Retunes lighting/material only (tone mapping, fill, IBL, AO) — never edges/grid. Overwrites
|
|
384
|
+
* any granular lighting dials set earlier.
|
|
385
|
+
*/
|
|
386
|
+
setLook: (look: 'studio' | 'technical' | 'showcase') => void;
|
|
387
|
+
/**
|
|
388
|
+
* Raising `hemisphereIntensity` is the most effective way to lift shadowed/under-facing surfaces
|
|
389
|
+
* a dark HDR leaves black; a positive value lazily creates the hemisphere light if the viewer was
|
|
390
|
+
* built without one, `0` switches it off.
|
|
391
|
+
*/
|
|
392
|
+
setFillLights: (opts: {
|
|
393
|
+
hemisphereIntensity?: number;
|
|
394
|
+
hemisphereSkyColor?: THREE.Color | number;
|
|
395
|
+
hemisphereGroundColor?: THREE.Color | number;
|
|
396
|
+
ambientIntensity?: number;
|
|
397
|
+
}) => void;
|
|
398
|
+
/**
|
|
399
|
+
* Normalizes IBL brightness across HDRs of differing exposure. Applies even before the HDR
|
|
400
|
+
* finishes decoding.
|
|
401
|
+
*/
|
|
402
|
+
setEnvironmentIntensity: (intensity: number) => void;
|
|
403
|
+
setToneMappingExposure: (exposure: number) => void;
|
|
404
|
+
/** GTAO strength (0-1). No-op when ambient occlusion isn't active. */
|
|
405
|
+
setAoIntensity: (intensity: number) => void;
|
|
406
|
+
/** Feed into the batch parser's `material` option so freshly-loaded meshes match the active look. */
|
|
407
|
+
getMaterialAppearance: () => MaterialAppearanceOptions;
|
|
408
|
+
/** Call after loading or replacing geometry. No-op when sunlight/shadows are off. */
|
|
409
|
+
updateShadowBounds: () => void;
|
|
410
|
+
/** Call after loading or replacing geometry. No-op when the grid is off or empty. */
|
|
411
|
+
updateGridScale: () => void;
|
|
412
|
+
dispose: () => void;
|
|
413
|
+
fitToView: () => void;
|
|
414
|
+
clearSelection: () => void;
|
|
415
|
+
/**
|
|
416
|
+
* Tagged `userData.source = 'user'` so it survives `updateScene` solves instead of being cleared
|
|
417
|
+
* with compute content, and counts as normal content for fit-to-view framing.
|
|
418
|
+
*/
|
|
419
|
+
addUserGeometry: (object: THREE.Object3D) => void;
|
|
420
|
+
removeUserGeometry: (object: THREE.Object3D) => void;
|
|
421
|
+
/** Removes and disposes everything added via `addUserGeometry`. */
|
|
422
|
+
clearUserGeometry: () => void;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
declare const initThree: (canvas: HTMLCanvasElement, options?: ThreeInitializerOptions) => ThreeViewer;
|
|
426
|
+
|
|
427
|
+
/** Replaces scene content with `meshes`, rescales the camera frustum to fit, and (first call only) positions the camera/controls. */
|
|
428
|
+
declare function updateScene(scene: THREE.Scene, meshes: THREE.Object3D[], camera: THREE.PerspectiveCamera, controls: OrbitControls, initialPositionSet: boolean): void;
|
|
429
|
+
|
|
430
|
+
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, LOOK_PRESETS, type LightingConfig, type Logger, Look, LookPreset, MaterialAppearanceOptions, type MeasureConfig, type MeasureTool, type RenderConfig, type ThreeInitializerOptions, type ThreeViewer, type ViewGizmo, type ViewPreset, VisualizationError, enableDebugLogging, getLogger, initThree, materialAppearanceForLook, setLogger, updateScene };
|