three-cad-viewer 5.0.6 → 5.1.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.
@@ -62,6 +62,23 @@ export declare class PickingController {
62
62
  private onIdHoverMove;
63
63
  /** Cursor left the canvas → clear any hover highlight. */
64
64
  private onIdHoverLeave;
65
+ /**
66
+ * Pick the visible component under the cursor with the current topo filter, or
67
+ * `null` when the cursor is off the canvas or over background.
68
+ */
69
+ private pickUnderCursor;
70
+ /**
71
+ * World-space point on the visible component under the cursor (same pick as the
72
+ * hover), or `null` when there is none or the GPU lacks the position attachment.
73
+ */
74
+ pointUnderCursor(): THREE.Vector3 | null;
75
+ /**
76
+ * Tree-row hover: HOVER the faces of the tree node at `path` (leaf or group), or
77
+ * clear when `null`. Drops the canvas hover target first — otherwise the next
78
+ * render's {@link handleIdHover} (cursor outside the canvas) would release that
79
+ * stale target and wipe the tree hover with it.
80
+ */
81
+ setTreeHover(path: string | null): void;
65
82
  /**
66
83
  * Whether hover preselection (highlight + status line) is active. Disabled for GDS:
67
84
  * dense, stacked, instance-unrolled layout data where per-pixel hover flickers
@@ -136,6 +136,8 @@ export interface ChangeNotification {
136
136
  clip_normal_1?: StateChange<Vector3Tuple | null>;
137
137
  clip_normal_2?: StateChange<Vector3Tuple | null>;
138
138
  lastPick?: StateChange<PickInfo | null>;
139
+ /** Point copied with Ctrl/Cmd-C (event, sent on every copy; `old` is always null). */
140
+ copiedPoint?: StateChange<Vector3Tuple>;
139
141
  [key: string]: StateChange<unknown> | undefined;
140
142
  }
141
143
  /** Callback for notifications */
