vim-web 0.3.42-dev.6 → 0.3.42-dev.8

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 +290 -502
  17. package/dist/vim-web.iife.js.map +1 -1
  18. package/dist/vim-web.js +290 -502
  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
package/dist/vim-web.js CHANGED
@@ -45333,6 +45333,7 @@ class ObjectAttribute {
45333
45333
  return this._value;
45334
45334
  }
45335
45335
  apply(value) {
45336
+ value ?? this.defaultValue;
45336
45337
  if (this._value === value) return false;
45337
45338
  this._value = value;
45338
45339
  if (!this._meshes) return false;
@@ -47646,7 +47647,6 @@ function createBasicOpaque() {
47646
47647
  vertexColors: true,
47647
47648
  flatShading: true,
47648
47649
  side: DoubleSide
47649
- //shininess: 20
47650
47650
  });
47651
47651
  }
47652
47652
  function createBasicTransparent() {
@@ -47912,107 +47912,69 @@ function createMaskMaterial() {
47912
47912
  `
47913
47913
  });
47914
47914
  }
47915
- function createIsolationMaterial() {
47915
+ function createGhostMaterial() {
47916
47916
  return new ShaderMaterial({
47917
+ userData: {
47918
+ isGhost: true
47919
+ },
47917
47920
  uniforms: {
47918
- opacity: { value: 0.1 },
47921
+ // Uniform controlling the overall transparency of the non-visible objects.
47922
+ opacity: { value: 1e-3 },
47923
+ // Uniform specifying the fill color for non-visible objects.
47919
47924
  fillColor: { value: new Vector3$1(0, 0, 0) }
47920
47925
  },
47926
+ // Render only the front side of faces to prevent drawing internal geometry.
47927
+ side: FrontSide,
47928
+ // Enable support for vertex colors.
47921
47929
  vertexColors: true,
47930
+ // Enable transparency for the material.
47922
47931
  transparent: true,
47932
+ // Enable clipping planes for geometry slicing.
47923
47933
  clipping: true,
47934
+ // Prevent writing to the depth buffer for proper blending of transparent objects.
47935
+ depthWrite: false,
47936
+ // Perform depth testing to ensure correct rendering order.
47937
+ depthTest: true,
47924
47938
  vertexShader: (
47925
47939
  /* glsl */
47926
47940
  `
47927
-
47928
- #include <common>
47929
- #include <logdepthbuf_pars_vertex>
47930
47941
  #include <clipping_planes_pars_vertex>
47931
-
47932
- // VISIBILITY
47933
- // Instance or vertex attribute to hide objects
47934
- // Used as instance attribute for instanced mesh and as vertex attribute for merged meshes.
47935
- attribute float ignore;
47936
-
47937
- // Passed to fragment to discard them
47938
- varying float vIgnore;
47939
- varying vec3 vPosition;
47940
-
47941
-
47942
- // COLORING
47943
- varying vec3 vColor;
47944
47942
 
47945
- // attribute for color override
47946
- // merged meshes use it as vertex attribute
47947
- // instanced meshes use it as an instance attribute
47948
- attribute float colored;
47949
-
47950
- // There seems to be an issue where setting mehs.instanceColor
47951
- // doesn't properly set USE_INSTANCING_COLOR
47952
- // so we always use it as a fix
47953
- #ifndef USE_INSTANCING_COLOR
47954
- attribute vec3 instanceColor;
47955
- #endif
47943
+ // Attribute to determine if an object or vertex should be visible.
47944
+ // Used as an instance attribute for instanced meshes or a vertex attribute for merged meshes.
47945
+ attribute float ignore;
47956
47946
 
47957
47947
  void main() {
47948
+ // Standard transformations to calculate vertex position.
47958
47949
  #include <begin_vertex>
47959
47950
  #include <project_vertex>
47960
47951
  #include <clipping_planes_vertex>
47961
- #include <logdepthbuf_vertex>
47962
-
47963
- // VISIBILITY
47964
- // Set frag ignore from instance or vertex attribute
47965
- vIgnore = ignore;
47966
-
47967
- // COLORING
47968
- vColor = color.xyz;
47969
-
47970
- // colored == 1 -> instance color
47971
- // colored == 0 -> vertex color
47972
- #ifdef USE_INSTANCING
47973
- vColor.xyz = colored * instanceColor.xyz + (1.0f - colored) * color.xyz;
47974
- #endif
47975
47952
 
47976
-
47977
- // ORDERING
47978
- if(vIgnore > 0.0f){
47979
- gl_Position.z = 1.0f;
47980
- }else{
47981
- gl_Position.z = -1.0f;
47953
+ // Hide objects or vertices where the 'ignore' attribute is set to 0.
47954
+ if (ignore == 0.0) {
47955
+ // Push the vertex far out of view, effectively hiding it.
47956
+ gl_Position = vec4(1e20, 1e20, 1e20, 1.0);
47982
47957
  }
47983
-
47984
- // LIGHTING
47985
- vPosition = vec3(mvPosition ) / mvPosition .w;
47986
47958
  }
47987
- `
47959
+ `
47988
47960
  ),
47989
47961
  fragmentShader: (
47990
47962
  /* glsl */
47991
47963
  `
47992
47964
  #include <clipping_planes_pars_fragment>
47993
- varying float vIgnore;
47965
+
47966
+ // Uniform controlling the transparency level of the material.
47994
47967
  uniform float opacity;
47968
+ // Uniform specifying the fill color for non-visible objects.
47995
47969
  uniform vec3 fillColor;
47996
- varying vec3 vPosition;
47997
- varying vec3 vColor;
47998
47970
 
47999
47971
  void main() {
47972
+ // Handle clipping planes to discard fragments outside the defined planes.
48000
47973
  #include <clipping_planes_fragment>
48001
-
48002
- if (vIgnore > 0.0f){
48003
- gl_FragColor = vec4(fillColor, opacity);
48004
- }
48005
- else{
48006
- gl_FragColor = vec4(vColor.x, vColor.y, vColor.z, 1.0f);
48007
-
48008
- // LIGHTING
48009
- vec3 normal = normalize( cross(dFdx(vPosition), dFdy(vPosition)) );
48010
- float light = dot(normal, normalize(vec3(1.4142f, 1.732f, 2.2360f)));
48011
- light = 0.5 + (light *0.5);
48012
- gl_FragColor.xyz *= light;
48013
- }
47974
+ // Set the fragment color to the specified fill color and opacity.
47975
+ gl_FragColor = vec4(fillColor, opacity);
48014
47976
  }
48015
- `
47977
+ `
48016
47978
  )
48017
47979
  });
48018
47980
  }
@@ -48300,42 +48262,40 @@ function createMergeMaterial() {
48300
48262
  }
48301
48263
  function createSimpleMaterial() {
48302
48264
  return new ShaderMaterial({
48303
- uniforms: {
48304
- opacity: { value: 0.1 },
48305
- fillColor: { value: new Vector3$1(0, 0, 0) }
48306
- },
48265
+ side: DoubleSide,
48266
+ // No uniforms are needed for this shader.
48267
+ uniforms: {},
48268
+ // Enable vertex colors for both instanced and merged meshes.
48307
48269
  vertexColors: true,
48308
- // transparent: true,
48270
+ // Enable support for clipping planes.
48309
48271
  clipping: true,
48310
48272
  vertexShader: (
48311
48273
  /* glsl */
48312
48274
  `
48313
-
48314
48275
  #include <common>
48315
48276
  #include <logdepthbuf_pars_vertex>
48316
48277
  #include <clipping_planes_pars_vertex>
48317
-
48278
+
48318
48279
  // VISIBILITY
48319
- // Instance or vertex attribute to hide objects
48320
- // Used as instance attribute for instanced mesh and as vertex attribute for merged meshes.
48280
+ // Determines if an object or vertex should be visible.
48281
+ // Used as an instance attribute for instanced meshes or as a vertex attribute for merged meshes.
48321
48282
  attribute float ignore;
48322
48283
 
48323
- // Passed to fragment to discard them
48324
- varying float vIgnore;
48284
+ // LIGHTING
48285
+ // Passes the vertex position to the fragment shader for lighting calculations.
48325
48286
  varying vec3 vPosition;
48326
48287
 
48327
-
48328
48288
  // COLORING
48289
+ // Passes the color of the vertex or instance to the fragment shader.
48329
48290
  varying vec3 vColor;
48330
48291
 
48331
- // attribute for color override
48332
- // merged meshes use it as vertex attribute
48333
- // instanced meshes use it as an instance attribute
48292
+ // Determines whether to use instance color (1.0) or vertex color (0.0).
48293
+ // For merged meshes, this is used as a vertex attribute.
48294
+ // For instanced meshes, this is used as an instance attribute.
48334
48295
  attribute float colored;
48335
48296
 
48336
- // There seems to be an issue where setting mehs.instanceColor
48337
- // doesn't properly set USE_INSTANCING_COLOR
48338
- // so we always use it as a fix
48297
+ // Fix for a known issue where setting mesh.instanceColor does not properly enable USE_INSTANCING_COLOR.
48298
+ // This ensures that instance colors are always used when required.
48339
48299
  #ifndef USE_INSTANCING_COLOR
48340
48300
  attribute vec3 instanceColor;
48341
48301
  #endif
@@ -48346,49 +48306,59 @@ function createSimpleMaterial() {
48346
48306
  #include <clipping_planes_vertex>
48347
48307
  #include <logdepthbuf_vertex>
48348
48308
 
48349
- // VISIBILITY
48350
- // Set frag ignore from instance or vertex attribute
48351
- vIgnore = ignore;
48309
+ // If ignore is greater than 0, hide the object by moving it far out of view.
48310
+ if (ignore > 0.0) {
48311
+ gl_Position = vec4(1e20, 1e20, 1e20, 1.0);
48312
+ return;
48313
+ }
48352
48314
 
48353
48315
  // COLORING
48316
+ // Default to the vertex color.
48354
48317
  vColor = color.xyz;
48355
48318
 
48356
- // colored == 1 -> instance color
48357
- // colored == 0 -> vertex color
48319
+ // Blend instance and vertex colors based on the colored attribute.
48320
+ // colored == 1.0 -> use instance color.
48321
+ // colored == 0.0 -> use vertex color.
48358
48322
  #ifdef USE_INSTANCING
48359
- vColor.xyz = colored * instanceColor.xyz + (1.0f - colored) * color.xyz;
48323
+ vColor.xyz = colored * instanceColor.xyz + (1.0 - colored) * color.xyz;
48360
48324
  #endif
48361
48325
 
48362
- gl_Position.z = -10.0f;
48363
-
48364
48326
  // LIGHTING
48365
- vPosition = vec3(mvPosition ) / mvPosition .w;
48327
+ // Pass the model-view position to the fragment shader for lighting calculations.
48328
+ vPosition = vec3(mvPosition) / mvPosition.w;
48366
48329
  }
48367
48330
  `
48368
48331
  ),
48369
48332
  fragmentShader: (
48370
48333
  /* glsl */
48371
48334
  `
48335
+ #include <common>
48336
+ #include <logdepthbuf_pars_fragment>
48372
48337
  #include <clipping_planes_pars_fragment>
48373
- varying float vIgnore;
48338
+
48339
+
48340
+ // Position and color data passed from the vertex shader.
48374
48341
  varying vec3 vPosition;
48375
48342
  varying vec3 vColor;
48376
48343
 
48377
48344
  void main() {
48378
48345
  #include <clipping_planes_fragment>
48346
+ #include <logdepthbuf_fragment>
48379
48347
 
48380
- if (vIgnore > 0.0f){
48381
- discard;
48382
- }
48383
- else{
48384
- gl_FragColor = vec4(vColor.x, vColor.y, vColor.z, 1.0f);
48348
+ // Set the fragment color to the interpolated vertex or instance color.
48349
+ gl_FragColor = vec4(vColor, 1.0);
48385
48350
 
48386
- // LIGHTING
48387
- vec3 normal = normalize( cross(dFdx(vPosition), dFdy(vPosition)) );
48388
- float light = dot(normal, normalize(vec3(1.4142f, 1.732f, 2.2360f)));
48389
- light = 0.5 + (light *0.5);
48390
- gl_FragColor.xyz *= light;
48391
- }
48351
+ // LIGHTING
48352
+ // Compute a pseudo-normal using screen-space derivatives of the vertex position.
48353
+ vec3 normal = normalize(cross(dFdx(vPosition), dFdy(vPosition)));
48354
+
48355
+ // Apply simple directional lighting.
48356
+ // Normalize the light direction for consistent shading.
48357
+ float light = dot(normal, normalize(vec3(1.4142, 1.732, 2.236)));
48358
+ light = 0.5 + (light * 0.5); // Adjust light intensity to range [0.5, 1.0].
48359
+
48360
+ // Modulate the fragment color by the lighting intensity.
48361
+ gl_FragColor.xyz *= light;
48392
48362
  }
48393
48363
  `
48394
48364
  )
@@ -48487,7 +48457,7 @@ class SkyboxMaterial extends ShaderMaterial {
48487
48457
  }
48488
48458
  }
48489
48459
  const _ViewerMaterials = class _ViewerMaterials {
48490
- constructor(opaque, transparent, simple, wireframe, isolation, mask, outline, merge, skyBox) {
48460
+ constructor(opaque, transparent, simple, wireframe, ghost2, mask, outline, merge, skyBox) {
48491
48461
  /**
48492
48462
  * Material used for opaque model geometry.
48493
48463
  */
@@ -48507,7 +48477,7 @@ const _ViewerMaterials = class _ViewerMaterials {
48507
48477
  /**
48508
48478
  * Material used to show traces of hidden objects.
48509
48479
  */
48510
- __publicField(this, "isolation");
48480
+ __publicField(this, "ghost");
48511
48481
  /**
48512
48482
  * Material used to filter out what is not selected for selection outline effect.
48513
48483
  */
@@ -48535,7 +48505,7 @@ const _ViewerMaterials = class _ViewerMaterials {
48535
48505
  this.transparent = transparent ?? createTransparent();
48536
48506
  this.simple = simple ?? createSimpleMaterial();
48537
48507
  this.wireframe = wireframe ?? createWireframe();
48538
- this.isolation = isolation ?? createIsolationMaterial();
48508
+ this.ghost = ghost2 ?? createGhostMaterial();
48539
48509
  this.mask = mask ?? createMaskMaterial();
48540
48510
  this.outline = outline ?? new OutlineMaterial();
48541
48511
  this.merge = merge ?? new MergeMaterial();
@@ -48557,8 +48527,8 @@ const _ViewerMaterials = class _ViewerMaterials {
48557
48527
  applySettings(settings2) {
48558
48528
  this.opaque.color = settings2.materials.standard.color;
48559
48529
  this.transparent.color = settings2.materials.standard.color;
48560
- this.isolationOpacity = settings2.materials.isolation.opacity;
48561
- this.isolationColor = settings2.materials.isolation.color;
48530
+ this.ghostOpacity = settings2.materials.ghost.opacity;
48531
+ this.ghostColor = settings2.materials.ghost.color;
48562
48532
  this.wireframeColor = settings2.materials.highlight.color;
48563
48533
  this.wireframeOpacity = settings2.materials.highlight.opacity;
48564
48534
  this.sectionStrokeWitdh = settings2.materials.section.strokeWidth;
@@ -48587,26 +48557,26 @@ const _ViewerMaterials = class _ViewerMaterials {
48587
48557
  this._onUpdate.dispatch();
48588
48558
  }
48589
48559
  /**
48590
- * Determines the opacity of the isolation material.
48560
+ * Determines the opacity of the ghost material.
48591
48561
  */
48592
- get isolationOpacity() {
48593
- return this.isolation.opacity;
48562
+ get ghostOpacity() {
48563
+ return this.ghost.opacity;
48594
48564
  }
48595
- set isolationOpacity(opacity) {
48596
- const mat = this.isolation;
48565
+ set ghostOpacity(opacity) {
48566
+ const mat = this.ghost;
48597
48567
  mat.uniforms.opacity.value = opacity;
48598
48568
  mat.uniformsNeedUpdate = true;
48599
48569
  this._onUpdate.dispatch();
48600
48570
  }
48601
48571
  /**
48602
- * Determines the color of the isolation material.
48572
+ * Determines the color of the ghost material.
48603
48573
  */
48604
- get isolationColor() {
48605
- const mat = this.isolation;
48574
+ get ghostColor() {
48575
+ const mat = this.ghost;
48606
48576
  return mat.uniforms.fillColor.value;
48607
48577
  }
48608
- set isolationColor(color) {
48609
- const mat = this.isolation;
48578
+ set ghostColor(color) {
48579
+ const mat = this.ghost;
48610
48580
  mat.uniforms.fillColor.value = color;
48611
48581
  mat.uniformsNeedUpdate = true;
48612
48582
  this._onUpdate.dispatch();
@@ -48667,10 +48637,11 @@ const _ViewerMaterials = class _ViewerMaterials {
48667
48637
  }
48668
48638
  set clippingPlanes(value) {
48669
48639
  this._clippingPlanes = value;
48640
+ this.simple.clippingPlanes = value ?? null;
48670
48641
  this.opaque.clippingPlanes = value ?? null;
48671
48642
  this.transparent.clippingPlanes = value ?? null;
48672
48643
  this.wireframe.clippingPlanes = value ?? null;
48673
- this.isolation.clippingPlanes = value ?? null;
48644
+ this.ghost.clippingPlanes = value ?? null;
48674
48645
  this.mask.clippingPlanes = value ?? null;
48675
48646
  this._onUpdate.dispatch();
48676
48647
  }
@@ -48790,7 +48761,7 @@ const _ViewerMaterials = class _ViewerMaterials {
48790
48761
  this.opaque.dispose();
48791
48762
  this.transparent.dispose();
48792
48763
  this.wireframe.dispose();
48793
- this.isolation.dispose();
48764
+ this.ghost.dispose();
48794
48765
  this.mask.dispose();
48795
48766
  this.outline.dispose();
48796
48767
  }
@@ -48902,16 +48873,12 @@ class InsertableMesh {
48902
48873
  setMaterial(value) {
48903
48874
  if (this._material === value) return;
48904
48875
  if (this.ignoreSceneMaterial) return;
48905
- if (value) {
48906
- if (!this._material) {
48907
- this._material = this.mesh.material;
48908
- }
48909
- this.mesh.material = value;
48910
- } else {
48911
- if (this._material) {
48912
- this.mesh.material = this._material;
48913
- this._material = void 0;
48914
- }
48876
+ this.mesh.material = value ?? this._material;
48877
+ this.mesh.geometry.clearGroups();
48878
+ if (value instanceof Array) {
48879
+ value.forEach((m, i) => {
48880
+ this.mesh.geometry.addGroup(0, Infinity, i);
48881
+ });
48915
48882
  }
48916
48883
  }
48917
48884
  }
@@ -48969,13 +48936,17 @@ class InstancedMesh2 {
48969
48936
  // State
48970
48937
  __publicField(this, "ignoreSceneMaterial");
48971
48938
  __publicField(this, "_material");
48939
+ __publicField(this, "size", 0);
48940
+ var _a2;
48972
48941
  this.g3dMesh = g3d2;
48973
48942
  this.mesh = mesh;
48974
48943
  this.mesh.userData.vim = this;
48975
48944
  this.bimInstances = g3d2 instanceof distExports$2.G3dMesh ? instances.map((i) => g3d2.scene.instanceNodes[i]) : instances;
48976
48945
  this.meshInstances = instances;
48977
48946
  this.boxes = g3d2 instanceof distExports$2.G3dMesh ? this.importBoundingBoxes() : this.computeBoundingBoxes();
48947
+ this.size = ((_a2 = this.boxes[0]) == null ? void 0 : _a2.getSize(new Vector3$1()).length()) ?? 0;
48978
48948
  this.boundingBox = this.computeBoundingBox(this.boxes);
48949
+ this._material = this.mesh.material;
48979
48950
  }
48980
48951
  get merged() {
48981
48952
  return false;
@@ -48999,16 +48970,12 @@ class InstancedMesh2 {
48999
48970
  setMaterial(value) {
49000
48971
  if (this._material === value) return;
49001
48972
  if (this.ignoreSceneMaterial) return;
49002
- if (value) {
49003
- if (!this._material) {
49004
- this._material = this.mesh.material;
49005
- }
49006
- this.mesh.material = value;
49007
- } else {
49008
- if (this._material) {
49009
- this.mesh.material = this._material;
49010
- this._material = void 0;
49011
- }
48973
+ this.mesh.material = value ?? this._material;
48974
+ this.mesh.geometry.clearGroups();
48975
+ if (value instanceof Array) {
48976
+ value.forEach((m, i) => {
48977
+ this.mesh.geometry.addGroup(0, Infinity, i);
48978
+ });
49012
48979
  }
49013
48980
  }
49014
48981
  computeBoundingBoxes() {
@@ -50080,9 +50047,6 @@ function isPlainObject(o) {
50080
50047
  }
50081
50048
  return true;
50082
50049
  }
50083
- const floor$1 = `
50084
- data:image/png;base64,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
50085
- `;
50086
50050
  class AxesSettings {
50087
50051
  constructor(init) {
50088
50052
  __publicField(this, "size", 84);
@@ -50158,14 +50122,6 @@ const defaultViewerSettings = {
50158
50122
  // less white
50159
50123
  sharpness: 2
50160
50124
  },
50161
- groundPlane: {
50162
- visible: false,
50163
- encoding: "base64",
50164
- texture: floor$1,
50165
- opacity: 1,
50166
- color: new Color(16777215),
50167
- size: 5
50168
- },
50169
50125
  skylight: {
50170
50126
  skyColor: new Color(16777215),
50171
50127
  groundColor: new Color(16777215),
@@ -50193,9 +50149,9 @@ const defaultViewerSettings = {
50193
50149
  color: new Color(7000831),
50194
50150
  opacity: 0.5
50195
50151
  },
50196
- isolation: {
50152
+ ghost: {
50197
50153
  color: new Color(5132892),
50198
- opacity: 0.08
50154
+ opacity: 0.01
50199
50155
  },
50200
50156
  section: {
50201
50157
  strokeWidth: 0.01,
@@ -52383,6 +52339,9 @@ class Selection {
52383
52339
  });
52384
52340
  this._onValueChanged.dispatch();
52385
52341
  }
52342
+ any() {
52343
+ return this._objects.size > 0;
52344
+ }
52386
52345
  /**
52387
52346
  * Returns true if the given object is currently selected.
52388
52347
  * @param {IObject} object The object to check for selection.
@@ -52492,92 +52451,6 @@ class Selection {
52492
52451
  this._materials.focusIntensity = focus / 2;
52493
52452
  }
52494
52453
  }
52495
- class GroundPlane {
52496
- constructor(settings2) {
52497
- __publicField(this, "mesh");
52498
- __publicField(this, "_source");
52499
- __publicField(this, "_size", 1);
52500
- // disposable
52501
- __publicField(this, "_geometry");
52502
- __publicField(this, "_material");
52503
- __publicField(this, "_texture");
52504
- this._geometry = new PlaneGeometry();
52505
- this._material = new MeshBasicMaterial({
52506
- transparent: true,
52507
- depthTest: true,
52508
- depthWrite: false
52509
- });
52510
- this.mesh = new Mesh(this._geometry, this._material);
52511
- this.mesh.renderOrder = -1;
52512
- this._size = settings2.groundPlane.size;
52513
- this.mesh.visible = settings2.groundPlane.visible;
52514
- this.applyTexture(
52515
- settings2.groundPlane.encoding,
52516
- settings2.groundPlane.texture
52517
- );
52518
- this._material.color.copy(settings2.groundPlane.color);
52519
- this._material.opacity = settings2.groundPlane.opacity;
52520
- }
52521
- /**
52522
- * Whether the ground plane is visible or not.
52523
- */
52524
- get visible() {
52525
- return this.mesh.visible;
52526
- }
52527
- set visible(value) {
52528
- this.mesh.visible = value;
52529
- }
52530
- adaptToContent(box) {
52531
- const center = box.getCenter(new Vector3$1());
52532
- const position = new Vector3$1(
52533
- center.x,
52534
- box.min.y - Math.abs(box.min.y) * 0.01,
52535
- center.z
52536
- );
52537
- this.mesh.position.copy(position);
52538
- this.mesh.quaternion.copy(
52539
- new Quaternion().setFromEuler(new Euler(1.5 * Math.PI, 0, 0))
52540
- );
52541
- const sphere = box == null ? void 0 : box.getBoundingSphere(new Sphere());
52542
- const size = ((sphere == null ? void 0 : sphere.radius) ?? 1) * this._size;
52543
- const scale = new Vector3$1(1, 1, 1).multiplyScalar(size);
52544
- this.mesh.scale.copy(scale);
52545
- }
52546
- applyTexture(encoding, source) {
52547
- var _a2;
52548
- if (source === this._source) return;
52549
- this._source = source;
52550
- (_a2 = this._texture) == null ? void 0 : _a2.dispose();
52551
- this._texture = void 0;
52552
- if (!source || !encoding) return;
52553
- if (encoding === "url") {
52554
- const loader = new TextureLoader();
52555
- this._texture = loader.load(source);
52556
- }
52557
- if (encoding === "base64") {
52558
- const image = new Image();
52559
- image.src = source;
52560
- const txt = new Texture();
52561
- this._texture = txt;
52562
- this._texture.image = image;
52563
- image.onload = () => {
52564
- txt.needsUpdate = true;
52565
- };
52566
- }
52567
- if (!this._texture) {
52568
- console.error("Failed to load texture: " + source);
52569
- return;
52570
- }
52571
- this._material.map = this._texture;
52572
- }
52573
- dispose() {
52574
- var _a2, _b2, _c;
52575
- (_a2 = this._geometry) == null ? void 0 : _a2.dispose();
52576
- (_b2 = this._material) == null ? void 0 : _b2.dispose();
52577
- (_c = this._texture) == null ? void 0 : _c.dispose();
52578
- this._texture = void 0;
52579
- }
52580
- }
52581
52454
  class Skybox {
52582
52455
  constructor(camera2, renderer, materials, settings2) {
52583
52456
  __publicField(this, "mesh");
@@ -52722,28 +52595,22 @@ class Environment {
52722
52595
  * The array of directional lights in the scene.
52723
52596
  */
52724
52597
  __publicField(this, "sunLights");
52725
- /**
52726
- * The ground plane under the model in the scene.
52727
- */
52728
- __publicField(this, "groundPlane");
52729
52598
  /*
52730
52599
  * The skybox in the scene.
52731
52600
  */
52732
52601
  __publicField(this, "skybox");
52733
52602
  this._camera = camera2;
52734
52603
  this._renderer = renderer;
52735
- this.groundPlane = new GroundPlane(settings2);
52736
52604
  this.skyLight = this.createSkyLight(settings2);
52737
52605
  this.skybox = new Skybox(camera2, renderer, viewerMaterials, settings2);
52738
52606
  this.sunLights = this.createSunLights(settings2);
52739
- this.setupRendererListeners();
52740
52607
  this.addObjectsToRenderer();
52741
52608
  }
52742
52609
  /**
52743
52610
  * Returns all three objects composing the environment
52744
52611
  */
52745
52612
  getObjects() {
52746
- return [this.groundPlane.mesh, this.skyLight, ...this.sunLights.map((l) => l.light), this.skybox.mesh];
52613
+ return [this.skyLight, ...this.sunLights.map((l) => l.light), this.skybox.mesh];
52747
52614
  }
52748
52615
  createSkyLight(settings2) {
52749
52616
  const { skyColor, groundColor, intensity } = settings2.skylight;
@@ -52757,12 +52624,6 @@ class Environment {
52757
52624
  addObjectsToRenderer() {
52758
52625
  this.getObjects().forEach((o) => this._renderer.add(o));
52759
52626
  }
52760
- setupRendererListeners() {
52761
- this._renderer.onBoxUpdated.subscribe(() => {
52762
- const box = this._renderer.getBoundingBox();
52763
- this.groundPlane.adaptToContent(box);
52764
- });
52765
- }
52766
52627
  /**
52767
52628
  * Dispose of all resources.
52768
52629
  */
@@ -52770,7 +52631,6 @@ class Environment {
52770
52631
  this.getObjects().forEach((o) => this._renderer.remove(o));
52771
52632
  this.sunLights.forEach((s) => s.dispose());
52772
52633
  this.skyLight.dispose();
52773
- this.groundPlane.dispose();
52774
52634
  this.skybox.dispose();
52775
52635
  }
52776
52636
  }
@@ -52907,10 +52767,10 @@ class RenderScene {
52907
52767
  __publicField(this, "_boundingBox");
52908
52768
  __publicField(this, "_memory", 0);
52909
52769
  __publicField(this, "_2dCount", 0);
52910
- __publicField(this, "_material");
52770
+ __publicField(this, "_modelMaterial");
52911
52771
  this.scene = new Scene$1();
52912
52772
  }
52913
- get models() {
52773
+ get meshes() {
52914
52774
  return this._vimScenes.flatMap((s) => s.meshes);
52915
52775
  }
52916
52776
  get estimatedMemory() {
@@ -53006,16 +52866,27 @@ class RenderScene {
53006
52866
  this._boundingBox = void 0;
53007
52867
  this._memory = 0;
53008
52868
  }
53009
- get material() {
53010
- return this._material;
52869
+ get modelMaterial() {
52870
+ return this._modelMaterial;
53011
52871
  }
53012
- set material(material) {
53013
- this._material = material;
52872
+ set modelMaterial(material) {
52873
+ this._modelMaterial = material;
53014
52874
  this._vimScenes.forEach((s) => {
53015
- s.meshes.forEach((m) => {
53016
- m.mesh.material = material;
53017
- });
52875
+ s.material = material;
53018
52876
  });
52877
+ this.updateInstanceMeshVisibility();
52878
+ }
52879
+ updateInstanceMeshVisibility() {
52880
+ var _a2, _b2;
52881
+ const hide = ((_b2 = (_a2 = this._modelMaterial) == null ? void 0 : _a2[1]) == null ? void 0 : _b2.userData.isGhost) === true;
52882
+ for (const mesh of this.meshes) {
52883
+ if (mesh instanceof InstancedMesh2) {
52884
+ const visible2 = mesh.getSubmeshes().some(
52885
+ (m) => m.object.visible
52886
+ );
52887
+ mesh.mesh.visible = !(hide && !visible2 && mesh.size < 10);
52888
+ }
52889
+ }
53019
52890
  }
53020
52891
  addScene(scene) {
53021
52892
  this._vimScenes.push(scene);
@@ -55621,7 +55492,6 @@ class RenderingSection {
55621
55492
  this.minZ.constant = -box.min.z;
55622
55493
  this.box.copy(box);
55623
55494
  this._renderer.needsUpdate = true;
55624
- this._renderer.skipAntialias = true;
55625
55495
  }
55626
55496
  /**
55627
55497
  * Determines whether objecets outside the section box will be culled or not.
@@ -56580,7 +56450,6 @@ let Renderer$1 = class Renderer {
56580
56450
  __publicField(this, "_composer");
56581
56451
  __publicField(this, "_materials");
56582
56452
  __publicField(this, "_renderText");
56583
- __publicField(this, "_skipAntialias");
56584
56453
  __publicField(this, "_needsUpdate");
56585
56454
  __publicField(this, "_onSceneUpdate", new distExports$1.SignalDispatcher());
56586
56455
  __publicField(this, "_onBoxUpdated", new distExports$1.SignalDispatcher());
@@ -56642,17 +56511,6 @@ let Renderer$1 = class Renderer {
56642
56511
  set needsUpdate(value) {
56643
56512
  this._needsUpdate = this._needsUpdate || value;
56644
56513
  }
56645
- /**
56646
- * Indicates whether the next render should skip antialiasing.
56647
- * Useful for expensive operations such as the section box.
56648
- * Can only be set to true. Cleared on each render.
56649
- */
56650
- get skipAntialias() {
56651
- return this._skipAntialias;
56652
- }
56653
- set skipAntialias(value) {
56654
- this._skipAntialias = this._skipAntialias || value;
56655
- }
56656
56514
  /**
56657
56515
  * Removes all objects from rendering and disposes the WebGL context.
56658
56516
  */
@@ -56673,6 +56531,12 @@ let Renderer$1 = class Renderer {
56673
56531
  this._scene.scene.background = color;
56674
56532
  this.needsUpdate = true;
56675
56533
  }
56534
+ get modelMaterial() {
56535
+ return this._scene.modelMaterial;
56536
+ }
56537
+ set modelMaterial(material) {
56538
+ this._scene.modelMaterial = material;
56539
+ }
56676
56540
  /**
56677
56541
  * Signal dispatched at the end of each frame if the scene was updated, such as visibility changes.
56678
56542
  */
@@ -56736,7 +56600,6 @@ let Renderer$1 = class Renderer {
56736
56600
  this._composer.render();
56737
56601
  }
56738
56602
  this._needsUpdate = false;
56739
- this.skipAntialias = false;
56740
56603
  if (this.textEnabled && this._scene.has2dObjects()) {
56741
56604
  this.textRenderer.render(this._scene.scene, this._camera.three);
56742
56605
  }
@@ -57002,14 +56865,6 @@ function parseSettingsFromUrl(url) {
57002
56865
  groundColor: get3("skybox.groundColor", strToColor),
57003
56866
  sharpness: get3("skybox.sharpness", Number.parseFloat)
57004
56867
  },
57005
- groundPlane: {
57006
- visible: get3("groundPlane.visible", strToBool),
57007
- encoding: get3("groundPlane.encoding"),
57008
- texture: get3("groundPlane.texture"),
57009
- opacity: get3("groundPlane.opacity", Number.parseFloat),
57010
- color: get3("groundPlane.color", strToColor),
57011
- size: get3("groundPlane.size", Number.parseFloat)
57012
- },
57013
56868
  skylight: {
57014
56869
  skyColor: get3("skylight.skyColor", strToColor),
57015
56870
  groundColor: get3("skylight.groundColor", strToColor),
@@ -57037,9 +56892,9 @@ function parseSettingsFromUrl(url) {
57037
56892
  color: get3("materials.highlight.color", strToColor),
57038
56893
  opacity: get3("materials.highlight.opacity", Number.parseFloat)
57039
56894
  },
57040
- isolation: {
57041
- color: get3("materials.isolation.color", strToColor),
57042
- opacity: get3("materials.isolation.opacity", Number.parseFloat)
56895
+ ghost: {
56896
+ color: get3("materials.ghost.color", strToColor),
56897
+ opacity: get3("materials.ghost.opacity", Number.parseFloat)
57043
56898
  },
57044
56899
  section: {
57045
56900
  strokeWidth: get3("materials.section.strokeWidth", Number.parseFloat),
@@ -66992,12 +66847,12 @@ function anyUiSettingButton(settings2) {
66992
66847
  return isTrue(settings2.ui.projectInspector) || isTrue(settings2.ui.settings) || isTrue(settings2.ui.help) || isTrue(settings2.ui.maximise);
66993
66848
  }
66994
66849
  const defaultSettings = {
66995
- peformance: {
66996
- useFastMaterial: false
66850
+ materials: {
66851
+ useFastMaterial: false,
66852
+ useGhostMaterial: true
66997
66853
  },
66998
66854
  isolation: {
66999
- enable: true,
67000
- useIsolationMaterial: true
66855
+ enable: true
67001
66856
  },
67002
66857
  capacity: {
67003
66858
  canFollowUrl: true,
@@ -67077,7 +66932,7 @@ function AxesPanel(props) {
67077
66932
  }, []);
67078
66933
  const onIsolationBtn = () => {
67079
66934
  props.settings.update(
67080
- (s) => s.isolation.useIsolationMaterial = !s.isolation.useIsolationMaterial
66935
+ (s) => s.materials.useGhostMaterial = !s.materials.useGhostMaterial
67081
66936
  );
67082
66937
  };
67083
66938
  const onHomeBtn = () => {
@@ -67087,11 +66942,11 @@ function AxesPanel(props) {
67087
66942
  const btnIsolation = /* @__PURE__ */ jsxRuntimeExports.jsx(
67088
66943
  "button",
67089
66944
  {
67090
- "data-tip": props.settings.value.isolation.useIsolationMaterial ? "Disable Ghosting" : "Enable Ghosting",
66945
+ "data-tip": props.settings.value.materials.useGhostMaterial ? "Disable Ghosting" : "Enable Ghosting",
67091
66946
  onClick: onIsolationBtn,
67092
66947
  className: "vim-isolation-btn " + btnStyle2,
67093
66948
  type: "button",
67094
- 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" })
66949
+ 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" })
67095
66950
  }
67096
66951
  );
67097
66952
  const btnHome = /* @__PURE__ */ jsxRuntimeExports.jsxs(
@@ -67621,7 +67476,7 @@ function ControlBar(props) {
67621
67476
  id: elementIds.buttonToggleIsolation,
67622
67477
  enabled: () => isTrue(props.settings.ui.toggleIsolation),
67623
67478
  tip: "Toggle Isolation",
67624
- action: () => props.isolation.toggleIsolation("controlBar"),
67479
+ action: () => props.isolation.toggle("controlBar"),
67625
67480
  icon: toggleIsolation,
67626
67481
  style: buttonDefaultStyle
67627
67482
  }
@@ -71642,7 +71497,7 @@ function VimContextMenu(props) {
71642
71497
  };
71643
71498
  const [clipping, setClipping] = useState(isClipping());
71644
71499
  const [, setVersion] = useState(0);
71645
- const hidden2 = props.isolation.any();
71500
+ const hidden2 = props.isolation.isActive();
71646
71501
  useEffect(() => {
71647
71502
  const subState = viewer.gizmos.section.onStateChanged.subscribe(() => {
71648
71503
  setSection({
@@ -74025,31 +73880,17 @@ function MenuSettings(props) {
74025
73880
  ),
74026
73881
  settingsSubtitle("Materials"),
74027
73882
  settingsToggle(
74028
- "Use Isolation Material",
74029
- (settings2) => settings2.isolation.useIsolationMaterial,
73883
+ "Use Ghost Material",
73884
+ (settings2) => settings2.materials.useGhostMaterial,
74030
73885
  (settings2, value) => {
74031
- settings2.isolation.useIsolationMaterial = value;
74032
- if (settings2.peformance.useFastMaterial && value) {
74033
- settings2.peformance.useFastMaterial = false;
74034
- }
73886
+ settings2.materials.useGhostMaterial = value;
74035
73887
  }
74036
73888
  ),
74037
73889
  settingsToggle(
74038
73890
  "Use Performance Material",
74039
- (settings2) => settings2.peformance.useFastMaterial,
73891
+ (settings2) => settings2.materials.useFastMaterial,
74040
73892
  (settings2, value) => {
74041
- settings2.peformance.useFastMaterial = value;
74042
- if (settings2.isolation.useIsolationMaterial && value) {
74043
- settings2.isolation.useIsolationMaterial = false;
74044
- }
74045
- }
74046
- ),
74047
- settingsSubtitle("Scene"),
74048
- settingsToggle(
74049
- "Show Ground Plane",
74050
- (_) => props.viewer.environment.groundPlane.visible,
74051
- (_, value) => {
74052
- props.viewer.environment.groundPlane.visible = value;
73893
+ settings2.materials.useFastMaterial = value;
74053
73894
  }
74054
73895
  ),
74055
73896
  settingsSubtitle("Panels"),
@@ -74323,7 +74164,6 @@ class ComponentInputs {
74323
74164
  __publicField(this, "_default");
74324
74165
  __publicField(this, "_isolation");
74325
74166
  __publicField(this, "_sideState");
74326
- __publicField(this, "_help");
74327
74167
  __publicField(this, "_getSelection", () => {
74328
74168
  return [...this._viewer.selection.objects].filter(
74329
74169
  (o) => o.type === "Object3D"
@@ -74353,7 +74193,7 @@ class ComponentInputs {
74353
74193
  return true;
74354
74194
  }
74355
74195
  case KEYS.KEY_I: {
74356
- this._isolation.toggleIsolation("keyboard");
74196
+ this._isolation.toggle("keyboard");
74357
74197
  return true;
74358
74198
  }
74359
74199
  case KEYS.KEY_ESCAPE: {
@@ -74361,7 +74201,7 @@ class ComponentInputs {
74361
74201
  this._viewer.selection.clear();
74362
74202
  return true;
74363
74203
  }
74364
- if (this._isolation.any()) {
74204
+ if (this._isolation.isActive()) {
74365
74205
  this._isolation.clear("keyboard");
74366
74206
  return true;
74367
74207
  }
@@ -74443,7 +74283,6 @@ function useSettings(viewer, value) {
74443
74283
  var _a2;
74444
74284
  const next = { ...settings2 };
74445
74285
  updater(next);
74446
- validateSettings(next);
74447
74286
  saveSettingsToLocal(next);
74448
74287
  setSettings(next);
74449
74288
  (_a2 = onUpdate.current) == null ? void 0 : _a2.call(onUpdate, next);
@@ -74463,11 +74302,6 @@ function useSettings(viewer, value) {
74463
74302
  [settings2]
74464
74303
  );
74465
74304
  }
74466
- function validateSettings(settings2) {
74467
- if (settings2.peformance.useFastMaterial && settings2.isolation.useIsolationMaterial) {
74468
- settings2.peformance.useFastMaterial = false;
74469
- }
74470
- }
74471
74305
  function applySettings(viewer, settings2) {
74472
74306
  const performance2 = document.getElementsByClassName("vim-performance-div")[0];
74473
74307
  if (performance2) {
@@ -74477,240 +74311,194 @@ function applySettings(viewer, settings2) {
74477
74311
  performance2.classList.add("vc-hidden");
74478
74312
  }
74479
74313
  }
74480
- viewer.vims.forEach((v) => {
74481
- if (settings2.peformance.useFastMaterial && v.scene.material === void 0) {
74482
- v.scene.material = viewer.materials.simple;
74483
- }
74484
- if (!settings2.peformance.useFastMaterial && v.scene.material === viewer.materials.simple) {
74485
- v.scene.material = void 0;
74486
- }
74487
- });
74314
+ if (!settings2.isolation.enable) {
74315
+ viewer.renderer.modelMaterial = settings2.materials.useFastMaterial ? viewer.materials.simple : void 0;
74316
+ }
74488
74317
  }
74489
74318
  class Isolation {
74319
+ /**
74320
+ * Constructs an IsolationManager.
74321
+ *
74322
+ * @param viewer - The VIM Viewer responsible for managing the 3D scene and objects.
74323
+ * @param camera - A component that handles camera control and framing.
74324
+ * @param settings - The settings that control isolation and material usage.
74325
+ */
74490
74326
  constructor(viewer, camera2, settings2) {
74491
74327
  __publicField(this, "_viewer");
74492
74328
  __publicField(this, "_settings");
74493
- __publicField(this, "_isolation");
74494
- __publicField(this, "_lastIsolation");
74329
+ __publicField(this, "_isolation", []);
74495
74330
  __publicField(this, "_camera");
74496
- __publicField(this, "_references", /* @__PURE__ */ new Map());
74497
74331
  __publicField(this, "_onChanged", new distExports.SimpleEventDispatcher());
74498
74332
  this._viewer = viewer;
74499
74333
  this._camera = camera2;
74500
74334
  this.applySettings(settings2);
74501
74335
  }
74502
- /** Signal dispatched when the isolation set changes. */
74336
+ /**
74337
+ * An event that is dispatched whenever the isolation set changes.
74338
+ *
74339
+ * @remarks
74340
+ * This can be used by other parts of the application to react to isolation
74341
+ * updates (for example, updating UI or triggering additional viewport actions).
74342
+ *
74343
+ * @returns {ISimpleEvent<string>} Event interface for subscribing to isolation changes.
74344
+ */
74503
74345
  get onChanged() {
74504
74346
  return this._onChanged.asEvent();
74505
74347
  }
74506
74348
  /**
74507
- * Applies relevant settings to isolation.
74508
- * @param settings The settings to be applied to isolation.
74349
+ * Applies relevant settings to the isolation behavior.
74350
+ *
74351
+ * @param settings - The new settings to apply.
74352
+ *
74353
+ * @remarks
74354
+ * This updates the internal reference to settings and immediately sets
74355
+ * the material based on whether isolation is currently active.
74509
74356
  */
74510
74357
  applySettings(settings2) {
74511
- var _a2;
74512
74358
  this._settings = settings2;
74513
74359
  if (!this._settings.isolation.enable) return;
74514
- const set3 = new Set((_a2 = this._isolation) == null ? void 0 : _a2.map((o) => o.vim));
74515
- this._viewer.vims.forEach((v) => {
74516
- v.scene.material = this.getMaterial(this._settings, set3.has(v));
74517
- });
74518
- }
74519
- /**
74520
- * Sets the reference objects for a given VIM.
74521
- * @param vim The VIM for which reference objects are being set.
74522
- * @param reference An array of reference objects or the string 'always' to indicate permanent reference.
74523
- */
74524
- setReference(vim, reference) {
74525
- const value = reference === "always" ? reference : new Set(reference);
74526
- this._references.set(vim, value);
74360
+ this._viewer.renderer.modelMaterial = this.getMaterial(this._settings, this.isActive());
74527
74361
  }
74528
74362
  /**
74529
- * Retrieves the reference objects set for a given VIM.
74530
- * @param vim The VIM for which reference objects are being retrieved.
74531
- * @returns The reference objects set for the specified VIM.
74363
+ * Checks if isolation is currently active (i.e., any objects are isolated).
74364
+ *
74365
+ * @returns True if isolation is active; otherwise, false.
74532
74366
  */
74533
- getReference(vim) {
74534
- return this._references.get(vim);
74367
+ isActive() {
74368
+ return this._isolation.length > 0;
74535
74369
  }
74536
74370
  /**
74537
- * Clears all reference objects set for VIMs.
74538
- */
74539
- clearReferences() {
74540
- this._references.clear();
74541
- }
74542
- /**
74543
- * Returns true if there are currently objects isolated.
74544
- * @returns True if there are currently objects isolated; otherwise, false.
74545
- */
74546
- any() {
74547
- return this._isolation !== void 0;
74548
- }
74549
- /**
74550
- * Returns the current array of isolated objects.
74551
- * @returns The array of objects currently isolated, or undefined if no objects are isolated.
74371
+ * Retrieves the current array of isolated objects.
74372
+ *
74373
+ * @returns An array of isolated objects, or undefined if isolation is not active.
74552
74374
  */
74553
74375
  current() {
74554
74376
  return this._isolation;
74555
74377
  }
74556
74378
  /**
74557
- * Isolates the objects in the given array and shows the rest as ghost.
74558
- * @param objects An array of objects to isolate.
74559
- * @param source The source of isolation.
74560
- * @returns True if isolation occurs; otherwise, false.
74379
+ * Sets the specified objects as isolated, hiding or ghosting the rest.
74380
+ *
74381
+ * @param objects - The objects to isolate.
74382
+ * @param source - A label or identifier indicating the source of this action (e.g., "user").
74561
74383
  */
74562
74384
  isolate(objects, source) {
74563
74385
  if (!this._settings.isolation.enable) return;
74564
- if (this._isolation) {
74565
- this._lastIsolation = this._isolation;
74566
- }
74567
- const isolated = this._isolate(this._viewer, this._settings, objects);
74568
- this._isolation = isolated ? objects : void 0;
74386
+ this._isolation = objects ?? [];
74387
+ this._apply(source);
74569
74388
  this._camera.frameVisibleObjects();
74570
- this._onChanged.dispatch(source);
74571
- return isolated;
74572
74389
  }
74573
74390
  /**
74574
- * Toggles current isolation based on selection.
74575
- * @param source The source of isolation.
74391
+ * Toggles isolation by using the current selection.
74392
+ *
74393
+ * @param source - A label or identifier for the isolation action.
74394
+ *
74395
+ * @remarks
74396
+ * This method replaces the current isolation set with whatever objects are
74397
+ * currently selected. If selection is empty, it effectively clears isolation.
74576
74398
  */
74577
- toggleIsolation(source) {
74399
+ toggle(source) {
74578
74400
  if (!this._settings.isolation.enable) return;
74579
- const selection = [...this._viewer.selection.objects].filter((o) => o.type === "Object3D");
74580
- if (this._isolation) {
74581
- this._lastIsolation = this._isolation;
74582
- }
74583
- if (this._isolation) {
74584
- if (selection.length === 0 || ArrayEquals(this._isolation, selection)) {
74585
- this._showAll();
74586
- this._isolation = void 0;
74587
- } else {
74588
- const isolated = this._isolate(this._viewer, this._settings, selection);
74589
- this._isolation = isolated ? selection : void 0;
74590
- this._camera.frameVisibleObjects();
74591
- this._viewer.selection.clear();
74592
- }
74593
- } else {
74594
- if (selection.length > 0) {
74595
- const isolated = this._isolate(this._viewer, this._settings, selection);
74596
- this._isolation = isolated ? selection : void 0;
74597
- this._camera.frameVisibleObjects();
74598
- this._viewer.selection.clear();
74599
- } else if (this._lastIsolation) {
74600
- const isolated = this._isolate(
74601
- this._viewer,
74602
- this._settings,
74603
- this._lastIsolation
74604
- );
74605
- this._isolation = isolated ? [...this._lastIsolation] : void 0;
74606
- }
74607
- }
74608
- this._onChanged.dispatch(source);
74401
+ this._isolation = [...this._viewer.selection.objects].filter((o) => o.type === "Object3D");
74402
+ this._apply(source);
74403
+ this._camera.frameVisibleObjects();
74404
+ this._viewer.selection.clear();
74609
74405
  }
74610
74406
  /**
74611
- * Removes the given objects from the isolation set.
74612
- * @param objects An array of objects to be removed from isolation.
74613
- * @param source The source of the removal operation.
74407
+ * Hides the specified objects from the isolation set.
74408
+ *
74409
+ * @param objects - The objects to hide.
74410
+ * @param source - A label or identifier for the isolation action.
74411
+ *
74412
+ * @remarks
74413
+ * If there is no active isolation set (i.e., all objects are visible),
74414
+ * the method first treats all objects in the scene as isolated,
74415
+ * and then removes the specified objects. This ensures the specified
74416
+ * objects become hidden.
74614
74417
  */
74615
74418
  hide(objects, source) {
74616
74419
  if (!this._settings.isolation.enable) return;
74617
- const selection = new Set(objects);
74618
- const initial = this._isolation ?? this._viewer.vims[0].getObjects();
74619
- const result = [];
74620
- for (const obj of initial) {
74621
- if (!selection.has(obj)) result.push(obj);
74622
- }
74623
- const isolated = this._isolate(this._viewer, this._settings, result);
74624
- this._isolation = isolated ? result : void 0;
74625
- this._onChanged.dispatch(source);
74420
+ this._isolation = this._isolation.length === 0 ? this.getAllObjects() : this._isolation;
74421
+ this._isolation = this._isolation.filter((o) => !objects.includes(o));
74422
+ this._apply(source);
74626
74423
  objects.forEach((o) => this._viewer.selection.remove(o));
74627
74424
  }
74628
74425
  /**
74629
- * Adds the given objects to the isolation set.
74630
- * @param objects An array of objects to be added to isolation.
74631
- * @param source The source of the addition operation.
74426
+ * Adds the specified objects to the current isolation set (making them visible).
74427
+ *
74428
+ * @param objects - The objects to show.
74429
+ * @param source - A label or identifier for the isolation action.
74632
74430
  */
74633
74431
  show(objects, source) {
74634
74432
  if (!this._settings.isolation.enable) return;
74635
- const isolation = this._isolation ?? [];
74636
- objects.forEach((o) => isolation.push(o));
74637
- const result = [...new Set(isolation)];
74638
- const isolated = this._isolate(this._viewer, this._settings, result);
74639
- this._isolation = isolated ? result : void 0;
74640
- this._onChanged.dispatch(source);
74433
+ objects.forEach((o) => this._isolation.push(o));
74434
+ this._apply(source);
74641
74435
  }
74642
74436
  /**
74643
- * Clears the current isolation.
74644
- * @param source The source of the isolation clearing operation.
74437
+ * Clears the current isolation set, making all objects visible.
74438
+ *
74439
+ * @param source - A label or identifier for the isolation action.
74645
74440
  */
74646
74441
  clear(source) {
74647
74442
  if (!this._settings.isolation.enable) return;
74648
- this._showAll();
74649
- this._lastIsolation = this._isolation;
74650
- this._isolation = void 0;
74651
- this._onChanged.dispatch(source);
74443
+ this._isolation.length = 0;
74444
+ this._apply(source);
74652
74445
  }
74653
74446
  /**
74654
- * Show all objects and quit isolation mode.
74447
+ * Constructs the correct material (or array of materials) based on the given settings.
74448
+ *
74449
+ * @param settings - The current component settings, including isolation rules.
74450
+ * @param isolate - Whether or not isolation is active.
74451
+ * @returns The material(s) to assign to the renderer, or undefined if default materials should be used.
74452
+ *
74453
+ * @remarks
74454
+ * - If isolation is active and `useGhostMaterial` is true, an array containing
74455
+ * the simple and ghost materials is returned.
74456
+ * - If fast materials are enabled, the simple material is returned.
74457
+ * - Otherwise, defaults to undefined, allowing the system to pick a standard material.
74655
74458
  */
74656
- _showAll() {
74657
- this._viewer.vims.forEach((v) => {
74658
- for (const obj of v.getObjects()) {
74659
- obj.visible = true;
74660
- }
74661
- v.scene.material = this.getMaterial(this._settings, false);
74662
- });
74663
- }
74664
74459
  getMaterial(settings2, isolate) {
74665
- if (settings2.peformance.useFastMaterial) {
74666
- return this._viewer.materials.simple;
74460
+ if (isolate && settings2.materials.useGhostMaterial) {
74461
+ return [this._viewer.materials.simple, this._viewer.materials.ghost];
74667
74462
  }
74668
- if (!settings2.isolation.useIsolationMaterial) {
74669
- return void 0;
74670
- }
74671
- if (!isolate) {
74672
- return void 0;
74463
+ if (settings2.materials.useFastMaterial) {
74464
+ return this._viewer.materials.simple;
74673
74465
  }
74674
- return this._viewer.materials.isolation;
74466
+ return void 0;
74675
74467
  }
74676
- _isolate(viewer, settings2, objects) {
74677
- let useIsolation = false;
74678
- if (!objects) {
74679
- this._showAll();
74680
- } else {
74681
- const set3 = new Set(objects);
74682
- let all = true;
74683
- viewer.vims.forEach((vim) => {
74684
- for (const obj of vim.getObjects()) {
74685
- if (obj.hasMesh) {
74686
- obj.visible = set3.has(obj);
74687
- all = all && obj.visible;
74688
- }
74689
- }
74690
- const reference = this._references.get(vim);
74691
- if (reference === void 0) {
74692
- useIsolation = !all;
74693
- } else if (reference === "always") {
74694
- useIsolation = true;
74695
- } else {
74696
- useIsolation = !setsEqual(reference, set3);
74468
+ /**
74469
+ * Applies the current isolation state: sets visibility for objects, updates materials,
74470
+ * and dispatches the changed event.
74471
+ *
74472
+ * @param source - A label or identifier for the isolation action.
74473
+ */
74474
+ _apply(source) {
74475
+ let all = true;
74476
+ let any = false;
74477
+ const set3 = this._isolation.length > 0 ? new Set(this._isolation) : void 0;
74478
+ this._viewer.vims.forEach((vim) => {
74479
+ for (const obj of vim.getObjects()) {
74480
+ if (obj.hasMesh) {
74481
+ obj.visible = (set3 == null ? void 0 : set3.has(obj)) ?? true;
74482
+ all = all && obj.visible;
74483
+ any = any || obj.visible;
74697
74484
  }
74698
- vim.scene.material = this.getMaterial(this._settings, useIsolation);
74699
- });
74700
- }
74701
- return useIsolation;
74702
- }
74703
- }
74704
- function setsEqual(set1, set22) {
74705
- if (set1.size !== set22.size) {
74706
- return false;
74485
+ }
74486
+ });
74487
+ this._viewer.renderer.modelMaterial = this.getMaterial(this._settings, any && !all);
74488
+ this._onChanged.dispatch(source);
74707
74489
  }
74708
- for (const item of set1) {
74709
- if (!set22.has(item)) {
74710
- return false;
74711
- }
74490
+ /**
74491
+ * Gathers all objects from all loaded VIM instances.
74492
+ *
74493
+ * @returns An array of all objects within the loaded VIM scenes.
74494
+ */
74495
+ getAllObjects() {
74496
+ let objects = [];
74497
+ this._viewer.vims.forEach((vim) => {
74498
+ objects = objects.concat(vim.getObjects());
74499
+ });
74500
+ return objects;
74712
74501
  }
74713
- return true;
74714
74502
  }
74715
74503
  class ComponentCamera {
74716
74504
  constructor(viewer) {