@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.
@@ -0,0 +1,22 @@
1
+ import { IComponent } from "@inweb/viewer-core";
2
+ import type { Viewer } from "../Viewer";
3
+ export declare class InfoComponent implements IComponent {
4
+ protected viewer: Viewer;
5
+ private startTime;
6
+ private beginTime;
7
+ private prevTime;
8
+ private frames;
9
+ constructor(viewer: Viewer);
10
+ dispose(): void;
11
+ initialize: () => void;
12
+ clear: () => void;
13
+ optionsChange: ({ data: options }: {
14
+ data: any;
15
+ }) => void;
16
+ geometryStart: () => void;
17
+ databaseChunk: () => void;
18
+ geometryEnd: () => void;
19
+ resize: () => void;
20
+ render: () => void;
21
+ animate: () => void;
22
+ }
@@ -5,5 +5,5 @@ export declare class RenderLoopComponent implements IComponent {
5
5
  protected requestId: number;
6
6
  constructor(viewer: Viewer);
7
7
  dispose(): void;
8
- animate: (time?: number) => void;
8
+ animate: (time: number) => void;
9
9
  }
@@ -55,11 +55,12 @@ import { ILoadersRegistry } from "@inweb/viewer-core";
55
55
  *
56
56
  * this.viewer.syncOptions();
57
57
  * this.viewer.syncOverlay();
58
- * this.viewer.update();
59
58
  *
60
59
  * this.viewer.emitEvent({ type: "geometryprogress", data: 1, file });
61
60
  * this.viewer.emitEvent({ type: "databasechunk", data, file });
62
61
  *
62
+ * this.viewer.update(true);
63
+ *
63
64
  * return Promise.resove(this);
64
65
  * };
65
66
  * }
@@ -23,6 +23,7 @@ export declare class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMa
23
23
  private _crossOrigin;
24
24
  private _activeDragger;
25
25
  private _components;
26
+ private _updateDelay;
26
27
  private _renderNeeded;
27
28
  private _renderTime;
28
29
  private _enableAutoUpdate;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inweb/viewer-visualize",
3
- "version": "26.12.7",
3
+ "version": "27.1.1",
4
4
  "description": "JavaScript library for rendering CAD and BIM files in a browser using VisualizeJS",
5
5
  "homepage": "https://cloud.opendesign.com/docs/index.html",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -29,10 +29,10 @@
29
29
  "docs": "typedoc"
30
30
  },
31
31
  "dependencies": {
32
- "@inweb/client": "~26.12.7",
33
- "@inweb/eventemitter2": "~26.12.7",
34
- "@inweb/markup": "~26.12.7",
35
- "@inweb/viewer-core": "~26.12.7"
32
+ "@inweb/client": "~27.1.1",
33
+ "@inweb/eventemitter2": "~27.1.1",
34
+ "@inweb/markup": "~27.1.1",
35
+ "@inweb/viewer-core": "~27.1.1"
36
36
  },
37
37
  "visualizeJS": "https://public-fhemb7e3embacwec.z02.azurefd.net/libs/visualizejs/master/Visualize.js"
38
38
  }
