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

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 +343 -560
  19. package/dist/vim-web.iife.js.map +1 -1
  20. package/dist/vim-web.js +349 -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() {
@@ -52957,6 +52820,7 @@ class RenderScene {
52957
52820
  add(target) {
52958
52821
  if (target instanceof Scene2) {
52959
52822
  this.addScene(target);
52823
+ target.material = this._modelMaterial;
52960
52824
  return;
52961
52825
  }
52962
52826
  this._2dCount += this.count2dObjects(target);
@@ -53006,16 +52870,31 @@ class RenderScene {
53006
52870
  this._boundingBox = void 0;
53007
52871
  this._memory = 0;
53008
52872
  }
53009
- get material() {
53010
- return this._material;
52873
+ get modelMaterial() {
52874
+ return this._modelMaterial;
53011
52875
  }
53012
- set material(material) {
53013
- this._material = material;
52876
+ set modelMaterial(material) {
52877
+ this._modelMaterial = material;
53014
52878
  this._vimScenes.forEach((s) => {
53015
- s.meshes.forEach((m) => {
53016
- m.mesh.material = material;
53017
- });
52879
+ s.material = material;
53018
52880
  });
52881
+ this.updateInstanceMeshVisibility();
52882
+ }
52883
+ updateInstanceMeshVisibility() {
52884
+ var _a2, _b2;
52885
+ const hide = ((_b2 = (_a2 = this._modelMaterial) == null ? void 0 : _a2[1]) == null ? void 0 : _b2.userData.isGhost) === true;
52886
+ for (const mesh of this.meshes) {
52887
+ if (mesh instanceof InstancedMesh2) {
52888
+ if (this.smallGhostThreshold <= 0) {
52889
+ mesh.mesh.visible = true;
52890
+ continue;
52891
+ }
52892
+ const visible2 = mesh.getSubmeshes().some(
52893
+ (m) => m.object.visible
52894
+ );
52895
+ mesh.mesh.visible = !(hide && !visible2 && mesh.size < this.smallGhostThreshold);
52896
+ }
52897
+ }
53019
52898
  }
53020
52899
  addScene(scene) {
53021
52900
  this._vimScenes.push(scene);
@@ -55621,7 +55500,6 @@ class RenderingSection {
55621
55500
  this.minZ.constant = -box.min.z;
55622
55501
  this.box.copy(box);
55623
55502
  this._renderer.needsUpdate = true;
55624
- this._renderer.skipAntialias = true;
55625
55503
  }
55626
55504
  /**
55627
55505
  * Determines whether objecets outside the section box will be culled or not.
@@ -56580,7 +56458,6 @@ let Renderer$1 = class Renderer {
56580
56458
  __publicField(this, "_composer");
56581
56459
  __publicField(this, "_materials");
56582
56460
  __publicField(this, "_renderText");
56583
- __publicField(this, "_skipAntialias");
56584
56461
  __publicField(this, "_needsUpdate");
56585
56462
  __publicField(this, "_onSceneUpdate", new distExports$1.SignalDispatcher());
56586
56463
  __publicField(this, "_onBoxUpdated", new distExports$1.SignalDispatcher());
@@ -56642,17 +56519,6 @@ let Renderer$1 = class Renderer {
56642
56519
  set needsUpdate(value) {
56643
56520
  this._needsUpdate = this._needsUpdate || value;
56644
56521
  }
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
56522
  /**
56657
56523
  * Removes all objects from rendering and disposes the WebGL context.
56658
56524
  */
@@ -56673,6 +56539,12 @@ let Renderer$1 = class Renderer {
56673
56539
  this._scene.scene.background = color;
56674
56540
  this.needsUpdate = true;
56675
56541
  }
56542
+ get modelMaterial() {
56543
+ return this._scene.modelMaterial;
56544
+ }
56545
+ set modelMaterial(material) {
56546
+ this._scene.modelMaterial = material;
56547
+ }
56676
56548
  /**
56677
56549
  * Signal dispatched at the end of each frame if the scene was updated, such as visibility changes.
56678
56550
  */
@@ -56697,6 +56569,12 @@ let Renderer$1 = class Renderer {
56697
56569
  this._renderText = value;
56698
56570
  this.textRenderer.domElement.style.display = value ? "block" : "none";
56699
56571
  }
56572
+ get smallGhostThreshold() {
56573
+ return this._scene.smallGhostThreshold;
56574
+ }
56575
+ set smallGhostThreshold(value) {
56576
+ this._scene.smallGhostThreshold = value;
56577
+ }
56700
56578
  /**
56701
56579
  * Returns the bounding box encompassing all rendered objects.
56702
56580
  * @param target - Box in which to copy the result. A new instance is created if undefined.
@@ -56736,7 +56614,6 @@ let Renderer$1 = class Renderer {
56736
56614
  this._composer.render();
56737
56615
  }
56738
56616
  this._needsUpdate = false;
56739
- this.skipAntialias = false;
56740
56617
  if (this.textEnabled && this._scene.has2dObjects()) {
56741
56618
  this.textRenderer.render(this._scene.scene, this._camera.three);
56742
56619
  }
@@ -57002,14 +56879,6 @@ function parseSettingsFromUrl(url) {
57002
56879
  groundColor: get3("skybox.groundColor", strToColor),
57003
56880
  sharpness: get3("skybox.sharpness", Number.parseFloat)
57004
56881
  },
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
56882
  skylight: {
57014
56883
  skyColor: get3("skylight.skyColor", strToColor),
57015
56884
  groundColor: get3("skylight.groundColor", strToColor),
@@ -57037,9 +56906,9 @@ function parseSettingsFromUrl(url) {
57037
56906
  color: get3("materials.highlight.color", strToColor),
57038
56907
  opacity: get3("materials.highlight.opacity", Number.parseFloat)
57039
56908
  },
57040
- isolation: {
57041
- color: get3("materials.isolation.color", strToColor),
57042
- opacity: get3("materials.isolation.opacity", Number.parseFloat)
56909
+ ghost: {
56910
+ color: get3("materials.ghost.color", strToColor),
56911
+ opacity: get3("materials.ghost.opacity", Number.parseFloat)
57043
56912
  },
57044
56913
  section: {
57045
56914
  strokeWidth: get3("materials.section.strokeWidth", Number.parseFloat),
@@ -59719,7 +59588,6 @@ class SocketClient {
59719
59588
  __publicField(this, "_rpcCallId", 0);
59720
59589
  __publicField(this, "_reconnectTimeout");
59721
59590
  __publicField(this, "_connectionTimeout");
59722
- __publicField(this, "_retries", -1);
59723
59591
  __publicField(this, "_validateConnection");
59724
59592
  /**
59725
59593
  * Callback function to handle incoming video frames.
@@ -59730,7 +59598,7 @@ class SocketClient {
59730
59598
  __publicField(this, "_state", { status: "disconnected" });
59731
59599
  __publicField(this, "_onStatusUpdate", new distExports.SimpleEventDispatcher());
59732
59600
  __publicField(this, "_connectPromise", new ResolvedPromise(void 0));
59733
- __publicField(this, "_connectingUrl");
59601
+ __publicField(this, "_connectionSettings");
59734
59602
  this._logger = logger;
59735
59603
  this._rpcCallId = 0;
59736
59604
  this._streamLogger = new StreamLogger(logger);
@@ -59763,7 +59631,8 @@ class SocketClient {
59763
59631
  * @returns The WebSocket URL as a string, or undefined if not set.
59764
59632
  */
59765
59633
  get url() {
59766
- return this._connectingUrl;
59634
+ var _a2;
59635
+ return (_a2 = this._connectionSettings) == null ? void 0 : _a2.url;
59767
59636
  }
59768
59637
  /**
59769
59638
  * Connects to a WebSocket server at the specified URL.
@@ -59773,7 +59642,9 @@ class SocketClient {
59773
59642
  connect(settings2) {
59774
59643
  settings2 = {
59775
59644
  url: (settings2 == null ? void 0 : settings2.url) ?? DEFAULT_LOCAL_ULTRA_SERVER_URL,
59776
- retries: (settings2 == null ? void 0 : settings2.retries) ?? 0
59645
+ retries: (settings2 == null ? void 0 : settings2.retries) ?? -1,
59646
+ timeout: (settings2 == null ? void 0 : settings2.timeout) ?? 5e3,
59647
+ retryDelay: (settings2 == null ? void 0 : settings2.retryDelay) ?? 5e3
59777
59648
  };
59778
59649
  const url = settings2.url;
59779
59650
  if (!isWebSocketUrl(url)) {
@@ -59785,17 +59656,18 @@ class SocketClient {
59785
59656
  return this._connectPromise.promise;
59786
59657
  } else {
59787
59658
  this._clearSocket();
59659
+ this._connectionSettings = void 0;
59788
59660
  this._connectPromise.reject("Connection to a different server");
59789
- this._connectPromise = new ControllablePromise();
59790
59661
  }
59791
- } else if (this._connectingUrl !== url) {
59662
+ }
59663
+ if (this.url !== url) {
59792
59664
  this._connectPromise = new ControllablePromise();
59793
- this._connectingUrl = url;
59665
+ this._connectionSettings = settings2;
59794
59666
  }
59795
59667
  this.updateState({ status: "connecting" });
59796
59668
  try {
59797
59669
  this._socket = new WebSocket(url);
59798
- this._connectionTimeout = setTimeout(() => this._onClose(), 5e3);
59670
+ this._connectionTimeout = setTimeout(() => this._onClose(), settings2.timeout);
59799
59671
  this._socket.onopen = (e) => {
59800
59672
  this._onOpen(e);
59801
59673
  };
@@ -59818,15 +59690,15 @@ class SocketClient {
59818
59690
  * Disconnects from the current WebSocket server.
59819
59691
  */
59820
59692
  disconnect(error) {
59821
- this._logger.log("Disconnecting from: ", this._connectingUrl);
59822
- this._connectingUrl = void 0;
59693
+ this._logger.log("Disconnecting from: ", this.url);
59694
+ this._connectionSettings = void 0;
59823
59695
  this._disconnect(error);
59824
59696
  }
59825
59697
  /**
59826
59698
  * Handles the disconnection logic, stopping logging and clearing the socket.
59827
59699
  */
59828
59700
  _disconnect(error) {
59829
- console.log("disconnect", error);
59701
+ this._logger.log("disconnect", error);
59830
59702
  clearTimeout(this._reconnectTimeout);
59831
59703
  clearTimeout(this._connectionTimeout);
59832
59704
  this._streamLogger.stopLogging();
@@ -59907,26 +59779,30 @@ class SocketClient {
59907
59779
  this._logger.log("Connected to: ", (_a2 = this._socket) == null ? void 0 : _a2.url);
59908
59780
  this.updateState({ status: "connected" });
59909
59781
  this._streamLogger.startLoggging();
59910
- this._connectPromise.resolve();
59782
+ this._connectPromise.resolve(true);
59911
59783
  }
59912
59784
  /**
59913
59785
  * Handler for WebSocket 'close' event.
59914
59786
  * @param _event - The event object.
59915
59787
  */
59916
59788
  _onClose(_event) {
59917
- clearTimeout(this._connectionTimeout);
59918
- this._disconnect({ status: "error", error: "connection", serverUrl: this._connectingUrl });
59789
+ const connecting = this.state.status === "connecting" || this.state.status === "validating";
59919
59790
  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);
59791
+ clearTimeout(this._connectionTimeout);
59792
+ this._disconnect({ status: "error", error: "connection", serverUrl: this.url });
59793
+ if (connecting && this._connectionSettings.retries === 0) {
59794
+ this._logger.log("No more retries left");
59795
+ this._connectPromise.resolve(false);
59796
+ return;
59929
59797
  }
59798
+ this._logger.log("Attempting to reconnect in 5 seconds");
59799
+ this._reconnectTimeout = setTimeout(() => {
59800
+ this.updateState({ status: "connecting" });
59801
+ if (connecting) {
59802
+ this._connectionSettings.retries--;
59803
+ }
59804
+ this.connect(this._connectionSettings);
59805
+ }, this._connectionSettings.retryDelay);
59930
59806
  }
59931
59807
  /**
59932
59808
  * Sends binary data over the WebSocket connection.
@@ -60299,31 +60175,6 @@ class Decoder {
60299
60175
  this._pendingFrame = frame;
60300
60176
  }
60301
60177
  }
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
60178
  class LoadSuccess {
60328
60179
  constructor(vim) {
60329
60180
  __publicField(this, "isError", false);
@@ -60346,8 +60197,8 @@ class LoadError {
60346
60197
  let LoadRequest$1 = class LoadRequest {
60347
60198
  constructor() {
60348
60199
  __publicField(this, "_progress", 0);
60349
- __publicField(this, "_progressPromise", new DeferredPromise$1());
60350
- __publicField(this, "_completionPromise", new DeferredPromise$1());
60200
+ __publicField(this, "_progressPromise", new ControllablePromise());
60201
+ __publicField(this, "_completionPromise", new ControllablePromise());
60351
60202
  __publicField(this, "_result");
60352
60203
  }
60353
60204
  get isCompleted() {
@@ -60360,18 +60211,18 @@ let LoadRequest$1 = class LoadRequest {
60360
60211
  return;
60361
60212
  }
60362
60213
  while (this._result === void 0) {
60363
- await this._progressPromise;
60214
+ await this._progressPromise.promise;
60364
60215
  yield this._progress;
60365
60216
  }
60366
60217
  }
60367
60218
  async getResult() {
60368
- await this._completionPromise;
60219
+ await this._completionPromise.promise;
60369
60220
  return this._result;
60370
60221
  }
60371
60222
  onProgress(progress) {
60372
60223
  this._progress = progress;
60373
60224
  this._progressPromise.resolve();
60374
- this._progressPromise = new DeferredPromise$1();
60225
+ this._progressPromise = new ControllablePromise();
60375
60226
  }
60376
60227
  success(vim) {
60377
60228
  this._result = new LoadSuccess(vim);
@@ -61752,7 +61603,7 @@ class Viewer2 {
61752
61603
  * @returns A promise that resolves when the connection is established.
61753
61604
  */
61754
61605
  async connect(settings2) {
61755
- await this._socketClient.connect(settings2);
61606
+ return this._socketClient.connect(settings2);
61756
61607
  }
61757
61608
  /**
61758
61609
  * Disconnects from the current VIM Ultra server.
@@ -67010,12 +66861,13 @@ function anyUiSettingButton(settings2) {
67010
66861
  return isTrue(settings2.ui.projectInspector) || isTrue(settings2.ui.settings) || isTrue(settings2.ui.help) || isTrue(settings2.ui.maximise);
67011
66862
  }
67012
66863
  const defaultSettings = {
67013
- peformance: {
67014
- useFastMaterial: false
66864
+ materials: {
66865
+ useFastMaterial: false,
66866
+ useGhostMaterial: true,
66867
+ smallGhostThreshold: 10
67015
66868
  },
67016
66869
  isolation: {
67017
- enable: true,
67018
- useIsolationMaterial: true
66870
+ enable: true
67019
66871
  },
67020
66872
  capacity: {
67021
66873
  canFollowUrl: true,
@@ -67095,7 +66947,7 @@ function AxesPanel(props) {
67095
66947
  }, []);
67096
66948
  const onIsolationBtn = () => {
67097
66949
  props.settings.update(
67098
- (s) => s.isolation.useIsolationMaterial = !s.isolation.useIsolationMaterial
66950
+ (s) => s.materials.useGhostMaterial = !s.materials.useGhostMaterial
67099
66951
  );
67100
66952
  };
67101
66953
  const onHomeBtn = () => {
@@ -67105,11 +66957,11 @@ function AxesPanel(props) {
67105
66957
  const btnIsolation = /* @__PURE__ */ jsxRuntimeExports.jsx(
67106
66958
  "button",
67107
66959
  {
67108
- "data-tip": props.settings.value.isolation.useIsolationMaterial ? "Disable Ghosting" : "Enable Ghosting",
66960
+ "data-tip": props.settings.value.materials.useGhostMaterial ? "Disable Ghosting" : "Enable Ghosting",
67109
66961
  onClick: onIsolationBtn,
67110
66962
  className: "vim-isolation-btn " + btnStyle2,
67111
66963
  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" })
66964
+ 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
66965
  }
67114
66966
  );
67115
66967
  const btnHome = /* @__PURE__ */ jsxRuntimeExports.jsxs(
@@ -67639,7 +67491,7 @@ function ControlBar(props) {
67639
67491
  id: elementIds.buttonToggleIsolation,
67640
67492
  enabled: () => isTrue(props.settings.ui.toggleIsolation),
67641
67493
  tip: "Toggle Isolation",
67642
- action: () => props.isolation.toggleIsolation("controlBar"),
67494
+ action: () => props.isolation.toggle("controlBar"),
67643
67495
  icon: toggleIsolation,
67644
67496
  style: buttonDefaultStyle
67645
67497
  }
@@ -71660,7 +71512,7 @@ function VimContextMenu(props) {
71660
71512
  };
71661
71513
  const [clipping, setClipping] = useState(isClipping());
71662
71514
  const [, setVersion] = useState(0);
71663
- const hidden2 = props.isolation.any();
71515
+ const hidden2 = props.isolation.isActive();
71664
71516
  useEffect(() => {
71665
71517
  const subState = viewer.gizmos.section.onStateChanged.subscribe(() => {
71666
71518
  setSection({
@@ -74043,31 +73895,17 @@ function MenuSettings(props) {
74043
73895
  ),
74044
73896
  settingsSubtitle("Materials"),
74045
73897
  settingsToggle(
74046
- "Use Isolation Material",
74047
- (settings2) => settings2.isolation.useIsolationMaterial,
73898
+ "Use Ghost Material",
73899
+ (settings2) => settings2.materials.useGhostMaterial,
74048
73900
  (settings2, value) => {
74049
- settings2.isolation.useIsolationMaterial = value;
74050
- if (settings2.peformance.useFastMaterial && value) {
74051
- settings2.peformance.useFastMaterial = false;
74052
- }
73901
+ settings2.materials.useGhostMaterial = value;
74053
73902
  }
74054
73903
  ),
74055
73904
  settingsToggle(
74056
73905
  "Use Performance Material",
74057
- (settings2) => settings2.peformance.useFastMaterial,
73906
+ (settings2) => settings2.materials.useFastMaterial,
74058
73907
  (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;
73908
+ settings2.materials.useFastMaterial = value;
74071
73909
  }
74072
73910
  ),
74073
73911
  settingsSubtitle("Panels"),
@@ -74341,7 +74179,6 @@ class ComponentInputs {
74341
74179
  __publicField(this, "_default");
74342
74180
  __publicField(this, "_isolation");
74343
74181
  __publicField(this, "_sideState");
74344
- __publicField(this, "_help");
74345
74182
  __publicField(this, "_getSelection", () => {
74346
74183
  return [...this._viewer.selection.objects].filter(
74347
74184
  (o) => o.type === "Object3D"
@@ -74371,7 +74208,7 @@ class ComponentInputs {
74371
74208
  return true;
74372
74209
  }
74373
74210
  case KEYS.KEY_I: {
74374
- this._isolation.toggleIsolation("keyboard");
74211
+ this._isolation.toggle("keyboard");
74375
74212
  return true;
74376
74213
  }
74377
74214
  case KEYS.KEY_ESCAPE: {
@@ -74379,7 +74216,7 @@ class ComponentInputs {
74379
74216
  this._viewer.selection.clear();
74380
74217
  return true;
74381
74218
  }
74382
- if (this._isolation.any()) {
74219
+ if (this._isolation.isActive()) {
74383
74220
  this._isolation.clear("keyboard");
74384
74221
  return true;
74385
74222
  }
@@ -74461,7 +74298,6 @@ function useSettings(viewer, value) {
74461
74298
  var _a2;
74462
74299
  const next = { ...settings2 };
74463
74300
  updater(next);
74464
- validateSettings(next);
74465
74301
  saveSettingsToLocal(next);
74466
74302
  setSettings(next);
74467
74303
  (_a2 = onUpdate.current) == null ? void 0 : _a2.call(onUpdate, next);
@@ -74481,11 +74317,6 @@ function useSettings(viewer, value) {
74481
74317
  [settings2]
74482
74318
  );
74483
74319
  }
74484
- function validateSettings(settings2) {
74485
- if (settings2.peformance.useFastMaterial && settings2.isolation.useIsolationMaterial) {
74486
- settings2.peformance.useFastMaterial = false;
74487
- }
74488
- }
74489
74320
  function applySettings(viewer, settings2) {
74490
74321
  const performance2 = document.getElementsByClassName("vim-performance-div")[0];
74491
74322
  if (performance2) {
@@ -74495,240 +74326,192 @@ function applySettings(viewer, settings2) {
74495
74326
  performance2.classList.add("vc-hidden");
74496
74327
  }
74497
74328
  }
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
- });
74329
+ viewer.renderer.smallGhostThreshold = settings2.materials.smallGhostThreshold;
74506
74330
  }
74507
74331
  class Isolation {
74332
+ /**
74333
+ * Constructs an IsolationManager.
74334
+ *
74335
+ * @param viewer - The VIM Viewer responsible for managing the 3D scene and objects.
74336
+ * @param camera - A component that handles camera control and framing.
74337
+ * @param settings - The settings that control isolation and material usage.
74338
+ */
74508
74339
  constructor(viewer, camera2, settings2) {
74509
74340
  __publicField(this, "_viewer");
74510
74341
  __publicField(this, "_settings");
74511
- __publicField(this, "_isolation");
74512
- __publicField(this, "_lastIsolation");
74342
+ __publicField(this, "_isolation", []);
74513
74343
  __publicField(this, "_camera");
74514
- __publicField(this, "_references", /* @__PURE__ */ new Map());
74515
74344
  __publicField(this, "_onChanged", new distExports.SimpleEventDispatcher());
74516
74345
  this._viewer = viewer;
74517
74346
  this._camera = camera2;
74518
74347
  this.applySettings(settings2);
74519
74348
  }
74520
- /** Signal dispatched when the isolation set changes. */
74349
+ /**
74350
+ * An event that is dispatched whenever the isolation set changes.
74351
+ *
74352
+ * @remarks
74353
+ * This can be used by other parts of the application to react to isolation
74354
+ * updates (for example, updating UI or triggering additional viewport actions).
74355
+ *
74356
+ * @returns {ISimpleEvent<string>} Event interface for subscribing to isolation changes.
74357
+ */
74521
74358
  get onChanged() {
74522
74359
  return this._onChanged.asEvent();
74523
74360
  }
74524
74361
  /**
74525
- * Applies relevant settings to isolation.
74526
- * @param settings The settings to be applied to isolation.
74362
+ * Applies relevant settings to the isolation behavior.
74363
+ *
74364
+ * @param settings - The new settings to apply.
74365
+ *
74366
+ * @remarks
74367
+ * This updates the internal reference to settings and immediately sets
74368
+ * the material based on whether isolation is currently active.
74527
74369
  */
74528
74370
  applySettings(settings2) {
74529
- var _a2;
74530
74371
  this._settings = settings2;
74531
74372
  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);
74373
+ this._viewer.renderer.modelMaterial = this.getMaterial(this._settings, this.isActive());
74553
74374
  }
74554
74375
  /**
74555
- * Clears all reference objects set for VIMs.
74376
+ * Checks if isolation is currently active (i.e., any objects are isolated).
74377
+ *
74378
+ * @returns True if isolation is active; otherwise, false.
74556
74379
  */
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;
74380
+ isActive() {
74381
+ return this._isolation.length > 0;
74566
74382
  }
74567
74383
  /**
74568
- * Returns the current array of isolated objects.
74569
- * @returns The array of objects currently isolated, or undefined if no objects are isolated.
74384
+ * Retrieves the current array of isolated objects.
74385
+ *
74386
+ * @returns An array of isolated objects, or undefined if isolation is not active.
74570
74387
  */
74571
74388
  current() {
74572
74389
  return this._isolation;
74573
74390
  }
74574
74391
  /**
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.
74392
+ * Sets the specified objects as isolated, hiding or ghosting the rest.
74393
+ *
74394
+ * @param objects - The objects to isolate.
74395
+ * @param source - A label or identifier indicating the source of this action (e.g., "user").
74579
74396
  */
74580
74397
  isolate(objects, source) {
74581
74398
  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;
74399
+ this._isolation = objects ?? [];
74400
+ this._apply(source);
74587
74401
  this._camera.frameVisibleObjects();
74588
- this._onChanged.dispatch(source);
74589
- return isolated;
74590
74402
  }
74591
74403
  /**
74592
- * Toggles current isolation based on selection.
74593
- * @param source The source of isolation.
74404
+ * Toggles isolation by using the current selection.
74405
+ *
74406
+ * @param source - A label or identifier for the isolation action.
74407
+ *
74408
+ * @remarks
74409
+ * This method replaces the current isolation set with whatever objects are
74410
+ * currently selected. If selection is empty, it effectively clears isolation.
74594
74411
  */
74595
- toggleIsolation(source) {
74412
+ toggle(source) {
74596
74413
  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);
74414
+ this._isolation = [...this._viewer.selection.objects].filter((o) => o.type === "Object3D");
74415
+ this._apply(source);
74416
+ this._camera.frameVisibleObjects();
74417
+ this._viewer.selection.clear();
74627
74418
  }
74628
74419
  /**
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.
74420
+ * Hides the specified objects from the isolation set.
74421
+ *
74422
+ * @param objects - The objects to hide.
74423
+ * @param source - A label or identifier for the isolation action.
74424
+ *
74425
+ * @remarks
74426
+ * If there is no active isolation set (i.e., all objects are visible),
74427
+ * the method first treats all objects in the scene as isolated,
74428
+ * and then removes the specified objects. This ensures the specified
74429
+ * objects become hidden.
74632
74430
  */
74633
74431
  hide(objects, source) {
74634
74432
  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);
74433
+ this._isolation = this._isolation.length === 0 ? this.getAllObjects() : this._isolation;
74434
+ this._isolation = this._isolation.filter((o) => !objects.includes(o));
74435
+ this._apply(source);
74644
74436
  objects.forEach((o) => this._viewer.selection.remove(o));
74645
74437
  }
74646
74438
  /**
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.
74439
+ * Adds the specified objects to the current isolation set (making them visible).
74440
+ *
74441
+ * @param objects - The objects to show.
74442
+ * @param source - A label or identifier for the isolation action.
74650
74443
  */
74651
74444
  show(objects, source) {
74652
74445
  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);
74446
+ objects.forEach((o) => this._isolation.push(o));
74447
+ this._apply(source);
74659
74448
  }
74660
74449
  /**
74661
- * Clears the current isolation.
74662
- * @param source The source of the isolation clearing operation.
74450
+ * Clears the current isolation set, making all objects visible.
74451
+ *
74452
+ * @param source - A label or identifier for the isolation action.
74663
74453
  */
74664
74454
  clear(source) {
74665
74455
  if (!this._settings.isolation.enable) return;
74666
- this._showAll();
74667
- this._lastIsolation = this._isolation;
74668
- this._isolation = void 0;
74669
- this._onChanged.dispatch(source);
74456
+ this._isolation.length = 0;
74457
+ this._apply(source);
74670
74458
  }
74671
74459
  /**
74672
- * Show all objects and quit isolation mode.
74460
+ * Constructs the correct material (or array of materials) based on the given settings.
74461
+ *
74462
+ * @param settings - The current component settings, including isolation rules.
74463
+ * @param isolate - Whether or not isolation is active.
74464
+ * @returns The material(s) to assign to the renderer, or undefined if default materials should be used.
74465
+ *
74466
+ * @remarks
74467
+ * - If isolation is active and `useGhostMaterial` is true, an array containing
74468
+ * the simple and ghost materials is returned.
74469
+ * - If fast materials are enabled, the simple material is returned.
74470
+ * - Otherwise, defaults to undefined, allowing the system to pick a standard material.
74673
74471
  */
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
74472
  getMaterial(settings2, isolate) {
74683
- if (settings2.peformance.useFastMaterial) {
74684
- return this._viewer.materials.simple;
74473
+ if (isolate && settings2.materials.useGhostMaterial) {
74474
+ return [this._viewer.materials.simple, this._viewer.materials.ghost];
74685
74475
  }
74686
- if (!settings2.isolation.useIsolationMaterial) {
74687
- return void 0;
74688
- }
74689
- if (!isolate) {
74690
- return void 0;
74476
+ if (settings2.materials.useFastMaterial) {
74477
+ return this._viewer.materials.simple;
74691
74478
  }
74692
- return this._viewer.materials.isolation;
74479
+ return void 0;
74693
74480
  }
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);
74481
+ /**
74482
+ * Applies the current isolation state: sets visibility for objects, updates materials,
74483
+ * and dispatches the changed event.
74484
+ *
74485
+ * @param source - A label or identifier for the isolation action.
74486
+ */
74487
+ _apply(source) {
74488
+ let all = true;
74489
+ let any = false;
74490
+ const set3 = this._isolation.length > 0 ? new Set(this._isolation) : void 0;
74491
+ this._viewer.vims.forEach((vim) => {
74492
+ for (const obj of vim.getObjects()) {
74493
+ if (obj.hasMesh) {
74494
+ obj.visible = (set3 == null ? void 0 : set3.has(obj)) ?? true;
74495
+ all = all && obj.visible;
74496
+ any = any || obj.visible;
74715
74497
  }
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;
74498
+ }
74499
+ });
74500
+ this._viewer.renderer.modelMaterial = this.getMaterial(this._settings, any && !all);
74501
+ this._onChanged.dispatch(source);
74725
74502
  }
74726
- for (const item of set1) {
74727
- if (!set22.has(item)) {
74728
- return false;
74729
- }
74503
+ /**
74504
+ * Gathers all objects from all loaded VIM instances.
74505
+ *
74506
+ * @returns An array of all objects within the loaded VIM scenes.
74507
+ */
74508
+ getAllObjects() {
74509
+ let objects = [];
74510
+ this._viewer.vims.forEach((vim) => {
74511
+ objects = objects.concat(vim.getObjects());
74512
+ });
74513
+ return objects;
74730
74514
  }
74731
- return true;
74732
74515
  }
74733
74516
  class ComponentCamera {
74734
74517
  constructor(viewer) {
@@ -74995,7 +74778,7 @@ const bimInfoData = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineP
74995
74778
  __proto__: null,
74996
74779
  useBimInfo
74997
74780
  }, Symbol.toStringTag, { value: "Module" }));
74998
- class DeferredPromise3 extends Promise {
74781
+ class DeferredPromise2 extends Promise {
74999
74782
  constructor(executor = () => {
75000
74783
  }) {
75001
74784
  var _a2;
@@ -75026,9 +74809,9 @@ class LoadRequest2 {
75026
74809
  __publicField(this, "_callbacks");
75027
74810
  __publicField(this, "_request");
75028
74811
  __publicField(this, "_progress", { loaded: 0, total: 0, all: /* @__PURE__ */ new Map() });
75029
- __publicField(this, "_progressPromise", new DeferredPromise3());
74812
+ __publicField(this, "_progressPromise", new DeferredPromise2());
75030
74813
  __publicField(this, "_isDone", false);
75031
- __publicField(this, "_completionPromise", new DeferredPromise3());
74814
+ __publicField(this, "_completionPromise", new DeferredPromise2());
75032
74815
  this.source = source;
75033
74816
  this._callbacks = callbacks;
75034
74817
  this.startRequest(source, settings2);
@@ -75049,7 +74832,7 @@ class LoadRequest2 {
75049
74832
  this._callbacks.onProgress(progress);
75050
74833
  this._progress = progress;
75051
74834
  this._progressPromise.resolve();
75052
- this._progressPromise = new DeferredPromise3();
74835
+ this._progressPromise = new DeferredPromise2();
75053
74836
  }
75054
74837
  onSuccess() {
75055
74838
  this._callbacks.onDone();
@@ -75409,7 +75192,7 @@ function setComponentBehind(value) {
75409
75192
  }
75410
75193
  }
75411
75194
  function createWebglComponent(container, componentSettings = {}, viewerSettings = {}) {
75412
- const promise2 = new DeferredPromise3();
75195
+ const promise2 = new DeferredPromise2();
75413
75196
  const cmpContainer = container instanceof HTMLElement ? createContainer(container) : container ?? createContainer();
75414
75197
  const viewer = new Viewer$1(viewerSettings);
75415
75198
  viewer.viewport.reparent(cmpContainer.gfx);
@@ -75872,7 +75655,7 @@ function getRequestErrorMessage(source, error) {
75872
75655
  }
75873
75656
  }
75874
75657
  function createUltraComponent(container) {
75875
- const promise2 = new DeferredPromise3();
75658
+ const promise2 = new DeferredPromise2();
75876
75659
  const cmpContainer = container instanceof HTMLElement ? createContainer(container) : container ?? createContainer();
75877
75660
  const viewer = Viewer2.createWithCanvas(cmpContainer.gfx);
75878
75661
  const reactRoot = clientExports.createRoot(cmpContainer.ui);