@inweb/viewer-three 26.11.0 → 26.12.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 (44) hide show
  1. package/dist/extensions/components/AxesHelperComponent.js +1 -1
  2. package/dist/extensions/components/AxesHelperComponent.js.map +1 -1
  3. package/dist/extensions/components/AxesHelperComponent.min.js +1 -1
  4. package/dist/extensions/components/AxesHelperComponent.module.js +1 -1
  5. package/dist/extensions/components/AxesHelperComponent.module.js.map +1 -1
  6. package/dist/extensions/components/InfoPanelComponent.js +170 -0
  7. package/dist/extensions/components/InfoPanelComponent.js.map +1 -0
  8. package/dist/extensions/components/InfoPanelComponent.min.js +24 -0
  9. package/dist/extensions/components/InfoPanelComponent.module.js +164 -0
  10. package/dist/extensions/components/InfoPanelComponent.module.js.map +1 -0
  11. package/dist/extensions/components/StatsPanelComponent.js +9 -3
  12. package/dist/extensions/components/StatsPanelComponent.js.map +1 -1
  13. package/dist/extensions/components/StatsPanelComponent.min.js +1 -1
  14. package/dist/extensions/components/StatsPanelComponent.module.js +9 -3
  15. package/dist/extensions/components/StatsPanelComponent.module.js.map +1 -1
  16. package/dist/extensions/loaders/PotreeLoader.js +55 -4
  17. package/dist/extensions/loaders/PotreeLoader.js.map +1 -1
  18. package/dist/extensions/loaders/PotreeLoader.min.js +1 -1
  19. package/dist/extensions/loaders/PotreeLoader.module.js +52 -0
  20. package/dist/extensions/loaders/PotreeLoader.module.js.map +1 -1
  21. package/dist/viewer-three.js +402 -5
  22. package/dist/viewer-three.js.map +1 -1
  23. package/dist/viewer-three.min.js +8 -3
  24. package/dist/viewer-three.module.js +358 -7
  25. package/dist/viewer-three.module.js.map +1 -1
  26. package/extensions/components/AxesHelperComponent.ts +1 -1
  27. package/extensions/components/InfoPanelComponent.ts +197 -0
  28. package/extensions/components/StatsPanelComponent.ts +10 -3
  29. package/extensions/loaders/Potree/PotreeModelImpl.ts +72 -0
  30. package/lib/Viewer/Viewer.d.ts +2 -1
  31. package/lib/Viewer/components/InfoComponent.d.ts +22 -0
  32. package/lib/Viewer/loaders/DynamicGltfLoader/DynamicModelImpl.d.ts +2 -0
  33. package/lib/Viewer/models/IModelImpl.d.ts +2 -1
  34. package/lib/Viewer/models/ModelImpl.d.ts +2 -0
  35. package/package.json +5 -5
  36. package/src/Viewer/Viewer.ts +7 -0
  37. package/src/Viewer/components/InfoComponent.ts +187 -0
  38. package/src/Viewer/components/index.ts +2 -0
  39. package/src/Viewer/loaders/DynamicGltfLoader/DynamicGltfLoader.js +16 -8
  40. package/src/Viewer/loaders/DynamicGltfLoader/DynamicModelImpl.ts +25 -0
  41. package/src/Viewer/loaders/DynamicGltfLoader/GltfStructure.js +67 -1
  42. package/src/Viewer/loaders/RangesLoader.ts +11 -1
  43. package/src/Viewer/models/IModelImpl.ts +3 -1
  44. package/src/Viewer/models/ModelImpl.ts +158 -0
@@ -536,6 +536,51 @@
536
536
  "wheel",
537
537
  ];
538
538
  const CANVAS_EVENTS = CanvasEvents;
