vim-web 0.3.42 → 0.3.44-dev.0

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 (46) hide show
  1. package/dist/types/core-viewers/ultra/index.d.ts +1 -1
  2. package/dist/types/core-viewers/ultra/viewer/camera.d.ts +1 -13
  3. package/dist/types/core-viewers/ultra/viewer/marshal.d.ts +37 -24
  4. package/dist/types/core-viewers/ultra/viewer/rpcClient.d.ts +9 -7
  5. package/dist/types/core-viewers/ultra/viewer/rpcSafeClient.d.ts +8 -1
  6. package/dist/types/core-viewers/ultra/viewer/sectionBox.d.ts +31 -0
  7. package/dist/types/core-viewers/ultra/viewer/socketClient.d.ts +14 -5
  8. package/dist/types/core-viewers/ultra/viewer/viewer.d.ts +7 -3
  9. package/dist/types/core-viewers/webgl/loader/materials/ghostMaterial.d.ts +16 -0
  10. package/dist/types/core-viewers/webgl/loader/materials/simpleMaterial.d.ts +10 -5
  11. package/dist/types/core-viewers/webgl/loader/materials/viewerMaterials.d.ts +9 -8
  12. package/dist/types/core-viewers/webgl/loader/mesh.d.ts +2 -1
  13. package/dist/types/core-viewers/webgl/loader/progressive/insertableMesh.d.ts +2 -1
  14. package/dist/types/core-viewers/webgl/loader/progressive/instancedMesh.d.ts +3 -1
  15. package/dist/types/core-viewers/webgl/loader/scene.d.ts +3 -2
  16. package/dist/types/core-viewers/webgl/viewer/camera/ICamera.d.ts +102 -0
  17. package/dist/types/core-viewers/webgl/viewer/environment/cameraLight.d.ts +1 -1
  18. package/dist/types/core-viewers/webgl/viewer/environment/environment.d.ts +1 -7
  19. package/dist/types/core-viewers/webgl/viewer/environment/skybox.d.ts +1 -1
  20. package/dist/types/core-viewers/webgl/viewer/gizmos/sectionBox/SectionBoxMesh.d.ts +15 -0
  21. package/dist/types/core-viewers/webgl/viewer/gizmos/sectionBox/sectionBox.d.ts +55 -21
  22. package/dist/types/core-viewers/webgl/viewer/gizmos/sectionBox/sectionBoxGizmo.d.ts +13 -43
  23. package/dist/types/core-viewers/webgl/viewer/gizmos/sectionBox/sectionBoxHandle.d.ts +15 -0
  24. package/dist/types/core-viewers/webgl/viewer/gizmos/sectionBox/sectionBoxHandles.d.ts +19 -0
  25. package/dist/types/core-viewers/webgl/viewer/gizmos/sectionBox/sectionBoxInputs.d.ts +143 -28
  26. package/dist/types/core-viewers/webgl/viewer/gizmos/sectionBox/sectionBoxOutline.d.ts +15 -0
  27. package/dist/types/core-viewers/webgl/viewer/inputs/input.d.ts +4 -4
  28. package/dist/types/core-viewers/webgl/viewer/rendering/renderScene.d.ts +8 -4
  29. package/dist/types/core-viewers/webgl/viewer/rendering/renderer.d.ts +5 -9
  30. package/dist/types/core-viewers/webgl/viewer/selection.d.ts +1 -0
  31. package/dist/types/core-viewers/webgl/viewer/settings/viewerSettings.d.ts +4 -39
  32. package/dist/types/core-viewers/webgl/viewer/viewer.d.ts +1 -1
  33. package/dist/types/react-viewers/helpers/inputs.d.ts +1 -2
  34. package/dist/types/react-viewers/helpers/isolation.d.ts +91 -50
  35. package/dist/types/react-viewers/settings/settings.d.ts +3 -2
  36. package/dist/vim-web.iife.js +1507 -1199
  37. package/dist/vim-web.iife.js.map +1 -1
  38. package/dist/vim-web.js +1505 -1197
  39. package/dist/vim-web.js.map +1 -1
  40. package/package.json +1 -1
  41. package/dist/types/core-viewers/webgl/images.d.ts +0 -4
  42. package/dist/types/core-viewers/webgl/loader/materials/isolationMaterial.d.ts +0 -12
  43. package/dist/types/core-viewers/webgl/viewer/environment/groundPlane.d.ts +0 -25
  44. /package/dist/types/core-viewers/webgl/viewer/inputs/{keyboard.d.ts → keyboardHandler.d.ts} +0 -0
  45. /package/dist/types/core-viewers/webgl/viewer/inputs/{mouse.d.ts → mouseHandler.d.ts} +0 -0
  46. /package/dist/types/core-viewers/webgl/viewer/inputs/{touch.d.ts → touchHandler.d.ts} +0 -0
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;
@@ -45700,9 +45701,15 @@ class Object3D2 {
45700
45701
  return this._visibleAttribute.value;
45701
45702
  }
45702
45703
  set visible(value) {
45704
+ var _a2;
45703
45705
  if (this._visibleAttribute.apply(value)) {
45704
45706
  this.vim.scene.setDirty();
45705
45707
  }
45708
+ if (value) {
45709
+ (_a2 = this._meshes) == null ? void 0 : _a2.forEach((m) => {
45710
+ m.mesh.mesh.visible = true;
45711
+ });
45712
+ }
45706
45713
  }
45707
45714
  /**
45708
45715
  * Gets or sets the display color of this object.
@@ -47141,6 +47148,154 @@ let Vim$1 = class Vim {
47141
47148
  this.scene.dispose();
47142
47149
  }
47143
47150
  };
47151
+ function mergeGeometries(geometries, useGroups = false) {
47152
+ const isIndexed = geometries[0].index !== null;
47153
+ const attributesUsed = new Set(Object.keys(geometries[0].attributes));
47154
+ const morphAttributesUsed = new Set(Object.keys(geometries[0].morphAttributes));
47155
+ const attributes = {};
47156
+ const morphAttributes = {};
47157
+ const morphTargetsRelative = geometries[0].morphTargetsRelative;
47158
+ const mergedGeometry = new BufferGeometry();
47159
+ let offset = 0;
47160
+ for (let i = 0; i < geometries.length; ++i) {
47161
+ const geometry = geometries[i];
47162
+ let attributesCount = 0;
47163
+ if (isIndexed !== (geometry.index !== null)) {
47164
+ console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index " + i + ". All geometries must have compatible attributes; make sure index attribute exists among all geometries, or in none of them.");
47165
+ return null;
47166
+ }
47167
+ for (const name in geometry.attributes) {
47168
+ if (!attributesUsed.has(name)) {
47169
+ console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index " + i + '. All geometries must have compatible attributes; make sure "' + name + '" attribute exists among all geometries, or in none of them.');
47170
+ return null;
47171
+ }
47172
+ if (attributes[name] === void 0) attributes[name] = [];
47173
+ attributes[name].push(geometry.attributes[name]);
47174
+ attributesCount++;
47175
+ }
47176
+ if (attributesCount !== attributesUsed.size) {
47177
+ console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index " + i + ". Make sure all geometries have the same number of attributes.");
47178
+ return null;
47179
+ }
47180
+ if (morphTargetsRelative !== geometry.morphTargetsRelative) {
47181
+ console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index " + i + ". .morphTargetsRelative must be consistent throughout all geometries.");
47182
+ return null;
47183
+ }
47184
+ for (const name in geometry.morphAttributes) {
47185
+ if (!morphAttributesUsed.has(name)) {
47186
+ console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index " + i + ". .morphAttributes must be consistent throughout all geometries.");
47187
+ return null;
47188
+ }
47189
+ if (morphAttributes[name] === void 0) morphAttributes[name] = [];
47190
+ morphAttributes[name].push(geometry.morphAttributes[name]);
47191
+ }
47192
+ if (useGroups) {
47193
+ let count;
47194
+ if (isIndexed) {
47195
+ count = geometry.index.count;
47196
+ } else if (geometry.attributes.position !== void 0) {
47197
+ count = geometry.attributes.position.count;
47198
+ } else {
47199
+ console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index " + i + ". The geometry must have either an index or a position attribute");
47200
+ return null;
47201
+ }
47202
+ mergedGeometry.addGroup(offset, count, i);
47203
+ offset += count;
47204
+ }
47205
+ }
47206
+ if (isIndexed) {
47207
+ let indexOffset = 0;
47208
+ const mergedIndex = [];
47209
+ for (let i = 0; i < geometries.length; ++i) {
47210
+ const index2 = geometries[i].index;
47211
+ for (let j = 0; j < index2.count; ++j) {
47212
+ mergedIndex.push(index2.getX(j) + indexOffset);
47213
+ }
47214
+ indexOffset += geometries[i].attributes.position.count;
47215
+ }
47216
+ mergedGeometry.setIndex(mergedIndex);
47217
+ }
47218
+ for (const name in attributes) {
47219
+ const mergedAttribute = mergeAttributes(attributes[name]);
47220
+ if (!mergedAttribute) {
47221
+ console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the " + name + " attribute.");
47222
+ return null;
47223
+ }
47224
+ mergedGeometry.setAttribute(name, mergedAttribute);
47225
+ }
47226
+ for (const name in morphAttributes) {
47227
+ const numMorphTargets = morphAttributes[name][0].length;
47228
+ if (numMorphTargets === 0) break;
47229
+ mergedGeometry.morphAttributes = mergedGeometry.morphAttributes || {};
47230
+ mergedGeometry.morphAttributes[name] = [];
47231
+ for (let i = 0; i < numMorphTargets; ++i) {
47232
+ const morphAttributesToMerge = [];
47233
+ for (let j = 0; j < morphAttributes[name].length; ++j) {
47234
+ morphAttributesToMerge.push(morphAttributes[name][j][i]);
47235
+ }
47236
+ const mergedMorphAttribute = mergeAttributes(morphAttributesToMerge);
47237
+ if (!mergedMorphAttribute) {
47238
+ console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the " + name + " morphAttribute.");
47239
+ return null;
47240
+ }
47241
+ mergedGeometry.morphAttributes[name].push(mergedMorphAttribute);
47242
+ }
47243
+ }
47244
+ return mergedGeometry;
47245
+ }
47246
+ function mergeAttributes(attributes) {
47247
+ let TypedArray;
47248
+ let itemSize;
47249
+ let normalized;
47250
+ let gpuType = -1;
47251
+ let arrayLength = 0;
47252
+ for (let i = 0; i < attributes.length; ++i) {
47253
+ const attribute = attributes[i];
47254
+ if (TypedArray === void 0) TypedArray = attribute.array.constructor;
47255
+ if (TypedArray !== attribute.array.constructor) {
47256
+ console.error("THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.array must be of consistent array types across matching attributes.");
47257
+ return null;
47258
+ }
47259
+ if (itemSize === void 0) itemSize = attribute.itemSize;
47260
+ if (itemSize !== attribute.itemSize) {
47261
+ console.error("THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.itemSize must be consistent across matching attributes.");
47262
+ return null;
47263
+ }
47264
+ if (normalized === void 0) normalized = attribute.normalized;
47265
+ if (normalized !== attribute.normalized) {
47266
+ console.error("THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.normalized must be consistent across matching attributes.");
47267
+ return null;
47268
+ }
47269
+ if (gpuType === -1) gpuType = attribute.gpuType;
47270
+ if (gpuType !== attribute.gpuType) {
47271
+ console.error("THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.gpuType must be consistent across matching attributes.");
47272
+ return null;
47273
+ }
47274
+ arrayLength += attribute.count * itemSize;
47275
+ }
47276
+ const array = new TypedArray(arrayLength);
47277
+ const result = new BufferAttribute(array, itemSize, normalized);
47278
+ let offset = 0;
47279
+ for (let i = 0; i < attributes.length; ++i) {
47280
+ const attribute = attributes[i];
47281
+ if (attribute.isInterleavedBufferAttribute) {
47282
+ const tupleOffset = offset / itemSize;
47283
+ for (let j = 0, l = attribute.count; j < l; j++) {
47284
+ for (let c = 0; c < itemSize; c++) {
47285
+ const value = attribute.getComponent(j, c);
47286
+ result.setComponent(j + tupleOffset, c, value);
47287
+ }
47288
+ }
47289
+ } else {
47290
+ array.set(attribute.array, offset);
47291
+ }
47292
+ offset += attribute.count * itemSize;
47293
+ }
47294
+ if (gpuType !== void 0) {
47295
+ result.gpuType = gpuType;
47296
+ }
47297
+ return result;
47298
+ }
47144
47299
  function estimateBytesUsed(geometry) {
47145
47300
  let mem = 0;
47146
47301
  for (const name in geometry.attributes) {
@@ -47646,7 +47801,6 @@ function createBasicOpaque() {
47646
47801
  vertexColors: true,
47647
47802
  flatShading: true,
47648
47803
  side: DoubleSide
47649
- //shininess: 20
47650
47804
  });
47651
47805
  }
47652
47806
  function createBasicTransparent() {
@@ -47912,107 +48066,69 @@ function createMaskMaterial() {
47912
48066
  `
47913
48067
  });
47914
48068
  }
47915
- function createIsolationMaterial() {
48069
+ function createGhostMaterial() {
47916
48070
  return new ShaderMaterial({
48071
+ userData: {
48072
+ isGhost: true
48073
+ },
47917
48074
  uniforms: {
47918
- opacity: { value: 0.1 },
48075
+ // Uniform controlling the overall transparency of the non-visible objects.
48076
+ opacity: { value: 1e-3 },
48077
+ // Uniform specifying the fill color for non-visible objects.
47919
48078
  fillColor: { value: new Vector3$1(0, 0, 0) }
47920
48079
  },
48080
+ // Render only the front side of faces to prevent drawing internal geometry.
48081
+ side: FrontSide,
48082
+ // Enable support for vertex colors.
47921
48083
  vertexColors: true,
48084
+ // Enable transparency for the material.
47922
48085
  transparent: true,
48086
+ // Enable clipping planes for geometry slicing.
47923
48087
  clipping: true,
48088
+ // Prevent writing to the depth buffer for proper blending of transparent objects.
48089
+ depthWrite: false,
48090
+ // Perform depth testing to ensure correct rendering order.
48091
+ depthTest: true,
47924
48092
  vertexShader: (
47925
48093
  /* glsl */
47926
48094
  `
47927
-
47928
- #include <common>
47929
- #include <logdepthbuf_pars_vertex>
47930
48095
  #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
48096
 
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
48097
+ // Attribute to determine if an object or vertex should be visible.
48098
+ // Used as an instance attribute for instanced meshes or a vertex attribute for merged meshes.
48099
+ attribute float ignore;
47956
48100
 
47957
48101
  void main() {
48102
+ // Standard transformations to calculate vertex position.
47958
48103
  #include <begin_vertex>
47959
48104
  #include <project_vertex>
47960
48105
  #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
48106
 
47976
-
47977
- // ORDERING
47978
- if(vIgnore > 0.0f){
47979
- gl_Position.z = 1.0f;
47980
- }else{
47981
- gl_Position.z = -1.0f;
48107
+ // Hide objects or vertices where the 'ignore' attribute is set to 0.
48108
+ if (ignore == 0.0) {
48109
+ // Push the vertex far out of view, effectively hiding it.
48110
+ gl_Position = vec4(1e20, 1e20, 1e20, 1.0);
47982
48111
  }
47983
-
47984
- // LIGHTING
47985
- vPosition = vec3(mvPosition ) / mvPosition .w;
47986
48112
  }
47987
- `
48113
+ `
47988
48114
  ),
47989
48115
  fragmentShader: (
47990
48116
  /* glsl */
47991
48117
  `
47992
48118
  #include <clipping_planes_pars_fragment>
47993
- varying float vIgnore;
48119
+
48120
+ // Uniform controlling the transparency level of the material.
47994
48121
  uniform float opacity;
48122
+ // Uniform specifying the fill color for non-visible objects.
47995
48123
  uniform vec3 fillColor;
47996
- varying vec3 vPosition;
47997
- varying vec3 vColor;
47998
48124
 
47999
48125
  void main() {
48126
+ // Handle clipping planes to discard fragments outside the defined planes.
48000
48127
  #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
- }
48128
+ // Set the fragment color to the specified fill color and opacity.
48129
+ gl_FragColor = vec4(fillColor, opacity);
48014
48130
  }
48015
- `
48131
+ `
48016
48132
  )
48017
48133
  });
48018
48134
  }
@@ -48300,42 +48416,40 @@ function createMergeMaterial() {
48300
48416
  }