@@ -0,0 +1,139 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2002-2025, Open Design Alliance (the "Alliance").
3
+ // All rights reserved.
4
+ //
5
+ // This software and its documentation and related materials are owned by
6
+ // the Alliance. The software may only be incorporated into application
7
+ // programs owned by members of the Alliance, subject to a signed
8
+ // Membership Agreement and Supplemental Software License Agreement with the
9
+ // Alliance. The structure and organization of this software are the valuable
10
+ // trade secrets of the Alliance and its suppliers. The software is also
11
+ // protected by copyright law and international treaty provisions. Application
12
+ // programs incorporating this software must include the following statement
13
+ // with their copyright notices:
14
+ //
15
+ // This application incorporates Open Design Alliance software pursuant to a
16
+ // license agreement with Open Design Alliance.
17
+ // Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance.
18
+ // All rights reserved.
19
+ //
20
+ // By use of this software, its documentation or related materials, you
21
+ // acknowledge and accept the above terms.
22
+ ///////////////////////////////////////////////////////////////////////////////
23
+
24
+ import { IComponent } from "@inweb/viewer-core";
25
+ import type { Viewer } from "../Viewer";
26
+
27
+ export class InfoComponent implements IComponent {
28
+ protected viewer: Viewer;
29
+ private startTime: number;
30
+ private beginTime: number;
31
+ private prevTime: number;
32
+ private frames: number;
33
+
34
+ constructor(viewer: Viewer) {
35
+ this.viewer = viewer;
36
+ this.startTime = 0;
37
+ this.beginTime = performance.now();
38
+ this.prevTime = performance.now();
39
+ this.frames = 0;
40
+ this.viewer.addEventListener("initialize", this.initialize);
41
+ this.viewer.addEventListener("clear", this.clear);
42
+ this.viewer.addEventListener("optionschange", this.optionsChange);
43
+ this.viewer.addEventListener("geometrystart", this.geometryStart);
44
+ this.viewer.addEventListener("databasechunk", this.databaseChunk);
45
+ this.viewer.addEventListener("geometryend", this.geometryEnd);
46
+ this.viewer.addEventListener("resize", this.resize);
47
+ this.viewer.addEventListener("render", this.render);
48
+ this.viewer.addEventListener("animate", this.animate);
49
+ }
50
+
51
+ dispose() {
52
+ this.viewer.removeEventListener("initialize", this.initialize);
53
+ this.viewer.removeEventListener("clear", this.clear);
54
+ this.viewer.removeEventListener("optionschange", this.optionsChange);
55
+ this.viewer.removeEventListener("geometrystart", this.geometryStart);
56
+ this.viewer.removeEventListener("databasechunk", this.databaseChunk);
57
+ this.viewer.removeEventListener("geometryend", this.geometryEnd);
58
+ this.viewer.removeEventListener("resize", this.resize);
59
+ this.viewer.removeEventListener("render", this.render);
60
+ this.viewer.addEventListener("animate", this.animate);
61
+ }
62
+
63
+ initialize = () => {
64
+ this.resize();
65
+ this.optionsChange({ data: this.viewer.options });
66
+ };
67
+
68
+ clear = () => {
69
+ this.viewer.info.performance.timeToFirstRender = 0;
70
+ this.viewer.info.performance.loadTime = 0;
71
+
72
+ this.viewer.info.scene.objects = 0;
73
+ this.viewer.info.scene.triangles = 0;
74
+ this.viewer.info.scene.points = 0;
75
+ this.viewer.info.scene.lines = 0;
76
+ this.viewer.info.scene.edges = 0;
77
+
78
+ this.viewer.info.optimizedScene.objects = 0;
79
+ this.viewer.info.optimizedScene.triangles = 0;
80
+ this.viewer.info.optimizedScene.points = 0;
81
+ this.viewer.info.optimizedScene.lines = 0;
82
+ this.viewer.info.optimizedScene.edges = 0;
83
+
84
+ this.viewer.info.memory.geometries = 0;
85
+ this.viewer.info.memory.geometryBytes = 0;
86
+ this.viewer.info.memory.textures = 0;
87
+ this.viewer.info.memory.textureBytes = 0;
88
+ this.viewer.info.memory.materials = 0;
89
+ this.viewer.info.memory.totalEstimatedGpuBytes = 0;
90
+ this.viewer.info.memory.usedJSHeapSize = 0;
91
+ };
92
+
93
+ optionsChange = ({ data: options }) => {
94
+ const antialiasing = options.antialiasing === true || options.antialiasing === "fxaa";
95
+ if (antialiasing) this.viewer.info.render.antialiasing = "fxaa";
96
+ else this.viewer.info.render.antialiasing = "";
97
+ };
98
+
99
+ geometryStart = () => {
100
+ this.startTime = performance.now();
101
+ };
102
+
103
+ databaseChunk = () => {
104
+ this.viewer.info.performance.timeToFirstRender += performance.now() - this.startTime;
105
+
106
+ console.log("Time to first render:", this.viewer.info.performance.timeToFirstRender, "ms");
107
+ };
108
+
109
+ geometryEnd = () => {
110
+ const memory = performance["memory"];
111
+ if (memory) this.viewer.info.memory.usedJSHeapSize = memory.usedJSHeapSize;
112
+
113
+ this.viewer.info.performance.loadTime += performance.now() - this.startTime;
114
+
115
+ console.log("File load time:", this.viewer.info.performance.loadTime, "ms");
116
+ };
117
+
118
+ resize = () => {
119
+ const { width, height } = this.viewer.canvas;
120
+ this.viewer.info.render.viewport.width = width;
121
+ this.viewer.info.render.viewport.height = height;
122
+ };
123
+
124
+ render = () => {};
125
+
126
+ animate = () => {
127
+ const time = performance.now();
128
+
129
+ this.viewer.info.performance.frameTime = Math.round(time - this.beginTime);
130
+ this.beginTime = time;
131
+
132
+ this.frames++;
133
+ if (time - this.prevTime >= 1000) {
134
+ this.viewer.info.performance.fps = Math.round((this.frames * 1000) / (time - this.prevTime));
135
+ this.prevTime = time;
136
+ this.frames = 0;
137
+ }
138
+ };
139
+ }
@@ -30,14 +30,14 @@ export class RenderLoopComponent implements IComponent {
30
30
 
31
31
  constructor(viewer: Viewer) {
32
32
  this.viewer = viewer;
33
- this.animate();
33
+ this.requestId = requestAnimationFrame(this.animate);
34
34
  }
35
35
 
36
36
  dispose() {
37
37
  cancelAnimationFrame(this.requestId);
38
38
  }
39
39
 
40
- animate = (time = 0) => {
40
+ animate = (time: number) => {
41
41
  this.requestId = requestAnimationFrame(this.animate);
42
42
 
43
43
  this.viewer.render(time);
@@ -24,6 +24,7 @@
24
24
  import { IComponentsRegistry, componentsRegistry } from "@inweb/viewer-core";
25
25
 
26
26
  import { CameraComponent } from "./CameraComponent";
27
+ import { InfoComponent } from "./InfoComponent";
27
28
  import { RenderLoopComponent } from "./RenderLoopComponent";
28
29
  import { ResizeCanvasComponent } from "./ResizeCanvasComponent";
29
30
  import { ZoomWheelComponent } from "./ZoomWheelComponent";
@@ -74,6 +75,7 @@ export const components: IComponentsRegistry = componentsRegistry("visualizejs")
74
75
  // build-in components
75
76
 
76
77
  components.registerComponent("CameraComponent", (viewer) => new CameraComponent(viewer));
78
+ components.registerComponent("InfoComponent", (viewer) => new InfoComponent(viewer));
77
79
  components.registerComponent("ResizeCanvasComponent", (viewer) => new ResizeCanvasComponent(viewer));
78
80
  components.registerComponent("RenderLoopComponent", (viewer) => new RenderLoopComponent(viewer));
79
81
  components.registerComponent("ZoomWheelComponent", (viewer) => new ZoomWheelComponent(viewer));
@@ -48,8 +48,6 @@ export class VSFCloudLoader extends Loader {
48
48
  const visViewer = this.viewer.visViewer();
49
49
  const filesToDownload = [model.database, ...model.geometry];
50
50
 
51
- console.time("File load time");
52
-
53
51
  for (let i = 0; i < filesToDownload.length; i++) {
54
52
  const dataId = filesToDownload[i];
55
53
 
@@ -78,17 +76,15 @@ export class VSFCloudLoader extends Loader {
78
76
 
79
77
  this.viewer.syncOptions();
80
78
  this.viewer.syncOverlay();
81
- this.viewer.update(true);
82
79
 
83
80
  this.viewer.emitEvent({ type: "databasechunk", data, file: model.file, model });
81
+ this.viewer.update(true);
84
82
  } else {
85
- this.viewer.update();
86
83
  this.viewer.emitEvent({ type: "geometrychunk", data, file: model.file, model });
84
+ this.viewer.update();
87
85
  }
88
86
  }
89
87
 
90
- console.timeEnd("File load time");
91
-
92
88
  return this;
93
89
  }
94
90
  }
@@ -76,9 +76,9 @@ export class VSFFileLoader extends Loader {
76
76
 
77
77
  this.viewer.syncOptions();
78
78
  this.viewer.syncOverlay();
79
- this.viewer.update(true);
80
79
 
81
80
  this.viewer.emitEvent({ type: "databasechunk", data, file });
81
+ this.viewer.update(true);
82
82
 
83
83
  return this;
84
84
  }
@@ -52,8 +52,6 @@ export class VSFXCloudLoader extends Loader {
52
52
  this.viewer.emitEvent({ type: "geometryprogress", data: progress, file: model.file, model });
53
53
  };
54
54
 
55
- console.time("File load time");
56
-
57
55
  const arrayBuffer = await model.downloadResource(model.database, progress, this.abortController.signal);
58
56
  const data = new Uint8Array(arrayBuffer);
59
57
 
@@ -73,11 +71,9 @@ export class VSFXCloudLoader extends Loader {
73
71
 
74
72
  this.viewer.syncOptions();
75
73
  this.viewer.syncOverlay();
76
- this.viewer.update(true);
77
74
 
78
75
  this.viewer.emitEvent({ type: "databasechunk", data, file: model.file, model });
79
-
80
- console.timeEnd("File load time");
76
+ this.viewer.update(true);
81
77
 
82
78
  return this;
83
79
  }
@@ -24,7 +24,6 @@
24
24
  import { Loader } from "@inweb/viewer-core";
25
25
  import { Viewer } from "../Viewer";
26
26
  import { ModelImpl } from "../Models/ModelImpl";
27
- import { UpdateController, UpdateType } from "./UpdateController";
28
27
 
29
28
  const PENDING_REQUESTS_SIZE = 50;
30
29
  const PENDING_REQUESTS_TIMEOUT = 250;
@@ -54,6 +53,8 @@ export class VSFXCloudPartialLoader extends Loader {
54
53
  if (!this.viewer.visualizeJs) return this;
55
54
 
56
55
  const visViewer = this.viewer.visViewer();
56
+ visViewer.memoryLimit = this.viewer.options.memoryLimit;
57
+
57
58
  let servicePartAborted = false;
58
59
 
59
60
  const pendingRequestsMap = new Map();
@@ -63,11 +64,6 @@ export class VSFXCloudPartialLoader extends Loader {
63
64
  const pendingRequestsAbortController = new AbortController();
64
65
  this.abortControllerForRequestMap.set(0, pendingRequestsAbortController);
65
66
 
66
- const updateController = new UpdateController();
67
- updateController.initialize(this.viewer);
68
-
69
- visViewer.memoryLimit = this.viewer.options.memoryLimit;
70
-
71
67
  const chunkLoadHandler = (progress: number, chunk: Uint8Array, requestId = 0) => {
72
68
  if (!this.viewer.visualizeJs) return;
73
69
 
@@ -89,12 +85,12 @@ export class VSFXCloudPartialLoader extends Loader {
89
85
 
90
86
  this.viewer.syncOptions();
91
87
  this.viewer.syncOverlay();
92
- updateController.update(UpdateType.kForce);
93
88
 
94
89
  this.viewer.emitEvent({ type: "databasechunk", data: chunk, file: model.file, model });
90
+ this.viewer.update(true);
95
91
  } else {
96
- updateController.update(UpdateType.kDelay);
97
92
  this.viewer.emitEvent({ type: "geometrychunk", data: chunk, file: model.file, model });
93
+ this.viewer.update();
98
94
  }
99
95
  };
100
96
 
@@ -108,7 +104,6 @@ export class VSFXCloudPartialLoader extends Loader {
108
104
  } finally {
109
105
  ranges.forEach((range) => visViewer.onRequestResponseComplete(range.requestId));
110
106
  this.abortControllerForRequestMap.delete(requestId);
111
- updateController.update(UpdateType.kNormal);
112
107
  }
113
108
  };
114
109
 
@@ -140,12 +135,11 @@ export class VSFXCloudPartialLoader extends Loader {
140
135
  },
141
136
 
142
137
  onFullLoaded: () => {
143
- updateController.update(UpdateType.kNormal);
138
+ this.viewer.update(true);
144
139
  },
145
140
 
146
141
  onRequestResponseParsed: (requestId: number) => {
147
142
  this.abortControllerForRequestMap.delete(requestId);
148
- updateController.update(UpdateType.kNormal);
149
143
  },
150
144
 
151
145
  onRequestAborted: (requestId: number) => {
@@ -165,7 +159,8 @@ export class VSFXCloudPartialLoader extends Loader {
165
159
  requestNumber = pendingRequest.number;
166
160
  }
167
161
 
168
- // first several records of each file are processed without grouping (they usually require to be processed sequentially)
162
+ // first several records of each file are processed without grouping
163
+ // (they usually require to be processed sequentially)
169
164
  if (requestNumber <= 5) {
170
165
  pendingRequestsMap.set(dataId, { ranges: [], number: requestNumber + 1 });
171
166
  downloadResourceRange(dataId, requestId, ranges);
@@ -24,7 +24,6 @@
24
24
  import { Loader } from "@inweb/viewer-core";
25
25
  import { Viewer } from "../Viewer";
26
26
  import { ModelImpl } from "../Models/ModelImpl";
27
- import { UpdateController, UpdateType } from "./UpdateController";
28
27
 
29
28
  export class VSFXCloudStreamingLoader extends Loader {
30
29
  public viewer: Viewer;
@@ -52,10 +51,7 @@ export class VSFXCloudStreamingLoader extends Loader {
52
51
  const visLib = this.viewer.visLib();
53
52
  const visViewer = this.viewer.visViewer();
54
53
 
55
- const updateController = new UpdateController();
56
- updateController.initialize(this.viewer);
57
-
58
- let isFireDatabaseChunk = false;
54
+ let isServiceDataReady = false;
59
55
 
60
56
  const chunkLoadHandler = (progress: number, chunk: Uint8Array) => {
61
57
  if (!this.viewer.visualizeJs) return;
@@ -73,9 +69,9 @@ export class VSFXCloudStreamingLoader extends Loader {
73
69
  let isDatabaseChunk = false;
74
70
  if (
75
71
  status === visLib.DatabaseStreamStatus.ReadyServiceData ||
76
- (status === visLib.DatabaseStreamStatus.Complete && !isFireDatabaseChunk)
72
+ (status === visLib.DatabaseStreamStatus.Complete && !isServiceDataReady)
77
73
  ) {
78
- isFireDatabaseChunk = true;
74
+ isServiceDataReady = true;
79
75
  isDatabaseChunk = true;
80
76
  }
81
77
 
@@ -87,22 +83,17 @@ export class VSFXCloudStreamingLoader extends Loader {
87
83
 
88
84
  this.viewer.syncOptions();
89
85
  this.viewer.syncOverlay();
90
- updateController.update(UpdateType.kForce);
91
86
 
92
87
  this.viewer.emitEvent({ type: "databasechunk", data: chunk, file: model.file, model });
88
+ this.viewer.update(true);
93
89
  } else {
94
- updateController.update(UpdateType.kDelay);
95
90
  this.viewer.emitEvent({ type: "geometrychunk", data: chunk, file: model.file, model });
91
+ this.viewer.update();
96
92
  }
97
93
  };
98
94
 
99
- console.time("File load time");
100
-
101
95
  await model.downloadResource(model.database, chunkLoadHandler, this.abortController.signal);
102
- updateController.update(UpdateType.kNormal);
103
-
104
- console.timeEnd("File load time");
105
96
 
106
- return Promise.resolve(this);
97
+ return this;
107
98
  }
108
99
  }
@@ -76,9 +76,9 @@ export class VSFXFileLoader extends Loader {
76
76
 
77
77
  this.viewer.syncOptions();
78
78
  this.viewer.syncOverlay();
79
- this.viewer.update(true);
80
79
 
81
80
  this.viewer.emitEvent({ type: "databasechunk", data, file });
81
+ this.viewer.update(true);
82
82
 
83
83
  return this;
84
84
  }
@@ -87,11 +87,12 @@ import { VSFXCloudPartialLoader } from "./VSFXCloudPartialLoader";
87
87
  *
88
88
  * this.viewer.syncOptions();
89
89
  * this.viewer.syncOverlay();
90
- * this.viewer.update();
91
90
  *
92
91
  * this.viewer.emitEvent({ type: "geometryprogress", data: 1, file });
93
92
  * this.viewer.emitEvent({ type: "databasechunk", data, file });
94
93
  *
94
+ * this.viewer.update(true);
95
+ *
95
96
  * return Promise.resove(this);
96
97
  * };
97
98
  * }
@@ -86,6 +86,7 @@ export class Viewer
86
86
  private _activeDragger: IDragger | null;
87
87
  private _components: IComponent[];
88
88
 
89
+ private _updateDelay: number;
89
90
  private _renderNeeded: boolean;
90
91
  private _renderTime: DOMHighResTimeStamp;
91
92
  private _enableAutoUpdate: boolean;
@@ -132,6 +133,7 @@ export class Viewer
132
133
  this._activeDragger = null;
133
134
  this._components = [];
134
135
 
136
+ this._updateDelay = 1000;
135
137
  this._renderNeeded = false;
136
138
  this._renderTime = 0;
137
139
  this._enableAutoUpdate = params.enableAutoUpdate ?? true;
@@ -282,9 +284,9 @@ export class Viewer
282
284
  this.syncOverlay();
283
285
 
284
286
  this._renderTime = performance.now();
285
- this.render(this._renderTime);
286
287
 
287
288
  this.emitEvent({ type: "initialize" });
289
+ this.update(true);
288
290
 
289
291
  return this;
290
292
  }
@@ -337,8 +339,8 @@ export class Viewer
337
339
 
338
340
  this._viewer.resize(0, this.canvas.width, this.canvas.height, 0);
339
341
 
340
- this.update(true);
341
342
  this.emitEvent({ type: "resize", width, height });
343
+ this.update(true);
342
344
  }
343
345
 
344
346
  resize(): this {
@@ -372,11 +374,15 @@ export class Viewer
372
374
  * Default is `false`.
373
375
  */
374
376
  update(force = false) {
377
+ const time = performance.now();
378
+ force = force || time - this._renderTime >= this._updateDelay;
379
+
375
380
  if (this._enableAutoUpdate) {
376
381
  this._renderNeeded = true;
377
- if (force) this.render();
382
+ if (force) this.render(time);
378
383
  }
379
- this.emitEvent({ type: "update", data: force });
384
+
385
+ this.emitEvent({ type: "update", force });
380
386
  }
381
387
 
382
388
  // Internal render routines
@@ -429,6 +435,8 @@ export class Viewer
429
435
  }
430
436
 
431
437
  applyModelTransformMatrix(model: Model | Assembly) {
438
+ if (!this.visualizeJs) return;
439
+
432
440
  this.executeCommand("applyModelTransform", model);
433
441
  }
434
442
 
@@ -555,16 +563,15 @@ export class Viewer
555
563
  try {
556
564
  await this.loadReferences(model);
557
565
  await loader.load(model, format, params);
566
+
567
+ this.applyModelTransformMatrix(model);
568
+ this.applySceneGraphSettings();
558
569
  } catch (error: any) {
559
570
  this.emitEvent({ type: "geometryerror", data: error, file, model });
560
571
  throw error;
561
572
  }
562
573
  this.emitEvent({ type: "geometryend", file, model });
563
-
564
- if (this.visualizeJs) {
565
- this.applyModelTransformMatrix(model);
566
- this.applySceneGraphSettings();
567
- }
574
+ this.update(true);
568
575
 
569
576
  return this;
570
577
  }
@@ -595,7 +602,6 @@ export class Viewer
595
602
 
596
603
  this.syncOptions();
597
604
  this.syncOverlay();
598
- this.update(true);
599
605
 
600
606
  this.emitEvent({ type: "geometryprogress", data: 1, file: "", buffer });
601
607
  this.emitEvent({ type: "databasechunk", data, file: "", buffer });
@@ -604,6 +610,7 @@ export class Viewer
604
610
  throw error;
605
611
  }
