vim-web 0.3.42-dev.6 → 0.3.42-dev.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.
Files changed (23) hide show
  1. package/dist/types/core-viewers/webgl/loader/materials/ghostMaterial.d.ts +16 -0
  2. package/dist/types/core-viewers/webgl/loader/materials/simpleMaterial.d.ts +10 -5
  3. package/dist/types/core-viewers/webgl/loader/materials/viewerMaterials.d.ts +9 -8
  4. package/dist/types/core-viewers/webgl/loader/mesh.d.ts +2 -1
  5. package/dist/types/core-viewers/webgl/loader/progressive/insertableMesh.d.ts +2 -1
  6. package/dist/types/core-viewers/webgl/loader/progressive/instancedMesh.d.ts +3 -1
  7. package/dist/types/core-viewers/webgl/loader/scene.d.ts +3 -2
  8. package/dist/types/core-viewers/webgl/viewer/environment/environment.d.ts +0 -6
  9. package/dist/types/core-viewers/webgl/viewer/rendering/renderScene.d.ts +7 -4
  10. package/dist/types/core-viewers/webgl/viewer/rendering/renderer.d.ts +3 -9
  11. package/dist/types/core-viewers/webgl/viewer/selection.d.ts +1 -0
  12. package/dist/types/core-viewers/webgl/viewer/settings/viewerSettings.d.ts +4 -39
  13. package/dist/types/react-viewers/helpers/inputs.d.ts +1 -2
  14. package/dist/types/react-viewers/helpers/isolation.d.ts +91 -50
  15. package/dist/types/react-viewers/settings/settings.d.ts +2 -2
  16. package/dist/vim-web.iife.js +291 -503
  17. package/dist/vim-web.iife.js.map +1 -1
  18. package/dist/vim-web.js +291 -503
  19. package/dist/vim-web.js.map +1 -1
  20. package/package.json +1 -1
  21. package/dist/types/core-viewers/webgl/images.d.ts +0 -4
  22. package/dist/types/core-viewers/webgl/loader/materials/isolationMaterial.d.ts +0 -12
  23. package/dist/types/core-viewers/webgl/viewer/environment/groundPlane.d.ts +0 -25
@@ -45349,6 +45349,7 @@ void main() {
45349
45349
  return this._value;
45350
45350
  }
45351
45351
  apply(value) {
45352
+ value ?? this.defaultValue;
45352
45353
  if (this._value === value) return false;
45353
45354
  this._value = value;
45354
45355
  if (!this._meshes) return false;
@@ -47662,7 +47663,6 @@ void main() {
47662
47663
  vertexColors: true,
47663
47664
  flatShading: true,
47664
47665
  side: DoubleSide
47665
- //shininess: 20
47666
47666
  });
47667
47667
  }