539
+ class Info {
540
+ constructor() {
541
+ this.performance = {
542
+ fps: 0,
543
+ frameTime: 0,
544
+ timeToFirstRender: 0,
545
+ loadTime: 0,
546
+ };
547
+ this.render = {
548
+ viewport: { width: 0, height: 0 },
549
+ antialiasing: "",
550
+ drawCalls: 0,
551
+ triangles: 0,
552
+ points: 0,
553
+ lines: 0,
554
+ };
555
+ this.scene = {
556
+ objects: 0,
557
+ triangles: 0,
558
+ points: 0,
559
+ lines: 0,
560
+ edges: 0,
561
+ };
562
+ this.optimizedScene = {
563
+ objects: 0,
564
+ triangles: 0,
565
+ points: 0,
566
+ lines: 0,
567
+ edges: 0,
568
+ };
569
+ this.memory = {
570
+ geometries: 0,
571
+ geometryBytes: 0,
572
+ textures: 0,
573
+ textureBytes: 0,
574
+ materials: 0,
575
+ totalEstimatedGpuBytes: 0,
576
+ usedJSHeapSize: 0,
577
+ };
578
+ this.system = {
579
+ webglRenderer: "",
580
+ webglVendor: "",
581
+ };
582
+ }
583
+ }
539
584
 