@@ -206,6 +206,12 @@ declare class Viewer {
206
206
  private _suppressUpdate;
207
207
  private _zebraSettingsApplied;
208
208
  idPicker: IdPicker | null;
209
+ /** Outline of the clip caps; created on first use, kept across renders. */
210
+ private _capOutline;
211
+ /** Camera world + projection matrix of the previous outline frame (motion test). */
212
+ private _capOutlineCamera;
213
+ /** Pending redraw that adds the outline once the camera has settled. */
214
+ private _capOutlineSettle;
209
215
  pickingController: PickingController;
210
216
  private _studioManager;
211
217
  /** Environment manager — proxied from StudioManager for display.ts access. */
@@ -213,6 +219,8 @@ declare class Viewer {
213
219
  /** True while the Studio (presentation) tab owns the render. PickHost member. */
214
220
  get studioActive(): boolean;
215
221
  zScale: number;
222
+ /** Whether the attached animation has moved parts (Play pressed or time slider moved). */
223
+ private _animationStarted;
216
224
  clipNormal0: Vector3Tuple | null;
217
225
  clipNormal1: Vector3Tuple | null;
218
226
  clipNormal2: Vector3Tuple | null;
@@ -339,6 +347,19 @@ declare class Viewer {
339
347
  */
340
348
  animate: () => void;
341
349
  toggleAnimationLoop(flag: boolean): void;
350
+ /**
351
+ * Draw the outline of the clip caps over the frame (Clip tab active only). Skipped
352
+ * while the camera moves (drag, wheel, damping, preset views): the outline pass
353
+ * renders faces and caps a second time, so it is drawn once the camera has been
354
+ * still for {@link CAP_OUTLINE_SETTLE_MS}.
355
+ */
356
+ private _renderCapOutline;
357
+ /** Whether the camera's world or projection matrix changed since the last call. */
358
+ private _cameraMovedSinceLastOutline;
359
+ /** Redraw once the camera has settled, so the skipped outline appears. */
360
+ private _scheduleCapOutline;
361
+ /** Cancel a pending outline redraw. */
362
+ private _cancelCapOutline;
342
363
  /**
343
364
  * Remove all assets and event handlers. Call when done with the viewer.
344
365
  *
@@ -540,6 +561,17 @@ declare class Viewer {
540
561
  get lastObject(): PickedComponent | null;
541
562
  /** Last committed selection. */
542
563
  get lastSelection(): PickedComponent | null;
564
+ /** Tree-row hover: highlight the faces of the node at `path`, or clear on `null`. */
565
+ handleTreeHover: (path: string | null) => void;
566
+ /**
567
+ * Copy the world-space point under the cursor as `"x, y, z"` to the clipboard and
568
+ * send it to the host as a `copiedPoint` notification (for hosts that block the
569
+ * browser clipboard). Does nothing while parts may be displaced from their model
570
+ * positions — explode mode, an animation once started (Play or time slider), a
571
+ * z-scale other than 1 — or when no visible component is under the cursor.
572
+ * @returns true when a point was copied (the caller then consumes the key event).
573
+ */
574
+ copyPointUnderCursor(): boolean;
543
575
  /** Enable/disable the double-click pick handler (on when no tool is active). */
544
576
  setPickHandler(flag: boolean): void;
545
577
  /** Enable/disable click+key selection input (on while a select/measure tool is active). */
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Screen-space outline of the clip caps (CAD mode).
3
+ *
4
+ * The caps carry no geometry of their own outline, and the faces next to a cut may
5
+ * face away from the camera or belong to a touching solid, so the outline is found
6
+ * in screen space instead:
7
+ *
8
+ * 1. Id pass into an offscreen target (color + depth + stencil):
9
+ * - visible faces as black occluders (face pick layer + override material), so a
10
+ * cap hidden behind another part gets no outline; face pixels within the line
11
+ * width of a clip plane write {@link CUT_EDGE_ID} instead, which draws the cut
12
+ * contour on the faces themselves (needed when the caps are behind the faces),
13
+ * - the stencil meshes and caps (on {@link CAP_LAYER}) with each cap writing its
14
+ * own id instead of its shaded color — the same stencil sequence as the main
15
+ * render, since three orders them identically (material creation order).
16
+ * 2. Composite over the canvas: a pixel is drawn in the edge color when its id is
17
+ * larger than a neighbour's id, which yields a line on one side of every boundary
18
+ * cap↔cap, cap↔surface and cap↔background. Cut-edge pixels are the largest id, so
19
+ * where they meet a cap only they are drawn — one line, not two.
20
+ */
21
+ import * as THREE from "three";
22
+ /** Render layer of the clip stencil meshes and cap quads (pick layers use 1-3). */
23
+ export declare const CAP_LAYER = 4;
24
+ /** Id of face pixels on the cut contour (larger than any cap id). */
25
+ export declare const CUT_EDGE_ID = 16777215;
26
+ /** Encode a cap id (1..2^24-1) as an exact 8-bit RGB color (0 = no cap). */
27
+ export declare function capIdColor(id: number): THREE.Vector3;
28
+ /** Per-frame inputs of {@link CapOutlinePass.render}. */
29
+ export interface CapOutlineOptions {
30
+ /** Clip planes and mode of the face materials (for the occluders). */
31
+ planes: THREE.Plane[];
32
+ intersection: boolean;
33
+ /** Draw faces as occluders (off in transparent mode: caps show through faces). */
34
+ occlude: boolean;
35
+ /** Outline color (sRGB hex). */
36
+ color: number;
37
+ /** Switch the cap materials between shaded output and id output. */
38
+ setCapIdPass: (flag: boolean) => void;
39
+ }
40
+ export declare class CapOutlinePass {
41
+ private target;
42
+ private readonly occluder;
43
+ /** Width of the cut contour on the faces, in device pixels (= outline width). */
44
+ private readonly cutWidth;
45
+ private readonly composite;
46
+ private readonly quadScene;
47
+ private readonly quadCamera;
48
+ private readonly quad;
49
+ private readonly size;
50
+ private readonly savedClearColor;
51
+ private readonly savedViewport;
52
+ constructor();
53
+ private ensureTarget;
54
+ /**
55
+ * Render the id pass and draw the outline over the current (canvas) framebuffer.
56
+ * Call right after the main scene render.
57
+ */
58
+ render(renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.Camera, options: CapOutlineOptions): void;
59
+ dispose(): void;
60
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Section hatching for clip caps (CAD mode, shader-only). The per-solid cap quads
3
+ * draw hatch lines anchored to the plane (stable while rotating/panning) whose
4
+ * spacing is kept at a constant pixel distance by a per-frame world-per-pixel
5
+ * uniform. The outline of the caps is drawn separately (see cap-outline.ts); for its
6
+ * id pass the same cap shader can output the cap's id instead of its color.
7
+ *
8
+ * All shared uniforms are plain `{ value }` objects held by reference, so a single
9
+ * write (e.g. the per-frame hatch spacing) updates every patched material without a
10
+ * recompile.
11
+ */
12
+ import * as THREE from "three";
13
+ /** Distance between hatch lines in pixels. */
14
+ export declare const HATCH_SPACING_PX = 8;
15
+ /** Width of a hatch line in pixels. */
16
+ export declare const HATCH_LINE_WIDTH_PX = 1;
17
+ /** Uniforms shared by all hatch patched cap materials of one clipping setup. */
18
+ export interface HatchUniforms {
19
+ /** World units between hatch lines (before the per-solid scale); set per frame. */
20
+ uHatchSpacing: {
21
+ value: number;
22
+ };
23
+ /** Half the cap quad size: maps the quad's [-1, 1] geometry to plane units. */
24
+ uCapHalfSize: {
25
+ value: number;
26
+ };
27
+ uHatchLineWidth: {
28
+ value: number;
29
+ };
30
+ uHatchOn: {
31
+ value: number;
32
+ };
33
+ /** 1 while the cap outline id pass renders: caps output their id, not a color. */
34
+ uCapIdPass: {
35
+ value: number;
36
+ };
37
+ }
38
+ export declare function createHatchUniforms(capHalfSize: number): HatchUniforms;
39
+ /**
40
+ * World units covered by one screen pixel at the given point (exact for an
41
+ * orthographic camera; at the point's distance for a perspective camera).
42
+ */
43
+ export declare function worldPerPixel(camera: THREE.Camera, point: THREE.Vector3, height: number): number;
44
+ /**
45
+ * Patch a cap quad material to draw section hatching. `index` is the solid's index
46
+ * among the caps of its plane; it selects the hatch direction and spacing. `capId`
47
+ * is the cap's unique id color for the outline id pass (see `capIdColor`).
48
+ */
49
+ export declare function patchHatchMaterial(material: THREE.Material, uniforms: HatchUniforms, index: number, capId: THREE.Vector3): void;
@@ -146,6 +146,11 @@ export declare class HighlightController {
146
146
  * when `null`. Mirrors {@link selectSolid} for the transient hover state.
147
147
  */
148
148
  setHoverSolid(solidPath: string | null): void;
149
+ /**
150
+ * HOVER every FACE at or below the tree path `prefix` (a leaf or a whole group),
151
+ * or clear hover when `null`. Drives the tree-row hover highlight.
152
+ */
153
+ setHoverPath(prefix: string | null): void;
149
154
  /** Set or clear the SELECTED flag for a single component id. */
150
155
  setSelected(id: number, flag: boolean): void;
151
156
  /** Whether a component currently carries the SELECTED flag. */
@@ -25,7 +25,10 @@ export declare const BACKGROUND_ID = 0;
25
25
  * `Uint32BufferAttribute` under this name; the pick pass reads it as an **integer**
26
26
  * attribute (`gpuType = THREE.IntType`, GLSL3 `in uint`) so ids stay exact past
27
27
  * 2^24. The geometry side must set `gpuType = THREE.IntType` on the attribute for
28
- * the pick shader to read it.
28
+ * the pick shader to read it. Between the stages the id travels as two float
29
+ * varyings (16-bit halves), deliberately NOT as a `flat uint` — see the note in
30
+ * highlight.ts: a `flat` varying costs ~25x the scene's buffer bytes in graphics
31
+ * memory under WebKit's ANGLE-on-Metal backend.
29
32
  */
30
33
  export declare const COMPONENT_ID_ATTRIBUTE = "componentId";
31
34
  /**
@@ -117,6 +117,9 @@ declare class Clipping extends THREE.Group {
117
117
  private _planeMeshGroup;
118
118
  /** Per-solid stencil/cap units, the unit of screen-size culling. */
119
119
  private _capUnits;
120
+ /** Shared uniforms of the section hatching on all cap quads. */
121
+ private _hatchUniforms;
122
+ private _hatchCenter;
120
123
  /**
121
124
  * Whether {@link cull} last ran with clipping active. Lets the inactive path
122
125
  * gate stencils/caps off exactly once, then early-return on later still frames.
@@ -191,6 +194,10 @@ declare class Clipping extends THREE.Group {
191
194
  * @param flag - True to show, false to hide.
192
195
  */
193
196
  setVisible: (flag: boolean) => void;
197
+ /** Whether any solid has clip caps (the cap outline pass has work to do). */
198
+ get hasCaps(): boolean;
199
+ /** Switch all cap materials between shaded output and outline id output. */
200
+ setCapIdPass: (flag: boolean) => void;
194
201
  /**
195
202
  * Bound the per-frame stencil/cap draw work to keep large assemblies from
196
203
  * overrunning the GPU watchdog on clip+rotate (see {@link CAP_CULL_MIN_PX}).