@inweb/viewer-visualize 26.10.5 → 26.11.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.
- package/README.md +6 -4
- package/dist/viewer-visualize.js +591 -475
- package/dist/viewer-visualize.js.map +1 -1
- package/dist/viewer-visualize.min.js +1 -1
- package/dist/viewer-visualize.module.js +583 -483
- package/dist/viewer-visualize.module.js.map +1 -1
- package/lib/Viewer/Commands/GetSelected2.d.ts +2 -0
- package/lib/Viewer/Commands/SetSelected.d.ts +1 -1
- package/lib/Viewer/Commands/SetSelected2.d.ts +2 -0
- package/lib/Viewer/Components/index.d.ts +8 -7
- package/lib/Viewer/Draggers/MeasureLineDragger/MeasureLineItem.d.ts +5 -1
- package/lib/Viewer/Draggers/MeasureLineDragger/index.d.ts +3 -2
- package/lib/Viewer/Loaders/VSFXCloudLoader.d.ts +1 -1
- package/lib/Viewer/Loaders/VSFXCloudPartialLoader.d.ts +1 -1
- package/lib/Viewer/Loaders/index.d.ts +14 -9
- package/lib/Viewer/Models/IModelImpl.d.ts +5 -0
- package/lib/Viewer/Models/ModelImpl.d.ts +5 -0
- package/lib/Viewer/Viewer.d.ts +129 -136
- package/package.json +5 -5
- package/src/Viewer/Commands/ClearSelected.ts +3 -1
- package/src/Viewer/Commands/GetSelected2.ts +33 -0
- package/src/Viewer/Commands/HideSelected.ts +3 -1
- package/src/Viewer/Commands/SelectModel.ts +2 -3
- package/src/Viewer/Commands/SetSelected.ts +5 -2
- package/src/Viewer/Commands/SetSelected2.ts +39 -0
- package/src/Viewer/Commands/index.ts +4 -0
- package/src/Viewer/Components/index.ts +8 -7
- package/src/Viewer/Draggers/Common/OdBaseDragger.ts +3 -2
- package/src/Viewer/Draggers/MeasureLineDragger/MeasureLineItem.ts +44 -13
- package/src/Viewer/Draggers/MeasureLineDragger/index.ts +53 -18
- package/src/Viewer/Draggers/OdJoyStickDragger.ts +2 -2
- package/src/Viewer/Loaders/VSFCloudLoader.ts +6 -0
- package/src/Viewer/Loaders/VSFFileLoader.ts +7 -1
- package/src/Viewer/Loaders/VSFXCloudLoader.ts +7 -1
- package/src/Viewer/Loaders/VSFXCloudPartialLoader.ts +8 -2
- package/src/Viewer/Loaders/VSFXCloudStreamingLoader.ts +7 -1
- package/src/Viewer/Loaders/VSFXFileLoader.ts +7 -1
- package/src/Viewer/Loaders/index.ts +14 -9
- package/src/Viewer/Models/IModelImpl.ts +29 -0
- package/src/Viewer/Models/ModelImpl.ts +32 -0
- package/src/Viewer/Viewer.ts +780 -775
package/src/Viewer/Viewer.ts
CHANGED
|
@@ -30,11 +30,12 @@ import {
|
|
|
30
30
|
FileSource,
|
|
31
31
|
IClippingPlane,
|
|
32
32
|
IComponent,
|
|
33
|
-
IEntity,
|
|
34
33
|
IDragger,
|
|
34
|
+
IEntity,
|
|
35
35
|
ILoader,
|
|
36
36
|
IOrthogonalCamera,
|
|
37
37
|
IOptions,
|
|
38
|
+
IPerspectiveCamera,
|
|
38
39
|
IPoint,
|
|
39
40
|
IViewer,
|
|
40
41
|
IViewpoint,
|
|
@@ -48,6 +49,7 @@ import { draggers } from "./Draggers";
|
|
|
48
49
|
import { commands } from "./Commands";
|
|
49
50
|
import { components } from "./Components";
|
|
50
51
|
import { loaders } from "./Loaders";
|
|
52
|
+
import { IModelImpl } from "./Models/IModelImpl";
|
|
51
53
|
|
|
52
54
|
import { loadVisualizeJs } from "./utils";
|
|
53
55
|
import { MarkupFactory, MarkupType } from "./Markup/MarkupFactory";
|
|
@@ -57,36 +59,38 @@ const OVERLAY_VIEW_NAME = "$OVERLAY_VIEW_NAME";
|
|
|
57
59
|
const isExist = (value) => value !== undefined && value !== null;
|
|
58
60
|
|
|
59
61
|
/**
|
|
60
|
-
* 3D viewer powered by {@link https://cloud.opendesign.com/docs/index.html#/visualizejs | VisualizeJS}
|
|
61
|
-
* library.
|
|
62
|
+
* 3D viewer powered by {@link https://cloud.opendesign.com/docs/index.html#/visualizejs | VisualizeJS}.
|
|
62
63
|
*/
|
|
63
64
|
export class Viewer
|
|
64
65
|
extends EventEmitter2<ViewerEventMap & CanvasEventMap & OptionsEventMap>
|
|
65
66
|
implements IViewer, IWorldTransform
|
|
66
67
|
{
|
|
68
|
+
public client: Client | undefined;
|
|
69
|
+
public options: IOptions;
|
|
70
|
+
public canvas: HTMLCanvasElement | undefined;
|
|
71
|
+
public canvasEvents: string[];
|
|
72
|
+
public loaders: ILoader[];
|
|
73
|
+
public models: IModelImpl[];
|
|
74
|
+
|
|
75
|
+
private canvaseventlistener: (event: Event) => void;
|
|
76
|
+
|
|
77
|
+
private _visualizeJsUrl = "";
|
|
78
|
+
private _visualizeJs: any;
|
|
79
|
+
private _visualizeTimestamp: number;
|
|
80
|
+
private _viewer: any;
|
|
81
|
+
private _crossOrigin;
|
|
82
|
+
|
|
67
83
|
private _activeDragger: IDragger | null;
|
|
68
|
-
private _components:
|
|
69
|
-
|
|
84
|
+
private _components: IComponent[];
|
|
85
|
+
|
|
70
86
|
private _renderNeeded: boolean;
|
|
71
87
|
private _renderTime: DOMHighResTimeStamp;
|
|
88
|
+
private _enableAutoUpdate: boolean;
|
|
72
89
|
private _isRunAsyncUpdate: boolean;
|
|
73
90
|
|
|
74
|
-
|
|
75
|
-
protected _visualizeJsUrl = "";
|
|
76
|
-
protected _visualizeJs: any;
|
|
77
|
-
protected _visualizeTimestamp: number;
|
|
78
|
-
protected _viewer: any;
|
|
79
|
-
protected _crossOrigin;
|
|
80
|
-
|
|
81
|
-
private canvaseventlistener: (event: Event) => void;
|
|
91
|
+
public _abortControllerForReferences: AbortController | undefined;
|
|
82
92
|
|
|
83
|
-
public canvasEvents: string[];
|
|
84
93
|
private _markup: IMarkup;
|
|
85
|
-
public canvas: HTMLCanvasElement | undefined;
|
|
86
|
-
|
|
87
|
-
public _abortControllerForReferences: AbortController | undefined;
|
|
88
|
-
public client: Client | undefined;
|
|
89
|
-
public loaders: Array<ILoader>;
|
|
90
94
|
|
|
91
95
|
/**
|
|
92
96
|
* @param client - The `Client` instance that is used to load model reference files from the Open Cloud
|
|
@@ -113,21 +117,20 @@ export class Viewer
|
|
|
113
117
|
super();
|
|
114
118
|
this.configure(params);
|
|
115
119
|
|
|
116
|
-
this._options = new Options(this);
|
|
117
|
-
|
|
118
120
|
this.client = client;
|
|
121
|
+
this.options = new Options(this);
|
|
119
122
|
this.loaders = [];
|
|
123
|
+
this.models = [];
|
|
124
|
+
|
|
125
|
+
this.canvasEvents = CANVAS_EVENTS.slice();
|
|
126
|
+
this.canvaseventlistener = (event: Event) => this.emit(event);
|
|
120
127
|
|
|
121
128
|
this._activeDragger = null;
|
|
122
129
|
this._components = [];
|
|
123
130
|
|
|
131
|
+
this._renderNeeded = false;
|
|
124
132
|
this._renderTime = 0;
|
|
125
|
-
|
|
126
|
-
this.canvasEvents = CANVAS_EVENTS.slice();
|
|
127
|
-
this.canvaseventlistener = (event: Event) => this.emit(event);
|
|
128
|
-
|
|
129
133
|
this._enableAutoUpdate = params.enableAutoUpdate ?? true;
|
|
130
|
-
this._renderNeeded = false;
|
|
131
134
|
this._isRunAsyncUpdate = false;
|
|
132
135
|
|
|
133
136
|
this.render = this.render.bind(this);
|
|
@@ -136,13 +139,6 @@ export class Viewer
|
|
|
136
139
|
this._markup = MarkupFactory.createMarkup(params.markupType);
|
|
137
140
|
}
|
|
138
141
|
|
|
139
|
-
/**
|
|
140
|
-
* Viewer options.
|
|
141
|
-
*/
|
|
142
|
-
get options(): IOptions {
|
|
143
|
-
return this._options;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
142
|
/**
|
|
147
143
|
* `VisualizeJS` library URL. Use {@link configure | configure()} to change library URL.
|
|
148
144
|
*
|
|
@@ -152,6 +148,30 @@ export class Viewer
|
|
|
152
148
|
return this._visualizeJsUrl;
|
|
153
149
|
}
|
|
154
150
|
|
|
151
|
+
/**
|
|
152
|
+
* Returns `VisualizeJS` {@link https://cloud.opendesign.com/docs/index.html#/visualizejs_api | module}
|
|
153
|
+
* instance.
|
|
154
|
+
*/
|
|
155
|
+
get visualizeJs(): any {
|
|
156
|
+
return this._visualizeJs;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Returns `VisualizeJS` {@link https://cloud.opendesign.com/docs/index.html#/visualizejs_api | module}
|
|
161
|
+
* instance.
|
|
162
|
+
*/
|
|
163
|
+
visLib(): any {
|
|
164
|
+
return this._visualizeJs;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Returns `VisualizeJS` {@link https://cloud.opendesign.com/docs/index.html#/vis/Viewer | Viewer}
|
|
169
|
+
* instance.
|
|
170
|
+
*/
|
|
171
|
+
visViewer(): any {
|
|
172
|
+
return this._viewer;
|
|
173
|
+
}
|
|
174
|
+
|
|
155
175
|
/**
|
|
156
176
|
* 2D markup core instance used to create markups.
|
|
157
177
|
*
|
|
@@ -179,6 +199,16 @@ export class Viewer
|
|
|
179
199
|
return this;
|
|
180
200
|
}
|
|
181
201
|
|
|
202
|
+
// IViewer
|
|
203
|
+
|
|
204
|
+
get draggers(): string[] {
|
|
205
|
+
return [...draggers.getDraggers().keys()];
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
get components(): string[] {
|
|
209
|
+
return [...components.getComponents().keys()];
|
|
210
|
+
}
|
|
211
|
+
|
|
182
212
|
/**
|
|
183
213
|
* Loads the `VisualizeJS` module and initializes it with the specified canvas. Call
|
|
184
214
|
* {@link dispose | dispose()} to release allocated resources.
|
|
@@ -197,12 +227,13 @@ export class Viewer
|
|
|
197
227
|
async initialize(canvas: HTMLCanvasElement, onProgress?: (event: ProgressEvent) => void): Promise<this> {
|
|
198
228
|
this.addEventListener("optionschange", (event) => this.syncOptions(event.data));
|
|
199
229
|
|
|
230
|
+
const pixelRatio = window.devicePixelRatio;
|
|
200
231
|
const rect = canvas.parentElement.getBoundingClientRect();
|
|
201
232
|
const width = rect.width || 1;
|
|
202
233
|
const height = rect.height || 1;
|
|
203
234
|
|
|
204
|
-
canvas.width = Math.round(width *
|
|
205
|
-
canvas.height = Math.round(height *
|
|
235
|
+
canvas.width = Math.round(width * pixelRatio);
|
|
236
|
+
canvas.height = Math.round(height * pixelRatio);
|
|
206
237
|
|
|
207
238
|
canvas.style.width = width + "px";
|
|
208
239
|
canvas.style.height = height + "px";
|
|
@@ -306,28 +337,7 @@ export class Viewer
|
|
|
306
337
|
this.emitEvent({ type: "resize", width, height });
|
|
307
338
|
}
|
|
308
339
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
public render(time?: DOMHighResTimeStamp) {
|
|
312
|
-
if (!this.visualizeJs) return;
|
|
313
|
-
if (this._isRunAsyncUpdate) return;
|
|
314
|
-
|
|
315
|
-
const renderNeeded = this.visViewer().isRunningAnimation() || this._renderNeeded;
|
|
316
|
-
if (!renderNeeded) return;
|
|
317
|
-
|
|
318
|
-
if (!time) time = performance.now();
|
|
319
|
-
const deltaTime = (time - this._renderTime) / 1000;
|
|
320
|
-
|
|
321
|
-
this._renderTime = time;
|
|
322
|
-
this._renderNeeded = !this.visViewer().getActiveDevice().isValid();
|
|
323
|
-
|
|
324
|
-
this.visViewer().update();
|
|
325
|
-
this._activeDragger?.updatePreview?.();
|
|
326
|
-
|
|
327
|
-
this.emitEvent({ type: "render", time, deltaTime });
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
public resize(): this {
|
|
340
|
+
resize(): this {
|
|
331
341
|
console.warn(
|
|
332
342
|
"Viewer.resize() has been deprecated since 26.9 and will be removed in a future release, use Viewer.setSize() instead."
|
|
333
343
|
);
|
|
@@ -365,515 +375,76 @@ export class Viewer
|
|
|
365
375
|
this.emitEvent({ type: "update", data: force });
|
|
366
376
|
}
|
|
367
377
|
|
|
368
|
-
|
|
369
|
-
return new Promise<void>((resolve, reject) => {
|
|
370
|
-
setTimeout(() => {
|
|
371
|
-
try {
|
|
372
|
-
if (this._enableAutoUpdate) {
|
|
373
|
-
this.visViewer()?.update(maxScheduleUpdateTimeInMs);
|
|
374
|
-
this._activeDragger?.updatePreview?.();
|
|
375
|
-
}
|
|
376
|
-
this.emitEvent({ type: "update", data: false });
|
|
377
|
-
resolve();
|
|
378
|
-
} catch (e) {
|
|
379
|
-
console.error(e);
|
|
380
|
-
reject();
|
|
381
|
-
}
|
|
382
|
-
}, 0);
|
|
383
|
-
});
|
|
384
|
-
}
|
|
378
|
+
// Internal render routines
|
|
385
379
|
|
|
386
|
-
|
|
387
|
-
* Updates the viewer asynchronously without locking the user interface. Used to update the viewer
|
|
388
|
-
* after changes that require a long rendering time.
|
|
389
|
-
*
|
|
390
|
-
* Do nothing if the auto-update mode is disabled in the constructor. In this case, register an
|
|
391
|
-
* `update` event handler and update the `VisualizeJS` viewer and active dragger manually.
|
|
392
|
-
*
|
|
393
|
-
* Fires:
|
|
394
|
-
*
|
|
395
|
-
* - {@link UpdateEvent | update}
|
|
396
|
-
*
|
|
397
|
-
* @param maxScheduleUpdateTimeInMs - Maximum time for one update, default 30 ms.
|
|
398
|
-
* @param maxScheduleUpdateCount - Maximum count of scheduled updates.
|
|
399
|
-
*/
|
|
400
|
-
async updateAsync(maxScheduleUpdateTimeInMs = 50, maxScheduleUpdateCount = 50): Promise<void> {
|
|
380
|
+
render(time?: DOMHighResTimeStamp) {
|
|
401
381
|
if (!this.visualizeJs) return;
|
|
382
|
+
if (this._isRunAsyncUpdate) return;
|
|
402
383
|
|
|
403
|
-
this.
|
|
404
|
-
|
|
405
|
-
const device = this.visViewer().getActiveDevice();
|
|
406
|
-
for (let iterationCount = 0; !device.isValid() && iterationCount < maxScheduleUpdateCount; iterationCount++) {
|
|
407
|
-
await this.scheduleUpdateAsync(maxScheduleUpdateTimeInMs);
|
|
408
|
-
}
|
|
409
|
-
await this.scheduleUpdateAsync(maxScheduleUpdateTimeInMs);
|
|
410
|
-
} catch (e) {
|
|
411
|
-
console.error(e);
|
|
412
|
-
} finally {
|
|
413
|
-
this._isRunAsyncUpdate = false;
|
|
414
|
-
}
|
|
415
|
-
}
|
|
384
|
+
const renderNeeded = this.visViewer().isRunningAnimation() || this._renderNeeded;
|
|
385
|
+
if (!renderNeeded) return;
|
|
416
386
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
* instance.
|
|
420
|
-
*/
|
|
421
|
-
get visualizeJs(): any {
|
|
422
|
-
return this._visualizeJs;
|
|
423
|
-
}
|
|
387
|
+
if (!time) time = performance.now();
|
|
388
|
+
const deltaTime = (time - this._renderTime) / 1000;
|
|
424
389
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
* instance.
|
|
428
|
-
*/
|
|
429
|
-
visLib(): any {
|
|
430
|
-
return this._visualizeJs;
|
|
431
|
-
}
|
|
390
|
+
this._renderTime = time;
|
|
391
|
+
this._renderNeeded = !this.visViewer().getActiveDevice().isValid();
|
|
432
392
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
visViewer(): any {
|
|
438
|
-
return this._viewer;
|
|
393
|
+
this.visViewer().update();
|
|
394
|
+
this._activeDragger?.updatePreview?.();
|
|
395
|
+
|
|
396
|
+
this.emitEvent({ type: "render", time, deltaTime });
|
|
439
397
|
}
|
|
440
398
|
|
|
441
|
-
//
|
|
399
|
+
// Internal loading routines
|
|
442
400
|
|
|
443
|
-
|
|
401
|
+
async loadReferences(model: Model | File | Assembly): Promise<this> {
|
|
444
402
|
if (!this.visualizeJs) return this;
|
|
403
|
+
if (!this.client) return this;
|
|
404
|
+
if (!model.getReferences) return this;
|
|
445
405
|
|
|
446
|
-
const
|
|
447
|
-
const visViewer = this.visViewer();
|
|
448
|
-
|
|
449
|
-
const device = visViewer.getActiveDevice();
|
|
450
|
-
if (device.isNull()) return this;
|
|
451
|
-
|
|
452
|
-
const view = device.getActiveView();
|
|
453
|
-
|
|
454
|
-
view.enableDefaultLighting(true, visLib.DefaultLightingType.kTwoLights);
|
|
455
|
-
view.setDefaultLightingIntensity(1.25);
|
|
456
|
-
|
|
457
|
-
// Visualize.js 25.11 and earlier threw an exception if the style did not exist.
|
|
458
|
-
let visualStyleId;
|
|
459
|
-
try {
|
|
460
|
-
visualStyleId = visViewer.findVisualStyle("OpenCloud");
|
|
461
|
-
} catch {
|
|
462
|
-
visualStyleId = undefined;
|
|
463
|
-
}
|
|
406
|
+
const abortController = new AbortController();
|
|
464
407
|
|
|
465
|
-
|
|
466
|
-
|
|
408
|
+
this._abortControllerForReferences?.abort();
|
|
409
|
+
this._abortControllerForReferences = abortController;
|
|
467
410
|
|
|
468
|
-
|
|
469
|
-
|
|
411
|
+
let references: any[] = [];
|
|
412
|
+
await model
|
|
413
|
+
.getReferences(abortController.signal)
|
|
414
|
+
.then((data) => (references = data.references))
|
|
415
|
+
.catch((e) => console.error("Cannot load model references.", e));
|
|
470
416
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
visualStylePtr.setOptionInt32(visLib.VisualStyleOptions.kEdgeStyles, 0, visLib.VisualStyleOperations.kSet);
|
|
477
|
-
visualStylePtr.setOptionInt32(visLib.VisualStyleOptions.kEdgeModifiers, 8, visLib.VisualStyleOperations.kSet);
|
|
478
|
-
visualStylePtr.setOptionColor(
|
|
479
|
-
visLib.VisualStyleOptions.kEdgeColorValue,
|
|
480
|
-
colorDef,
|
|
481
|
-
visLib.VisualStyleOperations.kSet
|
|
482
|
-
);
|
|
483
|
-
visualStylePtr.delete();
|
|
417
|
+
for (const file of references) {
|
|
418
|
+
await this.client
|
|
419
|
+
.downloadFile(file.id, undefined, abortController.signal)
|
|
420
|
+
.then((arrayBuffer) => this.visualizeJs?.getViewer().addEmbeddedFile(file.name, new Uint8Array(arrayBuffer)))
|
|
421
|
+
.catch((e) => console.error(`Cannot load reference file ${file.name}.`, e));
|
|
484
422
|
}
|
|
485
423
|
|
|
486
|
-
view.visualStyle = visualStyleId;
|
|
487
|
-
|
|
488
|
-
view.delete();
|
|
489
|
-
device.delete();
|
|
490
|
-
|
|
491
424
|
return this;
|
|
492
425
|
}
|
|
493
426
|
|
|
494
|
-
|
|
495
|
-
|
|
427
|
+
applyModelTransformMatrix(model: Model | Assembly) {
|
|
428
|
+
this.executeCommand("applyModelTransform", model);
|
|
429
|
+
}
|
|
496
430
|
|
|
497
|
-
|
|
431
|
+
applySceneGraphSettings(options = this.options) {
|
|
432
|
+
if (!this.visualizeJs) return;
|
|
498
433
|
|
|
499
434
|
const visLib = this.visLib();
|
|
500
435
|
const visViewer = this.visViewer();
|
|
501
436
|
|
|
502
437
|
const device = visViewer.getActiveDevice();
|
|
503
|
-
if (
|
|
504
|
-
|
|
505
|
-
if (options.showWCS !== visViewer.getEnableWCS()) {
|
|
506
|
-
visViewer.setEnableWCS(options.showWCS);
|
|
507
|
-
}
|
|
508
|
-
if (options.cameraAnimation !== visViewer.getEnableAnimation()) {
|
|
509
|
-
visViewer.setEnableAnimation(options.cameraAnimation);
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
const antialiasing = options.antialiasing === true || options.antialiasing === "fxaa";
|
|
513
|
-
if (antialiasing !== visViewer.fxaaAntiAliasing3d) {
|
|
514
|
-
visViewer.fxaaAntiAliasing3d = antialiasing;
|
|
515
|
-
visViewer.fxaaQuality = 5;
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
if (options.shadows !== visViewer.shadows) {
|
|
519
|
-
visViewer.shadows = options.shadows;
|
|
520
|
-
|
|
521
|
-
const canvas = visLib.canvas;
|
|
522
|
-
device.invalidate([0, canvas.width, canvas.height, 0]);
|
|
438
|
+
if (isExist(options.sceneGraph)) {
|
|
439
|
+
device.setOptionBool(visLib.DeviceOptions.kDelaySceneGraphProc, !options.sceneGraph);
|
|
523
440
|
}
|
|
441
|
+
// if (options.enablePartialMode && visLib.HpTrc.Usd >= visViewer.memoryLimit) {
|
|
442
|
+
// device.setOptionBool(visLib.DeviceOptions.kDelaySceneGraphProc, true);
|
|
443
|
+
// }
|
|
444
|
+
device.delete();
|
|
524
445
|
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
if (options.ambientOcclusion !== device.getOptionBool(visLib.DeviceOptions.kSSAOEnable)) {
|
|
530
|
-
device.setOptionBool(visLib.DeviceOptions.kSSAOEnable, options.ambientOcclusion);
|
|
531
|
-
device.setOptionBool(visLib.DeviceOptions.kSSAODynamicRadius, true);
|
|
532
|
-
device.setOptionDouble(visLib.DeviceOptions.kSSAORadius, 1);
|
|
533
|
-
device.setOptionInt32(visLib.DeviceOptions.kSSAOLoops, 32);
|
|
534
|
-
device.setOptionDouble(visLib.DeviceOptions.kSSAOPower, 2);
|
|
535
|
-
device.setOptionInt32(visLib.DeviceOptions.kSSAOBlurRadius, 2);
|
|
536
|
-
|
|
537
|
-
const activeView = visViewer.activeView;
|
|
538
|
-
activeView.setSSAOEnabled(options.ambientOcclusion);
|
|
539
|
-
activeView.delete();
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
if (isExist(options.edgeModel)) {
|
|
543
|
-
const activeView = device.getActiveView();
|
|
544
|
-
|
|
545
|
-
const visualStyleId = visViewer.findVisualStyle("OpenCloud");
|
|
546
|
-
const visualStylePtr = visualStyleId.openObject();
|
|
547
|
-
|
|
548
|
-
visualStylePtr.setOptionInt32(
|
|
549
|
-
visLib.VisualStyleOptions.kEdgeModel,
|
|
550
|
-
options.edgeModel ? 2 : 0,
|
|
551
|
-
visLib.VisualStyleOperations.kSet
|
|
552
|
-
);
|
|
553
|
-
|
|
554
|
-
activeView.visualStyle = visualStyleId;
|
|
555
|
-
|
|
556
|
-
visualStylePtr.delete();
|
|
557
|
-
visualStyleId.delete();
|
|
558
|
-
activeView.delete();
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
device.delete();
|
|
562
|
-
|
|
563
|
-
this.syncHighlightingOptions(options);
|
|
564
|
-
this.update();
|
|
565
|
-
|
|
566
|
-
return this;
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
syncHighlightingOptions(options: IOptions = this.options): this {
|
|
570
|
-
if (!this.visualizeJs) return this;
|
|
571
|
-
|
|
572
|
-
const params = options.enableCustomHighlight ? options : Options.defaults();
|
|
573
|
-
|
|
574
|
-
const visLib = this.visLib();
|
|
575
|
-
const visViewer = this.visViewer();
|
|
576
|
-
const { Entry, OdTvRGBColorDef } = visLib;
|
|
577
|
-
|
|
578
|
-
const highlightStyleId = visViewer.findHighlightStyle("Web_Default");
|
|
579
|
-
const highlightStylePtr = highlightStyleId.openObject();
|
|
580
|
-
|
|
581
|
-
if (isExist(params.facesColor)) {
|
|
582
|
-
const color = new OdTvRGBColorDef(params.facesColor.r, params.facesColor.g, params.facesColor.b);
|
|
583
|
-
highlightStylePtr.setFacesColor(Entry.k3D.value | Entry.k3DTop.value, color);
|
|
584
|
-
color.delete();
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
if (isExist(params.facesOverlap)) {
|
|
588
|
-
highlightStylePtr.setFacesVisibility(Entry.k3DTop.value, params.facesOverlap);
|
|
589
|
-
}
|
|
590
|
-
if (isExist(params.facesTransparancy)) {
|
|
591
|
-
highlightStylePtr.setFacesTransparency(Entry.k3D.value | Entry.k3DTop.value, params.facesTransparancy);
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
if (isExist(params.edgesColor)) {
|
|
595
|
-
const color = new OdTvRGBColorDef(params.edgesColor.r, params.edgesColor.g, params.edgesColor.b);
|
|
596
|
-
highlightStylePtr.setEdgesColor(
|
|
597
|
-
Entry.k3DTop.value | Entry.k3D.value | Entry.k2D.value | Entry.k2DTop.value,
|
|
598
|
-
color
|
|
599
|
-
);
|
|
600
|
-
color.delete();
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
if (isExist(params.edgesVisibility)) {
|
|
604
|
-
highlightStylePtr.setEdgesVisibility(
|
|
605
|
-
Entry.k2D.value | Entry.k2DTop.value | Entry.k3DTop.value | Entry.k3D.value,
|
|
606
|
-
params.edgesVisibility
|
|
607
|
-
);
|
|
608
|
-
}
|
|
609
|
-
if (isExist(params.edgesOverlap)) {
|
|
610
|
-
const visibility = !isExist(params.edgesVisibility) ? true : params.edgesVisibility;
|
|
611
|
-
highlightStylePtr.setEdgesVisibility(Entry.k2DTop.value | Entry.k3DTop.value, params.edgesOverlap && visibility);
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
const device = visViewer.getActiveDevice();
|
|
615
|
-
if (!device.isNull()) {
|
|
616
|
-
const canvas = visLib.canvas;
|
|
617
|
-
|
|
618
|
-
device.invalidate([0, canvas.width, canvas.height, 0]);
|
|
619
|
-
device.delete();
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
return this;
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
get draggers(): string[] {
|
|
626
|
-
return [...draggers.getDraggers().keys()];
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
get components(): string[] {
|
|
630
|
-
return [...components.getComponents().keys()];
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
/**
|
|
634
|
-
* Deprecated since `25.12`. Use {@link draggers.registerDragger} instead.
|
|
635
|
-
*/
|
|
636
|
-
public registerDragger(name: string, dragger: typeof Dragger): void {
|
|
637
|
-
console.warn(
|
|
638
|
-
"Viewer.registerDragger() has been deprecated since 25.12 and will be removed in a future release, use draggers('visualizejs').registerDragger() instead."
|
|
639
|
-
);
|
|
640
|
-
draggers.registerDragger(name, (viewer: IViewer) => new dragger(viewer));
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
activeDragger(): IDragger | null {
|
|
644
|
-
return this._activeDragger;
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
setActiveDragger(name = ""): IDragger | null {
|
|
648
|
-
if (!this._activeDragger || this._activeDragger.name !== name) {
|
|
649
|
-
const oldDragger = this._activeDragger;
|
|
650
|
-
let newDragger = null;
|
|
651
|
-
|
|
652
|
-
if (this._activeDragger) {
|
|
653
|
-
this._activeDragger.dispose();
|
|
654
|
-
this._activeDragger = null;
|
|
655
|
-
}
|
|
656
|
-
if (this.visualizeJs) {
|
|
657
|
-
newDragger = draggers.createDragger(name, this);
|
|
658
|
-
if (newDragger) {
|
|
659
|
-
this._activeDragger = newDragger;
|
|
660
|
-
this._activeDragger.initialize?.();
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
const canvas = this.canvas;
|
|
664
|
-
if (canvas) {
|
|
665
|
-
if (oldDragger) canvas.classList.remove(`oda-cursor-${oldDragger.name.toLowerCase()}`);
|
|
666
|
-
if (newDragger) canvas.classList.add(`oda-cursor-${newDragger.name.toLowerCase()}`);
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
this.emitEvent({ type: "changeactivedragger", data: name });
|
|
670
|
-
this.update();
|
|
671
|
-
}
|
|
672
|
-
return this._activeDragger;
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
resetActiveDragger(): void {
|
|
676
|
-
const dragger = this._activeDragger;
|
|
677
|
-
if (dragger) {
|
|
678
|
-
this.setActiveDragger();
|
|
679
|
-
this.setActiveDragger(dragger.name);
|
|
680
|
-
}
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
getComponent(name: string): IComponent {
|
|
684
|
-
return this._components.find((component) => component.name === name);
|
|
685
|
-
}
|
|
686
|
-
|
|
687
|
-
clearSlices(): void {
|
|
688
|
-
if (!this.visualizeJs) return;
|
|
689
|
-
|
|
690
|
-
const visViewer = this.visViewer();
|
|
691
|
-
const activeView = visViewer.activeView;
|
|
692
|
-
activeView.removeCuttingPlanes();
|
|
693
|
-
activeView.delete();
|
|
694
|
-
|
|
695
|
-
this.update();
|
|
696
|
-
}
|
|
697
|
-
|
|
698
|
-
clearOverlay(): void {
|
|
699
|
-
if (!this.visualizeJs) return;
|
|
700
|
-
|
|
701
|
-
this._markup.clearOverlay();
|
|
702
|
-
this.update();
|
|
703
|
-
}
|
|
704
|
-
|
|
705
|
-
syncOverlay(): void {
|
|
706
|
-
if (!this.visualizeJs) return;
|
|
707
|
-
|
|
708
|
-
const visViewer = this.visViewer();
|
|
709
|
-
const activeView = visViewer.activeView;
|
|
710
|
-
|
|
711
|
-
let overlayView = visViewer.getViewByName(OVERLAY_VIEW_NAME);
|
|
712
|
-
if (!overlayView) {
|
|
713
|
-
const markupModel = visViewer.getMarkupModel();
|
|
714
|
-
const pDevice = visViewer.getActiveDevice();
|
|
715
|
-
|
|
716
|
-
overlayView = pDevice.createView(OVERLAY_VIEW_NAME, false);
|
|
717
|
-
overlayView.addModel(markupModel);
|
|
718
|
-
|
|
719
|
-
activeView.addSibling(overlayView);
|
|
720
|
-
pDevice.addView(overlayView);
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
overlayView.viewPosition = activeView.viewPosition;
|
|
724
|
-
overlayView.viewTarget = activeView.viewTarget;
|
|
725
|
-
overlayView.upVector = activeView.upVector;
|
|
726
|
-
overlayView.viewFieldWidth = activeView.viewFieldWidth;
|
|
727
|
-
overlayView.viewFieldHeight = activeView.viewFieldHeight;
|
|
728
|
-
|
|
729
|
-
const viewPort = overlayView.getViewport();
|
|
730
|
-
overlayView.setViewport(viewPort.lowerLeft, viewPort.upperRight);
|
|
731
|
-
overlayView.vportRect = activeView.vportRect;
|
|
732
|
-
|
|
733
|
-
this._markup.syncOverlay();
|
|
734
|
-
this.update();
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
is3D(): boolean {
|
|
738
|
-
if (!this.visualizeJs) return false;
|
|
739
|
-
|
|
740
|
-
const visViewer = this.visViewer();
|
|
741
|
-
const ext = visViewer.getActiveExtents();
|
|
742
|
-
const min = ext.min();
|
|
743
|
-
const max = ext.max();
|
|
744
|
-
const extHeight = max[2] - min[2];
|
|
745
|
-
return extHeight !== 0;
|
|
746
|
-
|
|
747
|
-
//return visViewer.activeView.upVector[1] >= 0.95;
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
screenToWorld(position: { x: number; y: number }): { x: number; y: number; z: number } {
|
|
751
|
-
if (!this.visualizeJs) return { x: position.x, y: position.y, z: 0 };
|
|
752
|
-
|
|
753
|
-
const activeView = this.visViewer().activeView;
|
|
754
|
-
const worldPoint = activeView.transformScreenToWorld(
|
|
755
|
-
position.x * window.devicePixelRatio,
|
|
756
|
-
position.y * window.devicePixelRatio
|
|
757
|
-
);
|
|
758
|
-
|
|
759
|
-
const result = { x: worldPoint[0], y: worldPoint[1], z: worldPoint[2] };
|
|
760
|
-
|
|
761
|
-
activeView.delete();
|
|
762
|
-
|
|
763
|
-
return result;
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
worldToScreen(position: { x: number; y: number; z: number }): { x: number; y: number } {
|
|
767
|
-
if (!this.visualizeJs) return { x: position.x, y: position.y };
|
|
768
|
-
|
|
769
|
-
const activeView = this.visViewer().activeView;
|
|
770
|
-
const devicePoint = activeView.transformWorldToScreen(position.x, position.y, position.z);
|
|
771
|
-
|
|
772
|
-
const result = { x: devicePoint[0] / window.devicePixelRatio, y: devicePoint[1] / window.devicePixelRatio };
|
|
773
|
-
|
|
774
|
-
activeView.delete();
|
|
775
|
-
|
|
776
|
-
return result;
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
getScale(): { x: number; y: number; z: number } {
|
|
780
|
-
const result = { x: 1.0, y: 1.0, z: 1.0 };
|
|
781
|
-
|
|
782
|
-
const projMatrix = this.visViewer().activeView.projectionMatrix;
|
|
783
|
-
const tolerance = 1.0e-6;
|
|
784
|
-
|
|
785
|
-
const x = projMatrix.get(0, 0);
|
|
786
|
-
if (x > tolerance || x < -tolerance) result.x = 1 / x;
|
|
787
|
-
|
|
788
|
-
const y = projMatrix.get(1, 1);
|
|
789
|
-
if (y > tolerance || y < -tolerance) result.y = 1 / y;
|
|
790
|
-
|
|
791
|
-
const z = projMatrix.get(2, 2);
|
|
792
|
-
if (z > tolerance || z < -tolerance) result.z = 1 / z;
|
|
793
|
-
|
|
794
|
-
return result;
|
|
795
|
-
}
|
|
796
|
-
|
|
797
|
-
getSelected(): string[] {
|
|
798
|
-
return this.executeCommand("getSelected");
|
|
799
|
-
}
|
|
800
|
-
|
|
801
|
-
setSelected(handles?: string[]): void {
|
|
802
|
-
this.executeCommand("setSelected", handles);
|
|
803
|
-
}
|
|
804
|
-
|
|
805
|
-
clearSelected(): void {
|
|
806
|
-
this.executeCommand("clearSelected");
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
hideSelected(): void {
|
|
810
|
-
this.executeCommand("hideSelected");
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
isolateSelected(): void {
|
|
814
|
-
this.executeCommand("isolateSelected");
|
|
815
|
-
}
|
|
816
|
-
|
|
817
|
-
showAll(): void {
|
|
818
|
-
this.executeCommand("showAll");
|
|
819
|
-
}
|
|
820
|
-
|
|
821
|
-
explode(index = 0): void {
|
|
822
|
-
this.executeCommand("explode", index);
|
|
823
|
-
}
|
|
824
|
-
|
|
825
|
-
collect(): void {
|
|
826
|
-
this.executeCommand("collect");
|
|
827
|
-
}
|
|
828
|
-
|
|
829
|
-
// Internal loading routines
|
|
830
|
-
|
|
831
|
-
async loadReferences(model: Model | File | Assembly): Promise<this> {
|
|
832
|
-
if (!this.visualizeJs) return this;
|
|
833
|
-
if (!this.client) return this;
|
|
834
|
-
if (!model.getReferences) return this;
|
|
835
|
-
|
|
836
|
-
const abortController = new AbortController();
|
|
837
|
-
this._abortControllerForReferences?.abort();
|
|
838
|
-
this._abortControllerForReferences = abortController;
|
|
839
|
-
|
|
840
|
-
let references: any[] = [];
|
|
841
|
-
await model
|
|
842
|
-
.getReferences(abortController.signal)
|
|
843
|
-
.then((data) => (references = data.references))
|
|
844
|
-
.catch((e) => console.error("Cannot load model references.", e));
|
|
845
|
-
|
|
846
|
-
for (const file of references) {
|
|
847
|
-
await this.client
|
|
848
|
-
.downloadFile(file.id, undefined, abortController.signal)
|
|
849
|
-
.then((arrayBuffer) => this.visualizeJs?.getViewer().addEmbeddedFile(file.name, new Uint8Array(arrayBuffer)))
|
|
850
|
-
.catch((e) => console.error(`Cannot load reference file ${file.name}.`, e));
|
|
851
|
-
}
|
|
852
|
-
|
|
853
|
-
return this;
|
|
854
|
-
}
|
|
855
|
-
|
|
856
|
-
applyModelTransformMatrix(model: Model | Assembly) {
|
|
857
|
-
this.executeCommand("applyModelTransform", model);
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
applySceneGraphSettings(options = this.options) {
|
|
861
|
-
if (!this.visualizeJs) return;
|
|
862
|
-
|
|
863
|
-
const visLib = this.visLib();
|
|
864
|
-
const visViewer = this.visViewer();
|
|
865
|
-
|
|
866
|
-
const device = visViewer.getActiveDevice();
|
|
867
|
-
if (isExist(options.sceneGraph)) {
|
|
868
|
-
device.setOptionBool(visLib.DeviceOptions.kDelaySceneGraphProc, !options.sceneGraph);
|
|
869
|
-
}
|
|
870
|
-
// if (options.enablePartialMode && visLib.HpTrc.Usd >= visViewer.memoryLimit) {
|
|
871
|
-
// device.setOptionBool(visLib.DeviceOptions.kDelaySceneGraphProc, true);
|
|
872
|
-
// }
|
|
873
|
-
device.delete();
|
|
874
|
-
|
|
875
|
-
this.update();
|
|
876
|
-
}
|
|
446
|
+
this.update();
|
|
447
|
+
}
|
|
877
448
|
|
|
878
449
|
/**
|
|
879
450
|
* Loads a file into the viewer.
|
|
@@ -890,8 +461,8 @@ export class Viewer
|
|
|
890
461
|
* thrown.
|
|
891
462
|
*
|
|
892
463
|
* For URLs, the file extension is used to determine the file format. For a `ArrayBuffer` and `Data
|
|
893
|
-
* URL`, a file format must be specified using `params.format` parameter
|
|
894
|
-
*
|
|
464
|
+
* URL`, a file format must be specified using `params.format` parameter. If no appropriate loader is
|
|
465
|
+
* found for the specified format, an exception will be thrown.
|
|
895
466
|
*
|
|
896
467
|
* If there was an active dragger before opening the file, it will be deactivated. After opening the
|
|
897
468
|
* file, you must manually activate the required dragger.
|
|
@@ -908,6 +479,8 @@ export class Viewer
|
|
|
908
479
|
*
|
|
909
480
|
* Fires:
|
|
910
481
|
*
|
|
482
|
+
* - {@link CancelEvent | cancel}
|
|
483
|
+
* - {@link ClearEvent | clear}
|
|
911
484
|
* - {@link OpenEvent | open}
|
|
912
485
|
* - {@link GeometryStartEvent | geometrystart}
|
|
913
486
|
* - {@link GeometryProgressEvent | geometryprogress}
|
|
@@ -916,19 +489,20 @@ export class Viewer
|
|
|
916
489
|
* - {@link GeometryEndEvent | geometryend}
|
|
917
490
|
* - {@link GeometryErrorEvent | geometryerror}
|
|
918
491
|
*
|
|
919
|
-
* @param file - File to load. Can be
|
|
492
|
+
* @param file - File to load. Can be:
|
|
920
493
|
*
|
|
921
494
|
* - `File`, `Assembly` or `Model` instance from the Open Cloud Server
|
|
922
|
-
* -
|
|
495
|
+
* - `URL` string
|
|
923
496
|
* - {@link https://developer.mozilla.org/docs/Web/HTTP/Basics_of_HTTP/Data_URIs | Data URL} string
|
|
924
|
-
* - {@link https://developer.mozilla.org/docs/Web/API/File | Web API
|
|
497
|
+
* - {@link https://developer.mozilla.org/docs/Web/API/File | Web API dFile} object
|
|
925
498
|
* - {@link https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer | ArrayBuffer}
|
|
926
499
|
* object
|
|
927
500
|
*
|
|
928
501
|
* @param params - Loading parameters.
|
|
929
|
-
* @param params.format - File format
|
|
930
|
-
* URL`.
|
|
502
|
+
* @param params.format - File format. Can be one of `vsf` or `vsfx`. Required when loading a file as
|
|
503
|
+
* `ArrayBuffer` or `Data URL`.
|
|
931
504
|
* @param params.mode - Reserved for future use.
|
|
505
|
+
* @param params.modelId - Reserved for future use.
|
|
932
506
|
* @param params.requestHeader - The
|
|
933
507
|
* {@link https://developer.mozilla.org/docs/Glossary/Request_header | request header} used in HTTP
|
|
934
508
|
* request.
|
|
@@ -942,227 +516,529 @@ export class Viewer
|
|
|
942
516
|
params: {
|
|
943
517
|
format?: string;
|
|
944
518
|
mode?: string;
|
|
519
|
+
modelId?: string;
|
|
945
520
|
requestHeader?: HeadersInit;
|
|
946
521
|
withCredentials?: boolean;
|
|
947
522
|
} = {}
|
|
948
523
|
): Promise<this> {
|
|
949
524
|
if (!this.visualizeJs) return this;
|
|
950
525
|
|
|
951
|
-
this.cancel();
|
|
952
|
-
this.clear();
|
|
526
|
+
this.cancel();
|
|
527
|
+
this.clear();
|
|
528
|
+
|
|
529
|
+
this.emitEvent({ type: "open", mode: "file", file });
|
|
530
|
+
|
|
531
|
+
let model: any = file;
|
|
532
|
+
if (model && typeof model.getModels === "function") {
|
|
533
|
+
const models = await model.getModels();
|
|
534
|
+
model = models.find((model: Model) => model.default) || models[0] || file;
|
|
535
|
+
}
|
|
536
|
+
if (model && typeof model.database === "string") {
|
|
537
|
+
file = model.file;
|
|
538
|
+
}
|
|
539
|
+
if (!model) throw new Error(`Format not supported`);
|
|
540
|
+
|
|
541
|
+
let format = params.format;
|
|
542
|
+
if (!format && typeof file["type"] === "string") format = file["type"].split(".").pop();
|
|
543
|
+
if (!format && typeof file === "string") format = file.split(".").pop();
|
|
544
|
+
if (!format && file instanceof globalThis.File) format = file.name.split(".").pop();
|
|
545
|
+
|
|
546
|
+
const loader = loaders.createLoader(this, model, format);
|
|
547
|
+
if (!loader) throw new Error(`Format not supported`);
|
|
548
|
+
this.loaders.push(loader);
|
|
549
|
+
|
|
550
|
+
this.emitEvent({ type: "geometrystart", file, model });
|
|
551
|
+
try {
|
|
552
|
+
await this.loadReferences(model);
|
|
553
|
+
await loader.load(model, format, params);
|
|
554
|
+
} catch (error: any) {
|
|
555
|
+
this.emitEvent({ type: "geometryerror", data: error, file, model });
|
|
556
|
+
throw error;
|
|
557
|
+
}
|
|
558
|
+
this.emitEvent({ type: "geometryend", file, model });
|
|
559
|
+
|
|
560
|
+
if (this.visualizeJs) {
|
|
561
|
+
this.applyModelTransformMatrix(model);
|
|
562
|
+
this.applySceneGraphSettings();
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
return this;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
/**
|
|
569
|
+
* Deprecated since `26.4`. Use {@link open | open()} instead.
|
|
570
|
+
*
|
|
571
|
+
* @deprecated
|
|
572
|
+
*/
|
|
573
|
+
openVsfFile(buffer: Uint8Array | ArrayBuffer): this {
|
|
574
|
+
console.warn(
|
|
575
|
+
"Viewer.openVsfFile() has been deprecated since 26.4 and will be removed in a future release, use Viewer.open() instead."
|
|
576
|
+
);
|
|
577
|
+
|
|
578
|
+
if (!this.visualizeJs) return this;
|
|
579
|
+
|
|
580
|
+
this.cancel();
|
|
581
|
+
this.clear();
|
|
582
|
+
|
|
583
|
+
this.emitEvent({ type: "open", mode: "file", file: "", buffer });
|
|
584
|
+
|
|
585
|
+
const visViewer = this.visViewer();
|
|
586
|
+
|
|
587
|
+
this.emitEvent({ type: "geometrystart", file: "", buffer });
|
|
588
|
+
try {
|
|
589
|
+
const data = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);
|
|
590
|
+
visViewer.parseFile(data);
|
|
591
|
+
|
|
592
|
+
this.syncOptions();
|
|
593
|
+
this.syncOverlay();
|
|
594
|
+
this.update(true);
|
|
595
|
+
|
|
596
|
+
this.emitEvent({ type: "geometryprogress", data: 1, file: "", buffer });
|
|
597
|
+
this.emitEvent({ type: "databasechunk", data, file: "", buffer });
|
|
598
|
+
} catch (error: any) {
|
|
599
|
+
this.emitEvent({ type: "geometryerror", data: error, file: "", buffer });
|
|
600
|
+
throw error;
|
|
601
|
+
}
|
|
602
|
+
this.emitEvent({ type: "geometryend", file: "", buffer });
|
|
603
|
+
|
|
604
|
+
return this;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
/**
|
|
608
|
+
* Deprecated since `26.4`. Use {@link open | open()} instead.
|
|
609
|
+
*
|
|
610
|
+
* @deprecated
|
|
611
|
+
*/
|
|
612
|
+
openVsfxFile(buffer: Uint8Array | ArrayBuffer): this {
|
|
613
|
+
console.warn(
|
|
614
|
+
"Viewer.openVsfxFile() has been deprecated since 26.4 and will be removed in a future release, use Viewer.open() instead."
|
|
615
|
+
);
|
|
616
|
+
|
|
617
|
+
if (!this.visualizeJs) return this;
|
|
618
|
+
|
|
619
|
+
this.cancel();
|
|
620
|
+
this.clear();
|
|
621
|
+
|
|
622
|
+
this.emitEvent({ type: "open", mode: "file", file: "", buffer });
|
|
623
|
+
|
|
624
|
+
const visViewer = this.visViewer();
|
|
625
|
+
|
|
626
|
+
this.emitEvent({ type: "geometrystart", file: "", buffer });
|
|
627
|
+
try {
|
|
628
|
+
const data = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);
|
|
629
|
+
visViewer.parseVsfx(data);
|
|
630
|
+
|
|
631
|
+
this.syncOptions();
|
|
632
|
+
this.syncOverlay();
|
|
633
|
+
this.update(true);
|
|
634
|
+
|
|
635
|
+
this.emitEvent({ type: "geometryprogress", data: 1, file: "", buffer });
|
|
636
|
+
this.emitEvent({ type: "databasechunk", data, file: "", buffer });
|
|
637
|
+
} catch (error: any) {
|
|
638
|
+
this.emitEvent({ type: "geometryerror", data: error, file: "", buffer });
|
|
639
|
+
throw error;
|
|
640
|
+
}
|
|
641
|
+
this.emitEvent({ type: "geometryend", file: "", buffer });
|
|
642
|
+
|
|
643
|
+
return this;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
cancel(): this {
|
|
647
|
+
this._abortControllerForReferences?.abort();
|
|
648
|
+
this._abortControllerForReferences = undefined;
|
|
649
|
+
|
|
650
|
+
this.loaders.forEach((loader) => loader.cancel());
|
|
651
|
+
|
|
652
|
+
this.emitEvent({ type: "cancel" });
|
|
653
|
+
return this;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
clear(): this {
|
|
657
|
+
if (!this.visualizeJs) return this;
|
|
658
|
+
|
|
659
|
+
const visViewer = this.visViewer();
|
|
660
|
+
|
|
661
|
+
this.setActiveDragger();
|
|
662
|
+
this.clearSlices();
|
|
663
|
+
this.clearOverlay();
|
|
664
|
+
this.clearSelected();
|
|
665
|
+
|
|
666
|
+
this.loaders.forEach((loader) => loader.dispose());
|
|
667
|
+
this.loaders = [];
|
|
668
|
+
|
|
669
|
+
this.models.forEach((model) => model.dispose());
|
|
670
|
+
this.models = [];
|
|
671
|
+
|
|
672
|
+
visViewer.clear();
|
|
673
|
+
visViewer.createLocalDatabase();
|
|
674
|
+
|
|
675
|
+
this.syncOptions();
|
|
676
|
+
this.syncOverlay();
|
|
677
|
+
this.update(true);
|
|
678
|
+
|
|
679
|
+
this.emitEvent({ type: "clear" });
|
|
680
|
+
|
|
681
|
+
return this;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
is3D(): boolean {
|
|
685
|
+
if (!this.visualizeJs) return false;
|
|
686
|
+
|
|
687
|
+
const visViewer = this.visViewer();
|
|
688
|
+
const ext = visViewer.getActiveExtents();
|
|
689
|
+
const min = ext.min();
|
|
690
|
+
const max = ext.max();
|
|
691
|
+
const extHeight = max[2] - min[2];
|
|
692
|
+
return extHeight !== 0;
|
|
693
|
+
|
|
694
|
+
//return visViewer.activeView.upVector[1] >= 0.95;
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
syncOptions(options: IOptions = this.options): this {
|
|
698
|
+
if (!this.visualizeJs) return this;
|
|
699
|
+
|
|
700
|
+
const visLib = this.visLib();
|
|
701
|
+
const visViewer = this.visViewer();
|
|
702
|
+
|
|
703
|
+
const device = visViewer.getActiveDevice();
|
|
704
|
+
if (device.isNull()) return this;
|
|
705
|
+
|
|
706
|
+
// sync Open Cloud visual style
|
|
707
|
+
|
|
708
|
+
const view = device.getActiveView();
|
|
709
|
+
|
|
710
|
+
view.enableDefaultLighting(true, visLib.DefaultLightingType.kTwoLights);
|
|
711
|
+
view.setDefaultLightingIntensity(1.25);
|
|
712
|
+
|
|
713
|
+
let visualStyleId: any;
|
|
714
|
+
try {
|
|
715
|
+
visualStyleId = visViewer.findVisualStyle("OpenCloud");
|
|
716
|
+
} catch {
|
|
717
|
+
// Visualize.js 25.11 and earlier threw an exception if the style did not exist.
|
|
718
|
+
visualStyleId = undefined;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
if (!visualStyleId || visualStyleId.isNull()) {
|
|
722
|
+
visualStyleId = visViewer.createVisualStyle("OpenCloud");
|
|
723
|
+
|
|
724
|
+
const colorDef = new visLib.OdTvColorDef(66, 66, 66);
|
|
725
|
+
const shadedVsId = visViewer.findVisualStyle("Realistic");
|
|
726
|
+
|
|
727
|
+
const visualStylePtr = visualStyleId.openObject();
|
|
728
|
+
visualStylePtr.copyFrom(shadedVsId);
|
|
729
|
+
visualStylePtr.setOptionInt32(visLib.VisualStyleOptions.kFaceModifiers, 0, visLib.VisualStyleOperations.kSet);
|
|
730
|
+
visualStylePtr.setOptionInt32(visLib.VisualStyleOptions.kEdgeModel, 2, visLib.VisualStyleOperations.kSet);
|
|
731
|
+
visualStylePtr.setOptionDouble(visLib.VisualStyleOptions.kEdgeCreaseAngle, 60, visLib.VisualStyleOperations.kSet);
|
|
732
|
+
visualStylePtr.setOptionInt32(visLib.VisualStyleOptions.kEdgeStyles, 0, visLib.VisualStyleOperations.kSet);
|
|
733
|
+
visualStylePtr.setOptionInt32(visLib.VisualStyleOptions.kEdgeModifiers, 8, visLib.VisualStyleOperations.kSet);
|
|
734
|
+
visualStylePtr.setOptionColor(
|
|
735
|
+
visLib.VisualStyleOptions.kEdgeColorValue,
|
|
736
|
+
colorDef,
|
|
737
|
+
visLib.VisualStyleOperations.kSet
|
|
738
|
+
);
|
|
739
|
+
visualStylePtr.delete();
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
view.visualStyle = visualStyleId;
|
|
743
|
+
|
|
744
|
+
// sync Visualize options
|
|
745
|
+
|
|
746
|
+
if (options.showWCS !== visViewer.getEnableWCS()) {
|
|
747
|
+
visViewer.setEnableWCS(options.showWCS);
|
|
748
|
+
}
|
|
749
|
+
if (options.cameraAnimation !== visViewer.getEnableAnimation()) {
|
|
750
|
+
visViewer.setEnableAnimation(options.cameraAnimation);
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
const antialiasing = options.antialiasing === true || options.antialiasing === "fxaa";
|
|
754
|
+
if (antialiasing !== visViewer.fxaaAntiAliasing3d) {
|
|
755
|
+
visViewer.fxaaAntiAliasing3d = antialiasing;
|
|
756
|
+
visViewer.fxaaQuality = 5;
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
if (options.shadows !== visViewer.shadows) {
|
|
760
|
+
visViewer.shadows = options.shadows;
|
|
761
|
+
|
|
762
|
+
// const canvas = visLib.canvas;
|
|
763
|
+
// device.invalidate([0, canvas.width, canvas.height, 0]);
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
if (options.groundShadow !== visViewer.groundShadow) {
|
|
767
|
+
visViewer.groundShadow = options.groundShadow;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
if (options.ambientOcclusion !== device.getOptionBool(visLib.DeviceOptions.kSSAOEnable)) {
|
|
771
|
+
device.setOptionBool(visLib.DeviceOptions.kSSAOEnable, options.ambientOcclusion);
|
|
772
|
+
device.setOptionBool(visLib.DeviceOptions.kSSAODynamicRadius, true);
|
|
773
|
+
device.setOptionDouble(visLib.DeviceOptions.kSSAORadius, 1);
|
|
774
|
+
device.setOptionInt32(visLib.DeviceOptions.kSSAOLoops, 32);
|
|
775
|
+
device.setOptionDouble(visLib.DeviceOptions.kSSAOPower, 2);
|
|
776
|
+
device.setOptionInt32(visLib.DeviceOptions.kSSAOBlurRadius, 2);
|
|
777
|
+
|
|
778
|
+
const activeView = visViewer.activeView;
|
|
779
|
+
activeView.setSSAOEnabled(options.ambientOcclusion);
|
|
780
|
+
activeView.delete();
|
|
781
|
+
}
|
|
953
782
|
|
|
954
|
-
|
|
783
|
+
if (isExist(options.edgeModel)) {
|
|
784
|
+
const activeView = device.getActiveView();
|
|
955
785
|
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
786
|
+
const visualStyleId = visViewer.findVisualStyle("OpenCloud");
|
|
787
|
+
const visualStylePtr = visualStyleId.openObject();
|
|
788
|
+
|
|
789
|
+
visualStylePtr.setOptionInt32(
|
|
790
|
+
visLib.VisualStyleOptions.kEdgeModel,
|
|
791
|
+
options.edgeModel ? 2 : 0,
|
|
792
|
+
visLib.VisualStyleOperations.kSet
|
|
793
|
+
);
|
|
794
|
+
|
|
795
|
+
activeView.visualStyle = visualStyleId;
|
|
796
|
+
|
|
797
|
+
visualStylePtr.delete();
|
|
798
|
+
visualStyleId.delete();
|
|
799
|
+
activeView.delete();
|
|
960
800
|
}
|
|
961
|
-
if (!model) throw new Error(`Format not supported`);
|
|
962
801
|
|
|
963
|
-
|
|
964
|
-
if (!format && typeof model.type === "string") format = model.type.split(".").pop();
|
|
965
|
-
if (!format && typeof file === "string") format = file.split(".").pop();
|
|
966
|
-
if (!format && file instanceof globalThis.File) format = file.name.split(".").pop();
|
|
802
|
+
// sync highlighting options
|
|
967
803
|
|
|
968
|
-
const
|
|
969
|
-
if (!loader) throw new Error(`Format not supported`);
|
|
970
|
-
this.loaders.push(loader);
|
|
804
|
+
const params = options.enableCustomHighlight ? options : Options.defaults();
|
|
971
805
|
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
806
|
+
const { Entry, OdTvRGBColorDef } = visLib;
|
|
807
|
+
|
|
808
|
+
const highlightStyleId = visViewer.findHighlightStyle("Web_Default");
|
|
809
|
+
const highlightStylePtr = highlightStyleId.openObject();
|
|
810
|
+
|
|
811
|
+
if (isExist(params.facesColor)) {
|
|
812
|
+
const color = new OdTvRGBColorDef(params.facesColor.r, params.facesColor.g, params.facesColor.b);
|
|
813
|
+
highlightStylePtr.setFacesColor(Entry.k3D.value | Entry.k3DTop.value, color);
|
|
814
|
+
color.delete();
|
|
979
815
|
}
|
|
980
|
-
this.emitEvent({ type: "geometryend", file, model });
|
|
981
816
|
|
|
982
|
-
if (
|
|
983
|
-
|
|
984
|
-
|
|
817
|
+
if (isExist(params.facesOverlap)) {
|
|
818
|
+
highlightStylePtr.setFacesVisibility(Entry.k3DTop.value, params.facesOverlap);
|
|
819
|
+
}
|
|
820
|
+
if (isExist(params.facesTransparancy)) {
|
|
821
|
+
highlightStylePtr.setFacesTransparency(Entry.k3D.value | Entry.k3DTop.value, params.facesTransparancy);
|
|
985
822
|
}
|
|
986
823
|
|
|
987
|
-
|
|
988
|
-
|
|
824
|
+
if (isExist(params.edgesColor)) {
|
|
825
|
+
const color = new OdTvRGBColorDef(params.edgesColor.r, params.edgesColor.g, params.edgesColor.b);
|
|
826
|
+
highlightStylePtr.setEdgesColor(
|
|
827
|
+
Entry.k3DTop.value | Entry.k3D.value | Entry.k2D.value | Entry.k2DTop.value,
|
|
828
|
+
color
|
|
829
|
+
);
|
|
830
|
+
color.delete();
|
|
831
|
+
}
|
|
989
832
|
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
833
|
+
if (isExist(params.edgesVisibility)) {
|
|
834
|
+
highlightStylePtr.setEdgesVisibility(
|
|
835
|
+
Entry.k2D.value | Entry.k2DTop.value | Entry.k3DTop.value | Entry.k3D.value,
|
|
836
|
+
params.edgesVisibility
|
|
837
|
+
);
|
|
838
|
+
}
|
|
839
|
+
if (isExist(params.edgesOverlap)) {
|
|
840
|
+
const visibility = !isExist(params.edgesVisibility) ? true : params.edgesVisibility;
|
|
841
|
+
highlightStylePtr.setEdgesVisibility(Entry.k2DTop.value | Entry.k3DTop.value, params.edgesOverlap && visibility);
|
|
842
|
+
}
|
|
999
843
|
|
|
1000
|
-
|
|
844
|
+
// const canvas = visLib.canvas;
|
|
845
|
+
// device.invalidate([0, canvas.width, canvas.height, 0]);
|
|
1001
846
|
|
|
1002
|
-
|
|
1003
|
-
|
|
847
|
+
view.delete();
|
|
848
|
+
device.delete();
|
|
849
|
+
|
|
850
|
+
this.update();
|
|
851
|
+
|
|
852
|
+
return this;
|
|
853
|
+
}
|
|
1004
854
|
|
|
1005
|
-
|
|
855
|
+
syncOverlay(): void {
|
|
856
|
+
if (!this.visualizeJs) return;
|
|
1006
857
|
|
|
1007
858
|
const visViewer = this.visViewer();
|
|
859
|
+
const activeView = visViewer.activeView;
|
|
1008
860
|
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
const
|
|
1012
|
-
visViewer.
|
|
861
|
+
let overlayView = visViewer.getViewByName(OVERLAY_VIEW_NAME);
|
|
862
|
+
if (!overlayView) {
|
|
863
|
+
const markupModel = visViewer.getMarkupModel();
|
|
864
|
+
const pDevice = visViewer.getActiveDevice();
|
|
1013
865
|
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
this.update(true);
|
|
866
|
+
overlayView = pDevice.createView(OVERLAY_VIEW_NAME, false);
|
|
867
|
+
overlayView.addModel(markupModel);
|
|
1017
868
|
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
} catch (error: any) {
|
|
1021
|
-
this.emitEvent({ type: "geometryerror", data: error, file: "", buffer });
|
|
1022
|
-
throw error;
|
|
869
|
+
activeView.addSibling(overlayView);
|
|
870
|
+
pDevice.addView(overlayView);
|
|
1023
871
|
}
|
|
1024
|
-
this.emitEvent({ type: "geometryend", file: "", buffer });
|
|
1025
872
|
|
|
1026
|
-
|
|
1027
|
-
|
|
873
|
+
overlayView.viewPosition = activeView.viewPosition;
|
|
874
|
+
overlayView.viewTarget = activeView.viewTarget;
|
|
875
|
+
overlayView.upVector = activeView.upVector;
|
|
876
|
+
overlayView.viewFieldWidth = activeView.viewFieldWidth;
|
|
877
|
+
overlayView.viewFieldHeight = activeView.viewFieldHeight;
|
|
1028
878
|
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
* @deprecated
|
|
1033
|
-
*/
|
|
1034
|
-
openVsfxFile(buffer: Uint8Array | ArrayBuffer): this {
|
|
1035
|
-
console.warn(
|
|
1036
|
-
"Viewer.openVsfxFile() has been deprecated since 26.4 and will be removed in a future release, use Viewer.open() instead."
|
|
1037
|
-
);
|
|
879
|
+
const viewPort = overlayView.getViewport();
|
|
880
|
+
overlayView.setViewport(viewPort.lowerLeft, viewPort.upperRight);
|
|
881
|
+
overlayView.vportRect = activeView.vportRect;
|
|
1038
882
|
|
|
1039
|
-
|
|
883
|
+
this._markup.syncOverlay();
|
|
884
|
+
this.update();
|
|
885
|
+
}
|
|
1040
886
|
|
|
1041
|
-
|
|
1042
|
-
this.
|
|
887
|
+
clearOverlay(): void {
|
|
888
|
+
if (!this.visualizeJs) return;
|
|
889
|
+
|
|
890
|
+
this._markup.clearOverlay();
|
|
891
|
+
this.update();
|
|
892
|
+
}
|
|
1043
893
|
|
|
1044
|
-
|
|
894
|
+
clearSlices(): void {
|
|
895
|
+
if (!this.visualizeJs) return;
|
|
1045
896
|
|
|
1046
897
|
const visViewer = this.visViewer();
|
|
898
|
+
const activeView = visViewer.activeView;
|
|
899
|
+
activeView.removeCuttingPlanes();
|
|
900
|
+
activeView.delete();
|
|
1047
901
|
|
|
1048
|
-
this.
|
|
1049
|
-
|
|
1050
|
-
const data = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);
|
|
1051
|
-
visViewer.parseVsfx(data);
|
|
902
|
+
this.update();
|
|
903
|
+
}
|
|
1052
904
|
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
905
|
+
getSelected(): string[] {
|
|
906
|
+
return this.executeCommand("getSelected");
|
|
907
|
+
}
|
|
1056
908
|
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
this.emitEvent({ type: "geometryerror", data: error, file: "", buffer });
|
|
1061
|
-
throw error;
|
|
1062
|
-
}
|
|
1063
|
-
this.emitEvent({ type: "geometryend", file: "", buffer });
|
|
909
|
+
setSelected(handles?: string[]): void {
|
|
910
|
+
this.executeCommand("setSelected", handles);
|
|
911
|
+
}
|
|
1064
912
|
|
|
1065
|
-
|
|
913
|
+
getSelected2(): string[] {
|
|
914
|
+
return this.executeCommand("getSelected2");
|
|
1066
915
|
}
|
|
1067
916
|
|
|
1068
|
-
|
|
1069
|
-
this.
|
|
1070
|
-
|
|
917
|
+
setSelected2(handles?: string[]): void {
|
|
918
|
+
this.executeCommand("setSelected2", handles);
|
|
919
|
+
}
|
|
1071
920
|
|
|
1072
|
-
|
|
921
|
+
clearSelected(): void {
|
|
922
|
+
this.executeCommand("clearSelected");
|
|
923
|
+
}
|
|
1073
924
|
|
|
1074
|
-
|
|
1075
|
-
|
|
925
|
+
hideSelected(): void {
|
|
926
|
+
this.executeCommand("hideSelected");
|
|
1076
927
|
}
|
|
1077
928
|
|
|
1078
|
-
|
|
1079
|
-
|
|
929
|
+
isolateSelected(): void {
|
|
930
|
+
this.executeCommand("isolateSelected");
|
|
931
|
+
}
|
|
1080
932
|
|
|
1081
|
-
|
|
933
|
+
showAll(): void {
|
|
934
|
+
this.executeCommand("showAll");
|
|
935
|
+
}
|
|
1082
936
|
|
|
1083
|
-
|
|
1084
|
-
this.
|
|
1085
|
-
|
|
1086
|
-
this.clearSelected();
|
|
937
|
+
explode(index = 0): void {
|
|
938
|
+
this.executeCommand("explode", index);
|
|
939
|
+
}
|
|
1087
940
|
|
|
1088
|
-
|
|
1089
|
-
this.
|
|
941
|
+
collect(): void {
|
|
942
|
+
this.executeCommand("collect");
|
|
943
|
+
}
|
|
1090
944
|
|
|
1091
|
-
|
|
1092
|
-
|
|
945
|
+
/**
|
|
946
|
+
* Deprecated since `25.12`. Use {@link draggers.registerDragger} instead.
|
|
947
|
+
*/
|
|
948
|
+
public registerDragger(name: string, dragger: typeof Dragger): void {
|
|
949
|
+
console.warn(
|
|
950
|
+
"Viewer.registerDragger() has been deprecated since 25.12 and will be removed in a future release, use draggers('visualizejs').registerDragger() instead."
|
|
951
|
+
);
|
|
952
|
+
draggers.registerDragger(name, (viewer: IViewer) => new dragger(viewer));
|
|
953
|
+
}
|
|
1093
954
|
|
|
1094
|
-
|
|
1095
|
-
this.
|
|
1096
|
-
|
|
955
|
+
activeDragger(): IDragger | null {
|
|
956
|
+
return this._activeDragger;
|
|
957
|
+
}
|
|
1097
958
|
|
|
1098
|
-
|
|
959
|
+
setActiveDragger(name = ""): IDragger | null {
|
|
960
|
+
if (!this._activeDragger || this._activeDragger.name !== name) {
|
|
961
|
+
const oldDragger = this._activeDragger;
|
|
962
|
+
let newDragger = null;
|
|
1099
963
|
|
|
1100
|
-
|
|
1101
|
-
|
|
964
|
+
if (this._activeDragger) {
|
|
965
|
+
this._activeDragger.dispose();
|
|
966
|
+
this._activeDragger = null;
|
|
967
|
+
}
|
|
968
|
+
if (this.visualizeJs) {
|
|
969
|
+
newDragger = draggers.createDragger(name, this);
|
|
970
|
+
if (newDragger) {
|
|
971
|
+
this._activeDragger = newDragger;
|
|
972
|
+
this._activeDragger.initialize?.();
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
const canvas = this.canvas;
|
|
976
|
+
if (canvas) {
|
|
977
|
+
if (oldDragger) canvas.classList.remove(`oda-cursor-${oldDragger.name.toLowerCase()}`);
|
|
978
|
+
if (newDragger) canvas.classList.add(`oda-cursor-${newDragger.name.toLowerCase()}`);
|
|
979
|
+
}
|
|
1102
980
|
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
console.warn(
|
|
1108
|
-
"Viewer.getMarkupColor() has been deprecated since 25.11 and will be removed in a future release, use Viewer.markup.getMarkupColor() instead."
|
|
1109
|
-
);
|
|
1110
|
-
return this._markup.getMarkupColor();
|
|
981
|
+
this.emitEvent({ type: "changeactivedragger", data: name });
|
|
982
|
+
this.update();
|
|
983
|
+
}
|
|
984
|
+
return this._activeDragger;
|
|
1111
985
|
}
|
|
1112
986
|
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
);
|
|
1120
|
-
this._markup.setMarkupColor(r, g, b);
|
|
987
|
+
resetActiveDragger(): void {
|
|
988
|
+
const dragger = this._activeDragger;
|
|
989
|
+
if (dragger) {
|
|
990
|
+
this.setActiveDragger();
|
|
991
|
+
this.setActiveDragger(dragger.name);
|
|
992
|
+
}
|
|
1121
993
|
}
|
|
1122
994
|
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
*/
|
|
1126
|
-
colorizeAllMarkup(r = 255, g = 0, b = 0): void {
|
|
1127
|
-
console.warn(
|
|
1128
|
-
"Viewer.colorizeAllMarkup() has been deprecated since 25.11 and will be removed in a future release, use Viewer.markup.colorizeAllMarkup() instead."
|
|
1129
|
-
);
|
|
1130
|
-
this._markup.colorizeAllMarkup(r, g, b);
|
|
995
|
+
getComponent(name: string): IComponent {
|
|
996
|
+
return this._components.find((component) => component.name === name);
|
|
1131
997
|
}
|
|
1132
998
|
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
* {@link IMarkup.colorizeSelectedMarkups | markup.colorizeSelectedMarkups()} instead.
|
|
1136
|
-
*/
|
|
1137
|
-
colorizeSelectedMarkups(r = 255, g = 0, b = 0): void {
|
|
1138
|
-
this._markup.colorizeSelectedMarkups(r, g, b);
|
|
1139
|
-
}
|
|
999
|
+
drawViewpoint(viewpoint: IViewpoint): void {
|
|
1000
|
+
if (!this.visualizeJs) return;
|
|
1140
1001
|
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
*/
|
|
1144
|
-
addMarkupEntity(entityName: string) {
|
|
1145
|
-
if (!this.visualizeJs) return null;
|
|
1002
|
+
const visViewer = this.visViewer();
|
|
1003
|
+
const activeView = visViewer.activeView;
|
|
1146
1004
|
|
|
1147
|
-
|
|
1005
|
+
const getPoint3dAsArray = (point3d: IPoint): number[] => {
|
|
1006
|
+
return [point3d.x, point3d.y, point3d.z];
|
|
1007
|
+
};
|
|
1148
1008
|
|
|
1149
|
-
const
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1009
|
+
const setOrthogonalCamera = (orthogonal_camera: IOrthogonalCamera) => {
|
|
1010
|
+
if (orthogonal_camera) {
|
|
1011
|
+
activeView.setView(
|
|
1012
|
+
getPoint3dAsArray(orthogonal_camera.view_point),
|
|
1013
|
+
getPoint3dAsArray(orthogonal_camera.direction),
|
|
1014
|
+
getPoint3dAsArray(orthogonal_camera.up_vector),
|
|
1015
|
+
orthogonal_camera.field_width,
|
|
1016
|
+
orthogonal_camera.field_height,
|
|
1017
|
+
true
|
|
1018
|
+
);
|
|
1153
1019
|
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1020
|
+
this.syncOverlay();
|
|
1021
|
+
this.emitEvent({ type: "changecameramode", mode: "orthographic" });
|
|
1022
|
+
}
|
|
1023
|
+
};
|
|
1158
1024
|
|
|
1159
|
-
|
|
1025
|
+
const setPerspectiveCamera = (perspective_camera: IPerspectiveCamera) => {};
|
|
1160
1026
|
|
|
1161
|
-
|
|
1162
|
-
|
|
1027
|
+
const setClippingPlanes = (clipping_planes: IClippingPlane[]) => {
|
|
1028
|
+
if (clipping_planes) {
|
|
1029
|
+
for (const clipping_plane of clipping_planes) {
|
|
1030
|
+
const cuttingPlane = new (this.visLib().OdTvPlane)();
|
|
1031
|
+
cuttingPlane.set(getPoint3dAsArray(clipping_plane.location), getPoint3dAsArray(clipping_plane.direction));
|
|
1163
1032
|
|
|
1164
|
-
|
|
1165
|
-
|
|
1033
|
+
activeView.addCuttingPlane(cuttingPlane);
|
|
1034
|
+
activeView.setEnableCuttingPlaneFill(true, 0x66, 0x66, 0x66);
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
};
|
|
1038
|
+
|
|
1039
|
+
const setSelection = (selection: IEntity[]) => {
|
|
1040
|
+
if (selection) this.setSelected(selection.map((component) => component.handle));
|
|
1041
|
+
};
|
|
1166
1042
|
|
|
1167
1043
|
const draggerName = this._activeDragger?.name;
|
|
1168
1044
|
|
|
@@ -1174,9 +1050,10 @@ export class Viewer
|
|
|
1174
1050
|
this.showAll();
|
|
1175
1051
|
this.explode();
|
|
1176
1052
|
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1053
|
+
setOrthogonalCamera(viewpoint.orthogonal_camera);
|
|
1054
|
+
setPerspectiveCamera(viewpoint.perspective_camera);
|
|
1055
|
+
setClippingPlanes(viewpoint.clipping_planes);
|
|
1056
|
+
setSelection(viewpoint.custom_fields?.selection2 || viewpoint.selection);
|
|
1180
1057
|
this._markup.setViewpoint(viewpoint);
|
|
1181
1058
|
|
|
1182
1059
|
this.setActiveDragger(draggerName);
|
|
@@ -1187,103 +1064,119 @@ export class Viewer
|
|
|
1187
1064
|
createViewpoint(): IViewpoint {
|
|
1188
1065
|
if (!this.visualizeJs) return {};
|
|
1189
1066
|
|
|
1190
|
-
const
|
|
1067
|
+
const visViewer = this.visViewer();
|
|
1068
|
+
const activeView = visViewer.activeView;
|
|
1069
|
+
|
|
1070
|
+
const getPoint3dFromArray = (array: number[]): IPoint => {
|
|
1071
|
+
return { x: array[0], y: array[1], z: array[2] };
|
|
1072
|
+
};
|
|
1073
|
+
|
|
1074
|
+
const getOrthogonalCamera = (): IOrthogonalCamera => {
|
|
1075
|
+
return {
|
|
1076
|
+
view_point: getPoint3dFromArray(activeView.viewPosition),
|
|
1077
|
+
direction: getPoint3dFromArray(activeView.viewTarget),
|
|
1078
|
+
up_vector: getPoint3dFromArray(activeView.upVector),
|
|
1079
|
+
field_width: activeView.viewFieldWidth,
|
|
1080
|
+
field_height: activeView.viewFieldHeight,
|
|
1081
|
+
view_to_world_scale: 1,
|
|
1082
|
+
};
|
|
1083
|
+
};
|
|
1084
|
+
|
|
1085
|
+
const getPerspectiveCamera = (): IPerspectiveCamera => {
|
|
1086
|
+
return undefined;
|
|
1087
|
+
};
|
|
1088
|
+
|
|
1089
|
+
const getClippingPlanes = (): IClippingPlane[] => {
|
|
1090
|
+
const clipping_planes = [];
|
|
1091
|
+
for (let i = 0; i < activeView.numCuttingPlanes(); i++) {
|
|
1092
|
+
const cuttingPlane = activeView.getCuttingPlane(i);
|
|
1093
|
+
|
|
1094
|
+
const clipping_plane = {
|
|
1095
|
+
location: getPoint3dFromArray(cuttingPlane.getOrigin()),
|
|
1096
|
+
direction: getPoint3dFromArray(cuttingPlane.normal()),
|
|
1097
|
+
};
|
|
1098
|
+
|
|
1099
|
+
clipping_planes.push(clipping_plane);
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
return clipping_planes;
|
|
1103
|
+
};
|
|
1104
|
+
|
|
1105
|
+
const getSelection = (): IEntity[] => {
|
|
1106
|
+
return this.getSelected().map((handle) => ({ handle }));
|
|
1107
|
+
};
|
|
1108
|
+
|
|
1109
|
+
const getSelection2 = (): IEntity[] => {
|
|
1110
|
+
return this.getSelected2().map((handle) => ({ handle }));
|
|
1111
|
+
};
|
|
1112
|
+
|
|
1113
|
+
const viewpoint: IViewpoint = { custom_fields: {} };
|
|
1191
1114
|
|
|
1192
|
-
viewpoint.orthogonal_camera =
|
|
1193
|
-
viewpoint.
|
|
1194
|
-
viewpoint.
|
|
1115
|
+
viewpoint.orthogonal_camera = getOrthogonalCamera();
|
|
1116
|
+
viewpoint.perspective_camera = getPerspectiveCamera();
|
|
1117
|
+
viewpoint.clipping_planes = getClippingPlanes();
|
|
1118
|
+
viewpoint.selection = getSelection();
|
|
1195
1119
|
viewpoint.description = new Date().toDateString();
|
|
1196
1120
|
this._markup.getViewpoint(viewpoint);
|
|
1197
1121
|
|
|
1122
|
+
viewpoint.custom_fields.selection2 = getSelection2();
|
|
1123
|
+
|
|
1198
1124
|
this.emitEvent({ type: "createviewpoint", data: viewpoint });
|
|
1199
1125
|
|
|
1200
1126
|
return viewpoint;
|
|
1201
1127
|
}
|
|
1202
1128
|
|
|
1203
|
-
|
|
1204
|
-
return { x: array[0], y: array[1], z: array[2] };
|
|
1205
|
-
}
|
|
1129
|
+
// IWorldTransform
|
|
1206
1130
|
|
|
1207
|
-
|
|
1208
|
-
return
|
|
1209
|
-
}
|
|
1131
|
+
screenToWorld(position: { x: number; y: number }): { x: number; y: number; z: number } {
|
|
1132
|
+
if (!this.visualizeJs) return { x: position.x, y: position.y, z: 0 };
|
|
1210
1133
|
|
|
1211
|
-
|
|
1212
|
-
const
|
|
1213
|
-
|
|
1134
|
+
const activeView = this.visViewer().activeView;
|
|
1135
|
+
const worldPoint = activeView.transformScreenToWorld(
|
|
1136
|
+
position.x * window.devicePixelRatio,
|
|
1137
|
+
position.y * window.devicePixelRatio
|
|
1138
|
+
);
|
|
1214
1139
|
|
|
1215
|
-
|
|
1216
|
-
view_point: this.getPoint3dFromArray(activeView.viewPosition),
|
|
1217
|
-
direction: this.getPoint3dFromArray(activeView.viewTarget),
|
|
1218
|
-
up_vector: this.getPoint3dFromArray(activeView.upVector),
|
|
1219
|
-
field_width: activeView.viewFieldWidth,
|
|
1220
|
-
field_height: activeView.viewFieldHeight,
|
|
1221
|
-
view_to_world_scale: 1,
|
|
1222
|
-
};
|
|
1223
|
-
}
|
|
1140
|
+
const result = { x: worldPoint[0], y: worldPoint[1], z: worldPoint[2] };
|
|
1224
1141
|
|
|
1225
|
-
|
|
1226
|
-
const visViewer = this.visViewer();
|
|
1227
|
-
const activeView = visViewer.activeView;
|
|
1142
|
+
activeView.delete();
|
|
1228
1143
|
|
|
1229
|
-
|
|
1230
|
-
activeView.setView(
|
|
1231
|
-
this.getLogicalPoint3dAsArray(settings.view_point),
|
|
1232
|
-
this.getLogicalPoint3dAsArray(settings.direction),
|
|
1233
|
-
this.getLogicalPoint3dAsArray(settings.up_vector),
|
|
1234
|
-
settings.field_width,
|
|
1235
|
-
settings.field_height,
|
|
1236
|
-
true
|
|
1237
|
-
);
|
|
1238
|
-
this.syncOverlay();
|
|
1239
|
-
}
|
|
1144
|
+
return result;
|
|
1240
1145
|
}
|
|
1241
1146
|
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
const activeView = visViewer.activeView;
|
|
1147
|
+
worldToScreen(position: { x: number; y: number; z: number }): { x: number; y: number } {
|
|
1148
|
+
if (!this.visualizeJs) return { x: position.x, y: position.y };
|
|
1245
1149
|
|
|
1246
|
-
const
|
|
1247
|
-
|
|
1248
|
-
const cuttingPlane = activeView.getCuttingPlane(i);
|
|
1150
|
+
const activeView = this.visViewer().activeView;
|
|
1151
|
+
const devicePoint = activeView.transformWorldToScreen(position.x, position.y, position.z);
|
|
1249
1152
|
|
|
1250
|
-
|
|
1251
|
-
location: this.getPoint3dFromArray(cuttingPlane.getOrigin()),
|
|
1252
|
-
direction: this.getPoint3dFromArray(cuttingPlane.normal()),
|
|
1253
|
-
};
|
|
1153
|
+
const result = { x: devicePoint[0] / window.devicePixelRatio, y: devicePoint[1] / window.devicePixelRatio };
|
|
1254
1154
|
|
|
1255
|
-
|
|
1256
|
-
}
|
|
1155
|
+
activeView.delete();
|
|
1257
1156
|
|
|
1258
|
-
return
|
|
1157
|
+
return result;
|
|
1259
1158
|
}
|
|
1260
1159
|
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
const visViewer = this.visViewer();
|
|
1264
|
-
const activeView = visViewer.activeView;
|
|
1160
|
+
getScale(): { x: number; y: number; z: number } {
|
|
1161
|
+
const result = { x: 1.0, y: 1.0, z: 1.0 };
|
|
1265
1162
|
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
cuttingPlane.set(
|
|
1269
|
-
this.getLogicalPoint3dAsArray(clipping_plane.location),
|
|
1270
|
-
this.getLogicalPoint3dAsArray(clipping_plane.direction)
|
|
1271
|
-
);
|
|
1163
|
+
const projMatrix = this.visViewer().activeView.projectionMatrix;
|
|
1164
|
+
const tolerance = 1.0e-6;
|
|
1272
1165
|
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
}
|
|
1276
|
-
}
|
|
1277
|
-
}
|
|
1166
|
+
const x = projMatrix.get(0, 0);
|
|
1167
|
+
if (x > tolerance || x < -tolerance) result.x = 1 / x;
|
|
1278
1168
|
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1169
|
+
const y = projMatrix.get(1, 1);
|
|
1170
|
+
if (y > tolerance || y < -tolerance) result.y = 1 / y;
|
|
1171
|
+
|
|
1172
|
+
const z = projMatrix.get(2, 2);
|
|
1173
|
+
if (z > tolerance || z < -tolerance) result.z = 1 / z;
|
|
1282
1174
|
|
|
1283
|
-
|
|
1284
|
-
this.setSelected(selection?.map((component) => component.handle));
|
|
1175
|
+
return result;
|
|
1285
1176
|
}
|
|
1286
1177
|
|
|
1178
|
+
// ICommandService
|
|
1179
|
+
|
|
1287
1180
|
/**
|
|
1288
1181
|
* Executes the command denoted by the given command. If the command is not found, tries to set active
|
|
1289
1182
|
* dragger with the specified name.
|
|
@@ -1325,6 +1218,118 @@ export class Viewer
|
|
|
1325
1218
|
return commands.executeCommand(id, this, ...args);
|
|
1326
1219
|
}
|
|
1327
1220
|
|
|
1221
|
+
// VisualizeJS viewer specific
|
|
1222
|
+
|
|
1223
|
+
/**
|
|
1224
|
+
* Adds an empty `Visualize` markup entity to the VisualizeJS overlay.
|
|
1225
|
+
*/
|
|
1226
|
+
addMarkupEntity(entityName: string) {
|
|
1227
|
+
if (!this.visualizeJs) return null;
|
|
1228
|
+
|
|
1229
|
+
this.syncOverlay();
|
|
1230
|
+
|
|
1231
|
+
const visViewer = this.visViewer();
|
|
1232
|
+
const model = visViewer.getMarkupModel();
|
|
1233
|
+
const entityId = model.appendEntity(entityName);
|
|
1234
|
+
const entityPtr = entityId.openObject();
|
|
1235
|
+
|
|
1236
|
+
const color = this.getMarkupColor();
|
|
1237
|
+
entityPtr.setColor(color.r, color.g, color.b);
|
|
1238
|
+
entityPtr.setLineWeight(2);
|
|
1239
|
+
entityPtr.delete();
|
|
1240
|
+
|
|
1241
|
+
this.update();
|
|
1242
|
+
|
|
1243
|
+
return entityId;
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
/**
|
|
1247
|
+
* Deprecated since `25.11`. Use {@link IMarkup.getMarkupColor | markup.getMarkupColor()} instead.
|
|
1248
|
+
*/
|
|
1249
|
+
getMarkupColor(): { r: number; g: number; b: number } {
|
|
1250
|
+
console.warn(
|
|
1251
|
+
"Viewer.getMarkupColor() has been deprecated since 25.11 and will be removed in a future release, use Viewer.markup.getMarkupColor() instead."
|
|
1252
|
+
);
|
|
1253
|
+
return this._markup.getMarkupColor();
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
/**
|
|
1257
|
+
* Deprecated since `25.11`. Use {@link IMarkup.setMarkupColor | markup.setMarkupColor()} instead.
|
|
1258
|
+
*/
|
|
1259
|
+
setMarkupColor(r = 255, g = 0, b = 0): void {
|
|
1260
|
+
console.warn(
|
|
1261
|
+
"Viewer.setMarkupColor() has been deprecated since 25.11 and will be removed in a future release, use Viewer.markup.setMarkupColor() instead."
|
|
1262
|
+
);
|
|
1263
|
+
this._markup.setMarkupColor(r, g, b);
|
|
1264
|
+
}
|
|
1265
|
+
|
|
1266
|
+
/**
|
|
1267
|
+
* Deprecated since `25.11`. Use {@link IMarkup.colorizeAllMarkup | markup.colorizeAllMarkup()} instead.
|
|
1268
|
+
*/
|
|
1269
|
+
colorizeAllMarkup(r = 255, g = 0, b = 0): void {
|
|
1270
|
+
console.warn(
|
|
1271
|
+
"Viewer.colorizeAllMarkup() has been deprecated since 25.11 and will be removed in a future release, use Viewer.markup.colorizeAllMarkup() instead."
|
|
1272
|
+
);
|
|
1273
|
+
this._markup.colorizeAllMarkup(r, g, b);
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
/**
|
|
1277
|
+
* Deprecated since `25.11`. Use
|
|
1278
|
+
* {@link IMarkup.colorizeSelectedMarkups | markup.colorizeSelectedMarkups()} instead.
|
|
1279
|
+
*/
|
|
1280
|
+
colorizeSelectedMarkups(r = 255, g = 0, b = 0): void {
|
|
1281
|
+
this._markup.colorizeSelectedMarkups(r, g, b);
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
private scheduleUpdateAsync(maxScheduleUpdateTimeInMs = 50): Promise<void> {
|
|
1285
|
+
return new Promise<void>((resolve, reject) => {
|
|
1286
|
+
setTimeout(() => {
|
|
1287
|
+
try {
|
|
1288
|
+
if (this._enableAutoUpdate) {
|
|
1289
|
+
this.visViewer()?.update(maxScheduleUpdateTimeInMs);
|
|
1290
|
+
this._activeDragger?.updatePreview?.();
|
|
1291
|
+
}
|
|
1292
|
+
this.emitEvent({ type: "update", data: false });
|
|
1293
|
+
resolve();
|
|
1294
|
+
} catch (e) {
|
|
1295
|
+
console.error(e);
|
|
1296
|
+
reject();
|
|
1297
|
+
}
|
|
1298
|
+
}, 0);
|
|
1299
|
+
});
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
/**
|
|
1303
|
+
* Updates the viewer asynchronously without locking the user interface. Used to update the viewer
|
|
1304
|
+
* after changes that require a long rendering time.
|
|
1305
|
+
*
|
|
1306
|
+
* Do nothing if the auto-update mode is disabled in the constructor. In this case, register an
|
|
1307
|
+
* `update` event handler and update the `VisualizeJS` viewer and active dragger manually.
|
|
1308
|
+
*
|
|
1309
|
+
* Fires:
|
|
1310
|
+
*
|
|
1311
|
+
* - {@link UpdateEvent | update}
|
|
1312
|
+
*
|
|
1313
|
+
* @param maxScheduleUpdateTimeInMs - Maximum time for one update, default 30 ms.
|
|
1314
|
+
* @param maxScheduleUpdateCount - Maximum count of scheduled updates.
|
|
1315
|
+
*/
|
|
1316
|
+
async updateAsync(maxScheduleUpdateTimeInMs = 50, maxScheduleUpdateCount = 50): Promise<void> {
|
|
1317
|
+
if (!this.visualizeJs) return;
|
|
1318
|
+
|
|
1319
|
+
this._isRunAsyncUpdate = true;
|
|
1320
|
+
try {
|
|
1321
|
+
const device = this.visViewer().getActiveDevice();
|
|
1322
|
+
for (let iterationCount = 0; !device.isValid() && iterationCount < maxScheduleUpdateCount; iterationCount++) {
|
|
1323
|
+
await this.scheduleUpdateAsync(maxScheduleUpdateTimeInMs);
|
|
1324
|
+
}
|
|
1325
|
+
await this.scheduleUpdateAsync(maxScheduleUpdateTimeInMs);
|
|
1326
|
+
} catch (e) {
|
|
1327
|
+
console.error(e);
|
|
1328
|
+
} finally {
|
|
1329
|
+
this._isRunAsyncUpdate = false;
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1328
1333
|
public deviceAutoRegeneration() {
|
|
1329
1334
|
const visViewer = this.visViewer();
|
|
1330
1335
|
const device = visViewer.getActiveDevice();
|