three-cad-viewer 5.0.6 → 5.0.7
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.
|
@@ -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
|
/**
|
|
@@ -83999,7 +83999,10 @@ const BACKGROUND_ID = 0;
|
|
|
83999
83999
|
* `Uint32BufferAttribute` under this name; the pick pass reads it as an **integer**
|
|
84000
84000
|
* attribute (`gpuType = THREE.IntType`, GLSL3 `in uint`) so ids stay exact past
|
|
84001
84001
|
* 2^24. The geometry side must set `gpuType = THREE.IntType` on the attribute for
|
|
84002
|
-
* the pick shader to read it.
|
|
84002
|
+
* the pick shader to read it. Between the stages the id travels as two float
|
|
84003
|
+
* varyings (16-bit halves), deliberately NOT as a `flat uint` — see the note in
|
|
84004
|
+
* highlight.ts: a `flat` varying costs ~25x the scene's buffer bytes in graphics
|
|
84005
|
+
* memory under WebKit's ANGLE-on-Metal backend.
|
|
84003
84006
|
*/
|
|
84004
84007
|
const COMPONENT_ID_ATTRIBUTE = "componentId";
|
|
84005
84008
|
/**
|
|
@@ -84297,8 +84300,9 @@ const VERTEX_DEPTH_BIAS_FACTOR = 2e-4;
|
|
|
84297
84300
|
*/
|
|
84298
84301
|
const PICK_POINT_SIZE = 3;
|
|
84299
84302
|
/**
|
|
84300
|
-
* Shared GLSL3 MRT fragment shader for all pick materials (face/vertex/edge):
|
|
84301
|
-
* the
|
|
84303
|
+
* Shared GLSL3 MRT fragment shader for all pick materials (face/vertex/edge):
|
|
84304
|
+
* reassembles the id from its two interpolated halves and packs it into attachment 0
|
|
84305
|
+
* (byte order MUST match `packId()`: low byte in R)
|
|
84302
84306
|
* and writes the interpolated world position into attachment 1 (RGBA32F; `w=1` marks
|
|
84303
84307
|
* "has position"). The fragment clip chunk only `discard`s (non-ALPHA_TO_COVERAGE),
|
|
84304
84308
|
* so no `diffuseColor` symbol is required.
|
|
@@ -84306,13 +84310,15 @@ const PICK_POINT_SIZE = 3;
|
|
|
84306
84310
|
const PICK_FRAGMENT_SHADER = /* glsl */ `
|
|
84307
84311
|
#include <clipping_planes_pars_fragment>
|
|
84308
84312
|
|
|
84309
|
-
|
|
84313
|
+
in float vIdLo;
|
|
84314
|
+
in float vIdHi;
|
|
84310
84315
|
in vec3 vWorldPos;
|
|
84311
84316
|
layout(location = 0) out vec4 fragId;
|
|
84312
84317
|
layout(location = 1) out vec4 fragPos;
|
|
84313
84318
|
|
|
84314
84319
|
void main() {
|
|
84315
84320
|
#include <clipping_planes_fragment>
|
|
84321
|
+
uint vId = ( uint( vIdHi + 0.5 ) << 16 ) | uint( vIdLo + 0.5 );
|
|
84316
84322
|
fragId = vec4(
|
|
84317
84323
|
float( vId & 0xFFu ) / 255.0,
|
|
84318
84324
|
float( ( vId >> 8 ) & 0xFFu ) / 255.0,
|
|
@@ -84330,19 +84336,24 @@ const PICK_FRAGMENT_SHADER = /* glsl */ `
|
|
|
84330
84336
|
function createFacePickMaterial(options = {}) {
|
|
84331
84337
|
// GLSL3 (WebGL2). For a (non-Raw) ShaderMaterial three.js auto-injects
|
|
84332
84338
|
// `in vec3 position;`, `uniform mat4 modelMatrix/modelViewMatrix/projectionMatrix`,
|
|
84333
|
-
// so we declare ONLY the custom integer attribute +
|
|
84334
|
-
//
|
|
84339
|
+
// so we declare ONLY the custom integer attribute + the two id-half varyings
|
|
84340
|
+
// (float, interpolated — an integer varying would have to be `flat`, which is
|
|
84341
|
+
// the ANGLE-on-Metal memory trap described in highlight.ts; all vertices of a
|
|
84342
|
+
// primitive carry the same id, so interpolation + rounding is exact). Clip
|
|
84343
|
+
// chunks use legacy `varying`/`attribute` keywords
|
|
84335
84344
|
// which three remaps via `#define` under GLSL3; the vertex chunk reads a local
|
|
84336
84345
|
// `vec4 mvPosition`, which we compute before the include.
|
|
84337
84346
|
const vertexShader = /* glsl */ `
|
|
84338
84347
|
#include <clipping_planes_pars_vertex>
|
|
84339
84348
|
|
|
84340
84349
|
in uint componentId;
|
|
84341
|
-
|
|
84350
|
+
out float vIdLo;
|
|
84351
|
+
out float vIdHi;
|
|
84342
84352
|
out vec3 vWorldPos;
|
|
84343
84353
|
|
|
84344
84354
|
void main() {
|
|
84345
|
-
|
|
84355
|
+
vIdLo = float( componentId & 0xFFFFu );
|
|
84356
|
+
vIdHi = float( componentId >> 16 );
|
|
84346
84357
|
vec4 worldPos = modelMatrix * vec4( position, 1.0 );
|
|
84347
84358
|
vWorldPos = worldPos.xyz;
|
|
84348
84359
|
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
|
|
@@ -84381,13 +84392,15 @@ function createVertexPickMaterial(options = {}) {
|
|
|
84381
84392
|
#include <clipping_planes_pars_vertex>
|
|
84382
84393
|
|
|
84383
84394
|
in uint componentId;
|
|
84384
|
-
|
|
84395
|
+
out float vIdLo;
|
|
84396
|
+
out float vIdHi;
|
|
84385
84397
|
out vec3 vWorldPos;
|
|
84386
84398
|
uniform float uPickSize;
|
|
84387
84399
|
uniform float uDepthBias;
|
|
84388
84400
|
|
|
84389
84401
|
void main() {
|
|
84390
|
-
|
|
84402
|
+
vIdLo = float( componentId & 0xFFFFu );
|
|
84403
|
+
vIdHi = float( componentId >> 16 );
|
|
84391
84404
|
vec4 worldPos = modelMatrix * vec4( position, 1.0 );
|
|
84392
84405
|
vWorldPos = worldPos.xyz;
|
|
84393
84406
|
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
|
|
@@ -84447,7 +84460,8 @@ function createEdgePickMaterial(options = {}) {
|
|
|
84447
84460
|
in vec3 instanceEnd;
|
|
84448
84461
|
in uint componentId;
|
|
84449
84462
|
|
|
84450
|
-
|
|
84463
|
+
out float vIdLo;
|
|
84464
|
+
out float vIdHi;
|
|
84451
84465
|
out vec3 vWorldPos;
|
|
84452
84466
|
|
|
84453
84467
|
void trimSegment( const in vec4 start, inout vec4 end ) {
|
|
@@ -84459,7 +84473,8 @@ function createEdgePickMaterial(options = {}) {
|
|
|
84459
84473
|
}
|
|
84460
84474
|
|
|
84461
84475
|
void main() {
|
|
84462
|
-
|
|
84476
|
+
vIdLo = float( componentId & 0xFFFFu );
|
|
84477
|
+
vIdHi = float( componentId >> 16 );
|
|
84463
84478
|
|
|
84464
84479
|
// World-space segment endpoints → approximate hit point along the edge.
|
|
84465
84480
|
vWorldPos = ( position.y < 0.5 )
|
|
@@ -84997,20 +85012,41 @@ const U_HIGHLIGHT_HOVER_COLOR = "uHighlightHoverColor";
|
|
|
84997
85012
|
//
|
|
84998
85013
|
// three upgrades stock materials to GLSL ES 3.00 on WebGL2 via `#define attribute
|
|
84999
85014
|
// in` / `#define varying out|in` macros (WebGLProgram.js), so writing `attribute` /
|
|
85000
|
-
// `
|
|
85015
|
+
// `varying` here is converted automatically; `usampler2D` / `texelFetch` /
|
|
85001
85016
|
// integer attributes are then available.
|
|
85017
|
+
//
|
|
85018
|
+
// The component id crosses to the fragment stage as TWO ordinary (interpolated)
|
|
85019
|
+
// float varyings holding its 16-bit halves — NOT as a `flat uint`. A `flat`
|
|
85020
|
+
// varying is what an integer varying would require, and it is exactly what must
|
|
85021
|
+
// be avoided here: under WebKit's ANGLE-on-Metal backend, every draw whose
|
|
85022
|
+
// program has a `flat` varying makes ANGLE allocate a converted copy of the
|
|
85023
|
+
// draw's index data (>= 64 KB each, pooled, never returned to the GL on
|
|
85024
|
+
// deleteBuffer). With this varying on every visible material that was ~25x the
|
|
85025
|
+
// scene's vertex/index bytes in graphics memory (26 MB of buffers -> 812 MB;
|
|
85026
|
+
// 100 MB -> 2.3 GB) and it is charged to the page's WebContent process in the
|
|
85027
|
+
// system WebKit, which killed build123d Studio at 16 GB after a few large
|
|
85028
|
+
// shows. Without `flat` the same scene takes 63 MB / 160 MB. Measured 2026-09-17
|
|
85029
|
+
// (working-docs/leak-harness.html + probe2.html, Playwright WebKit and Safari).
|
|
85030
|
+
//
|
|
85031
|
+
// Interpolating floats is exact for the id's purpose: every vertex of a face,
|
|
85032
|
+
// every vertex of an instanced segment and a point carry the SAME id, so the
|
|
85033
|
+
// interpolated value equals it up to rounding, and `uint(x + 0.5)` recovers it.
|
|
85034
|
+
// Two 16-bit halves (both < 65536, exactly representable in float32) keep the
|
|
85035
|
+
// full 32-bit id range that `applyComponentIds` promises.
|
|
85002
85036
|
// ---------------------------------------------------------------------------
|
|
85003
85037
|
/**
|
|
85004
85038
|
* Shared state-fetch GLSL, injected into BOTH stages: the vertex stage needs it for
|
|
85005
85039
|
* widening / point size, the fragment for color. Declares the sampler + texWidth +
|
|
85006
|
-
* the
|
|
85007
|
-
* (0 for background / nothing).
|
|
85040
|
+
* the two id-half varyings and a helper returning the component's
|
|
85041
|
+
* {@link HighlightFlag} bits (0 for background / nothing).
|
|
85008
85042
|
*/
|
|
85009
85043
|
const HL_STATE_GLSL = `
|
|
85010
|
-
|
|
85044
|
+
varying float vHighlightIdLo;
|
|
85045
|
+
varying float vHighlightIdHi;
|
|
85011
85046
|
uniform highp usampler2D ${U_HIGHLIGHT_STATE};
|
|
85012
85047
|
uniform int ${U_HIGHLIGHT_TEX_WIDTH};
|
|
85013
85048
|
uint highlightState() {
|
|
85049
|
+
uint vHighlightId = (uint(vHighlightIdHi + 0.5) << 16) | uint(vHighlightIdLo + 0.5);
|
|
85014
85050
|
if (vHighlightId == 0u) return 0u;
|
|
85015
85051
|
ivec2 hlUv = ivec2(
|
|
85016
85052
|
int(vHighlightId) % ${U_HIGHLIGHT_TEX_WIDTH},
|
|
@@ -85025,8 +85061,8 @@ uint highlightState() {
|
|
|
85025
85061
|
const HL_VERTEX_HEADER = `
|
|
85026
85062
|
attribute uint ${COMPONENT_ID_ATTRIBUTE};
|
|
85027
85063
|
${HL_STATE_GLSL}`;
|
|
85028
|
-
/** Vertex main: forward the id. Injected right after `void main() {`. */
|
|
85029
|
-
const HL_VERTEX_ASSIGN = `
|
|
85064
|
+
/** Vertex main: forward the id as two 16-bit halves. Injected right after `void main() {`. */
|
|
85065
|
+
const HL_VERTEX_ASSIGN = `vHighlightIdLo = float(${COMPONENT_ID_ATTRIBUTE} & 0xFFFFu); vHighlightIdHi = float(${COMPONENT_ID_ATTRIBUTE} >> 16);`;
|
|
85030
85066
|
/** Fragment header: the shared state fetch + the two highlight colors. */
|
|
85031
85067
|
const HL_FRAGMENT_HEADER = `
|
|
85032
85068
|
${HL_STATE_GLSL}
|
|
@@ -85276,7 +85312,7 @@ class HighlightController {
|
|
|
85276
85312
|
this.uniforms.uHighlightSelectedColor;
|
|
85277
85313
|
shader.uniforms[U_HIGHLIGHT_HOVER_COLOR] =
|
|
85278
85314
|
this.uniforms.uHighlightHoverColor;
|
|
85279
|
-
// Common: forward the component id as
|
|
85315
|
+
// Common: forward the component id (as two interpolated float halves).
|
|
85280
85316
|
shader.vertexShader =
|
|
85281
85317
|
HL_VERTEX_HEADER +
|
|
85282
85318
|
"\n" +
|
|
@@ -88808,7 +88844,14 @@ class Grid extends Group {
|
|
|
88808
88844
|
group.name = `GridHelper-${i}`;
|
|
88809
88845
|
group.add(new GridHelper(this.size, 2 * this.ticks, this.colors[this.theme][i === 0 ? 1 : i === 1 ? 0 : 2], this.colors[this.theme][i === 0 ? 0 : i === 1 ? 2 : 1], this.theme == "dark" ? 0x7777777 : 0xbbbbbb));
|
|
88810
88846
|
let label;
|
|
88811
|
-
|
|
88847
|
+
// A grid of no size has no labels, and asking for them hangs the tab:
|
|
88848
|
+
// `niceBounds` answers [0, 0, 0] for a bounding box whose largest extent
|
|
88849
|
+
// is zero - which is what an empty model gives it - so `delta` is zero
|
|
88850
|
+
// and the loop below steps by zero, never advancing and never throwing.
|
|
88851
|
+
// Guarded here rather than in `niceBounds`, whose answer is right: there
|
|
88852
|
+
// is nothing to place ticks on.
|
|
88853
|
+
const step = this.delta / 2;
|
|
88854
|
+
for (let x = -this.size / 2; step > 0 && x <= this.size / 2; x += step) {
|
|
88812
88855
|
if (Math.abs(x) < 1e-6) {
|
|
88813
88856
|
continue;
|
|
88814
88857
|
} // skip center label
|
|
@@ -97350,7 +97393,7 @@ class Tools {
|
|
|
97350
97393
|
}
|
|
97351
97394
|
}
|
|
97352
97395
|
|
|
97353
|
-
const version = "5.0.
|
|
97396
|
+
const version = "5.0.7";
|
|
97354
97397
|
|
|
97355
97398
|
/**
|
|
97356
97399
|
* `PickedComponent` over a GPU id-pick result. Drives the shader
|
|
@@ -110820,6 +110863,11 @@ class Viewer {
|
|
|
110820
110863
|
deepDispose(this._rendered.camera);
|
|
110821
110864
|
deepDispose(this._rendered.controls);
|
|
110822
110865
|
deepDispose(this._rendered.treeview);
|
|
110866
|
+
// The orientation marker owns its own THREE.Scene (cones, labels, sphere,
|
|
110867
|
+
// axes), not part of the main scene above, so it needs its own dispose —
|
|
110868
|
+
// without it every clear()/render() cycle left 8 geometries and 3 programs
|
|
110869
|
+
// behind on the GL (measured 2026-09-17, working-docs/leak-harness.html).
|
|
110870
|
+
this._rendered.orientationMarker.dispose();
|
|
110823
110871
|
// clear tree view
|
|
110824
110872
|
this.display.clearCadTree();
|
|
110825
110873
|
// clear info
|