@selvajs/compute 3.1.0 → 4.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/README.md +2 -11
- package/dist/chunk-G7NVQAK5.cjs +2 -0
- package/dist/chunk-G7NVQAK5.cjs.map +1 -0
- package/dist/chunk-LLUNR66G.cjs +4 -0
- package/dist/chunk-LLUNR66G.cjs.map +1 -0
- package/dist/chunk-RFFCVRKM.js +2 -0
- package/dist/chunk-RFFCVRKM.js.map +1 -0
- package/dist/chunk-XT3XWDDV.js +4 -0
- package/dist/chunk-XT3XWDDV.js.map +1 -0
- package/dist/core.cjs +1 -1
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +13 -4
- package/dist/core.d.ts +13 -4
- package/dist/core.js +1 -1
- package/dist/grasshopper.cjs +1 -1
- package/dist/grasshopper.cjs.map +1 -1
- package/dist/grasshopper.d.cts +387 -34
- package/dist/grasshopper.d.ts +387 -34
- package/dist/grasshopper.js +1 -1
- package/dist/{handle-files-BISo_wob.d.cts → handle-files-DcA24IkS.d.cts} +45 -1
- package/dist/{handle-files-BISo_wob.d.ts → handle-files-DcA24IkS.d.ts} +45 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -7
- package/dist/index.d.ts +3 -7
- package/dist/index.js +1 -1
- package/package.json +16 -37
- package/dist/chunk-FQKQISPG.cjs +0 -2
- package/dist/chunk-FQKQISPG.cjs.map +0 -1
- package/dist/chunk-H3FZW6OX.cjs +0 -4
- package/dist/chunk-H3FZW6OX.cjs.map +0 -1
- package/dist/chunk-N2WCSETE.js +0 -120
- package/dist/chunk-N2WCSETE.js.map +0 -1
- package/dist/chunk-RFE763NG.cjs +0 -120
- package/dist/chunk-RFE763NG.cjs.map +0 -1
- package/dist/chunk-S3VUIIRE.js +0 -2
- package/dist/chunk-S3VUIIRE.js.map +0 -1
- package/dist/chunk-Y3M7P3BW.js +0 -4
- package/dist/chunk-Y3M7P3BW.js.map +0 -1
- package/dist/types-4FMvnx2j.d.ts +0 -556
- package/dist/types-BGhtYxZ-.d.cts +0 -45
- package/dist/types-BGhtYxZ-.d.ts +0 -45
- package/dist/types-BpOl6U02.d.cts +0 -556
- package/dist/visualization-E6BTQZCA.cjs +0 -2
- package/dist/visualization-E6BTQZCA.cjs.map +0 -1
- package/dist/visualization-HDBKPJGQ.js +0 -2
- package/dist/visualization-HDBKPJGQ.js.map +0 -1
- package/dist/visualization.cjs +0 -2
- package/dist/visualization.cjs.map +0 -1
- package/dist/visualization.d.cts +0 -1093
- package/dist/visualization.d.ts +0 -1093
- package/dist/visualization.js +0 -2
- package/dist/visualization.js.map +0 -1
package/dist/visualization.d.cts
DELETED
|
@@ -1,1093 +0,0 @@
|
|
|
1
|
-
import * as THREE from 'three';
|
|
2
|
-
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
|
|
3
|
-
import { M as MaterialAppearanceOptions, f as GrasshopperComputeResponse, m as MeshExtractionOptions, n as MeshBatchParsingOptions, o as DisplayBatch, p as DisplayItem } from './types-BpOl6U02.cjs';
|
|
4
|
-
export { q as DisplayCurve, r as DisplayIdentity, s as DisplayItemBase, t as DisplayPoint, u as DisplayPosition, v as MeshBatch } from './types-BpOl6U02.cjs';
|
|
5
|
-
import { CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js';
|
|
6
|
-
import { LineSegments2 } from 'three/addons/lines/LineSegments2.js';
|
|
7
|
-
import { Pass } from 'three/addons/postprocessing/Pass.js';
|
|
8
|
-
import { RhinoModule } from 'rhino3dm';
|
|
9
|
-
import './types-BGhtYxZ-.cjs';
|
|
10
|
-
|
|
11
|
-
type CameraConfig = {
|
|
12
|
-
position?: THREE.Vector3;
|
|
13
|
-
fov?: number;
|
|
14
|
-
near?: number;
|
|
15
|
-
far?: number;
|
|
16
|
-
target?: THREE.Vector3;
|
|
17
|
-
/**
|
|
18
|
-
* Refit the perspective camera's near plane to the camera↔content gap every frame (default true).
|
|
19
|
-
* Recovers depth-buffer precision when zoomed out (precision ∝ near/z²), which is what stops
|
|
20
|
-
* distant surfaces z-fighting. `near` stays the lower bound — the plane is only raised, never
|
|
21
|
-
* lowered below it.
|
|
22
|
-
*/
|
|
23
|
-
dynamicNear?: boolean;
|
|
24
|
-
};
|
|
25
|
-
type LightingConfig = {
|
|
26
|
-
enableSunlight?: boolean;
|
|
27
|
-
sunlightIntensity?: number;
|
|
28
|
-
sunlightPosition?: THREE.Vector3;
|
|
29
|
-
ambientLightColor?: THREE.Color;
|
|
30
|
-
ambientLightIntensity?: number;
|
|
31
|
-
sunlightColor?: THREE.Color | number;
|
|
32
|
-
/**
|
|
33
|
-
* Add a hemisphere fill light (sky color from above, ground color from below). Unlike the flat
|
|
34
|
-
* ambient, this gives soft *direction-aware* fill, so downward- and side-facing surfaces never
|
|
35
|
-
* collapse to black when the HDR's lower hemisphere is dark. The single biggest lever for keeping
|
|
36
|
-
* results well-lit regardless of which HDR is loaded. Default false (opt-in) — enabling it shifts
|
|
37
|
-
* the look. See {@link LightingConfig.hemisphereIntensity}.
|
|
38
|
-
*/
|
|
39
|
-
enableHemisphereLight?: boolean;
|
|
40
|
-
/** Hemisphere fill sky color (lights upward-facing surfaces). Default white. */
|
|
41
|
-
hemisphereSkyColor?: THREE.Color | number;
|
|
42
|
-
/** Hemisphere fill ground color (lights downward-facing surfaces). Default a mid grey. */
|
|
43
|
-
hemisphereGroundColor?: THREE.Color | number;
|
|
44
|
-
/** Hemisphere fill strength. Default 0.6. Only applies when {@link LightingConfig.enableHemisphereLight}. */
|
|
45
|
-
hemisphereIntensity?: number;
|
|
46
|
-
};
|
|
47
|
-
type EnvironmentConfig = {
|
|
48
|
-
hdrPath?: string;
|
|
49
|
-
backgroundColor?: THREE.Color | string;
|
|
50
|
-
enableEnvironmentLighting?: boolean;
|
|
51
|
-
/**
|
|
52
|
-
* The scene's up axis. **Defaults to `(0, 0, 1)` — Rhino's Z-up**, not Three's native Y-up,
|
|
53
|
-
* because geometry arrives in Rhino's frame and is never rotated on ingress (see
|
|
54
|
-
* `coordinate-transform.ts`). Everything orientation-dependent derives from this: view presets,
|
|
55
|
-
* the default iso camera, sun position, grid plane, floor normal, and the hemisphere light.
|
|
56
|
-
*
|
|
57
|
-
* Overriding it reorients the viewer but does NOT rotate incoming geometry, so a Y-up value only
|
|
58
|
-
* makes sense if the host also feeds Y-up geometry.
|
|
59
|
-
*/
|
|
60
|
-
sceneUp?: THREE.Vector3;
|
|
61
|
-
showEnvironment?: boolean;
|
|
62
|
-
/**
|
|
63
|
-
* Uniform multiplier on the HDR's image-based lighting contribution (`scene.environmentIntensity`).
|
|
64
|
-
* Normalizes brightness across HDRs of differing exposure — raise it to lift a dim HDR, lower it to
|
|
65
|
-
* tame a blown-out one — so the scene doesn't render dim-or-blown purely because of the HDR chosen.
|
|
66
|
-
* Default 1 (three.js default, unchanged look).
|
|
67
|
-
*/
|
|
68
|
-
environmentIntensity?: number;
|
|
69
|
-
};
|
|
70
|
-
type FloorConfig = {
|
|
71
|
-
enabled?: boolean;
|
|
72
|
-
size?: number;
|
|
73
|
-
color?: THREE.Color | string;
|
|
74
|
-
roughness?: number;
|
|
75
|
-
metalness?: number;
|
|
76
|
-
receiveShadow?: boolean;
|
|
77
|
-
};
|
|
78
|
-
type RenderConfig = {
|
|
79
|
-
enableShadows?: boolean;
|
|
80
|
-
shadowMapSize?: number;
|
|
81
|
-
antialias?: boolean;
|
|
82
|
-
pixelRatio?: number;
|
|
83
|
-
toneMapping?: THREE.ToneMapping;
|
|
84
|
-
toneMappingExposure?: number;
|
|
85
|
-
preserveDrawingBuffer?: boolean;
|
|
86
|
-
/**
|
|
87
|
-
* Enable ground-truth ambient occlusion (GTAO) via a postprocessing pipeline. Default false —
|
|
88
|
-
* turning it on switches rendering from `renderer.render` to an EffectComposer, which costs more.
|
|
89
|
-
*/
|
|
90
|
-
ambientOcclusion?: boolean;
|
|
91
|
-
/** AO strength 0–1 when {@link RenderConfig.ambientOcclusion} is on. Default 1. */
|
|
92
|
-
aoIntensity?: number;
|
|
93
|
-
/**
|
|
94
|
-
* Device-pixel-ratio cap for the ambient-occlusion postprocessing buffers. AO is low-frequency, so
|
|
95
|
-
* rendering its buffers below the display DPR is nearly invisible but hugely cheaper — on a Retina
|
|
96
|
-
* display (DPR 2) full-resolution AO means 4× the pixels through GTAO's per-pixel sample loops,
|
|
97
|
-
* which can dominate frame time. Default 1 (AO buffers at 1× regardless of display DPR). Raise
|
|
98
|
-
* toward the display DPR for sharper AO at higher cost; only relevant when AO is enabled.
|
|
99
|
-
*/
|
|
100
|
-
aoPixelRatio?: number;
|
|
101
|
-
/**
|
|
102
|
-
* Render only when something changed (camera motion, invalidate(), pointer input, resize), with
|
|
103
|
-
* a ~500 ms safety repaint, instead of every animation frame. Default true — cuts idle GPU/battery
|
|
104
|
-
* to ~2 fps worth of work, which matters especially with ambient occlusion on. Set false to
|
|
105
|
-
* restore the legacy continuous loop.
|
|
106
|
-
*/
|
|
107
|
-
onDemand?: boolean;
|
|
108
|
-
};
|
|
109
|
-
/**
|
|
110
|
-
* A ready-to-go visual look. A `look` is a named bundle of LIGHTING/MATERIAL defaults only — it is
|
|
111
|
-
* deliberately decoupled from the CAD overlays (edges, grid), which are driven independently by
|
|
112
|
-
* {@link EdgesConfig}/{@link GridConfig}. Pick one and the viewer looks professional with zero other
|
|
113
|
-
* config; every individual `lighting`/`environment`/`render` option still overrides the preset. Seeds
|
|
114
|
-
* construction defaults and can be re-applied live via `setLook`.
|
|
115
|
-
*
|
|
116
|
-
* - 'technical' (default): matte, drawing-like — neutral tone mapping, low IBL, no fill. Reads like a
|
|
117
|
-
* CAD shaded view (Rhino/Onshape).
|
|
118
|
-
* - 'studio': balanced presentation — ACES tone mapping, hemisphere fill + lifted HDR so results are
|
|
119
|
-
* well-lit regardless of the HDR, without washing colour out. The polished "product shot" look.
|
|
120
|
-
* - 'showcase': punchier presentation — ACES, stronger IBL/fill and a touch more exposure.
|
|
121
|
-
*/
|
|
122
|
-
/**
|
|
123
|
-
* The look values as a runtime array — the single source of truth. {@link Look} is derived from it, so
|
|
124
|
-
* the type and the enumerable list can never drift. Consumers (e.g. a viewer's style picker) iterate
|
|
125
|
-
* this instead of hardcoding the names, so adding or renaming a look here updates them automatically.
|
|
126
|
-
* 'technical' is first because it's the default.
|
|
127
|
-
*/
|
|
128
|
-
declare const LOOKS: readonly ["technical", "studio", "showcase"];
|
|
129
|
-
type Look = (typeof LOOKS)[number];
|
|
130
|
-
/** Crisp boundary/crease edge overlays on meshes. See `addEdges`. */
|
|
131
|
-
type EdgesConfig = {
|
|
132
|
-
/** Auto-attach edge overlays to meshes as they load. Default false (opt-in). */
|
|
133
|
-
enabled?: boolean;
|
|
134
|
-
/**
|
|
135
|
-
* Force a single edge color for all meshes. Omit (the default) to derive each mesh's edge color
|
|
136
|
-
* from its own surface material, darkened by `darken` — so edges read as the object's own outline.
|
|
137
|
-
*/
|
|
138
|
-
color?: THREE.ColorRepresentation;
|
|
139
|
-
/**
|
|
140
|
-
* How far derived edge colors are darkened toward black, 0–1 (default 0.75). Ignored when `color`
|
|
141
|
-
* is set.
|
|
142
|
-
*/
|
|
143
|
-
darken?: number;
|
|
144
|
-
/** Edge thickness in CSS px. Default 1.5. */
|
|
145
|
-
width?: number;
|
|
146
|
-
/** Crease angle (degrees): keep edges where faces differ by more than this. Default 44. */
|
|
147
|
-
thresholdAngle?: number;
|
|
148
|
-
/** Fade an overlay out as its mesh shrinks on screen, so far zoom-outs stay clean. Default true. */
|
|
149
|
-
distanceFade?: boolean;
|
|
150
|
-
/** Skip overlay extraction for meshes above this triangle count. Default 4M. See `EdgeOptions`. */
|
|
151
|
-
maxTriangles?: number;
|
|
152
|
-
/** Overlays above this segment count render opaque (no distance fade). Default 2M. */
|
|
153
|
-
maxSegments?: number;
|
|
154
|
-
/**
|
|
155
|
-
* When a mesh is skipped for exceeding `maxTriangles`, approximate its edges with the
|
|
156
|
-
* screen-space edge-detection pass (constant cost in triangle count). Default true.
|
|
157
|
-
*/
|
|
158
|
-
screenSpaceFallback?: boolean;
|
|
159
|
-
};
|
|
160
|
-
type ControlsConfig = {
|
|
161
|
-
enableDamping?: boolean;
|
|
162
|
-
dampingFactor?: number;
|
|
163
|
-
autoRotate?: boolean;
|
|
164
|
-
autoRotateSpeed?: number;
|
|
165
|
-
enableZoom?: boolean;
|
|
166
|
-
enablePan?: boolean;
|
|
167
|
-
minDistance?: number;
|
|
168
|
-
maxDistance?: number;
|
|
169
|
-
};
|
|
170
|
-
/** Infinite distance-fading reference grid. See `createGrid`. */
|
|
171
|
-
type GridConfig = {
|
|
172
|
-
/** Show the grid. Default false (opt-in). */
|
|
173
|
-
enabled?: boolean;
|
|
174
|
-
/** Minor cell size in world units (meters). Default 1. */
|
|
175
|
-
cellSize?: number;
|
|
176
|
-
/** Minor cells per major line. Default 10. */
|
|
177
|
-
majorEvery?: number;
|
|
178
|
-
/** Minor line color. */
|
|
179
|
-
cellColor?: THREE.ColorRepresentation;
|
|
180
|
-
/** Major line color. */
|
|
181
|
-
majorColor?: THREE.ColorRepresentation;
|
|
182
|
-
/** World radius at which the grid fully fades. Default 100. */
|
|
183
|
-
fadeDistance?: number;
|
|
184
|
-
/**
|
|
185
|
-
* Axis the grid lies perpendicular to — the scene's up axis. Defaults to whichever axis
|
|
186
|
-
* `sceneUp` points along, so it is `'z'` (Rhino's horizontal ground) unless you override
|
|
187
|
-
* `sceneUp`. Set explicitly only to force a grid orientation that ignores the scene up.
|
|
188
|
-
*/
|
|
189
|
-
plane?: 'x' | 'y' | 'z';
|
|
190
|
-
};
|
|
191
|
-
/** Corner nav-cube/axis gizmo that snaps to preset views. See `createViewGizmo`. */
|
|
192
|
-
type GizmoConfig = {
|
|
193
|
-
/** Show the gizmo. Default false (opt-in). */
|
|
194
|
-
enabled?: boolean;
|
|
195
|
-
};
|
|
196
|
-
/** Two-click distance measurement tool. See `createMeasureTool`. */
|
|
197
|
-
type MeasureConfig = {
|
|
198
|
-
/**
|
|
199
|
-
* Create the measurement tool. Default false. Note: this only *builds* the tool (and its label
|
|
200
|
-
* overlay); start measuring by calling `measureTool.setEnabled(true)` on the init result.
|
|
201
|
-
*/
|
|
202
|
-
enabled?: boolean;
|
|
203
|
-
/** Snap to a vertex within this many screen px. Default 12. */
|
|
204
|
-
snapPixels?: number;
|
|
205
|
-
/** Marker + line color. Default yellow. */
|
|
206
|
-
color?: THREE.ColorRepresentation;
|
|
207
|
-
/** CSS class for the distance label. */
|
|
208
|
-
labelClassName?: string;
|
|
209
|
-
/**
|
|
210
|
-
* Model unit (pass the response's `modelunits`). The scene is in meters, so the default label is
|
|
211
|
-
* converted to this unit — a mm model reads "25.0 mm". Defaults to meters. Ignored if `format` is set.
|
|
212
|
-
*/
|
|
213
|
-
displayUnit?: string;
|
|
214
|
-
/**
|
|
215
|
-
* Format the measurement → label text. Receives the straight-line `distance` and per-axis `delta`.
|
|
216
|
-
* Default renders the total plus a Δx/Δy/Δz breakdown.
|
|
217
|
-
*/
|
|
218
|
-
format?: (distance: number, delta: THREE.Vector3) => string;
|
|
219
|
-
};
|
|
220
|
-
type ThreeInitializerOptions = {
|
|
221
|
-
sceneScale?: 'mm' | 'cm' | 'm' | 'inches' | 'feet';
|
|
222
|
-
/**
|
|
223
|
-
* Pick a ready-to-go visual look up front — seeds professional lighting/material defaults (tone
|
|
224
|
-
* mapping, AO, IBL strength, hemisphere fill; see {@link Look}). Individual `lighting`/
|
|
225
|
-
* `environment`/`render` options still win when set explicitly, so this only fills in what you
|
|
226
|
-
* leave unspecified. A look does NOT touch edges/grid (those are independent overlays). Defaults
|
|
227
|
-
* to 'technical'. Re-apply later via the init result's `setLook`.
|
|
228
|
-
*/
|
|
229
|
-
look?: Look;
|
|
230
|
-
camera?: CameraConfig;
|
|
231
|
-
lighting?: LightingConfig;
|
|
232
|
-
environment?: EnvironmentConfig;
|
|
233
|
-
floor?: FloorConfig;
|
|
234
|
-
render?: RenderConfig;
|
|
235
|
-
controls?: ControlsConfig;
|
|
236
|
-
grid?: GridConfig;
|
|
237
|
-
gizmo?: GizmoConfig;
|
|
238
|
-
edges?: EdgesConfig;
|
|
239
|
-
measure?: MeasureConfig;
|
|
240
|
-
events?: EventConfig;
|
|
241
|
-
};
|
|
242
|
-
type EventConfig = {
|
|
243
|
-
onBackgroundClicked?: (event: {
|
|
244
|
-
x: number;
|
|
245
|
-
y: number;
|
|
246
|
-
}) => void;
|
|
247
|
-
onObjectSelected?: (object: THREE.Object3D) => void;
|
|
248
|
-
/** Called when a mesh with metadata is clicked. Receives the mesh's metadata object. */
|
|
249
|
-
onMeshMetadataClicked?: (metadata: Record<string, string>) => void;
|
|
250
|
-
/** Called when a mesh is double-clicked. Receives the mesh object. */
|
|
251
|
-
onMeshDoubleClicked?: (object: THREE.Object3D) => void;
|
|
252
|
-
/** Color to use for highlighting selected meshes. Defaults to red (#ff0000). */
|
|
253
|
-
selectionColor?: THREE.Color | string;
|
|
254
|
-
/** Enable all event handlers (click/selection/metadata). Defaults to true. */
|
|
255
|
-
enableEventHandlers?: boolean;
|
|
256
|
-
enableKeyboardControls?: boolean;
|
|
257
|
-
enableClickToFocus?: boolean;
|
|
258
|
-
/** Zoom into a mesh on double-click. Defaults to true. */
|
|
259
|
-
enableDoubleClickZoom?: boolean;
|
|
260
|
-
/** Called once the HDR environment map has finished loading and been applied to the scene. */
|
|
261
|
-
onReady?: () => void;
|
|
262
|
-
/** Called every animation frame, after controls update and before render. Use for custom per-frame logic. */
|
|
263
|
-
onFrame?: (delta: number) => void;
|
|
264
|
-
};
|
|
265
|
-
|
|
266
|
-
/**
|
|
267
|
-
* Runtime camera control for the viewer: preset views (top/front/…), a true 2D/3D toggle
|
|
268
|
-
* (orthographic ⇄ perspective), and a rotate lock.
|
|
269
|
-
*
|
|
270
|
-
* Why a controller and not just loose methods: all three features have to agree on *which* camera
|
|
271
|
-
* is active. Switching projection swaps the camera object OrbitControls drives, the animation loop
|
|
272
|
-
* renders, the resize handler reshapes, and the raycaster picks with. Centralizing that here keeps
|
|
273
|
-
* those four call sites reading one source of truth ({@link getActiveCamera}) instead of each
|
|
274
|
-
* branching on a `mode` flag.
|
|
275
|
-
*
|
|
276
|
-
* The perspective camera stays the primary (it's what {@link updateScene} and existing consumers
|
|
277
|
-
* size). The orthographic camera shadows it: same position/target, frustum derived from the
|
|
278
|
-
* perspective FOV + current distance so the 3D→2D switch doesn't visually jump.
|
|
279
|
-
*/
|
|
280
|
-
/** The six axis-aligned presets plus the default 3/4 iso. Named in Three's Y-up frame. */
|
|
281
|
-
type ViewPreset = 'top' | 'bottom' | 'front' | 'back' | 'left' | 'right' | 'iso';
|
|
282
|
-
type CameraProjection = 'perspective' | 'orthographic';
|
|
283
|
-
interface CameraController {
|
|
284
|
-
/** The camera currently being rendered/picked with. Swaps identity on {@link setProjection}. */
|
|
285
|
-
getActiveCamera(): THREE.Camera;
|
|
286
|
-
/** Current projection mode. */
|
|
287
|
-
getProjection(): CameraProjection;
|
|
288
|
-
/** Switch between perspective (3D) and orthographic (2D). No-op if already in that mode. */
|
|
289
|
-
setProjection(projection: CameraProjection): void;
|
|
290
|
-
/** Convenience toggle for a 2D/3D button. */
|
|
291
|
-
toggleProjection(): CameraProjection;
|
|
292
|
-
/** Move the camera to a preset orientation, framing current scene content. Animated. */
|
|
293
|
-
setView(preset: ViewPreset, animate?: boolean): void;
|
|
294
|
-
/**
|
|
295
|
-
* Frame current content viewed from `direction` (a world-space vector from target toward camera).
|
|
296
|
-
* Like {@link setView} but takes an explicit direction — used by the nav-cube, whose clicked axis
|
|
297
|
-
* is a world axis, not a named preset. Pole directions are nudged off-axis to avoid the orbit
|
|
298
|
-
* singularity.
|
|
299
|
-
*/
|
|
300
|
-
setViewDirection(direction: THREE.Vector3, animate?: boolean): void;
|
|
301
|
-
/**
|
|
302
|
-
* Frame an arbitrary world-space box (e.g. a double-clicked object) from the current view
|
|
303
|
-
* direction, moving the *active* camera — in 2D mode that means resizing the ortho frustum, not
|
|
304
|
-
* just translating. No-op on an empty box.
|
|
305
|
-
*/
|
|
306
|
-
frameBounds(box: THREE.Box3, animate?: boolean): void;
|
|
307
|
-
/** Enable/disable orbit rotation at runtime (pan/zoom unaffected). */
|
|
308
|
-
setRotateEnabled(enabled: boolean): void;
|
|
309
|
-
/** Whether rotation is currently enabled. */
|
|
310
|
-
isRotateEnabled(): boolean;
|
|
311
|
-
/** Keep the orthographic frustum aspect in sync on canvas resize. Called by the resize loop. */
|
|
312
|
-
updateAspect(width: number, height: number): void;
|
|
313
|
-
/** Cancel any in-flight camera tween. Call on viewer teardown so ticks can't touch disposed controls. */
|
|
314
|
-
dispose(): void;
|
|
315
|
-
}
|
|
316
|
-
interface CameraControllerDeps {
|
|
317
|
-
scene: THREE.Scene;
|
|
318
|
-
perspective: THREE.PerspectiveCamera;
|
|
319
|
-
controls: OrbitControls;
|
|
320
|
-
/** Called whenever the active camera identity changes, so callers can re-point the renderer/raycaster. */
|
|
321
|
-
onActiveCameraChange: (camera: THREE.Camera) => void;
|
|
322
|
-
/**
|
|
323
|
-
* The scene's up axis. Presets, the orthographic camera's up, and the iso direction are all derived
|
|
324
|
-
* from this so the controller is correct in any up convention (Three's native Y-up, Rhino's Z-up, …)
|
|
325
|
-
* without hardcoding an axis. Falls back to `perspective.up` when omitted; `initThree` always
|
|
326
|
-
* passes the configured `sceneUp`, which itself defaults to Rhino's Z-up.
|
|
327
|
-
*/
|
|
328
|
-
up?: THREE.Vector3;
|
|
329
|
-
}
|
|
330
|
-
declare function createCameraController(deps: CameraControllerDeps): CameraController;
|
|
331
|
-
|
|
332
|
-
/**
|
|
333
|
-
* An "infinite", distance-fading reference grid — the single strongest visual cue that reads as CAD.
|
|
334
|
-
*
|
|
335
|
-
* Why not `GridHelper`: it's a fixed-size square of line segments that visibly ends and looks wrong
|
|
336
|
-
* once you pan or zoom past it. Instead we draw one large screen-facing plane and compute the grid
|
|
337
|
-
* in the fragment shader from world coordinates, fading lines out with distance so the edge is never
|
|
338
|
-
* a hard cutoff. The plane is big enough to cover any reasonable view; the fade hides its bounds.
|
|
339
|
-
*
|
|
340
|
-
* Two line frequencies (minor + major every 10th) give the usual graph-paper depth read. Spacing is
|
|
341
|
-
* in world units (meters — the scene's normalized unit), so a `cellSize` of 1 = 1m minor cells.
|
|
342
|
-
*/
|
|
343
|
-
interface GridOptions {
|
|
344
|
-
/** Minor cell size in world units (meters). Default 1. */
|
|
345
|
-
cellSize?: number;
|
|
346
|
-
/** How many minor cells per major line. Default 10. */
|
|
347
|
-
majorEvery?: number;
|
|
348
|
-
/** Minor line color. */
|
|
349
|
-
cellColor?: THREE.ColorRepresentation;
|
|
350
|
-
/** Major line color. */
|
|
351
|
-
majorColor?: THREE.ColorRepresentation;
|
|
352
|
-
/** World-space radius at which the grid has fully faded out. Default 100. */
|
|
353
|
-
fadeDistance?: number;
|
|
354
|
-
/**
|
|
355
|
-
* Axis the grid is laid perpendicular to — i.e. the scene's up axis. `'z'` is the horizontal
|
|
356
|
-
* ground in the Rhino Z-up frame the viewer uses; `'y'` is Three's native Y-up.
|
|
357
|
-
*
|
|
358
|
-
* This standalone default is `'y'`, but `initThree` always passes a plane derived from the
|
|
359
|
-
* configured `sceneUp`, so a viewer-created grid defaults to `'z'`.
|
|
360
|
-
*/
|
|
361
|
-
plane?: 'x' | 'y' | 'z';
|
|
362
|
-
}
|
|
363
|
-
interface Grid {
|
|
364
|
-
/** The grid mesh; add to the scene. Tagged `userData.id = 'grid'` so pick/fit code skips it. */
|
|
365
|
-
readonly object: THREE.Mesh;
|
|
366
|
-
/** Keep the fade centered on the camera so the grid feels infinite as you move. Call per frame. */
|
|
367
|
-
update(cameraPosition: THREE.Vector3): void;
|
|
368
|
-
/**
|
|
369
|
-
* Rescale the grid's cell spacing and fade radius to the loaded content's extent. Call after a
|
|
370
|
-
* geometry change (e.g. right after `updateScene`) so a part that is 3 units or 3000 units wide
|
|
371
|
-
* both get sensibly-sized cells and a fade that reaches past the model. No-op for empty/degenerate
|
|
372
|
-
* bounds — the grid keeps its last (or default) scale. See {@link Grid.fitToContent}'s impl notes.
|
|
373
|
-
*/
|
|
374
|
-
fitToContent(bounds: THREE.Box3): void;
|
|
375
|
-
setVisible(visible: boolean): void;
|
|
376
|
-
dispose(): void;
|
|
377
|
-
}
|
|
378
|
-
declare function createGrid(options?: GridOptions): Grid;
|
|
379
|
-
|
|
380
|
-
/**
|
|
381
|
-
* The corner nav-cube/axis gizmo. Uses three's {@link ViewHelper} purely as the rendered widget, but
|
|
382
|
-
* NOT its click→animate behavior: ViewHelper's built-in snap assumes a Y-up world and animates the
|
|
383
|
-
* camera straight onto the up axis, which in our Z-up scene rolls the view and makes the gizmo jitter
|
|
384
|
-
* at the pole. Instead we hit-test the axis sprites ourselves and drive the viewer's up-aware camera
|
|
385
|
-
* controller, which snaps (no animation) with a pole nudge so the orbit basis never degenerates.
|
|
386
|
-
*
|
|
387
|
-
* Integration points with the viewer's dual-camera setup:
|
|
388
|
-
* 1. The snap frames the current orbit target via the controller, so it rotates about what the user
|
|
389
|
-
* is looking at (not the world origin).
|
|
390
|
-
* 2. The nav cube is inherently a 3D-orientation tool, so if the viewer is in orthographic (2D) mode
|
|
391
|
-
* when the gizmo is clicked, we first flip back to perspective.
|
|
392
|
-
*
|
|
393
|
-
* Caller responsibilities (mirror ViewHelper's own contract):
|
|
394
|
-
* - call {@link ViewGizmo.render} *after* the main scene render each frame (overlay viewport),
|
|
395
|
-
* - forward pointer clicks to {@link ViewGizmo.handleClick}.
|
|
396
|
-
*/
|
|
397
|
-
interface ViewGizmo {
|
|
398
|
-
render(renderer: THREE.WebGLRenderer): void;
|
|
399
|
-
/**
|
|
400
|
-
* @deprecated No-op, kept only for API stability. This wrapper never uses ViewHelper's
|
|
401
|
-
* click→animate path (see module comment) — view changes snap instantly through the camera
|
|
402
|
-
* controller — so there is never a gizmo animation to advance. Safe to stop calling.
|
|
403
|
-
*/
|
|
404
|
-
update(delta: number): void;
|
|
405
|
-
/** Hit-test a click. Returns true if it hit the gizmo (and a view change started). */
|
|
406
|
-
handleClick(event: MouseEvent): boolean;
|
|
407
|
-
/**
|
|
408
|
-
* @deprecated Always `false`, kept only for API stability. Gizmo clicks snap the view
|
|
409
|
-
* instantly rather than animating (deliberately — ViewHelper's built-in animation assumes a
|
|
410
|
-
* Y-up world and rolls the view in this Z-up scene), so there is no animation window to gate
|
|
411
|
-
* input on.
|
|
412
|
-
*/
|
|
413
|
-
readonly isAnimating: boolean;
|
|
414
|
-
/** Show/hide the gizmo at runtime. Hidden = not rendered and not click-hittable. */
|
|
415
|
-
setVisible(visible: boolean): void;
|
|
416
|
-
isVisible(): boolean;
|
|
417
|
-
dispose(): void;
|
|
418
|
-
}
|
|
419
|
-
interface ViewGizmoDeps {
|
|
420
|
-
/** The perspective (primary) camera the gizmo visualizes and re-orients. */
|
|
421
|
-
camera: THREE.PerspectiveCamera;
|
|
422
|
-
domElement: HTMLElement;
|
|
423
|
-
controller: CameraController;
|
|
424
|
-
}
|
|
425
|
-
declare function createViewGizmo(deps: ViewGizmoDeps): ViewGizmo;
|
|
426
|
-
|
|
427
|
-
/**
|
|
428
|
-
* An HTML label layer that tracks 3D positions, via three's {@link CSS2DRenderer}. Labels are real
|
|
429
|
-
* DOM nodes (crisp text, CSS-stylable) positioned each frame to follow points in the scene — the
|
|
430
|
-
* foundation for measurement readouts, dimension annotations, and point tags.
|
|
431
|
-
*
|
|
432
|
-
* The CSS2D renderer draws into its own absolutely-positioned DOM overlay stacked on top of the
|
|
433
|
-
* WebGL canvas (pointer-events disabled so it never steals clicks from the viewer). The viewer owns
|
|
434
|
-
* one of these; features like the measure tool add/remove labels through it.
|
|
435
|
-
*/
|
|
436
|
-
interface LabelHandle {
|
|
437
|
-
/** The CSS2DObject in the scene graph. */
|
|
438
|
-
readonly object: CSS2DObject;
|
|
439
|
-
/** Move the label to a new world position. */
|
|
440
|
-
setPosition(position: THREE.Vector3): void;
|
|
441
|
-
/** Replace the label's text/HTML. */
|
|
442
|
-
setText(text: string): void;
|
|
443
|
-
/** Remove the label from the scene and the DOM. */
|
|
444
|
-
remove(): void;
|
|
445
|
-
}
|
|
446
|
-
interface LabelLayer {
|
|
447
|
-
/** Create a label at a world position. `className` lets callers theme groups of labels. */
|
|
448
|
-
addLabel(text: string, position: THREE.Vector3, className?: string): LabelHandle;
|
|
449
|
-
/** Render the DOM overlay. Call each frame after the WebGL render, with the active camera. */
|
|
450
|
-
render(scene: THREE.Scene, camera: THREE.Camera): void;
|
|
451
|
-
setSize(width: number, height: number): void;
|
|
452
|
-
dispose(): void;
|
|
453
|
-
}
|
|
454
|
-
/**
|
|
455
|
-
* @param container element to overlay labels onto — normally the canvas's parent, so the overlay and
|
|
456
|
-
* canvas share a positioning context. The overlay is appended here and absolutely positioned.
|
|
457
|
-
* @param scene labels are parented to a group added to this scene, so they render and follow the
|
|
458
|
-
* camera without the caller wiring scene-graph parenting.
|
|
459
|
-
*/
|
|
460
|
-
declare function createLabelLayer(container: HTMLElement, scene: THREE.Scene): LabelLayer;
|
|
461
|
-
|
|
462
|
-
/**
|
|
463
|
-
* A two-click distance measurement tool — the CAD verb users expect. Click a point, click a second,
|
|
464
|
-
* read the distance off a label on the connecting line; a third click starts a new measurement.
|
|
465
|
-
*
|
|
466
|
-
* Picking snaps to geometry so measurements are exact, not "wherever the ray happened to land":
|
|
467
|
-
* on a mesh hit we snap to the nearest vertex of the struck triangle if it's within
|
|
468
|
-
* {@link MeasureOptions.snapPixels} on screen, else use the raw hit point. This is a cheap local
|
|
469
|
-
* snap (three candidate vertices), no spatial index — enough for clean vertex-to-vertex measurement
|
|
470
|
-
* without the cost/complexity of full edge/midpoint snapping (a later refinement).
|
|
471
|
-
*
|
|
472
|
-
* The tool is dormant until {@link MeasureTool.setEnabled}(true). While enabled it intercepts clicks
|
|
473
|
-
* (the caller forwards them and swallows the event when {@link MeasureTool.handleClick} returns
|
|
474
|
-
* true) so measuring doesn't also select objects.
|
|
475
|
-
*/
|
|
476
|
-
interface MeasureTool {
|
|
477
|
-
setEnabled(enabled: boolean): void;
|
|
478
|
-
isEnabled(): boolean;
|
|
479
|
-
/** Process a click. Returns true if the tool consumed it (caller should not also select). */
|
|
480
|
-
handleClick(event: MouseEvent): boolean;
|
|
481
|
-
/**
|
|
482
|
-
* Process pointer movement to preview the next snap point — a ghost marker tracks the cursor and
|
|
483
|
-
* jumps to the vertex a click would snap to, so users can aim before committing. No-op when the
|
|
484
|
-
* tool is disabled. The caller forwards mousemove; nothing is consumed.
|
|
485
|
-
*/
|
|
486
|
-
handleMove(event: MouseEvent): void;
|
|
487
|
-
/** Clear the current measurement (markers, line, label). */
|
|
488
|
-
clear(): void;
|
|
489
|
-
dispose(): void;
|
|
490
|
-
}
|
|
491
|
-
interface MeasureOptions {
|
|
492
|
-
/** Snap to a vertex when the cursor is within this many screen pixels of it. Default 12. */
|
|
493
|
-
snapPixels?: number;
|
|
494
|
-
/** Marker + line color. Default yellow. */
|
|
495
|
-
color?: THREE.ColorRepresentation;
|
|
496
|
-
/** CSS class applied to the distance label, for styling. */
|
|
497
|
-
labelClassName?: string;
|
|
498
|
-
/**
|
|
499
|
-
* The model's unit (pass `data.modelunits`). The scene is in meters, so the default formatter
|
|
500
|
-
* converts and labels in this unit — e.g. a mm model reads "25.0 mm", not "0.025 m". Defaults
|
|
501
|
-
* to meters. Ignored when a custom `format` is supplied.
|
|
502
|
-
*/
|
|
503
|
-
displayUnit?: string;
|
|
504
|
-
/**
|
|
505
|
-
* Format the measurement → label text. Receives the straight-line `distance` and the per-axis
|
|
506
|
-
* `delta` (|b − a| on each axis), both in **meters**. May return multi-line text or HTML; the
|
|
507
|
-
* default renders the total plus a Δx/Δy/Δz breakdown in `displayUnit`. Overrides `displayUnit`.
|
|
508
|
-
*/
|
|
509
|
-
format?: (distance: number, delta: THREE.Vector3) => string;
|
|
510
|
-
}
|
|
511
|
-
interface MeasureDeps {
|
|
512
|
-
canvas: HTMLCanvasElement;
|
|
513
|
-
scene: THREE.Scene;
|
|
514
|
-
getActiveCamera: () => THREE.Camera;
|
|
515
|
-
/**
|
|
516
|
-
* The current orbit target (e.g. `controls.target`). Used to scale the line/point pick
|
|
517
|
-
* threshold with the view: the tolerance is a fraction of the camera→target distance, so it
|
|
518
|
-
* stays roughly constant on screen wherever the user has framed the model. Optional for
|
|
519
|
-
* backward compatibility — without it the perspective fallback is the camera's distance to the
|
|
520
|
-
* world origin, which misjudges the threshold for off-origin content. Thread it in when you can.
|
|
521
|
-
*/
|
|
522
|
-
getViewTarget?: () => THREE.Vector3;
|
|
523
|
-
labelLayer: LabelLayer;
|
|
524
|
-
options?: MeasureOptions;
|
|
525
|
-
}
|
|
526
|
-
/**
|
|
527
|
-
* Snap a raycast hit to the nearest geometry vertex within `snapPixels` on screen; otherwise return
|
|
528
|
-
* the raw hit point. Works for meshes (triangle vertices), lines (segment endpoints), and points
|
|
529
|
-
* (the vertex itself). Pure (no DOM) so it's unit-testable: it takes the screen size explicitly
|
|
530
|
-
* rather than reading the canvas. Exported for that reason.
|
|
531
|
-
*
|
|
532
|
-
* Falls back to the raw point for hits without usable vertex indices or positions.
|
|
533
|
-
*/
|
|
534
|
-
declare function snapToVertex(hit: THREE.Intersection, camera: THREE.Camera, screenSize: {
|
|
535
|
-
width: number;
|
|
536
|
-
height: number;
|
|
537
|
-
}, snapPixels: number): THREE.Vector3;
|
|
538
|
-
declare function createMeasureTool(deps: MeasureDeps): MeasureTool;
|
|
539
|
-
|
|
540
|
-
/**
|
|
541
|
-
* Initializes a Three.js environment with scene, camera, renderer, and event handling.
|
|
542
|
-
*/
|
|
543
|
-
declare const initThree: (canvas: HTMLCanvasElement, options?: ThreeInitializerOptions) => {
|
|
544
|
-
scene: THREE.Scene;
|
|
545
|
-
camera: THREE.PerspectiveCamera;
|
|
546
|
-
controls: OrbitControls;
|
|
547
|
-
renderer: THREE.WebGLRenderer;
|
|
548
|
-
cameraController: CameraController;
|
|
549
|
-
grid: Grid | null;
|
|
550
|
-
gizmo: ViewGizmo | null;
|
|
551
|
-
/** Two-click distance measurement tool. Null unless `measure.enabled`; `setEnabled(true)` to use. */
|
|
552
|
-
measureTool: MeasureTool | null;
|
|
553
|
-
/**
|
|
554
|
-
* Attach edge overlays to the meshes under `root` (no-op unless `edges.enabled`). Call after
|
|
555
|
-
* loading meshes via `updateScene`, since meshes arrive after init. Extraction for large meshes
|
|
556
|
-
* runs off-thread — their overlays attach a beat later; meshes over `edges.maxTriangles` are
|
|
557
|
-
* skipped and (by default) covered by the screen-space edge fallback instead.
|
|
558
|
-
*/
|
|
559
|
-
applyEdges: (root: THREE.Object3D) => void;
|
|
560
|
-
/**
|
|
561
|
-
* Remove edge overlays under `root` — the toggle-off counterpart of `applyEdges`. Prefer this
|
|
562
|
-
* over calling `removeEdges` directly: it also cancels in-flight async attaches' fallout and
|
|
563
|
-
* stands down the screen-space edge fallback if it was active.
|
|
564
|
-
*/
|
|
565
|
-
clearEdges: (root: THREE.Object3D) => void;
|
|
566
|
-
/**
|
|
567
|
-
* Request a repaint from the on-demand render loop. Camera motion, resizes, pointer input, and
|
|
568
|
-
* the built-in setters invalidate automatically; call this after mutating the scene externally
|
|
569
|
-
* (e.g. `updateScene`, adding user geometry) so the change shows immediately rather than on the
|
|
570
|
-
* next safety repaint. No-op (harmless) when `render.onDemand` is false.
|
|
571
|
-
*/
|
|
572
|
-
invalidate: () => void;
|
|
573
|
-
/** Toggle ambient occlusion at runtime — builds or tears down the postprocessing pipeline. */
|
|
574
|
-
setAmbientOcclusion: (enabled: boolean) => void;
|
|
575
|
-
/**
|
|
576
|
-
* Apply a coherent look to the already-loaded scene: 'technical' (matte/CAD — edges, grid, low
|
|
577
|
-
* IBL, neutral tone mapping) or 'rendered' (presentation — stronger IBL, ACES tone mapping, no
|
|
578
|
-
* edges). Retunes viewer-owned dials only; per-material parse choices are set via the batch
|
|
579
|
-
* parser's `material` option. Handy for comparing the two looks in a live viewer.
|
|
580
|
-
*/
|
|
581
|
-
/**
|
|
582
|
-
* Switch the viewer to a ready-to-go look at runtime ('studio' | 'technical' | 'showcase'). Retunes
|
|
583
|
-
* lighting/material only (tone mapping, fill, IBL, AO) — never edges/grid. A straight preset apply:
|
|
584
|
-
* overwrites any granular lighting dials you set earlier.
|
|
585
|
-
*/
|
|
586
|
-
setLook: (look: "studio" | "technical" | "showcase") => void;
|
|
587
|
-
/**
|
|
588
|
-
* Retune the fill lights at runtime: the direction-aware hemisphere fill (sky/ground) and the flat
|
|
589
|
-
* ambient. Raising `hemisphereIntensity` is the most effective way to lift shadowed / under-facing
|
|
590
|
-
* surfaces a dark HDR leaves black. A positive `hemisphereIntensity` lazily creates the hemisphere
|
|
591
|
-
* light if the viewer was built without one; `0` switches it off.
|
|
592
|
-
*/
|
|
593
|
-
setFillLights: (opts: {
|
|
594
|
-
hemisphereIntensity?: number;
|
|
595
|
-
hemisphereSkyColor?: THREE.Color | number;
|
|
596
|
-
hemisphereGroundColor?: THREE.Color | number;
|
|
597
|
-
ambientIntensity?: number;
|
|
598
|
-
}) => void;
|
|
599
|
-
/**
|
|
600
|
-
* Set the uniform multiplier on the HDR's image-based lighting (`scene.environmentIntensity`) at
|
|
601
|
-
* runtime — normalizes brightness across HDRs of differing exposure so the scene isn't at the
|
|
602
|
-
* mercy of whichever HDR is loaded. Applies immediately, even before the HDR finishes decoding.
|
|
603
|
-
*/
|
|
604
|
-
setEnvironmentIntensity: (intensity: number) => void;
|
|
605
|
-
/** Set renderer tone-mapping exposure at runtime. Higher lifts shadows and overall brightness. */
|
|
606
|
-
setToneMappingExposure: (exposure: number) => void;
|
|
607
|
-
/** Set GTAO strength at runtime (0–1). No-op when ambient occlusion isn't active. */
|
|
608
|
-
setAoIntensity: (intensity: number) => void;
|
|
609
|
-
/**
|
|
610
|
-
* The parse-time material options (backface culling, IBL strength) matching the active look — feed
|
|
611
|
-
* into the batch parser's `material` option so freshly-loaded meshes are built to match it. See
|
|
612
|
-
* `setLook`.
|
|
613
|
-
*/
|
|
614
|
-
getMaterialAppearance: () => MaterialAppearanceOptions;
|
|
615
|
-
/**
|
|
616
|
-
* Refit the sun's shadow frustum to the current scene content for crisp shadows. Call after
|
|
617
|
-
* loading or replacing geometry (e.g. after `updateScene`). No-op when sunlight/shadows are off.
|
|
618
|
-
*/
|
|
619
|
-
updateShadowBounds: () => void;
|
|
620
|
-
/**
|
|
621
|
-
* Rescale the grid's cell spacing and fade radius to the current scene content, so parts of any
|
|
622
|
-
* size get readable cells and a fade that reaches past the model. Call after loading or replacing
|
|
623
|
-
* geometry (e.g. after `updateScene`). No-op when the grid is off or there's no content.
|
|
624
|
-
*/
|
|
625
|
-
updateGridScale: () => void;
|
|
626
|
-
dispose: () => void;
|
|
627
|
-
fitToView: () => void;
|
|
628
|
-
clearSelection: () => void;
|
|
629
|
-
/**
|
|
630
|
-
* Add caller-owned geometry (lines, annotations, construction aids) to the scene. The object is
|
|
631
|
-
* tagged `userData.source = 'user'` so it persists across `updateScene` solves instead of being
|
|
632
|
-
* cleared with compute content. It is treated as normal content for fit-to-view framing.
|
|
633
|
-
*/
|
|
634
|
-
addUserGeometry: (object: THREE.Object3D) => void;
|
|
635
|
-
/** Remove a single user-added object and dispose its geometry/materials. */
|
|
636
|
-
removeUserGeometry: (object: THREE.Object3D) => void;
|
|
637
|
-
/** Remove and dispose all user-added geometry (every object tagged `source === 'user'`). */
|
|
638
|
-
clearUserGeometry: () => void;
|
|
639
|
-
};
|
|
640
|
-
|
|
641
|
-
/** Updates scene with meshes and positions camera on first call. */
|
|
642
|
-
declare function updateScene(scene: THREE.Scene, meshes: THREE.Object3D[], camera: THREE.PerspectiveCamera, controls: OrbitControls, initialPositionSet: boolean): void;
|
|
643
|
-
/** Parses color strings (hex, RGB, CSS names). */
|
|
644
|
-
declare function parseColor(colorString: string): THREE.Color;
|
|
645
|
-
/**
|
|
646
|
-
* Shift objects along one world axis. Defaults to `z` — the up axis of the unified Z-up scene
|
|
647
|
-
* frame (see `../coordinate-transform.ts`), so grounding subtracts the content's lowest z. Pass an
|
|
648
|
-
* explicit axis when the scene is configured with a different `sceneUp`.
|
|
649
|
-
*/
|
|
650
|
-
declare function applyOffset(meshes: THREE.Object3D[], offset: number, axis?: 'x' | 'y' | 'z'): void;
|
|
651
|
-
/**
|
|
652
|
-
* Computes the combined world-axis-aligned bounding box of a set of objects (meshes, lines, points).
|
|
653
|
-
* Correctly accounts for transformations (rotation, position, scale).
|
|
654
|
-
*/
|
|
655
|
-
declare function computeCombinedBoundingBox(meshes: THREE.Object3D[]): THREE.Box3;
|
|
656
|
-
|
|
657
|
-
declare const EMISSIVE_MATERIAL: THREE.MeshPhysicalMaterial;
|
|
658
|
-
declare const METAL_MATERIAL: THREE.MeshPhysicalMaterial;
|
|
659
|
-
declare const CONCRETE_MATERIAL: THREE.MeshPhysicalMaterial;
|
|
660
|
-
declare const PLASTIC_MATERIAL: THREE.MeshPhysicalMaterial;
|
|
661
|
-
declare const GLASS_MATERIAL: THREE.MeshPhysicalMaterial;
|
|
662
|
-
declare const RUBBER_MATERIAL: THREE.MeshPhysicalMaterial;
|
|
663
|
-
declare const WOOD_MATERIAL: THREE.MeshPhysicalMaterial;
|
|
664
|
-
/** Shared singleton materials; must not be disposed (rebuilds shaders, frees textures). */
|
|
665
|
-
declare const SHARED_MATERIALS: ReadonlySet<THREE.Material>;
|
|
666
|
-
|
|
667
|
-
declare const threeMaterials_CONCRETE_MATERIAL: typeof CONCRETE_MATERIAL;
|
|
668
|
-
declare const threeMaterials_EMISSIVE_MATERIAL: typeof EMISSIVE_MATERIAL;
|
|
669
|
-
declare const threeMaterials_GLASS_MATERIAL: typeof GLASS_MATERIAL;
|
|
670
|
-
declare const threeMaterials_METAL_MATERIAL: typeof METAL_MATERIAL;
|
|
671
|
-
declare const threeMaterials_PLASTIC_MATERIAL: typeof PLASTIC_MATERIAL;
|
|
672
|
-
declare const threeMaterials_RUBBER_MATERIAL: typeof RUBBER_MATERIAL;
|
|
673
|
-
declare const threeMaterials_SHARED_MATERIALS: typeof SHARED_MATERIALS;
|
|
674
|
-
declare const threeMaterials_WOOD_MATERIAL: typeof WOOD_MATERIAL;
|
|
675
|
-
declare namespace threeMaterials {
|
|
676
|
-
export { threeMaterials_CONCRETE_MATERIAL as CONCRETE_MATERIAL, threeMaterials_EMISSIVE_MATERIAL as EMISSIVE_MATERIAL, threeMaterials_GLASS_MATERIAL as GLASS_MATERIAL, threeMaterials_METAL_MATERIAL as METAL_MATERIAL, threeMaterials_PLASTIC_MATERIAL as PLASTIC_MATERIAL, threeMaterials_RUBBER_MATERIAL as RUBBER_MATERIAL, threeMaterials_SHARED_MATERIALS as SHARED_MATERIALS, threeMaterials_WOOD_MATERIAL as WOOD_MATERIAL };
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
/**
|
|
680
|
-
* The single source of truth for "which way is up, and what do front/right mean" in the viewer.
|
|
681
|
-
*
|
|
682
|
-
* Every up-dependent default (camera framing, sun position, ground offset, view presets) derives
|
|
683
|
-
* from {@link buildUpBasis} instead of hardcoding an axis. Before this module those defaults each
|
|
684
|
-
* spelled out a Z-up vector inline, so a scene configured Y-up got a below-horizon camera and a
|
|
685
|
-
* near-horizontal sun while the presets and floor correctly followed `sceneUp`.
|
|
686
|
-
*
|
|
687
|
-
* ## Why front is -forward
|
|
688
|
-
*
|
|
689
|
-
* The basis returns `forward` = the direction the camera LOOKS (from camera toward model), and the
|
|
690
|
-
* preset positions are the opposite (from target toward camera). Rhino's convention fixes the signs:
|
|
691
|
-
* its Front view looks along +Y, so the camera sits at -Y; its Right view looks along -X, so the
|
|
692
|
-
* camera sits at +X. Deriving `right` as `seed x up` (rather than `up x seed`) is what makes the
|
|
693
|
-
* handedness come out matching Rhino rather than mirrored.
|
|
694
|
-
*/
|
|
695
|
-
/** An orthonormal frame derived from a scene up axis. All vectors are unit length. */
|
|
696
|
-
interface UpBasis {
|
|
697
|
-
/** The scene up axis, normalized. */
|
|
698
|
-
up: THREE.Vector3;
|
|
699
|
-
/** The direction a "front" view looks along (from camera toward the model). */
|
|
700
|
-
forward: THREE.Vector3;
|
|
701
|
-
/** Completes a right-handed frame with `up` and `forward`. */
|
|
702
|
-
right: THREE.Vector3;
|
|
703
|
-
}
|
|
704
|
-
/**
|
|
705
|
-
* Derive the ground-plane axes for a given up vector.
|
|
706
|
-
*
|
|
707
|
-
* The seed picks whichever world axis is least parallel to `up`, so the cross products stay
|
|
708
|
-
* well-conditioned in any up convention. For Rhino's Z-up this yields forward = +Y and right = +X,
|
|
709
|
-
* matching Rhino's own Front/Right views; for Three's native Y-up it yields forward = -Z and
|
|
710
|
-
* right = +X, matching Three's convention that the default camera looks down -Z.
|
|
711
|
-
*/
|
|
712
|
-
declare function buildUpBasis(up: THREE.Vector3): UpBasis;
|
|
713
|
-
/**
|
|
714
|
-
* The default 3/4 iso camera OFFSET from the target, scaled to `distance`.
|
|
715
|
-
*
|
|
716
|
-
* Placed behind-left and above the model (the conventional architectural 3/4), expressed in the
|
|
717
|
-
* scene's own basis so it reads the same in any up convention. Callers add this to the framing
|
|
718
|
-
* target to get a camera position.
|
|
719
|
-
*/
|
|
720
|
-
declare function isoOffset(up: THREE.Vector3, distance: number): THREE.Vector3;
|
|
721
|
-
/**
|
|
722
|
-
* A default sun position: high above the model, offset to one side so surfaces get a directional
|
|
723
|
-
* gradient instead of flat top-down light. Expressed in the scene basis rather than a literal
|
|
724
|
-
* Z-up vector, so a Y-up scene still gets an overhead sun rather than a horizontal one.
|
|
725
|
-
*/
|
|
726
|
-
declare function sunOffset(up: THREE.Vector3, sideDistance: number, height: number): THREE.Vector3;
|
|
727
|
-
/**
|
|
728
|
-
* The rotation that puts an equirectangular environment map's horizon on the scene's ground plane.
|
|
729
|
-
*
|
|
730
|
-
* Three's equirect mapping is hardcoded to Y-up: it assumes the HDR's horizon lies in the XZ plane
|
|
731
|
-
* and its zenith points along +Y. In a Z-up scene that leaves the environment on its side — the
|
|
732
|
-
* horizon runs vertically and image-based lighting arrives from +Y rather than from overhead. The
|
|
733
|
-
* result is a subtly wrong key direction that a neutral studio HDR hides but any sky/ground HDR
|
|
734
|
-
* makes obvious.
|
|
735
|
-
*
|
|
736
|
-
* Returns the Euler that rotates the map's native +Y zenith onto `up`. Identity for a Y-up scene.
|
|
737
|
-
* Apply to BOTH `scene.environmentRotation` and `scene.backgroundRotation` — they are independent
|
|
738
|
-
* properties, and setting only one makes the visible background disagree with the lighting.
|
|
739
|
-
*/
|
|
740
|
-
declare function environmentRotationFor(up: THREE.Vector3): THREE.Euler;
|
|
741
|
-
/**
|
|
742
|
-
* Which world axis (`'x' | 'y' | 'z'`) the up vector most closely aligns with.
|
|
743
|
-
*
|
|
744
|
-
* Used for the grid plane and for the ground-offset axis — both need a single component index
|
|
745
|
-
* rather than a full vector. An off-axis up vector resolves to its dominant component.
|
|
746
|
-
*/
|
|
747
|
-
declare function upToAxis(up: THREE.Vector3): 'x' | 'y' | 'z';
|
|
748
|
-
|
|
749
|
-
/**
|
|
750
|
-
* Crisp boundary/crease edges overlaid on meshes — the defining "technical drawing" look that makes
|
|
751
|
-
* shaded geometry read as discrete objects rather than blobs.
|
|
752
|
-
*
|
|
753
|
-
* Edge segments are extracted by `extractEdgeSegments` (see edge-extract.ts — an
|
|
754
|
-
* `EdgesGeometry`-equivalent that is ~an order of magnitude faster and worker-portable) and
|
|
755
|
-
* rendered as fat `LineSegments2` using the same `LineMaterial` family as curves — so edges get
|
|
756
|
-
* controllable thickness, not the 1px cap of `THREE.LineSegments`. The overlay is added as a
|
|
757
|
-
* *child* of each mesh, so it inherits the mesh's transform and is disposed when the mesh subtree
|
|
758
|
-
* is cleared.
|
|
759
|
-
*
|
|
760
|
-
* Performance model (docs/plans/4.edge-overlay-performance.md):
|
|
761
|
-
* - Extraction results are cached at two levels: per source `BufferGeometry` (object identity,
|
|
762
|
-
* helps instanced parts within one solve) and by *content fingerprint* in an LRU — the viewer
|
|
763
|
-
* rebuilds all geometry objects every solve, so only a content key survives re-solves.
|
|
764
|
-
* - {@link addEdgesAsync} runs extraction for large meshes in a Worker built from a blob URL
|
|
765
|
-
* (bundler-agnostic; falls back to inline extraction when Workers are unavailable), keeping the
|
|
766
|
-
* main thread free of the multi-second stalls extraction causes at millions of triangles.
|
|
767
|
-
* - Caps bound the pathological cases: meshes above `maxTriangles` are skipped outright (tagged
|
|
768
|
-
* `userData.edgesSkipped = 'triangle-cap'`), overlays above `maxSegments` lose the distance
|
|
769
|
-
* fade so they render in the cheaper opaque pass.
|
|
770
|
-
*
|
|
771
|
-
* Depth strategy: surfaces render at TRUE depth, untouched; the LINES carry a small units-only
|
|
772
|
-
* polygonOffset toward the camera (see EDGE_OFFSET_FACTOR/UNITS).
|
|
773
|
-
*
|
|
774
|
-
* This reverses an earlier strategy that instead pushed each mesh's *surface* back with a
|
|
775
|
-
* slope-scaled offset (factor 1, units 2). That version bled badly: the slope term scales with
|
|
776
|
-
* dZ/dpixel, which is enormous on a surface viewed near edge-on, so grazing faces receded by much
|
|
777
|
-
* more than the millimetre gaps between stacked parts — geometry behind a wall then beat the wall's
|
|
778
|
-
* own receded surface and drew through it. It also clobbered the polygonOffset that look presets
|
|
779
|
-
* configure on their materials, and its "restore" path reset those to 0 rather than to the preset's
|
|
780
|
-
* values.
|
|
781
|
-
*
|
|
782
|
-
* A units-only bias on the lines is bounded by construction: a fixed number of depth quantization
|
|
783
|
-
* steps, independent of viewing angle, so it lifts an edge off its own coplanar surface without ever
|
|
784
|
-
* reaching across to a neighbouring part.
|
|
785
|
-
*
|
|
786
|
-
* The caveat the old strategy correctly identified: a depth ULP grows ~quadratically with viewing
|
|
787
|
-
* distance, so a constant bias is only safe while ULPs stay small. That is what the dynamic
|
|
788
|
-
* near-plane fitter (near-plane.ts) buys — it keeps `camera.near` proportional to the camera↔content
|
|
789
|
-
* gap, holding ULPs at micron scale even zoomed well out. The two mechanisms are load-bearing
|
|
790
|
-
* together; weakening the near fit will make this bias start to bleed.
|
|
791
|
-
*/
|
|
792
|
-
interface EdgeOptions {
|
|
793
|
-
/**
|
|
794
|
-
* Force a single edge color for every overlay. When omitted (the default), each overlay derives
|
|
795
|
-
* its color from its own mesh's material — a darkened tint of the surface — so edges read as the
|
|
796
|
-
* object's own outline rather than a uniform black frame. Meshes with no readable material color
|
|
797
|
-
* fall back to {@link DEFAULT_EDGE_COLOR}.
|
|
798
|
-
*/
|
|
799
|
-
color?: THREE.ColorRepresentation;
|
|
800
|
-
/**
|
|
801
|
-
* How far to darken the derived edge color toward black, 0–1 (default 0.75). Only applies when
|
|
802
|
-
* `color` is omitted. Higher = darker edges; 0 leaves edges the surface color, 1 makes them black.
|
|
803
|
-
*/
|
|
804
|
-
darken?: number;
|
|
805
|
-
/** Edge thickness in CSS px. Default 1.5. */
|
|
806
|
-
width?: number;
|
|
807
|
-
/**
|
|
808
|
-
* Crease angle in degrees: an edge is kept only where its two faces differ by more than this.
|
|
809
|
-
* Default 44. Higher = fewer edges (only sharp creases); lower = more (catches gentle bends).
|
|
810
|
-
*/
|
|
811
|
-
thresholdAngle?: number;
|
|
812
|
-
/**
|
|
813
|
-
* Fade an overlay out as its own edges crowd together on screen (default true). Edges draw at a
|
|
814
|
-
* constant pixel width, so once neighbouring lines sit less than a pixel or two apart they stop
|
|
815
|
-
* resolving and merge into a dark smear — worst on layered sheet goods, whose millimetre-pitch
|
|
816
|
-
* laminations are sub-pixel at any normal zoom on a metre-scale part. Fading by edge density
|
|
817
|
-
* (not by how large the mesh is) returns those parts to a clean shaded read while leaving
|
|
818
|
-
* sparsely-edged geometry fully drawn at the same distance.
|
|
819
|
-
*/
|
|
820
|
-
distanceFade?: boolean;
|
|
821
|
-
/**
|
|
822
|
-
* Skip meshes above this triangle count entirely (default 4M) — extraction time is linear in
|
|
823
|
-
* triangles, and past this bound even the worker path burns seconds for a look the screen-space
|
|
824
|
-
* fallback approximates at constant cost. Skipped meshes are tagged
|
|
825
|
-
* `userData.edgesSkipped = 'triangle-cap'` so hosts can react (e.g. enable the render-pipeline
|
|
826
|
-
* edge pass).
|
|
827
|
-
*/
|
|
828
|
-
maxTriangles?: number;
|
|
829
|
-
/**
|
|
830
|
-
* Above this many extracted segments (default 2M), an overlay drops the distance fade so it
|
|
831
|
-
* renders opaque — millions of blended fat-line quads are a fill-rate cliff; opaque ones aren't.
|
|
832
|
-
*/
|
|
833
|
-
maxSegments?: number;
|
|
834
|
-
}
|
|
835
|
-
/** Tag on edge overlays so pick/fit/clear logic can recognize and skip or dispose them. */
|
|
836
|
-
declare const EDGE_USERDATA_KIND = "edge-overlay";
|
|
837
|
-
/** `userData.edgesSkipped` value on meshes whose triangle count exceeded {@link EdgeOptions.maxTriangles}. */
|
|
838
|
-
declare const EDGES_SKIPPED_TRIANGLE_CAP = "triangle-cap";
|
|
839
|
-
/** Whether an object is an edge overlay (for pick/fit filters elsewhere). */
|
|
840
|
-
declare function isEdgeOverlay(object: THREE.Object3D): boolean;
|
|
841
|
-
/**
|
|
842
|
-
* Walk an object subtree and attach an edge overlay to every `Mesh` found, returning the created
|
|
843
|
-
* overlays (so callers can dispose them explicitly if they don't clear the whole subtree). Meshes
|
|
844
|
-
* that already carry an overlay are skipped, so this is safe to call more than once.
|
|
845
|
-
*
|
|
846
|
-
* Skips the floor and the grid (they're aids, not content) and anything already tagged as an edge.
|
|
847
|
-
*
|
|
848
|
-
* Fully synchronous — extraction for every mesh runs on the calling thread. Interactive hosts with
|
|
849
|
-
* potentially-large meshes should prefer {@link addEdgesAsync}, which offloads big extractions to
|
|
850
|
-
* a worker.
|
|
851
|
-
*/
|
|
852
|
-
declare function addEdges(root: THREE.Object3D, options?: EdgeOptions): LineSegments2[];
|
|
853
|
-
/**
|
|
854
|
-
* Like {@link addEdges}, but extraction for large meshes runs in a Worker so the main thread never
|
|
855
|
-
* stalls. Small meshes (< ~25k triangles) still attach synchronously before this returns — only
|
|
856
|
-
* heavy extractions arrive a beat later. Resolves with every overlay actually attached.
|
|
857
|
-
*
|
|
858
|
-
* Late results are dropped (never attached) when the mesh has left the root's subtree (scene was
|
|
859
|
-
* cleared by a newer solve), the root's edges were removed via {@link removeEdges}, or another
|
|
860
|
-
* apply already attached an overlay to that mesh.
|
|
861
|
-
*/
|
|
862
|
-
declare function addEdgesAsync(root: THREE.Object3D, options?: EdgeOptions): Promise<LineSegments2[]>;
|
|
863
|
-
/**
|
|
864
|
-
* Remove every edge overlay under `root`, disposing its geometry and material. The inverse of
|
|
865
|
-
* {@link addEdges}/{@link addEdgesAsync}; together they make edges a live on/off toggle — this
|
|
866
|
-
* also cancels any in-flight async attaches for `root`. Returns how many were removed.
|
|
867
|
-
*/
|
|
868
|
-
declare function removeEdges(root: THREE.Object3D): number;
|
|
869
|
-
|
|
870
|
-
/**
|
|
871
|
-
* Screen-space edge detection: draws crease/silhouette lines by finding depth and normal
|
|
872
|
-
* discontinuities, as a fullscreen pass — cost is O(pixels), independent of triangle count.
|
|
873
|
-
*
|
|
874
|
-
* This is the fallback look for scenes too heavy for geometry edge overlays (see
|
|
875
|
-
* docs/plans/4.edge-overlay-performance.md Phase 3): meshes over `EdgeOptions.maxTriangles` skip
|
|
876
|
-
* extraction, and this pass approximates the technical-drawing read at constant cost. Trade-offs
|
|
877
|
-
* vs geometry edges: uniform pixel width, one global color (no per-object tinting), view-dependent
|
|
878
|
-
* response, and gentle creases below the normal threshold don't register.
|
|
879
|
-
*
|
|
880
|
-
* Works like GTAOPass internally: the scene is re-rendered with a `MeshNormalMaterial` override
|
|
881
|
-
* into a normal target carrying a depth texture (a pattern this scene already tolerates for AO),
|
|
882
|
-
* then a fullscreen shader Roberts-crosses depth (relative view-Z difference, so far scenes don't
|
|
883
|
-
* dissolve into noise) and normals, and blends the edge color over the composed image.
|
|
884
|
-
*
|
|
885
|
-
* The render target is allocated lazily on first enabled render, so constructing the pass
|
|
886
|
-
* disabled costs nothing but the material.
|
|
887
|
-
*/
|
|
888
|
-
interface EdgeDetectionOptions {
|
|
889
|
-
/** Edge line color. Default 0x222222 — matches the geometry overlays' default. */
|
|
890
|
-
color?: THREE.ColorRepresentation;
|
|
891
|
-
/** Edge blend strength 0–1. Default 1. */
|
|
892
|
-
opacity?: number;
|
|
893
|
-
/**
|
|
894
|
-
* Normal discontinuity threshold, in summed `1 - dot(n₁, n₂)` across the two diagonal pairs.
|
|
895
|
-
* Lower catches gentler creases. Default 0.4 (≈ the 44° crease default of geometry edges).
|
|
896
|
-
*/
|
|
897
|
-
normalThreshold?: number;
|
|
898
|
-
/** Relative view-depth discontinuity threshold. Default 0.02 (2% of the center depth). */
|
|
899
|
-
depthThreshold?: number;
|
|
900
|
-
/** Sample offset in device px — line thickness. Default 1. */
|
|
901
|
-
thickness?: number;
|
|
902
|
-
}
|
|
903
|
-
declare class EdgeDetectionPass extends Pass {
|
|
904
|
-
camera: THREE.Camera;
|
|
905
|
-
private readonly scene;
|
|
906
|
-
private readonly normalMaterial;
|
|
907
|
-
private readonly edgeMaterial;
|
|
908
|
-
private readonly fsQuad;
|
|
909
|
-
private normalTarget;
|
|
910
|
-
private width;
|
|
911
|
-
private height;
|
|
912
|
-
constructor(scene: THREE.Scene, camera: THREE.Camera, width: number, height: number, options?: EdgeDetectionOptions);
|
|
913
|
-
private acquireNormalTarget;
|
|
914
|
-
setSize(width: number, height: number): void;
|
|
915
|
-
render(renderer: THREE.WebGLRenderer, writeBuffer: THREE.WebGLRenderTarget, readBuffer: THREE.WebGLRenderTarget): void;
|
|
916
|
-
dispose(): void;
|
|
917
|
-
}
|
|
918
|
-
|
|
919
|
-
/**
|
|
920
|
-
* Optional postprocessing pipeline. Default-OFF: the viewer only constructs this when a
|
|
921
|
-
* postprocessed feature (ambient occlusion, screen-space edges) is enabled, and otherwise renders
|
|
922
|
-
* with a plain `renderer.render` so the cheap path stays cheap (the chosen tradeoff — see
|
|
923
|
-
* cad-viewer-plan.md).
|
|
924
|
-
*
|
|
925
|
-
* Pipeline: RenderPass → GTAOPass? → EdgeDetectionPass? → SMAAPass → OutputPass. GTAO
|
|
926
|
-
* (ground-truth AO) is the modern replacement for SSAO/SAO — better contact shadows in crevices,
|
|
927
|
-
* the "engineered" depth cue. `screenSpaceRadius` is on so the AO radius is in screen space, which
|
|
928
|
-
* keeps it scale-robust across the viewer's mm→m scenes without per-scene tuning.
|
|
929
|
-
*
|
|
930
|
-
* EdgeDetectionPass draws crease/silhouette lines in screen space at O(pixels) — the fallback for
|
|
931
|
-
* scenes too triangle-heavy for geometry edge overlays (docs/plans/4.edge-overlay-performance.md).
|
|
932
|
-
* It sits before SMAA so its 1px lines get antialiased. Always constructed (its render target is
|
|
933
|
-
* lazy), so it can be toggled at runtime via {@link RenderPipeline.setEdgeDetection} without a
|
|
934
|
-
* pipeline rebuild.
|
|
935
|
-
*
|
|
936
|
-
* SMAA restores antialiasing on this path. The EffectComposer renders into an offscreen target, so
|
|
937
|
-
* the WebGLRenderer's own MSAA (`antialias: true`) does nothing here — without a dedicated AA pass,
|
|
938
|
-
* enabling AO would visibly *worsen* edge quality. SMAA is chosen over TAA because TAA's temporal
|
|
939
|
-
* jitter smears during OrbitControls drags; SMAA is single-frame, cheap, and stable while orbiting.
|
|
940
|
-
*
|
|
941
|
-
* OutputPass applies tone mapping + color space last (taking over the roles the renderer did
|
|
942
|
-
* directly in the non-composer path), so SMAA operates on the pre-tonemapped image as intended.
|
|
943
|
-
*
|
|
944
|
-
* Camera swaps: the active camera can flip perspective↔ortho. Rather than rebuild the composer, we
|
|
945
|
-
* retarget the passes' `camera` each render via {@link setCamera}.
|
|
946
|
-
*/
|
|
947
|
-
interface RenderPipeline {
|
|
948
|
-
render(deltaTime: number): void;
|
|
949
|
-
setSize(width: number, height: number, pixelRatio: number): void;
|
|
950
|
-
/** Point the passes at the currently active camera (call when projection changes). */
|
|
951
|
-
setCamera(camera: THREE.Camera): void;
|
|
952
|
-
/** Toggle the screen-space edge pass at runtime (no pipeline rebuild). */
|
|
953
|
-
setEdgeDetection(enabled: boolean): void;
|
|
954
|
-
/** Whether the screen-space edge pass currently runs. */
|
|
955
|
-
edgeDetectionEnabled(): boolean;
|
|
956
|
-
dispose(): void;
|
|
957
|
-
}
|
|
958
|
-
interface RenderPipelineOptions {
|
|
959
|
-
/** Tone mapping to apply in OutputPass (mirror the renderer's). */
|
|
960
|
-
toneMapping: THREE.ToneMapping;
|
|
961
|
-
toneMappingExposure: number;
|
|
962
|
-
/** Build the pipeline with the GTAO ambient-occlusion pass. Default true. */
|
|
963
|
-
ambientOcclusion?: boolean;
|
|
964
|
-
/** AO strength 0–1. Default 1. */
|
|
965
|
-
aoIntensity?: number;
|
|
966
|
-
/**
|
|
967
|
-
* Cap on the device-pixel-ratio used for the composer's (AO) buffers. AO is low-frequency, so
|
|
968
|
-
* rendering below the display DPR is nearly invisible but far cheaper. `setSize`'s incoming
|
|
969
|
-
* pixelRatio is clamped to this. Default 1.
|
|
970
|
-
*/
|
|
971
|
-
aoPixelRatio?: number;
|
|
972
|
-
/**
|
|
973
|
-
* Start with the screen-space edge pass enabled; pass an object to tune it. The pass itself is
|
|
974
|
-
* always constructed (cheap while disabled) so it can be toggled later via `setEdgeDetection`.
|
|
975
|
-
*/
|
|
976
|
-
edgeDetection?: boolean | EdgeDetectionOptions;
|
|
977
|
-
}
|
|
978
|
-
declare function createRenderPipeline(renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.Camera, width: number, height: number, options: RenderPipelineOptions): RenderPipeline;
|
|
979
|
-
|
|
980
|
-
/**
|
|
981
|
-
* Metres per model unit, keyed by Rhino `UnitSystem` name (the `modelunits` string on the compute
|
|
982
|
-
* response). Imperial factors are the exact international definitions (1 in = 0.0254 m,
|
|
983
|
-
* 1 ft = 0.3048 m, 1 mi = 1609.344 m). Units not in this table scale 1 and log a one-time warning
|
|
984
|
-
* — see {@link getScaleFactor}.
|
|
985
|
-
*/
|
|
986
|
-
declare const SCALE_FACTORS: Record<string, number>;
|
|
987
|
-
/**
|
|
988
|
-
* Extracts and processes display meshes from a ComputePointerResponse using the Grasshopper WebDisplay component.
|
|
989
|
-
*
|
|
990
|
-
* This is the primary entry point for extracting mesh geometry from Grasshopper compute responses.
|
|
991
|
-
* It handles all aspects of mesh processing: decompression, coordinate transformation, scaling, and positioning.
|
|
992
|
-
*
|
|
993
|
-
* **Note:** The entire pipeline (base64 decode, inflate, dequantization, mesh construction) runs
|
|
994
|
-
* synchronously on the calling thread — large batches will block the UI for their duration. The
|
|
995
|
-
* function is `async` only so its shape can stay stable if parsing moves off-thread later.
|
|
996
|
-
*
|
|
997
|
-
* @param data - The ComputePointerResponse containing Grasshopper output trees.
|
|
998
|
-
* @param options - Configuration for mesh extraction and parsing behavior. All options are optional with sensible defaults.
|
|
999
|
-
* @returns Promise resolving to array of THREE.Mesh objects (may be empty).
|
|
1000
|
-
* @throws Rethrows unexpected errors after attempting to dispose any created meshes.
|
|
1001
|
-
*
|
|
1002
|
-
* @remarks
|
|
1003
|
-
* - Only works with the WebDisplay component of GHHeadless.
|
|
1004
|
-
* - Requires changes to Rhino.Compute (see https://github.com/TheVessen/compute.rhino3d).
|
|
1005
|
-
* - Provides a performant way to display mesh data in Three.js.
|
|
1006
|
-
* - All decoding is synchronous on the main thread; there is no Web Worker offload today.
|
|
1007
|
-
* - Supports mesh metadata (names, user data) if provided in the compute response.
|
|
1008
|
-
*
|
|
1009
|
-
* @internal Internal helper: high-level extraction remains public via visualization module, but this
|
|
1010
|
-
* function is considered internal implementation detail for mesh extraction.
|
|
1011
|
-
*
|
|
1012
|
-
* @example
|
|
1013
|
-
* ```ts
|
|
1014
|
-
* // Simple usage with defaults (all processing enabled)
|
|
1015
|
-
* const meshes = await getThreeMeshesFromComputeResponse(response);
|
|
1016
|
-
*
|
|
1017
|
-
* // With debugging enabled
|
|
1018
|
-
* const meshes = await getThreeMeshesFromComputeResponse(response, { debug: true });
|
|
1019
|
-
*
|
|
1020
|
-
* // Opt in to seating the model on the grid instead of using its Rhino coordinates
|
|
1021
|
-
* const meshes = await getThreeMeshesFromComputeResponse(response, {
|
|
1022
|
-
* debug: true,
|
|
1023
|
-
* allowScaling: true,
|
|
1024
|
-
* allowAutoPosition: true,
|
|
1025
|
-
* parsing: {
|
|
1026
|
-
* mergeByMaterial: false,
|
|
1027
|
-
* applyTransforms: true,
|
|
1028
|
-
* debug: true,
|
|
1029
|
-
* },
|
|
1030
|
-
* });
|
|
1031
|
-
* ```
|
|
1032
|
-
*/
|
|
1033
|
-
declare function getThreeMeshesFromComputeResponse(data: GrasshopperComputeResponse, options?: MeshExtractionOptions): Promise<THREE.Object3D[]>;
|
|
1034
|
-
|
|
1035
|
-
/** Internal telemetry only (not exposed in public options). */
|
|
1036
|
-
interface ParseTelemetry {
|
|
1037
|
-
parseTime?: number;
|
|
1038
|
-
perfStart?: number;
|
|
1039
|
-
}
|
|
1040
|
-
/**
|
|
1041
|
-
* Parses a DisplayBatch object and creates Three.js meshes from its mesh blob.
|
|
1042
|
-
*
|
|
1043
|
-
* The path is synchronous internally — `parseBinaryMeshBatch` does no IO, just typed-array views
|
|
1044
|
-
* over the blob. The function stays `async` so callers don't have to change shape if we move
|
|
1045
|
-
* parsing into a worker later.
|
|
1046
|
-
*
|
|
1047
|
-
* A batch with no `compressedData` (genuinely empty/absent geometry) resolves to `[]`. A corrupt,
|
|
1048
|
-
* truncated, or unsupported blob throws so callers get a signal instead of a silent empty scene —
|
|
1049
|
-
* `getThreeMeshesFromComputeResponse` documents (and now delivers) exactly that rethrow.
|
|
1050
|
-
*
|
|
1051
|
-
* @param batch - DisplayBatch object
|
|
1052
|
-
* @param options - Rendering options
|
|
1053
|
-
* @returns Promise resolving to array of Three.js mesh objects
|
|
1054
|
-
* @throws {RhinoComputeError} On a corrupt/truncated/unsupported mesh blob or malformed group metadata.
|
|
1055
|
-
*/
|
|
1056
|
-
declare function parseMeshBatchObject(batch: DisplayBatch, options?: MeshBatchParsingOptions,
|
|
1057
|
-
/** @internal Timings threaded from an outer entry point; not a caller option. */
|
|
1058
|
-
telemetry?: ParseTelemetry): Promise<THREE.Mesh[]>;
|
|
1059
|
-
/**
|
|
1060
|
-
* Parses a raw binary mesh batch blob (SLVA wire format) and creates Three.js meshes.
|
|
1061
|
-
*
|
|
1062
|
-
* Use this entry point when the blob arrives as a binary WebSocket frame (Phase 1b transport):
|
|
1063
|
-
* the JSON envelope no longer carries `displayData`, so there's nothing to `JSON.parse`. The blob
|
|
1064
|
-
* is self-describing — materials, groups, and `sourceComponentId` come from its embedded metadata
|
|
1065
|
-
* header.
|
|
1066
|
-
*
|
|
1067
|
-
* @param blob - Raw blob bytes from a binary WebSocket frame.
|
|
1068
|
-
* @param options - Rendering options.
|
|
1069
|
-
* @returns Promise resolving to array of Three.js mesh objects.
|
|
1070
|
-
* @throws {RhinoComputeError} On a corrupt/truncated/unsupported mesh blob or malformed group metadata.
|
|
1071
|
-
*/
|
|
1072
|
-
declare function parseMeshBatchBlob(blob: ArrayBuffer | Uint8Array, options?: MeshBatchParsingOptions): Promise<THREE.Mesh[]>;
|
|
1073
|
-
|
|
1074
|
-
interface DisplayItemParseOptions {
|
|
1075
|
-
/** rhino3dm instance for decoding curve JSON. Omit to skip curves (points still render). */
|
|
1076
|
-
rhino?: RhinoModule;
|
|
1077
|
-
/**
|
|
1078
|
-
* No-op. Historically toggled the Rhino Z-up → Three Y-up rotation, but the pipeline now keeps
|
|
1079
|
-
* one coordinate frame end to end ({@link rhinoToThree} is the identity), so this flag no longer
|
|
1080
|
-
* changes the result. Do NOT pre-rotate your own geometry to compensate — none is applied.
|
|
1081
|
-
*
|
|
1082
|
-
* @deprecated Retained only so existing call sites compile unchanged; has no effect.
|
|
1083
|
-
*/
|
|
1084
|
-
applyTransforms?: boolean;
|
|
1085
|
-
}
|
|
1086
|
-
/**
|
|
1087
|
-
* Parse a batch's `items` into renderable THREE objects. Returns an empty array when there are no
|
|
1088
|
-
* items. Unknown kinds are skipped with a warning (forward-compatible with future label/icon kinds
|
|
1089
|
-
* a viewer hasn't taught itself to render yet).
|
|
1090
|
-
*/
|
|
1091
|
-
declare function parseDisplayItems(items: DisplayItem[] | undefined, options?: DisplayItemParseOptions): THREE.Object3D[];
|
|
1092
|
-
|
|
1093
|
-
export { type CameraConfig, type CameraController, type CameraProjection, type ControlsConfig, DisplayBatch, DisplayItem, type DisplayItemParseOptions, EDGES_SKIPPED_TRIANGLE_CAP, EDGE_USERDATA_KIND, type EdgeDetectionOptions, EdgeDetectionPass, type EdgeOptions, type EdgesConfig, type EnvironmentConfig, type EventConfig, type FloorConfig, type GizmoConfig, type Grid, type GridConfig, type GridOptions, LOOKS, type LabelHandle, type LabelLayer, type LightingConfig, type Look, threeMaterials as Materials, type MeasureConfig, type MeasureOptions, type MeasureTool, MeshExtractionOptions, type RenderConfig, type RenderPipeline, type RenderPipelineOptions, SCALE_FACTORS, type ThreeInitializerOptions, type UpBasis, type ViewGizmo, type ViewPreset, addEdges, addEdgesAsync, applyOffset, buildUpBasis, computeCombinedBoundingBox, createCameraController, createGrid, createLabelLayer, createMeasureTool, createRenderPipeline, createViewGizmo, environmentRotationFor, getThreeMeshesFromComputeResponse, initThree, isEdgeOverlay, isoOffset, parseColor, parseDisplayItems, parseMeshBatchBlob, parseMeshBatchObject, removeEdges, snapToVertex, sunOffset, upToAxis, updateScene };
|