three-cad-viewer 4.3.8 → 5.0.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 → Readme.md} +7 -5
- package/dist/core/picking-controller.d.ts +125 -0
- package/dist/core/studio-manager.d.ts +7 -0
- package/dist/core/types.d.ts +24 -6
- package/dist/core/viewer-state.d.ts +1 -1
- package/dist/core/viewer.d.ts +44 -47
- package/dist/index.d.ts +5 -5
- package/dist/rendering/environment.d.ts +3 -19
- package/dist/rendering/highlight.d.ts +209 -0
- package/dist/rendering/id-picking.d.ts +464 -0
- package/dist/rendering/light-detection.d.ts +3 -3
- package/dist/rendering/material-factory.d.ts +11 -7
- package/dist/rendering/picked.d.ts +55 -0
- package/dist/rendering/studio-composer.d.ts +3 -3
- package/dist/rendering/tree-model.d.ts +1 -1
- package/dist/scene/clipping.d.ts +53 -0
- package/dist/scene/nestedgroup.d.ts +46 -4
- package/dist/scene/objectgroup.d.ts +17 -0
- package/dist/scene/render-shape.d.ts +3 -19
- package/dist/three-cad-viewer.css +54 -20
- package/dist/three-cad-viewer.esm.js +4867 -1562
- package/dist/three-cad-viewer.esm.js.map +1 -1
- package/dist/three-cad-viewer.esm.min.js +3 -3
- package/dist/three-cad-viewer.js +4867 -1562
- package/dist/three-cad-viewer.min.js +4 -4
- package/dist/tools/cad_tools/measure.d.ts +8 -9
- package/dist/tools/cad_tools/mesh-measure.d.ts +264 -0
- package/dist/tools/cad_tools/select.d.ts +4 -3
- package/dist/tools/cad_tools/tools.d.ts +17 -5
- package/dist/tools/cad_tools/ui.d.ts +8 -6
- package/dist/ui/display.d.ts +25 -2
- package/dist/utils/utils.d.ts +1 -1
- package/package.json +4 -1
- package/dist/rendering/raycast.d.ts +0 -111
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Analyzes equirectangular HDR pixel data to find dominant light sources
|
|
5
5
|
* (softboxes in studio HDRs, sun in outdoor HDRs). Returns direction,
|
|
6
|
-
* intensity, and color for up to
|
|
7
|
-
*
|
|
6
|
+
* intensity, and color for up to MAX_LIGHTS (currently 1), used to create the
|
|
7
|
+
* shadow-casting DirectionalLight in Studio mode.
|
|
8
8
|
*
|
|
9
9
|
* Algorithm: downsample to 128x64 luminance grid → threshold at 10x median
|
|
10
10
|
* → flood-fill cluster → convert centroids to 3D direction vectors.
|
|
@@ -32,7 +32,7 @@ export interface LightDetectionResult {
|
|
|
32
32
|
* @param data - Raw pixel data (Uint16Array for HalfFloat, or Float32Array)
|
|
33
33
|
* @param width - HDR image width in pixels
|
|
34
34
|
* @param height - HDR image height in pixels
|
|
35
|
-
* @returns Detection result with up to
|
|
35
|
+
* @returns Detection result with up to MAX_LIGHTS (currently 1) lights
|
|
36
36
|
*/
|
|
37
37
|
export declare function detectDominantLights(data: Uint16Array | Float32Array, width: number, height: number): LightDetectionResult;
|
|
38
38
|
/**
|
|
@@ -117,12 +117,12 @@ declare class MaterialFactory {
|
|
|
117
117
|
* Create a standard material for back faces with PBR properties.
|
|
118
118
|
* Used for polygon rendering where back faces need full shading.
|
|
119
119
|
*/
|
|
120
|
-
createBackFaceStandardMaterial({ color, alpha, polygonOffsetUnits, visible }: BackFaceMaterialOptions, label?: string): THREE.MeshStandardMaterial;
|
|
120
|
+
createBackFaceStandardMaterial({ color, alpha, polygonOffsetUnits, visible, }: BackFaceMaterialOptions, label?: string): THREE.MeshStandardMaterial;
|
|
121
121
|
/**
|
|
122
122
|
* Create a basic material for back faces (no lighting/PBR).
|
|
123
123
|
* Used for shape rendering where back faces are simple fills.
|
|
124
124
|
*/
|
|
125
|
-
createBackFaceBasicMaterial({ color, alpha, polygonOffsetUnits, visible }: BackFaceMaterialOptions, label?: string): THREE.MeshBasicMaterial;
|
|
125
|
+
createBackFaceBasicMaterial({ color, alpha, polygonOffsetUnits, visible, }: BackFaceMaterialOptions, label?: string): THREE.MeshBasicMaterial;
|
|
126
126
|
/**
|
|
127
127
|
* Create a basic front face material (no PBR, for simple shapes).
|
|
128
128
|
*/
|
|
@@ -130,7 +130,7 @@ declare class MaterialFactory {
|
|
|
130
130
|
/**
|
|
131
131
|
* Create a fat line material (LineMaterial from Three.js examples).
|
|
132
132
|
*/
|
|
133
|
-
createEdgeMaterial({ lineWidth, color, vertexColors, visible, resolution }: EdgeMaterialOptions, label?: string): LineMaterial;
|
|
133
|
+
createEdgeMaterial({ lineWidth, color, vertexColors, visible, resolution, }: EdgeMaterialOptions, label?: string): LineMaterial;
|
|
134
134
|
/**
|
|
135
135
|
* Create a basic line material for simple edges (e.g., polygon outlines).
|
|
136
136
|
*/
|
|
@@ -156,22 +156,26 @@ declare class MaterialFactory {
|
|
|
156
156
|
* @param label - Optional label for GPU tracking
|
|
157
157
|
* @returns Configured MeshPhysicalMaterial (or MeshBasicMaterial if unlit)
|
|
158
158
|
*/
|
|
159
|
-
createStudioMaterial({ materialDef, fallbackColor, fallbackAlpha, textureCache }: StudioMaterialOptions, label?: string): Promise<THREE.MeshPhysicalMaterial | THREE.MeshBasicMaterial>;
|
|
159
|
+
createStudioMaterial({ materialDef, fallbackColor, fallbackAlpha, textureCache, }: StudioMaterialOptions, label?: string): Promise<THREE.MeshPhysicalMaterial | THREE.MeshBasicMaterial>;
|
|
160
160
|
/**
|
|
161
161
|
* Create a Studio mode material from a threejs-materials format entry.
|
|
162
162
|
*
|
|
163
163
|
* threejs-materials `properties` uses simplified property names (e.g., "color",
|
|
164
164
|
* "roughness", "normal") where each entry has an optional `value` (scalar or
|
|
165
|
-
* [r,g,b] array
|
|
165
|
+
* [r,g,b] color array) and/or `texture` (inline data URI). Color arrays follow
|
|
166
|
+
* a per-key color-space convention: `color` is sRGB, the other color keys are
|
|
167
|
+
* linear (see the COLOR_ARRAY_KEYS handling in the values loop below).
|
|
166
168
|
*
|
|
167
169
|
* @param values - Scalar PBR values from threejs-materials
|
|
168
170
|
* @param textures - Texture map references from threejs-materials
|
|
169
171
|
* @param textureRepeat - Optional [u, v] texture tiling applied to all loaded textures
|
|
172
|
+
* @param textureRotation - Optional texture rotation in radians (counterclockwise),
|
|
173
|
+
* pivoting around the texture center (0.5, 0.5)
|
|
170
174
|
* @param textureCache - TextureCache for resolving data URI textures
|
|
171
175
|
* @param label - Optional label for GPU tracking
|
|
172
176
|
* @returns Configured MeshPhysicalMaterial
|
|
173
177
|
*/
|
|
174
|
-
createStudioMaterialFromMaterialX(values: Record<string, unknown>, textures: Record<string, string>, textureRepeat: [number, number] | undefined, textureCache: TextureCacheInterface | null, label?: string): Promise<THREE.MeshPhysicalMaterial>;
|
|
178
|
+
createStudioMaterialFromMaterialX(values: Record<string, unknown>, textures: Record<string, string>, textureRepeat: [number, number] | undefined, textureRotation: number | undefined, textureCache: TextureCacheInterface | null, label?: string): Promise<THREE.MeshPhysicalMaterial>;
|
|
175
179
|
/**
|
|
176
180
|
* Apply alpha mode settings to a material.
|
|
177
181
|
*
|
|
@@ -201,4 +205,4 @@ declare class MaterialFactory {
|
|
|
201
205
|
update(options: UpdateOptions): void;
|
|
202
206
|
}
|
|
203
207
|
export { MaterialFactory };
|
|
204
|
-
export type { MaterialFactoryOptions, UpdateOptions, StudioMaterialOptions, TextureCacheInterface };
|
|
208
|
+
export type { MaterialFactoryOptions, UpdateOptions, StudioMaterialOptions, TextureCacheInterface, };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type * as THREE from "three";
|
|
2
|
+
import type { ComponentInfo, TopoType } from "./id-picking.js";
|
|
3
|
+
import type { HighlightController } from "./highlight.js";
|
|
4
|
+
/**
|
|
5
|
+
* A picked component, so the viewer's selection state and the measure/select
|
|
6
|
+
* tools consume ONE interface. {@link IdPicked} wraps a registry `ComponentInfo`
|
|
7
|
+
* + the shader `HighlightController` (the GPU id-pick path) — NO dependency on the
|
|
8
|
+
* exploded scene graph.
|
|
9
|
+
*/
|
|
10
|
+
export interface PickedComponent {
|
|
11
|
+
/** Canonical "/"-path sent to the backend (component path, or solid path when
|
|
12
|
+
* {@link fromSolid}). Replaces measure's `getId` + tree-sync name munging. */
|
|
13
|
+
readonly backendId: string;
|
|
14
|
+
/** Leaf name, e.g. "faces_3" — source for select.ts's numeric sub-index. */
|
|
15
|
+
readonly name: string;
|
|
16
|
+
/** Topology type of the resolved component. */
|
|
17
|
+
readonly topo: TopoType;
|
|
18
|
+
/** Solid-selection mode (the topo filter is "solid"). */
|
|
19
|
+
readonly fromSolid: boolean;
|
|
20
|
+
/** World-space hit point, when the backend provides one (else null). */
|
|
21
|
+
readonly point: THREE.Vector3 | null;
|
|
22
|
+
/** Show the hover highlight (`true`) — selection is via {@link toggleSelection}. */
|
|
23
|
+
highlight(asHover: boolean): void;
|
|
24
|
+
/** Remove the hover highlight; `keepSelected` preserves the selected state. */
|
|
25
|
+
unhighlight(keepSelected: boolean): void;
|
|
26
|
+
/** Toggle the persistent selected highlight. */
|
|
27
|
+
toggleSelection(): void;
|
|
28
|
+
/** Clear all highlight (hover + selected) for this component. */
|
|
29
|
+
clearHighlights(): void;
|
|
30
|
+
/** Identity equality (same component / same solid), for hover + isNewObject dedup. */
|
|
31
|
+
equals(other: PickedComponent | null): boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* `PickedComponent` over a GPU id-pick result. Drives the shader
|
|
35
|
+
* `HighlightController` by `componentId` (faces of a solid via `*Solid`), with no
|
|
36
|
+
* per-component `ObjectGroup` and no exploded graph.
|
|
37
|
+
*/
|
|
38
|
+
export declare class IdPicked implements PickedComponent {
|
|
39
|
+
readonly info: ComponentInfo;
|
|
40
|
+
readonly fromSolid: boolean;
|
|
41
|
+
readonly point: THREE.Vector3 | null;
|
|
42
|
+
private readonly highlightCtl;
|
|
43
|
+
constructor(info: ComponentInfo, fromSolid: boolean, point: THREE.Vector3 | null, highlightCtl: HighlightController);
|
|
44
|
+
/** Whether to act on the whole solid (faces) rather than the single component. */
|
|
45
|
+
private get asSolid();
|
|
46
|
+
get backendId(): string;
|
|
47
|
+
get name(): string;
|
|
48
|
+
get topo(): TopoType;
|
|
49
|
+
highlight(asHover: boolean): void;
|
|
50
|
+
unhighlight(keepSelected: boolean): void;
|
|
51
|
+
toggleSelection(): void;
|
|
52
|
+
clearHighlights(): void;
|
|
53
|
+
private _setSelected;
|
|
54
|
+
equals(other: PickedComponent | null): boolean;
|
|
55
|
+
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Wraps the pmndrs EffectComposer to provide:
|
|
5
5
|
* - Scene rendering (RenderPass)
|
|
6
6
|
* - Screen-space ambient occlusion (N8AOPostPass)
|
|
7
|
-
* - Screen-space shadow mask (
|
|
7
|
+
* - Screen-space shadow mask (PCFShadowMap + KawaseBlurPass)
|
|
8
8
|
* - Tone mapping + sRGB output + antialiasing (ToneMappingEffect + SMAAEffect)
|
|
9
9
|
*
|
|
10
10
|
* Tone mapping is handled by the postprocessing ToneMappingEffect, which uses
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* transparent, and the EffectPass alpha-blends its output onto a pre-cleared
|
|
19
19
|
* canvas that already has the correct background color.
|
|
20
20
|
*
|
|
21
|
-
* Shadow mask:
|
|
21
|
+
* Shadow mask: PCFShadowMap produces sharp shadow boundaries at 4096×4096.
|
|
22
22
|
* A half-resolution ShadowMaterial override pass captures the mask, which is
|
|
23
23
|
* then blurred via KawaseBlurPass and composited by ShadowMaskEffect before
|
|
24
24
|
* tone mapping. The floor keeps its own ShadowMaterial reading the shadow map
|
|
@@ -61,7 +61,7 @@ declare class StudioComposer {
|
|
|
61
61
|
* @param width - Canvas width in pixels
|
|
62
62
|
* @param height - Canvas height in pixels
|
|
63
63
|
*/
|
|
64
|
-
constructor(renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.Camera, width: number, height: number);
|
|
64
|
+
constructor(renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.Camera, width: number, height: number, onSmaaReady?: () => void);
|
|
65
65
|
/**
|
|
66
66
|
* Enable or disable solid-background protection.
|
|
67
67
|
*
|
|
@@ -7,7 +7,7 @@ declare const States: {
|
|
|
7
7
|
readonly mixed: 2;
|
|
8
8
|
readonly disabled: 3;
|
|
9
9
|
};
|
|
10
|
-
type StateValue = typeof States[keyof typeof States];
|
|
10
|
+
type StateValue = (typeof States)[keyof typeof States];
|
|
11
11
|
/** Icon index: 0 for shapes, 1 for edges */
|
|
12
12
|
type IconIndex = 0 | 1;
|
|
13
13
|
/**
|
package/dist/scene/clipping.d.ts
CHANGED
|
@@ -2,6 +2,18 @@ import * as THREE from "three";
|
|
|
2
2
|
import type { Vector3Tuple } from "three";
|
|
3
3
|
import { ObjectGroup } from "./nestedgroup.js";
|
|
4
4
|
import type { Theme, ClipIndex } from "../core/types";
|
|
5
|
+
/**
|
|
6
|
+
* Cap-culling thresholds (see {@link Clipping.cull}). The per-solid stencil + cap
|
|
7
|
+
* meshes are correct but O(N) in draw calls; on a large assembly (~1300 solids ×
|
|
8
|
+
* 3 planes × 3 meshes ≈ 12000 draws/frame) a zoomed-out clip+rotate overruns the
|
|
9
|
+
* GPU watchdog → context loss. Culling bounds the per-frame work:
|
|
10
|
+
* - `CAP_CULL_MIN_PX`: skip a solid's caps when its projected screen radius is
|
|
11
|
+
* below this (sub-pixel solids contribute nothing visible zoomed out).
|
|
12
|
+
* - `CAP_CULL_BUDGET`: hard cap on the number of capped solids (largest-first);
|
|
13
|
+
* the real crash guard for pathologically dense views. Tune on a real GPU.
|
|
14
|
+
*/
|
|
15
|
+
export declare const CAP_CULL_MIN_PX = 3;
|
|
16
|
+
export declare const CAP_CULL_BUDGET = 400;
|
|
5
17
|
/**
|
|
6
18
|
* A THREE.Plane that maintains a constant relative to a center point.
|
|
7
19
|
*/
|
|
@@ -103,6 +115,17 @@ declare class Clipping extends THREE.Group {
|
|
|
103
115
|
objectColorCaps: boolean;
|
|
104
116
|
planeHelpers: PlaneMeshGroup | null;
|
|
105
117
|
private _planeMeshGroup;
|
|
118
|
+
/** Per-solid stencil/cap units, the unit of screen-size culling. */
|
|
119
|
+
private _capUnits;
|
|
120
|
+
/**
|
|
121
|
+
* Whether {@link cull} last ran with clipping active. Lets the inactive path
|
|
122
|
+
* gate stencils/caps off exactly once, then early-return on later still frames.
|
|
123
|
+
* Starts `true` so the first inactive call performs the initial gate-off (the
|
|
124
|
+
* meshes default to `visible:true`).
|
|
125
|
+
*/
|
|
126
|
+
private _cullActive;
|
|
127
|
+
/** Reused buffer for the budget threshold sort (no per-frame alloc). */
|
|
128
|
+
private _radiiScratch;
|
|
106
129
|
/**
|
|
107
130
|
* Create a Clipping instance.
|
|
108
131
|
* @param center - The center point [x, y, z].
|
|
@@ -168,6 +191,36 @@ declare class Clipping extends THREE.Group {
|
|
|
168
191
|
* @param flag - True to show, false to hide.
|
|
169
192
|
*/
|
|
170
193
|
setVisible: (flag: boolean) => void;
|
|
194
|
+
/**
|
|
195
|
+
* Bound the per-frame stencil/cap draw work to keep large assemblies from
|
|
196
|
+
* overrunning the GPU watchdog on clip+rotate (see {@link CAP_CULL_MIN_PX}).
|
|
197
|
+
*
|
|
198
|
+
* Toggles each unit's `Object3D.visible` (NOT material.visible), which composes
|
|
199
|
+
* by AND with the existing material-level toggles — `setShapeVisible` (per-solid
|
|
200
|
+
* hide) and `setVisible` (clip-tab on/off) — so a unit renders only when it is
|
|
201
|
+
* un-culled AND its solid is shown AND the clip tab is active. Render order and
|
|
202
|
+
* the per-solid `clearStencil` isolation are untouched (removing a whole solid's
|
|
203
|
+
* units never affects the remaining solids' cap correctness).
|
|
204
|
+
*
|
|
205
|
+
* @param camera - The active camera (ortho or perspective).
|
|
206
|
+
* @param width - Canvas width in CSS px.
|
|
207
|
+
* @param height - Canvas height in CSS px.
|
|
208
|
+
* @param clipActive - `renderer.localClippingEnabled` (clip tab selected).
|
|
209
|
+
*/
|
|
210
|
+
cull(camera: THREE.Camera, width: number, height: number, clipActive: boolean): void;
|
|
211
|
+
/**
|
|
212
|
+
* World-space AABB of a solid (local bounding box transformed by the front
|
|
213
|
+
* mesh's world matrix, which folds in GDS z-scale). Returns a shared scratch
|
|
214
|
+
* Box3 (valid only until the next call) or `null` when geometry is missing.
|
|
215
|
+
*/
|
|
216
|
+
private _solidWorldBox;
|
|
217
|
+
/**
|
|
218
|
+
* Projected screen radius (px) of a solid's bounding sphere. Projects the world
|
|
219
|
+
* sphere center and a point one world-radius along the camera-right axis, and
|
|
220
|
+
* measures their screen-space separation — correct for both ortho and
|
|
221
|
+
* perspective. Returns `Infinity` (never cull) when geometry is missing.
|
|
222
|
+
*/
|
|
223
|
+
private _solidScreenRadius;
|
|
171
224
|
/**
|
|
172
225
|
* Save the current clipping state for later restoration.
|
|
173
226
|
* Captures plane positions, helper visibility, and stencil plane visibility.
|
|
@@ -2,6 +2,9 @@ import * as THREE from "three";
|
|
|
2
2
|
import { BoundingBox } from "./bbox.js";
|
|
3
3
|
import { ObjectGroup, isObjectGroup } from "./objectgroup.js";
|
|
4
4
|
import { MaterialFactory } from "../rendering/material-factory.js";
|
|
5
|
+
import { ComponentRegistry } from "../rendering/id-picking.js";
|
|
6
|
+
import { HighlightController } from "../rendering/highlight.js";
|
|
7
|
+
import { MeshGeometrySource } from "../tools/cad_tools/mesh-measure.js";
|
|
5
8
|
import type { ZebraColorScheme, ZebraMappingMode, StudioTextureMapping, Shapes, ColorValue, MaterialAppearance, MaterialXMaterial } from "../core/types";
|
|
6
9
|
interface ShapeData {
|
|
7
10
|
vertices: Float32Array | number[][];
|
|
@@ -9,9 +12,16 @@ interface ShapeData {
|
|
|
9
12
|
triangles: Uint32Array | number[][];
|
|
10
13
|
edges?: Float32Array | number[][];
|
|
11
14
|
uvs?: Float32Array | number[];
|
|
15
|
+
triangles_per_face?: number[] | Uint32Array;
|
|
16
|
+
segments_per_edge?: number[] | Uint32Array;
|
|
17
|
+
obj_vertices?: Float32Array | number[];
|
|
18
|
+
face_types?: number[] | Uint32Array;
|
|
19
|
+
edge_types?: number[] | Uint8Array | Uint32Array;
|
|
12
20
|
}
|
|
13
21
|
interface EdgeData {
|
|
14
22
|
edges: Float32Array | number[][];
|
|
23
|
+
segments_per_edge?: number[] | Uint32Array;
|
|
24
|
+
obj_vertices?: Float32Array | number[];
|
|
15
25
|
}
|
|
16
26
|
interface VertexData {
|
|
17
27
|
obj_vertices: Float32Array | number[];
|
|
@@ -37,7 +47,6 @@ interface ShapeEntry {
|
|
|
37
47
|
state: number[];
|
|
38
48
|
loc?: [[number, number, number], [number, number, number, number]];
|
|
39
49
|
renderback?: boolean;
|
|
40
|
-
exploded?: boolean;
|
|
41
50
|
geomtype?: number | null;
|
|
42
51
|
subtype?: string | null;
|
|
43
52
|
texture?: {
|
|
@@ -77,6 +86,24 @@ declare class NestedGroup {
|
|
|
77
86
|
bbox: BoundingBox | null;
|
|
78
87
|
bsphere: THREE.Sphere | null;
|
|
79
88
|
groups: GroupsMap;
|
|
89
|
+
/**
|
|
90
|
+
* id-based-picking component registry: maps each per-vertex `componentId` to its
|
|
91
|
+
* `ComponentInfo` for the GPU picker (populated when `assignIds === true`).
|
|
92
|
+
*/
|
|
93
|
+
registry: ComponentRegistry;
|
|
94
|
+
/** Whether to assign component ids while rendering. */
|
|
95
|
+
assignIds: boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Component-level shader highlight: patches visual materials to tint/widen by
|
|
98
|
+
* `componentId` (created when `assignIds`).
|
|
99
|
+
*/
|
|
100
|
+
highlight: HighlightController | null;
|
|
101
|
+
/**
|
|
102
|
+
* Per-node mesh geometry for the internal (TypeScript) measurement backend.
|
|
103
|
+
* Populated for the compact group only (`assignIds`), keyed by node path like the
|
|
104
|
+
* {@link registry}; lets measurements be computed without the Python backend.
|
|
105
|
+
*/
|
|
106
|
+
meshGeometry: MeshGeometrySource;
|
|
80
107
|
clipPlanes: THREE.Plane[] | null;
|
|
81
108
|
materialFactory: MaterialFactory;
|
|
82
109
|
materialsTable: Record<string, string | MaterialXMaterial | MaterialAppearance> | null;
|
|
@@ -159,10 +186,25 @@ declare class NestedGroup {
|
|
|
159
186
|
/**
|
|
160
187
|
* Render a tessellated 3D shape with front/back faces and optional edges.
|
|
161
188
|
*/
|
|
162
|
-
renderShape(shape: ShapeData, color: ColorValue, alpha: number | null, renderback: boolean,
|
|
189
|
+
renderShape(shape: ShapeData, color: ColorValue, alpha: number | null, renderback: boolean, path: string, name: string, states: number[], geomtype?: {
|
|
163
190
|
topo: string;
|
|
164
191
|
geomtype: number | string | null;
|
|
165
192
|
} | null, subtype?: string | null, texture_data?: TextureData | null, texture_width?: number | null, texture_height?: number | null): ObjectGroup;
|
|
193
|
+
/**
|
|
194
|
+
* Build the pick-only B-rep-corner cloud (+ a selection-marker highlight Points) for a
|
|
195
|
+
* node carrying `obj_vertices` — a solid, a standalone face, or a standalone edge — so
|
|
196
|
+
* its corners are selectable via id-picking.
|
|
197
|
+
*
|
|
198
|
+
* The pick cloud lives on the VERTEX pick layer ONLY (NOT visual layer 0), so the visual
|
|
199
|
+
* camera never draws it; its material stays `visible:true` because three drops
|
|
200
|
+
* `material.visible===false` objects before `overrideMaterial` applies. Its pick-buffer
|
|
201
|
+
* visibility is kept in sync with the owning group (`setPickVertices`) so a hidden shape
|
|
202
|
+
* stops contributing corner ids.
|
|
203
|
+
*
|
|
204
|
+
* `subtype` is "solid" for a solid (→ the corner ids carry the owning `solidPath`, so the
|
|
205
|
+
* pick gates on faces||edges) and null for standalone faces/edges (→ own-node corners).
|
|
206
|
+
*/
|
|
207
|
+
private _addPickVertices;
|
|
166
208
|
/**
|
|
167
209
|
* Create edge geometry from extruded polygons.
|
|
168
210
|
*/
|
|
@@ -170,14 +212,14 @@ declare class NestedGroup {
|
|
|
170
212
|
/**
|
|
171
213
|
* Render extruded 2D polygons (GDS format) as 3D geometry.
|
|
172
214
|
*/
|
|
173
|
-
renderPolygons(shape: PolygonShape, minZ: number, color: ColorValue, alpha: number, renderback: boolean,
|
|
215
|
+
renderPolygons(shape: PolygonShape, minZ: number, color: ColorValue, alpha: number, renderback: boolean, path: string, name: string, states: number[], geomtype?: {
|
|
174
216
|
topo: string;
|
|
175
217
|
geomtype: number | string | null;
|
|
176
218
|
} | null, subtype?: string | null): ObjectGroup;
|
|
177
219
|
/**
|
|
178
220
|
* Recursively render all shapes in the shape tree.
|
|
179
221
|
* Note: The shapes parameter uses the public Shapes type but internally
|
|
180
|
-
* contains ShapeEntry/ShapeTree data
|
|
222
|
+
* contains ShapeEntry/ShapeTree data.
|
|
181
223
|
*/
|
|
182
224
|
renderLoop(shapes: Shapes): THREE.Group;
|
|
183
225
|
/**
|
|
@@ -61,6 +61,13 @@ declare class ObjectGroup extends THREE.Group {
|
|
|
61
61
|
edges: Edges | null;
|
|
62
62
|
edgeMaterial: EdgeMaterial | null;
|
|
63
63
|
vertices: VertexPoints | null;
|
|
64
|
+
/**
|
|
65
|
+
* Pick-only `obj_vertices` cloud for a solid's B-rep corners (vertex pick layer,
|
|
66
|
+
* off the visual layer). Has its own always-visible material, so it is NOT covered by
|
|
67
|
+
* {@link setShapeVisible}/{@link setEdgesVisible} — its pick-buffer visibility is kept
|
|
68
|
+
* in sync explicitly so a hidden solid's corners don't keep stealing hover picks.
|
|
69
|
+
*/
|
|
70
|
+
pickVertices: VertexPoints | null;
|
|
64
71
|
clipping: Map<number, THREE.Group>;
|
|
65
72
|
isSelected: boolean;
|
|
66
73
|
originalColor: THREE.Color | null;
|
|
@@ -120,6 +127,16 @@ declare class ObjectGroup extends THREE.Group {
|
|
|
120
127
|
* Set the vertices points.
|
|
121
128
|
*/
|
|
122
129
|
setVertices(points: VertexPoints): void;
|
|
130
|
+
/**
|
|
131
|
+
* Register the pick-only B-rep-corner cloud (vertex pick layer). Its pick-buffer
|
|
132
|
+
* visibility is then kept in sync with the solid's overall visibility so a hidden
|
|
133
|
+
* solid stops contributing vertex ids to the pick buffer (otherwise its corners win
|
|
134
|
+
* the vertex>face priority over a visible face behind them → hover flicker).
|
|
135
|
+
*/
|
|
136
|
+
setPickVertices(points: VertexPoints): void;
|
|
137
|
+
/** Sync the pick-only vertex cloud's visibility with the group's (pickable iff the
|
|
138
|
+
* front faces or edges are visible — matches the picker's hidden-component gate). */
|
|
139
|
+
private _syncPickVertices;
|
|
123
140
|
/**
|
|
124
141
|
* Add a clipping group for a plane index.
|
|
125
142
|
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Shape tessellation
|
|
2
|
+
* Shape tessellation for rendering CAD objects.
|
|
3
3
|
*/
|
|
4
4
|
import { NestedGroup } from "./nestedgroup.js";
|
|
5
5
|
import { BoundingBox } from "./bbox.js";
|
|
@@ -32,7 +32,7 @@ interface ShapeRenderConfig {
|
|
|
32
32
|
normalLen: number;
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
|
-
* Handles tessellation
|
|
35
|
+
* Handles tessellation of CAD shapes for rendering.
|
|
36
36
|
*/
|
|
37
37
|
declare class ShapeRenderer {
|
|
38
38
|
private config;
|
|
@@ -58,28 +58,12 @@ declare class ShapeRenderer {
|
|
|
58
58
|
* @returns The navigation tree object.
|
|
59
59
|
*/
|
|
60
60
|
private _getTree;
|
|
61
|
-
/**
|
|
62
|
-
* Decompose a CAD object into faces, edges and vertices.
|
|
63
|
-
* @param part - The part to decompose.
|
|
64
|
-
* @returns A decomposed part object.
|
|
65
|
-
*/
|
|
66
|
-
private _decompose;
|
|
67
|
-
/**
|
|
68
|
-
* Convert Shape arrays to TypedArrays for efficient rendering.
|
|
69
|
-
* Note: This mutates the shape in place.
|
|
70
|
-
*/
|
|
71
|
-
private _convertArrays;
|
|
72
|
-
/**
|
|
73
|
-
* Recursively process shapes, converting arrays and decomposing parts.
|
|
74
|
-
*/
|
|
75
|
-
private _processShapes;
|
|
76
61
|
/**
|
|
77
62
|
* Render the shapes of the CAD object.
|
|
78
|
-
* @param exploded - Whether to render the compact or exploded version
|
|
79
63
|
* @param shapes - The Shapes object.
|
|
80
64
|
* @returns A nested THREE.Group object and navigation tree.
|
|
81
65
|
*/
|
|
82
|
-
render(
|
|
66
|
+
render(shapes: Shapes): RenderResult;
|
|
83
67
|
}
|
|
84
68
|
export { ShapeRenderer };
|
|
85
69
|
export type { ShapeTreeData, RenderResult, ShapeRenderConfig };
|
|
@@ -258,7 +258,6 @@ input[type="radio"] {
|
|
|
258
258
|
background-image: var(--tcv-icon-nav_closed);
|
|
259
259
|
} */
|
|
260
260
|
|
|
261
|
-
|
|
262
261
|
.tcv_cad_viewer {
|
|
263
262
|
--tcv-ui-row-gap: 8px;
|
|
264
263
|
margin: 0;
|
|
@@ -288,6 +287,30 @@ input[type="radio"] {
|
|
|
288
287
|
margin: 2px;
|
|
289
288
|
}
|
|
290
289
|
|
|
290
|
+
/* Hover preselection readout: a rounded overlay badge in a FIXED row directly
|
|
291
|
+
below the grid-size badge (.tcv_tick_size at bottom:22px), so the grid badge
|
|
292
|
+
never moves when this appears/vanishes. Left:84px clears the 80px orientation
|
|
293
|
+
marker — keep in sync with OrientationMarker(80,80) in viewer.ts. JS hides it
|
|
294
|
+
(display:none) when empty. Pure overlay — never intercepts pointer events. */
|
|
295
|
+
.tcv_status_line {
|
|
296
|
+
position: absolute;
|
|
297
|
+
bottom: 4px;
|
|
298
|
+
left: 84px;
|
|
299
|
+
max-width: calc(100% - 88px);
|
|
300
|
+
font-size: 12px;
|
|
301
|
+
line-height: 14px;
|
|
302
|
+
font-family: sans-serif;
|
|
303
|
+
color: var(--tcv-font-color);
|
|
304
|
+
background-color: var(--tcv-bg-overlay-rest-color);
|
|
305
|
+
border-radius: 4px;
|
|
306
|
+
padding: 1px 4px;
|
|
307
|
+
white-space: nowrap;
|
|
308
|
+
overflow: hidden;
|
|
309
|
+
text-overflow: ellipsis;
|
|
310
|
+
pointer-events: none;
|
|
311
|
+
z-index: 100;
|
|
312
|
+
}
|
|
313
|
+
|
|
291
314
|
.tcv_cad_view_glass {
|
|
292
315
|
position: absolute !important;
|
|
293
316
|
left: 4px;
|
|
@@ -326,7 +349,7 @@ input[type="radio"] {
|
|
|
326
349
|
font-family: sans-serif;
|
|
327
350
|
font-size: 12px;
|
|
328
351
|
overflow: hidden;
|
|
329
|
-
user-select:text;
|
|
352
|
+
user-select: text;
|
|
330
353
|
}
|
|
331
354
|
|
|
332
355
|
.tcv_cad_info_wrapper {
|
|
@@ -418,7 +441,7 @@ input[type="radio"] {
|
|
|
418
441
|
line-height: 14px;
|
|
419
442
|
}
|
|
420
443
|
|
|
421
|
-
.tcv_small_table_row>td,
|
|
444
|
+
.tcv_small_table_row > td,
|
|
422
445
|
th {
|
|
423
446
|
padding-left: 6px;
|
|
424
447
|
}
|
|
@@ -856,7 +879,6 @@ input[type="button"] {
|
|
|
856
879
|
margin-right: 0;
|
|
857
880
|
}
|
|
858
881
|
|
|
859
|
-
|
|
860
882
|
.tcv_zebra_radio {
|
|
861
883
|
margin-bottom: var(--tcv-ui-row-gap);
|
|
862
884
|
margin-left: -3px;
|
|
@@ -1107,7 +1129,7 @@ input[type="button"] {
|
|
|
1107
1129
|
max-width: 80%;
|
|
1108
1130
|
text-align: center;
|
|
1109
1131
|
pointer-events: auto;
|
|
1110
|
-
box-shadow: 0 1px 4px rgba(0,0,0,0.3);
|
|
1132
|
+
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
|
|
1111
1133
|
}
|
|
1112
1134
|
|
|
1113
1135
|
.tcv_studio_spinner {
|
|
@@ -1124,7 +1146,9 @@ input[type="button"] {
|
|
|
1124
1146
|
}
|
|
1125
1147
|
|
|
1126
1148
|
@keyframes tcv_spin {
|
|
1127
|
-
to {
|
|
1149
|
+
to {
|
|
1150
|
+
transform: rotate(360deg);
|
|
1151
|
+
}
|
|
1128
1152
|
}
|
|
1129
1153
|
|
|
1130
1154
|
.tcv_filter_menu {
|
|
@@ -1144,10 +1168,13 @@ input[type="button"] {
|
|
|
1144
1168
|
color: var(--tcv-font-color);
|
|
1145
1169
|
font-size: 13px;
|
|
1146
1170
|
border: none;
|
|
1147
|
-
float: right;
|
|
1148
1171
|
position: absolute;
|
|
1149
|
-
right:
|
|
1150
|
-
|
|
1172
|
+
right: -4px;
|
|
1173
|
+
top: -3px;
|
|
1174
|
+
/* Fixed width so the trigger pill and the option list share one right-anchored
|
|
1175
|
+
box — their right borders coincide (and line up with the panel edge). Wide
|
|
1176
|
+
enough for the longest option ("Vertex"). */
|
|
1177
|
+
width: 5em;
|
|
1151
1178
|
}
|
|
1152
1179
|
|
|
1153
1180
|
.tcv_shape_filter:hover {
|
|
@@ -1161,9 +1188,9 @@ input[type="button"] {
|
|
|
1161
1188
|
}
|
|
1162
1189
|
|
|
1163
1190
|
.tcv_filter_value {
|
|
1164
|
-
|
|
1191
|
+
flex: 1;
|
|
1192
|
+
text-align: left;
|
|
1165
1193
|
padding-left: 3px;
|
|
1166
|
-
display: inline-block;
|
|
1167
1194
|
}
|
|
1168
1195
|
|
|
1169
1196
|
.tcv_filter_dropdown_active {
|
|
@@ -1180,22 +1207,29 @@ input[type="button"] {
|
|
|
1180
1207
|
}
|
|
1181
1208
|
|
|
1182
1209
|
.tcv_filter_content {
|
|
1210
|
+
display: flex;
|
|
1211
|
+
align-items: center;
|
|
1212
|
+
justify-content: space-between;
|
|
1183
1213
|
background-color: var(--tcv-bg-overlay-color);
|
|
1184
1214
|
}
|
|
1185
1215
|
|
|
1186
|
-
.
|
|
1187
|
-
|
|
1216
|
+
/* Grid-size badge: FIXED bottom-left row, just above the status readout. Stays
|
|
1217
|
+
put whether or not the status line is shown (no jumping). */
|
|
1218
|
+
.tcv_tick_size {
|
|
1219
|
+
position: absolute;
|
|
1220
|
+
bottom: 22px;
|
|
1221
|
+
left: 84px;
|
|
1222
|
+
background-color: var(--tcv-bg-overlay-rest-color);
|
|
1188
1223
|
border-radius: 4px;
|
|
1189
|
-
padding:
|
|
1190
|
-
width:fit-content;
|
|
1224
|
+
padding: 1px 4px;
|
|
1225
|
+
width: fit-content;
|
|
1191
1226
|
font-size: 12px;
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
z-index: 1000;
|
|
1227
|
+
line-height: 14px;
|
|
1228
|
+
z-index: 100;
|
|
1195
1229
|
}
|
|
1196
1230
|
|
|
1197
|
-
.tcv_tick_size_value{
|
|
1198
|
-
padding:3px;
|
|
1231
|
+
.tcv_tick_size_value {
|
|
1232
|
+
padding: 3px;
|
|
1199
1233
|
}
|
|
1200
1234
|
|
|
1201
1235
|
|