vim-web 0.3.42-dev.1 → 0.3.42-dev.10

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 (25) hide show
  1. package/dist/types/core-viewers/ultra/viewer/socketClient.d.ts +5 -4
  2. package/dist/types/core-viewers/ultra/viewer/viewer.d.ts +1 -1
  3. package/dist/types/core-viewers/webgl/loader/materials/ghostMaterial.d.ts +16 -0
  4. package/dist/types/core-viewers/webgl/loader/materials/simpleMaterial.d.ts +10 -5
  5. package/dist/types/core-viewers/webgl/loader/materials/viewerMaterials.d.ts +9 -8
  6. package/dist/types/core-viewers/webgl/loader/mesh.d.ts +2 -1
  7. package/dist/types/core-viewers/webgl/loader/progressive/insertableMesh.d.ts +2 -1
  8. package/dist/types/core-viewers/webgl/loader/progressive/instancedMesh.d.ts +3 -1
  9. package/dist/types/core-viewers/webgl/loader/scene.d.ts +3 -2
  10. package/dist/types/core-viewers/webgl/viewer/environment/environment.d.ts +0 -6
  11. package/dist/types/core-viewers/webgl/viewer/rendering/renderScene.d.ts +8 -4
  12. package/dist/types/core-viewers/webgl/viewer/rendering/renderer.d.ts +5 -9
  13. package/dist/types/core-viewers/webgl/viewer/selection.d.ts +1 -0
  14. package/dist/types/core-viewers/webgl/viewer/settings/viewerSettings.d.ts +4 -39
  15. package/dist/types/react-viewers/helpers/inputs.d.ts +1 -2
  16. package/dist/types/react-viewers/helpers/isolation.d.ts +91 -50
  17. package/dist/types/react-viewers/settings/settings.d.ts +3 -2
  18. package/dist/vim-web.iife.js +342 -560
  19. package/dist/vim-web.iife.js.map +1 -1
  20. package/dist/vim-web.js +348 -566
  21. package/dist/vim-web.js.map +1 -1
  22. package/package.json +1 -1
  23. package/dist/types/core-viewers/webgl/images.d.ts +0 -4
  24. package/dist/types/core-viewers/webgl/loader/materials/isolationMaterial.d.ts +0 -12
  25. 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
-
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
47942
 
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
-
47976
47952
 
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,27 @@ 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
+ const mat = this.ghost;
48564
+ return mat.uniforms.opacity.value;
48594
48565
  }