48301
48417
  function createSimpleMaterial() {
48302
48418
  return new ShaderMaterial({
48303
- uniforms: {
48304
- opacity: { value: 0.1 },
48305
- fillColor: { value: new Vector3$1(0, 0, 0) }
48306
- },
48419
+ side: DoubleSide,
48420
+ // No uniforms are needed for this shader.
48421
+ uniforms: {},
48422
+ // Enable vertex colors for both instanced and merged meshes.
48307
48423
  vertexColors: true,
48308
- // transparent: true,
48424
+ // Enable support for clipping planes.
48309
48425
  clipping: true,
48310
48426
  vertexShader: (
48311
48427
  /* glsl */
48312
48428
  `
48313
-
48314
48429
  #include <common>
48315
48430
  #include <logdepthbuf_pars_vertex>
48316
48431
  #include <clipping_planes_pars_vertex>
48317
-
48432
+
48318
48433
  // VISIBILITY
48319
- // Instance or vertex attribute to hide objects
48320
- // Used as instance attribute for instanced mesh and as vertex attribute for merged meshes.
48434
+ // Determines if an object or vertex should be visible.
48435
+ // Used as an instance attribute for instanced meshes or as a vertex attribute for merged meshes.
48321
48436
  attribute float ignore;
48322
48437
 
48323
- // Passed to fragment to discard them
48324
- varying float vIgnore;
48438
+ // LIGHTING
48439
+ // Passes the vertex position to the fragment shader for lighting calculations.
48325
48440
  varying vec3 vPosition;
48326
48441
 
48327
-
48328
48442
  // COLORING
48443
+ // Passes the color of the vertex or instance to the fragment shader.
48329
48444
  varying vec3 vColor;
48330
48445
 
48331
- // attribute for color override
48332
- // merged meshes use it as vertex attribute
48333
- // instanced meshes use it as an instance attribute
48446
+ // Determines whether to use instance color (1.0) or vertex color (0.0).
48447
+ // For merged meshes, this is used as a vertex attribute.
48448
+ // For instanced meshes, this is used as an instance attribute.
48334
48449
  attribute float colored;
48335
48450
 
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
48451
+ // Fix for a known issue where setting mesh.instanceColor does not properly enable USE_INSTANCING_COLOR.
48452
+ // This ensures that instance colors are always used when required.
48339
48453
  #ifndef USE_INSTANCING_COLOR
48340
48454
  attribute vec3 instanceColor;
48341
48455
  #endif
@@ -48346,49 +48460,59 @@ function createSimpleMaterial() {
48346
48460
  #include <clipping_planes_vertex>
48347
48461
  #include <logdepthbuf_vertex>
48348
48462
 
48349
- // VISIBILITY
48350
- // Set frag ignore from instance or vertex attribute
48351
- vIgnore = ignore;
48463
+ // If ignore is greater than 0, hide the object by moving it far out of view.
48464
+ if (ignore > 0.0) {
48465
+ gl_Position = vec4(1e20, 1e20, 1e20, 1.0);
48466
+ return;
48467
+ }
48352
48468
 
48353
48469
  // COLORING
48470
+ // Default to the vertex color.
48354
48471
  vColor = color.xyz;
48355
48472
 
48356
- // colored == 1 -> instance color
48357
- // colored == 0 -> vertex color
48473
+ // Blend instance and vertex colors based on the colored attribute.
48474
+ // colored == 1.0 -> use instance color.
48475
+ // colored == 0.0 -> use vertex color.
48358
48476
  #ifdef USE_INSTANCING
48359
- vColor.xyz = colored * instanceColor.xyz + (1.0f - colored) * color.xyz;
48477
+ vColor.xyz = colored * instanceColor.xyz + (1.0 - colored) * color.xyz;
48360
48478
  #endif
48361
48479
 
48362
- gl_Position.z = -10.0f;
48363
-
48364
48480
  // LIGHTING
48365
- vPosition = vec3(mvPosition ) / mvPosition .w;
48481
+ // Pass the model-view position to the fragment shader for lighting calculations.
48482
+ vPosition = vec3(mvPosition) / mvPosition.w;
48366
48483
  }
48367
48484
  `
48368
48485
  ),
48369
48486
  fragmentShader: (
48370
48487
  /* glsl */
48371
48488
  `
48489
+ #include <common>
48490
+ #include <logdepthbuf_pars_fragment>
48372
48491
  #include <clipping_planes_pars_fragment>
48373
- varying float vIgnore;
48492
+
48493
+
48494
+ // Position and color data passed from the vertex shader.
48374
48495
  varying vec3 vPosition;
48375
48496
  varying vec3 vColor;
48376
48497
 
48377
48498
  void main() {
48378
48499
  #include <clipping_planes_fragment>
48500
+ #include <logdepthbuf_fragment>
48379
48501
 
48380
- if (vIgnore > 0.0f){
48381
- discard;
48382
- }
48383
- else{
48384
- gl_FragColor = vec4(vColor.x, vColor.y, vColor.z, 1.0f);
48502
+ // Set the fragment color to the interpolated vertex or instance color.
48503
+ gl_FragColor = vec4(vColor, 1.0);
48385
48504
 
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
- }
48505
+ // LIGHTING
48506
+ // Compute a pseudo-normal using screen-space derivatives of the vertex position.
48507
+ vec3 normal = normalize(cross(dFdx(vPosition), dFdy(vPosition)));
48508
+
48509
+ // Apply simple directional lighting.
48510
+ // Normalize the light direction for consistent shading.
48511
+ float light = dot(normal, normalize(vec3(1.4142, 1.732, 2.236)));
48512
+ light = 0.5 + (light * 0.5); // Adjust light intensity to range [0.5, 1.0].
48513
+
48514
+ // Modulate the fragment color by the lighting intensity.
48515
+ gl_FragColor.xyz *= light;
48392
48516
  }
48393
48517
  `
48394
48518
  )
@@ -48487,7 +48611,7 @@ class SkyboxMaterial extends ShaderMaterial {
48487
48611
  }
48488
48612
  }
48489
48613
  const _ViewerMaterials = class _ViewerMaterials {
48490
- constructor(opaque, transparent, simple, wireframe, isolation, mask, outline, merge, skyBox) {
48614
+ constructor(opaque, transparent, simple, wireframe, ghost2, mask, outline, merge, skyBox) {
48491
48615
  /**
48492
48616
  * Material used for opaque model geometry.
48493
48617
  */
@@ -48507,7 +48631,7 @@ const _ViewerMaterials = class _ViewerMaterials {
48507
48631
  /**
48508
48632
  * Material used to show traces of hidden objects.
48509
48633
  */
48510
- __publicField(this, "isolation");
48634
+ __publicField(this, "ghost");
48511
48635
  /**
48512
48636
  * Material used to filter out what is not selected for selection outline effect.
48513
48637
  */
@@ -48535,7 +48659,7 @@ const _ViewerMaterials = class _ViewerMaterials {
48535
48659
  this.transparent = transparent ?? createTransparent();
48536
48660
  this.simple = simple ?? createSimpleMaterial();
48537
48661
  this.wireframe = wireframe ?? createWireframe();
48538
- this.isolation = isolation ?? createIsolationMaterial();
48662
+ this.ghost = ghost2 ?? createGhostMaterial();
48539
48663
  this.mask = mask ?? createMaskMaterial();
48540
48664
  this.outline = outline ?? new OutlineMaterial();
48541
48665
  this.merge = merge ?? new MergeMaterial();
@@ -48557,8 +48681,8 @@ const _ViewerMaterials = class _ViewerMaterials {
48557
48681
  applySettings(settings2) {
48558
48682
  this.opaque.color = settings2.materials.standard.color;
48559
48683
  this.transparent.color = settings2.materials.standard.color;
48560
- this.isolationOpacity = settings2.materials.isolation.opacity;
48561
- this.isolationColor = settings2.materials.isolation.color;
48684
+ this.ghostOpacity = settings2.materials.ghost.opacity;
48685
+ this.ghostColor = settings2.materials.ghost.color;
48562
48686
  this.wireframeColor = settings2.materials.highlight.color;
48563
48687
  this.wireframeOpacity = settings2.materials.highlight.opacity;
48564
48688
  this.sectionStrokeWitdh = settings2.materials.section.strokeWidth;
@@ -48587,26 +48711,27 @@ const _ViewerMaterials = class _ViewerMaterials {
48587
48711
  this._onUpdate.dispatch();
48588
48712
  }
48589
48713
  /**
48590
- * Determines the opacity of the isolation material.
48714
+ * Determines the opacity of the ghost material.
48591
48715
  */
48592
- get isolationOpacity() {
48593
- return this.isolation.opacity;
48716
+ get ghostOpacity() {
48717
+ const mat = this.ghost;
48718
+ return mat.uniforms.opacity.value;
48594
48719
  }
48595
- set isolationOpacity(opacity) {
48596
- const mat = this.isolation;
48720
+ set ghostOpacity(opacity) {
48721
+ const mat = this.ghost;
48597
48722
  mat.uniforms.opacity.value = opacity;
48598
48723
  mat.uniformsNeedUpdate = true;
48599
48724
  this._onUpdate.dispatch();
48600
48725
  }
48601
48726
  /**
48602
- * Determines the color of the isolation material.
48727
+ * Determines the color of the ghost material.
48603
48728
  */
48604
- get isolationColor() {
48605
- const mat = this.isolation;
48729
+ get ghostColor() {
48730
+ const mat = this.ghost;
48606
48731
  return mat.uniforms.fillColor.value;
48607
48732
  }
48608
- set isolationColor(color) {
48609
- const mat = this.isolation;
48733
+ set ghostColor(color) {
48734
+ const mat = this.ghost;
48610
48735
  mat.uniforms.fillColor.value = color;
48611
48736
  mat.uniformsNeedUpdate = true;
48612
48737
  this._onUpdate.dispatch();
@@ -48667,10 +48792,11 @@ const _ViewerMaterials = class _ViewerMaterials {
48667
48792
  }
48668
48793
  set clippingPlanes(value) {
48669
48794
  this._clippingPlanes = value;
48795
+ this.simple.clippingPlanes = value ?? null;
48670
48796
  this.opaque.clippingPlanes = value ?? null;
48671
48797
  this.transparent.clippingPlanes = value ?? null;
48672
48798
  this.wireframe.clippingPlanes = value ?? null;
48673
- this.isolation.clippingPlanes = value ?? null;
48799
+ this.ghost.clippingPlanes = value ?? null;
48674
48800
  this.mask.clippingPlanes = value ?? null;
48675
48801
  this._onUpdate.dispatch();
48676
48802
  }
@@ -48790,7 +48916,7 @@ const _ViewerMaterials = class _ViewerMaterials {
48790
48916
  this.opaque.dispose();
48791
48917
  this.transparent.dispose();
48792
48918
  this.wireframe.dispose();
48793
- this.isolation.dispose();
48919
+ this.ghost.dispose();
48794
48920
  this.mask.dispose();
48795
48921
  this.outline.dispose();
48796
48922
  }
@@ -48902,16 +49028,12 @@ class InsertableMesh {
48902
49028
  setMaterial(value) {
48903
49029
  if (this._material === value) return;
48904
49030
  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
- }
49031
+ this.mesh.material = value ?? this._material;
49032
+ this.mesh.geometry.clearGroups();
49033
+ if (value instanceof Array) {
49034
+ value.forEach((m, i) => {
49035
+ this.mesh.geometry.addGroup(0, Infinity, i);
49036
+ });
48915
49037
  }
48916
49038
  }
48917
49039
  }
@@ -48969,13 +49091,17 @@ class InstancedMesh2 {
48969
49091
  // State
48970
49092
  __publicField(this, "ignoreSceneMaterial");
48971
49093
  __publicField(this, "_material");
49094
+ __publicField(this, "size", 0);
49095
+ var _a2;
48972
49096
  this.g3dMesh = g3d2;
48973
49097
  this.mesh = mesh;
48974
49098
  this.mesh.userData.vim = this;
48975
49099
  this.bimInstances = g3d2 instanceof distExports$2.G3dMesh ? instances.map((i) => g3d2.scene.instanceNodes[i]) : instances;
48976
49100
  this.meshInstances = instances;
48977
49101
  this.boxes = g3d2 instanceof distExports$2.G3dMesh ? this.importBoundingBoxes() : this.computeBoundingBoxes();
49102
+ this.size = ((_a2 = this.boxes[0]) == null ? void 0 : _a2.getSize(new Vector3$1()).length()) ?? 0;
48978
49103
  this.boundingBox = this.computeBoundingBox(this.boxes);
49104
+ this._material = this.mesh.material;
48979
49105
  }
48980
49106
  get merged() {
48981
49107
  return false;
@@ -48999,16 +49125,12 @@ class InstancedMesh2 {
48999
49125
  setMaterial(value) {
49000
49126
  if (this._material === value) return;
49001
49127
  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
- }
49128
+ this.mesh.material = value ?? this._material;
49129
+ this.mesh.geometry.clearGroups();
49130
+ if (value instanceof Array) {
49131
+ value.forEach((m, i) => {
49132
+ this.mesh.geometry.addGroup(0, Infinity, i);
49133
+ });
49012
49134
  }
49013
49135
  }
49014
49136
  computeBoundingBoxes() {
@@ -49947,7 +50069,7 @@ async function loadFromVim(bfast2, settings2, onProgress) {
49947
50069
  }
49948
50070
  return vim;
49949
50071
  }
49950
- let DeferredPromise$2 = class DeferredPromise extends Promise {
50072
+ let DeferredPromise$1 = class DeferredPromise extends Promise {
49951
50073
  constructor(executor = () => {
49952
50074
  }) {
49953
50075
  var _a2;
@@ -50010,8 +50132,8 @@ class VimRequest {
50010
50132
  __publicField(this, "_error");
50011
50133
  // Promises to await progress updates and completion
50012
50134
  __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());
50135
+ __publicField(this, "_progressPromise", new DeferredPromise$1());
50136
+ __publicField(this, "_completionPromise", new DeferredPromise$1());
50015
50137
  this._source = source;
50016
50138
  this._settings = settings2;
50017
50139
  this.startRequest();
@@ -50025,7 +50147,7 @@ class VimRequest {
50025
50147
  const vim = await open(this._bfast, this._settings, (progress) => {
50026
50148
  this._progress = progress;
50027
50149
  this._progressPromise.resolve(progress);
50028
- this._progressPromise = new DeferredPromise$2();
50150
+ this._progressPromise = new DeferredPromise$1();
50029
50151
  });
50030
50152
  this._vimResult = vim;
50031
50153
  } catch (err) {
@@ -50080,9 +50202,6 @@ function isPlainObject(o) {
50080
50202
  }
50081
50203
  return true;
50082
50204
  }
50083
- const floor$1 = `
50084
- data:image/png;base64,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
50085
- `;
50086
50205
  class AxesSettings {
50087
50206
  constructor(init) {
50088
50207
  __publicField(this, "size", 84);
@@ -50133,7 +50252,7 @@ const defaultViewerSettings = {
50133
50252
  fov: 50,
50134
50253
  zoom: 1,
50135
50254
  // 45 deg down looking down z.
50136
- forward: new Vector3$1(1, -1, 1),
50255
+ forward: new Vector3$1(1, -1, -1),
50137
50256
  controls: {
50138
50257
  orbit: true,
50139
50258
  rotateSpeed: 1,
@@ -50158,14 +50277,6 @@ const defaultViewerSettings = {
50158
50277
  // less white
50159
50278
  sharpness: 2
50160
50279
  },
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
50280
  skylight: {
50170
50281
  skyColor: new Color(16777215),
50171
50282
  groundColor: new Color(16777215),
@@ -50193,9 +50304,9 @@ const defaultViewerSettings = {
50193
50304
  color: new Color(7000831),
50194
50305
  opacity: 0.5
50195
50306
  },
50196
- isolation: {
50307
+ ghost: {
50197
50308
  color: new Color(5132892),
50198
- opacity: 0.08
50309
+ opacity: 0.01
50199
50310
  },
50200
50311
  section: {
50201
50312
  strokeWidth: 0.01,
@@ -50465,18 +50576,18 @@ class CameraMovement {
50465
50576
  orbitTowards(direction) {
50466
50577
  const forward = this._camera.forward;
50467
50578
  const _direction = direction.clone();
50468
- if (_direction.x === 0 && _direction.z === 0) {
50579
+ if (_direction.x === 0 && _direction.y === 0) {
50469
50580
  _direction.x = this._camera.forward.x * 1e-3;
50470
- _direction.z = this._camera.forward.z * 1e-3;
50581
+ _direction.y = this._camera.forward.y * 1e-3;
50471
50582
  _direction.normalize();
50472
50583
  }
50473
- const flatForward = forward.clone().setY(0);
50474
- const flatDirection = _direction.clone().setY(0);
50584
+ const flatForward = forward.clone().setZ(0);
50585
+ const flatDirection = _direction.clone().setZ(0);
50475
50586
  const cross = flatForward.clone().cross(flatDirection);
50476
- const clockwise = cross.y === 0 ? 1 : Math.sign(cross.y);
50587
+ const clockwise = cross.z === 0 ? 1 : Math.sign(cross.z);
50477
50588
  const azimuth = flatForward.angleTo(flatDirection) * clockwise;
50478
- const angleForward = flatForward.angleTo(forward) * Math.sign(forward.y);
50479
- const angleDirection = flatDirection.angleTo(_direction) * Math.sign(_direction.y);
50589
+ const angleForward = flatForward.angleTo(forward) * Math.sign(forward.z);
50590
+ const angleDirection = flatDirection.angleTo(_direction) * Math.sign(_direction.z);
50480
50591
  const declination = angleForward - angleDirection;
50481
50592
  const angle = new Vector2$1(-declination, azimuth);
50482
50593
  angle.multiplyScalar(180 / Math.PI);
@@ -50684,12 +50795,30 @@ class CameraMovementSnap extends CameraMovement {
50684
50795
  this.set(pos, target);
50685
50796
  }
50686
50797
  set(position, target) {
50687
- const locked = this.lockVector(position, this._camera.position);
50688
- this._camera.position.copy(locked);
50689
50798
  target = target ?? this._camera.target;
50799
+ const direction = new Vector3$1().subVectors(position, target);
50800
+ const dist2 = direction.length();
50801
+ if (dist2 > 1e-6) {
50802
+ const up = new Vector3$1(0, 0, 1);
50803
+ const angle = direction.angleTo(up);
50804
+ const minAngle = MathUtils.degToRad(5);
50805
+ const maxAngle = MathUtils.degToRad(175);
50806
+ if (angle < minAngle) {
50807
+ const axis = new Vector3$1().crossVectors(up, direction).normalize();
50808
+ const delta = minAngle - angle;
50809
+ direction.applyQuaternion(new Quaternion().setFromAxisAngle(axis, delta));
50810
+ } else if (angle > maxAngle) {
50811
+ const axis = new Vector3$1().crossVectors(up, direction).normalize();
50812
+ const delta = maxAngle - angle;
50813
+ direction.applyQuaternion(new Quaternion().setFromAxisAngle(axis, delta));
50814
+ }
50815
+ position.copy(target).add(direction);
50816
+ }
50817
+ const lockedPos = this.lockVector(position, this._camera.position);
50818
+ this._camera.position.copy(lockedPos);
50690
50819
  this._camera.target.copy(target);
50820
+ this._camera.camPerspective.camera.up.set(0, 0, 1);
50691
50821
  this._camera.camPerspective.camera.lookAt(target);
50692
- this._camera.camPerspective.camera.up.set(0, 1, 0);
50693
50822
  }
50694
50823
  lockVector(position, fallback) {
50695
50824
  const x = this._camera.allowedMovement.x === 0 ? fallback.x : position.x;
@@ -50700,17 +50829,14 @@ class CameraMovementSnap extends CameraMovement {
50700
50829
  predictOrbit(angle) {
50701
50830
  const rotation = this.predictRotate(angle);
50702
50831
  const delta = new Vector3$1(0, 0, 1).applyQuaternion(rotation).multiplyScalar(this._camera.orbitDistance);
50703
- return this._camera.target.clone().add(delta);
50832
+ const pos = this._camera.target.clone().add(delta);
50833
+ return pos;
50704
50834
  }
50705
50835
  predictRotate(angle) {
50706
- const euler = new Euler(0, 0, 0, "YXZ");
50707
- euler.setFromQuaternion(this._camera.quaternion);
50708
- euler.x += angle.x * Math.PI / 180;
50709
- euler.y += angle.y * Math.PI / 180;
50710
- euler.z = 0;
50711
- const max2 = Math.PI * 0.4999;
50712
- euler.x = Math.max(-max2, Math.min(max2, euler.x));
50713
- const rotation = new Quaternion().setFromEuler(euler);
50836
+ const xQuat = new Quaternion().setFromAxisAngle(new Vector3$1(1, 0, 0), angle.x * Math.PI / 180);
50837
+ const zQuat = new Quaternion().setFromAxisAngle(new Vector3$1(0, 1, 0), angle.y * Math.PI / 180);
50838
+ const rotation = this._camera.quaternion.clone();
50839
+ rotation.multiply(xQuat).multiply(zQuat);
50714
50840
  return rotation;
50715
50841
  }
50716
50842
  }
@@ -50759,6 +50885,8 @@ let Camera$1 = class Camera2 {
50759
50885
  __publicField(this, "_velocityBlendFactor", 1e-4);
50760
50886
  __publicField(this, "_moveSpeed", 1);
50761
50887
  this.camPerspective = new PerspectiveWrapper(new PerspectiveCamera());
50888
+ this.camPerspective.camera.up = new Vector3$1(0, 0, 1);
50889
+ this.camPerspective.camera.lookAt(new Vector3$1(0, 1, 0));
50762
50890
  this.camOrthographic = new OrthographicWrapper(
50763
50891
  new OrthographicCamera()
50764
50892
  );
@@ -50819,7 +50947,7 @@ let Camera$1 = class Camera2 {
50819
50947
  }
50820
50948
  set defaultForward(value) {
50821
50949
  if (value.x === 0 && value.y === 0 && value.z === 0) {
50822
- this._defaultForward.set(1, -1, 1).normalize();
50950
+ this._defaultForward.set(1, -1, -1).normalize();
50823
50951
  } else {
50824
50952
  this._defaultForward.copy(value).normalize();
50825
50953
  }
@@ -52383,6 +52511,9 @@ class Selection {
52383
52511
  });
52384
52512
  this._onValueChanged.dispatch();
52385
52513
  }
52514
+ any() {
52515
+ return this._objects.size > 0;
52516
+ }
52386
52517
  /**
52387
52518
  * Returns true if the given object is currently selected.
52388
52519
  * @param {IObject} object The object to check for selection.
@@ -52492,92 +52623,6 @@ class Selection {
52492
52623
  this._materials.focusIntensity = focus / 2;
52493
52624
  }
52494
52625
  }
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
52626
  class Skybox {
52582
52627
  constructor(camera2, renderer, materials, settings2) {
52583
52628
  __publicField(this, "mesh");
@@ -52722,28 +52767,22 @@ class Environment {
52722
52767
  * The array of directional lights in the scene.
52723
52768
  */
52724
52769
  __publicField(this, "sunLights");
52725
- /**
52726
- * The ground plane under the model in the scene.
52727
- */
52728
- __publicField(this, "groundPlane");
52729
52770
  /*
52730
52771
  * The skybox in the scene.
52731
52772
  */
52732
52773
  __publicField(this, "skybox");
52733
52774
  this._camera = camera2;
52734
52775
  this._renderer = renderer;
52735
- this.groundPlane = new GroundPlane(settings2);
52736
52776
  this.skyLight = this.createSkyLight(settings2);
52737
52777
  this.skybox = new Skybox(camera2, renderer, viewerMaterials, settings2);
52738
52778
  this.sunLights = this.createSunLights(settings2);
52739
- this.setupRendererListeners();
52740
52779
  this.addObjectsToRenderer();
52741
52780
  }
52742
52781
  /**
52743
52782
  * Returns all three objects composing the environment
52744
52783
  */
52745
52784
  getObjects() {
52746
- return [this.groundPlane.mesh, this.skyLight, ...this.sunLights.map((l) => l.light), this.skybox.mesh];
52785
+ return [this.skyLight, ...this.sunLights.map((l) => l.light), this.skybox.mesh];
52747
52786
  }
52748
52787
  createSkyLight(settings2) {
52749
52788
  const { skyColor, groundColor, intensity } = settings2.skylight;
@@ -52757,12 +52796,6 @@ class Environment {
52757
52796
  addObjectsToRenderer() {
52758
52797
  this.getObjects().forEach((o) => this._renderer.add(o));
52759
52798
  }
52760
- setupRendererListeners() {
52761
- this._renderer.onBoxUpdated.subscribe(() => {
52762
- const box = this._renderer.getBoundingBox();
52763
- this.groundPlane.adaptToContent(box);
52764
- });
52765
- }
52766
52799
  /**
52767
52800
  * Dispose of all resources.
52768
52801
  */
@@ -52770,7 +52803,6 @@ class Environment {
52770
52803
  this.getObjects().forEach((o) => this._renderer.remove(o));
52771
52804
  this.sunLights.forEach((s) => s.dispose());
52772
52805
  this.skyLight.dispose();
52773
- this.groundPlane.dispose();
52774
52806
  this.skybox.dispose();
52775
52807
  }
52776
52808
  }
@@ -52903,14 +52935,16 @@ class RenderScene {
52903
52935
  __publicField(this, "scene");
52904
52936
  // state
52905
52937
  __publicField(this, "boxUpdated", false);
52938
+ // public value
52939
+ __publicField(this, "smallGhostThreshold", 10);
52906
52940
  __publicField(this, "_vimScenes", []);
52907
52941
  __publicField(this, "_boundingBox");
52908
52942
  __publicField(this, "_memory", 0);
52909
52943
  __publicField(this, "_2dCount", 0);
52910
- __publicField(this, "_material");
52944
+ __publicField(this, "_modelMaterial");
52911
52945
  this.scene = new Scene$1();
52912
52946
  }
52913
- get models() {
52947
+ get meshes() {
52914
52948
  return this._vimScenes.flatMap((s) => s.meshes);
52915
52949
  }
52916
52950
  get estimatedMemory() {
@@ -52957,6 +52991,7 @@ class RenderScene {
52957
52991
  add(target) {
52958
52992
  if (target instanceof Scene2) {
52959
52993
  this.addScene(target);
52994
+ target.material = this._modelMaterial;
52960
52995
  return;
52961
52996
  }
52962
52997
  this._2dCount += this.count2dObjects(target);
@@ -53006,16 +53041,31 @@ class RenderScene {
53006
53041
  this._boundingBox = void 0;
53007
53042
  this._memory = 0;
53008
53043
  }
53009
- get material() {
53010
- return this._material;
53044
+ get modelMaterial() {
53045
+ return this._modelMaterial;
53011
53046
  }
53012
- set material(material) {
53013
- this._material = material;
53047
+ set modelMaterial(material) {
53048
+ this._modelMaterial = material;
53014
53049
  this._vimScenes.forEach((s) => {
53015
- s.meshes.forEach((m) => {
53016
- m.mesh.material = material;
53017
- });
53050
+ s.material = material;
53018
53051
  });
53052
+ this.updateInstanceMeshVisibility();
53053
+ }
53054
+ updateInstanceMeshVisibility() {
53055
+ var _a2, _b2;
53056
+ const hide = ((_b2 = (_a2 = this._modelMaterial) == null ? void 0 : _a2[1]) == null ? void 0 : _b2.userData.isGhost) === true;
53057
+ for (const mesh of this.meshes) {
53058
+ if (mesh instanceof InstancedMesh2) {
53059
+ if (this.smallGhostThreshold <= 0) {
53060
+ mesh.mesh.visible = true;
53061
+ continue;
53062
+ }
53063
+ const visible2 = mesh.getSubmeshes().some(
53064
+ (m) => m.object.visible
53065
+ );
53066
+ mesh.mesh.visible = !(hide && !visible2 && mesh.size < this.smallGhostThreshold);
53067
+ }
53068
+ }
53019
53069
  }
53020
53070
  addScene(scene) {
53021
53071
  this._vimScenes.push(scene);
@@ -54984,93 +55034,279 @@ class Measure {
54984
55034
  this._meshes = void 0;
54985
55035
  }
54986
55036
  }
54987
- class BoxOutline extends LineSegments {
54988
- constructor() {
54989
- const vertices = new Float32Array([
54990
- -0.5,
54991
- -0.5,
54992
- -0.5,
54993
- 0.5,
54994
- -0.5,
54995
- -0.5,
54996
- 0.5,
54997
- 0.5,
54998
- -0.5,
54999
- -0.5,
55000
- 0.5,
55001
- -0.5,
55002
- -0.5,
55003
- -0.5,
55004
- 0.5,
55005
- 0.5,
55006
- -0.5,
55007
- 0.5,
55008
- 0.5,
55009
- 0.5,
55010
- 0.5,
55011
- -0.5,
55012
- 0.5,
55013
- 0.5
55014
- ]);
55015
- const indices = [
55016
- 0.5,
55017
- 1,
55018
- 1,
55019
- 2,
55020
- 2,
55021
- 3,
55022
- 3,
55023
- 0,
55024
- 4,
55025
- 5,
55026
- 5,
55027
- 6,
55028
- 6,
55029
- 7,
55030
- 7,
55031
- 4,
55032
- 0,
55033
- 4,
55034
- 1,
55035
- 5,
55036
- 2,
55037
- 6,
55038
- 3,
55039
- 7
55040
- ];
55041
- const geo = new BufferGeometry();
55042
- const mat = new LineBasicMaterial({
55043
- opacity: 1,
55044
- color: new Color(0)
55045
- });
55046
- geo.setAttribute("position", new BufferAttribute(vertices, 3));
55047
- geo.setIndex(indices);
55048
- super(geo, mat);
55049
- }
55050
- /**
55051
- * Resize the outline to the given box.
55052
- */
55053
- fitBox(box) {
55054
- this.scale.set(
55055
- box.max.x - box.min.x,
55056
- box.max.y - box.min.y,
55057
- box.max.z - box.min.z
55058
- );
55059
- this.position.set(
55060
- (box.max.x + box.min.x) / 2,
55061
- (box.max.y + box.min.y) / 2,
55062
- (box.max.z + box.min.z) / 2
55063
- );
55037
+ const MIN_BOX_SIZE = 3;
55038
+ class BoxInputs {
55039
+ // -------------------------------------------------------------------------
55040
+ // Constructor
55041
+ // -------------------------------------------------------------------------
55042
+ /**
55043
+ * Creates a new BoxInputs instance for pointer-driven box resizing.
55044
+ *
55045
+ * @param viewer - The parent {@link Viewer} that renders the scene.
55046
+ * @param handles - A {@link SectionBoxHandles} instance containing the draggable mesh handles.
55047
+ * @param box - The shared bounding box (`Box3`) that will be updated by dragging.
55048
+ */
55049
+ constructor(viewer, handles, box) {
55050
+ // -------------------------------------------------------------------------
55051
+ // Dependencies and shared resources
55052
+ // -------------------------------------------------------------------------
55053
+ /** The parent Viewer controlling the scene. */
55054
+ __publicField(this, "_viewer");
55055
+ /** The handles mesh group containing the draggable cones/faces. */
55056
+ __publicField(this, "_handles");
55057
+ /** The main box that is being reshaped by dragging handles. */
55058
+ __publicField(this, "_sharedBox");
55059
+ // -------------------------------------------------------------------------
55060
+ // Internal state
55061
+ // -------------------------------------------------------------------------
55062
+ /** The currently hovered/dragged handle, if any. */
55063
+ __publicField(this, "_handle");
55064
+ /** The origin point for dragging, updated on pointer down. */
55065
+ __publicField(this, "_dragOrigin", new Vector3$1());
55066
+ /** The plane used for drag intersection (perpendicular to the camera direction). */
55067
+ __publicField(this, "_dragPlane", new Plane());
55068
+ /** Whether a pointer is currently down on a handle. */
55069
+ __publicField(this, "_mouseDown", false);
55070
+ /** A reusable Raycaster for picking and plane intersection. */
55071
+ __publicField(this, "_raycaster", new Raycaster$1());
55072
+ /** The box state before the current drag. */
55073
+ __publicField(this, "_lastBox", new Box3$1());
55074
+ /** A collection of unregister callbacks for event listeners. */
55075
+ __publicField(this, "_unregisters", []);
55076
+ /** The ID of the pointer that is captured, if any. */
55077
+ __publicField(this, "_capturedPointerId");
55078
+ // -------------------------------------------------------------------------
55079
+ // Callbacks
55080
+ // -------------------------------------------------------------------------
55081
+ /**
55082
+ * Called when the pointer enters or leaves a handle face.
55083
+ * @param normal - The normal (forward) vector of the hovered handle, or a zero vector if none.
55084
+ */
55085
+ __publicField(this, "onFaceEnter");
55086
+ /**
55087
+ * Called continuously as the box is reshaped by dragging.
55088
+ * @param box - The updated box after the latest drag move.
55089
+ */
55090
+ __publicField(this, "onBoxStretch");
55091
+ /**
55092
+ * Called when the user has finished reshaping the box (pointer up).
55093
+ * @param box - The final box after dragging ends.
55094
+ */
55095
+ __publicField(this, "onBoxConfirm");
55096
+ this._viewer = viewer;
55097
+ this._handles = handles;
55098
+ this._sharedBox = box;
55064
55099
  }
55100
+ // -------------------------------------------------------------------------
55101
+ // Public Methods
55102
+ // -------------------------------------------------------------------------
55065
55103
  /**
55066
- * Disposes of all resources.
55104
+ * Registers pointer event listeners on the viewer's canvas.
55105
+ * If already registered, it does nothing.
55067
55106
  */
55068
- dispose() {
55069
- this.geometry.dispose();
55070
- this.material.dispose();
55107
+ register() {
55108
+ if (this._unregisters.length > 0) return;
55109
+ const canvas = this._viewer.viewport.canvas;
55110
+ this.reg(canvas, "pointerdown", (e) => this.onMouseDown(e));
55111
+ this.reg(canvas, "pointermove", (e) => this.onMouseMove(e));
55112
+ this.reg(canvas, "pointerup", (e) => this.onMouseUp(e));
55113
+ this.reg(canvas, "pointerleave", (e) => this.onPointerLeave(e));
55114
+ }
55115
+ /**
55116
+ * Unregisters any previously set pointer event listeners, releasing pointer capture
55117
+ * and resetting drag state.
55118
+ */
55119
+ unregister() {
55120
+ var _a2;
55121
+ this._mouseDown = false;
55122
+ (_a2 = this._handle) == null ? void 0 : _a2.highlight(false);
55123
+ this._handle = void 0;
55124
+ this.releasePointer();
55125
+ this._viewer.inputs.registerAll();
55126
+ this._unregisters.forEach((unreg) => unreg());
55127
+ this._unregisters.length = 0;
55128
+ }
55129
+ /**
55130
+ * Indicates if a pointer is currently captured for dragging.
55131
+ */
55132
+ get pointerCaptured() {
55133
+ return this._capturedPointerId !== void 0;
55134
+ }
55135
+ // -------------------------------------------------------------------------
55136
+ // Private Methods
55137
+ // -------------------------------------------------------------------------
55138
+ /**
55139
+ * A helper method to attach an event listener and store its unregister callback.
55140
+ *
55141
+ * @param handler - The DOM element or Window to attach the listener to.
55142
+ * @param type - The pointer event type, e.g. 'pointerdown'.
55143
+ * @param listener - The event handler function.
55144
+ */
55145
+ reg(handler, type, listener2) {
55146
+ handler.addEventListener(type, listener2);
55147
+ this._unregisters.push(() => handler.removeEventListener(type, listener2));
55148
+ }
55149
+ /**
55150
+ * Called when the pointer leaves the canvas. If not dragging,
55151
+ * invokes {@link onFaceEnter} to indicate no active handle is hovered.
55152
+ *
55153
+ * @param event - The pointerleave event.
55154
+ */
55155
+ onPointerLeave(event) {
55156
+ var _a2, _b2;
55157
+ if (!this.pointerCaptured) {
55158
+ (_b2 = this.onFaceEnter) == null ? void 0 : _b2.call(this, ((_a2 = this._handle) == null ? void 0 : _a2.forward) ?? new Vector3$1());
55159
+ }
55160
+ }
55161
+ /**
55162
+ * Sets pointer capture on the canvas for a specific pointer (ID).
55163
+ *
55164
+ * @param pointerId - The pointer ID to capture.
55165
+ */
55166
+ capturePointer(pointerId) {
55167
+ this.releasePointer();
55168
+ this._viewer.viewport.canvas.setPointerCapture(pointerId);
55169
+ this._capturedPointerId = pointerId;
55170
+ }
55171
+ /**
55172
+ * Releases any captured pointer on the canvas, if present.
55173
+ */
55174
+ releasePointer() {
55175
+ if (this.pointerCaptured) {
55176
+ this._viewer.viewport.canvas.releasePointerCapture(this._capturedPointerId);
55177
+ this._capturedPointerId = void 0;
55178
+ }
55179
+ }
55180
+ /**
55181
+ * Handles pointer movement events.
55182
+ * - If dragging, calls {@link onDrag}.
55183
+ * - Otherwise, performs a raycast to detect which handle is under the pointer.
55184
+ *
55185
+ * @param event - The pointermove event.
55186
+ */
55187
+ onMouseMove(event) {
55188
+ var _a2, _b2, _c, _d;
55189
+ if (this._mouseDown) {
55190
+ this.onDrag(event);
55191
+ return;
55192
+ }
55193
+ const hits = this.raycast(new Vector2$1(event.offsetX, event.offsetY));
55194
+ const handle = (_b2 = (_a2 = hits == null ? void 0 : hits[0]) == null ? void 0 : _a2.object) == null ? void 0 : _b2.userData.handle;
55195
+ if (handle !== this._handle) {
55196
+ (_c = this._handle) == null ? void 0 : _c.highlight(false);
55197
+ handle == null ? void 0 : handle.highlight(true);
55198
+ this._handle = handle;
55199
+ (_d = this.onFaceEnter) == null ? void 0 : _d.call(this, (handle == null ? void 0 : handle.forward) ?? new Vector3$1());
55200
+ }
55201
+ }
55202
+ /**
55203
+ * Handles pointer up events. Ends dragging and triggers {@link onBoxConfirm}.
55204
+ *
55205
+ * @param event - The pointerup event.
55206
+ */
55207
+ onMouseUp(event) {
55208
+ var _a2, _b2;
55209
+ this.releasePointer();
55210
+ if (this._mouseDown) {
55211
+ this._mouseDown = false;
55212
+ this._viewer.inputs.registerAll();
55213
+ if (event.pointerType === "mouse") {
55214
+ this.onMouseMove(event);
55215
+ } else {
55216
+ this._handle = void 0;
55217
+ (_a2 = this.onFaceEnter) == null ? void 0 : _a2.call(this, new Vector3$1());
55218
+ }
55219
+ (_b2 = this.onBoxConfirm) == null ? void 0 : _b2.call(this, this._sharedBox);
55220
+ }
55221
+ }
55222
+ /**
55223
+ * Handles pointer down events. Begins drag if a handle is hit, capturing the pointer.
55224
+ *
55225
+ * @param event - The pointerdown event.
55226
+ */
55227
+ onMouseDown(event) {
55228
+ var _a2, _b2, _c, _d;
55229
+ const hits = this.raycast(new Vector2$1(event.offsetX, event.offsetY));
55230
+ const handle = (_c = (_b2 = (_a2 = hits == null ? void 0 : hits[0]) == null ? void 0 : _a2.object) == null ? void 0 : _b2.userData) == null ? void 0 : _c.handle;
55231
+ if (!handle) return;
55232
+ this._handle = handle;
55233
+ this.capturePointer(event.pointerId);
55234
+ this._lastBox.copy(this._sharedBox);
55235
+ this._dragOrigin.copy(handle.position);
55236
+ const dist2 = handle.position.clone().dot(this._viewer.camera.forward);
55237
+ this._dragPlane.set(this._viewer.camera.forward, -dist2);
55238
+ this._mouseDown = true;
55239
+ this._viewer.inputs.unregisterAll();
55240
+ (_d = this.onFaceEnter) == null ? void 0 : _d.call(this, this._handle.forward.clone());
55241
+ }
55242
+ /**
55243
+ * Continues the drag operation. Determines the new position on the drag plane
55244
+ * and computes how far we moved along the handle's forward axis.
55245
+ *
55246
+ * @param event - The pointermove event while dragging.
55247
+ */
55248
+ onDrag(event) {
55249
+ var _a2;
55250
+ if (!this._handle) return;
55251
+ const point = this.raycastPlane(new Vector2$1(event.offsetX, event.offsetY)) ?? this._dragOrigin.clone();
55252
+ const delta = point.sub(this._dragOrigin);
55253
+ const amount = delta.dot(this._handle.forward);
55254
+ const box = this.stretch(this._handle.axis, this._handle.sign, amount);
55255
+ (_a2 = this.onBoxStretch) == null ? void 0 : _a2.call(this, box);
55256
+ }
55257
+ /**
55258
+ * Expands or contracts the `_sharedBox` along one axis by a certain amount,
55259
+ * ensuring the box cannot shrink below the minimum size (`MIN_BOX_SIZE`).
55260
+ *
55261
+ * @param axis - The axis ('x', 'y', or 'z') to stretch.
55262
+ * @param sign - +1 if stretching the 'max' side, -1 if stretching the 'min' side.
55263
+ * @param amount - The numeric offset along that axis to add or subtract.
55264
+ * @returns A **new** `Box3` instance with updated min/max coordinates.
55265
+ */
55266
+ stretch(axis, sign2, amount) {
55267
+ const box = this._sharedBox.clone();
55268
+ const direction = sign2 > 0 ? "max" : "min";
55269
+ const opposite = sign2 > 0 ? "min" : "max";
55270
+ const target = this._lastBox[direction][axis] + amount * sign2;
55271
+ const minBoundary = this._lastBox[opposite][axis] + MIN_BOX_SIZE * sign2;
55272
+ box[direction][axis] = target;
55273
+ if (sign2 * (target - minBoundary) < 0) {
55274
+ box[opposite][axis] = target - MIN_BOX_SIZE * sign2;
55275
+ }
55276
+ return box;
55277
+ }
55278
+ /**
55279
+ * Prepares the internal raycaster for a given 2D pointer position.
55280
+ *
55281
+ * @param position - The pointer position in canvas coordinates.
55282
+ * @returns The updated raycaster pointing from the camera through this position.
55283
+ */
55284
+ getRaycaster(position) {
55285
+ return this._viewer.raycaster.fromPoint2(position, this._raycaster);
55286
+ }
55287
+ /**
55288
+ * Raycasts into the handle meshes from the given pointer position.
55289
+ *
55290
+ * @param position - The pointer position in canvas coordinates.
55291
+ * @returns An array of intersection results, if any.
55292
+ */
55293
+ raycast(position) {
55294
+ return this.getRaycaster(position).intersectObject(this._handles.meshes);
55295
+ }
55296
+ /**
55297
+ * Raycasts into the drag plane from the given pointer position.
55298
+ *
55299
+ * @param position - The pointer position in canvas coordinates.
55300
+ * @returns The intersection point in 3D space, or `null` if none.
55301
+ */
55302
+ raycastPlane(position) {
55303
+ return this.getRaycaster(position).ray.intersectPlane(
55304
+ this._dragPlane,
55305
+ new Vector3$1()
55306
+ );
55071
55307
  }
55072
55308
  }
55073
- class BoxMesh extends Mesh {
55309
+ class SectionBoxMesh extends Mesh {
55074
55310
  constructor() {
55075
55311
  const geo = new BoxGeometry();
55076
55312
  const mat = new MeshBasicMaterial({
@@ -55104,271 +55340,255 @@ class BoxMesh extends Mesh {
55104
55340
  this.material.dispose();
55105
55341
  }
55106
55342
  }
55107
- class BoxHighlight extends Mesh {
55108
- constructor() {
55343
+ class SectionBoxOutline extends LineSegments {
55344
+ constructor(color) {
55345
+ const vertices = new Float32Array([
55346
+ -0.5,
55347
+ -0.5,
55348
+ -0.5,
55349
+ 0.5,
55350
+ -0.5,
55351
+ -0.5,
55352
+ 0.5,
55353
+ 0.5,
55354
+ -0.5,
55355
+ -0.5,
55356
+ 0.5,
55357
+ -0.5,
55358
+ -0.5,
55359
+ -0.5,
55360
+ 0.5,
55361
+ 0.5,
55362
+ -0.5,
55363
+ 0.5,
55364
+ 0.5,
55365
+ 0.5,
55366
+ 0.5,
55367
+ -0.5,
55368
+ 0.5,
55369
+ 0.5
55370
+ ]);
55371
+ const indices = [
55372
+ 0.5,
55373
+ 1,
55374
+ 1,
55375
+ 2,
55376
+ 2,
55377
+ 3,
55378
+ 3,
55379
+ 0,
55380
+ 4,
55381
+ 5,
55382
+ 5,
55383
+ 6,
55384
+ 6,
55385
+ 7,
55386
+ 7,
55387
+ 4,
55388
+ 0,
55389
+ 4,
55390
+ 1,
55391
+ 5,
55392
+ 2,
55393
+ 6,
55394
+ 3,
55395
+ 7
55396
+ ];
55109
55397
  const geo = new BufferGeometry();
55110
- geo.setAttribute(
55111
- "position",
55112
- new BufferAttribute(new Float32Array(12), 3)
55113
- );
55114
- geo.setIndex([0, 1, 2, 0, 2, 3]);
55115
- const mat = new MeshBasicMaterial({
55116
- opacity: 0.7,
55117
- transparent: true,
55118
- depthTest: false,
55119
- side: DoubleSide
55398
+ const mat = new LineBasicMaterial({
55399
+ opacity: 1,
55400
+ color
55120
55401
  });
55402
+ geo.setAttribute("position", new BufferAttribute(vertices, 3));
55403
+ geo.setIndex(indices);
55121
55404
  super(geo, mat);
55122
- this.renderOrder = 1;
55123
- this.frustumCulled = false;
55124
55405
  }
55125
55406
  /**
55126
- * Sets the face to highlight
55127
- * @param normal a direction vector from theses options (X,-X, Y,-Y, Z,-Z)
55407
+ * Resize the outline to the given box.
55128
55408
  */
55129
- highlight(box, normal) {
55130
- this.visible = false;
55131
- const positions = this.geometry.getAttribute("position");
55132
- if (normal.x > 0.1) {
55133
- positions.setXYZ(0, box.max.x, box.max.y, box.max.z);
55134
- positions.setXYZ(1, box.max.x, box.min.y, box.max.z);
55135
- positions.setXYZ(2, box.max.x, box.min.y, box.min.z);
55136
- positions.setXYZ(3, box.max.x, box.max.y, box.min.z);
55137
- this.visible = true;
55138
- }
55139
- if (normal.x < -0.1) {
55140
- positions.setXYZ(0, box.min.x, box.max.y, box.max.z);
55141
- positions.setXYZ(1, box.min.x, box.min.y, box.max.z);
55142
- positions.setXYZ(2, box.min.x, box.min.y, box.min.z);
55143
- positions.setXYZ(3, box.min.x, box.max.y, box.min.z);
55144
- this.visible = true;
55145
- }
55146
- if (normal.y > 0.1) {
55147
- positions.setXYZ(0, box.max.x, box.max.y, box.max.z);
55148
- positions.setXYZ(1, box.min.x, box.max.y, box.max.z);
55149
- positions.setXYZ(2, box.min.x, box.max.y, box.min.z);
55150
- positions.setXYZ(3, box.max.x, box.max.y, box.min.z);
55151
- this.visible = true;
55152
- }
55153
- if (normal.y < -0.1) {
55154
- positions.setXYZ(0, box.max.x, box.min.y, box.max.z);
55155
- positions.setXYZ(1, box.min.x, box.min.y, box.max.z);
55156
- positions.setXYZ(2, box.min.x, box.min.y, box.min.z);
55157
- positions.setXYZ(3, box.max.x, box.min.y, box.min.z);
55158
- this.visible = true;
55159
- }
55160
- if (normal.z > 0.1) {
55161
- positions.setXYZ(0, box.max.x, box.max.y, box.max.z);
55162
- positions.setXYZ(1, box.min.x, box.max.y, box.max.z);
55163
- positions.setXYZ(2, box.min.x, box.min.y, box.max.z);
55164
- positions.setXYZ(3, box.max.x, box.min.y, box.max.z);
55165
- this.visible = true;
55166
- }
55167
- if (normal.z < -0.1) {
55168
- positions.setXYZ(0, box.max.x, box.max.y, box.min.z);
55169
- positions.setXYZ(1, box.min.x, box.max.y, box.min.z);
55170
- positions.setXYZ(2, box.min.x, box.min.y, box.min.z);
55171
- positions.setXYZ(3, box.max.x, box.min.y, box.min.z);
55172
- this.visible = true;
55173
- }
55174
- positions.needsUpdate = true;
55409
+ fitBox(box) {
55410
+ this.scale.set(
55411
+ box.max.x - box.min.x,
55412
+ box.max.y - box.min.y,
55413
+ box.max.z - box.min.z
55414
+ );
55415
+ this.position.set(
55416
+ (box.max.x + box.min.x) / 2,
55417
+ (box.max.y + box.min.y) / 2,
55418
+ (box.max.z + box.min.z) / 2
55419
+ );
55175
55420
  }
55176
55421
  /**
55177
- * Disposes all resources.
55422
+ * Disposes of all resources.
55178
55423
  */
55179
55424
  dispose() {
55180
55425
  this.geometry.dispose();
55181
55426
  this.material.dispose();
55182
55427
  }
55183
55428
  }
55184
- class BoxInputs {
55185
- constructor(viewer, cube, box) {
55186
- // dependencies
55187
- __publicField(this, "viewer");
55188
- __publicField(this, "cube");
55189
- __publicField(this, "sharedBox");
55190
- // state
55191
- __publicField(this, "faceNormal", new Vector3$1());
55192
- __publicField(this, "dragOrigin", new Vector3$1());
55193
- __publicField(this, "dragpPlane", new Plane());
55194
- __publicField(this, "mouseDown");
55195
- __publicField(this, "raycaster", new Raycaster$1());
55196
- __publicField(this, "lastBox", new Box3$1());
55197
- __publicField(this, "unregisters", []);
55198
- __publicField(this, "lastMouse");
55199
- __publicField(this, "ctrlDown", false);
55200
- __publicField(this, "capturedId");
55201
- // Called when mouse enters or leave a face
55202
- __publicField(this, "onFaceEnter");
55203
- // Called the box is reshaped
55204
- __publicField(this, "onBoxStretch");
55205
- // Called when the user is done reshaping the box
55206
- __publicField(this, "onBoxConfirm");
55207
- __publicField(this, "reg", (handler, type, listener2) => {
55208
- handler.addEventListener(type, listener2);
55209
- this.unregisters.push(() => handler.removeEventListener(type, listener2));
55429
+ class SectionBoxHandle extends Mesh {
55430
+ constructor(axes, sign2, size, color) {
55431
+ const geo = createDoubleCone(size);
55432
+ geo.clearGroups();
55433
+ geo.addGroup(0, Infinity, 0);
55434
+ geo.addGroup(0, Infinity, 1);
55435
+ const matBehind = new MeshBasicMaterial({
55436
+ transparent: true,
55437
+ opacity: 0.5,
55438
+ color: color ?? new Color(0),
55439
+ depthTest: false,
55440
+ side: FrontSide
55210
55441
  });
55211
- this.viewer = viewer;
55212
- this.cube = cube;
55213
- this.sharedBox = box;
55442
+ const matAlways = new MeshBasicMaterial({
55443
+ color: color ?? new Color(0),
55444
+ side: FrontSide
55445
+ });
55446
+ super(geo, [matAlways, matBehind]);
55447
+ __publicField(this, "axis");
55448
+ __publicField(this, "sign");
55449
+ __publicField(this, "_forward");
55450
+ __publicField(this, "_color");
55451
+ __publicField(this, "_highlightColor");
55452
+ __publicField(this, "_materials");
55453
+ this._materials = [matAlways, matBehind];
55454
+ this._forward = new Vector3$1();
55455
+ this.forward[axes] = sign2;
55456
+ this.axis = axes;
55457
+ this.sign = sign2;
55458
+ this._color = color ?? new Color(0);
55459
+ this._highlightColor = this._color.clone().lerp(new Color(13421772), 0.8);
55460
+ this.userData.handle = this;
55461
+ this.quaternion.setFromUnitVectors(new Vector3$1(0, -1, 0), this._forward);
55214
55462
  }
55215
- register() {
55216
- if (this.unregister.length > 0) return;
55217
- const canvas = this.viewer.viewport.canvas;
55218
- this.reg(window, "keydown", this.onKey.bind(this));
55219
- this.reg(window, "keyup", this.onKey.bind(this));
55220
- this.reg(canvas, "pointerdown", this.onMouseDown.bind(this));
55221
- this.reg(canvas, "pointermove", this.onMouseMove.bind(this));
55222
- this.reg(canvas, "pointerup", this.onMouseUp.bind(this));
55223
- this.reg(canvas, "pointerleave", this.onPointerLeave.bind(this));
55463
+ setPosition(position) {
55464
+ this.position.copy(position);
55224
55465
  }
55225
- onPointerLeave(event) {
55226
- var _a2;
55227
- if (this.capturedId !== void 0) {
55228
- return;
55229
- }
55230
- this.faceNormal.set(0, 0, 0);
55231
- (_a2 = this.onFaceEnter) == null ? void 0 : _a2.call(this, this.faceNormal);
55466
+ get forward() {
55467
+ return this._forward;
55232
55468
  }
55233
- capturePointer(pointerId) {
55234
- this.releasePointer();
55235
- this.viewer.viewport.canvas.setPointerCapture(pointerId);
55236
- this.capturedId = pointerId;
55469
+ highlight(value) {
55470
+ this.material[0].color.set(value ? this._highlightColor : this._color);
55471
+ this.material[1].color.set(value ? this._highlightColor : this._color);
55237
55472
  }
55238
- releasePointer() {
55239
- if (this.capturedId === void 0) return;
55240
- this.viewer.viewport.canvas.releasePointerCapture(this.capturedId);
55241
- this.capturedId = void 0;
55473
+ dispose() {
55474
+ this.geometry.dispose();
55475
+ this._materials.forEach((m) => m.dispose());
55476
+ }
55477
+ }
55478
+ function createDoubleCone(size) {
55479
+ const coneHeight = 2 * size;
55480
+ const cone1 = new ConeGeometry(size, coneHeight, 12);
55481
+ cone1.translate(0, coneHeight * 0.75, 0);
55482
+ const cone2 = new ConeGeometry(size, coneHeight, 12);
55483
+ cone2.rotateZ(Math.PI);
55484
+ cone2.translate(0, -coneHeight * 0.75, 0);
55485
+ const mergedGeo = mergeGeometries([cone1, cone2]);
55486
+ cone1.dispose();
55487
+ cone2.dispose();
55488
+ return mergedGeo;
55489
+ }
55490
+ class SectionBoxHandles {
55491
+ constructor() {
55492
+ __publicField(this, "up");
55493
+ __publicField(this, "down");
55494
+ __publicField(this, "left");
55495
+ __publicField(this, "right");
55496
+ __publicField(this, "front");
55497
+ __publicField(this, "back");
55498
+ __publicField(this, "meshes");
55499
+ const size = 2;
55500
+ this.up = new SectionBoxHandle("y", 1, size, new Color(65280));
55501
+ this.down = new SectionBoxHandle("y", -1, size, new Color(65280));
55502
+ this.left = new SectionBoxHandle("x", -1, size, new Color(16711680));
55503
+ this.right = new SectionBoxHandle("x", 1, size, new Color(16711680));
55504
+ this.front = new SectionBoxHandle("z", 1, size, new Color(255));
55505
+ this.back = new SectionBoxHandle("z", -1, size, new Color(255));
55506
+ this.meshes = new Group();
55507
+ this.meshes.add(this.up);
55508
+ this.meshes.add(this.down);
55509
+ this.meshes.add(this.left);
55510
+ this.meshes.add(this.right);
55511
+ this.meshes.add(this.front);
55512
+ this.meshes.add(this.back);
55242
55513
  }
55243
- unregister() {
55244
- this.ctrlDown = false;
55245
- this.mouseDown = false;
55246
- this.releasePointer();
55247
- this.viewer.inputs.registerAll();
55248
- this.unregisters.forEach((unreg) => unreg());
55249
- this.unregisters.length = 0;
55514
+ get visible() {
55515
+ return this.meshes.visible;
55250
55516
  }
55251
- onKey(event) {
55252
- if (this.ctrlDown !== event.ctrlKey) {
55253
- this.ctrlDown = event.ctrlKey;
55254
- this.onMouseMove(this.lastMouse);
55255
- }
55517
+ set visible(value) {
55518
+ this.meshes.visible = value;
55256
55519
  }
55257
- onMouseMove(event) {
55258
- var _a2, _b2, _c;
55259
- this.lastMouse = event;
55260
- if (this.mouseDown) {
55261
- this.onDrag(event);
55262
- return;
55263
- }
55264
- const hits = this.raycast(
55265
- new Vector2$1(event.offsetX, event.offsetY),
55266
- this.ctrlDown
55267
- );
55268
- const hit = hits == null ? void 0 : hits[0];
55269
- const norm = (_a2 = hit == null ? void 0 : hit.face) == null ? void 0 : _a2.normal;
55270
- if (!norm) {
55271
- if (this.faceNormal.x !== 0 || this.faceNormal.y !== 0 || this.faceNormal.z !== 0) {
55272
- this.faceNormal.set(0, 0, 0);
55273
- (_b2 = this.onFaceEnter) == null ? void 0 : _b2.call(this, this.faceNormal);
55274
- }
55275
- return;
55276
- }
55277
- if (this.faceNormal.equals(norm)) {
55278
- return;
55279
- }
55280
- this.faceNormal = norm;
55281
- (_c = this.onFaceEnter) == null ? void 0 : _c.call(this, this.faceNormal);
55520
+ fitBox(box) {
55521
+ const center = box.getCenter(new Vector3$1());
55522
+ this.up.setPosition(new Vector3$1(center.x, box.max.y, center.z));
55523
+ this.down.setPosition(new Vector3$1(center.x, box.min.y, center.z));
55524
+ this.left.setPosition(new Vector3$1(box.min.x, center.y, center.z));
55525
+ this.right.setPosition(new Vector3$1(box.max.x, center.y, center.z));
55526
+ this.front.setPosition(new Vector3$1(center.x, center.y, box.max.z));
55527
+ this.back.setPosition(new Vector3$1(center.x, center.y, box.min.z));
55282
55528
  }
55283
- onMouseUp(event) {
55284
- var _a2, _b2;
55285
- this.releasePointer();
55286
- if (this.mouseDown) {
55287
- this.mouseDown = false;
55288
- this.viewer.inputs.registerAll();
55289
- if (event.pointerType === "mouse") {
55290
- this.onMouseMove(event);
55291
- } else {
55292
- this.faceNormal = new Vector3$1();
55293
- (_a2 = this.onFaceEnter) == null ? void 0 : _a2.call(this, this.faceNormal);
55294
- }
55295
- (_b2 = this.onBoxConfirm) == null ? void 0 : _b2.call(this, this.sharedBox);
55296
- }
55529
+ dispose() {
55530
+ this.up.dispose();
55531
+ this.down.dispose();
55532
+ this.left.dispose();
55533
+ this.right.dispose();
55534
+ this.front.dispose();
55535
+ this.back.dispose();
55297
55536
  }
55298
- onMouseDown(event) {
55299
- var _a2, _b2;
55300
- const hits = this.raycast(
55301
- new Vector2$1(event.offsetX, event.offsetY),
55302
- this.ctrlDown
55303
- );
55304
- const hit = hits == null ? void 0 : hits[0];
55305
- if (!((_a2 = hit == null ? void 0 : hit.face) == null ? void 0 : _a2.normal)) return;
55306
- this.capturePointer(event.pointerId);
55307
- this.lastBox.copy(this.sharedBox);
55308
- this.faceNormal = hit.face.normal;
55309
- this.dragOrigin.copy(hit.point);
55310
- const dist2 = hit.point.clone().dot(this.viewer.camera.forward);
55311
- this.dragpPlane.set(this.viewer.camera.forward, -dist2);
55312
- this.mouseDown = true;
55313
- this.viewer.inputs.unregisterAll();
55314
- (_b2 = this.onFaceEnter) == null ? void 0 : _b2.call(this, this.faceNormal);
55537
+ }
55538
+ class SectionBoxGizmo {
55539
+ constructor(renderer) {
55540
+ __publicField(this, "_renderer");
55541
+ __publicField(this, "cube");
55542
+ __publicField(this, "outline");
55543
+ __publicField(this, "handles");
55544
+ __publicField(this, "_visible", false);
55545
+ this._renderer = renderer;
55546
+ this.cube = new SectionBoxMesh();
55547
+ this.outline = new SectionBoxOutline(new Color(8882833));
55548
+ this.handles = new SectionBoxHandles();
55549
+ this._renderer.add(this.outline);
55550
+ this._renderer.add(this.handles.meshes);
55551
+ this.visible = false;
55315
55552
  }
55316
- onDrag(event) {
55317
- var _a2;
55318
- this.raycaster = this.viewer.raycaster.fromPoint2(
55319
- new Vector2$1(event.offsetX, event.offsetY),
55320
- this.raycaster
55321
- );
55322
- const point = this.raycaster.ray.intersectPlane(this.dragpPlane, new Vector3$1()) ?? this.dragOrigin.clone();
55323
- const delta = point.sub(this.dragOrigin);
55324
- const amount = delta.dot(this.faceNormal);
55325
- const box = this.stretch(this.faceNormal, amount);
55326
- (_a2 = this.onBoxStretch) == null ? void 0 : _a2.call(this, box);
55553
+ get visible() {
55554
+ return this._visible;
55327
55555
  }
55328
- stretch(normal, amount) {
55329
- const result = this.sharedBox.clone();
55330
- if (normal.x > 0.1) {
55331
- result.max.setX(Math.max(this.lastBox.max.x + amount, result.min.x - 1));
55332
- }
55333
- if (normal.x < -0.1) {
55334
- result.min.setX(Math.min(this.lastBox.min.x - amount, result.max.x + 1));
55335
- }
55336
- if (normal.y > 0.1) {
55337
- result.max.setY(Math.max(this.lastBox.max.y + amount, result.min.y - 1));
55338
- }
55339
- if (normal.y < -0.1) {
55340
- result.min.setY(Math.min(this.lastBox.min.y - amount, result.max.y + 1));
55341
- }
55342
- if (normal.z > 0.1) {
55343
- result.max.setZ(Math.max(this.lastBox.max.z + amount, result.min.z - 1));
55344
- }
55345
- if (normal.z < -0.1) {
55346
- result.min.setZ(Math.min(this.lastBox.min.z - amount, result.max.z + 1));
55347
- }
55348
- return result;
55556
+ set visible(value) {
55557
+ this._visible = value;
55558
+ this.cube.visible = value;
55559
+ this.outline.visible = value;
55560
+ this.handles.visible = value;
55349
55561
  }
55350
- raycast(position, reverse) {
55351
- this.raycaster = this.viewer.raycaster.fromPoint2(position, this.raycaster);
55352
- if (reverse) {
55353
- this.raycaster.ray.set(
55354
- this.raycaster.ray.origin.clone().add(this.raycaster.ray.direction.clone().multiplyScalar(this.viewer.settings.camera.far)),
55355
- this.raycaster.ray.direction.negate()
55356
- );
55357
- }
55358
- return this.raycaster.intersectObject(this.cube);
55562
+ fitBox(box) {
55563
+ this.cube.fitBox(box);
55564
+ this.outline.fitBox(box);
55565
+ this.handles.fitBox(box);
55566
+ }
55567
+ dispose() {
55568
+ this._renderer.remove(this.cube);
55569
+ this._renderer.remove(this.outline);
55570
+ this._renderer.remove(this.handles.meshes);
55571
+ this.cube.dispose();
55572
+ this.outline.dispose();
55573
+ this.handles.dispose();
55359
55574
  }
55360
55575
  }
55361
- class SectionBox {
55576
+ let SectionBox$1 = class SectionBox {
55577
+ // -------------------------------------------------------------------------
55578
+ // Constructor
55579
+ // -------------------------------------------------------------------------
55580
+ /**
55581
+ * Creates a new SectionBox gizmo controller.
55582
+ *
55583
+ * @param viewer - The parent {@link Viewer} in which the section box is rendered.
55584
+ */
55362
55585
  constructor(viewer) {
55363
- // dependencies
55586
+ // -------------------------------------------------------------------------
55587
+ // Private fields
55588
+ // -------------------------------------------------------------------------
55364
55589
  __publicField(this, "_viewer");
55365
- // resources
55590
+ __publicField(this, "_gizmos");
55366
55591
  __publicField(this, "_inputs");
55367
- __publicField(this, "_cube");
55368
- __publicField(this, "_outline");
55369
- __publicField(this, "_highlight");
55370
- // State
55371
- __publicField(this, "_normal");
55372
55592
  __publicField(this, "_clip");
55373
55593
  __publicField(this, "_visible");
55374
55594
  __publicField(this, "_interactive");
@@ -55376,21 +55596,13 @@ class SectionBox {
55376
55596
  __publicField(this, "_onBoxConfirm", new distExports.SimpleEventDispatcher());
55377
55597
  __publicField(this, "_onHover", new distExports.SimpleEventDispatcher());
55378
55598
  this._viewer = viewer;
55379
- this._normal = new Vector3$1();
55380
- this._cube = new BoxMesh();
55381
- this._outline = new BoxOutline();
55382
- this._highlight = new BoxHighlight();
55383
- this.renderer.add(this._cube);
55384
- this.renderer.add(this._outline);
55385
- this.renderer.add(this._highlight);
55599
+ this._gizmos = new SectionBoxGizmo(viewer.renderer);
55386
55600
  this._inputs = new BoxInputs(
55387
55601
  viewer,
55388
- this._cube,
55602
+ this._gizmos.handles,
55389
55603
  this._viewer.renderer.section.box
55390
55604
  );
55391
55605
  this._inputs.onFaceEnter = (normal) => {
55392
- this._normal = normal;
55393
- if (this.visible) this._highlight.highlight(this.section.box, normal);
55394
55606
  this._onHover.dispatch(normal.x !== 0 || normal.y !== 0 || normal.z !== 0);
55395
55607
  this.renderer.needsUpdate = true;
55396
55608
  };
@@ -55405,37 +55617,61 @@ class SectionBox {
55405
55617
  this.update();
55406
55618
  }
55407
55619
  /**
55408
- * Signal dispatched when clip, show, or interactive are updated.
55620
+ * @internal
55621
+ * A convenience getter to the viewer's renderer.
55622
+ */
55623
+ get renderer() {
55624
+ return this._viewer.renderer;
55625
+ }
55626
+ /**
55627
+ * @internal
55628
+ * A convenience getter to the `Section` module in the renderer.
55629
+ */
55630
+ get section() {
55631
+ return this._viewer.renderer.section;
55632
+ }
55633
+ // -------------------------------------------------------------------------
55634
+ // Public Signals
55635
+ // -------------------------------------------------------------------------
55636
+ /**
55637
+ * Dispatches when any of the following properties change:
55638
+ * - {@link clip} (clipping planes active)
55639
+ * - {@link visible} (gizmo visibility)
55640
+ * - {@link interactive} (pointer inputs active)
55409
55641
  */
55410
55642
  get onStateChanged() {
55411
55643
  return this._onStateChanged.asEvent();
55412
55644
  }
55413
55645
  /**
55414
- * Signal dispatched when user is done manipulating the box.
55646
+ * Dispatches when the user finishes manipulating (dragging) the box.
55647
+ * The payload is the final {@link THREE.Box3} used for clipping.
55415
55648
  */
55416
55649
  get onBoxConfirm() {
55417
55650
  return this._onBoxConfirm.asEvent();
55418
55651
  }
55419
55652
  /**
55420
- * Signal dispatched with true when pointer enters box and false when pointer leaves.
55653
+ * Dispatches a boolean indicating pointer hover state on the box handles:
55654
+ * - `true` if the pointer has entered a handle
55655
+ * - `false` if it has left or no handle is hovered
55421
55656
  */
55422
55657
  get onHover() {
55423
55658
  return this._onHover.asEvent();
55424
55659
  }
55425
- get renderer() {
55426
- return this._viewer.renderer;
55427
- }
55428
- get section() {
55429
- return this._viewer.renderer.section;
55430
- }
55660
+ // -------------------------------------------------------------------------
55661
+ // Public Properties
55662
+ // -------------------------------------------------------------------------
55431
55663
  /**
55432
- * Section bounding box, to update the box use fitBox.
55664
+ * The shared bounding box that defines the section region.
55665
+ *
55666
+ * To programmatically update the box, see {@link fitBox}.
55433
55667
  */
55434
55668
  get box() {
55435
55669
  return this.section.box;
55436
55670
  }
55437
55671
  /**
55438
- * Determines whether the section gizmo will section the model with clipping planes.
55672
+ * Determines whether the section gizmo applies clipping planes to the model.
55673
+ *
55674
+ * When `true`, `renderer.section.active` is enabled.
55439
55675
  */
55440
55676
  get clip() {
55441
55677
  return this._clip ?? false;
@@ -55447,71 +55683,79 @@ class SectionBox {
55447
55683
  this._onStateChanged.dispatch();
55448
55684
  }
55449
55685
  /**
55450
- * Determines whether the gizmo reacts to user inputs.
55686
+ * Determines whether the gizmo is interactive (i.e. responds to pointer events).
55687
+ *
55688
+ * When `true`, pointer events are registered and box handles can be dragged.
55451
55689
  */
55452
55690
  get interactive() {
55453
55691
  return this._interactive ?? false;
55454
55692
  }
55455
55693
  set interactive(value) {
55456
55694
  if (value === this._interactive) return;
55457
- if (!this._interactive && value) this._inputs.register();
55458
- if (this._interactive && !value) this._inputs.unregister();
55695
+ if (!this._interactive && value) {
55696
+ this._inputs.register();
55697
+ }
55698
+ if (this._interactive && !value) {
55699
+ this._inputs.unregister();
55700
+ }
55459
55701
  this._interactive = value;
55460
- this._highlight.visible = false;
55461
55702
  this.renderer.needsUpdate = true;
55462
55703
  this._onStateChanged.dispatch();
55463
55704
  }
55464
55705
  /**
55465
- * Determines whether the gizmo will be rendered.
55706
+ * Determines whether the section box gizmo is visible in the scene.
55466
55707
  */
55467
55708
  get visible() {
55468
55709
  return this._visible ?? false;
55469
55710
  }
55470
55711
  set visible(value) {
55471
55712
  if (value === this._visible) return;
55472
- this._visible = value;
55473
- this._cube.visible = value;
55474
- this._outline.visible = value;
55475
- this._highlight.visible = value;
55476
- if (value) this.update();
55713
+ this._gizmos.visible = value;
55714
+ if (value) {
55715
+ this.update();
55716
+ }
55477
55717
  this.renderer.needsUpdate = true;
55478
55718
  this._onStateChanged.dispatch();
55479
55719
  }
55720
+ // -------------------------------------------------------------------------
55721
+ // Public Methods
55722
+ // -------------------------------------------------------------------------
55480
55723
  /**
55481
- * Sets the section gizmo size to match the given box.
55482
- * @param {THREE.Box3} box - The box to match the section gizmo size to.
55483
- * @param {number} [padding=1] - The padding to apply to the box.
55724
+ * Resizes the section gizmo to match the given box, optionally expanded by a padding.
55725
+ * After resizing, this method also updates the renderer's clipping box.
55726
+ *
55727
+ * @param box - The bounding box to match (required).
55728
+ * @param padding - The scalar amount by which to expand the bounding box. Default is `1`.
55484
55729
  */
55485
55730
  fitBox(box, padding = 1) {
55486
55731
  if (!box) return;
55487
55732
  const b = box.expandByScalar(padding);
55488
- this._cube.fitBox(b);
55489
- this._outline.fitBox(b);
55733
+ this._gizmos.fitBox(b);
55490
55734
  this.renderer.section.fitBox(b);
55491
55735
  this._onBoxConfirm.dispatch(this.box);
55492
55736
  this.renderer.needsUpdate = true;
55493
55737
  }
55494
55738
  /**
55495
- * Call this if there were direct changes to renderer.section
55739
+ * Updates the section box to match the current size of `this.section.box`.
55740
+ *
55741
+ * Call this if the renderer's section box is changed by code outside this class.
55496
55742
  */
55497
55743
  update() {
55498
55744
  this.fitBox(this.section.box, 0);
55499
- this._highlight.highlight(this.section.box, this._normal);
55500
55745
  this.renderer.needsUpdate = true;
55501
55746
  }
55502
55747
  /**
55503
- * Removes gizmo from rendering and inputs and dispose all resources.
55748
+ * Disposes of the gizmo and input event listeners, cleaning up related resources.
55749
+ *
55750
+ * After disposal, this `SectionBox` instance should no longer be used.
55504
55751
  */
55505
55752
  dispose() {
55506
- this.renderer.remove(this._cube);
55507
- this.renderer.remove(this._outline);
55508
- this.renderer.remove(this._highlight);
55753
+ this._onBoxConfirm.clear();
55754
+ this._onHover.clear();
55755
+ this._gizmos.dispose();
55509
55756
  this._inputs.unregister();
55510
- this._cube.dispose();
55511
- this._outline.dispose();
55512
- this._highlight.dispose();
55513
55757
  }
55514
- }
55758
+ };
55515
55759
  class Gizmos {
55516
55760
  constructor(viewer, camera2) {
55517
55761
  __publicField(this, "viewer");
@@ -55543,7 +55787,7 @@ class Gizmos {
55543
55787
  var _a2;
55544
55788
  this.viewer = viewer;
55545
55789
  this._measure = new Measure(viewer);
55546
- this.section = new SectionBox(viewer);
55790
+ this.section = new SectionBox$1(viewer);
55547
55791
  this.loading = new GizmoLoading(viewer);
55548
55792
  this.orbit = new GizmoOrbit(
55549
55793
  viewer.renderer,
@@ -55621,7 +55865,6 @@ class RenderingSection {
55621
55865
  this.minZ.constant = -box.min.z;
55622
55866
  this.box.copy(box);
55623
55867
  this._renderer.needsUpdate = true;
55624
- this._renderer.skipAntialias = true;
55625
55868
  }
55626
55869
  /**
55627
55870
  * Determines whether objecets outside the section box will be culled or not.
@@ -56580,7 +56823,6 @@ let Renderer$1 = class Renderer {
56580
56823
  __publicField(this, "_composer");
56581
56824
  __publicField(this, "_materials");
56582
56825
  __publicField(this, "_renderText");
56583
- __publicField(this, "_skipAntialias");
56584
56826
  __publicField(this, "_needsUpdate");
56585
56827
  __publicField(this, "_onSceneUpdate", new distExports$1.SignalDispatcher());
56586
56828
  __publicField(this, "_onBoxUpdated", new distExports$1.SignalDispatcher());
@@ -56642,17 +56884,6 @@ let Renderer$1 = class Renderer {
56642
56884
  set needsUpdate(value) {
56643
56885
  this._needsUpdate = this._needsUpdate || value;
56644
56886
  }
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
56887
  /**
56657
56888
  * Removes all objects from rendering and disposes the WebGL context.
56658
56889
  */
@@ -56673,6 +56904,12 @@ let Renderer$1 = class Renderer {
56673
56904
  this._scene.scene.background = color;
56674
56905
  this.needsUpdate = true;
56675
56906
  }
56907
+ get modelMaterial() {
56908
+ return this._scene.modelMaterial;
56909
+ }
56910
+ set modelMaterial(material) {
56911
+ this._scene.modelMaterial = material;
56912
+ }
56676
56913
  /**
56677
56914
  * Signal dispatched at the end of each frame if the scene was updated, such as visibility changes.
56678
56915
  */
@@ -56697,6 +56934,12 @@ let Renderer$1 = class Renderer {
56697
56934
  this._renderText = value;
56698
56935
  this.textRenderer.domElement.style.display = value ? "block" : "none";
56699
56936
  }
56937
+ get smallGhostThreshold() {
56938
+ return this._scene.smallGhostThreshold;
56939
+ }
56940
+ set smallGhostThreshold(value) {
56941
+ this._scene.smallGhostThreshold = value;
56942
+ }
56700
56943
  /**
56701
56944
  * Returns the bounding box encompassing all rendered objects.
56702
56945
  * @param target - Box in which to copy the result. A new instance is created if undefined.
@@ -56736,7 +56979,6 @@ let Renderer$1 = class Renderer {
56736
56979
  this._composer.render();
56737
56980
  }
56738
56981
  this._needsUpdate = false;
56739
- this.skipAntialias = false;
56740
56982
  if (this.textEnabled && this._scene.has2dObjects()) {
56741
56983
  this.textRenderer.render(this._scene.scene, this._camera.three);
56742
56984
  }
@@ -57002,14 +57244,6 @@ function parseSettingsFromUrl(url) {
57002
57244
  groundColor: get3("skybox.groundColor", strToColor),
57003
57245
  sharpness: get3("skybox.sharpness", Number.parseFloat)
57004
57246
  },
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
57247
  skylight: {
57014
57248
  skyColor: get3("skylight.skyColor", strToColor),
57015
57249
  groundColor: get3("skylight.groundColor", strToColor),
@@ -57037,9 +57271,9 @@ function parseSettingsFromUrl(url) {
57037
57271
  color: get3("materials.highlight.color", strToColor),
57038
57272
  opacity: get3("materials.highlight.opacity", Number.parseFloat)
57039
57273
  },
57040
- isolation: {
57041
- color: get3("materials.isolation.color", strToColor),
57042
- opacity: get3("materials.isolation.opacity", Number.parseFloat)
57274
+ ghost: {
57275
+ color: get3("materials.ghost.color", strToColor),
57276
+ opacity: get3("materials.ghost.opacity", Number.parseFloat)
57043
57277
  },
57044
57278
  section: {
57045
57279
  strokeWidth: get3("materials.section.strokeWidth", Number.parseFloat),
@@ -57786,17 +58020,16 @@ function isWebSocketUrl(input) {
57786
58020
  class Marshal {
57787
58021
  constructor(initialSize = 1024) {
57788
58022
  __publicField(this, "buffer");
57789
- __publicField(this, "dataView");
57790
- __publicField(this, "readOffset", 0);
57791
- __publicField(this, "writeOffset", 0);
58023
+ __publicField(this, "_dataView");
58024
+ __publicField(this, "_offset", 0);
57792
58025
  this.buffer = new ArrayBuffer(initialSize);
57793
- this.dataView = new DataView(this.buffer);
58026
+ this._dataView = new DataView(this.buffer);
57794
58027
  }
57795
58028
  getBuffer() {
57796
- return this.buffer.slice(0, this.writeOffset);
58029
+ return this.buffer.slice(0, this._offset);
57797
58030
  }
57798
58031
  ensureCapacity(additionalSize) {
57799
- const requiredSize = this.writeOffset + additionalSize;
58032
+ const requiredSize = this._offset + additionalSize;
57800
58033
  if (requiredSize > this.buffer.byteLength) {
57801
58034
  let newLength = this.buffer.byteLength;
57802
58035
  while (newLength < requiredSize) {
@@ -57805,21 +58038,162 @@ class Marshal {
57805
58038
  const newBuffer = new ArrayBuffer(newLength);
57806
58039
  new Uint8Array(newBuffer).set(new Uint8Array(this.buffer));
57807
58040
  this.buffer = newBuffer;
57808
- this.dataView = new DataView(this.buffer);
58041
+ this._dataView = new DataView(this.buffer);
57809
58042
  }
57810
58043
  }
57811
58044
  writeData(data2) {
57812
58045
  this.ensureCapacity(data2.byteLength);
57813
- new Uint8Array(this.buffer, this.writeOffset).set(new Uint8Array(data2));
57814
- this.writeOffset += data2.byteLength;
58046
+ new Uint8Array(this.buffer, this._offset).set(new Uint8Array(data2));
58047
+ this._offset += data2.byteLength;
57815
58048
  }
57816
- // -------------------- Matrix44 Methods --------------------
58049
+ // -------------------- Matrix44 -------------------
57817
58050
  writeMatrix44(data2) {
57818
58051
  this.ensureCapacity(4 * 4 * 4);
57819
58052
  this.writeArray(data2.toArray(), 4, (element) => {
57820
58053
  this.writeFloat(element);
57821
58054
  });
57822
58055
  }
58056
+ // -------------------- Boolean -------------------
58057
+ writeBoolean(value) {
58058
+ this.ensureCapacity(4);
58059
+ this._dataView.setUint32(this._offset, value ? 1 : 0, true);
58060
+ this._offset += 4;
58061
+ }
58062
+ // -------------------- Int -------------------
58063
+ writeInt(value) {
58064
+ this.ensureCapacity(4);
58065
+ this._dataView.setInt32(this._offset, value, true);
58066
+ this._offset += 4;
58067
+ }
58068
+ // -------------------- UInt -------------------
58069
+ writeUInt(value) {
58070
+ this.ensureCapacity(4);
58071
+ this._dataView.setUint32(this._offset, value, true);
58072
+ this._offset += 4;
58073
+ }
58074
+ // -------------------- Float -------------------
58075
+ writeFloat(value) {
58076
+ this.ensureCapacity(4);
58077
+ this._dataView.setFloat32(this._offset, value, true);
58078
+ this._offset += 4;
58079
+ }
58080
+ // -------------------- String -------------------
58081
+ writeString(value) {
58082
+ const textEncoder = new TextEncoder();
58083
+ const encodedString = textEncoder.encode(value + "\0");
58084
+ this.ensureCapacity(4 + encodedString.byteLength);
58085
+ this.writeUInt(encodedString.length);
58086
+ new Uint8Array(this.buffer, this._offset).set(encodedString);
58087
+ this._offset += encodedString.length;
58088
+ }
58089
+ // -------------------- HitCheckResult -------------------
58090
+ writeHitCheckResult(data2) {
58091
+ this.ensureCapacity(4 + 4 + 4 * 3 + 4 * 3);
58092
+ this.writeUInt(data2.vimHandle);
58093
+ this.writeUInt(data2.nodeIndex);
58094
+ this.writeVector3(data2.worldPosition);
58095
+ this.writeVector3(data2.worldNormal);
58096
+ }
58097
+ // -------------------- VimStatus -------------------
58098
+ writeVimStatus(data2) {
58099
+ this.ensureCapacity(4 + 4);
58100
+ this.writeUInt(data2.status);
58101
+ this.writeFloat(data2.progress);
58102
+ }
58103
+ // -------------------- Vector2 -------------------
58104
+ writeVector2(data2) {
58105
+ this.ensureCapacity(4 + 4);
58106
+ this.writeFloat(data2.x);
58107
+ this.writeFloat(data2.y);
58108
+ }
58109
+ // -------------------- Vector3 -------------------
58110
+ writeVector3(data2) {
58111
+ this.ensureCapacity(4 + 4 + 4);
58112
+ this.writeFloat(data2.x);
58113
+ this.writeFloat(data2.y);
58114
+ this.writeFloat(data2.z);
58115
+ }
58116
+ // -------------------- Vector4 -------------------
58117
+ writeVector4(data2) {
58118
+ this.ensureCapacity(4 + 4 + 4 + 4);
58119
+ this.writeFloat(data2.x);
58120
+ this.writeFloat(data2.y);
58121
+ this.writeFloat(data2.z);
58122
+ this.writeFloat(data2.w);
58123
+ }
58124
+ // -------------------- RGBA -------------------
58125
+ writeRGBA(color) {
58126
+ this.ensureCapacity(4 + 4 + 4 + 4);
58127
+ this.writeFloat(color.r);
58128
+ this.writeFloat(color.g);
58129
+ this.writeFloat(color.b);
58130
+ this.writeFloat(color.a);
58131
+ }
58132
+ // -------------------- RGB -------------------
58133
+ writeRGB(color) {
58134
+ this.ensureCapacity(4 + 4 + 4 + 4);
58135
+ this.writeFloat(color.r);
58136
+ this.writeFloat(color.g);
58137
+ this.writeFloat(color.b);
58138
+ }
58139
+ // -------------------- RGBA32 -------------------
58140
+ writeRGBA32(color) {
58141
+ this.ensureCapacity(4);
58142
+ this.writeUInt(color.hex);
58143
+ }
58144
+ // -------------------- CameraPositionAndTarget -------------------
58145
+ writeSegment(segment) {
58146
+ this.ensureCapacity(4 * 3 * 2);
58147
+ this.writeVector3(segment.origin);
58148
+ this.writeVector3(segment.target);
58149
+ }
58150
+ // -------------------- Box3 -------------------
58151
+ writeBox3(data2) {
58152
+ this.ensureCapacity(4 * 3 * 2);
58153
+ this.writeVector3(data2.min);
58154
+ this.writeVector3(data2.max);
58155
+ }
58156
+ // -------------------- SectionBox -------------------
58157
+ writeSectionBoxState(data2) {
58158
+ this.writeBoolean(data2.enabled);
58159
+ this.writeBoolean(data2.visible);
58160
+ this.writeBoolean(data2.interactible);
58161
+ this.writeBoolean(data2.clip);
58162
+ this.writeBox3(data2.box);
58163
+ }
58164
+ // -------------------- Array of Int -------------------
58165
+ writeArrayOfInt(values) {
58166
+ this.writeArray(values, 4, (v) => this.writeInt(v));
58167
+ }
58168
+ // -------------------- Array of UInt -------------------
58169
+ writeArrayOfUInt(values) {
58170
+ this.writeArray(values, 4, (v) => this.writeUInt(v));
58171
+ }
58172
+ // -------------------- Array of Float -------------------
58173
+ writeArrayOfFloat(values) {
58174
+ this.writeArray(values, 4, (v) => this.writeFloat(v));
58175
+ }
58176
+ // -------------------- Array of Bool -------------------
58177
+ writeArrayOfBool(values) {
58178
+ this.writeArray(values, 4, (v) => this.writeBoolean(v));
58179
+ }
58180
+ // -------------------- Array of RGBA32 -------------------
58181
+ writeArrayOfRGBA32(values) {
58182
+ this.writeArray(values, 4, (v) => this.writeRGBA32(v));
58183
+ }
58184
+ // -------------------- Helpers --------------------
58185
+ writeArray(data2, sizeT, write) {
58186
+ this.ensureCapacity(4 + data2.length * sizeT);
58187
+ this.writeUInt(data2.length);
58188
+ data2.forEach((value) => write(value));
58189
+ }
58190
+ }
58191
+ class ReadMarshal {
58192
+ constructor(buffer) {
58193
+ __publicField(this, "_dataView");
58194
+ __publicField(this, "_offset", 0);
58195
+ this._dataView = new DataView(buffer);
58196
+ }
57823
58197
  readMatrix44() {
57824
58198
  const m00 = this.readFloat();
57825
58199
  const m01 = this.readFloat();
@@ -57839,74 +58213,33 @@ class Marshal {
57839
58213
  const m33 = this.readFloat();
57840
58214
  return new Matrix4(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33);
57841
58215
  }
57842
- // -------------------- Boolean Methods --------------------
57843
- writeBoolean(value) {
57844
- this.ensureCapacity(4);
57845
- this.dataView.setUint32(this.writeOffset, value ? 1 : 0, true);
57846
- this.writeOffset += 4;
57847
- }
57848
- readBoolean() {
57849
- const value = this.dataView.getUint32(this.readOffset, true);
57850
- this.readOffset += 4;
57851
- return value !== 0;
57852
- }
57853
- // -------------------- Int Methods --------------------
57854
- writeInt(value) {
57855
- this.ensureCapacity(4);
57856
- this.dataView.setInt32(this.writeOffset, value, true);
57857
- this.writeOffset += 4;
57858
- }
57859
58216
  readInt() {
57860
- const value = this.dataView.getInt32(this.readOffset, true);
57861
- this.readOffset += 4;
58217
+ const value = this._dataView.getInt32(this._offset, true);
58218
+ this._offset += 4;
57862
58219
  return value;
57863
58220
  }
57864
- // -------------------- UInt Methods --------------------
57865
- writeUInt(value) {
57866
- this.ensureCapacity(4);
57867
- this.dataView.setUint32(this.writeOffset, value, true);
57868
- this.writeOffset += 4;
57869
- }
57870
58221
  readUInt() {
57871
- const value = this.dataView.getUint32(this.readOffset, true);
57872
- this.readOffset += 4;
58222
+ const value = this._dataView.getUint32(this._offset, true);
58223
+ this._offset += 4;
57873
58224
  return value;
57874
58225
  }
57875
- // -------------------- Float Methods --------------------
57876
- writeFloat(value) {
57877
- this.ensureCapacity(4);
57878
- this.dataView.setFloat32(this.writeOffset, value, true);
57879
- this.writeOffset += 4;
57880
- }
57881
58226
  readFloat() {
57882
- const value = this.dataView.getFloat32(this.readOffset, true);
57883
- this.readOffset += 4;
58227
+ const value = this._dataView.getFloat32(this._offset, true);
58228
+ this._offset += 4;
57884
58229
  return value;
57885
58230
  }
57886
- // -------------------- String Methods --------------------
57887
- writeString(value) {
57888
- const textEncoder = new TextEncoder();
57889
- const encodedString = textEncoder.encode(value + "\0");
57890
- this.ensureCapacity(4 + encodedString.byteLength);
57891
- this.writeUInt(encodedString.length);
57892
- new Uint8Array(this.buffer, this.writeOffset).set(encodedString);
57893
- this.writeOffset += encodedString.length;
58231
+ readBoolean() {
58232
+ const value = this._dataView.getUint32(this._offset, true);
58233
+ this._offset += 4;
58234
+ return value !== 0;
57894
58235
  }
57895
58236
  readString() {
57896
58237
  const length = this.readUInt();
57897
58238
  const textDecoder = new TextDecoder();
57898
- const stringData = new Uint8Array(this.buffer, this.readOffset, length - 1);
57899
- this.readOffset += length;
58239
+ const stringData = new Uint8Array(this._dataView.buffer, this._offset, length - 1);
58240
+ this._offset += length;
57900
58241
  return textDecoder.decode(stringData);
57901
58242
  }
57902
- // -------------------- HitCheckResult Methods --------------------
57903
- writeHitCheckResult(data2) {
57904
- this.ensureCapacity(4 + 4 + 4 * 3 + 4 * 3);
57905
- this.writeUInt(data2.vimHandle);
57906
- this.writeUInt(data2.nodeIndex);
57907
- this.writeVector3(data2.worldPosition);
57908
- this.writeVector3(data2.worldNormal);
57909
- }
57910
58243
  readHitCheckResult() {
57911
58244
  const vimHandle = this.readUInt();
57912
58245
  const nodeIndex = this.readUInt();
@@ -57919,12 +58252,6 @@ class Marshal {
57919
58252
  worldNormal
57920
58253
  };
57921
58254
  }
57922
- // -------------------- VimStatus Methods --------------------
57923
- writeVimStatus(data2) {
57924
- this.ensureCapacity(4 + 4);
57925
- this.writeUInt(data2.status);
57926
- this.writeFloat(data2.progress);
57927
- }
57928
58255
  readVimStatus() {
57929
58256
  const status = this.readUInt();
57930
58257
  const progress = this.readFloat();
@@ -57933,38 +58260,17 @@ class Marshal {
57933
58260
  progress
57934
58261
  };
57935
58262
  }
57936
- // -------------------- Vector2 Methods --------------------
57937
- writeVector2(data2) {
57938
- this.ensureCapacity(4 + 4);
57939
- this.writeFloat(data2.x);
57940
- this.writeFloat(data2.y);
57941
- }
57942
58263
  readVector2() {
57943
58264
  const x = this.readFloat();
57944
58265
  const y = this.readFloat();
57945
58266
  return new Vector22(x, y);
57946
58267
  }
57947
- // -------------------- Vector3 Methods --------------------
57948
- writeVector3(data2) {
57949
- this.ensureCapacity(4 + 4 + 4);
57950
- this.writeFloat(data2.x);
57951
- this.writeFloat(data2.y);
57952
- this.writeFloat(data2.z);
57953
- }
57954
58268
  readVector3() {
57955
58269
  const x = this.readFloat();
57956
58270
  const y = this.readFloat();
57957
58271
  const z = this.readFloat();
57958
58272
  return new Vector32(x, y, z);
57959
58273
  }
57960
- // -------------------- Vector4 Methods --------------------
57961
- writeVector4(data2) {
57962
- this.ensureCapacity(4 + 4 + 4 + 4);
57963
- this.writeFloat(data2.x);
57964
- this.writeFloat(data2.y);
57965
- this.writeFloat(data2.z);
57966
- this.writeFloat(data2.w);
57967
- }
57968
58274
  readVector4() {
57969
58275
  const x = this.readFloat();
57970
58276
  const y = this.readFloat();
@@ -57977,14 +58283,6 @@ class Marshal {
57977
58283
  w
57978
58284
  };
57979
58285
  }
57980
- // -------------------- RGBA Methods --------------------
57981
- writeRGBA(color) {
57982
- this.ensureCapacity(4 + 4 + 4 + 4);
57983
- this.writeFloat(color.r);
57984
- this.writeFloat(color.g);
57985
- this.writeFloat(color.b);
57986
- this.writeFloat(color.a);
57987
- }
57988
58286
  readRGBA() {
57989
58287
  const r = this.readFloat();
57990
58288
  const g = this.readFloat();
@@ -57992,91 +58290,55 @@ class Marshal {
57992
58290
  const a = this.readFloat();
57993
58291
  return new RGBA(r, g, b, a);
57994
58292
  }
57995
- // -------------------- RGB Methods --------------------
57996
- writeRGB(color) {
57997
- this.ensureCapacity(4 + 4 + 4 + 4);
57998
- this.writeFloat(color.r);
57999
- this.writeFloat(color.g);
58000
- this.writeFloat(color.b);
58001
- }
58002
58293
  readRGB() {
58003
58294
  const r = this.readFloat();
58004
58295
  const g = this.readFloat();
58005
58296
  const b = this.readFloat();
58006
- return new RGB(r, g, b);
58007
- }
58008
- // -------------------- RGBA32 Methods --------------------
58009
- writeRGBA32(color) {
58010
- this.ensureCapacity(4);
58011
- this.writeUInt(color.hex);
58297
+ return new RGB(r, g, b);
58012
58298
  }
58013
58299
  readRGBA32() {
58014
58300
  const hex = this.readUInt();
58015
58301
  return new RGBA32(hex);
58016
58302
  }
58017
- // -------------------- CameraPositionAndTarget Methods --------------------
58018
- writeSegment(segment) {
58019
- this.ensureCapacity(4 * 3 * 2);
58020
- this.writeVector3(segment.origin);
58021
- this.writeVector3(segment.target);
58303
+ readBox3() {
58304
+ const min2 = this.readVector3();
58305
+ const max2 = this.readVector3();
58306
+ return new Box32(min2, max2);
58022
58307
  }
58023
58308
  readSegment() {
58024
58309
  const position = this.readVector3();
58025
58310
  const target = this.readVector3();
58026
58311
  return new Segment(position, target);
58027
58312
  }
58028
- // -------------------- Box3 Methods --------------------
58029
- writeBox3(data2) {
58030
- this.ensureCapacity(4 * 3 * 2);
58031
- this.writeVector3(data2.min);
58032
- this.writeVector3(data2.max);
58033
- }
58034
- readBox3() {
58035
- const min2 = this.readVector3();
58036
- const max2 = this.readVector3();
58037
- return new Box32(min2, max2);
58038
- }
58039
- // -------------------- Array of Int Methods --------------------
58040
- writeArrayOfInt(values) {
58041
- this.writeArray(values, 4, (v) => this.writeInt(v));
58313
+ readSectionBoxState() {
58314
+ const enabled = this.readBoolean();
58315
+ const visible2 = this.readBoolean();
58316
+ const interactible = this.readBoolean();
58317
+ const clip = this.readBoolean();
58318
+ const box = this.readBox3();
58319
+ return {
58320
+ enabled,
58321
+ visible: visible2,
58322
+ interactible,
58323
+ clip,
58324
+ box
58325
+ };
58042
58326
  }
58043
58327
  readArrayOfInt() {
58044
58328
  return this.readArray(() => this.readInt());
58045
58329
  }
58046
- // -------------------- Array of UInt Methods --------------------
58047
- writeArrayOfUInt(values) {
58048
- this.writeArray(values, 4, (v) => this.writeUInt(v));
58049
- }
58050
58330
  readArrayOfUInt() {
58051
58331
  return this.readArray(() => this.readUInt());
58052
58332
  }
58053
- // -------------------- Array of Float Methods --------------------
58054
- writeArrayOfFloat(values) {
58055
- this.writeArray(values, 4, (v) => this.writeFloat(v));
58056
- }
58057
58333
  readArrayOfFloat() {
58058
58334
  return this.readArray(() => this.readFloat());
58059
58335
  }
58060
- // -------------------- Array of Bool Methods --------------------
58061
- writeArrayOfBool(values) {
58062
- this.writeArray(values, 4, (v) => this.writeBoolean(v));
58063
- }
58064
58336
  readArrayOfBool() {
58065
58337
  return this.readArray(() => this.readBoolean());
58066
58338
  }
58067
- // -------------------- Array of RGBA32 Methods --------------------
58068
- writeArrayOfRGBA32(values) {
58069
- this.writeArray(values, 4, (v) => this.writeRGBA32(v));
58070
- }
58071
58339
  readArrayOfRGBA32() {
58072
58340
  return this.readArray(() => this.readRGBA32());
58073
58341
  }
58074
- // -------------------- Helpers --------------------
58075
- writeArray(data2, sizeT, write) {
58076
- this.ensureCapacity(4 + data2.length * sizeT);
58077
- this.writeUInt(data2.length);
58078
- data2.forEach((value) => write(value));
58079
- }
58080
58342
  readArray(read) {
58081
58343
  const length = this.readUInt();
58082
58344
  const array = [];
@@ -58111,17 +58373,17 @@ const materialHandles = [
58111
58373
  MaterialHandles.Invisible
58112
58374
  ];
58113
58375
  class RpcClient {
58114
- constructor(_messenger) {
58115
- __publicField(this, "_messenger");
58376
+ constructor(_socket) {
58377
+ __publicField(this, "_socket");
58116
58378
  // RPC Generated Code
58117
- __publicField(this, "API_VERSION", "5.0.0");
58118
- this._messenger = _messenger;
58119
- }
58120
- get url() {
58121
- return this._messenger.url;
58379
+ __publicField(this, "API_VERSION", "5.1.0");
58380
+ this._socket = _socket;
58122
58381
  }
58123
58382
  get connected() {
58124
- return this._messenger.state.status === "connected";
58383
+ return this._socket.state.status === "connected";
58384
+ }
58385
+ get url() {
58386
+ return this._socket.url;
58125
58387
  }
58126
58388
  RPCAddNodeFlags(componentHandle, nodes, flags) {
58127
58389
  const marshal = new Marshal();
@@ -58129,18 +58391,18 @@ class RpcClient {
58129
58391
  marshal.writeUInt(componentHandle);
58130
58392
  marshal.writeArrayOfUInt(nodes);
58131
58393
  marshal.writeUInt(flags);
58132
- this._messenger.sendRPC(marshal);
58394
+ this._socket.sendRPC(marshal);
58133
58395
  }
58134
58396
  RPCClearMaterialOverrides(componentHandle) {
58135
58397
  const marshal = new Marshal();
58136
58398
  marshal.writeString("RPCClearMaterialOverrides");
58137
58399
  marshal.writeUInt(componentHandle);
58138
- this._messenger.sendRPC(marshal);
58400
+ this._socket.sendRPC(marshal);
58139
58401
  }
58140
58402
  RPCClearScene() {
58141
58403
  const marshal = new Marshal();
58142
58404
  marshal.writeString("RPCClearScene");
58143
- this._messenger.sendRPC(marshal);
58405
+ this._socket.sendRPC(marshal);
58144
58406
  }
58145
58407
  async RPCCreateMaterialInstances(materialHandle, smoothness, colors) {
58146
58408
  const marshal = new Marshal();
@@ -58148,7 +58410,7 @@ class RpcClient {
58148
58410
  marshal.writeUInt(materialHandle);
58149
58411
  marshal.writeUInt(smoothness);
58150
58412
  marshal.writeArrayOfRGBA32(colors);
58151
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58413
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58152
58414
  const ret = returnMarshal.readUInt();
58153
58415
  return ret;
58154
58416
  }
@@ -58158,7 +58420,7 @@ class RpcClient {
58158
58420
  marshal.writeVector3(position);
58159
58421
  marshal.writeRGBA32(color);
58160
58422
  marshal.writeString(text);
58161
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58423
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58162
58424
  const ret = returnMarshal.readUInt();
58163
58425
  return ret;
58164
58426
  }
@@ -58166,25 +58428,19 @@ class RpcClient {
58166
58428
  const marshal = new Marshal();
58167
58429
  marshal.writeString("RPCDestroyMaterialInstances");
58168
58430
  marshal.writeArrayOfUInt(materialInstanceHandle);
58169
- this._messenger.sendRPC(marshal);
58431
+ this._socket.sendRPC(marshal);
58170
58432
  }
58171
58433
  RPCDestroyText(componentHandle) {
58172
58434
  const marshal = new Marshal();
58173
58435
  marshal.writeString("RPCDestroyText");
58174
58436
  marshal.writeUInt(componentHandle);
58175
- this._messenger.sendRPC(marshal);
58176
- }
58177
- RPCEnableSectionBox(enable) {
58178
- const marshal = new Marshal();
58179
- marshal.writeString("RPCEnableSectionBox");
58180
- marshal.writeBoolean(enable);
58181
- this._messenger.sendRPC(marshal);
58437
+ this._socket.sendRPC(marshal);
58182
58438
  }
58183
58439
  async RPCFrameAll(blendTime) {
58184
58440
  const marshal = new Marshal();
58185
58441
  marshal.writeString("RPCFrameAll");
58186
58442
  marshal.writeFloat(blendTime);
58187
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58443
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58188
58444
  const ret = returnMarshal.readSegment();
58189
58445
  return ret;
58190
58446
  }
@@ -58193,7 +58449,7 @@ class RpcClient {
58193
58449
  marshal.writeString("RPCFrameBox");
58194
58450
  marshal.writeBox3(box);
58195
58451
  marshal.writeFloat(blendTime);
58196
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58452
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58197
58453
  const ret = returnMarshal.readSegment();
58198
58454
  return ret;
58199
58455
  }
@@ -58203,7 +58459,7 @@ class RpcClient {
58203
58459
  marshal.writeUInt(componentHandle);
58204
58460
  marshal.writeArrayOfUInt(nodes);
58205
58461
  marshal.writeFloat(blendTime);
58206
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58462
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58207
58463
  const ret = returnMarshal.readSegment();
58208
58464
  return ret;
58209
58465
  }
@@ -58212,14 +58468,14 @@ class RpcClient {
58212
58468
  marshal.writeString("RPCFrameVim");
58213
58469
  marshal.writeUInt(componentHandle);
58214
58470
  marshal.writeFloat(blendTime);
58215
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58471
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58216
58472
  const ret = returnMarshal.readSegment();
58217
58473
  return ret;
58218
58474
  }
58219
58475
  async RPCGetAPIVersion() {
58220
58476
  const marshal = new Marshal();
58221
58477
  marshal.writeString("RPCGetAPIVersion");
58222
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58478
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58223
58479
  const ret = returnMarshal.readString();
58224
58480
  return ret;
58225
58481
  }
@@ -58228,36 +58484,58 @@ class RpcClient {
58228
58484
  marshal.writeString("RPCGetBoundingBox");
58229
58485
  marshal.writeUInt(componentHandle);
58230
58486
  marshal.writeArrayOfUInt(nodes);
58231
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58487
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58488
+ const ret = returnMarshal.readBox3();
58489
+ return ret;
58490
+ }
58491
+ async RPCGetBoundingBoxAll(componentHandle) {
58492
+ const marshal = new Marshal();
58493
+ marshal.writeString("RPCGetBoundingBoxAll");
58494
+ marshal.writeUInt(componentHandle);
58495
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58232
58496
  const ret = returnMarshal.readBox3();
58233
58497
  return ret;
58234
58498
  }
58235
58499
  async RPCGetCameraPosition() {
58236
58500
  const marshal = new Marshal();
58237
58501
  marshal.writeString("RPCGetCameraPosition");
58238
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58502
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58239
58503
  const ret = returnMarshal.readSegment();
58240
58504
  return ret;
58241
58505
  }
58242
58506
  async RPCGetIblRotation() {
58243
58507
  const marshal = new Marshal();
58244
58508
  marshal.writeString("RPCGetIblRotation");
58245
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58509
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58246
58510
  const ret = returnMarshal.readMatrix44();
58247
58511
  return ret;
58248
58512
  }
58249
58513
  async RPCGetLastError() {
58250
58514
  const marshal = new Marshal();
58251
58515
  marshal.writeString("RPCGetLastError");
58252
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58516
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58253
58517
  const ret = returnMarshal.readString();
58254
58518
  return ret;
58255
58519
  }
58520
+ async RPCGetSceneAABB() {
58521
+ const marshal = new Marshal();
58522
+ marshal.writeString("RPCGetSceneAABB");
58523
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58524
+ const ret = returnMarshal.readBox3();
58525
+ return ret;
58526
+ }
58527
+ async RPCGetSectionBox() {
58528
+ const marshal = new Marshal();
58529
+ marshal.writeString("RPCGetSectionBox");
58530
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58531
+ const ret = returnMarshal.readSectionBoxState();
58532
+ return ret;
58533
+ }
58256
58534
  async RPCGetVimLoadingState(componentHandle) {
58257
58535
  const marshal = new Marshal();
58258
58536
  marshal.writeString("RPCGetVimLoadingState");
58259
58537
  marshal.writeUInt(componentHandle);
58260
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58538
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58261
58539
  const ret = returnMarshal.readVimStatus();
58262
58540
  return ret;
58263
58541
  }
@@ -58266,65 +58544,65 @@ class RpcClient {
58266
58544
  marshal.writeString("RPCGhost");
58267
58545
  marshal.writeUInt(componentHandle);
58268
58546
  marshal.writeArrayOfUInt(nodes);
58269
- this._messenger.sendRPC(marshal);
58547
+ this._socket.sendRPC(marshal);
58270
58548
  }
58271
58549
  RPCGhostAll(componentHandle) {
58272
58550
  const marshal = new Marshal();
58273
58551
  marshal.writeString("RPCGhostAll");
58274
58552
  marshal.writeUInt(componentHandle);
58275
- this._messenger.sendRPC(marshal);
58553
+ this._socket.sendRPC(marshal);
58276
58554
  }
58277
58555
  RPCHide(componentHandle, nodes) {
58278
58556
  const marshal = new Marshal();
58279
58557
  marshal.writeString("RPCHide");
58280
58558
  marshal.writeUInt(componentHandle);
58281
58559
  marshal.writeArrayOfUInt(nodes);
58282
- this._messenger.sendRPC(marshal);
58560
+ this._socket.sendRPC(marshal);
58283
58561
  }
58284
58562
  RPCHideAABBs(componentHandle, nodes) {
58285
58563
  const marshal = new Marshal();
58286
58564
  marshal.writeString("RPCHideAABBs");
58287
58565
  marshal.writeUInt(componentHandle);
58288
58566
  marshal.writeArrayOfUInt(nodes);
58289
- this._messenger.sendRPC(marshal);
58567
+ this._socket.sendRPC(marshal);
58290
58568
  }
58291
58569
  RPCHideAll(componentHandle) {
58292
58570
  const marshal = new Marshal();
58293
58571
  marshal.writeString("RPCHideAll");
58294
58572
  marshal.writeUInt(componentHandle);
58295
- this._messenger.sendRPC(marshal);
58573
+ this._socket.sendRPC(marshal);
58296
58574
  }
58297
58575
  RPCHideAllAABBs(componentHandle) {
58298
58576
  const marshal = new Marshal();
58299
58577
  marshal.writeString("RPCHideAllAABBs");
58300
58578
  marshal.writeUInt(componentHandle);
58301
- this._messenger.sendRPC(marshal);
58579
+ this._socket.sendRPC(marshal);
58302
58580
  }
58303
58581
  RPCHighlight(componentHandle, nodes) {
58304
58582
  const marshal = new Marshal();
58305
58583
  marshal.writeString("RPCHighlight");
58306
58584
  marshal.writeUInt(componentHandle);
58307
58585
  marshal.writeArrayOfUInt(nodes);
58308
- this._messenger.sendRPC(marshal);
58586
+ this._socket.sendRPC(marshal);
58309
58587
  }
58310
58588
  RPCHighlightAll(componentHandle) {
58311
58589
  const marshal = new Marshal();
58312
58590
  marshal.writeString("RPCHighlightAll");
58313
58591
  marshal.writeUInt(componentHandle);
58314
- this._messenger.sendRPC(marshal);
58592
+ this._socket.sendRPC(marshal);
58315
58593
  }
58316
58594
  RPCKeyEvent(keyCode, down) {
58317
58595
  const marshal = new Marshal();
58318
58596
  marshal.writeString("RPCKeyEvent");
58319
58597
  marshal.writeInt(keyCode);
58320
58598
  marshal.writeBoolean(down);
58321
- this._messenger.sendRPC(marshal);
58599
+ this._socket.sendRPC(marshal);
58322
58600
  }
58323
58601
  async RPCLoadVim(fileName) {
58324
58602
  const marshal = new Marshal();
58325
58603
  marshal.writeString("RPCLoadVim");
58326
58604
  marshal.writeString(fileName);
58327
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58605
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58328
58606
  const ret = returnMarshal.readUInt();
58329
58607
  return ret;
58330
58608
  }
@@ -58333,7 +58611,7 @@ class RpcClient {
58333
58611
  marshal.writeString("RPCLoadVimURL");
58334
58612
  marshal.writeString(url);
58335
58613
  marshal.writeString(authToken);
58336
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58614
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58337
58615
  const ret = returnMarshal.readUInt();
58338
58616
  return ret;
58339
58617
  }
@@ -58341,7 +58619,7 @@ class RpcClient {
58341
58619
  const marshal = new Marshal();
58342
58620
  marshal.writeString("RPCLockIblRotation");
58343
58621
  marshal.writeBoolean(lock);
58344
- this._messenger.sendRPC(marshal);
58622
+ this._socket.sendRPC(marshal);
58345
58623
  }
58346
58624
  RPCMouseButtonEvent(mousePos, mouseButton, down) {
58347
58625
  const marshal = new Marshal();
@@ -58349,33 +58627,33 @@ class RpcClient {
58349
58627
  marshal.writeVector2(mousePos);
58350
58628
  marshal.writeInt(mouseButton);
58351
58629
  marshal.writeBoolean(down);
58352
- this._messenger.sendRPC(marshal);
58630
+ this._socket.sendRPC(marshal);
58353
58631
  }
58354
58632
  RPCMouseDoubleClickEvent(mousePos, mouseButton) {
58355
58633
  const marshal = new Marshal();
58356
58634
  marshal.writeString("RPCMouseDoubleClickEvent");
58357
58635
  marshal.writeVector2(mousePos);
58358
58636
  marshal.writeInt(mouseButton);
58359
- this._messenger.sendRPC(marshal);
58637
+ this._socket.sendRPC(marshal);
58360
58638
  }
58361
58639
  RPCMouseMoveEvent(mousePos) {
58362
58640
  const marshal = new Marshal();
58363
58641
  marshal.writeString("RPCMouseMoveEvent");
58364
58642
  marshal.writeVector2(mousePos);
58365
- this._messenger.sendRPC(marshal);
58643
+ this._socket.sendRPC(marshal);
58366
58644
  }
58367
58645
  RPCMouseScrollEvent(scrollValue) {
58368
58646
  const marshal = new Marshal();
58369
58647
  marshal.writeString("RPCMouseScrollEvent");
58370
58648
  marshal.writeInt(scrollValue);
58371
- this._messenger.sendRPC(marshal);
58649
+ this._socket.sendRPC(marshal);
58372
58650
  }
58373
58651
  RPCMouseSelectEvent(mousePos, mouseButton) {
58374
58652
  const marshal = new Marshal();
58375
58653
  marshal.writeString("RPCMouseSelectEvent");
58376
58654
  marshal.writeVector2(mousePos);
58377
58655
  marshal.writeInt(mouseButton);
58378
- this._messenger.sendRPC(marshal);
58656
+ this._socket.sendRPC(marshal);
58379
58657
  }
58380
58658
  RPCMoveCameraTo(usePosition, useTarget, position, target, blendTime) {
58381
58659
  const marshal = new Marshal();
@@ -58385,19 +58663,19 @@ class RpcClient {
58385
58663
  marshal.writeVector3(position);
58386
58664
  marshal.writeVector3(target);
58387
58665
  marshal.writeFloat(blendTime);
58388
- this._messenger.sendRPC(marshal);
58666
+ this._socket.sendRPC(marshal);
58389
58667
  }
58390
58668
  RPCPauseRendering(pause) {
58391
58669
  const marshal = new Marshal();
58392
58670
  marshal.writeString("RPCPauseRendering");
58393
58671
  marshal.writeBoolean(pause);
58394
- this._messenger.sendRPC(marshal);
58672
+ this._socket.sendRPC(marshal);
58395
58673
  }
58396
58674
  async RPCPerformHitTest(pos) {
58397
58675
  const marshal = new Marshal();
58398
58676
  marshal.writeString("RPCPerformHitTest");
58399
58677
  marshal.writeVector2(pos);
58400
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58678
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58401
58679
  const ret = returnMarshal.readHitCheckResult();
58402
58680
  return ret;
58403
58681
  }
@@ -58407,39 +58685,39 @@ class RpcClient {
58407
58685
  marshal.writeUInt(componentHandle);
58408
58686
  marshal.writeArrayOfUInt(nodes);
58409
58687
  marshal.writeUInt(flags);
58410
- this._messenger.sendRPC(marshal);
58688
+ this._socket.sendRPC(marshal);
58411
58689
  }
58412
58690
  RPCSetAspectRatio(width, height) {
58413
58691
  const marshal = new Marshal();
58414
58692
  marshal.writeString("RPCSetAspectRatio");
58415
58693
  marshal.writeUInt(width);
58416
58694
  marshal.writeUInt(height);
58417
- this._messenger.sendRPC(marshal);
58695
+ this._socket.sendRPC(marshal);
58418
58696
  }
58419
58697
  RPCSetCameraMode(orbit2) {
58420
58698
  const marshal = new Marshal();
58421
58699
  marshal.writeString("RPCSetCameraMode");
58422
58700
  marshal.writeBoolean(orbit2);
58423
- this._messenger.sendRPC(marshal);
58701
+ this._socket.sendRPC(marshal);
58424
58702
  }
58425
58703
  RPCSetCameraPosition(state, blendTime) {
58426
58704
  const marshal = new Marshal();
58427
58705
  marshal.writeString("RPCSetCameraPosition");
58428
58706
  marshal.writeSegment(state);
58429
58707
  marshal.writeFloat(blendTime);
58430
- this._messenger.sendRPC(marshal);
58708
+ this._socket.sendRPC(marshal);
58431
58709
  }
58432
58710
  RPCSetGhostColor(ghostColor) {
58433
58711
  const marshal = new Marshal();
58434
58712
  marshal.writeString("RPCSetGhostColor");
58435
58713
  marshal.writeRGBA(ghostColor);
58436
- this._messenger.sendRPC(marshal);
58714
+ this._socket.sendRPC(marshal);
58437
58715
  }
58438
58716
  RPCSetIblRotation(transform) {
58439
58717
  const marshal = new Marshal();
58440
58718
  marshal.writeString("RPCSetIblRotation");
58441
58719
  marshal.writeMatrix44(transform);
58442
- this._messenger.sendRPC(marshal);
58720
+ this._socket.sendRPC(marshal);
58443
58721
  }
58444
58722
  RPCSetLighting(toneMappingWhitePoint, hdrScale, hdrBackgroundScale, hdrBackgroundSaturation, backgroundBlur, backgroundColor) {
58445
58723
  const marshal = new Marshal();
@@ -58450,7 +58728,7 @@ class RpcClient {
58450
58728
  marshal.writeFloat(hdrBackgroundSaturation);
58451
58729
  marshal.writeFloat(backgroundBlur);
58452
58730
  marshal.writeRGBA(backgroundColor);
58453
- this._messenger.sendRPC(marshal);
58731
+ this._socket.sendRPC(marshal);
58454
58732
  }
58455
58733
  RPCSetMaterialOverrides(componentHandle, nodes, materialInstanceHandles) {
58456
58734
  const marshal = new Marshal();
@@ -58458,26 +58736,26 @@ class RpcClient {
58458
58736
  marshal.writeUInt(componentHandle);
58459
58737
  marshal.writeArrayOfUInt(nodes);
58460
58738
  marshal.writeArrayOfUInt(materialInstanceHandles);
58461
- this._messenger.sendRPC(marshal);
58739
+ this._socket.sendRPC(marshal);
58462
58740
  }
58463
58741
  RPCSetMoveSpeed(speed) {
58464
58742
  const marshal = new Marshal();
58465
58743
  marshal.writeString("RPCSetMoveSpeed");
58466
58744
  marshal.writeFloat(speed);
58467
- this._messenger.sendRPC(marshal);
58745
+ this._socket.sendRPC(marshal);
58468
58746
  }
58469
- RPCSetSectionBox(aabb) {
58747
+ RPCSetSectionBox(state) {
58470
58748
  const marshal = new Marshal();
58471
58749
  marshal.writeString("RPCSetSectionBox");
58472
- marshal.writeBox3(aabb);
58473
- this._messenger.sendRPC(marshal);
58750
+ marshal.writeSectionBoxState(state);
58751
+ this._socket.sendRPC(marshal);
58474
58752
  }
58475
58753
  RPCShow(componentHandle, nodes) {
58476
58754
  const marshal = new Marshal();
58477
58755
  marshal.writeString("RPCShow");
58478
58756
  marshal.writeUInt(componentHandle);
58479
58757
  marshal.writeArrayOfUInt(nodes);
58480
- this._messenger.sendRPC(marshal);
58758
+ this._socket.sendRPC(marshal);
58481
58759
  }
58482
58760
  RPCShowAABBs(componentHandle, nodes, colors) {
58483
58761
  const marshal = new Marshal();
@@ -58485,13 +58763,13 @@ class RpcClient {
58485
58763
  marshal.writeUInt(componentHandle);
58486
58764
  marshal.writeArrayOfUInt(nodes);
58487
58765
  marshal.writeArrayOfRGBA32(colors);
58488
- this._messenger.sendRPC(marshal);
58766
+ this._socket.sendRPC(marshal);
58489
58767
  }
58490
58768
  RPCShowAll(componentHandle) {
58491
58769
  const marshal = new Marshal();
58492
58770
  marshal.writeString("RPCShowAll");
58493
58771
  marshal.writeUInt(componentHandle);
58494
- this._messenger.sendRPC(marshal);
58772
+ this._socket.sendRPC(marshal);
58495
58773
  }
58496
58774
  async RPCStartScene(toneMappingWhitePoint, hdrScale, hdrBackgroundScale, hdrBackgroundSaturation, backgroundBlur, backgroundColor) {
58497
58775
  const marshal = new Marshal();
@@ -58502,20 +58780,20 @@ class RpcClient {
58502
58780
  marshal.writeFloat(hdrBackgroundSaturation);
58503
58781
  marshal.writeFloat(backgroundBlur);
58504
58782
  marshal.writeRGBA(backgroundColor);
58505
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58783
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58506
58784
  const ret = returnMarshal.readBoolean();
58507
58785
  return ret;
58508
58786
  }
58509
58787
  RPCTriggerRenderDocCapture() {
58510
58788
  const marshal = new Marshal();
58511
58789
  marshal.writeString("RPCTriggerRenderDocCapture");
58512
- this._messenger.sendRPC(marshal);
58790
+ this._socket.sendRPC(marshal);
58513
58791
  }
58514
58792
  RPCUnloadVim(componentHandle) {
58515
58793
  const marshal = new Marshal();
58516
58794
  marshal.writeString("RPCUnloadVim");
58517
58795
  marshal.writeUInt(componentHandle);
58518
- this._messenger.sendRPC(marshal);
58796
+ this._socket.sendRPC(marshal);
58519
58797
  }
58520
58798
  }
58521
58799
  class Validation {
@@ -58994,6 +59272,19 @@ class RpcSafeClient {
58994
59272
  if (!Validation.isComponentHandle(componentHandle)) return;
58995
59273
  this.rpc.RPCDestroyText(componentHandle);
58996
59274
  }
59275
+ /*******************************************************************************
59276
+ * SECTION BOX METHODS
59277
+ * Methods for controlling section box visibility and position.
59278
+ ******************************************************************************/
59279
+ RPCSetSectionBox(state) {
59280
+ this.rpc.RPCSetSectionBox(state);
59281
+ }
59282
+ async RPCGetSectionBox() {
59283
+ return await this.safeCall(
59284
+ () => this.rpc.RPCGetSectionBox(),
59285
+ void 0
59286
+ );
59287
+ }
58997
59288
  /*******************************************************************************
58998
59289
  * CAMERA AND VIEW METHODS
58999
59290
  * Methods for controlling camera position, movement, framing, and view settings.
@@ -59019,6 +59310,12 @@ class RpcSafeClient {
59019
59310
  blendTime = Validation.clamp01(blendTime);
59020
59311
  this.rpc.RPCSetCameraPosition(segment, blendTime);
59021
59312
  }
59313
+ async RPCGetBoundingBoxAll(componentHandle) {
59314
+ return await this.safeCall(
59315
+ () => this.rpc.RPCGetBoundingBoxAll(componentHandle),
59316
+ void 0
59317
+ );
59318
+ }
59022
59319
  /**
59023
59320
  * Calculates the bounding box for specified nodes in a component.
59024
59321
  * Large node arrays are automatically processed in batches for better performance.
@@ -59612,9 +59909,6 @@ class StreamLogger {
59612
59909
  * Starts logging the stream metrics.
59613
59910
  */
59614
59911
  startLoggging() {
59615
- this._id = setInterval(() => {
59616
- this.logMetrics();
59617
- }, 5e3);
59618
59912
  }
59619
59913
  /**
59620
59914
  * Stops logging the stream metrics.
@@ -59704,6 +59998,7 @@ const promise = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePrope
59704
59998
  ControllablePromise,
59705
59999
  ResolvedPromise
59706
60000
  }, Symbol.toStringTag, { value: "Module" }));
60001
+ const DEFAULT_LOCAL_ULTRA_SERVER_URL = "ws://localhost:8123";
59707
60002
  class SocketClient {
59708
60003
  /**
59709
60004
  * Constructs a new Messenger instance.
@@ -59725,10 +60020,12 @@ class SocketClient {
59725
60020
  */
59726
60021
  __publicField(this, "onVideoFrame", () => {
59727
60022
  });
60023
+ __publicField(this, "onCameraPose", () => {
60024
+ });
59728
60025
  __publicField(this, "_state", { status: "disconnected" });
59729
60026
  __publicField(this, "_onStatusUpdate", new distExports.SimpleEventDispatcher());
59730
60027
  __publicField(this, "_connectPromise", new ResolvedPromise(void 0));
59731
- __publicField(this, "_connectingUrl");
60028
+ __publicField(this, "_connectionSettings");
59732
60029
  this._logger = logger;
59733
60030
  this._rpcCallId = 0;
59734
60031
  this._streamLogger = new StreamLogger(logger);
@@ -59761,34 +60058,43 @@ class SocketClient {
59761
60058
  * @returns The WebSocket URL as a string, or undefined if not set.
59762
60059
  */
59763
60060
  get url() {
59764
- return this._connectingUrl;
60061
+ var _a2;
60062
+ return (_a2 = this._connectionSettings) == null ? void 0 : _a2.url;
59765
60063
  }
59766
60064
  /**
59767
60065
  * Connects to a WebSocket server at the specified URL.
59768
60066
  * @param url - The WebSocket URL to connect to.
59769
60067
  * @returns A promise that resolves when the connection is established.
59770
60068
  */
59771
- connect(url) {
60069
+ connect(settings2) {
60070
+ settings2 = {
60071
+ url: (settings2 == null ? void 0 : settings2.url) ?? DEFAULT_LOCAL_ULTRA_SERVER_URL,
60072
+ retries: (settings2 == null ? void 0 : settings2.retries) ?? -1,
60073
+ timeout: (settings2 == null ? void 0 : settings2.timeout) ?? 5e3,
60074
+ retryDelay: (settings2 == null ? void 0 : settings2.retryDelay) ?? 5e3
60075
+ };
60076
+ const url = settings2.url;
59772
60077
  if (!isWebSocketUrl(url)) {
59773
60078
  this._disconnect({ status: "error", error: "connection", serverUrl: url });
59774
60079
  return Promise.reject(new Error(`Invalid WebSocket URL: ${url}`));
59775
60080
  }
59776
60081
  if (this._socket) {
59777
- if (this._socket.url === url) {
60082
+ if (this._connectionSettings.url === url) {
59778
60083
  return this._connectPromise.promise;
59779
60084
  } else {
59780
60085
  this._clearSocket();
60086
+ this._connectionSettings = void 0;
59781
60087
  this._connectPromise.reject("Connection to a different server");
59782
- this._connectPromise = new ControllablePromise();
59783
60088
  }
59784
- } else if (this._connectingUrl !== url) {
60089
+ }
60090
+ if (this.url !== url) {
59785
60091
  this._connectPromise = new ControllablePromise();
59786
- this._connectingUrl = url;
60092
+ this._connectionSettings = settings2;
59787
60093
  }
59788
60094
  this.updateState({ status: "connecting" });
59789
60095
  try {
59790
60096
  this._socket = new WebSocket(url);
59791
- this._connectionTimeout = setTimeout(() => this._onClose(), 5e3);
60097
+ this._connectionTimeout = setTimeout(() => this._onClose(), settings2.timeout);
59792
60098
  this._socket.onopen = (e) => {
59793
60099
  this._onOpen(e);
59794
60100
  };
@@ -59811,15 +60117,15 @@ class SocketClient {
59811
60117
  * Disconnects from the current WebSocket server.
59812
60118
  */
59813
60119
  disconnect(error) {
59814
- this._logger.log("Disconnecting from: ", this._connectingUrl);
59815
- this._connectingUrl = void 0;
60120
+ this._logger.log("Disconnecting from: ", this.url);
60121
+ this._connectionSettings = void 0;
59816
60122
  this._disconnect(error);
59817
60123
  }
59818
60124
  /**
59819
60125
  * Handles the disconnection logic, stopping logging and clearing the socket.
59820
60126
  */
59821
60127
  _disconnect(error) {
59822
- console.log("disconnect", error);
60128
+ this._logger.log("disconnect", error);
59823
60129
  clearTimeout(this._reconnectTimeout);
59824
60130
  clearTimeout(this._connectionTimeout);
59825
60131
  this._streamLogger.stopLogging();
@@ -59860,6 +60166,10 @@ class SocketClient {
59860
60166
  this.handleRPCResponse(msg.dataBuffer);
59861
60167
  return;
59862
60168
  case 254:
60169
+ const m = new ReadMarshal(msg.dataBuffer);
60170
+ if (this.onCameraPose) {
60171
+ this.onCameraPose(m.readSegment());
60172
+ }
59863
60173
  return;
59864
60174
  case 0:
59865
60175
  case 1:
@@ -59873,8 +60183,7 @@ class SocketClient {
59873
60183
  * @param buffer - The ArrayBuffer containing the response data.
59874
60184
  */
59875
60185
  handleRPCResponse(buffer) {
59876
- const m = new Marshal();
59877
- m.writeData(buffer);
60186
+ const m = new ReadMarshal(buffer);
59878
60187
  const callId = m.readUInt();
59879
60188
  const pendingRPC = this._pendingRPCs.get(callId);
59880
60189
  if (pendingRPC !== void 0) {
@@ -59900,21 +60209,30 @@ class SocketClient {
59900
60209
  this._logger.log("Connected to: ", (_a2 = this._socket) == null ? void 0 : _a2.url);
59901
60210
  this.updateState({ status: "connected" });
59902
60211
  this._streamLogger.startLoggging();
59903
- this._connectPromise.resolve();
60212
+ this._connectPromise.resolve(true);
59904
60213
  }
59905
60214
  /**
59906
60215
  * Handler for WebSocket 'close' event.
59907
60216
  * @param _event - The event object.
59908
60217
  */
59909
60218
  _onClose(_event) {
59910
- clearTimeout(this._connectionTimeout);
59911
- this._disconnect({ status: "error", error: "connection", serverUrl: this._connectingUrl });
60219
+ const connecting = this.state.status === "connecting" || this.state.status === "validating";
59912
60220
  this._logger.log("WebSocket closed.");
60221
+ clearTimeout(this._connectionTimeout);
60222
+ this._disconnect({ status: "error", error: "connection", serverUrl: this.url });
60223
+ if (connecting && this._connectionSettings.retries === 0) {
60224
+ this._logger.log("No more retries left");
60225
+ this._connectPromise.resolve(false);
60226
+ return;
60227
+ }
59913
60228
  this._logger.log("Attempting to reconnect in 5 seconds");
59914
60229
  this._reconnectTimeout = setTimeout(() => {
59915
60230
  this.updateState({ status: "connecting" });
59916
- this.connect(this._connectingUrl);
59917
- }, 5e3);
60231
+ if (connecting) {
60232
+ this._connectionSettings.retries--;
60233
+ }
60234
+ this.connect(this._connectionSettings);
60235
+ }, this._connectionSettings.retryDelay);
59918
60236
  }
59919
60237
  /**
59920
60238
  * Sends binary data over the WebSocket connection.
@@ -60287,31 +60605,6 @@ class Decoder {
60287
60605
  this._pendingFrame = frame;
60288
60606
  }
60289
60607
  }
60290
- let DeferredPromise$1 = class DeferredPromise2 extends Promise {
60291
- constructor(executor = () => {
60292
- }) {
60293
- var _a2;
60294
- let resolver;
60295
- let rejector;
60296
- super((resolve, reject) => {
60297
- resolver = resolve;
60298
- rejector = reject;
60299
- return executor(resolve, reject);
60300
- });
60301
- __publicField(this, "resolve");
60302
- __publicField(this, "reject");
60303
- __publicField(this, "initialCallStack");
60304
- this.resolve = resolver;
60305
- this.reject = rejector;
60306
- this.initialCallStack = (_a2 = Error().stack) == null ? void 0 : _a2.split("\n").slice(2).join("\n");
60307
- }
60308
- /** @throws error with amended call stack */
60309
- rejectWithError(error) {
60310
- var _a2;
60311
- error.stack = [(_a2 = error.stack) == null ? void 0 : _a2.split("\n")[0], this.initialCallStack].join("\n");
60312
- this.reject(error);
60313
- }
60314
- };
60315
60608
  class LoadSuccess {
60316
60609
  constructor(vim) {
60317
60610
  __publicField(this, "isError", false);
@@ -60334,8 +60627,8 @@ class LoadError {
60334
60627
  let LoadRequest$1 = class LoadRequest {
60335
60628
  constructor() {
60336
60629
  __publicField(this, "_progress", 0);
60337
- __publicField(this, "_progressPromise", new DeferredPromise$1());
60338
- __publicField(this, "_completionPromise", new DeferredPromise$1());
60630
+ __publicField(this, "_progressPromise", new ControllablePromise());
60631
+ __publicField(this, "_completionPromise", new ControllablePromise());
60339
60632
  __publicField(this, "_result");
60340
60633
  }
60341
60634
  get isCompleted() {
@@ -60348,18 +60641,18 @@ let LoadRequest$1 = class LoadRequest {
60348
60641
  return;
60349
60642
  }
60350
60643
  while (this._result === void 0) {
60351
- await this._progressPromise;
60644
+ await this._progressPromise.promise;
60352
60645
  yield this._progress;
60353
60646
  }
60354
60647
  }
60355
60648
  async getResult() {
60356
- await this._completionPromise;
60649
+ await this._completionPromise.promise;
60357
60650
  return this._result;
60358
60651
  }
60359
60652
  onProgress(progress) {
60360
60653
  this._progress = progress;
60361
60654
  this._progressPromise.resolve();
60362
- this._progressPromise = new DeferredPromise$1();
60655
+ this._progressPromise = new ControllablePromise();
60363
60656
  }
60364
60657
  success(vim) {
60365
60658
  this._result = new LoadSuccess(vim);
@@ -60593,12 +60886,12 @@ class Vim2 {
60593
60886
  * @throws Error if 'all' is passed, as this feature is not supported yet.
60594
60887
  */
60595
60888
  async getBoundingBox(nodes) {
60596
- if (nodes === "all") {
60597
- throw new Error("Feature not supported yet.");
60598
- }
60599
60889
  if (!this.connected || nodes.length === 0) {
60600
60890
  return Promise.resolve(void 0);
60601
60891
  }
60892
+ if (nodes === "all") {
60893
+ return await this._rpc.RPCGetBoundingBoxAll(this._handle);
60894
+ }
60602
60895
  return await this._rpc.RPCGetBoundingBox(this._handle, nodes);
60603
60896
  }
60604
60897
  /**
@@ -61060,7 +61353,7 @@ class Camera3 {
61060
61353
  }
61061
61354
  /**
61062
61355
  * Restores the camera to its last tracked position
61063
- * @param blendTime - Duration of the camera animation in seconds
61356
+ * @param blendTime - Duration of the camera animation in seconds
61064
61357
  */
61065
61358
  restoreLastPosition(blendTime = this._defaultBlendTime) {
61066
61359
  var _a2;
@@ -61073,29 +61366,10 @@ class Camera3 {
61073
61366
  * Handles camera initialization when connection is established
61074
61367
  */
61075
61368
  onConnect() {
61076
- this.startTracking();
61077
61369
  this.restoreLastPosition();
61078
61370
  }
61079
- /**
61080
- * Starts tracking camera position at regular intervals
61081
- */
61082
- startTracking() {
61083
- clearInterval(this._interval);
61084
- this._interval = setInterval(() => this.update(), 1e3);
61085
- }
61086
- /**
61087
- * Stops tracking camera position
61088
- */
61089
- stopTracking() {
61090
- clearInterval(this._interval);
61091
- this._interval = void 0;
61092
- }
61093
- /**
61094
- * Updates the stored camera position
61095
- * @private
61096
- */
61097
- async update() {
61098
- this._lastPosition = await this._rpc.RPCGetCameraPosition();
61371
+ onCameraPose(pose) {
61372
+ this._lastPosition = pose;
61099
61373
  }
61100
61374
  /**
61101
61375
  * Pauses or resumes rendering
@@ -61567,7 +61841,103 @@ class Renderer2 {
61567
61841
  }
61568
61842
  }
61569
61843
  }
61570
- const DEFAULT_LOCAL_ULTRA_SERVER_URL = "ws://localhost:8123";
61844
+ class SectionBox2 {
61845
+ constructor(rpc) {
61846
+ __publicField(this, "_enabled", false);
61847
+ __publicField(this, "_visible", true);
61848
+ __publicField(this, "_interactible", true);
61849
+ __publicField(this, "_clip", true);
61850
+ __publicField(this, "_box", new Box32());
61851
+ __publicField(this, "_rpc");
61852
+ __publicField(this, "_interval");
61853
+ __publicField(this, "_animationFrame");
61854
+ // Signals
61855
+ __publicField(this, "_onUpdate", new distExports$1.SignalDispatcher());
61856
+ this._rpc = rpc;
61857
+ }
61858
+ get onUpdate() {
61859
+ return this._onUpdate.asEvent();
61860
+ }
61861
+ get needUpdate() {
61862
+ return this._animationFrame > 0;
61863
+ }
61864
+ async onConnect() {
61865
+ this.push();
61866
+ this._interval = setInterval(() => this.pull(), 1e3);
61867
+ }
61868
+ scheduleUpdate() {
61869
+ if (this._animationFrame) return;
61870
+ this._animationFrame = requestAnimationFrame(() => {
61871
+ this._animationFrame = void 0;
61872
+ this.push();
61873
+ });
61874
+ }
61875
+ async pull() {
61876
+ if (this.needUpdate) return;
61877
+ const state = await this._rpc.RPCGetSectionBox();
61878
+ let changed = false;
61879
+ if (state.enabled !== this._enabled || state.visible !== this._visible || state.interactible !== this._interactible || state.clip !== this._clip || state.box !== this._box) {
61880
+ changed = true;
61881
+ }
61882
+ this._enabled = state.enabled;
61883
+ this._visible = state.visible;
61884
+ this._interactible = state.interactible;
61885
+ this._clip = state.clip;
61886
+ this._box = state.box;
61887
+ if (changed) {
61888
+ this._onUpdate.dispatch();
61889
+ }
61890
+ }
61891
+ async push() {
61892
+ await this._rpc.RPCSetSectionBox({
61893
+ enabled: this._enabled,
61894
+ visible: this._visible,
61895
+ interactible: this._interactible,
61896
+ clip: this._clip,
61897
+ box: this._box
61898
+ });
61899
+ }
61900
+ get enabled() {
61901
+ return this._enabled;
61902
+ }
61903
+ set enabled(value) {
61904
+ this._enabled = value;
61905
+ this.scheduleUpdate();
61906
+ }
61907
+ get visible() {
61908
+ return this._visible;
61909
+ }
61910
+ set visible(value) {
61911
+ this._visible = value;
61912
+ this.scheduleUpdate();
61913
+ }
61914
+ get interactible() {
61915
+ return this._interactible;
61916
+ }
61917
+ set interactible(value) {
61918
+ this._interactible = value;
61919
+ this.scheduleUpdate();
61920
+ }
61921
+ get clip() {
61922
+ return this._clip;
61923
+ }
61924
+ set clip(value) {
61925
+ this._clip = value;
61926
+ this.scheduleUpdate();
61927
+ }
61928
+ fitBox(box) {
61929
+ this._box = box;
61930
+ this.scheduleUpdate();
61931
+ }
61932
+ getBox() {
61933
+ return this._box;
61934
+ }
61935
+ dispose() {
61936
+ clearInterval(this._interval);
61937
+ cancelAnimationFrame(this._animationFrame);
61938
+ this._onUpdate.clear();
61939
+ }
61940
+ }
61571
61941
  const INVALID_HANDLE = 4294967295;
61572
61942
  class Viewer2 {
61573
61943
  /**
@@ -61595,6 +61965,10 @@ class Viewer2 {
61595
61965
  * API to create, manage, and destroy colors.
61596
61966
  */
61597
61967
  __publicField(this, "colors");
61968
+ /**
61969
+ * The section box API for controlling the section box.
61970
+ */
61971
+ __publicField(this, "sectionBox");
61598
61972
  this._logger = logger ?? defaultLogger;
61599
61973
  this._socketClient = new SocketClient(this._logger, () => this.validateConnection());
61600
61974
  this.rpc = new RpcSafeClient(new RpcClient(this._socketClient));
@@ -61607,7 +61981,9 @@ class Viewer2 {
61607
61981
  this.colors = new ColorManager(this.rpc);
61608
61982
  this._camera = new Camera3(this.rpc);
61609
61983
  this._input = new Inputs(canvas, this.rpc, this._selection, this._camera, this._renderer);
61984
+ this.sectionBox = new SectionBox2(this.rpc);
61610
61985
  this._socketClient.onVideoFrame = (msg) => this._decoder.enqueue(msg);
61986
+ this._socketClient.onCameraPose = (pose) => this._camera.onCameraPose(pose);
61611
61987
  this._socketClient.onStatusUpdate.subscribe((state) => {
61612
61988
  if (state.status === "disconnected") {
61613
61989
  this.onDisconnect();
@@ -61692,6 +62068,7 @@ class Viewer2 {
61692
62068
  this._input.onConnect();
61693
62069
  this._camera.onConnect();
61694
62070
  this._vims.getAll().forEach((vim) => vim.connect());
62071
+ this.sectionBox.onConnect();
61695
62072
  this._viewport.update();
61696
62073
  this._decoder.start();
61697
62074
  }
@@ -61729,7 +62106,6 @@ class Viewer2 {
61729
62106
  * Cleans up resources and stops tracking.
61730
62107
  */
61731
62108
  onDisconnect() {
61732
- this._camera.stopTracking();
61733
62109
  this._decoder.stop();
61734
62110
  this._decoder.clear();
61735
62111
  this.colors.clear();
@@ -61740,8 +62116,8 @@ class Viewer2 {
61740
62116
  * @param url - The server URL to connect to. Defaults to 'ws://localhost:8123'.
61741
62117
  * @returns A promise that resolves when the connection is established.
61742
62118
  */
61743
- async connect(url = DEFAULT_LOCAL_ULTRA_SERVER_URL) {
61744
- await this._socketClient.connect(url);
62119
+ async connect(settings2) {
62120
+ return this._socketClient.connect(settings2);
61745
62121
  }
61746
62122
  /**
61747
62123
  * Disconnects from the current VIM Ultra server.
@@ -61796,6 +62172,7 @@ class Viewer2 {
61796
62172
  this._viewport.dispose();
61797
62173
  this._decoder.dispose();
61798
62174
  this._input.dispose();
62175
+ this.sectionBox.dispose();
61799
62176
  this._canvas.remove();
61800
62177
  window.onbeforeunload = null;
61801
62178
  }
@@ -61804,7 +62181,6 @@ const index$2 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePrope
61804
62181
  __proto__: null,
61805
62182
  Box3: Box32,
61806
62183
  ColorHandle,
61807
- DEFAULT_LOCAL_ULTRA_SERVER_URL,
61808
62184
  INVALID_HANDLE,
61809
62185
  Matrix44: Matrix4,
61810
62186
  RGB,
@@ -67000,12 +67376,13 @@ function anyUiSettingButton(settings2) {
67000
67376
  return isTrue(settings2.ui.projectInspector) || isTrue(settings2.ui.settings) || isTrue(settings2.ui.help) || isTrue(settings2.ui.maximise);
67001
67377
  }
67002
67378
  const defaultSettings = {
67003
- peformance: {
67004
- useFastMaterial: false
67379
+ materials: {
67380
+ useFastMaterial: false,
67381
+ useGhostMaterial: true,
67382
+ smallGhostThreshold: 10
67005
67383
  },
67006
67384
  isolation: {
67007
- enable: true,
67008
- useIsolationMaterial: true
67385
+ enable: true
67009
67386
  },
67010
67387
  capacity: {
67011
67388
  canFollowUrl: true,
@@ -67085,7 +67462,7 @@ function AxesPanel(props) {
67085
67462
  }, []);
67086
67463
  const onIsolationBtn = () => {
67087
67464
  props.settings.update(
67088
- (s) => s.isolation.useIsolationMaterial = !s.isolation.useIsolationMaterial
67465
+ (s) => s.materials.useGhostMaterial = !s.materials.useGhostMaterial
67089
67466
  );
67090
67467
  };
67091
67468
  const onHomeBtn = () => {
@@ -67095,11 +67472,11 @@ function AxesPanel(props) {
67095
67472
  const btnIsolation = /* @__PURE__ */ jsxRuntimeExports.jsx(
67096
67473
  "button",
67097
67474
  {
67098
- "data-tip": props.settings.value.isolation.useIsolationMaterial ? "Disable Ghosting" : "Enable Ghosting",
67475
+ "data-tip": props.settings.value.materials.useGhostMaterial ? "Disable Ghosting" : "Enable Ghosting",
67099
67476
  onClick: onIsolationBtn,
67100
67477
  className: "vim-isolation-btn " + btnStyle2,
67101
67478
  type: "button",
67102
- 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" })
67479
+ 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" })
67103
67480
  }
67104
67481
  );
67105
67482
  const btnHome = /* @__PURE__ */ jsxRuntimeExports.jsxs(
@@ -67629,7 +68006,7 @@ function ControlBar(props) {
67629
68006
  id: elementIds.buttonToggleIsolation,
67630
68007
  enabled: () => isTrue(props.settings.ui.toggleIsolation),
67631
68008
  tip: "Toggle Isolation",
67632
- action: () => props.isolation.toggleIsolation("controlBar"),
68009
+ action: () => props.isolation.toggle("controlBar"),
67633
68010
  icon: toggleIsolation,
67634
68011
  style: buttonDefaultStyle
67635
68012
  }
@@ -71650,7 +72027,7 @@ function VimContextMenu(props) {
71650
72027
  };
71651
72028
  const [clipping, setClipping] = useState(isClipping());
71652
72029
  const [, setVersion] = useState(0);
71653
- const hidden2 = props.isolation.any();
72030
+ const hidden2 = props.isolation.isActive();
71654
72031
  useEffect(() => {
71655
72032
  const subState = viewer.gizmos.section.onStateChanged.subscribe(() => {
71656
72033
  setSection({
@@ -74033,31 +74410,17 @@ function MenuSettings(props) {
74033
74410
  ),
74034
74411
  settingsSubtitle("Materials"),
74035
74412
  settingsToggle(
74036
- "Use Isolation Material",
74037
- (settings2) => settings2.isolation.useIsolationMaterial,
74413
+ "Use Ghost Material",
74414
+ (settings2) => settings2.materials.useGhostMaterial,
74038
74415
  (settings2, value) => {
74039
- settings2.isolation.useIsolationMaterial = value;
74040
- if (settings2.peformance.useFastMaterial && value) {
74041
- settings2.peformance.useFastMaterial = false;
74042
- }
74416
+ settings2.materials.useGhostMaterial = value;
74043
74417
  }
74044
74418
  ),
74045
74419
  settingsToggle(
74046
74420
  "Use Performance Material",
74047
- (settings2) => settings2.peformance.useFastMaterial,
74421
+ (settings2) => settings2.materials.useFastMaterial,
74048
74422
  (settings2, value) => {
74049
- settings2.peformance.useFastMaterial = value;
74050
- if (settings2.isolation.useIsolationMaterial && value) {
74051
- settings2.isolation.useIsolationMaterial = false;
74052
- }
74053
- }
74054
- ),
74055
- settingsSubtitle("Scene"),
74056
- settingsToggle(
74057
- "Show Ground Plane",
74058
- (_) => props.viewer.environment.groundPlane.visible,
74059
- (_, value) => {
74060
- props.viewer.environment.groundPlane.visible = value;
74423
+ settings2.materials.useFastMaterial = value;
74061
74424
  }
74062
74425
  ),
74063
74426
  settingsSubtitle("Panels"),
@@ -74331,7 +74694,6 @@ class ComponentInputs {
74331
74694
  __publicField(this, "_default");
74332
74695
  __publicField(this, "_isolation");
74333
74696
  __publicField(this, "_sideState");
74334
- __publicField(this, "_help");
74335
74697
  __publicField(this, "_getSelection", () => {
74336
74698
  return [...this._viewer.selection.objects].filter(
74337
74699
  (o) => o.type === "Object3D"
@@ -74361,7 +74723,7 @@ class ComponentInputs {
74361
74723
  return true;
74362
74724
  }
74363
74725
  case KEYS.KEY_I: {
74364
- this._isolation.toggleIsolation("keyboard");
74726
+ this._isolation.toggle("keyboard");
74365
74727
  return true;
74366
74728
  }
74367
74729
  case KEYS.KEY_ESCAPE: {
@@ -74369,7 +74731,7 @@ class ComponentInputs {
74369
74731
  this._viewer.selection.clear();
74370
74732
  return true;
74371
74733
  }
74372
- if (this._isolation.any()) {
74734
+ if (this._isolation.isActive()) {
74373
74735
  this._isolation.clear("keyboard");
74374
74736
  return true;
74375
74737
  }
@@ -74451,7 +74813,6 @@ function useSettings(viewer, value) {
74451
74813
  var _a2;
74452
74814
  const next = { ...settings2 };
74453
74815
  updater(next);
74454
- validateSettings(next);
74455
74816
  saveSettingsToLocal(next);
74456
74817
  setSettings(next);
74457
74818
  (_a2 = onUpdate.current) == null ? void 0 : _a2.call(onUpdate, next);
@@ -74471,11 +74832,6 @@ function useSettings(viewer, value) {
74471
74832
  [settings2]
74472
74833
  );
74473
74834
  }
74474
- function validateSettings(settings2) {
74475
- if (settings2.peformance.useFastMaterial && settings2.isolation.useIsolationMaterial) {
74476
- settings2.peformance.useFastMaterial = false;
74477
- }
74478
- }
74479
74835
  function applySettings(viewer, settings2) {
74480
74836
  const performance2 = document.getElementsByClassName("vim-performance-div")[0];
74481
74837
  if (performance2) {
@@ -74485,240 +74841,192 @@ function applySettings(viewer, settings2) {
74485
74841
  performance2.classList.add("vc-hidden");
74486
74842
  }
74487
74843
  }
74488
- viewer.vims.forEach((v) => {
74489
- if (settings2.peformance.useFastMaterial && v.scene.material === void 0) {
74490
- v.scene.material = viewer.materials.simple;
74491
- }
74492
- if (!settings2.peformance.useFastMaterial && v.scene.material === viewer.materials.simple) {
74493
- v.scene.material = void 0;
74494
- }
74495
- });
74844
+ viewer.renderer.smallGhostThreshold = settings2.materials.smallGhostThreshold;
74496
74845
  }
74497
74846
  class Isolation {
74847
+ /**
74848
+ * Constructs an IsolationManager.
74849
+ *
74850
+ * @param viewer - The VIM Viewer responsible for managing the 3D scene and objects.
74851
+ * @param camera - A component that handles camera control and framing.
74852
+ * @param settings - The settings that control isolation and material usage.
74853
+ */
74498
74854
  constructor(viewer, camera2, settings2) {
74499
74855
  __publicField(this, "_viewer");
74500
74856
  __publicField(this, "_settings");
74501
- __publicField(this, "_isolation");
74502
- __publicField(this, "_lastIsolation");
74857
+ __publicField(this, "_isolation", []);
74503
74858
  __publicField(this, "_camera");
74504
- __publicField(this, "_references", /* @__PURE__ */ new Map());
74505
74859
  __publicField(this, "_onChanged", new distExports.SimpleEventDispatcher());
74506
74860
  this._viewer = viewer;
74507
74861
  this._camera = camera2;
74508
74862
  this.applySettings(settings2);
74509
74863
  }
74510
- /** Signal dispatched when the isolation set changes. */
74864
+ /**
74865
+ * An event that is dispatched whenever the isolation set changes.
74866
+ *
74867
+ * @remarks
74868
+ * This can be used by other parts of the application to react to isolation
74869
+ * updates (for example, updating UI or triggering additional viewport actions).
74870
+ *
74871
+ * @returns {ISimpleEvent<string>} Event interface for subscribing to isolation changes.
74872
+ */
74511
74873
  get onChanged() {
74512
74874
  return this._onChanged.asEvent();
74513
74875
  }
74514
74876
  /**
74515
- * Applies relevant settings to isolation.
74516
- * @param settings The settings to be applied to isolation.
74877
+ * Applies relevant settings to the isolation behavior.
74878
+ *
74879
+ * @param settings - The new settings to apply.
74880
+ *
74881
+ * @remarks
74882
+ * This updates the internal reference to settings and immediately sets
74883
+ * the material based on whether isolation is currently active.
74517
74884
  */
74518
74885
  applySettings(settings2) {
74519
- var _a2;
74520
74886
  this._settings = settings2;
74521
74887
  if (!this._settings.isolation.enable) return;
74522
- const set3 = new Set((_a2 = this._isolation) == null ? void 0 : _a2.map((o) => o.vim));
74523
- this._viewer.vims.forEach((v) => {
74524
- v.scene.material = this.getMaterial(this._settings, set3.has(v));
74525
- });
74526
- }
74527
- /**
74528
- * Sets the reference objects for a given VIM.
74529
- * @param vim The VIM for which reference objects are being set.
74530
- * @param reference An array of reference objects or the string 'always' to indicate permanent reference.
74531
- */
74532
- setReference(vim, reference) {
74533
- const value = reference === "always" ? reference : new Set(reference);
74534
- this._references.set(vim, value);
74535
- }
74536
- /**
74537
- * Retrieves the reference objects set for a given VIM.
74538
- * @param vim The VIM for which reference objects are being retrieved.
74539
- * @returns The reference objects set for the specified VIM.
74540
- */
74541
- getReference(vim) {
74542
- return this._references.get(vim);
74543
- }
74544
- /**
74545
- * Clears all reference objects set for VIMs.
74546
- */
74547
- clearReferences() {
74548
- this._references.clear();
74888
+ this._viewer.renderer.modelMaterial = this.getMaterial(this._settings, this.isActive());
74549
74889
  }
74550
74890
  /**
74551
- * Returns true if there are currently objects isolated.
74552
- * @returns True if there are currently objects isolated; otherwise, false.
74891
+ * Checks if isolation is currently active (i.e., any objects are isolated).
74892
+ *
74893
+ * @returns True if isolation is active; otherwise, false.
74553
74894
  */
74554
- any() {
74555
- return this._isolation !== void 0;
74895
+ isActive() {
74896
+ return this._isolation.length > 0;
74556
74897
  }
74557
74898
  /**
74558
- * Returns the current array of isolated objects.
74559
- * @returns The array of objects currently isolated, or undefined if no objects are isolated.
74899
+ * Retrieves the current array of isolated objects.
74900
+ *
74901
+ * @returns An array of isolated objects, or undefined if isolation is not active.
74560
74902
  */
74561
74903
  current() {
74562
74904
  return this._isolation;
74563
74905
  }
74564
74906
  /**
74565
- * Isolates the objects in the given array and shows the rest as ghost.
74566
- * @param objects An array of objects to isolate.
74567
- * @param source The source of isolation.
74568
- * @returns True if isolation occurs; otherwise, false.
74907
+ * Sets the specified objects as isolated, hiding or ghosting the rest.
74908
+ *
74909
+ * @param objects - The objects to isolate.
74910
+ * @param source - A label or identifier indicating the source of this action (e.g., "user").
74569
74911
  */
74570
74912
  isolate(objects, source) {
74571
74913
  if (!this._settings.isolation.enable) return;
74572
- if (this._isolation) {
74573
- this._lastIsolation = this._isolation;
74574
- }
74575
- const isolated = this._isolate(this._viewer, this._settings, objects);
74576
- this._isolation = isolated ? objects : void 0;
74914
+ this._isolation = objects ?? [];
74915
+ this._apply(source);
74577
74916
  this._camera.frameVisibleObjects();
74578
- this._onChanged.dispatch(source);
74579
- return isolated;
74580
74917
  }
74581
74918
  /**
74582
- * Toggles current isolation based on selection.
74583
- * @param source The source of isolation.
74919
+ * Toggles isolation by using the current selection.
74920
+ *
74921
+ * @param source - A label or identifier for the isolation action.
74922
+ *
74923
+ * @remarks
74924
+ * This method replaces the current isolation set with whatever objects are
74925
+ * currently selected. If selection is empty, it effectively clears isolation.
74584
74926
  */
74585
- toggleIsolation(source) {
74927
+ toggle(source) {
74586
74928
  if (!this._settings.isolation.enable) return;
74587
- const selection = [...this._viewer.selection.objects].filter((o) => o.type === "Object3D");
74588
- if (this._isolation) {
74589
- this._lastIsolation = this._isolation;
74590
- }
74591
- if (this._isolation) {
74592
- if (selection.length === 0 || ArrayEquals(this._isolation, selection)) {
74593
- this._showAll();
74594
- this._isolation = void 0;
74595
- } else {
74596
- const isolated = this._isolate(this._viewer, this._settings, selection);
74597
- this._isolation = isolated ? selection : void 0;
74598
- this._camera.frameVisibleObjects();
74599
- this._viewer.selection.clear();
74600
- }
74601
- } else {
74602
- if (selection.length > 0) {
74603
- const isolated = this._isolate(this._viewer, this._settings, selection);
74604
- this._isolation = isolated ? selection : void 0;
74605
- this._camera.frameVisibleObjects();
74606
- this._viewer.selection.clear();
74607
- } else if (this._lastIsolation) {
74608
- const isolated = this._isolate(
74609
- this._viewer,
74610
- this._settings,
74611
- this._lastIsolation
74612
- );
74613
- this._isolation = isolated ? [...this._lastIsolation] : void 0;
74614
- }
74615
- }
74616
- this._onChanged.dispatch(source);
74929
+ this._isolation = [...this._viewer.selection.objects].filter((o) => o.type === "Object3D");
74930
+ this._apply(source);
74931
+ this._camera.frameVisibleObjects();
74932
+ this._viewer.selection.clear();
74617
74933
  }
74618
74934
  /**
74619
- * Removes the given objects from the isolation set.
74620
- * @param objects An array of objects to be removed from isolation.
74621
- * @param source The source of the removal operation.
74935
+ * Hides the specified objects from the isolation set.
74936
+ *
74937
+ * @param objects - The objects to hide.
74938
+ * @param source - A label or identifier for the isolation action.
74939
+ *
74940
+ * @remarks
74941
+ * If there is no active isolation set (i.e., all objects are visible),
74942
+ * the method first treats all objects in the scene as isolated,
74943
+ * and then removes the specified objects. This ensures the specified
74944
+ * objects become hidden.
74622
74945
  */
74623
74946
  hide(objects, source) {
74624
74947
  if (!this._settings.isolation.enable) return;
74625
- const selection = new Set(objects);
74626
- const initial = this._isolation ?? this._viewer.vims[0].getObjects();
74627
- const result = [];
74628
- for (const obj of initial) {
74629
- if (!selection.has(obj)) result.push(obj);
74630
- }
74631
- const isolated = this._isolate(this._viewer, this._settings, result);
74632
- this._isolation = isolated ? result : void 0;
74633
- this._onChanged.dispatch(source);
74948
+ this._isolation = this._isolation.length === 0 ? this.getAllObjects() : this._isolation;
74949
+ this._isolation = this._isolation.filter((o) => !objects.includes(o));
74950
+ this._apply(source);
74634
74951
  objects.forEach((o) => this._viewer.selection.remove(o));
74635
74952
  }
74636
74953
  /**
74637
- * Adds the given objects to the isolation set.
74638
- * @param objects An array of objects to be added to isolation.
74639
- * @param source The source of the addition operation.
74954
+ * Adds the specified objects to the current isolation set (making them visible).
74955
+ *
74956
+ * @param objects - The objects to show.
74957
+ * @param source - A label or identifier for the isolation action.
74640
74958
  */
74641
74959
  show(objects, source) {
74642
74960
  if (!this._settings.isolation.enable) return;
74643
- const isolation = this._isolation ?? [];
74644
- objects.forEach((o) => isolation.push(o));
74645
- const result = [...new Set(isolation)];
74646
- const isolated = this._isolate(this._viewer, this._settings, result);
74647
- this._isolation = isolated ? result : void 0;
74648
- this._onChanged.dispatch(source);
74961
+ objects.forEach((o) => this._isolation.push(o));
74962
+ this._apply(source);
74649
74963
  }
74650
74964
  /**
74651
- * Clears the current isolation.
74652
- * @param source The source of the isolation clearing operation.
74965
+ * Clears the current isolation set, making all objects visible.
74966
+ *
74967
+ * @param source - A label or identifier for the isolation action.
74653
74968
  */
74654
74969
  clear(source) {
74655
74970
  if (!this._settings.isolation.enable) return;
74656
- this._showAll();
74657
- this._lastIsolation = this._isolation;
74658
- this._isolation = void 0;
74659
- this._onChanged.dispatch(source);
74971
+ this._isolation.length = 0;
74972
+ this._apply(source);
74660
74973
  }
74661
74974
  /**
74662
- * Show all objects and quit isolation mode.
74975
+ * Constructs the correct material (or array of materials) based on the given settings.
74976
+ *
74977
+ * @param settings - The current component settings, including isolation rules.
74978
+ * @param isolate - Whether or not isolation is active.
74979
+ * @returns The material(s) to assign to the renderer, or undefined if default materials should be used.
74980
+ *
74981
+ * @remarks
74982
+ * - If isolation is active and `useGhostMaterial` is true, an array containing
74983
+ * the simple and ghost materials is returned.
74984
+ * - If fast materials are enabled, the simple material is returned.
74985
+ * - Otherwise, defaults to undefined, allowing the system to pick a standard material.
74663
74986
  */
74664
- _showAll() {
74665
- this._viewer.vims.forEach((v) => {
74666
- for (const obj of v.getObjects()) {
74667
- obj.visible = true;
74668
- }
74669
- v.scene.material = this.getMaterial(this._settings, false);
74670
- });
74671
- }
74672
74987
  getMaterial(settings2, isolate) {
74673
- if (settings2.peformance.useFastMaterial) {
74674
- return this._viewer.materials.simple;
74675
- }
74676
- if (!settings2.isolation.useIsolationMaterial) {
74677
- return void 0;
74988
+ if (isolate && settings2.materials.useGhostMaterial) {
74989
+ return [this._viewer.materials.simple, this._viewer.materials.ghost];
74678
74990
  }
74679
- if (!isolate) {
74680
- return void 0;
74991
+ if (settings2.materials.useFastMaterial) {
74992
+ return this._viewer.materials.simple;
74681
74993
  }
74682
- return this._viewer.materials.isolation;
74994
+ return void 0;
74683
74995
  }
74684
- _isolate(viewer, settings2, objects) {
74685
- let useIsolation = false;
74686
- if (!objects) {
74687
- this._showAll();
74688
- } else {
74689
- const set3 = new Set(objects);
74690
- let all = true;
74691
- viewer.vims.forEach((vim) => {
74692
- for (const obj of vim.getObjects()) {
74693
- if (obj.hasMesh) {
74694
- obj.visible = set3.has(obj);
74695
- all = all && obj.visible;
74696
- }
74697
- }
74698
- const reference = this._references.get(vim);
74699
- if (reference === void 0) {
74700
- useIsolation = !all;
74701
- } else if (reference === "always") {
74702
- useIsolation = true;
74703
- } else {
74704
- useIsolation = !setsEqual(reference, set3);
74996
+ /**
74997
+ * Applies the current isolation state: sets visibility for objects, updates materials,
74998
+ * and dispatches the changed event.
74999
+ *
75000
+ * @param source - A label or identifier for the isolation action.
75001
+ */
75002
+ _apply(source) {
75003
+ let all = true;
75004
+ let any = false;
75005
+ const set3 = this._isolation.length > 0 ? new Set(this._isolation) : void 0;
75006
+ this._viewer.vims.forEach((vim) => {
75007
+ for (const obj of vim.getObjects()) {
75008
+ if (obj.hasMesh) {
75009
+ obj.visible = (set3 == null ? void 0 : set3.has(obj)) ?? true;
75010
+ all = all && obj.visible;
75011
+ any = any || obj.visible;
74705
75012
  }
74706
- vim.scene.material = this.getMaterial(this._settings, useIsolation);
74707
- });
74708
- }
74709
- return useIsolation;
74710
- }
74711
- }
74712
- function setsEqual(set1, set22) {
74713
- if (set1.size !== set22.size) {
74714
- return false;
75013
+ }
75014
+ });
75015
+ this._viewer.renderer.modelMaterial = this.getMaterial(this._settings, any && !all);
75016
+ this._onChanged.dispatch(source);
74715
75017
  }
74716
- for (const item of set1) {
74717
- if (!set22.has(item)) {
74718
- return false;
74719
- }
75018
+ /**
75019
+ * Gathers all objects from all loaded VIM instances.
75020
+ *
75021
+ * @returns An array of all objects within the loaded VIM scenes.
75022
+ */
75023
+ getAllObjects() {
75024
+ let objects = [];
75025
+ this._viewer.vims.forEach((vim) => {
75026
+ objects = objects.concat(vim.getObjects());
75027
+ });
75028
+ return objects;
74720
75029
  }
74721
- return true;
74722
75030
  }
74723
75031
  class ComponentCamera {
74724
75032
  constructor(viewer) {
@@ -74985,7 +75293,7 @@ const bimInfoData = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineP
74985
75293
  __proto__: null,
74986
75294
  useBimInfo
74987
75295
  }, Symbol.toStringTag, { value: "Module" }));
74988
- class DeferredPromise3 extends Promise {
75296
+ class DeferredPromise2 extends Promise {
74989
75297
  constructor(executor = () => {
74990
75298
  }) {
74991
75299
  var _a2;
@@ -75016,9 +75324,9 @@ class LoadRequest2 {
75016
75324
  __publicField(this, "_callbacks");
75017
75325
  __publicField(this, "_request");
75018
75326
  __publicField(this, "_progress", { loaded: 0, total: 0, all: /* @__PURE__ */ new Map() });
75019
- __publicField(this, "_progressPromise", new DeferredPromise3());
75327
+ __publicField(this, "_progressPromise", new DeferredPromise2());
75020
75328
  __publicField(this, "_isDone", false);
75021
- __publicField(this, "_completionPromise", new DeferredPromise3());
75329
+ __publicField(this, "_completionPromise", new DeferredPromise2());
75022
75330
  this.source = source;
75023
75331
  this._callbacks = callbacks;
75024
75332
  this.startRequest(source, settings2);
@@ -75039,7 +75347,7 @@ class LoadRequest2 {
75039
75347
  this._callbacks.onProgress(progress);
75040
75348
  this._progress = progress;
75041
75349
  this._progressPromise.resolve();
75042
- this._progressPromise = new DeferredPromise3();
75350
+ this._progressPromise = new DeferredPromise2();
75043
75351
  }
75044
75352
  onSuccess() {
75045
75353
  this._callbacks.onDone();
@@ -75399,7 +75707,7 @@ function setComponentBehind(value) {
75399
75707
  }
75400
75708
  }
75401
75709
  function createWebglComponent(container, componentSettings = {}, viewerSettings = {}) {
75402
- const promise2 = new DeferredPromise3();
75710
+ const promise2 = new DeferredPromise2();
75403
75711
  const cmpContainer = container instanceof HTMLElement ? createContainer(container) : container ?? createContainer();
75404
75712
  const viewer = new Viewer$1(viewerSettings);
75405
75713
  viewer.viewport.reparent(cmpContainer.gfx);
@@ -75862,7 +76170,7 @@ function getRequestErrorMessage(source, error) {
75862
76170
  }
75863
76171
  }
75864
76172
  function createUltraComponent(container) {
75865
- const promise2 = new DeferredPromise3();
76173
+ const promise2 = new DeferredPromise2();
75866
76174
  const cmpContainer = container instanceof HTMLElement ? createContainer(container) : container ?? createContainer();
75867
76175
  const viewer = Viewer2.createWithCanvas(cmpContainer.gfx);
75868
76176
  const reactRoot = clientExports.createRoot(cmpContainer.ui);