540
585
  /**
541
586
  * @license
@@ -35612,6 +35657,140 @@ void main() {
35612
35657
  }
35613
35658
  }
35614
35659
 
35660
+ class InfoComponent {
35661
+ constructor(viewer) {
35662
+ this.initialize = () => {
35663
+ try {
35664
+ const gl = this.viewer.renderer.getContext();
35665
+ const dbgInfo = gl.getExtension("WEBGL_debug_renderer_info");
35666
+ if (dbgInfo) {
35667
+ this.viewer.info.system.webglRenderer = gl.getParameter(dbgInfo.UNMASKED_RENDERER_WEBGL);
35668
+ this.viewer.info.system.webglVendor = gl.getParameter(dbgInfo.UNMASKED_VENDOR_WEBGL);
35669
+ }
35670
+ }
35671
+ catch (error) {
35672
+ console.error("Error reading WebGL info.", error);
35673
+ }
35674
+ console.log("THREE.WebGLRenderer:", REVISION);
35675
+ console.log("WebGL Renderer:", this.viewer.info.system.webglRenderer);
35676
+ console.log("WebGL Vendor:", this.viewer.info.system.webglVendor);
35677
+ this.resize();
35678
+ this.optionsChange({ data: this.viewer.options });
35679
+ };
35680
+ this.clear = () => {
35681
+ this.viewer.info.performance.timeToFirstRender = 0;
35682
+ this.viewer.info.performance.loadTime = 0;
35683
+ this.viewer.info.scene.objects = 0;
35684
+ this.viewer.info.scene.triangles = 0;
35685
+ this.viewer.info.scene.points = 0;
35686
+ this.viewer.info.scene.lines = 0;
35687
+ this.viewer.info.scene.edges = 0;
35688
+ this.viewer.info.optimizedScene.objects = 0;
35689
+ this.viewer.info.optimizedScene.triangles = 0;
35690
+ this.viewer.info.optimizedScene.points = 0;
35691
+ this.viewer.info.optimizedScene.lines = 0;
35692
+ this.viewer.info.optimizedScene.edges = 0;
35693
+ this.viewer.info.memory.geometries = 0;
35694
+ this.viewer.info.memory.geometryBytes = 0;
35695
+ this.viewer.info.memory.textures = 0;
35696
+ this.viewer.info.memory.textureBytes = 0;
35697
+ this.viewer.info.memory.materials = 0;
35698
+ this.viewer.info.memory.totalEstimatedGpuBytes = 0;
35699
+ this.viewer.info.memory.usedJSHeapSize = 0;
35700
+ };
35701
+ this.optionsChange = ({ data: options }) => {
35702
+ if (options.antialiasing === false)
35703
+ this.viewer.info.render.antialiasing = "";
35704
+ else if (options.antialiasing === true)
35705
+ this.viewer.info.render.antialiasing = "mxaa";
35706
+ else
35707
+ this.viewer.info.render.antialiasing = options.antialiasing;
35708
+ };
35709
+ this.geometryStart = () => {
35710
+ this.startTime = performance.now();
35711
+ };
35712
+ this.databaseChunk = () => {
35713
+ this.viewer.info.performance.timeToFirstRender += performance.now() - this.startTime;
35714
+ console.log("Time to first render:", this.viewer.info.performance.timeToFirstRender, "ms");
35715
+ };
35716
+ this.geometryEnd = () => {
35717
+ const model = this.viewer.models[this.viewer.models.length - 1];
35718
+ const info = model.getInfo();
35719
+ this.viewer.info.scene.objects += info.scene.objects;
35720
+ this.viewer.info.scene.triangles += info.scene.triangles;
35721
+ this.viewer.info.scene.points += info.scene.points;
35722
+ this.viewer.info.scene.lines += info.scene.lines;
35723
+ this.viewer.info.scene.edges += info.scene.edges;
35724
+ this.viewer.info.optimizedScene.objects += info.optimizedScene.objects;
35725
+ this.viewer.info.optimizedScene.triangles += info.optimizedScene.triangles;
35726
+ this.viewer.info.optimizedScene.points += info.optimizedScene.points;
35727
+ this.viewer.info.optimizedScene.lines += info.optimizedScene.lines;
35728
+ this.viewer.info.optimizedScene.edges += info.optimizedScene.edges;
35729
+ this.viewer.info.memory.geometries += info.memory.geometries;
35730
+ this.viewer.info.memory.geometryBytes += info.memory.geometryBytes;
35731
+ this.viewer.info.memory.textures += info.memory.textures;
35732
+ this.viewer.info.memory.textureBytes += info.memory.textureBytes;
35733
+ this.viewer.info.memory.materials += info.memory.materials;
35734
+ this.viewer.info.memory.totalEstimatedGpuBytes += info.memory.totalEstimatedGpuBytes;
35735
+ const memory = performance["memory"];
35736
+ if (memory)
35737
+ this.viewer.info.memory.usedJSHeapSize = memory.usedJSHeapSize;
35738
+ this.viewer.info.performance.loadTime += performance.now() - this.startTime;
35739
+ console.log("Number of objects:", info.scene.objects);
35740
+ console.log("Number of objects after optimization:", info.optimizedScene.objects);
35741
+ console.log("Total geometry size:", info.memory.totalEstimatedGpuBytes / (1024 * 1024), "MB");
35742
+ console.log("File load time:", this.viewer.info.performance.loadTime, "ms");
35743
+ };
35744
+ this.resize = () => {
35745
+ const rendererSize = this.viewer.renderer.getSize(new Vector2());
35746
+ this.viewer.info.render.viewport.width = rendererSize.x;
35747
+ this.viewer.info.render.viewport.height = rendererSize.y;
35748
+ };
35749
+ this.render = () => {
35750
+ this.viewer.info.render.drawCalls = this.viewer.renderer.info.render.calls;
35751
+ this.viewer.info.render.triangles = this.viewer.renderer.info.render.triangles;
35752
+ this.viewer.info.render.points = this.viewer.renderer.info.render.points;
35753
+ this.viewer.info.render.lines = this.viewer.renderer.info.render.lines;
35754
+ };
35755
+ this.animate = () => {
35756
+ const time = performance.now();
35757
+ this.viewer.info.performance.frameTime = Math.round(time - this.beginTime);
35758
+ this.beginTime = time;
35759
+ this.frames++;
35760
+ if (time - this.prevTime >= 1000) {
35761
+ this.viewer.info.performance.fps = Math.round((this.frames * 1000) / (time - this.prevTime));
35762
+ this.prevTime = time;
35763
+ this.frames = 0;
35764
+ }
35765
+ };
35766
+ this.viewer = viewer;
35767
+ this.startTime = 0;
35768
+ this.beginTime = performance.now();
35769
+ this.prevTime = performance.now();
35770
+ this.frames = 0;
35771
+ this.viewer.addEventListener("initialize", this.initialize);
35772
+ this.viewer.addEventListener("clear", this.clear);
35773
+ this.viewer.addEventListener("optionschange", this.optionsChange);
35774
+ this.viewer.addEventListener("geometrystart", this.geometryStart);
35775
+ this.viewer.addEventListener("databasechunk", this.databaseChunk);
35776
+ this.viewer.addEventListener("geometryend", this.geometryEnd);
35777
+ this.viewer.addEventListener("resize", this.resize);
35778
+ this.viewer.addEventListener("render", this.render);
35779
+ this.viewer.addEventListener("animate", this.animate);
35780
+ }
35781
+ dispose() {
35782
+ this.viewer.removeEventListener("initialize", this.initialize);
35783
+ this.viewer.removeEventListener("clear", this.clear);
35784
+ this.viewer.removeEventListener("optionschange", this.optionsChange);
35785
+ this.viewer.removeEventListener("geometrystart", this.geometryStart);
35786
+ this.viewer.removeEventListener("databasechunk", this.databaseChunk);
35787
+ this.viewer.removeEventListener("geometryend", this.geometryEnd);
35788
+ this.viewer.removeEventListener("resize", this.resize);
35789
+ this.viewer.removeEventListener("render", this.render);
35790
+ this.viewer.addEventListener("animate", this.animate);
35791
+ }
35792
+ }
35793
+
35615
35794
  class RenderLoopComponent {
35616
35795
  constructor(viewer) {
35617
35796
  this.animate = (time = 0) => {
@@ -36737,6 +36916,7 @@ void main() {
36737
36916
  components.registerComponent("CameraComponent", (viewer) => new CameraComponent(viewer));
36738
36917
  components.registerComponent("BackgroundComponent", (viewer) => new BackgroundComponent(viewer));
36739
36918
  components.registerComponent("LightComponent", (viewer) => new LightComponent(viewer));
36919
+ components.registerComponent("InfoComponent", (viewer) => new InfoComponent(viewer));
36740
36920
  components.registerComponent("ResizeCanvasComponent", (viewer) => new ResizeCanvasComponent(viewer));
36741
36921
  components.registerComponent("RenderLoopComponent", (viewer) => new RenderLoopComponent(viewer));
36742
36922
  components.registerComponent("HighlighterComponent", (viewer) => new HighlighterComponent(viewer));
@@ -36777,6 +36957,132 @@ void main() {
36777
36957
  getPrecision() {
36778
36958
  return 2;
36779
36959
  }
36960
+ getInfo() {
36961
+ const geometries = new Set();
36962
+ const materials = new Set();
36963
+ const textures = new Set();
36964
+ let totalObjects = 0;
36965
+ let totalTriangles = 0;
36966
+ let totalPoints = 0;
36967
+ let totalLines = 0;
36968
+ let totalEdges = 0;
36969
+ let geometryBytes = 0;
36970
+ let textureBytes = 0;
36971
+ this.scene.traverse((object) => {
36972
+ totalObjects++;
36973
+ if (object.geometry) {
36974
+ const geometry = object.geometry;
36975
+ if (!geometries.has(geometry)) {
36976
+ geometries.add(geometry);
36977
+ if (geometry.attributes) {
36978
+ for (const name in geometry.attributes) {
36979
+ const attribute = geometry.attributes[name];
36980
+ if (attribute && attribute.array) {
36981
+ geometryBytes += attribute.array.byteLength;
36982
+ }
36983
+ }
36984
+ }
36985
+ if (geometry.index && geometry.index.array) {
36986
+ geometryBytes += geometry.index.array.byteLength;
36987
+ }
36988
+ }
36989
+ if (geometry.index) {
36990
+ const indexCount = geometry.index.count;
36991
+ if (object.isLine || object.isLineSegments) {
36992
+ totalLines += indexCount / 2;
36993
+ }
36994
+ else if (object.isPoints) {
36995
+ totalPoints += indexCount;
36996
+ }
36997
+ else {
36998
+ totalTriangles += indexCount / 3;
36999
+ }
37000
+ }
37001
+ else if (geometry.attributes && geometry.attributes.position) {
37002
+ const positionCount = geometry.attributes.position.count;
37003
+ if (object.isLine || object.isLineSegments) {
37004
+ totalLines += positionCount / 2;
37005
+ }
37006
+ else if (object.isPoints) {
37007
+ totalPoints += positionCount;
37008
+ }
37009
+ else {
37010
+ totalTriangles += positionCount / 3;
37011
+ }
37012
+ }
37013
+ if (object.isLineSegments && geometry.attributes.position) {
37014
+ totalEdges += geometry.attributes.position.count / 2;
37015
+ }
37016
+ }
37017
+ if (object.material) {
37018
+ const materialsArray = Array.isArray(object.material) ? object.material : [object.material];
37019
+ materialsArray.forEach((material) => {
37020
+ materials.add(material);
37021
+ if (material.map && !textures.has(material.map)) {
37022
+ textures.add(material.map);
37023
+ textureBytes += estimateTextureSize(material.map);
37024
+ }
37025
+ const textureProps = [
37026
+ "alphaMap",
37027
+ "aoMap",
37028
+ "bumpMap",
37029
+ "displacementMap",
37030
+ "emissiveMap",
37031
+ "envMap",
37032
+ "lightMap",
37033
+ "metalnessMap",
37034
+ "normalMap",
37035
+ "roughnessMap",
37036
+ "specularMap",
37037
+ "clearcoatMap",
37038
+ "clearcoatNormalMap",
37039
+ "clearcoatRoughnessMap",
37040
+ "iridescenceMap",
37041
+ "sheenColorMap",
37042
+ "sheenRoughnessMap",
37043
+ "thicknessMap",
37044
+ "transmissionMap",
37045
+ "anisotropyMap",
37046
+ "gradientMap",
37047
+ ];
37048
+ textureProps.forEach((prop) => {
37049
+ const texture = material[prop];
37050
+ if (texture && !textures.has(texture)) {
37051
+ textures.add(texture);
37052
+ textureBytes += estimateTextureSize(texture);
37053
+ }
37054
+ });
37055
+ });
37056
+ }
37057
+ });
37058
+ function estimateTextureSize(texture) {
37059
+ if (!texture.image)
37060
+ return 0;
37061
+ const width = texture.image.width || 0;
37062
+ const height = texture.image.height || 0;
37063
+ const bytesPerPixel = 4;
37064
+ const mipmapMultiplier = texture.generateMipmaps ? 1.33 : 1;
37065
+ return width * height * bytesPerPixel * mipmapMultiplier;
37066
+ }
37067
+ const info = new Info();
37068
+ info.scene.objects = totalObjects;
37069
+ info.scene.triangles = Math.floor(totalTriangles);
37070
+ info.scene.points = Math.floor(totalPoints);
37071
+ info.scene.lines = Math.floor(totalLines);
37072
+ info.scene.edges = Math.floor(totalEdges);
37073
+ info.memory.geometries = geometries.size;
37074
+ info.memory.geometryBytes = geometryBytes;
37075
+ info.memory.textures = textures.size;
37076
+ info.memory.textureBytes = Math.floor(textureBytes);
37077
+ info.memory.materials = materials.size;
37078
+ info.memory.totalEstimatedGpuBytes = geometryBytes + Math.floor(textureBytes);
37079
+ info.optimizedScene.objects = info.scene.objects;
37080
+ info.optimizedScene.triangles = info.scene.triangles;
37081
+ info.optimizedScene.points = info.scene.points;
37082
+ info.optimizedScene.lines = info.scene.lines;
37083
+ info.optimizedScene.edges = info.scene.edges;
37084
+ return info;
37085
+ }
36780
37086
  getExtents(target) {
36781
37087
  this.scene.traverseVisible((object) => !object.children.length && target.expandByObject(object));
36782
37088
  return target;
@@ -36909,6 +37215,24 @@ void main() {
36909
37215
  }
36910
37216
 
36911
37217
  class DynamicModelImpl extends ModelImpl {
37218
+ getInfo() {
37219
+ const stats = this.gltfLoader.getStats();
37220
+ const info = new Info();
37221
+ info.scene.objects = stats.scene.beforeOptimization.objects;
37222
+ info.scene.triangles = stats.scene.beforeOptimization.triangles;
37223
+ info.scene.lines = stats.scene.beforeOptimization.lines;
37224
+ info.scene.edges = stats.scene.beforeOptimization.edges;
37225
+ info.optimizedScene.objects = stats.scene.afterOptimization.objects;
37226
+ info.optimizedScene.triangles = stats.scene.afterOptimization.triangles;
37227
+ info.optimizedScene.lines = stats.scene.afterOptimization.lines;
37228
+ info.optimizedScene.edges = stats.scene.afterOptimization.edges;
37229
+ info.memory.geometries = stats.memory.geometries.count;
37230
+ info.memory.geometryBytes = stats.memory.geometries.bytes;
37231
+ info.memory.textures = stats.memory.textures.count;
37232
+ info.memory.materials = stats.memory.materials.count;
37233
+ info.memory.totalEstimatedGpuBytes = stats.memory.totalEstimatedGpuBytes;
37234
+ return info;
37235
+ }
36912
37236
  getExtents(target) {
36913
37237
  return target.union(this.gltfLoader.getTotalGeometryExtent());
36914
37238
  }
@@ -37025,6 +37349,8 @@ void main() {
37025
37349
  this.materialCache = new Map();
37026
37350
  this.uri = "";
37027
37351
  this._nextObjectId = 0;
37352
+ this.loadingAborted = false;
37353
+ this.criticalError = null;
37028
37354
  }
37029
37355
  async initialize(loader) {
37030
37356
  this.json = await this.loadController.loadJson();
@@ -37046,12 +37372,18 @@ void main() {
37046
37372
  this.materials.clear();
37047
37373
  this.activeChunkLoads = 0;
37048
37374
  this.chunkQueue = [];
37375
+ this.loadingAborted = false;
37376
+ this.criticalError = null;
37049
37377
  }
37050
37378
  getJson() {
37051
37379
  return this.json;
37052
37380
  }
37053
37381
  scheduleRequest(request) {
37054
37382
  return new Promise((resolve, reject) => {
37383
+ if (this.loadingAborted) {
37384
+ reject(this.criticalError || new Error("Structure loading has been aborted due to critical error"));
37385
+ return;
37386
+ }
37055
37387
  this.pendingRequests.push({
37056
37388
  ...request,
37057
37389
  _resolve: resolve,
@@ -37059,6 +37391,41 @@ void main() {
37059
37391
  });
37060
37392
  });
37061
37393
  }
37394
+ isCriticalHttpError(error) {
37395
+ if (!error) return false;
37396
+ const status = error.status || error.statusCode || error.code;
37397
+ if (typeof status === "number") {
37398
+ return status >= 400 && status < 600;
37399
+ }
37400
+ if (error.message) {
37401
+ const match = error.message.match(/HTTP\s+(\d{3})/i);
37402
+ if (match) {
37403
+ const code = parseInt(match[1], 10);
37404
+ return code >= 400 && code < 600;
37405
+ }
37406
+ }
37407
+ return false;
37408
+ }
37409
+ abortLoading(error) {
37410
+ if (this.loadingAborted) {
37411
+ return;
37412
+ }
37413
+ this.loadingAborted = true;
37414
+ this.criticalError = error;
37415
+ const requests = [...this.pendingRequests];
37416
+ this.pendingRequests = [];
37417
+ for (const req of requests) {
37418
+ if (req._reject) {
37419
+ req._reject(error);
37420
+ }
37421
+ }
37422
+ console.error(
37423
+ `❌ Critical error for structure "${this.id}". All further loading aborted.`,
37424
+ `\n Error: ${error.message || error}`,
37425
+ `\n Rejected ${requests.length} pending chunk requests.`
37426
+ );
37427
+ throw error;
37428
+ }
37062
37429
  async flushBufferRequests() {
37063
37430
  if (!this.pendingRequests || this.pendingRequests.length === 0) return;
37064
37431
  const requests = [...this.pendingRequests];
@@ -37121,6 +37488,12 @@ void main() {
37121
37488
  }
37122
37489
  }
37123
37490
  const promises = finalRanges.map(async (range, index) => {
37491
+ if (this.loadingAborted) {
37492
+ for (const req of range.requests) {
37493
+ req._reject(this.criticalError || new Error("Structure loading aborted"));
37494
+ }
37495
+ return;
37496
+ }
37124
37497
  await this.loader.waitForChunkSlot();
37125
37498
  try {
37126
37499
  const length = range.end - range.start;
@@ -37137,7 +37510,11 @@ void main() {
37137
37510
  for (const req of range.requests) {
37138
37511
  req._reject(error);
37139
37512
  }
37140
- console.warn(`Failed to load chunk ${index + 1}/${finalRanges.length} (${range.start}-${range.end}):`, error);
37513
+ if (this.isCriticalHttpError(error)) {
37514
+ this.abortLoading(error);
37515
+ } else {
37516
+ console.warn(`Failed to load chunk ${index + 1}/${finalRanges.length} (${range.start}-${range.end}):`, error);
37517
+ }
37141
37518
  } finally {
37142
37519
  this.loader.releaseChunkSlot();
37143
37520
  }
@@ -38077,10 +38454,14 @@ void main() {
38077
38454
  onLoadFinishCb();
38078
38455
  }
38079
38456
  } catch (error) {
38080
- if (error.name !== "AbortError") {
38081
- console.error(`Error loading node ${nodeId}:`, error);
38082
- }
38083
38457
  node.loading = false;
38458
+ if (error.name === "AbortError") {
38459
+ return;
38460
+ }
38461
+ if (node.structure && node.structure.loadingAborted) {
38462
+ return;
38463
+ }
38464
+ console.error(`Error loading node ${nodeId}:`, error);
38084
38465
  }
38085
38466
  }
38086
38467
  unloadNode(nodeId) {
@@ -38886,6 +39267,7 @@ void main() {
38886
39267
  }
38887
39268
  const visibilityMaterial = this.createVisibilityMaterial(group.material);
38888
39269
  const mergedMesh = new Mesh(mergedGeometry, visibilityMaterial);
39270
+ mergedMesh.userData.isOptimized = true;
38889
39271
  rootGroup.add(mergedMesh);
38890
39272
  this.mergedMesh.add(mergedMesh);
38891
39273
  this.optimizedOriginalMap.set(mergedMesh, optimizedObjects);
@@ -38992,6 +39374,7 @@ void main() {
38992
39374
  const visibilityMaterial = this.createVisibilityMaterial(group.material);
38993
39375
  const mergedLine = new LineSegments(geometry, visibilityMaterial);
38994
39376
  mergedLine.userData.isEdge = isEdge;
39377
+ mergedLine.userData.isOptimized = true;
38995
39378
  const mergedObjects = [mergedLine];
38996
39379
  if (this.useVAO) {
38997
39380
  this.createVAO(mergedLine);
@@ -39070,6 +39453,7 @@ void main() {
39070
39453
  const visibilityMaterial = this.createVisibilityMaterial(group.material);
39071
39454
  const mergedLine = new LineSegments(mergedGeometry, visibilityMaterial);
39072
39455
  mergedLine.userData.isEdge = isEdge;
39456
+ mergedLine.userData.isOptimized = true;
39073
39457
  if (this.useVAO) {
39074
39458
  this.createVAO(mergedLine);
39075
39459
  }
@@ -39129,6 +39513,7 @@ void main() {
39129
39513
  if (geometries.length > 0) {
39130
39514
  const mergedGeometry = mergeGeometries(geometries, false);
39131
39515
  const mergedPoints = new Points(mergedGeometry, group.material);
39516
+ mergedPoints.userData.isOptimized = true;
39132
39517
  if (this.useVAO) {
39133
39518
  this.createVAO(mergedPoints);
39134
39519
  }
@@ -39204,6 +39589,7 @@ void main() {
39204
39589
  }
39205
39590
  const mergedLine = new LineSegments(finalGeometry, material);
39206
39591
  mergedLine.userData.structureId = structureId;
39592
+ mergedLine.userData.isOptimized = true;
39207
39593
  rootGroup.add(mergedLine);
39208
39594
  this.mergedLineSegments.add(mergedLine);
39209
39595
  lineSegmentsArray.forEach((obj) => {
@@ -39473,6 +39859,13 @@ void main() {
39473
39859
  }
39474
39860
  }
39475
39861
 
39862
+ class FetchError extends Error {
39863
+ constructor(status, message) {
39864
+ super(message);
39865
+ this.name = "FetchError";
39866
+ this.status = status;
39867
+ }
39868
+ }
39476
39869
  class RangesLoader {
39477
39870
  constructor() {
39478
39871
  this.requestHeader = {};
@@ -39499,7 +39892,7 @@ void main() {
39499
39892
  };
39500
39893
  const response = await fetch(url, init);
39501
39894
  if (!response.ok) {
39502
- throw new Error(`Failed to fetch "${url}", status ${response.status}`);
39895
+ throw new FetchError(response.status, `Failed to fetch "${url}", status ${response.status}`);
39503
39896
  }
39504
39897
  if (response.status !== 206) {
39505
39898
  const arrayBuffer = await response.arrayBuffer();
@@ -54639,6 +55032,7 @@ js: import "konva/skia-backend";
54639
55032
  this.options = new Options(this);
54640
55033
  this.loaders = [];
54641
55034
  this.models = [];
55035
+ this.info = new Info();
54642
55036
  this.canvasEvents = CANVAS_EVENTS.slice();
54643
55037
  this.canvaseventlistener = (event) => this.emit(event);
54644
55038
  this.selected = [];
@@ -54799,6 +55193,8 @@ js: import "konva/skia-backend";
54799
55193
  const deltaTime = (time - this._renderTime) / 1000;
54800
55194
  this._renderTime = time;
54801
55195
  this._renderNeeded = false;
55196
+ this.renderer.info.autoReset = false;
55197
+ this.renderer.info.reset();
54802
55198
  if (this.options.antialiasing === true || this.options.antialiasing === "msaa") {
54803
55199
  this.renderer.render(this.scene, this.camera);
54804
55200
  this.renderer.render(this.helpers, this.camera);
@@ -55165,6 +55561,7 @@ js: import "konva/skia-backend";
55165
55561
  exports.Component = Component;
55166
55562
  exports.Dragger = Dragger;
55167
55563
  exports.GLTFLoadingManager = GLTFLoadingManager;
55564
+ exports.Info = Info;
55168
55565
  exports.Loader = Loader$1;
55169
55566
  exports.Markup = KonvaMarkup;
55170
55567
  exports.ModelImpl = ModelImpl;