@inweb/viewer-visualize 26.12.7 → 27.1.1

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.
@@ -2781,15 +2781,108 @@ class CameraComponent {
2781
2781
  }
2782
2782
  }
2783
2783
 
2784
+ class InfoComponent {
2785
+ constructor(viewer) {
2786
+ this.initialize = () => {
2787
+ this.resize();
2788
+ this.optionsChange({ data: this.viewer.options });
2789
+ };
2790
+ this.clear = () => {
2791
+ this.viewer.info.performance.timeToFirstRender = 0;
2792
+ this.viewer.info.performance.loadTime = 0;
2793
+ this.viewer.info.scene.objects = 0;
2794
+ this.viewer.info.scene.triangles = 0;
2795
+ this.viewer.info.scene.points = 0;
2796
+ this.viewer.info.scene.lines = 0;
2797
+ this.viewer.info.scene.edges = 0;
2798
+ this.viewer.info.optimizedScene.objects = 0;
2799
+ this.viewer.info.optimizedScene.triangles = 0;
2800
+ this.viewer.info.optimizedScene.points = 0;
2801
+ this.viewer.info.optimizedScene.lines = 0;
2802
+ this.viewer.info.optimizedScene.edges = 0;
2803
+ this.viewer.info.memory.geometries = 0;
2804
+ this.viewer.info.memory.geometryBytes = 0;
2805
+ this.viewer.info.memory.textures = 0;
2806
+ this.viewer.info.memory.textureBytes = 0;
2807
+ this.viewer.info.memory.materials = 0;
2808
+ this.viewer.info.memory.totalEstimatedGpuBytes = 0;
2809
+ this.viewer.info.memory.usedJSHeapSize = 0;
2810
+ };
2811
+ this.optionsChange = ({ data: options }) => {
2812
+ const antialiasing = options.antialiasing === true || options.antialiasing === "fxaa";
2813
+ if (antialiasing)
2814
+ this.viewer.info.render.antialiasing = "fxaa";
2815
+ else
2816
+ this.viewer.info.render.antialiasing = "";
2817
+ };
2818
+ this.geometryStart = () => {
2819
+ this.startTime = performance.now();
2820
+ };
2821
+ this.databaseChunk = () => {
2822
+ this.viewer.info.performance.timeToFirstRender += performance.now() - this.startTime;
2823
+ console.log("Time to first render:", this.viewer.info.performance.timeToFirstRender, "ms");
2824
+ };
2825
+ this.geometryEnd = () => {
2826
+ const memory = performance["memory"];
2827
+ if (memory)
2828
+ this.viewer.info.memory.usedJSHeapSize = memory.usedJSHeapSize;
2829
+ this.viewer.info.performance.loadTime += performance.now() - this.startTime;
2830
+ console.log("File load time:", this.viewer.info.performance.loadTime, "ms");
2831
+ };
2832
+ this.resize = () => {
2833
+ const { width, height } = this.viewer.canvas;
2834
+ this.viewer.info.render.viewport.width = width;
2835
+ this.viewer.info.render.viewport.height = height;
2836
+ };
2837
+ this.render = () => { };
2838
+ this.animate = () => {
2839
+ const time = performance.now();
2840
+ this.viewer.info.performance.frameTime = Math.round(time - this.beginTime);
2841
+ this.beginTime = time;
2842
+ this.frames++;
2843
+ if (time - this.prevTime >= 1000) {
2844
+ this.viewer.info.performance.fps = Math.round((this.frames * 1000) / (time - this.prevTime));
2845
+ this.prevTime = time;
2846
+ this.frames = 0;
2847
+ }
2848
+ };
2849
+ this.viewer = viewer;
2850
+ this.startTime = 0;
2851
+ this.beginTime = performance.now();
2852
+ this.prevTime = performance.now();
2853
+ this.frames = 0;
2854
+ this.viewer.addEventListener("initialize", this.initialize);
2855
+ this.viewer.addEventListener("clear", this.clear);
2856
+ this.viewer.addEventListener("optionschange", this.optionsChange);
2857
+ this.viewer.addEventListener("geometrystart", this.geometryStart);
2858
+ this.viewer.addEventListener("databasechunk", this.databaseChunk);
2859
+ this.viewer.addEventListener("geometryend", this.geometryEnd);
2860
+ this.viewer.addEventListener("resize", this.resize);
2861
+ this.viewer.addEventListener("render", this.render);
2862
+ this.viewer.addEventListener("animate", this.animate);
2863
+ }
2864
+ dispose() {
2865
+ this.viewer.removeEventListener("initialize", this.initialize);
2866
+ this.viewer.removeEventListener("clear", this.clear);
2867
+ this.viewer.removeEventListener("optionschange", this.optionsChange);
2868
+ this.viewer.removeEventListener("geometrystart", this.geometryStart);
2869
+ this.viewer.removeEventListener("databasechunk", this.databaseChunk);
2870
+ this.viewer.removeEventListener("geometryend", this.geometryEnd);
2871
+ this.viewer.removeEventListener("resize", this.resize);
2872
+ this.viewer.removeEventListener("render", this.render);
2873
+ this.viewer.addEventListener("animate", this.animate);
2874
+ }
2875
+ }
2876
+
2784
2877
  class RenderLoopComponent {
2785
2878
  constructor(viewer) {
2786
- this.animate = (time = 0) => {
2879
+ this.animate = (time) => {
2787
2880
  this.requestId = requestAnimationFrame(this.animate);
2788
2881
  this.viewer.render(time);
2789
2882
  this.viewer.emitEvent({ type: "animate", time });
2790
2883
  };
2791
2884
  this.viewer = viewer;
2792
- this.animate();
2885
+ this.requestId = requestAnimationFrame(this.animate);
2793
2886
  }
2794
2887
  dispose() {
2795
2888
  cancelAnimationFrame(this.requestId);
@@ -3066,6 +3159,7 @@ class ResetComponent {
3066
3159
 
3067
3160
  const components = componentsRegistry("visualizejs");
3068
3161
  components.registerComponent("CameraComponent", (viewer) => new CameraComponent(viewer));
3162
+ components.registerComponent("InfoComponent", (viewer) => new InfoComponent(viewer));
3069
3163
  components.registerComponent("ResizeCanvasComponent", (viewer) => new ResizeCanvasComponent(viewer));
3070
3164
  components.registerComponent("RenderLoopComponent", (viewer) => new RenderLoopComponent(viewer));
3071
3165
  components.registerComponent("ZoomWheelComponent", (viewer) => new ZoomWheelComponent(viewer));
@@ -3188,8 +3282,8 @@ class VSFFileLoader extends Loader {
3188
3282
  this.viewer.models.push(modelImpl);
3189
3283
  this.viewer.syncOptions();
3190
3284
  this.viewer.syncOverlay();
3191
- this.viewer.update(true);
3192
3285
  this.viewer.emitEvent({ type: "databasechunk", data, file });
3286
+ this.viewer.update(true);
3193
3287
  return this;
3194
3288
  }
3195
3289
  }
@@ -3210,7 +3304,6 @@ class VSFCloudLoader extends Loader {
3210
3304
  return this;
3211
3305
  const visViewer = this.viewer.visViewer();
3212
3306
  const filesToDownload = [model.database, ...model.geometry];
3213
- console.time("File load time");
3214
3307
  for (let i = 0; i < filesToDownload.length; i++) {
3215
3308
  const dataId = filesToDownload[i];
3216
3309
  const progress = (progress) => {
@@ -3234,15 +3327,14 @@ class VSFCloudLoader extends Loader {
3234
3327
  this.viewer.models.push(modelImpl);
3235
3328
  this.viewer.syncOptions();
3236
3329
  this.viewer.syncOverlay();
3237
- this.viewer.update(true);
3238
3330
  this.viewer.emitEvent({ type: "databasechunk", data, file: model.file, model });
3331
+ this.viewer.update(true);
3239
3332
  }
3240
3333
  else {
3241
- this.viewer.update();
3242
3334
  this.viewer.emitEvent({ type: "geometrychunk", data, file: model.file, model });
3335
+ this.viewer.update();
3243
3336
  }
3244
3337
  }
3245
- console.timeEnd("File load time");
3246
3338
  return this;
3247
3339
  }
3248
3340
  }
@@ -3285,8 +3377,8 @@ class VSFXFileLoader extends Loader {
3285
3377
  this.viewer.models.push(modelImpl);
3286
3378
  this.viewer.syncOptions();
3287
3379
  this.viewer.syncOverlay();
3288
- this.viewer.update(true);
3289
3380
  this.viewer.emitEvent({ type: "databasechunk", data, file });
3381
+ this.viewer.update(true);
3290
3382
  return this;
3291
3383
  }
3292
3384
  }
@@ -3310,7 +3402,6 @@ class VSFXCloudLoader extends Loader {
3310
3402
  const progress = (progress) => {
3311
3403
  this.viewer.emitEvent({ type: "geometryprogress", data: progress, file: model.file, model });
3312
3404
  };
3313
- console.time("File load time");
3314
3405
  const arrayBuffer = await model.downloadResource(model.database, progress, this.abortController.signal);
3315
3406
  const data = new Uint8Array(arrayBuffer);
3316
3407
  if (!this.viewer.visualizeJs)
@@ -3327,41 +3418,12 @@ class VSFXCloudLoader extends Loader {
3327
3418
  this.viewer.models.push(modelImpl);
3328
3419
  this.viewer.syncOptions();
3329
3420
  this.viewer.syncOverlay();
3330
- this.viewer.update(true);
3331
3421
  this.viewer.emitEvent({ type: "databasechunk", data, file: model.file, model });
3332
- console.timeEnd("File load time");
3422
+ this.viewer.update(true);
3333
3423
  return this;
3334
3424
  }
3335
3425
  }
3336
3426
 
3337
- const DELAY_TIME_MULTIPLEXER = 2.0;
3338
- const START_UPDATE_TIME = 1000;
3339
- var UpdateType;
3340
- (function (UpdateType) {
3341
- UpdateType[UpdateType["kDelay"] = 0] = "kDelay";
3342
- UpdateType[UpdateType["kNormal"] = 1] = "kNormal";
3343
- UpdateType[UpdateType["kForce"] = 2] = "kForce";
3344
- })(UpdateType || (UpdateType = {}));
3345
- class UpdateController {
3346
- constructor() {
3347
- this.lastUpdate = 0;
3348
- this.delayUpdateTime = START_UPDATE_TIME;
3349
- }
3350
- initialize(viewer) {
3351
- this.viewer = viewer;
3352
- this.lastUpdate = performance.now();
3353
- }
3354
- update(type) {
3355
- const isNeedUpdate = type !== UpdateType.kDelay || performance.now() - this.lastUpdate >= this.delayUpdateTime;
3356
- const isForce = type === UpdateType.kForce;
3357
- if (isNeedUpdate) {
3358
- this.viewer.update(isForce);
3359
- this.lastUpdate = performance.now();
3360
- this.delayUpdateTime *= DELAY_TIME_MULTIPLEXER;
3361
- }
3362
- }
3363
- }
3364
-
3365
3427
  class VSFXCloudStreamingLoader extends Loader {
3366
3428
  constructor(viewer) {
3367
3429
  super();
@@ -3381,9 +3443,7 @@ class VSFXCloudStreamingLoader extends Loader {
3381
3443
  return this;
3382
3444
  const visLib = this.viewer.visLib();
3383
3445
  const visViewer = this.viewer.visViewer();
3384
- const updateController = new UpdateController();
3385
- updateController.initialize(this.viewer);
3386
- let isFireDatabaseChunk = false;
3446
+ let isServiceDataReady = false;
3387
3447
  const chunkLoadHandler = (progress, chunk) => {
3388
3448
  if (!this.viewer.visualizeJs)
3389
3449
  return;
@@ -3398,8 +3458,8 @@ class VSFXCloudStreamingLoader extends Loader {
3398
3458
  this.viewer.emitEvent({ type: "geometryprogress", data: progress, file: model.file, model });
3399
3459
  let isDatabaseChunk = false;
3400
3460
  if (status === visLib.DatabaseStreamStatus.ReadyServiceData ||
3401
- (status === visLib.DatabaseStreamStatus.Complete && !isFireDatabaseChunk)) {
3402
- isFireDatabaseChunk = true;
3461
+ (status === visLib.DatabaseStreamStatus.Complete && !isServiceDataReady)) {
3462
+ isServiceDataReady = true;
3403
3463
  isDatabaseChunk = true;
3404
3464
  }
3405
3465
  if (isDatabaseChunk) {
@@ -3408,19 +3468,16 @@ class VSFXCloudStreamingLoader extends Loader {
3408
3468
  this.viewer.models.push(modelImpl);
3409
3469
  this.viewer.syncOptions();
3410
3470
  this.viewer.syncOverlay();
3411
- updateController.update(UpdateType.kForce);
3412
3471
  this.viewer.emitEvent({ type: "databasechunk", data: chunk, file: model.file, model });
3472
+ this.viewer.update(true);
3413
3473
  }
3414
3474
  else {
3415
- updateController.update(UpdateType.kDelay);
3416
3475
  this.viewer.emitEvent({ type: "geometrychunk", data: chunk, file: model.file, model });
3476
+ this.viewer.update();
3417
3477
  }
3418
3478
  };
3419
- console.time("File load time");
3420
3479
  await model.downloadResource(model.database, chunkLoadHandler, this.abortController.signal);
3421
- updateController.update(UpdateType.kNormal);
3422
- console.timeEnd("File load time");
3423
- return Promise.resolve(this);
3480
+ return this;
3424
3481
  }
3425
3482
  }
3426
3483
 
@@ -3444,15 +3501,13 @@ class VSFXCloudPartialLoader extends Loader {
3444
3501
  if (!this.viewer.visualizeJs)
3445
3502
  return this;
3446
3503
  const visViewer = this.viewer.visViewer();
3504
+ visViewer.memoryLimit = this.viewer.options.memoryLimit;
3447
3505
  let servicePartAborted = false;
3448
3506
  const pendingRequestsMap = new Map();
3449
3507
  let pendingRequestsTimerId = 0;
3450
3508
  const pendingRequestsAbortHandler = () => clearTimeout(pendingRequestsTimerId);
3451
3509
  const pendingRequestsAbortController = new AbortController();
3452
3510
  this.abortControllerForRequestMap.set(0, pendingRequestsAbortController);
3453
- const updateController = new UpdateController();
3454
- updateController.initialize(this.viewer);
3455
- visViewer.memoryLimit = this.viewer.options.memoryLimit;
3456
3511
  const chunkLoadHandler = (progress, chunk, requestId = 0) => {
3457
3512
  if (!this.viewer.visualizeJs)
3458
3513
  return;
@@ -3471,12 +3526,12 @@ class VSFXCloudPartialLoader extends Loader {
3471
3526
  this.viewer.models.push(modelImpl);
3472
3527
  this.viewer.syncOptions();
3473
3528
  this.viewer.syncOverlay();
3474
- updateController.update(UpdateType.kForce);
3475
3529
  this.viewer.emitEvent({ type: "databasechunk", data: chunk, file: model.file, model });
3530
+ this.viewer.update(true);
3476
3531
  }
3477
3532
  else {
3478
- updateController.update(UpdateType.kDelay);
3479
3533
  this.viewer.emitEvent({ type: "geometrychunk", data: chunk, file: model.file, model });
3534
+ this.viewer.update();
3480
3535
  }
3481
3536
  };
3482
3537
  const downloadResourceRange = async (dataId, requestId, ranges) => {
@@ -3491,7 +3546,6 @@ class VSFXCloudPartialLoader extends Loader {
3491
3546
  finally {
3492
3547
  ranges.forEach((range) => visViewer.onRequestResponseComplete(range.requestId));
3493
3548
  this.abortControllerForRequestMap.delete(requestId);
3494
- updateController.update(UpdateType.kNormal);
3495
3549
  }
3496
3550
  };
3497
3551
  const requestRecordsToRanges = (requestId, records) => {
@@ -3519,11 +3573,10 @@ class VSFXCloudPartialLoader extends Loader {
3519
3573
  downloadResourceRange(model.database, requestId, ranges);
3520
3574
  },
3521
3575
  onFullLoaded: () => {
3522
- updateController.update(UpdateType.kNormal);
3576
+ this.viewer.update(true);
3523
3577
  },
3524
3578
  onRequestResponseParsed: (requestId) => {
3525
3579
  this.abortControllerForRequestMap.delete(requestId);
3526
- updateController.update(UpdateType.kNormal);
3527
3580
  },
3528
3581
  onRequestAborted: (requestId) => {
3529
3582
  const abortCtrl = this.abortControllerForRequestMap.get(requestId);
@@ -3962,6 +4015,7 @@ class Viewer extends EventEmitter2 {
3962
4015
  this.canvaseventlistener = (event) => this.emit(event);
3963
4016
  this._activeDragger = null;
3964
4017
  this._components = [];
4018
+ this._updateDelay = 1000;
3965
4019
  this._renderNeeded = false;
3966
4020
  this._renderTime = 0;
3967
4021
  this._enableAutoUpdate = (_a = params.enableAutoUpdate) !== null && _a !== void 0 ? _a : true;
@@ -4031,8 +4085,8 @@ class Viewer extends EventEmitter2 {
4031
4085
  this.syncOptions();
4032
4086
  this.syncOverlay();
4033
4087
  this._renderTime = performance.now();
4034
- this.render(this._renderTime);
4035
4088
  this.emitEvent({ type: "initialize" });
4089
+ this.update(true);
4036
4090
  return this;
4037
4091
  }
4038
4092
  dispose() {
@@ -4068,8 +4122,8 @@ class Viewer extends EventEmitter2 {
4068
4122
  this.canvas.style.height = height + "px";
4069
4123
  }
4070
4124
  this._viewer.resize(0, this.canvas.width, this.canvas.height, 0);
4071
- this.update(true);
4072
4125
  this.emitEvent({ type: "resize", width, height });
4126
+ this.update(true);
4073
4127
  }
4074
4128
  resize() {
4075
4129
  console.warn("Viewer.resize() has been deprecated since 26.9 and will be removed in a future release, use Viewer.setSize() instead.");
@@ -4084,12 +4138,14 @@ class Viewer extends EventEmitter2 {
4084
4138
  return this;
4085
4139
  }
4086
4140
  update(force = false) {
4141
+ const time = performance.now();
4142
+ force = force || time - this._renderTime >= this._updateDelay;
4087
4143
  if (this._enableAutoUpdate) {
4088
4144
  this._renderNeeded = true;
4089
4145
  if (force)
4090
- this.render();
4146
+ this.render(time);
4091
4147
  }
4092
- this.emitEvent({ type: "update", data: force });
4148
+ this.emitEvent({ type: "update", force });
4093
4149
  }
4094
4150
  render(time) {
4095
4151
  var _a, _b;
@@ -4134,6 +4190,8 @@ class Viewer extends EventEmitter2 {
4134
4190
  return this;
4135
4191
  }
4136
4192
  applyModelTransformMatrix(model) {
4193
+ if (!this.visualizeJs)
4194
+ return;
4137
4195
  this.executeCommand("applyModelTransform", model);
4138
4196
  }
4139
4197
  applySceneGraphSettings(options = this.options) {
@@ -4179,16 +4237,15 @@ class Viewer extends EventEmitter2 {
4179
4237
  try {
4180
4238
  await this.loadReferences(model);
4181
4239
  await loader.load(model, format, params);
4240
+ this.applyModelTransformMatrix(model);
4241
+ this.applySceneGraphSettings();
4182
4242
  }
4183
4243
  catch (error) {
4184
4244
  this.emitEvent({ type: "geometryerror", data: error, file, model });
4185
4245
  throw error;
4186
4246
  }
4187
4247
  this.emitEvent({ type: "geometryend", file, model });
4188
- if (this.visualizeJs) {
4189
- this.applyModelTransformMatrix(model);
4190
- this.applySceneGraphSettings();
4191
- }
4248
+ this.update(true);
4192
4249
  return this;
4193
4250
  }
4194
4251
  openVsfFile(buffer) {
@@ -4205,7 +4262,6 @@ class Viewer extends EventEmitter2 {
4205
4262
  visViewer.parseFile(data);
4206
4263
  this.syncOptions();
4207
4264
  this.syncOverlay();
4208
- this.update(true);
4209
4265
  this.emitEvent({ type: "geometryprogress", data: 1, file: "", buffer });
4210
4266
  this.emitEvent({ type: "databasechunk", data, file: "", buffer });
4211
4267
  }
@@ -4214,6 +4270,7 @@ class Viewer extends EventEmitter2 {
4214
4270
  throw error;
4215
4271
  }
4216
4272
  this.emitEvent({ type: "geometryend", file: "", buffer });
4273
+ this.update(true);
4217
4274
  return this;
4218
4275
  }
4219
4276
  openVsfxFile(buffer) {
@@ -4230,7 +4287,6 @@ class Viewer extends EventEmitter2 {
4230
4287
  visViewer.parseVsfx(data);
4231
4288
  this.syncOptions();
4232
4289
  this.syncOverlay();
4233
- this.update(true);
4234
4290
  this.emitEvent({ type: "geometryprogress", data: 1, file: "", buffer });
4235
4291
  this.emitEvent({ type: "databasechunk", data, file: "", buffer });
4236
4292
  }
@@ -4239,6 +4295,7 @@ class Viewer extends EventEmitter2 {
4239
4295
  throw error;
4240
4296
  }
4241
4297
  this.emitEvent({ type: "geometryend", file: "", buffer });
4298
+ this.update(true);
4242
4299
  return this;
4243
4300
  }
4244
4301
  cancel() {
@@ -4265,8 +4322,8 @@ class Viewer extends EventEmitter2 {
4265
4322
  visViewer.createLocalDatabase();
4266
4323
  this.syncOptions();
4267
4324
  this.syncOverlay();
4268
- this.update(true);
4269
4325
  this.emitEvent({ type: "clear" });
4326
+ this.update(true);
4270
4327
  return this;
4271
4328
  }
4272
4329
  is3D() {
@@ -4559,7 +4616,7 @@ class Viewer extends EventEmitter2 {
4559
4616
  this.syncOverlay();
4560
4617
  this.setActiveDragger(draggerName);
4561
4618
  this.emitEvent({ type: "drawviewpoint", data: viewpoint });
4562
- this.update();
4619
+ this.update(true);
4563
4620
  }
4564
4621
  createViewpoint() {
4565
4622
  if (!this.visualizeJs)
@@ -4706,7 +4763,7 @@ class Viewer extends EventEmitter2 {
4706
4763
  (_a = this.visViewer()) === null || _a === void 0 ? void 0 : _a.update(maxScheduleUpdateTimeInMs);
4707
4764
  (_c = (_b = this._activeDragger) === null || _b === void 0 ? void 0 : _b.updatePreview) === null || _c === void 0 ? void 0 : _c.call(_b);
4708
4765
  }
4709
- this.emitEvent({ type: "update", data: false });
4766
+ this.emitEvent({ type: "update", force: false });
4710
4767
  resolve();
4711
4768
  }
4712
4769
  catch (e) {