48595
- set isolationOpacity(opacity) {
48596
- const mat = this.isolation;
48566
+ set ghostOpacity(opacity) {
48567
+ const mat = this.ghost;
48597
48568
  mat.uniforms.opacity.value = opacity;
48598
48569
  mat.uniformsNeedUpdate = true;
48599
48570
  this._onUpdate.dispatch();
48600
48571
  }
48601
48572
  /**
48602
- * Determines the color of the isolation material.
48573
+ * Determines the color of the ghost material.
48603
48574
  */
48604
- get isolationColor() {
48605
- const mat = this.isolation;
48575
+ get ghostColor() {
48576
+ const mat = this.ghost;
48606
48577
  return mat.uniforms.fillColor.value;
48607
48578
  }
48608
- set isolationColor(color) {
48609
- const mat = this.isolation;
48579
+ set ghostColor(color) {
48580
+ const mat = this.ghost;
48610
48581
  mat.uniforms.fillColor.value = color;
48611
48582
  mat.uniformsNeedUpdate = true;
48612
48583
  this._onUpdate.dispatch();
@@ -48667,10 +48638,11 @@ const _ViewerMaterials = class _ViewerMaterials {
48667
48638
  }
48668
48639
  set clippingPlanes(value) {
48669
48640
  this._clippingPlanes = value;
48641
+ this.simple.clippingPlanes = value ?? null;
48670
48642
  this.opaque.clippingPlanes = value ?? null;
48671
48643
  this.transparent.clippingPlanes = value ?? null;
48672
48644
  this.wireframe.clippingPlanes = value ?? null;
48673
- this.isolation.clippingPlanes = value ?? null;
48645
+ this.ghost.clippingPlanes = value ?? null;
48674
48646
  this.mask.clippingPlanes = value ?? null;
48675
48647
  this._onUpdate.dispatch();
48676
48648
  }
@@ -48790,7 +48762,7 @@ const _ViewerMaterials = class _ViewerMaterials {
48790
48762
  this.opaque.dispose();
48791
48763
  this.transparent.dispose();
48792
48764
  this.wireframe.dispose();
48793
- this.isolation.dispose();
48765
+ this.ghost.dispose();
48794
48766
  this.mask.dispose();
48795
48767
  this.outline.dispose();
48796
48768
  }
@@ -48902,16 +48874,12 @@ class InsertableMesh {
48902
48874
  setMaterial(value) {
48903
48875
  if (this._material === value) return;
48904
48876
  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
- }
48877
+ this.mesh.material = value ?? this._material;
48878
+ this.mesh.geometry.clearGroups();
48879
+ if (value instanceof Array) {
48880
+ value.forEach((m, i) => {
48881
+ this.mesh.geometry.addGroup(0, Infinity, i);
48882
+ });
48915
48883
  }
48916
48884
  }
48917
48885
  }
@@ -48969,13 +48937,17 @@ class InstancedMesh2 {
48969
48937
  // State
48970
48938
  __publicField(this, "ignoreSceneMaterial");
48971
48939
  __publicField(this, "_material");
48940
+ __publicField(this, "size", 0);
48941
+ var _a2;
48972
48942
  this.g3dMesh = g3d2;
48973
48943
  this.mesh = mesh;
48974
48944
  this.mesh.userData.vim = this;
48975
48945
  this.bimInstances = g3d2 instanceof distExports$2.G3dMesh ? instances.map((i) => g3d2.scene.instanceNodes[i]) : instances;
48976
48946
  this.meshInstances = instances;
48977
48947
  this.boxes = g3d2 instanceof distExports$2.G3dMesh ? this.importBoundingBoxes() : this.computeBoundingBoxes();
48948
+ this.size = ((_a2 = this.boxes[0]) == null ? void 0 : _a2.getSize(new Vector3$1()).length()) ?? 0;
48978
48949
  this.boundingBox = this.computeBoundingBox(this.boxes);
48950
+ this._material = this.mesh.material;
48979
48951
  }
48980
48952
  get merged() {
48981
48953
  return false;
@@ -48999,16 +48971,12 @@ class InstancedMesh2 {
48999
48971
  setMaterial(value) {
49000
48972
  if (this._material === value) return;
49001
48973
  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
- }
48974
+ this.mesh.material = value ?? this._material;
48975
+ this.mesh.geometry.clearGroups();
48976
+ if (value instanceof Array) {
48977
+ value.forEach((m, i) => {
48978
+ this.mesh.geometry.addGroup(0, Infinity, i);
48979
+ });
49012
48980
  }
49013
48981
  }
49014
48982
  computeBoundingBoxes() {
@@ -49947,7 +49915,7 @@ async function loadFromVim(bfast2, settings2, onProgress) {
49947
49915
  }
49948
49916
  return vim;
49949
49917
  }
49950
- let DeferredPromise$2 = class DeferredPromise extends Promise {
49918
+ let DeferredPromise$1 = class DeferredPromise extends Promise {
49951
49919
  constructor(executor = () => {
49952
49920
  }) {
49953
49921
  var _a2;
@@ -50010,8 +49978,8 @@ class VimRequest {
50010
49978
  __publicField(this, "_error");
50011
49979
  // Promises to await progress updates and completion
50012
49980
  __publicField(this, "_progress", { loaded: 0, total: 0, all: /* @__PURE__ */ new Map() });
50013
- __publicField(this, "_progressPromise", new DeferredPromise$2());
50014
- __publicField(this, "_completionPromise", new DeferredPromise$2());
49981
+ __publicField(this, "_progressPromise", new DeferredPromise$1());
49982
+ __publicField(this, "_completionPromise", new DeferredPromise$1());
50015
49983
  this._source = source;
50016
49984
  this._settings = settings2;
50017
49985
  this.startRequest();
@@ -50025,7 +49993,7 @@ class VimRequest {
50025
49993
  const vim = await open(this._bfast, this._settings, (progress) => {
50026
49994
  this._progress = progress;
50027
49995
  this._progressPromise.resolve(progress);
50028
- this._progressPromise = new DeferredPromise$2();
49996
+ this._progressPromise = new DeferredPromise$1();
50029
49997
  });
50030
49998
  this._vimResult = vim;
50031
49999
  } catch (err) {
@@ -50080,9 +50048,6 @@ function isPlainObject(o) {
50080
50048
  }
50081
50049
  return true;
50082
50050
  }
50083
- const floor$1 = `
50084
- data:image/png;base64,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
50085
- `;
50086
50051
  class AxesSettings {
50087
50052
  constructor(init) {
50088
50053
  __publicField(this, "size", 84);
@@ -50158,14 +50123,6 @@ const defaultViewerSettings = {
50158
50123
  // less white
50159
50124
  sharpness: 2
50160
50125
  },
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
50126
  skylight: {
50170
50127
  skyColor: new Color(16777215),
50171
50128
  groundColor: new Color(16777215),
@@ -50193,9 +50150,9 @@ const defaultViewerSettings = {
50193
50150
  color: new Color(7000831),
50194
50151
  opacity: 0.5
50195
50152
  },
50196
- isolation: {
50153
+ ghost: {
50197
50154
  color: new Color(5132892),
50198
- opacity: 0.08
50155
+ opacity: 0.01
50199
50156
  },
50200
50157
  section: {
50201
50158
  strokeWidth: 0.01,
@@ -52383,6 +52340,9 @@ class Selection {
52383
52340
  });
52384
52341
  this._onValueChanged.dispatch();
52385
52342
  }
52343
+ any() {
52344
+ return this._objects.size > 0;
52345
+ }
52386
52346
  /**
52387
52347
  * Returns true if the given object is currently selected.
52388
52348
  * @param {IObject} object The object to check for selection.
@@ -52492,92 +52452,6 @@ class Selection {
52492
52452
  this._materials.focusIntensity = focus / 2;
52493
52453
  }
52494
52454
  }
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
52455
  class Skybox {
52582
52456
  constructor(camera2, renderer, materials, settings2) {
52583
52457
  __publicField(this, "mesh");
@@ -52722,28 +52596,22 @@ class Environment {
52722
52596
  * The array of directional lights in the scene.
52723
52597
  */
52724
52598
  __publicField(this, "sunLights");
52725
- /**
52726
- * The ground plane under the model in the scene.
52727
- */
52728
- __publicField(this, "groundPlane");
52729
52599
  /*
52730
52600
  * The skybox in the scene.
52731
52601
  */
52732
52602
  __publicField(this, "skybox");
52733
52603
  this._camera = camera2;
52734
52604
  this._renderer = renderer;
52735
- this.groundPlane = new GroundPlane(settings2);
52736
52605
  this.skyLight = this.createSkyLight(settings2);
52737
52606
  this.skybox = new Skybox(camera2, renderer, viewerMaterials, settings2);
52738
52607
  this.sunLights = this.createSunLights(settings2);
52739
- this.setupRendererListeners();
52740
52608
  this.addObjectsToRenderer();
52741
52609
  }
52742
52610
  /**
52743
52611
  * Returns all three objects composing the environment
52744
52612
  */
52745
52613
  getObjects() {
52746
- return [this.groundPlane.mesh, this.skyLight, ...this.sunLights.map((l) => l.light), this.skybox.mesh];
52614
+ return [this.skyLight, ...this.sunLights.map((l) => l.light), this.skybox.mesh];
52747
52615
  }
52748
52616
  createSkyLight(settings2) {
52749
52617
  const { skyColor, groundColor, intensity } = settings2.skylight;
@@ -52757,12 +52625,6 @@ class Environment {
52757
52625
  addObjectsToRenderer() {
52758
52626
  this.getObjects().forEach((o) => this._renderer.add(o));
52759
52627
  }
52760
- setupRendererListeners() {
52761
- this._renderer.onBoxUpdated.subscribe(() => {
52762
- const box = this._renderer.getBoundingBox();
52763
- this.groundPlane.adaptToContent(box);
52764
- });
52765
- }
52766
52628
  /**
52767
52629
  * Dispose of all resources.
52768
52630
  */
@@ -52770,7 +52632,6 @@ class Environment {
52770
52632
  this.getObjects().forEach((o) => this._renderer.remove(o));
52771
52633
  this.sunLights.forEach((s) => s.dispose());
52772
52634
  this.skyLight.dispose();
52773
- this.groundPlane.dispose();
52774
52635
  this.skybox.dispose();
52775
52636
  }
52776
52637
  }
@@ -52903,14 +52764,16 @@ class RenderScene {
52903
52764
  __publicField(this, "scene");
52904
52765
  // state
52905
52766
  __publicField(this, "boxUpdated", false);
52767
+ // public value
52768
+ __publicField(this, "smallGhostThreshold", 10);
52906
52769
  __publicField(this, "_vimScenes", []);
52907
52770
  __publicField(this, "_boundingBox");
52908
52771
  __publicField(this, "_memory", 0);
52909
52772
  __publicField(this, "_2dCount", 0);
52910
- __publicField(this, "_material");
52773
+ __publicField(this, "_modelMaterial");
52911
52774
  this.scene = new Scene$1();
52912
52775
  }
52913
- get models() {
52776
+ get meshes() {
52914
52777
  return this._vimScenes.flatMap((s) => s.meshes);
52915
52778
  }
52916
52779
  get estimatedMemory() {
@@ -53006,16 +52869,31 @@ class RenderScene {
53006
52869
  this._boundingBox = void 0;
53007
52870
  this._memory = 0;
53008
52871
  }
53009
- get material() {
53010
- return this._material;
52872
+ get modelMaterial() {
52873
+ return this._modelMaterial;
53011
52874
  }
53012
- set material(material) {
53013
- this._material = material;
52875
+ set modelMaterial(material) {
52876
+ this._modelMaterial = material;
53014
52877
  this._vimScenes.forEach((s) => {
53015
- s.meshes.forEach((m) => {
53016
- m.mesh.material = material;
53017
- });
52878
+ s.material = material;
53018
52879
  });
52880
+ this.updateInstanceMeshVisibility();
52881
+ }
52882
+ updateInstanceMeshVisibility() {
52883
+ var _a2, _b2;
52884
+ const hide = ((_b2 = (_a2 = this._modelMaterial) == null ? void 0 : _a2[1]) == null ? void 0 : _b2.userData.isGhost) === true;
52885
+ for (const mesh of this.meshes) {
52886
+ if (mesh instanceof InstancedMesh2) {
52887
+ if (this.smallGhostThreshold <= 0) {
52888
+ mesh.mesh.visible = true;
52889
+ continue;
52890
+ }
52891
+ const visible2 = mesh.getSubmeshes().some(
52892
+ (m) => m.object.visible
52893
+ );
52894
+ mesh.mesh.visible = !(hide && !visible2 && mesh.size < this.smallGhostThreshold);
52895
+ }
52896
+ }
53019
52897
  }
53020
52898
  addScene(scene) {
53021
52899
  this._vimScenes.push(scene);
@@ -55621,7 +55499,6 @@ class RenderingSection {
55621
55499
  this.minZ.constant = -box.min.z;
55622
55500
  this.box.copy(box);
55623
55501
  this._renderer.needsUpdate = true;
55624
- this._renderer.skipAntialias = true;
55625
55502
  }
55626
55503
  /**
55627
55504
  * Determines whether objecets outside the section box will be culled or not.
@@ -56580,7 +56457,6 @@ let Renderer$1 = class Renderer {
56580
56457
  __publicField(this, "_composer");
56581
56458
  __publicField(this, "_materials");
56582
56459
  __publicField(this, "_renderText");
56583
- __publicField(this, "_skipAntialias");
56584
56460
  __publicField(this, "_needsUpdate");
56585
56461
  __publicField(this, "_onSceneUpdate", new distExports$1.SignalDispatcher());
56586
56462
  __publicField(this, "_onBoxUpdated", new distExports$1.SignalDispatcher());
@@ -56642,17 +56518,6 @@ let Renderer$1 = class Renderer {
56642
56518
  set needsUpdate(value) {
56643
56519
  this._needsUpdate = this._needsUpdate || value;
56644
56520
  }
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
56521
  /**
56657
56522
  * Removes all objects from rendering and disposes the WebGL context.
56658
56523
  */
@@ -56673,6 +56538,12 @@ let Renderer$1 = class Renderer {
56673
56538
  this._scene.scene.background = color;
56674
56539
  this.needsUpdate = true;
56675
56540
  }
56541
+ get modelMaterial() {
56542
+ return this._scene.modelMaterial;
56543
+ }
56544
+ set modelMaterial(material) {
56545
+ this._scene.modelMaterial = material;
56546
+ }
56676
56547
  /**
56677
56548
  * Signal dispatched at the end of each frame if the scene was updated, such as visibility changes.
56678
56549
  */
@@ -56697,6 +56568,12 @@ let Renderer$1 = class Renderer {
56697
56568
  this._renderText = value;
56698
56569
  this.textRenderer.domElement.style.display = value ? "block" : "none";
56699
56570
  }
56571
+ get smallGhostThreshold() {
56572
+ return this._scene.smallGhostThreshold;
56573
+ }
56574
+ set smallGhostThreshold(value) {
56575
+ this._scene.smallGhostThreshold = value;
56576
+ }
56700
56577
  /**
56701
56578
  * Returns the bounding box encompassing all rendered objects.
56702
56579
  * @param target - Box in which to copy the result. A new instance is created if undefined.
@@ -56736,7 +56613,6 @@ let Renderer$1 = class Renderer {
56736
56613
  this._composer.render();
56737
56614
  }
56738
56615
  this._needsUpdate = false;
56739
- this.skipAntialias = false;
56740
56616
  if (this.textEnabled && this._scene.has2dObjects()) {
56741
56617
  this.textRenderer.render(this._scene.scene, this._camera.three);
56742
56618
  }
@@ -57002,14 +56878,6 @@ function parseSettingsFromUrl(url) {
57002
56878
  groundColor: get3("skybox.groundColor", strToColor),
57003
56879
  sharpness: get3("skybox.sharpness", Number.parseFloat)
57004
56880
  },
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
56881
  skylight: {
57014
56882
  skyColor: get3("skylight.skyColor", strToColor),
57015
56883
  groundColor: get3("skylight.groundColor", strToColor),
@@ -57037,9 +56905,9 @@ function parseSettingsFromUrl(url) {
57037
56905
  color: get3("materials.highlight.color", strToColor),
57038
56906
  opacity: get3("materials.highlight.opacity", Number.parseFloat)
57039
56907
  },
57040
- isolation: {
57041
- color: get3("materials.isolation.color", strToColor),
57042
- opacity: get3("materials.isolation.opacity", Number.parseFloat)
56908
+ ghost: {
56909
+ color: get3("materials.ghost.color", strToColor),
56910
+ opacity: get3("materials.ghost.opacity", Number.parseFloat)
57043
56911
  },
57044
56912
  section: {
57045
56913
  strokeWidth: get3("materials.section.strokeWidth", Number.parseFloat),
@@ -59719,7 +59587,6 @@ class SocketClient {
59719
59587
  __publicField(this, "_rpcCallId", 0);
59720
59588
  __publicField(this, "_reconnectTimeout");
59721
59589
  __publicField(this, "_connectionTimeout");
59722
- __publicField(this, "_retries", -1);
59723
59590
  __publicField(this, "_validateConnection");
59724
59591
  /**
59725
59592
  * Callback function to handle incoming video frames.
@@ -59730,7 +59597,7 @@ class SocketClient {
59730
59597
  __publicField(this, "_state", { status: "disconnected" });
59731
59598
  __publicField(this, "_onStatusUpdate", new distExports.SimpleEventDispatcher());
59732
59599
  __publicField(this, "_connectPromise", new ResolvedPromise(void 0));
59733
- __publicField(this, "_connectingUrl");
59600
+ __publicField(this, "_connectionSettings");
59734
59601
  this._logger = logger;
59735
59602
  this._rpcCallId = 0;
59736
59603
  this._streamLogger = new StreamLogger(logger);
@@ -59763,7 +59630,8 @@ class SocketClient {
59763
59630
  * @returns The WebSocket URL as a string, or undefined if not set.
59764
59631
  */
59765
59632
  get url() {
59766
- return this._connectingUrl;
59633
+ var _a2;
59634
+ return (_a2 = this._connectionSettings) == null ? void 0 : _a2.url;
59767
59635
  }
59768
59636
  /**
59769
59637
  * Connects to a WebSocket server at the specified URL.
@@ -59773,7 +59641,9 @@ class SocketClient {
59773
59641
  connect(settings2) {
59774
59642
  settings2 = {
59775
59643
  url: (settings2 == null ? void 0 : settings2.url) ?? DEFAULT_LOCAL_ULTRA_SERVER_URL,
59776
- retries: (settings2 == null ? void 0 : settings2.retries) ?? 0
59644
+ retries: (settings2 == null ? void 0 : settings2.retries) ?? -1,
59645
+ timeout: (settings2 == null ? void 0 : settings2.timeout) ?? 5e3,
59646
+ retryDelay: (settings2 == null ? void 0 : settings2.retryDelay) ?? 5e3
59777
59647
  };
59778
59648
  const url = settings2.url;
59779
59649
  if (!isWebSocketUrl(url)) {
@@ -59785,17 +59655,18 @@ class SocketClient {
59785
59655
  return this._connectPromise.promise;
59786
59656
  } else {
59787
59657
  this._clearSocket();
59658
+ this._connectionSettings = void 0;
59788
59659
  this._connectPromise.reject("Connection to a different server");
59789
- this._connectPromise = new ControllablePromise();
59790
59660
  }
59791
- } else if (this._connectingUrl !== url) {
59661
+ }
59662
+ if (this.url !== url) {
59792
59663
  this._connectPromise = new ControllablePromise();
59793
- this._connectingUrl = url;
59664
+ this._connectionSettings = settings2;
59794
59665
  }
59795
59666
  this.updateState({ status: "connecting" });
59796
59667
  try {
59797
59668
  this._socket = new WebSocket(url);
59798
- this._connectionTimeout = setTimeout(() => this._onClose(), 5e3);
59669
+ this._connectionTimeout = setTimeout(() => this._onClose(), settings2.timeout);
59799
59670
  this._socket.onopen = (e) => {
59800
59671
  this._onOpen(e);
59801
59672
  };
@@ -59818,15 +59689,15 @@ class SocketClient {
59818
59689
  * Disconnects from the current WebSocket server.
59819
59690
  */
59820
59691
  disconnect(error) {
59821
- this._logger.log("Disconnecting from: ", this._connectingUrl);
59822
- this._connectingUrl = void 0;
59692
+ this._logger.log("Disconnecting from: ", this.url);
59693
+ this._connectionSettings = void 0;
59823
59694
  this._disconnect(error);
59824
59695
  }
59825
59696
  /**
59826
59697
  * Handles the disconnection logic, stopping logging and clearing the socket.
59827
59698
  */
59828
59699
  _disconnect(error) {
59829
- console.log("disconnect", error);
59700
+ this._logger.log("disconnect", error);
59830
59701
  clearTimeout(this._reconnectTimeout);
59831
59702
  clearTimeout(this._connectionTimeout);
59832
59703
  this._streamLogger.stopLogging();
@@ -59907,26 +59778,30 @@ class SocketClient {
59907
59778
  this._logger.log("Connected to: ", (_a2 = this._socket) == null ? void 0 : _a2.url);
59908
59779
  this.updateState({ status: "connected" });
59909
59780
  this._streamLogger.startLoggging();
59910
- this._connectPromise.resolve();
59781
+ this._connectPromise.resolve(true);
59911
59782
  }
59912
59783
  /**
59913
59784
  * Handler for WebSocket 'close' event.
59914
59785
  * @param _event - The event object.
59915
59786
  */
59916
59787
  _onClose(_event) {
59917
- clearTimeout(this._connectionTimeout);
59918
- this._disconnect({ status: "error", error: "connection", serverUrl: this._connectingUrl });
59788
+ const connecting = this.state.status === "connecting" || this.state.status === "validating";
59919
59789
  this._logger.log("WebSocket closed.");
59920
- if (this._retries !== 0) {
59921
- this._logger.log("Attempting to reconnect in 5 seconds");
59922
- this._reconnectTimeout = setTimeout(() => {
59923
- this.updateState({ status: "connecting" });
59924
- this.connect({
59925
- url: this._connectingUrl,
59926
- retries: this._retries - 1
59927
- });
59928
- }, 5e3);
59790
+ clearTimeout(this._connectionTimeout);
59791
+ this._disconnect({ status: "error", error: "connection", serverUrl: this.url });
59792
+ if (connecting && this._connectionSettings.retries === 0) {
59793
+ this._logger.log("No more retries left");
59794
+ this._connectPromise.resolve(false);
59795
+ return;
59929
59796
  }
59797
+ this._logger.log("Attempting to reconnect in 5 seconds");
59798
+ this._reconnectTimeout = setTimeout(() => {
59799
+ this.updateState({ status: "connecting" });
59800
+ if (connecting) {
59801
+ this._connectionSettings.retries--;
59802
+ }
59803
+ this.connect(this._connectionSettings);
59804
+ }, this._connectionSettings.retryDelay);
59930
59805
  }
59931
59806
  /**
59932
59807
  * Sends binary data over the WebSocket connection.
@@ -60299,31 +60174,6 @@ class Decoder {
60299
60174
  this._pendingFrame = frame;
60300
60175
  }
60301
60176
  }
60302
- let DeferredPromise$1 = class DeferredPromise2 extends Promise {
60303
- constructor(executor = () => {
60304
- }) {
60305
- var _a2;
60306
- let resolver;
60307
- let rejector;
60308
- super((resolve, reject) => {
60309
- resolver = resolve;
60310
- rejector = reject;
60311
- return executor(resolve, reject);
60312
- });
60313
- __publicField(this, "resolve");
60314
- __publicField(this, "reject");
60315
- __publicField(this, "initialCallStack");
60316
- this.resolve = resolver;
60317
- this.reject = rejector;
60318
- this.initialCallStack = (_a2 = Error().stack) == null ? void 0 : _a2.split("\n").slice(2).join("\n");
60319
- }
60320
- /** @throws error with amended call stack */
60321
- rejectWithError(error) {
60322
- var _a2;
60323
- error.stack = [(_a2 = error.stack) == null ? void 0 : _a2.split("\n")[0], this.initialCallStack].join("\n");
60324
- this.reject(error);
60325
- }
60326
- };
60327
60177
  class LoadSuccess {
60328
60178
  constructor(vim) {
60329
60179
  __publicField(this, "isError", false);
@@ -60346,8 +60196,8 @@ class LoadError {
60346
60196
  let LoadRequest$1 = class LoadRequest {
60347
60197
  constructor() {
60348
60198
  __publicField(this, "_progress", 0);
60349
- __publicField(this, "_progressPromise", new DeferredPromise$1());
60350
- __publicField(this, "_completionPromise", new DeferredPromise$1());
60199
+ __publicField(this, "_progressPromise", new ControllablePromise());
60200
+ __publicField(this, "_completionPromise", new ControllablePromise());
60351
60201
  __publicField(this, "_result");
60352
60202
  }
60353
60203
  get isCompleted() {
@@ -60360,18 +60210,18 @@ let LoadRequest$1 = class LoadRequest {
60360
60210
  return;
60361
60211
  }
60362
60212
  while (this._result === void 0) {
60363
- await this._progressPromise;
60213
+ await this._progressPromise.promise;
60364
60214
  yield this._progress;
60365
60215
  }
60366
60216
  }
60367
60217
  async getResult() {
60368
- await this._completionPromise;
60218
+ await this._completionPromise.promise;
60369
60219
  return this._result;
60370
60220
  }
60371
60221
  onProgress(progress) {
60372
60222
  this._progress = progress;
60373
60223
  this._progressPromise.resolve();
60374
- this._progressPromise = new DeferredPromise$1();
60224
+ this._progressPromise = new ControllablePromise();
60375
60225
  }
60376
60226
  success(vim) {
60377
60227
  this._result = new LoadSuccess(vim);
@@ -61752,7 +61602,7 @@ class Viewer2 {
61752
61602
  * @returns A promise that resolves when the connection is established.
61753
61603
  */
61754
61604
  async connect(settings2) {
61755
- await this._socketClient.connect(settings2);
61605
+ return this._socketClient.connect(settings2);
61756
61606
  }
61757
61607
  /**
61758
61608
  * Disconnects from the current VIM Ultra server.
@@ -67010,12 +66860,13 @@ function anyUiSettingButton(settings2) {
67010
66860
  return isTrue(settings2.ui.projectInspector) || isTrue(settings2.ui.settings) || isTrue(settings2.ui.help) || isTrue(settings2.ui.maximise);
67011
66861
  }
67012
66862
  const defaultSettings = {
67013
- peformance: {
67014
- useFastMaterial: false
66863
+ materials: {
66864
+ useFastMaterial: false,
66865
+ useGhostMaterial: true,
66866
+ smallGhostThreshold: 10
67015
66867
  },
67016
66868
  isolation: {
67017
- enable: true,
67018
- useIsolationMaterial: true
66869
+ enable: true
67019
66870
  },
67020
66871
  capacity: {
67021
66872
  canFollowUrl: true,
@@ -67095,7 +66946,7 @@ function AxesPanel(props) {
67095
66946
  }, []);
67096
66947
  const onIsolationBtn = () => {
67097
66948
  props.settings.update(
67098
- (s) => s.isolation.useIsolationMaterial = !s.isolation.useIsolationMaterial
66949
+ (s) => s.materials.useGhostMaterial = !s.materials.useGhostMaterial
67099
66950
  );
67100
66951
  };
67101
66952
  const onHomeBtn = () => {
@@ -67105,11 +66956,11 @@ function AxesPanel(props) {
67105
66956
  const btnIsolation = /* @__PURE__ */ jsxRuntimeExports.jsx(
67106
66957
  "button",
67107
66958
  {
67108
- "data-tip": props.settings.value.isolation.useIsolationMaterial ? "Disable Ghosting" : "Enable Ghosting",
66959
+ "data-tip": props.settings.value.materials.useGhostMaterial ? "Disable Ghosting" : "Enable Ghosting",
67109
66960
  onClick: onIsolationBtn,
67110
66961
  className: "vim-isolation-btn " + btnStyle2,
67111
66962
  type: "button",
67112
- 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" })
66963
+ 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" })
67113
66964
  }
67114
66965
  );
67115
66966
  const btnHome = /* @__PURE__ */ jsxRuntimeExports.jsxs(
@@ -67639,7 +67490,7 @@ function ControlBar(props) {
67639
67490
  id: elementIds.buttonToggleIsolation,
67640
67491
  enabled: () => isTrue(props.settings.ui.toggleIsolation),
67641
67492
  tip: "Toggle Isolation",
67642
- action: () => props.isolation.toggleIsolation("controlBar"),
67493
+ action: () => props.isolation.toggle("controlBar"),
67643
67494
  icon: toggleIsolation,
67644
67495
  style: buttonDefaultStyle
67645
67496
  }
@@ -71660,7 +71511,7 @@ function VimContextMenu(props) {
71660
71511
  };
71661
71512
  const [clipping, setClipping] = useState(isClipping());
71662
71513
  const [, setVersion] = useState(0);
71663
- const hidden2 = props.isolation.any();
71514
+ const hidden2 = props.isolation.isActive();
71664
71515
  useEffect(() => {
71665
71516
  const subState = viewer.gizmos.section.onStateChanged.subscribe(() => {
71666
71517
  setSection({
@@ -74043,31 +73894,17 @@ function MenuSettings(props) {
74043
73894
  ),
74044
73895
  settingsSubtitle("Materials"),
74045
73896
  settingsToggle(
74046
- "Use Isolation Material",
74047
- (settings2) => settings2.isolation.useIsolationMaterial,
73897
+ "Use Ghost Material",
73898
+ (settings2) => settings2.materials.useGhostMaterial,
74048
73899
  (settings2, value) => {
74049
- settings2.isolation.useIsolationMaterial = value;
74050
- if (settings2.peformance.useFastMaterial && value) {
74051
- settings2.peformance.useFastMaterial = false;
74052
- }
73900
+ settings2.materials.useGhostMaterial = value;
74053
73901
  }
74054
73902
  ),
74055
73903
  settingsToggle(
74056
73904
  "Use Performance Material",
74057
- (settings2) => settings2.peformance.useFastMaterial,
73905
+ (settings2) => settings2.materials.useFastMaterial,
74058
73906
  (settings2, value) => {
74059
- settings2.peformance.useFastMaterial = value;
74060
- if (settings2.isolation.useIsolationMaterial && value) {
74061
- settings2.isolation.useIsolationMaterial = false;
74062
- }
74063
- }
74064
- ),
74065
- settingsSubtitle("Scene"),
74066
- settingsToggle(
74067
- "Show Ground Plane",
74068
- (_) => props.viewer.environment.groundPlane.visible,
74069
- (_, value) => {
74070
- props.viewer.environment.groundPlane.visible = value;
73907
+ settings2.materials.useFastMaterial = value;
74071
73908
  }
74072
73909
  ),
74073
73910
  settingsSubtitle("Panels"),
@@ -74341,7 +74178,6 @@ class ComponentInputs {
74341
74178
  __publicField(this, "_default");
74342
74179
  __publicField(this, "_isolation");
74343
74180
  __publicField(this, "_sideState");
74344
- __publicField(this, "_help");
74345
74181
  __publicField(this, "_getSelection", () => {
74346
74182
  return [...this._viewer.selection.objects].filter(
74347
74183
  (o) => o.type === "Object3D"
@@ -74371,7 +74207,7 @@ class ComponentInputs {
74371
74207
  return true;
74372
74208
  }
74373
74209
  case KEYS.KEY_I: {
74374
- this._isolation.toggleIsolation("keyboard");
74210
+ this._isolation.toggle("keyboard");
74375
74211
  return true;
74376
74212
  }
74377
74213
  case KEYS.KEY_ESCAPE: {
@@ -74379,7 +74215,7 @@ class ComponentInputs {
74379
74215
  this._viewer.selection.clear();
74380
74216
  return true;
74381
74217
  }
74382
- if (this._isolation.any()) {
74218
+ if (this._isolation.isActive()) {
74383
74219
  this._isolation.clear("keyboard");
74384
74220
  return true;
74385
74221
  }
@@ -74461,7 +74297,6 @@ function useSettings(viewer, value) {
74461
74297
  var _a2;
74462
74298
  const next = { ...settings2 };
74463
74299
  updater(next);
74464
- validateSettings(next);
74465
74300
  saveSettingsToLocal(next);
74466
74301
  setSettings(next);
74467
74302
  (_a2 = onUpdate.current) == null ? void 0 : _a2.call(onUpdate, next);
@@ -74481,11 +74316,6 @@ function useSettings(viewer, value) {
74481
74316
  [settings2]
74482
74317
  );
74483
74318
  }
74484
- function validateSettings(settings2) {
74485
- if (settings2.peformance.useFastMaterial && settings2.isolation.useIsolationMaterial) {
74486
- settings2.peformance.useFastMaterial = false;
74487
- }
74488
- }
74489
74319
  function applySettings(viewer, settings2) {
74490
74320
  const performance2 = document.getElementsByClassName("vim-performance-div")[0];
74491
74321
  if (performance2) {
@@ -74495,240 +74325,192 @@ function applySettings(viewer, settings2) {
74495
74325
  performance2.classList.add("vc-hidden");
74496
74326
  }
74497
74327
  }
74498
- viewer.vims.forEach((v) => {
74499
- if (settings2.peformance.useFastMaterial && v.scene.material === void 0) {
74500
- v.scene.material = viewer.materials.simple;
74501
- }
74502
- if (!settings2.peformance.useFastMaterial && v.scene.material === viewer.materials.simple) {
74503
- v.scene.material = void 0;
74504
- }
74505
- });
74328
+ viewer.renderer.smallGhostThreshold = settings2.materials.smallGhostThreshold;
74506
74329
  }
74507
74330
  class Isolation {
74331
+ /**
74332
+ * Constructs an IsolationManager.
74333
+ *
74334
+ * @param viewer - The VIM Viewer responsible for managing the 3D scene and objects.
74335
+ * @param camera - A component that handles camera control and framing.
74336
+ * @param settings - The settings that control isolation and material usage.
74337
+ */
74508
74338
  constructor(viewer, camera2, settings2) {
74509
74339
  __publicField(this, "_viewer");
74510
74340
  __publicField(this, "_settings");
74511
- __publicField(this, "_isolation");
74512
- __publicField(this, "_lastIsolation");
74341
+ __publicField(this, "_isolation", []);
74513
74342
  __publicField(this, "_camera");
74514
- __publicField(this, "_references", /* @__PURE__ */ new Map());
74515
74343
  __publicField(this, "_onChanged", new distExports.SimpleEventDispatcher());
74516
74344
  this._viewer = viewer;
74517
74345
  this._camera = camera2;
74518
74346
  this.applySettings(settings2);
74519
74347
  }
74520
- /** Signal dispatched when the isolation set changes. */
74348
+ /**
74349
+ * An event that is dispatched whenever the isolation set changes.
74350
+ *
74351
+ * @remarks
74352
+ * This can be used by other parts of the application to react to isolation
74353
+ * updates (for example, updating UI or triggering additional viewport actions).
74354
+ *
74355
+ * @returns {ISimpleEvent<string>} Event interface for subscribing to isolation changes.
74356
+ */
74521
74357
  get onChanged() {
74522
74358
  return this._onChanged.asEvent();
74523
74359
  }
74524
74360
  /**
74525
- * Applies relevant settings to isolation.
74526
- * @param settings The settings to be applied to isolation.
74361
+ * Applies relevant settings to the isolation behavior.
74362
+ *
74363
+ * @param settings - The new settings to apply.
74364
+ *
74365
+ * @remarks
74366
+ * This updates the internal reference to settings and immediately sets
74367
+ * the material based on whether isolation is currently active.
74527
74368
  */
74528
74369
  applySettings(settings2) {
74529
- var _a2;
74530
74370
  this._settings = settings2;
74531
74371
  if (!this._settings.isolation.enable) return;
74532
- const set3 = new Set((_a2 = this._isolation) == null ? void 0 : _a2.map((o) => o.vim));
74533
- this._viewer.vims.forEach((v) => {
74534
- v.scene.material = this.getMaterial(this._settings, set3.has(v));
74535
- });
74536
- }
74537
- /**
74538
- * Sets the reference objects for a given VIM.
74539
- * @param vim The VIM for which reference objects are being set.
74540
- * @param reference An array of reference objects or the string 'always' to indicate permanent reference.
74541
- */
74542
- setReference(vim, reference) {
74543
- const value = reference === "always" ? reference : new Set(reference);
74544
- this._references.set(vim, value);
74545
- }
74546
- /**
74547
- * Retrieves the reference objects set for a given VIM.
74548
- * @param vim The VIM for which reference objects are being retrieved.
74549
- * @returns The reference objects set for the specified VIM.
74550
- */
74551
- getReference(vim) {
74552
- return this._references.get(vim);
74372
+ this._viewer.renderer.modelMaterial = this.getMaterial(this._settings, this.isActive());
74553
74373
  }
74554
74374
  /**
74555
- * Clears all reference objects set for VIMs.
74375
+ * Checks if isolation is currently active (i.e., any objects are isolated).
74376
+ *
74377
+ * @returns True if isolation is active; otherwise, false.
74556
74378
  */
74557
- clearReferences() {
74558
- this._references.clear();
74559
- }
74560
- /**
74561
- * Returns true if there are currently objects isolated.
74562
- * @returns True if there are currently objects isolated; otherwise, false.
74563
- */
74564
- any() {
74565
- return this._isolation !== void 0;
74379
+ isActive() {
74380
+ return this._isolation.length > 0;
74566
74381
  }
74567
74382
  /**
74568
- * Returns the current array of isolated objects.
74569
- * @returns The array of objects currently isolated, or undefined if no objects are isolated.
74383
+ * Retrieves the current array of isolated objects.
74384
+ *
74385
+ * @returns An array of isolated objects, or undefined if isolation is not active.
74570
74386
  */
74571
74387
  current() {
74572
74388
  return this._isolation;
74573
74389
  }
74574
74390
  /**
74575
- * Isolates the objects in the given array and shows the rest as ghost.
74576
- * @param objects An array of objects to isolate.
74577
- * @param source The source of isolation.
74578
- * @returns True if isolation occurs; otherwise, false.
74391
+ * Sets the specified objects as isolated, hiding or ghosting the rest.
74392
+ *
74393
+ * @param objects - The objects to isolate.
74394
+ * @param source - A label or identifier indicating the source of this action (e.g., "user").
74579
74395
  */
74580
74396
  isolate(objects, source) {
74581
74397
  if (!this._settings.isolation.enable) return;
74582
- if (this._isolation) {
74583
- this._lastIsolation = this._isolation;
74584
- }
74585
- const isolated = this._isolate(this._viewer, this._settings, objects);
74586
- this._isolation = isolated ? objects : void 0;
74398
+ this._isolation = objects ?? [];
74399
+ this._apply(source);
74587
74400
  this._camera.frameVisibleObjects();
74588
- this._onChanged.dispatch(source);
74589
- return isolated;
74590
74401
  }
74591
74402
  /**
74592
- * Toggles current isolation based on selection.
74593
- * @param source The source of isolation.
74403
+ * Toggles isolation by using the current selection.
74404
+ *
74405
+ * @param source - A label or identifier for the isolation action.
74406
+ *
74407
+ * @remarks
74408
+ * This method replaces the current isolation set with whatever objects are
74409
+ * currently selected. If selection is empty, it effectively clears isolation.
74594
74410
  */
74595
- toggleIsolation(source) {
74411
+ toggle(source) {
74596
74412
  if (!this._settings.isolation.enable) return;
74597
- const selection = [...this._viewer.selection.objects].filter((o) => o.type === "Object3D");
74598
- if (this._isolation) {
74599
- this._lastIsolation = this._isolation;
74600
- }
74601
- if (this._isolation) {
74602
- if (selection.length === 0 || ArrayEquals(this._isolation, selection)) {
74603
- this._showAll();
74604
- this._isolation = void 0;
74605
- } else {
74606
- const isolated = this._isolate(this._viewer, this._settings, selection);
74607
- this._isolation = isolated ? selection : void 0;
74608
- this._camera.frameVisibleObjects();
74609
- this._viewer.selection.clear();
74610
- }
74611
- } else {
74612
- if (selection.length > 0) {
74613
- const isolated = this._isolate(this._viewer, this._settings, selection);
74614
- this._isolation = isolated ? selection : void 0;
74615
- this._camera.frameVisibleObjects();
74616
- this._viewer.selection.clear();
74617
- } else if (this._lastIsolation) {
74618
- const isolated = this._isolate(
74619
- this._viewer,
74620
- this._settings,
74621
- this._lastIsolation
74622
- );
74623
- this._isolation = isolated ? [...this._lastIsolation] : void 0;
74624
- }
74625
- }
74626
- this._onChanged.dispatch(source);
74413
+ this._isolation = [...this._viewer.selection.objects].filter((o) => o.type === "Object3D");
74414
+ this._apply(source);
74415
+ this._camera.frameVisibleObjects();
74416
+ this._viewer.selection.clear();
74627
74417
  }
74628
74418
  /**
74629
- * Removes the given objects from the isolation set.
74630
- * @param objects An array of objects to be removed from isolation.
74631
- * @param source The source of the removal operation.
74419
+ * Hides the specified objects from the isolation set.
74420
+ *
74421
+ * @param objects - The objects to hide.
74422
+ * @param source - A label or identifier for the isolation action.
74423
+ *
74424
+ * @remarks
74425
+ * If there is no active isolation set (i.e., all objects are visible),
74426
+ * the method first treats all objects in the scene as isolated,
74427
+ * and then removes the specified objects. This ensures the specified
74428
+ * objects become hidden.
74632
74429
  */
74633
74430
  hide(objects, source) {
74634
74431
  if (!this._settings.isolation.enable) return;
74635
- const selection = new Set(objects);
74636
- const initial = this._isolation ?? this._viewer.vims[0].getObjects();
74637
- const result = [];
74638
- for (const obj of initial) {
74639
- if (!selection.has(obj)) result.push(obj);
74640
- }
74641
- const isolated = this._isolate(this._viewer, this._settings, result);
74642
- this._isolation = isolated ? result : void 0;
74643
- this._onChanged.dispatch(source);
74432
+ this._isolation = this._isolation.length === 0 ? this.getAllObjects() : this._isolation;
74433
+ this._isolation = this._isolation.filter((o) => !objects.includes(o));
74434
+ this._apply(source);
74644
74435
  objects.forEach((o) => this._viewer.selection.remove(o));
74645
74436
  }
74646
74437
  /**
74647
- * Adds the given objects to the isolation set.
74648
- * @param objects An array of objects to be added to isolation.
74649
- * @param source The source of the addition operation.
74438
+ * Adds the specified objects to the current isolation set (making them visible).
74439
+ *
74440
+ * @param objects - The objects to show.
74441
+ * @param source - A label or identifier for the isolation action.
74650
74442
  */
74651
74443
  show(objects, source) {
74652
74444
  if (!this._settings.isolation.enable) return;
74653
- const isolation = this._isolation ?? [];
74654
- objects.forEach((o) => isolation.push(o));
74655
- const result = [...new Set(isolation)];
74656
- const isolated = this._isolate(this._viewer, this._settings, result);
74657
- this._isolation = isolated ? result : void 0;
74658
- this._onChanged.dispatch(source);
74445
+ objects.forEach((o) => this._isolation.push(o));
74446
+ this._apply(source);
74659
74447
  }
74660
74448
  /**
74661
- * Clears the current isolation.
74662
- * @param source The source of the isolation clearing operation.
74449
+ * Clears the current isolation set, making all objects visible.
74450
+ *
74451
+ * @param source - A label or identifier for the isolation action.
74663
74452
  */
74664
74453
  clear(source) {
74665
74454
  if (!this._settings.isolation.enable) return;
74666
- this._showAll();
74667
- this._lastIsolation = this._isolation;
74668
- this._isolation = void 0;
74669
- this._onChanged.dispatch(source);
74455
+ this._isolation.length = 0;
74456
+ this._apply(source);
74670
74457
  }
74671
74458
  /**
74672
- * Show all objects and quit isolation mode.
74459
+ * Constructs the correct material (or array of materials) based on the given settings.
74460
+ *
74461
+ * @param settings - The current component settings, including isolation rules.
74462
+ * @param isolate - Whether or not isolation is active.
74463
+ * @returns The material(s) to assign to the renderer, or undefined if default materials should be used.
74464
+ *
74465
+ * @remarks
74466
+ * - If isolation is active and `useGhostMaterial` is true, an array containing
74467
+ * the simple and ghost materials is returned.
74468
+ * - If fast materials are enabled, the simple material is returned.
74469
+ * - Otherwise, defaults to undefined, allowing the system to pick a standard material.
74673
74470
  */
74674
- _showAll() {
74675
- this._viewer.vims.forEach((v) => {
74676
- for (const obj of v.getObjects()) {
74677
- obj.visible = true;
74678
- }
74679
- v.scene.material = this.getMaterial(this._settings, false);
74680
- });
74681
- }
74682
74471
  getMaterial(settings2, isolate) {
74683
- if (settings2.peformance.useFastMaterial) {
74684
- return this._viewer.materials.simple;
74472
+ if (isolate && settings2.materials.useGhostMaterial) {
74473
+ return [this._viewer.materials.simple, this._viewer.materials.ghost];
74685
74474
  }
74686
- if (!settings2.isolation.useIsolationMaterial) {
74687
- return void 0;
74688
- }
74689
- if (!isolate) {
74690
- return void 0;
74475
+ if (settings2.materials.useFastMaterial) {
74476
+ return this._viewer.materials.simple;
74691
74477
  }
74692
- return this._viewer.materials.isolation;
74478
+ return void 0;
74693
74479
  }
74694
- _isolate(viewer, settings2, objects) {
74695
- let useIsolation = false;
74696
- if (!objects) {
74697
- this._showAll();
74698
- } else {
74699
- const set3 = new Set(objects);
74700
- let all = true;
74701
- viewer.vims.forEach((vim) => {
74702
- for (const obj of vim.getObjects()) {
74703
- if (obj.hasMesh) {
74704
- obj.visible = set3.has(obj);
74705
- all = all && obj.visible;
74706
- }
74707
- }
74708
- const reference = this._references.get(vim);
74709
- if (reference === void 0) {
74710
- useIsolation = !all;
74711
- } else if (reference === "always") {
74712
- useIsolation = true;
74713
- } else {
74714
- useIsolation = !setsEqual(reference, set3);
74480
+ /**
74481
+ * Applies the current isolation state: sets visibility for objects, updates materials,
74482
+ * and dispatches the changed event.
74483
+ *
74484
+ * @param source - A label or identifier for the isolation action.
74485
+ */
74486
+ _apply(source) {
74487
+ let all = true;
74488
+ let any = false;
74489
+ const set3 = this._isolation.length > 0 ? new Set(this._isolation) : void 0;
74490
+ this._viewer.vims.forEach((vim) => {
74491
+ for (const obj of vim.getObjects()) {
74492
+ if (obj.hasMesh) {
74493
+ obj.visible = (set3 == null ? void 0 : set3.has(obj)) ?? true;
74494
+ all = all && obj.visible;
74495
+ any = any || obj.visible;
74715
74496
  }
74716
- vim.scene.material = this.getMaterial(this._settings, useIsolation);
74717
- });
74718
- }
74719
- return useIsolation;
74720
- }
74721
- }
74722
- function setsEqual(set1, set22) {
74723
- if (set1.size !== set22.size) {
74724
- return false;
74497
+ }
74498
+ });
74499
+ this._viewer.renderer.modelMaterial = this.getMaterial(this._settings, any && !all);
74500
+ this._onChanged.dispatch(source);
74725
74501
  }
74726
- for (const item of set1) {
74727
- if (!set22.has(item)) {
74728
- return false;
74729
- }
74502
+ /**
74503
+ * Gathers all objects from all loaded VIM instances.
74504
+ *
74505
+ * @returns An array of all objects within the loaded VIM scenes.
74506
+ */
74507
+ getAllObjects() {
74508
+ let objects = [];
74509
+ this._viewer.vims.forEach((vim) => {
74510
+ objects = objects.concat(vim.getObjects());
74511
+ });
74512
+ return objects;
74730
74513
  }
74731
- return true;
74732
74514
  }
74733
74515
  class ComponentCamera {
74734
74516
  constructor(viewer) {
@@ -74995,7 +74777,7 @@ const bimInfoData = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineP
74995
74777
  __proto__: null,
74996
74778
  useBimInfo
74997
74779
  }, Symbol.toStringTag, { value: "Module" }));
74998
- class DeferredPromise3 extends Promise {
74780
+ class DeferredPromise2 extends Promise {
74999
74781
  constructor(executor = () => {
75000
74782
  }) {
75001
74783
  var _a2;
@@ -75026,9 +74808,9 @@ class LoadRequest2 {
75026
74808
  __publicField(this, "_callbacks");
75027
74809
  __publicField(this, "_request");
75028
74810
  __publicField(this, "_progress", { loaded: 0, total: 0, all: /* @__PURE__ */ new Map() });
75029
- __publicField(this, "_progressPromise", new DeferredPromise3());
74811
+ __publicField(this, "_progressPromise", new DeferredPromise2());
75030
74812
  __publicField(this, "_isDone", false);
75031
- __publicField(this, "_completionPromise", new DeferredPromise3());
74813
+ __publicField(this, "_completionPromise", new DeferredPromise2());
75032
74814
  this.source = source;
75033
74815
  this._callbacks = callbacks;
75034
74816
  this.startRequest(source, settings2);
@@ -75049,7 +74831,7 @@ class LoadRequest2 {
75049
74831
  this._callbacks.onProgress(progress);
75050
74832
  this._progress = progress;
75051
74833
  this._progressPromise.resolve();
75052
- this._progressPromise = new DeferredPromise3();
74834
+ this._progressPromise = new DeferredPromise2();
75053
74835
  }
75054
74836
  onSuccess() {
75055
74837
  this._callbacks.onDone();
@@ -75409,7 +75191,7 @@ function setComponentBehind(value) {
75409
75191
  }
75410
75192
  }
75411
75193
  function createWebglComponent(container, componentSettings = {}, viewerSettings = {}) {
75412
- const promise2 = new DeferredPromise3();
75194
+ const promise2 = new DeferredPromise2();
75413
75195
  const cmpContainer = container instanceof HTMLElement ? createContainer(container) : container ?? createContainer();
75414
75196
  const viewer = new Viewer$1(viewerSettings);
75415
75197
  viewer.viewport.reparent(cmpContainer.gfx);
@@ -75872,7 +75654,7 @@ function getRequestErrorMessage(source, error) {
75872
75654
  }
75873
75655
  }
75874
75656
  function createUltraComponent(container) {
75875
- const promise2 = new DeferredPromise3();
75657
+ const promise2 = new DeferredPromise2();
75876
75658
  const cmpContainer = container instanceof HTMLElement ? createContainer(container) : container ?? createContainer();
75877
75659
  const viewer = Viewer2.createWithCanvas(cmpContainer.gfx);
75878
75660
  const reactRoot = clientExports.createRoot(cmpContainer.ui);