47668
47668
  function createBasicTransparent() {
@@ -47928,107 +47928,69 @@ void main() {
47928
47928
  `
47929
47929
  });
47930
47930
  }
47931
- function createIsolationMaterial() {
47931
+ function createGhostMaterial() {
47932
47932
  return new ShaderMaterial({
47933
+ userData: {
47934
+ isGhost: true
47935
+ },
47933
47936
  uniforms: {
47934
- opacity: { value: 0.1 },
47937
+ // Uniform controlling the overall transparency of the non-visible objects.
47938
+ opacity: { value: 1e-3 },
47939
+ // Uniform specifying the fill color for non-visible objects.
47935
47940
  fillColor: { value: new Vector3$1(0, 0, 0) }
47936
47941
  },
47942
+ // Render only the front side of faces to prevent drawing internal geometry.
47943
+ side: FrontSide,
47944
+ // Enable support for vertex colors.
47937
47945
  vertexColors: true,
47946
+ // Enable transparency for the material.
47938
47947
  transparent: true,
47948
+ // Enable clipping planes for geometry slicing.
47939
47949
  clipping: true,
47950
+ // Prevent writing to the depth buffer for proper blending of transparent objects.
47951
+ depthWrite: false,
47952
+ // Perform depth testing to ensure correct rendering order.
47953
+ depthTest: true,
47940
47954
  vertexShader: (
47941
47955
  /* glsl */
47942
47956
  `
47943
-
47944
- #include <common>
47945
- #include <logdepthbuf_pars_vertex>
47946
47957
  #include <clipping_planes_pars_vertex>
47947
-
47948
- // VISIBILITY
47949
- // Instance or vertex attribute to hide objects
47950
- // Used as instance attribute for instanced mesh and as vertex attribute for merged meshes.
47951
- attribute float ignore;
47952
-
47953
- // Passed to fragment to discard them
47954
- varying float vIgnore;
47955
- varying vec3 vPosition;
47956
-
47957
-
47958
- // COLORING
47959
- varying vec3 vColor;
47960
47958
 
47961
- // attribute for color override
47962
- // merged meshes use it as vertex attribute
47963
- // instanced meshes use it as an instance attribute
47964
- attribute float colored;
47965
-
47966
- // There seems to be an issue where setting mehs.instanceColor
47967
- // doesn't properly set USE_INSTANCING_COLOR
47968
- // so we always use it as a fix
47969
- #ifndef USE_INSTANCING_COLOR
47970
- attribute vec3 instanceColor;
47971
- #endif
47959
+ // Attribute to determine if an object or vertex should be visible.
47960
+ // Used as an instance attribute for instanced meshes or a vertex attribute for merged meshes.
47961
+ attribute float ignore;
47972
47962
 
47973
47963
  void main() {
47964
+ // Standard transformations to calculate vertex position.
47974
47965
  #include <begin_vertex>
47975
47966
  #include <project_vertex>
47976
47967
  #include <clipping_planes_vertex>
47977
- #include <logdepthbuf_vertex>
47978
-
47979
- // VISIBILITY
47980
- // Set frag ignore from instance or vertex attribute
47981
- vIgnore = ignore;
47982
-
47983
- // COLORING
47984
- vColor = color.xyz;
47985
-
47986
- // colored == 1 -> instance color
47987
- // colored == 0 -> vertex color
47988
- #ifdef USE_INSTANCING
47989
- vColor.xyz = colored * instanceColor.xyz + (1.0f - colored) * color.xyz;
47990
- #endif
47991
47968
 
47992
-
47993
- // ORDERING
47994
- if(vIgnore > 0.0f){
47995
- gl_Position.z = 1.0f;
47996
- }else{
47997
- gl_Position.z = -1.0f;
47969
+ // Hide objects or vertices where the 'ignore' attribute is set to 0.
47970
+ if (ignore == 0.0) {
47971
+ // Push the vertex far out of view, effectively hiding it.
47972
+ gl_Position = vec4(1e20, 1e20, 1e20, 1.0);
47998
47973
  }
47999
-
48000
- // LIGHTING
48001
- vPosition = vec3(mvPosition ) / mvPosition .w;
48002
47974
  }
48003
- `
47975
+ `
48004
47976
  ),
48005
47977
  fragmentShader: (
48006
47978
  /* glsl */
48007
47979
  `
48008
47980
  #include <clipping_planes_pars_fragment>
48009
- varying float vIgnore;
47981
+
47982
+ // Uniform controlling the transparency level of the material.
48010
47983
  uniform float opacity;
47984
+ // Uniform specifying the fill color for non-visible objects.
48011
47985
  uniform vec3 fillColor;
48012
- varying vec3 vPosition;
48013
- varying vec3 vColor;
48014
47986
 
48015
47987
  void main() {
47988
+ // Handle clipping planes to discard fragments outside the defined planes.
48016
47989
  #include <clipping_planes_fragment>
48017
-
48018
- if (vIgnore > 0.0f){
48019
- gl_FragColor = vec4(fillColor, opacity);
48020
- }
48021
- else{
48022
- gl_FragColor = vec4(vColor.x, vColor.y, vColor.z, 1.0f);
48023
-
48024
- // LIGHTING
48025
- vec3 normal = normalize( cross(dFdx(vPosition), dFdy(vPosition)) );
48026
- float light = dot(normal, normalize(vec3(1.4142f, 1.732f, 2.2360f)));
48027
- light = 0.5 + (light *0.5);
48028
- gl_FragColor.xyz *= light;
48029
- }
47990
+ // Set the fragment color to the specified fill color and opacity.
47991
+ gl_FragColor = vec4(fillColor, opacity);
48030
47992
  }
48031
- `
47993
+ `
48032
47994
  )
48033
47995
  });
48034
47996
  }
@@ -48316,42 +48278,40 @@ void main() {
48316
48278
  }
48317
48279
  function createSimpleMaterial() {
48318
48280
  return new ShaderMaterial({
48319
- uniforms: {
48320
- opacity: { value: 0.1 },
48321
- fillColor: { value: new Vector3$1(0, 0, 0) }
48322
- },
48281
+ side: DoubleSide,
48282
+ // No uniforms are needed for this shader.
48283
+ uniforms: {},
48284
+ // Enable vertex colors for both instanced and merged meshes.
48323
48285
  vertexColors: true,
48324
- // transparent: true,
48286
+ // Enable support for clipping planes.
48325
48287
  clipping: true,
48326
48288
  vertexShader: (
48327
48289
  /* glsl */
48328
48290
  `
48329
-
48330
48291
  #include <common>
48331
48292
  #include <logdepthbuf_pars_vertex>
48332
48293
  #include <clipping_planes_pars_vertex>
48333
-
48294
+
48334
48295
  // VISIBILITY
48335
- // Instance or vertex attribute to hide objects
48336
- // Used as instance attribute for instanced mesh and as vertex attribute for merged meshes.
48296
+ // Determines if an object or vertex should be visible.
48297
+ // Used as an instance attribute for instanced meshes or as a vertex attribute for merged meshes.
48337
48298
  attribute float ignore;
48338
48299
 
48339
- // Passed to fragment to discard them
48340
- varying float vIgnore;
48300
+ // LIGHTING
48301
+ // Passes the vertex position to the fragment shader for lighting calculations.
48341
48302
  varying vec3 vPosition;
48342
48303
 
48343
-
48344
48304
  // COLORING
48305
+ // Passes the color of the vertex or instance to the fragment shader.
48345
48306
  varying vec3 vColor;
48346
48307
 
48347
- // attribute for color override
48348
- // merged meshes use it as vertex attribute
48349
- // instanced meshes use it as an instance attribute
48308
+ // Determines whether to use instance color (1.0) or vertex color (0.0).
48309
+ // For merged meshes, this is used as a vertex attribute.
48310
+ // For instanced meshes, this is used as an instance attribute.
48350
48311
  attribute float colored;
48351
48312
 
48352
- // There seems to be an issue where setting mehs.instanceColor
48353
- // doesn't properly set USE_INSTANCING_COLOR
48354
- // so we always use it as a fix
48313
+ // Fix for a known issue where setting mesh.instanceColor does not properly enable USE_INSTANCING_COLOR.
48314
+ // This ensures that instance colors are always used when required.
48355
48315
  #ifndef USE_INSTANCING_COLOR
48356
48316
  attribute vec3 instanceColor;
48357
48317
  #endif
@@ -48362,49 +48322,59 @@ void main() {
48362
48322
  #include <clipping_planes_vertex>
48363
48323
  #include <logdepthbuf_vertex>
48364
48324
 
48365
- // VISIBILITY
48366
- // Set frag ignore from instance or vertex attribute
48367
- vIgnore = ignore;
48325
+ // If ignore is greater than 0, hide the object by moving it far out of view.
48326
+ if (ignore > 0.0) {
48327
+ gl_Position = vec4(1e20, 1e20, 1e20, 1.0);
48328
+ return;
48329
+ }
48368
48330
 
48369
48331
  // COLORING
48332
+ // Default to the vertex color.
48370
48333
  vColor = color.xyz;
48371
48334
 
48372
- // colored == 1 -> instance color
48373
- // colored == 0 -> vertex color
48335
+ // Blend instance and vertex colors based on the colored attribute.
48336
+ // colored == 1.0 -> use instance color.
48337
+ // colored == 0.0 -> use vertex color.
48374
48338
  #ifdef USE_INSTANCING
48375
- vColor.xyz = colored * instanceColor.xyz + (1.0f - colored) * color.xyz;
48339
+ vColor.xyz = colored * instanceColor.xyz + (1.0 - colored) * color.xyz;
48376
48340
  #endif
48377
48341
 
48378
- gl_Position.z = -10.0f;
48379
-
48380
48342
  // LIGHTING
48381
- vPosition = vec3(mvPosition ) / mvPosition .w;
48343
+ // Pass the model-view position to the fragment shader for lighting calculations.
48344
+ vPosition = vec3(mvPosition) / mvPosition.w;
48382
48345
  }
48383
48346
  `
48384
48347
  ),
48385
48348
  fragmentShader: (
48386
48349
  /* glsl */
48387
48350
  `
48351
+ #include <common>
48352
+ #include <logdepthbuf_pars_fragment>
48388
48353
  #include <clipping_planes_pars_fragment>
48389
- varying float vIgnore;
48354
+
48355
+
48356
+ // Position and color data passed from the vertex shader.
48390
48357
  varying vec3 vPosition;
48391
48358
  varying vec3 vColor;
48392
48359
 
48393
48360
  void main() {
48394
48361
  #include <clipping_planes_fragment>
48362
+ #include <logdepthbuf_fragment>
48395
48363
 
48396
- if (vIgnore > 0.0f){
48397
- discard;
48398
- }
48399
- else{
48400
- gl_FragColor = vec4(vColor.x, vColor.y, vColor.z, 1.0f);
48364
+ // Set the fragment color to the interpolated vertex or instance color.
48365
+ gl_FragColor = vec4(vColor, 1.0);
48401
48366
 
48402
- // LIGHTING
48403
- vec3 normal = normalize( cross(dFdx(vPosition), dFdy(vPosition)) );
48404
- float light = dot(normal, normalize(vec3(1.4142f, 1.732f, 2.2360f)));
48405
- light = 0.5 + (light *0.5);
48406
- gl_FragColor.xyz *= light;
48407
- }
48367
+ // LIGHTING
48368
+ // Compute a pseudo-normal using screen-space derivatives of the vertex position.
48369
+ vec3 normal = normalize(cross(dFdx(vPosition), dFdy(vPosition)));
48370
+
48371
+ // Apply simple directional lighting.
48372
+ // Normalize the light direction for consistent shading.
48373
+ float light = dot(normal, normalize(vec3(1.4142, 1.732, 2.236)));
48374
+ light = 0.5 + (light * 0.5); // Adjust light intensity to range [0.5, 1.0].
48375
+
48376
+ // Modulate the fragment color by the lighting intensity.
48377
+ gl_FragColor.xyz *= light;
48408
48378
  }
48409
48379
  `
48410
48380
  )
@@ -48503,7 +48473,7 @@ void main() {
48503
48473
  }
48504
48474
  }
48505
48475
  const _ViewerMaterials = class _ViewerMaterials {
48506
- constructor(opaque, transparent, simple, wireframe, isolation, mask, outline, merge, skyBox) {
48476
+ constructor(opaque, transparent, simple, wireframe, ghost2, mask, outline, merge, skyBox) {
48507
48477
  /**
48508
48478
  * Material used for opaque model geometry.
48509
48479
  */
@@ -48523,7 +48493,7 @@ void main() {
48523
48493
  /**
48524
48494
  * Material used to show traces of hidden objects.
48525
48495
  */
48526
- __publicField(this, "isolation");
48496
+ __publicField(this, "ghost");
48527
48497
  /**
48528
48498
  * Material used to filter out what is not selected for selection outline effect.
48529
48499
  */
@@ -48551,7 +48521,7 @@ void main() {
48551
48521
  this.transparent = transparent ?? createTransparent();
48552
48522
  this.simple = simple ?? createSimpleMaterial();
48553
48523
  this.wireframe = wireframe ?? createWireframe();
48554
- this.isolation = isolation ?? createIsolationMaterial();
48524
+ this.ghost = ghost2 ?? createGhostMaterial();
48555
48525
  this.mask = mask ?? createMaskMaterial();
48556
48526
  this.outline = outline ?? new OutlineMaterial();
48557
48527
  this.merge = merge ?? new MergeMaterial();
@@ -48573,8 +48543,8 @@ void main() {
48573
48543
  applySettings(settings2) {
48574
48544
  this.opaque.color = settings2.materials.standard.color;
48575
48545
  this.transparent.color = settings2.materials.standard.color;
48576
- this.isolationOpacity = settings2.materials.isolation.opacity;
48577
- this.isolationColor = settings2.materials.isolation.color;
48546
+ this.ghostOpacity = settings2.materials.ghost.opacity;
48547
+ this.ghostColor = settings2.materials.ghost.color;
48578
48548
  this.wireframeColor = settings2.materials.highlight.color;
48579
48549
  this.wireframeOpacity = settings2.materials.highlight.opacity;
48580
48550
  this.sectionStrokeWitdh = settings2.materials.section.strokeWidth;
@@ -48603,26 +48573,26 @@ void main() {
48603
48573
  this._onUpdate.dispatch();
48604
48574
  }
48605
48575
  /**
48606
- * Determines the opacity of the isolation material.
48576
+ * Determines the opacity of the ghost material.
48607
48577
  */
48608
- get isolationOpacity() {
48609
- return this.isolation.opacity;
48578
+ get ghostOpacity() {
48579
+ return this.ghost.opacity;
48610
48580
  }
48611
- set isolationOpacity(opacity) {
48612
- const mat = this.isolation;
48581
+ set ghostOpacity(opacity) {
48582
+ const mat = this.ghost;
48613
48583
  mat.uniforms.opacity.value = opacity;
48614
48584
  mat.uniformsNeedUpdate = true;
48615
48585
  this._onUpdate.dispatch();
48616
48586
  }
48617
48587
  /**
48618
- * Determines the color of the isolation material.
48588
+ * Determines the color of the ghost material.
48619
48589
  */
48620
- get isolationColor() {
48621
- const mat = this.isolation;
48590
+ get ghostColor() {
48591
+ const mat = this.ghost;
48622
48592
  return mat.uniforms.fillColor.value;
48623
48593
  }
48624
- set isolationColor(color) {
48625
- const mat = this.isolation;
48594
+ set ghostColor(color) {
48595
+ const mat = this.ghost;
48626
48596
  mat.uniforms.fillColor.value = color;
48627
48597
  mat.uniformsNeedUpdate = true;
48628
48598
  this._onUpdate.dispatch();
@@ -48683,10 +48653,11 @@ void main() {
48683
48653
  }
48684
48654
  set clippingPlanes(value) {
48685
48655
  this._clippingPlanes = value;
48656
+ this.simple.clippingPlanes = value ?? null;
48686
48657
  this.opaque.clippingPlanes = value ?? null;
48687
48658
  this.transparent.clippingPlanes = value ?? null;
48688
48659
  this.wireframe.clippingPlanes = value ?? null;
48689
- this.isolation.clippingPlanes = value ?? null;
48660
+ this.ghost.clippingPlanes = value ?? null;
48690
48661
  this.mask.clippingPlanes = value ?? null;
48691
48662
  this._onUpdate.dispatch();
48692
48663
  }
@@ -48806,7 +48777,7 @@ void main() {
48806
48777
  this.opaque.dispose();
48807
48778
  this.transparent.dispose();
48808
48779
  this.wireframe.dispose();
48809
- this.isolation.dispose();
48780
+ this.ghost.dispose();
48810
48781
  this.mask.dispose();
48811
48782
  this.outline.dispose();
48812
48783
  }
@@ -48918,16 +48889,12 @@ void main() {
48918
48889
  setMaterial(value) {
48919
48890
  if (this._material === value) return;
48920
48891
  if (this.ignoreSceneMaterial) return;
48921
- if (value) {
48922
- if (!this._material) {
48923
- this._material = this.mesh.material;
48924
- }
48925
- this.mesh.material = value;
48926
- } else {
48927
- if (this._material) {
48928
- this.mesh.material = this._material;
48929
- this._material = void 0;
48930
- }
48892
+ this.mesh.material = value ?? this._material;
48893
+ this.mesh.geometry.clearGroups();
48894
+ if (value instanceof Array) {
48895
+ value.forEach((m, i2) => {
48896
+ this.mesh.geometry.addGroup(0, Infinity, i2);
48897
+ });
48931
48898
  }
48932
48899
  }
48933
48900
  }
@@ -48985,13 +48952,17 @@ void main() {
48985
48952
  // State
48986
48953
  __publicField(this, "ignoreSceneMaterial");
48987
48954
  __publicField(this, "_material");
48955
+ __publicField(this, "size", 0);
48956
+ var _a2;
48988
48957
  this.g3dMesh = g3d2;
48989
48958
  this.mesh = mesh;
48990
48959
  this.mesh.userData.vim = this;
48991
48960
  this.bimInstances = g3d2 instanceof distExports$2.G3dMesh ? instances.map((i2) => g3d2.scene.instanceNodes[i2]) : instances;
48992
48961
  this.meshInstances = instances;
48993
48962
  this.boxes = g3d2 instanceof distExports$2.G3dMesh ? this.importBoundingBoxes() : this.computeBoundingBoxes();
48963
+ this.size = ((_a2 = this.boxes[0]) == null ? void 0 : _a2.getSize(new Vector3$1()).length()) ?? 0;
48994
48964
  this.boundingBox = this.computeBoundingBox(this.boxes);
48965
+ this._material = this.mesh.material;
48995
48966
  }
48996
48967
  get merged() {
48997
48968
  return false;
@@ -49015,16 +48986,12 @@ void main() {
49015
48986
  setMaterial(value) {
49016
48987
  if (this._material === value) return;
49017
48988
  if (this.ignoreSceneMaterial) return;
49018
- if (value) {
49019
- if (!this._material) {
49020
- this._material = this.mesh.material;
49021
- }
49022
- this.mesh.material = value;
49023
- } else {
49024
- if (this._material) {
49025
- this.mesh.material = this._material;
49026
- this._material = void 0;
49027
- }
48989
+ this.mesh.material = value ?? this._material;
48990
+ this.mesh.geometry.clearGroups();
48991
+ if (value instanceof Array) {
48992
+ value.forEach((m, i2) => {
48993
+ this.mesh.geometry.addGroup(0, Infinity, i2);
48994
+ });
49028
48995
  }
49029
48996
  }
49030
48997
  computeBoundingBoxes() {
@@ -50096,9 +50063,6 @@ void main() {
50096
50063
  }
50097
50064
  return true;
50098
50065
  }
50099
- const floor$1 = `
50100
- data:image/png;base64,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
50101
- `;
50102
50066
  class AxesSettings {
50103
50067
  constructor(init) {
50104
50068
  __publicField(this, "size", 84);
@@ -50174,14 +50138,6 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
50174
50138
  // less white
50175
50139
  sharpness: 2
50176
50140
  },
50177
- groundPlane: {
50178
- visible: false,
50179
- encoding: "base64",
50180
- texture: floor$1,
50181
- opacity: 1,
50182
- color: new Color(16777215),
50183
- size: 5
50184
- },
50185
50141
  skylight: {
50186
50142
  skyColor: new Color(16777215),
50187
50143
  groundColor: new Color(16777215),
@@ -50209,9 +50165,9 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
50209
50165
  color: new Color(7000831),
50210
50166
  opacity: 0.5
50211
50167
  },
50212
- isolation: {
50168
+ ghost: {
50213
50169
  color: new Color(5132892),
50214
- opacity: 0.08
50170
+ opacity: 0.01
50215
50171
  },
50216
50172
  section: {
50217
50173
  strokeWidth: 0.01,
@@ -52399,6 +52355,9 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
52399
52355
  });
52400
52356
  this._onValueChanged.dispatch();
52401
52357
  }
52358
+ any() {
52359
+ return this._objects.size > 0;
52360
+ }
52402
52361
  /**
52403
52362
  * Returns true if the given object is currently selected.
52404
52363
  * @param {IObject} object The object to check for selection.
@@ -52508,92 +52467,6 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
52508
52467
  this._materials.focusIntensity = focus / 2;
52509
52468
  }
52510
52469
  }
52511
- class GroundPlane {
52512
- constructor(settings2) {
52513
- __publicField(this, "mesh");
52514
- __publicField(this, "_source");
52515
- __publicField(this, "_size", 1);
52516
- // disposable
52517
- __publicField(this, "_geometry");
52518
- __publicField(this, "_material");
52519
- __publicField(this, "_texture");
52520
- this._geometry = new PlaneGeometry();
52521
- this._material = new MeshBasicMaterial({
52522
- transparent: true,
52523
- depthTest: true,
52524
- depthWrite: false
52525
- });
52526
- this.mesh = new Mesh(this._geometry, this._material);
52527
- this.mesh.renderOrder = -1;
52528
- this._size = settings2.groundPlane.size;
52529
- this.mesh.visible = settings2.groundPlane.visible;
52530
- this.applyTexture(
52531
- settings2.groundPlane.encoding,
52532
- settings2.groundPlane.texture
52533
- );
52534
- this._material.color.copy(settings2.groundPlane.color);
52535
- this._material.opacity = settings2.groundPlane.opacity;
52536
- }
52537
- /**
52538
- * Whether the ground plane is visible or not.
52539
- */
52540
- get visible() {
52541
- return this.mesh.visible;
52542
- }
52543
- set visible(value) {
52544
- this.mesh.visible = value;
52545
- }
52546
- adaptToContent(box) {
52547
- const center = box.getCenter(new Vector3$1());
52548
- const position = new Vector3$1(
52549
- center.x,
52550
- box.min.y - Math.abs(box.min.y) * 0.01,
52551
- center.z
52552
- );
52553
- this.mesh.position.copy(position);
52554
- this.mesh.quaternion.copy(
52555
- new Quaternion().setFromEuler(new Euler(1.5 * Math.PI, 0, 0))
52556
- );
52557
- const sphere = box == null ? void 0 : box.getBoundingSphere(new Sphere());
52558
- const size = ((sphere == null ? void 0 : sphere.radius) ?? 1) * this._size;
52559
- const scale = new Vector3$1(1, 1, 1).multiplyScalar(size);
52560
- this.mesh.scale.copy(scale);
52561
- }
52562
- applyTexture(encoding, source) {
52563
- var _a2;
52564
- if (source === this._source) return;
52565
- this._source = source;
52566
- (_a2 = this._texture) == null ? void 0 : _a2.dispose();
52567
- this._texture = void 0;
52568
- if (!source || !encoding) return;
52569
- if (encoding === "url") {
52570
- const loader = new TextureLoader();
52571
- this._texture = loader.load(source);
52572
- }
52573
- if (encoding === "base64") {
52574
- const image = new Image();
52575
- image.src = source;
52576
- const txt = new Texture();
52577
- this._texture = txt;
52578
- this._texture.image = image;
52579
- image.onload = () => {
52580
- txt.needsUpdate = true;
52581
- };
52582
- }
52583
- if (!this._texture) {
52584
- console.error("Failed to load texture: " + source);
52585
- return;
52586
- }
52587
- this._material.map = this._texture;
52588
- }
52589
- dispose() {
52590
- var _a2, _b2, _c;
52591
- (_a2 = this._geometry) == null ? void 0 : _a2.dispose();
52592
- (_b2 = this._material) == null ? void 0 : _b2.dispose();
52593
- (_c = this._texture) == null ? void 0 : _c.dispose();
52594
- this._texture = void 0;
52595
- }
52596
- }
52597
52470
  class Skybox {
52598
52471
  constructor(camera2, renderer, materials, settings2) {
52599
52472
  __publicField(this, "mesh");
@@ -52738,28 +52611,22 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
52738
52611
  * The array of directional lights in the scene.
52739
52612
  */
52740
52613
  __publicField(this, "sunLights");
52741
- /**
52742
- * The ground plane under the model in the scene.
52743
- */
52744
- __publicField(this, "groundPlane");
52745
52614
  /*
52746
52615
  * The skybox in the scene.
52747
52616
  */
52748
52617
  __publicField(this, "skybox");
52749
52618
  this._camera = camera2;
52750
52619
  this._renderer = renderer;
52751
- this.groundPlane = new GroundPlane(settings2);
52752
52620
  this.skyLight = this.createSkyLight(settings2);
52753
52621
  this.skybox = new Skybox(camera2, renderer, viewerMaterials, settings2);
52754
52622
  this.sunLights = this.createSunLights(settings2);
52755
- this.setupRendererListeners();
52756
52623
  this.addObjectsToRenderer();
52757
52624
  }
52758
52625
  /**
52759
52626
  * Returns all three objects composing the environment
52760
52627
  */
52761
52628
  getObjects() {
52762
- return [this.groundPlane.mesh, this.skyLight, ...this.sunLights.map((l) => l.light), this.skybox.mesh];
52629
+ return [this.skyLight, ...this.sunLights.map((l) => l.light), this.skybox.mesh];
52763
52630
  }
52764
52631
  createSkyLight(settings2) {
52765
52632
  const { skyColor, groundColor, intensity } = settings2.skylight;
@@ -52773,12 +52640,6 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
52773
52640
  addObjectsToRenderer() {
52774
52641
  this.getObjects().forEach((o) => this._renderer.add(o));
52775
52642
  }
52776
- setupRendererListeners() {
52777
- this._renderer.onBoxUpdated.subscribe(() => {
52778
- const box = this._renderer.getBoundingBox();
52779
- this.groundPlane.adaptToContent(box);
52780
- });
52781
- }
52782
52643
  /**
52783
52644
  * Dispose of all resources.
52784
52645
  */
@@ -52786,7 +52647,6 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
52786
52647
  this.getObjects().forEach((o) => this._renderer.remove(o));
52787
52648
  this.sunLights.forEach((s) => s.dispose());
52788
52649
  this.skyLight.dispose();
52789
- this.groundPlane.dispose();
52790
52650
  this.skybox.dispose();
52791
52651
  }
52792
52652
  }
@@ -52923,10 +52783,10 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
52923
52783
  __publicField(this, "_boundingBox");
52924
52784
  __publicField(this, "_memory", 0);
52925
52785
  __publicField(this, "_2dCount", 0);
52926
- __publicField(this, "_material");
52786
+ __publicField(this, "_modelMaterial");
52927
52787
  this.scene = new Scene$1();
52928
52788
  }
52929
- get models() {
52789
+ get meshes() {
52930
52790
  return this._vimScenes.flatMap((s) => s.meshes);
52931
52791
  }
52932
52792
  get estimatedMemory() {
@@ -53022,16 +52882,27 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
53022
52882
  this._boundingBox = void 0;
53023
52883
  this._memory = 0;
53024
52884
  }
53025
- get material() {
53026
- return this._material;
52885
+ get modelMaterial() {
52886
+ return this._modelMaterial;
53027
52887
  }
53028
- set material(material) {
53029
- this._material = material;
52888
+ set modelMaterial(material) {
52889
+ this._modelMaterial = material;
53030
52890
  this._vimScenes.forEach((s) => {
53031
- s.meshes.forEach((m) => {
53032
- m.mesh.material = material;
53033
- });
52891
+ s.material = material;
53034
52892
  });
52893
+ this.updateInstanceMeshVisibility();
52894
+ }
52895
+ updateInstanceMeshVisibility() {
52896
+ var _a2, _b2;
52897
+ const hide = ((_b2 = (_a2 = this._modelMaterial) == null ? void 0 : _a2[1]) == null ? void 0 : _b2.userData.isGhost) === true;
52898
+ for (const mesh of this.meshes) {
52899
+ if (mesh instanceof InstancedMesh) {
52900
+ const visible2 = mesh.getSubmeshes().some(
52901
+ (m) => m.object.visible
52902
+ );
52903
+ mesh.mesh.visible = !(hide && !visible2 && mesh.size < 10);
52904
+ }
52905
+ }
53035
52906
  }
53036
52907
  addScene(scene) {
53037
52908
  this._vimScenes.push(scene);
@@ -55637,7 +55508,6 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
55637
55508
  this.minZ.constant = -box.min.z;
55638
55509
  this.box.copy(box);
55639
55510
  this._renderer.needsUpdate = true;
55640
- this._renderer.skipAntialias = true;
55641
55511
  }
55642
55512
  /**
55643
55513
  * Determines whether objecets outside the section box will be culled or not.
@@ -56596,7 +56466,6 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
56596
56466
  __publicField(this, "_composer");
56597
56467
  __publicField(this, "_materials");
56598
56468
  __publicField(this, "_renderText");
56599
- __publicField(this, "_skipAntialias");
56600
56469
  __publicField(this, "_needsUpdate");
56601
56470
  __publicField(this, "_onSceneUpdate", new distExports$1.SignalDispatcher());
56602
56471
  __publicField(this, "_onBoxUpdated", new distExports$1.SignalDispatcher());
@@ -56658,17 +56527,6 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
56658
56527
  set needsUpdate(value) {
56659
56528
  this._needsUpdate = this._needsUpdate || value;
56660
56529
  }
56661
- /**
56662
- * Indicates whether the next render should skip antialiasing.
56663
- * Useful for expensive operations such as the section box.
56664
- * Can only be set to true. Cleared on each render.
56665
- */
56666
- get skipAntialias() {
56667
- return this._skipAntialias;
56668
- }
56669
- set skipAntialias(value) {
56670
- this._skipAntialias = this._skipAntialias || value;
56671
- }
56672
56530
  /**
56673
56531
  * Removes all objects from rendering and disposes the WebGL context.
56674
56532
  */
@@ -56689,6 +56547,12 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
56689
56547
  this._scene.scene.background = color;
56690
56548
  this.needsUpdate = true;
56691
56549
  }
56550
+ get modelMaterial() {
56551
+ return this._scene.modelMaterial;
56552
+ }
56553
+ set modelMaterial(material) {
56554
+ this._scene.modelMaterial = material;
56555
+ }
56692
56556
  /**
56693
56557
  * Signal dispatched at the end of each frame if the scene was updated, such as visibility changes.
56694
56558
  */
@@ -56752,7 +56616,6 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
56752
56616
  this._composer.render();
56753
56617
  }
56754
56618
  this._needsUpdate = false;
56755
- this.skipAntialias = false;
56756
56619
  if (this.textEnabled && this._scene.has2dObjects()) {
56757
56620
  this.textRenderer.render(this._scene.scene, this._camera.three);
56758
56621
  }
@@ -57018,14 +56881,6 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
57018
56881
  groundColor: get2("skybox.groundColor", strToColor),
57019
56882
  sharpness: get2("skybox.sharpness", Number.parseFloat)
57020
56883
  },
57021
- groundPlane: {
57022
- visible: get2("groundPlane.visible", strToBool),
57023
- encoding: get2("groundPlane.encoding"),
57024
- texture: get2("groundPlane.texture"),
57025
- opacity: get2("groundPlane.opacity", Number.parseFloat),
57026
- color: get2("groundPlane.color", strToColor),
57027
- size: get2("groundPlane.size", Number.parseFloat)
57028
- },
57029
56884
  skylight: {
57030
56885
  skyColor: get2("skylight.skyColor", strToColor),
57031
56886
  groundColor: get2("skylight.groundColor", strToColor),
@@ -57053,9 +56908,9 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
57053
56908
  color: get2("materials.highlight.color", strToColor),
57054
56909
  opacity: get2("materials.highlight.opacity", Number.parseFloat)
57055
56910
  },
57056
- isolation: {
57057
- color: get2("materials.isolation.color", strToColor),
57058
- opacity: get2("materials.isolation.opacity", Number.parseFloat)
56911
+ ghost: {
56912
+ color: get2("materials.ghost.color", strToColor),
56913
+ opacity: get2("materials.ghost.opacity", Number.parseFloat)
57059
56914
  },
57060
56915
  section: {
57061
56916
  strokeWidth: get2("materials.section.strokeWidth", Number.parseFloat),
@@ -67008,12 +66863,12 @@ Averrage Date/Second ${avgDataRatePS} kb
67008
66863
  return isTrue(settings2.ui.projectInspector) || isTrue(settings2.ui.settings) || isTrue(settings2.ui.help) || isTrue(settings2.ui.maximise);
67009
66864
  }
67010
66865
  const defaultSettings = {
67011
- peformance: {
67012
- useFastMaterial: false
66866
+ materials: {
66867
+ useFastMaterial: false,
66868
+ useGhostMaterial: true
67013
66869
  },
67014
66870
  isolation: {
67015
- enable: true,
67016
- useIsolationMaterial: true
66871
+ enable: true
67017
66872
  },
67018
66873
  capacity: {
67019
66874
  canFollowUrl: true,
@@ -67093,7 +66948,7 @@ Averrage Date/Second ${avgDataRatePS} kb
67093
66948
  }, []);
67094
66949
  const onIsolationBtn = () => {
67095
66950
  props.settings.update(
67096
- (s) => s.isolation.useIsolationMaterial = !s.isolation.useIsolationMaterial
66951
+ (s) => s.materials.useGhostMaterial = !s.materials.useGhostMaterial
67097
66952
  );
67098
66953
  };
67099
66954
  const onHomeBtn = () => {
@@ -67103,11 +66958,11 @@ Averrage Date/Second ${avgDataRatePS} kb
67103
66958
  const btnIsolation = /* @__PURE__ */ jsxRuntimeExports.jsx(
67104
66959
  "button",
67105
66960
  {
67106
- "data-tip": props.settings.value.isolation.useIsolationMaterial ? "Disable Ghosting" : "Enable Ghosting",
66961
+ "data-tip": props.settings.value.materials.useGhostMaterial ? "Disable Ghosting" : "Enable Ghosting",
67107
66962
  onClick: onIsolationBtn,
67108
66963
  className: "vim-isolation-btn " + btnStyle2,
67109
66964
  type: "button",
67110
- children: props.settings.value.isolation.useIsolationMaterial ? /* @__PURE__ */ jsxRuntimeExports.jsx(ghost, { height: 20, width: 20, fill: "currentColor" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ghostDead, { height: 20, width: 20, fill: "currentColor" })
66965
+ children: props.settings.value.materials.useGhostMaterial ? /* @__PURE__ */ jsxRuntimeExports.jsx(ghost, { height: 20, width: 20, fill: "currentColor" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ghostDead, { height: 20, width: 20, fill: "currentColor" })
67111
66966
  }
67112
66967
  );
67113
66968
  const btnHome = /* @__PURE__ */ jsxRuntimeExports.jsxs(
@@ -67637,7 +67492,7 @@ Averrage Date/Second ${avgDataRatePS} kb
67637
67492
  id: elementIds.buttonToggleIsolation,
67638
67493
  enabled: () => isTrue(props.settings.ui.toggleIsolation),
67639
67494
  tip: "Toggle Isolation",
67640
- action: () => props.isolation.toggleIsolation("controlBar"),
67495
+ action: () => props.isolation.toggle("controlBar"),
67641
67496
  icon: toggleIsolation,
67642
67497
  style: buttonDefaultStyle
67643
67498
  }
@@ -71658,7 +71513,7 @@ Averrage Date/Second ${avgDataRatePS} kb
71658
71513
  };
71659
71514
  const [clipping, setClipping] = React2.useState(isClipping());
71660
71515
  const [, setVersion] = React2.useState(0);
71661
- const hidden2 = props.isolation.any();
71516
+ const hidden2 = props.isolation.isActive();
71662
71517
  React2.useEffect(() => {
71663
71518
  const subState = viewer.gizmos.section.onStateChanged.subscribe(() => {
71664
71519
  setSection({
@@ -74041,31 +73896,17 @@ Averrage Date/Second ${avgDataRatePS} kb
74041
73896
  ),
74042
73897
  settingsSubtitle("Materials"),
74043
73898
  settingsToggle(
74044
- "Use Isolation Material",
74045
- (settings2) => settings2.isolation.useIsolationMaterial,
73899
+ "Use Ghost Material",
73900
+ (settings2) => settings2.materials.useGhostMaterial,
74046
73901
  (settings2, value) => {
74047
- settings2.isolation.useIsolationMaterial = value;
74048
- if (settings2.peformance.useFastMaterial && value) {
74049
- settings2.peformance.useFastMaterial = false;
74050
- }
73902
+ settings2.materials.useGhostMaterial = value;
74051
73903
  }
74052
73904
  ),
74053
73905
  settingsToggle(
74054
73906
  "Use Performance Material",
74055
- (settings2) => settings2.peformance.useFastMaterial,
73907
+ (settings2) => settings2.materials.useFastMaterial,
74056
73908
  (settings2, value) => {
74057
- settings2.peformance.useFastMaterial = value;
74058
- if (settings2.isolation.useIsolationMaterial && value) {
74059
- settings2.isolation.useIsolationMaterial = false;
74060
- }
74061
- }
74062
- ),
74063
- settingsSubtitle("Scene"),
74064
- settingsToggle(
74065
- "Show Ground Plane",
74066
- (_) => props.viewer.environment.groundPlane.visible,
74067
- (_, value) => {
74068
- props.viewer.environment.groundPlane.visible = value;
73909
+ settings2.materials.useFastMaterial = value;
74069
73910
  }
74070
73911
  ),
74071
73912
  settingsSubtitle("Panels"),
@@ -74339,7 +74180,6 @@ Averrage Date/Second ${avgDataRatePS} kb
74339
74180
  __publicField(this, "_default");
74340
74181
  __publicField(this, "_isolation");
74341
74182
  __publicField(this, "_sideState");
74342
- __publicField(this, "_help");
74343
74183
  __publicField(this, "_getSelection", () => {
74344
74184
  return [...this._viewer.selection.objects].filter(
74345
74185
  (o) => o.type === "Object3D"
@@ -74369,7 +74209,7 @@ Averrage Date/Second ${avgDataRatePS} kb
74369
74209
  return true;
74370
74210
  }
74371
74211
  case KEYS.KEY_I: {
74372
- this._isolation.toggleIsolation("keyboard");
74212
+ this._isolation.toggle("keyboard");
74373
74213
  return true;
74374
74214
  }
74375
74215
  case KEYS.KEY_ESCAPE: {
@@ -74377,7 +74217,7 @@ Averrage Date/Second ${avgDataRatePS} kb
74377
74217
  this._viewer.selection.clear();
74378
74218
  return true;
74379
74219
  }
74380
- if (this._isolation.any()) {
74220
+ if (this._isolation.isActive()) {
74381
74221
  this._isolation.clear("keyboard");
74382
74222
  return true;
74383
74223
  }
@@ -74459,7 +74299,6 @@ Averrage Date/Second ${avgDataRatePS} kb
74459
74299
  var _a2;
74460
74300
  const next = { ...settings2 };
74461
74301
  updater(next);
74462
- validateSettings(next);
74463
74302
  saveSettingsToLocal(next);
74464
74303
  setSettings(next);
74465
74304
  (_a2 = onUpdate.current) == null ? void 0 : _a2.call(onUpdate, next);
@@ -74479,11 +74318,6 @@ Averrage Date/Second ${avgDataRatePS} kb
74479
74318
  [settings2]
74480
74319
  );
74481
74320
  }
74482
- function validateSettings(settings2) {
74483
- if (settings2.peformance.useFastMaterial && settings2.isolation.useIsolationMaterial) {
74484
- settings2.peformance.useFastMaterial = false;
74485
- }
74486
- }
74487
74321
  function applySettings(viewer, settings2) {
74488
74322
  const performance2 = document.getElementsByClassName("vim-performance-div")[0];
74489
74323
  if (performance2) {
@@ -74493,240 +74327,194 @@ Averrage Date/Second ${avgDataRatePS} kb
74493
74327
  performance2.classList.add("vc-hidden");
74494
74328
  }
74495
74329
  }
74496
- viewer.vims.forEach((v) => {
74497
- if (settings2.peformance.useFastMaterial && v.scene.material === void 0) {
74498
- v.scene.material = viewer.materials.simple;
74499
- }
74500
- if (!settings2.peformance.useFastMaterial && v.scene.material === viewer.materials.simple) {
74501
- v.scene.material = void 0;
74502
- }
74503
- });
74330
+ if (!settings2.isolation.enable) {
74331
+ viewer.renderer.modelMaterial = settings2.materials.useFastMaterial ? viewer.materials.simple : void 0;
74332
+ }
74504
74333
  }
74505
74334
  class Isolation {
74335
+ /**
74336
+ * Constructs an IsolationManager.
74337
+ *
74338
+ * @param viewer - The VIM Viewer responsible for managing the 3D scene and objects.
74339
+ * @param camera - A component that handles camera control and framing.
74340
+ * @param settings - The settings that control isolation and material usage.
74341
+ */
74506
74342
  constructor(viewer, camera2, settings2) {
74507
74343
  __publicField(this, "_viewer");
74508
74344
  __publicField(this, "_settings");
74509
- __publicField(this, "_isolation");
74510
- __publicField(this, "_lastIsolation");
74345
+ __publicField(this, "_isolation", []);
74511
74346
  __publicField(this, "_camera");
74512
- __publicField(this, "_references", /* @__PURE__ */ new Map());
74513
74347
  __publicField(this, "_onChanged", new distExports.SimpleEventDispatcher());
74514
74348
  this._viewer = viewer;
74515
74349
  this._camera = camera2;
74516
74350
  this.applySettings(settings2);
74517
74351
  }
74518
- /** Signal dispatched when the isolation set changes. */
74352
+ /**
74353
+ * An event that is dispatched whenever the isolation set changes.
74354
+ *
74355
+ * @remarks
74356
+ * This can be used by other parts of the application to react to isolation
74357
+ * updates (for example, updating UI or triggering additional viewport actions).
74358
+ *
74359
+ * @returns {ISimpleEvent<string>} Event interface for subscribing to isolation changes.
74360
+ */
74519
74361
  get onChanged() {
74520
74362
  return this._onChanged.asEvent();
74521
74363
  }
74522
74364
  /**
74523
- * Applies relevant settings to isolation.
74524
- * @param settings The settings to be applied to isolation.
74365
+ * Applies relevant settings to the isolation behavior.
74366
+ *
74367
+ * @param settings - The new settings to apply.
74368
+ *
74369
+ * @remarks
74370
+ * This updates the internal reference to settings and immediately sets
74371
+ * the material based on whether isolation is currently active.
74525
74372
  */
74526
74373
  applySettings(settings2) {
74527
- var _a2;
74528
74374
  this._settings = settings2;
74529
- if (!this._settings.isolation.enable) return;
74530
- const set2 = new Set((_a2 = this._isolation) == null ? void 0 : _a2.map((o) => o.vim));
74531
- this._viewer.vims.forEach((v) => {
74532
- v.scene.material = this.getMaterial(this._settings, set2.has(v));
74533
- });
74534
- }
74535
- /**
74536
- * Sets the reference objects for a given VIM.
74537
- * @param vim The VIM for which reference objects are being set.
74538
- * @param reference An array of reference objects or the string 'always' to indicate permanent reference.
74539
- */
74540
- setReference(vim, reference) {
74541
- const value = reference === "always" ? reference : new Set(reference);
74542
- this._references.set(vim, value);
74375
+ this._viewer.renderer.modelMaterial = this.getMaterial(this._settings, this.isActive());
74376
+ console.log("Isolation.applySettings", this._viewer.renderer.modelMaterial);
74543
74377
  }
74544
74378
  /**
74545
- * Retrieves the reference objects set for a given VIM.
74546
- * @param vim The VIM for which reference objects are being retrieved.
74547
- * @returns The reference objects set for the specified VIM.
74379
+ * Checks if isolation is currently active (i.e., any objects are isolated).
74380
+ *
74381
+ * @returns True if isolation is active; otherwise, false.
74548
74382
  */
74549
- getReference(vim) {
74550
- return this._references.get(vim);
74383
+ isActive() {
74384
+ return this._isolation.length > 0;
74551
74385
  }
74552
74386
  /**
74553
- * Clears all reference objects set for VIMs.
74554
- */
74555
- clearReferences() {
74556
- this._references.clear();
74557
- }
74558
- /**
74559
- * Returns true if there are currently objects isolated.
74560
- * @returns True if there are currently objects isolated; otherwise, false.
74561
- */
74562
- any() {
74563
- return this._isolation !== void 0;
74564
- }
74565
- /**
74566
- * Returns the current array of isolated objects.
74567
- * @returns The array of objects currently isolated, or undefined if no objects are isolated.
74387
+ * Retrieves the current array of isolated objects.
74388
+ *
74389
+ * @returns An array of isolated objects, or undefined if isolation is not active.
74568
74390
  */
74569
74391
  current() {
74570
74392
  return this._isolation;
74571
74393
  }
74572
74394
  /**
74573
- * Isolates the objects in the given array and shows the rest as ghost.
74574
- * @param objects An array of objects to isolate.
74575
- * @param source The source of isolation.
74576
- * @returns True if isolation occurs; otherwise, false.
74395
+ * Sets the specified objects as isolated, hiding or ghosting the rest.
74396
+ *
74397
+ * @param objects - The objects to isolate.
74398
+ * @param source - A label or identifier indicating the source of this action (e.g., "user").
74577
74399
  */
74578
74400
  isolate(objects, source) {
74579
74401
  if (!this._settings.isolation.enable) return;
74580
- if (this._isolation) {
74581
- this._lastIsolation = this._isolation;
74582
- }
74583
- const isolated = this._isolate(this._viewer, this._settings, objects);
74584
- this._isolation = isolated ? objects : void 0;
74402
+ this._isolation = objects ?? [];
74403
+ this._apply(source);
74585
74404
  this._camera.frameVisibleObjects();
74586
- this._onChanged.dispatch(source);
74587
- return isolated;
74588
74405
  }
74589
74406
  /**
74590
- * Toggles current isolation based on selection.
74591
- * @param source The source of isolation.
74407
+ * Toggles isolation by using the current selection.
74408
+ *
74409
+ * @param source - A label or identifier for the isolation action.
74410
+ *
74411
+ * @remarks
74412
+ * This method replaces the current isolation set with whatever objects are
74413
+ * currently selected. If selection is empty, it effectively clears isolation.
74592
74414
  */
74593
- toggleIsolation(source) {
74415
+ toggle(source) {
74594
74416
  if (!this._settings.isolation.enable) return;
74595
- const selection = [...this._viewer.selection.objects].filter((o) => o.type === "Object3D");
74596
- if (this._isolation) {
74597
- this._lastIsolation = this._isolation;
74598
- }
74599
- if (this._isolation) {
74600
- if (selection.length === 0 || ArrayEquals(this._isolation, selection)) {
74601
- this._showAll();
74602
- this._isolation = void 0;
74603
- } else {
74604
- const isolated = this._isolate(this._viewer, this._settings, selection);
74605
- this._isolation = isolated ? selection : void 0;
74606
- this._camera.frameVisibleObjects();
74607
- this._viewer.selection.clear();
74608
- }
74609
- } else {
74610
- if (selection.length > 0) {
74611
- const isolated = this._isolate(this._viewer, this._settings, selection);
74612
- this._isolation = isolated ? selection : void 0;
74613
- this._camera.frameVisibleObjects();
74614
- this._viewer.selection.clear();
74615
- } else if (this._lastIsolation) {
74616
- const isolated = this._isolate(
74617
- this._viewer,
74618
- this._settings,
74619
- this._lastIsolation
74620
- );
74621
- this._isolation = isolated ? [...this._lastIsolation] : void 0;
74622
- }
74623
- }
74624
- this._onChanged.dispatch(source);
74417
+ this._isolation = [...this._viewer.selection.objects].filter((o) => o.type === "Object3D");
74418
+ this._apply(source);
74419
+ this._camera.frameVisibleObjects();
74420
+ this._viewer.selection.clear();
74625
74421
  }
74626
74422
  /**
74627
- * Removes the given objects from the isolation set.
74628
- * @param objects An array of objects to be removed from isolation.
74629
- * @param source The source of the removal operation.
74423
+ * Hides the specified objects from the isolation set.
74424
+ *
74425
+ * @param objects - The objects to hide.
74426
+ * @param source - A label or identifier for the isolation action.
74427
+ *
74428
+ * @remarks
74429
+ * If there is no active isolation set (i.e., all objects are visible),
74430
+ * the method first treats all objects in the scene as isolated,
74431
+ * and then removes the specified objects. This ensures the specified
74432
+ * objects become hidden.
74630
74433
  */
74631
74434
  hide(objects, source) {
74632
74435
  if (!this._settings.isolation.enable) return;
74633
- const selection = new Set(objects);
74634
- const initial = this._isolation ?? this._viewer.vims[0].getObjects();
74635
- const result = [];
74636
- for (const obj of initial) {
74637
- if (!selection.has(obj)) result.push(obj);
74638
- }
74639
- const isolated = this._isolate(this._viewer, this._settings, result);
74640
- this._isolation = isolated ? result : void 0;
74641
- this._onChanged.dispatch(source);
74436
+ this._isolation = this._isolation.length === 0 ? this.getAllObjects() : this._isolation;
74437
+ this._isolation = this._isolation.filter((o) => !objects.includes(o));
74438
+ this._apply(source);
74642
74439
  objects.forEach((o) => this._viewer.selection.remove(o));
74643
74440
  }
74644
74441
  /**
74645
- * Adds the given objects to the isolation set.
74646
- * @param objects An array of objects to be added to isolation.
74647
- * @param source The source of the addition operation.
74442
+ * Adds the specified objects to the current isolation set (making them visible).
74443
+ *
74444
+ * @param objects - The objects to show.
74445
+ * @param source - A label or identifier for the isolation action.
74648
74446
  */
74649
74447
  show(objects, source) {
74650
74448
  if (!this._settings.isolation.enable) return;
74651
- const isolation = this._isolation ?? [];
74652
- objects.forEach((o) => isolation.push(o));
74653
- const result = [...new Set(isolation)];
74654
- const isolated = this._isolate(this._viewer, this._settings, result);
74655
- this._isolation = isolated ? result : void 0;
74656
- this._onChanged.dispatch(source);
74449
+ objects.forEach((o) => this._isolation.push(o));
74450
+ this._apply(source);
74657
74451
  }
74658
74452
  /**
74659
- * Clears the current isolation.
74660
- * @param source The source of the isolation clearing operation.
74453
+ * Clears the current isolation set, making all objects visible.
74454
+ *
74455
+ * @param source - A label or identifier for the isolation action.
74661
74456
  */
74662
74457
  clear(source) {
74663
74458
  if (!this._settings.isolation.enable) return;
74664
- this._showAll();
74665
- this._lastIsolation = this._isolation;
74666
- this._isolation = void 0;
74667
- this._onChanged.dispatch(source);
74459
+ this._isolation.length = 0;
74460
+ this._apply(source);
74668
74461
  }
74669
74462
  /**
74670
- * Show all objects and quit isolation mode.
74463
+ * Constructs the correct material (or array of materials) based on the given settings.
74464
+ *
74465
+ * @param settings - The current component settings, including isolation rules.
74466
+ * @param isolate - Whether or not isolation is active.
74467
+ * @returns The material(s) to assign to the renderer, or undefined if default materials should be used.
74468
+ *
74469
+ * @remarks
74470
+ * - If isolation is active and `useGhostMaterial` is true, an array containing
74471
+ * the simple and ghost materials is returned.
74472
+ * - If fast materials are enabled, the simple material is returned.
74473
+ * - Otherwise, defaults to undefined, allowing the system to pick a standard material.
74671
74474
  */
74672
- _showAll() {
74673
- this._viewer.vims.forEach((v) => {
74674
- for (const obj of v.getObjects()) {
74675
- obj.visible = true;
74676
- }
74677
- v.scene.material = this.getMaterial(this._settings, false);
74678
- });
74679
- }
74680
74475
  getMaterial(settings2, isolate) {
74681
- if (settings2.peformance.useFastMaterial) {
74682
- return this._viewer.materials.simple;
74476
+ if (isolate && settings2.materials.useGhostMaterial) {
74477
+ return [this._viewer.materials.simple, this._viewer.materials.ghost];
74683
74478
  }
74684
- if (!settings2.isolation.useIsolationMaterial) {
74685
- return void 0;
74686
- }
74687
- if (!isolate) {
74688
- return void 0;
74479
+ if (settings2.materials.useFastMaterial) {
74480
+ return this._viewer.materials.simple;
74689
74481
  }
74690
- return this._viewer.materials.isolation;
74482
+ return void 0;
74691
74483
  }
74692
- _isolate(viewer, settings2, objects) {
74693
- let useIsolation = false;
74694
- if (!objects) {
74695
- this._showAll();
74696
- } else {
74697
- const set2 = new Set(objects);
74698
- let all = true;
74699
- viewer.vims.forEach((vim) => {
74700
- for (const obj of vim.getObjects()) {
74701
- if (obj.hasMesh) {
74702
- obj.visible = set2.has(obj);
74703
- all = all && obj.visible;
74704
- }
74705
- }
74706
- const reference = this._references.get(vim);
74707
- if (reference === void 0) {
74708
- useIsolation = !all;
74709
- } else if (reference === "always") {
74710
- useIsolation = true;
74711
- } else {
74712
- useIsolation = !setsEqual(reference, set2);
74484
+ /**
74485
+ * Applies the current isolation state: sets visibility for objects, updates materials,
74486
+ * and dispatches the changed event.
74487
+ *
74488
+ * @param source - A label or identifier for the isolation action.
74489
+ */
74490
+ _apply(source) {
74491
+ let all = true;
74492
+ let any = false;
74493
+ const set2 = this._isolation.length > 0 ? new Set(this._isolation) : void 0;
74494
+ this._viewer.vims.forEach((vim) => {
74495
+ for (const obj of vim.getObjects()) {
74496
+ if (obj.hasMesh) {
74497
+ obj.visible = (set2 == null ? void 0 : set2.has(obj)) ?? true;
74498
+ all = all && obj.visible;
74499
+ any = any || obj.visible;
74713
74500
  }
74714
- vim.scene.material = this.getMaterial(this._settings, useIsolation);
74715
- });
74716
- }
74717
- return useIsolation;
74718
- }
74719
- }
74720
- function setsEqual(set1, set2) {
74721
- if (set1.size !== set2.size) {
74722
- return false;
74501
+ }
74502
+ });
74503
+ this._viewer.renderer.modelMaterial = this.getMaterial(this._settings, any && !all);
74504
+ this._onChanged.dispatch(source);
74723
74505
  }
74724
- for (const item of set1) {
74725
- if (!set2.has(item)) {
74726
- return false;
74727
- }
74506
+ /**
74507
+ * Gathers all objects from all loaded VIM instances.
74508
+ *
74509
+ * @returns An array of all objects within the loaded VIM scenes.
74510
+ */
74511
+ getAllObjects() {
74512
+ let objects = [];
74513
+ this._viewer.vims.forEach((vim) => {
74514
+ objects = objects.concat(vim.getObjects());
74515
+ });
74516
+ return objects;
74728
74517
  }
74729
- return true;
74730
74518
  }
74731
74519
  class ComponentCamera {
74732
74520
  constructor(viewer) {