606
612
  this.emitEvent({ type: "geometryend", file: "", buffer });
613
+ this.update(true);
607
614
 
608
615
  return this;
609
616
  }
@@ -634,7 +641,6 @@ export class Viewer
634
641
 
635
642
  this.syncOptions();
636
643
  this.syncOverlay();
637
- this.update(true);
638
644
 
639
645
  this.emitEvent({ type: "geometryprogress", data: 1, file: "", buffer });
640
646
  this.emitEvent({ type: "databasechunk", data, file: "", buffer });
@@ -643,6 +649,7 @@ export class Viewer
643
649
  throw error;
644
650
  }
645
651
  this.emitEvent({ type: "geometryend", file: "", buffer });
652
+ this.update(true);
646
653
 
647
654
  return this;
648
655
  }
@@ -678,9 +685,9 @@ export class Viewer
678
685
 
679
686
  this.syncOptions();
680
687
  this.syncOverlay();
681
- this.update(true);
682
688
 
683
689
  this.emitEvent({ type: "clear" });
690
+ this.update(true);
684
691
 
685
692
  return this;
686
693
  }
@@ -1098,10 +1105,10 @@ export class Viewer
1098
1105
  this._markup.setViewpoint(viewpoint);
1099
1106
 
1100
1107
  this.syncOverlay();
1101
-
1102
1108
  this.setActiveDragger(draggerName);
1109
+
1103
1110
  this.emitEvent({ type: "drawviewpoint", data: viewpoint });
1104
- this.update();
1111
+ this.update(true);
1105
1112
  }
1106
1113
 
1107
1114
  createViewpoint(): IViewpoint {
@@ -1361,7 +1368,7 @@ export class Viewer
1361
1368
  this.visViewer()?.update(maxScheduleUpdateTimeInMs);
1362
1369
  this._activeDragger?.updatePreview?.();
1363
1370
  }
1364
- this.emitEvent({ type: "update", data: false });
1371
+ this.emitEvent({ type: "update", force: false });
1365
1372
  resolve();
1366
1373
  } catch (e) {
1367
1374
  console.error(e);
@@ -1,14 +0,0 @@
1
- import { Viewer } from "../Viewer";
2
- export declare enum UpdateType {
3
- kDelay = 0,
4
- kNormal = 1,
5
- kForce = 2
6
- }
7
- export declare class UpdateController {
8
- private lastUpdate;
9
- private viewer;
10
- delayUpdateTime: number;
11
- constructor();
12
- initialize(viewer: Viewer): void;
13
- update(type: UpdateType): void;
14
- }