@inweb/viewer-three 26.10.6 → 26.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -4
- package/dist/{plugins → extensions}/components/AxesHelperComponent.js +23 -1
- package/dist/extensions/components/AxesHelperComponent.js.map +1 -0
- package/dist/extensions/components/AxesHelperComponent.min.js +24 -0
- package/dist/{plugins → extensions}/components/AxesHelperComponent.module.js +24 -2
- package/dist/extensions/components/AxesHelperComponent.module.js.map +1 -0
- package/dist/{plugins → extensions}/components/ExtentsHelperComponent.js +18 -0
- package/dist/extensions/components/ExtentsHelperComponent.js.map +1 -0
- package/dist/{plugins/components/AxesHelperComponent.min.js → extensions/components/ExtentsHelperComponent.min.js} +1 -1
- package/dist/{plugins → extensions}/components/ExtentsHelperComponent.module.js +19 -1
- package/dist/extensions/components/ExtentsHelperComponent.module.js.map +1 -0
- package/dist/extensions/components/GridHelperComponent.js.map +1 -0
- package/dist/extensions/components/GridHelperComponent.module.js.map +1 -0
- package/dist/extensions/components/InfoPanelComponent.js +170 -0
- package/dist/extensions/components/InfoPanelComponent.js.map +1 -0
- package/dist/extensions/components/InfoPanelComponent.min.js +24 -0
- package/dist/extensions/components/InfoPanelComponent.module.js +164 -0
- package/dist/extensions/components/InfoPanelComponent.module.js.map +1 -0
- package/dist/extensions/components/LightHelperComponent.js.map +1 -0
- package/dist/extensions/components/LightHelperComponent.module.js.map +1 -0
- package/dist/extensions/components/RoomEnvironmentComponent.js.map +1 -0
- package/dist/extensions/components/RoomEnvironmentComponent.module.js.map +1 -0
- package/dist/{plugins → extensions}/components/StatsPanelComponent.js +9 -3
- package/dist/extensions/components/StatsPanelComponent.js.map +1 -0
- package/dist/extensions/components/StatsPanelComponent.min.js +24 -0
- package/dist/{plugins → extensions}/components/StatsPanelComponent.module.js +9 -3
- package/dist/extensions/components/StatsPanelComponent.module.js.map +1 -0
- package/dist/{plugins → extensions}/loaders/GLTFCloudLoader.js +2 -3
- package/dist/extensions/loaders/GLTFCloudLoader.js.map +1 -0
- package/dist/{plugins → extensions}/loaders/GLTFCloudLoader.min.js +1 -1
- package/dist/{plugins → extensions}/loaders/GLTFCloudLoader.module.js +2 -3
- package/dist/extensions/loaders/GLTFCloudLoader.module.js.map +1 -0
- package/dist/extensions/loaders/GLTFFileLoader.js +2499 -0
- package/dist/extensions/loaders/GLTFFileLoader.js.map +1 -0
- package/dist/extensions/loaders/GLTFFileLoader.min.js +24 -0
- package/dist/extensions/loaders/GLTFFileLoader.module.js +74 -0
- package/dist/extensions/loaders/GLTFFileLoader.module.js.map +1 -0
- package/dist/{plugins → extensions}/loaders/IFCXLoader.js +5 -7
- package/dist/extensions/loaders/IFCXLoader.js.map +1 -0
- package/dist/{plugins → extensions}/loaders/IFCXLoader.min.js +1 -1
- package/dist/{plugins → extensions}/loaders/IFCXLoader.module.js +5 -7
- package/dist/extensions/loaders/IFCXLoader.module.js.map +1 -0
- package/dist/{plugins → extensions}/loaders/PotreeLoader.js +56 -6
- package/dist/extensions/loaders/PotreeLoader.js.map +1 -0
- package/dist/extensions/loaders/PotreeLoader.min.js +24 -0
- package/dist/{plugins → extensions}/loaders/PotreeLoader.module.js +53 -2
- package/dist/extensions/loaders/PotreeLoader.module.js.map +1 -0
- package/dist/viewer-three.js +1416 -2930
- package/dist/viewer-three.js.map +1 -1
- package/dist/viewer-three.min.js +8 -3
- package/dist/viewer-three.module.js +1205 -363
- package/dist/viewer-three.module.js.map +1 -1
- package/{plugins → extensions}/components/AxesHelperComponent.ts +31 -2
- package/{plugins → extensions}/components/ExtentsHelperComponent.ts +25 -0
- package/extensions/components/InfoPanelComponent.ts +197 -0
- package/{plugins → extensions}/components/StatsPanelComponent.ts +10 -3
- package/{plugins → extensions}/loaders/GLTFCloudLoader.ts +2 -3
- package/{src/Viewer → extensions}/loaders/GLTFFileLoader.ts +21 -12
- package/{plugins → extensions}/loaders/IFCX/IFCXCloudLoader.ts +5 -5
- package/{plugins → extensions}/loaders/IFCX/IFCXFileLoader.ts +3 -4
- package/{plugins → extensions}/loaders/Potree/PotreeFileLoader.ts +3 -4
- package/extensions/loaders/Potree/PotreeModelImpl.ts +108 -0
- package/lib/Viewer/Viewer.d.ts +28 -20
- package/lib/Viewer/commands/GetSelected2.d.ts +2 -0
- package/lib/Viewer/commands/SelectModel.d.ts +1 -1
- package/lib/Viewer/commands/SetSelected2.d.ts +2 -0
- package/lib/Viewer/components/InfoComponent.d.ts +22 -0
- package/lib/Viewer/components/SelectionComponent.d.ts +1 -3
- package/lib/Viewer/components/index.d.ts +6 -6
- package/lib/Viewer/draggers/MeasureLineDragger.d.ts +7 -1
- package/lib/Viewer/loaders/DynamicGltfLoader/DynamicModelImpl.d.ts +2 -1
- package/lib/Viewer/loaders/GLTFBinaryExtension.d.ts +5 -0
- package/lib/Viewer/loaders/GLTFCloudDynamicLoader.d.ts +2 -2
- package/lib/Viewer/loaders/{GLTFFileLoader.d.ts → GLTFFileDynamicLoader.d.ts} +7 -1
- package/lib/Viewer/loaders/GLTFLoadingManager.d.ts +4 -3
- package/lib/Viewer/loaders/RangesLoader.d.ts +15 -0
- package/lib/Viewer/loaders/index.d.ts +22 -14
- package/lib/Viewer/measurement/Snapper.d.ts +15 -0
- package/lib/Viewer/measurement/UnitConverter.d.ts +63 -0
- package/lib/Viewer/measurement/UnitFormatter.d.ts +4 -0
- package/lib/Viewer/models/IModelImpl.d.ts +11 -8
- package/lib/Viewer/models/ModelImpl.d.ts +9 -5
- package/package.json +11 -11
- package/src/Viewer/Viewer.ts +127 -88
- package/src/Viewer/commands/ClearSelected.ts +3 -1
- package/src/Viewer/commands/GetModels.ts +1 -1
- package/src/Viewer/commands/GetSelected.ts +2 -2
- package/{plugins/loaders/Potree/PotreeModelImpl.ts → src/Viewer/commands/GetSelected2.ts} +7 -9
- package/src/Viewer/commands/HideSelected.ts +3 -1
- package/src/Viewer/commands/SelectModel.ts +5 -5
- package/src/Viewer/commands/SetSelected.ts +9 -10
- package/src/Viewer/commands/SetSelected2.ts +42 -0
- package/src/Viewer/commands/ZoomToObjects.ts +5 -6
- package/src/Viewer/commands/ZoomToSelected.ts +3 -1
- package/src/Viewer/commands/index.ts +4 -0
- package/src/Viewer/components/CameraComponent.ts +6 -1
- package/src/Viewer/components/ExtentsComponent.ts +4 -1
- package/src/Viewer/components/InfoComponent.ts +187 -0
- package/src/Viewer/components/SelectionComponent.ts +7 -30
- package/src/Viewer/components/index.ts +8 -6
- package/src/Viewer/draggers/MeasureLineDragger.ts +84 -226
- package/src/Viewer/loaders/DynamicGltfLoader/DynamicGltfLoader.js +276 -39
- package/src/Viewer/loaders/DynamicGltfLoader/DynamicModelImpl.ts +45 -10
- package/src/Viewer/loaders/DynamicGltfLoader/GltfStructure.js +71 -2
- package/src/Viewer/loaders/GLTFBinaryExtension.ts +91 -0
- package/src/Viewer/loaders/GLTFCloudDynamicLoader.ts +13 -19
- package/src/Viewer/loaders/GLTFFileDynamicLoader.ts +145 -0
- package/src/Viewer/loaders/GLTFLoadingManager.ts +5 -4
- package/src/Viewer/loaders/RangesLoader.ts +105 -0
- package/src/Viewer/loaders/index.ts +24 -16
- package/src/Viewer/measurement/Snapper.ts +208 -0
- package/src/Viewer/measurement/UnitConverter.ts +47 -0
- package/src/Viewer/measurement/UnitFormatter.ts +95 -0
- package/src/Viewer/models/IModelImpl.ts +17 -8
- package/src/Viewer/models/ModelImpl.ts +205 -16
- package/src/index-umd.ts +1 -1
- package/dist/plugins/components/AxesHelperComponent.js.map +0 -1
- package/dist/plugins/components/AxesHelperComponent.module.js.map +0 -1
- package/dist/plugins/components/ExtentsHelperComponent.js.map +0 -1
- package/dist/plugins/components/ExtentsHelperComponent.min.js +0 -24
- package/dist/plugins/components/ExtentsHelperComponent.module.js.map +0 -1
- package/dist/plugins/components/GridHelperComponent.js.map +0 -1
- package/dist/plugins/components/GridHelperComponent.module.js.map +0 -1
- package/dist/plugins/components/LightHelperComponent.js.map +0 -1
- package/dist/plugins/components/LightHelperComponent.module.js.map +0 -1
- package/dist/plugins/components/RoomEnvironmentComponent.js.map +0 -1
- package/dist/plugins/components/RoomEnvironmentComponent.module.js.map +0 -1
- package/dist/plugins/components/StatsPanelComponent.js.map +0 -1
- package/dist/plugins/components/StatsPanelComponent.min.js +0 -24
- package/dist/plugins/components/StatsPanelComponent.module.js.map +0 -1
- package/dist/plugins/loaders/GLTFCloudLoader.js.map +0 -1
- package/dist/plugins/loaders/GLTFCloudLoader.module.js.map +0 -1
- package/dist/plugins/loaders/IFCXLoader.js.map +0 -1
- package/dist/plugins/loaders/IFCXLoader.module.js.map +0 -1
- package/dist/plugins/loaders/PotreeLoader.js.map +0 -1
- package/dist/plugins/loaders/PotreeLoader.min.js +0 -24
- package/dist/plugins/loaders/PotreeLoader.module.js.map +0 -1
- /package/dist/{plugins → extensions}/components/GridHelperComponent.js +0 -0
- /package/dist/{plugins → extensions}/components/GridHelperComponent.min.js +0 -0
- /package/dist/{plugins → extensions}/components/GridHelperComponent.module.js +0 -0
- /package/dist/{plugins → extensions}/components/LightHelperComponent.js +0 -0
- /package/dist/{plugins → extensions}/components/LightHelperComponent.min.js +0 -0
- /package/dist/{plugins → extensions}/components/LightHelperComponent.module.js +0 -0
- /package/dist/{plugins → extensions}/components/RoomEnvironmentComponent.js +0 -0
- /package/dist/{plugins → extensions}/components/RoomEnvironmentComponent.min.js +0 -0
- /package/dist/{plugins → extensions}/components/RoomEnvironmentComponent.module.js +0 -0
- /package/{plugins → extensions}/components/GridHelperComponent.ts +0 -0
- /package/{plugins → extensions}/components/LightHelperComponent.ts +0 -0
- /package/{plugins → extensions}/components/RoomEnvironmentComponent.ts +0 -0
- /package/{plugins → extensions}/loaders/IFCX/IFCXLoader.ts +0 -0
- /package/{plugins → extensions}/loaders/IFCX/index.ts +0 -0
- /package/{plugins → extensions}/loaders/IFCX/render.js +0 -0
- /package/{plugins → extensions}/loaders/Potree/index.ts +0 -0
package/src/Viewer/Viewer.ts
CHANGED
|
@@ -50,9 +50,11 @@ import {
|
|
|
50
50
|
FileSource,
|
|
51
51
|
IClippingPlane,
|
|
52
52
|
IComponent,
|
|
53
|
-
IEntity,
|
|
54
53
|
IDragger,
|
|
54
|
+
IEntity,
|
|
55
|
+
IInfo,
|
|
55
56
|
ILoader,
|
|
57
|
+
Info,
|
|
56
58
|
IOptions,
|
|
57
59
|
IOrthogonalCamera,
|
|
58
60
|
IPerspectiveCamera,
|
|
@@ -80,12 +82,14 @@ export class Viewer
|
|
|
80
82
|
implements IViewer, IWorldTransform
|
|
81
83
|
{
|
|
82
84
|
public client: Client | undefined;
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
private canvaseventlistener: (event: any) => void;
|
|
86
|
-
|
|
85
|
+
public options: IOptions;
|
|
87
86
|
public canvas: HTMLCanvasElement | undefined;
|
|
88
87
|
public canvasEvents: string[];
|
|
88
|
+
public loaders: ILoader[];
|
|
89
|
+
public models: IModelImpl[];
|
|
90
|
+
public info: IInfo;
|
|
91
|
+
|
|
92
|
+
private canvaseventlistener: (event: any) => void;
|
|
89
93
|
|
|
90
94
|
public scene: Scene | undefined;
|
|
91
95
|
public helpers: Helpers | undefined;
|
|
@@ -98,9 +102,6 @@ export class Viewer
|
|
|
98
102
|
public ssaaRenderPass: SSAARenderPass | undefined;
|
|
99
103
|
public outputPass: OutputPass | undefined;
|
|
100
104
|
public composer: EffectComposer | undefined;
|
|
101
|
-
|
|
102
|
-
public loaders: ILoader[];
|
|
103
|
-
public models: IModelImpl[];
|
|
104
105
|
public selected: Object3D[];
|
|
105
106
|
public extents: Box3;
|
|
106
107
|
public target: Vector3;
|
|
@@ -120,22 +121,23 @@ export class Viewer
|
|
|
120
121
|
*/
|
|
121
122
|
constructor(client?: Client) {
|
|
122
123
|
super();
|
|
123
|
-
this._options = new Options(this);
|
|
124
|
-
|
|
125
124
|
this.client = client;
|
|
125
|
+
this.options = new Options(this);
|
|
126
|
+
this.loaders = [];
|
|
127
|
+
this.models = [];
|
|
128
|
+
this.info = new Info();
|
|
126
129
|
|
|
127
|
-
this.canvasEvents = CANVAS_EVENTS;
|
|
130
|
+
this.canvasEvents = CANVAS_EVENTS.slice();
|
|
128
131
|
this.canvaseventlistener = (event: Event) => this.emit(event);
|
|
129
132
|
|
|
130
|
-
this.loaders = [];
|
|
131
|
-
this.models = [];
|
|
132
133
|
this.selected = [];
|
|
133
134
|
this.extents = new Box3();
|
|
134
|
-
this.target = new Vector3();
|
|
135
|
+
this.target = new Vector3(0, 0, 0);
|
|
135
136
|
|
|
136
137
|
this._activeDragger = null;
|
|
137
138
|
this._components = [];
|
|
138
139
|
|
|
140
|
+
this._renderNeeded = false;
|
|
139
141
|
this._renderTime = 0;
|
|
140
142
|
|
|
141
143
|
this.render = this.render.bind(this);
|
|
@@ -144,10 +146,17 @@ export class Viewer
|
|
|
144
146
|
this._markup = new Markup();
|
|
145
147
|
}
|
|
146
148
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
+
/**
|
|
150
|
+
* 2D markup core instance used to create markups.
|
|
151
|
+
*
|
|
152
|
+
* @readonly
|
|
153
|
+
*/
|
|
154
|
+
get markup(): IMarkup {
|
|
155
|
+
return this._markup;
|
|
149
156
|
}
|
|
150
157
|
|
|
158
|
+
// IViewer
|
|
159
|
+
|
|
151
160
|
get draggers(): string[] {
|
|
152
161
|
return [...draggers.getDraggers().keys()];
|
|
153
162
|
}
|
|
@@ -156,21 +165,11 @@ export class Viewer
|
|
|
156
165
|
return [...components.getComponents().keys()];
|
|
157
166
|
}
|
|
158
167
|
|
|
159
|
-
/**
|
|
160
|
-
* 2D markup core instance used to create markups.
|
|
161
|
-
*
|
|
162
|
-
* @readonly
|
|
163
|
-
*/
|
|
164
|
-
get markup(): IMarkup {
|
|
165
|
-
return this._markup;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
168
|
initialize(canvas: HTMLCanvasElement, onProgress?: (event: ProgressEvent<EventTarget>) => void): Promise<this> {
|
|
169
169
|
this.addEventListener("optionschange", (event) => this.syncOptions(event.data));
|
|
170
170
|
|
|
171
171
|
this.scene = new Scene();
|
|
172
172
|
this.helpers = new Helpers();
|
|
173
|
-
this.target = new Vector3(0, 0, 0);
|
|
174
173
|
|
|
175
174
|
const pixelRatio = window.devicePixelRatio;
|
|
176
175
|
const rect = canvas.parentElement.getBoundingClientRect();
|
|
@@ -319,6 +318,8 @@ export class Viewer
|
|
|
319
318
|
this.emitEvent({ type: "update", data: force });
|
|
320
319
|
}
|
|
321
320
|
|
|
321
|
+
// Internal render routines
|
|
322
|
+
|
|
322
323
|
render(time?: DOMHighResTimeStamp, force = false): void {
|
|
323
324
|
if (!this.renderer) return;
|
|
324
325
|
if (!this._renderNeeded && !force) return;
|
|
@@ -329,6 +330,9 @@ export class Viewer
|
|
|
329
330
|
this._renderTime = time;
|
|
330
331
|
this._renderNeeded = false;
|
|
331
332
|
|
|
333
|
+
this.renderer.info.autoReset = false;
|
|
334
|
+
this.renderer.info.reset();
|
|
335
|
+
|
|
332
336
|
if (this.options.antialiasing === true || this.options.antialiasing === "msaa") {
|
|
333
337
|
this.renderer.render(this.scene, this.camera);
|
|
334
338
|
this.renderer.render(this.helpers, this.camera);
|
|
@@ -341,6 +345,8 @@ export class Viewer
|
|
|
341
345
|
this.emitEvent({ type: "render", time, deltaTime });
|
|
342
346
|
}
|
|
343
347
|
|
|
348
|
+
// Internal loading routines
|
|
349
|
+
|
|
344
350
|
loadReferences(model: Model | File | Assembly): Promise<this> {
|
|
345
351
|
// todo: load reference as text fonts
|
|
346
352
|
return Promise.resolve(this);
|
|
@@ -357,18 +363,20 @@ export class Viewer
|
|
|
357
363
|
* exception will be thrown.
|
|
358
364
|
*
|
|
359
365
|
* For files from Open Cloud Server, the default model will be loaded. If there is no default model,
|
|
360
|
-
* first
|
|
366
|
+
* the first available model will be loaded. If no models are found in the file, an exception will be
|
|
361
367
|
* thrown.
|
|
362
368
|
*
|
|
363
369
|
* For URLs, the file extension is used to determine the file format. For a `ArrayBuffer` and `Data
|
|
364
|
-
* URL`, a file format must be specified using `params.format` parameter
|
|
365
|
-
*
|
|
370
|
+
* URL`, a file format must be specified using `params.format` parameter. If no appropriate loader is
|
|
371
|
+
* found for the specified format, an exception will be thrown.
|
|
366
372
|
*
|
|
367
373
|
* If there was an active dragger before opening the file, it will be deactivated. After opening the
|
|
368
374
|
* file, you must manually activate the required dragger.
|
|
369
375
|
*
|
|
370
376
|
* Fires:
|
|
371
377
|
*
|
|
378
|
+
* - {@link CancelEvent | cancel}
|
|
379
|
+
* - {@link ClearEvent | clear}
|
|
372
380
|
* - {@link OpenEvent | open}
|
|
373
381
|
* - {@link GeometryStartEvent | geometrystart}
|
|
374
382
|
* - {@link GeometryProgressEvent | geometryprogress}
|
|
@@ -377,23 +385,26 @@ export class Viewer
|
|
|
377
385
|
* - {@link GeometryEndEvent | geometryend}
|
|
378
386
|
* - {@link GeometryErrorEvent | geometryerror}
|
|
379
387
|
*
|
|
380
|
-
* @param file - File to load. Can be
|
|
388
|
+
* @param file - File to load. Can be:
|
|
381
389
|
*
|
|
382
390
|
* - `File`, `Assembly` or `Model` instance from the Open Cloud Server
|
|
383
|
-
* -
|
|
391
|
+
* - `URL` string
|
|
384
392
|
* - {@link https://developer.mozilla.org/docs/Web/HTTP/Basics_of_HTTP/Data_URIs | Data URL} string
|
|
385
393
|
* - {@link https://developer.mozilla.org/docs/Web/API/File | Web API File} object
|
|
386
394
|
* - {@link https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer | ArrayBuffer}
|
|
387
395
|
* object
|
|
388
396
|
*
|
|
389
397
|
* @param params - Loading parameters.
|
|
390
|
-
* @param params.format - File format
|
|
391
|
-
* URL`.
|
|
398
|
+
* @param params.format - File format. Can be `gltf`, `glb` or format from an extension. Required when
|
|
399
|
+
* loading a file as `ArrayBuffer` or `Data URL`.
|
|
392
400
|
* @param params.mode - File opening mode. Can be one of:
|
|
393
401
|
*
|
|
394
|
-
* - `
|
|
395
|
-
* - `
|
|
402
|
+
* - `file` - Single file mode. Unloads an open file and opens a new one. This is default mode.
|
|
403
|
+
* - `assembly` - Assembly mode. Appends a file to an already open file.
|
|
396
404
|
*
|
|
405
|
+
* @param params.modelId - Unique model ID in the assembly (multi-model scene). Used as a model prefix
|
|
406
|
+
* when selecting objects (see {@link getSelected2}). Must not contain the ":" (colon). Required when
|
|
407
|
+
* loading a file as `ArrayBuffer` or `Data URL`.
|
|
397
408
|
* @param params.requestHeader - The
|
|
398
409
|
* {@link https://developer.mozilla.org/docs/Glossary/Request_header | request header} used in HTTP
|
|
399
410
|
* request.
|
|
@@ -415,6 +426,7 @@ export class Viewer
|
|
|
415
426
|
params: {
|
|
416
427
|
format?: string;
|
|
417
428
|
mode?: string;
|
|
429
|
+
modelId?: string;
|
|
418
430
|
requestHeader?: HeadersInit;
|
|
419
431
|
withCredentials?: boolean;
|
|
420
432
|
path?: string;
|
|
@@ -424,22 +436,27 @@ export class Viewer
|
|
|
424
436
|
): Promise<this> {
|
|
425
437
|
if (!this.renderer) return this;
|
|
426
438
|
|
|
427
|
-
|
|
439
|
+
const mode = params.mode || "file";
|
|
440
|
+
|
|
441
|
+
if (mode !== "assembly" && mode !== "a" && mode !== "append") {
|
|
428
442
|
this.cancel();
|
|
429
443
|
this.clear();
|
|
430
444
|
}
|
|
431
445
|
|
|
432
|
-
this.emitEvent({ type: "open", file });
|
|
446
|
+
this.emitEvent({ type: "open", mode, file });
|
|
433
447
|
|
|
434
448
|
let model: any = file;
|
|
435
449
|
if (model && typeof model.getModels === "function") {
|
|
436
450
|
const models = await model.getModels();
|
|
437
451
|
model = models.find((model: Model) => model.default) || models[0] || file;
|
|
438
452
|
}
|
|
453
|
+
if (model && typeof model.database === "string") {
|
|
454
|
+
file = model.file;
|
|
455
|
+
}
|
|
439
456
|
if (!model) throw new Error(`Format not supported`);
|
|
440
457
|
|
|
441
458
|
let format = params.format;
|
|
442
|
-
if (!format && typeof
|
|
459
|
+
if (!format && typeof file["type"] === "string") format = file["type"].split(".").pop();
|
|
443
460
|
if (!format && typeof file === "string") format = file.split(".").pop();
|
|
444
461
|
if (!format && file instanceof globalThis.File) format = file.name.split(".").pop();
|
|
445
462
|
|
|
@@ -483,7 +500,7 @@ export class Viewer
|
|
|
483
500
|
"Viewer.loadGltfFile() has been deprecated since 26.4 and will be removed in a future release, use Viewer.open() instead."
|
|
484
501
|
);
|
|
485
502
|
|
|
486
|
-
return this.open(file, { ...params, format: "gltf", externalFiles, mode: "
|
|
503
|
+
return this.open(file, { ...params, format: "gltf", externalFiles, mode: "assembly" });
|
|
487
504
|
}
|
|
488
505
|
|
|
489
506
|
cancel(): this {
|
|
@@ -510,6 +527,9 @@ export class Viewer
|
|
|
510
527
|
this.scene.clear();
|
|
511
528
|
this.helpers.clear();
|
|
512
529
|
|
|
530
|
+
this.extents.makeEmpty();
|
|
531
|
+
this.target.set(0, 0, 0);
|
|
532
|
+
|
|
513
533
|
this.syncOptions();
|
|
514
534
|
this.syncOverlay();
|
|
515
535
|
this.update(true);
|
|
@@ -519,6 +539,10 @@ export class Viewer
|
|
|
519
539
|
return this;
|
|
520
540
|
}
|
|
521
541
|
|
|
542
|
+
is3D(): boolean {
|
|
543
|
+
return true;
|
|
544
|
+
}
|
|
545
|
+
|
|
522
546
|
syncOptions(options: IOptions = this.options): void {
|
|
523
547
|
if (!this.renderer) return;
|
|
524
548
|
|
|
@@ -557,10 +581,18 @@ export class Viewer
|
|
|
557
581
|
return this.executeCommand("getSelected");
|
|
558
582
|
}
|
|
559
583
|
|
|
584
|
+
getSelected2(): string[] {
|
|
585
|
+
return this.executeCommand("getSelected2");
|
|
586
|
+
}
|
|
587
|
+
|
|
560
588
|
setSelected(handles?: string[]): void {
|
|
561
589
|
this.executeCommand("setSelected", handles);
|
|
562
590
|
}
|
|
563
591
|
|
|
592
|
+
setSelected2(handles?: string[]): void {
|
|
593
|
+
this.executeCommand("setSelected2", handles);
|
|
594
|
+
}
|
|
595
|
+
|
|
564
596
|
clearSelected(): void {
|
|
565
597
|
this.executeCommand("clearSelected");
|
|
566
598
|
}
|
|
@@ -630,44 +662,6 @@ export class Viewer
|
|
|
630
662
|
return this._components.find((component) => component.name === name);
|
|
631
663
|
}
|
|
632
664
|
|
|
633
|
-
is3D(): boolean {
|
|
634
|
-
return true;
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
screenToWorld(position: { x: number; y: number }): { x: number; y: number; z: number } {
|
|
638
|
-
if (!this.renderer) return { x: position.x, y: position.y, z: 0 };
|
|
639
|
-
|
|
640
|
-
const rect = this.canvas.getBoundingClientRect();
|
|
641
|
-
const x = position.x / (rect.width / 2) - 1;
|
|
642
|
-
const y = -position.y / (rect.height / 2) + 1;
|
|
643
|
-
|
|
644
|
-
const point = new Vector3(x, y, -1);
|
|
645
|
-
point.unproject(this.camera);
|
|
646
|
-
|
|
647
|
-
return { x: point.x, y: point.y, z: point.z };
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
worldToScreen(position: { x: number; y: number; z: number }): { x: number; y: number } {
|
|
651
|
-
if (!this.renderer) return { x: position.x, y: position.y };
|
|
652
|
-
|
|
653
|
-
const point = new Vector3(position.x, position.y, position.z);
|
|
654
|
-
point.project(this.camera);
|
|
655
|
-
|
|
656
|
-
const rect = this.canvas.getBoundingClientRect();
|
|
657
|
-
const x = (point.x + 1) * (rect.width / 2);
|
|
658
|
-
const y = (-point.y + 1) * (rect.height / 2);
|
|
659
|
-
|
|
660
|
-
return { x, y };
|
|
661
|
-
}
|
|
662
|
-
|
|
663
|
-
getScale(): { x: number; y: number; z: number } {
|
|
664
|
-
return { x: 1, y: 1, z: 1 };
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
executeCommand(id: string, ...args: any[]): any {
|
|
668
|
-
return commands.executeCommand(id, this, ...args);
|
|
669
|
-
}
|
|
670
|
-
|
|
671
665
|
drawViewpoint(viewpoint: IViewpoint): void {
|
|
672
666
|
if (!this.renderer) return;
|
|
673
667
|
|
|
@@ -731,15 +725,17 @@ export class Viewer
|
|
|
731
725
|
};
|
|
732
726
|
|
|
733
727
|
const setClippingPlanes = (clipping_planes: IClippingPlane[]) => {
|
|
734
|
-
clipping_planes
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
728
|
+
if (clipping_planes) {
|
|
729
|
+
clipping_planes.forEach((clipping_plane) => {
|
|
730
|
+
const plane = new Plane();
|
|
731
|
+
plane.setFromNormalAndCoplanarPoint(
|
|
732
|
+
getVector3FromPoint3d(clipping_plane.direction),
|
|
733
|
+
getVector3FromPoint3d(clipping_plane.location)
|
|
734
|
+
);
|
|
735
|
+
|
|
736
|
+
this.renderer.clippingPlanes.push(plane);
|
|
737
|
+
});
|
|
738
|
+
}
|
|
743
739
|
};
|
|
744
740
|
|
|
745
741
|
const setSelection = (selection: IEntity[]) => {
|
|
@@ -759,10 +755,10 @@ export class Viewer
|
|
|
759
755
|
setOrthogonalCamera(viewpoint.orthogonal_camera);
|
|
760
756
|
setPerspectiveCamera(viewpoint.perspective_camera);
|
|
761
757
|
setClippingPlanes(viewpoint.clipping_planes);
|
|
762
|
-
setSelection(viewpoint.selection);
|
|
758
|
+
setSelection(viewpoint.custom_fields?.selection2 || viewpoint.selection);
|
|
763
759
|
this._markup.setViewpoint(viewpoint);
|
|
764
760
|
|
|
765
|
-
this.target
|
|
761
|
+
this.target.copy(getVector3FromPoint3d(viewpoint.custom_fields?.camera_target ?? this.target));
|
|
766
762
|
|
|
767
763
|
this.setActiveDragger(draggerName);
|
|
768
764
|
this.emitEvent({ type: "drawviewpoint", data: viewpoint });
|
|
@@ -814,6 +810,10 @@ export class Viewer
|
|
|
814
810
|
return this.getSelected().map((handle) => ({ handle }));
|
|
815
811
|
};
|
|
816
812
|
|
|
813
|
+
const getSelection2 = (): IEntity[] => {
|
|
814
|
+
return this.getSelected2().map((handle) => ({ handle }));
|
|
815
|
+
};
|
|
816
|
+
|
|
817
817
|
const viewpoint: IViewpoint = { custom_fields: {} };
|
|
818
818
|
|
|
819
819
|
viewpoint.orthogonal_camera = getOrthogonalCamera();
|
|
@@ -824,9 +824,48 @@ export class Viewer
|
|
|
824
824
|
this._markup.getViewpoint(viewpoint);
|
|
825
825
|
|
|
826
826
|
viewpoint.custom_fields.camera_target = getPoint3dFromVector3(this.target);
|
|
827
|
+
viewpoint.custom_fields.selection2 = getSelection2();
|
|
827
828
|
|
|
828
829
|
this.emitEvent({ type: "createviewpoint", data: viewpoint });
|
|
829
830
|
|
|
830
831
|
return viewpoint;
|
|
831
832
|
}
|
|
833
|
+
|
|
834
|
+
// IWorldTransform
|
|
835
|
+
|
|
836
|
+
screenToWorld(position: { x: number; y: number }): { x: number; y: number; z: number } {
|
|
837
|
+
if (!this.renderer) return { x: position.x, y: position.y, z: 0 };
|
|
838
|
+
|
|
839
|
+
const rect = this.canvas.getBoundingClientRect();
|
|
840
|
+
const x = position.x / (rect.width / 2) - 1;
|
|
841
|
+
const y = -position.y / (rect.height / 2) + 1;
|
|
842
|
+
|
|
843
|
+
const point = new Vector3(x, y, -1);
|
|
844
|
+
point.unproject(this.camera);
|
|
845
|
+
|
|
846
|
+
return { x: point.x, y: point.y, z: point.z };
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
worldToScreen(position: { x: number; y: number; z: number }): { x: number; y: number } {
|
|
850
|
+
if (!this.renderer) return { x: position.x, y: position.y };
|
|
851
|
+
|
|
852
|
+
const point = new Vector3(position.x, position.y, position.z);
|
|
853
|
+
point.project(this.camera);
|
|
854
|
+
|
|
855
|
+
const rect = this.canvas.getBoundingClientRect();
|
|
856
|
+
const x = (point.x + 1) * (rect.width / 2);
|
|
857
|
+
const y = (-point.y + 1) * (rect.height / 2);
|
|
858
|
+
|
|
859
|
+
return { x, y };
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
getScale(): { x: number; y: number; z: number } {
|
|
863
|
+
return { x: 1, y: 1, z: 1 };
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
// ICommandService
|
|
867
|
+
|
|
868
|
+
executeCommand(id: string, ...args: any[]): any {
|
|
869
|
+
return commands.executeCommand(id, this, ...args);
|
|
870
|
+
}
|
|
832
871
|
}
|
|
@@ -29,5 +29,7 @@ export function clearSelected(viewer: Viewer): void {
|
|
|
29
29
|
selection.clearSelection();
|
|
30
30
|
|
|
31
31
|
viewer.update();
|
|
32
|
-
|
|
32
|
+
|
|
33
|
+
viewer.emitEvent({ type: "select", handles: [] });
|
|
34
|
+
viewer.emitEvent({ type: "select2", handles: [] });
|
|
33
35
|
}
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
import type { Viewer } from "../Viewer";
|
|
25
25
|
|
|
26
26
|
export function getSelected(viewer: Viewer): string[] {
|
|
27
|
-
const
|
|
28
|
-
|
|
27
|
+
const handles2 = viewer.executeCommand("getSelected2");
|
|
28
|
+
const handles = handles2.map((handle) => handle.slice(handle.indexOf(":") + 1));
|
|
29
29
|
return handles;
|
|
30
30
|
}
|
|
@@ -21,16 +21,14 @@
|
|
|
21
21
|
// acknowledge and accept the above terms.
|
|
22
22
|
///////////////////////////////////////////////////////////////////////////////
|
|
23
23
|
|
|
24
|
-
import {
|
|
25
|
-
import { PointCloudOctree } from "potree-core";
|
|
26
|
-
import { ModelImpl } from "@inweb/viewer-three";
|
|
24
|
+
import type { Viewer } from "../Viewer";
|
|
27
25
|
|
|
28
|
-
|
|
26
|
+
export function getSelected2(viewer: Viewer): string[] {
|
|
27
|
+
const handles2 = [];
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
viewer.models.forEach((model) => {
|
|
30
|
+
handles2.push(...model.getHandlesByObjects(viewer.selected));
|
|
31
|
+
});
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
return target.union(this.pco.pcoGeometry.boundingBox);
|
|
35
|
-
}
|
|
33
|
+
return handles2;
|
|
36
34
|
}
|
|
@@ -31,6 +31,8 @@ export function hideSelected(viewer: Viewer): void {
|
|
|
31
31
|
selection.clearSelection();
|
|
32
32
|
|
|
33
33
|
viewer.update();
|
|
34
|
+
|
|
34
35
|
viewer.emitEvent({ type: "hide" });
|
|
35
|
-
viewer.emitEvent({ type: "select",
|
|
36
|
+
viewer.emitEvent({ type: "select", handles: [] });
|
|
37
|
+
viewer.emitEvent({ type: "select2", handles: [] });
|
|
36
38
|
}
|
|
@@ -24,14 +24,14 @@
|
|
|
24
24
|
import type { Viewer } from "../Viewer";
|
|
25
25
|
import type { SelectionComponent } from "../components/SelectionComponent";
|
|
26
26
|
|
|
27
|
-
export function selectModel(viewer: Viewer,
|
|
27
|
+
export function selectModel(viewer: Viewer, id: string): void {
|
|
28
28
|
const selection = viewer.getComponent("SelectionComponent") as SelectionComponent;
|
|
29
29
|
selection.clearSelection();
|
|
30
30
|
|
|
31
|
-
viewer.models
|
|
32
|
-
.filter((model) => model.handle === handle)
|
|
33
|
-
.forEach((model) => selection.select(model.getObjects(), model));
|
|
31
|
+
viewer.models.filter((model) => model.id === id).forEach((model) => selection.select(model.getObjects(), model));
|
|
34
32
|
|
|
35
33
|
viewer.update();
|
|
36
|
-
|
|
34
|
+
|
|
35
|
+
viewer.emitEvent({ type: "select", handles: viewer.getSelected() });
|
|
36
|
+
viewer.emitEvent({ type: "select2", handles: viewer.getSelected2() });
|
|
37
37
|
}
|
|
@@ -22,19 +22,18 @@
|
|
|
22
22
|
///////////////////////////////////////////////////////////////////////////////
|
|
23
23
|
|
|
24
24
|
import type { Viewer } from "../Viewer";
|
|
25
|
-
import type { SelectionComponent } from "../components/SelectionComponent";
|
|
26
25
|
|
|
27
26
|
export function setSelected(viewer: Viewer, handles: string[] = []): void {
|
|
28
|
-
const
|
|
29
|
-
selection.clearSelection();
|
|
27
|
+
const handles2 = [];
|
|
30
28
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
handles.forEach((handle) => {
|
|
30
|
+
if (handle.includes(":")) {
|
|
31
|
+
handles2.push(handle);
|
|
32
|
+
} else
|
|
33
|
+
viewer.models.forEach((model) => {
|
|
34
|
+
handles2.push(`${model.id}:${handle}`);
|
|
35
|
+
});
|
|
35
36
|
});
|
|
36
37
|
|
|
37
|
-
viewer.
|
|
38
|
-
viewer.emitEvent({ type: "show" });
|
|
39
|
-
viewer.emitEvent({ type: "select", data: undefined, handles });
|
|
38
|
+
viewer.executeCommand("setSelected2", handles2);
|
|
40
39
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
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 type { Viewer } from "../Viewer";
|
|
25
|
+
import type { SelectionComponent } from "../components/SelectionComponent";
|
|
26
|
+
|
|
27
|
+
export function setSelected2(viewer: Viewer, handles: string[] = []): void {
|
|
28
|
+
const selectionComponent = viewer.getComponent("SelectionComponent") as SelectionComponent;
|
|
29
|
+
selectionComponent.clearSelection();
|
|
30
|
+
|
|
31
|
+
viewer.models.forEach((model) => {
|
|
32
|
+
const objects = model.getObjectsByHandles(handles);
|
|
33
|
+
model.showObjects(objects);
|
|
34
|
+
selectionComponent.select(objects, model);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
viewer.update();
|
|
38
|
+
|
|
39
|
+
viewer.emitEvent({ type: "show" });
|
|
40
|
+
viewer.emitEvent({ type: "select", data: undefined, handles: viewer.getSelected() });
|
|
41
|
+
viewer.emitEvent({ type: "select2", data: undefined, handles });
|
|
42
|
+
}
|
|
@@ -26,13 +26,12 @@ import type { Viewer } from "../Viewer";
|
|
|
26
26
|
import { zoomTo } from "./ZoomTo";
|
|
27
27
|
|
|
28
28
|
export function zoomToObjects(viewer: Viewer, handles: string[] = []): void {
|
|
29
|
-
const
|
|
30
|
-
const objects = [];
|
|
31
|
-
viewer.scene.traverseVisible((child) => {
|
|
32
|
-
if (handleSet.has(child.userData?.handle)) objects.push(child);
|
|
33
|
-
});
|
|
29
|
+
const extents = new Box3();
|
|
34
30
|
|
|
35
|
-
|
|
31
|
+
viewer.models.forEach((model) => {
|
|
32
|
+
const objects = model.getObjectsByHandles(handles);
|
|
33
|
+
objects.forEach((object) => extents.expandByObject(object));
|
|
34
|
+
});
|
|
36
35
|
if (extents.isEmpty()) extents.copy(viewer.extents);
|
|
37
36
|
|
|
38
37
|
zoomTo(viewer, extents);
|
|
@@ -26,7 +26,9 @@ import type { Viewer } from "../Viewer";
|
|
|
26
26
|
import { zoomTo } from "./ZoomTo";
|
|
27
27
|
|
|
28
28
|
export function zoomToSelected(viewer: Viewer): void {
|
|
29
|
-
const extents =
|
|
29
|
+
const extents = new Box3();
|
|
30
|
+
|
|
31
|
+
viewer.selected.forEach((object) => extents.expandByObject(object));
|
|
30
32
|
if (extents.isEmpty()) extents.copy(viewer.extents);
|
|
31
33
|
|
|
32
34
|
zoomTo(viewer, extents);
|
|
@@ -32,6 +32,7 @@ import { explode, collect } from "./Explode";
|
|
|
32
32
|
import { getDefaultViewPositions } from "./GetDefaultViewPositions";
|
|
33
33
|
import { getModels } from "./GetModels";
|
|
34
34
|
import { getSelected } from "./GetSelected";
|
|
35
|
+
import { getSelected2 } from "./GetSelected2";
|
|
35
36
|
import { hideSelected } from "./HideSelected";
|
|
36
37
|
import { isolateSelected } from "./IsolateSelected";
|
|
37
38
|
import { regenerateAll } from "./RegenerateAll";
|
|
@@ -41,6 +42,7 @@ import { setActiveDragger } from "./SetActiveDragger";
|
|
|
41
42
|
import { setDefaultViewPosition } from "./SetDefaultViewPosition";
|
|
42
43
|
import { setMarkupColor } from "./SetMarkupColor";
|
|
43
44
|
import { setSelected } from "./SetSelected";
|
|
45
|
+
import { setSelected2 } from "./SetSelected2";
|
|
44
46
|
import { showAll } from "./ShowAll";
|
|
45
47
|
import { zoomToExtents } from "./ZoomToExtents";
|
|
46
48
|
import { zoomToObjects } from "./ZoomToObjects";
|
|
@@ -86,6 +88,7 @@ commands.registerCommand("explode", explode);
|
|
|
86
88
|
commands.registerCommand("getDefaultViewPositions", getDefaultViewPositions);
|
|
87
89
|
commands.registerCommand("getModels", getModels);
|
|
88
90
|
commands.registerCommand("getSelected", getSelected);
|
|
91
|
+
commands.registerCommand("getSelected2", getSelected2);
|
|
89
92
|
commands.registerCommand("hideSelected", hideSelected);
|
|
90
93
|
commands.registerCommand("isolateSelected", isolateSelected);
|
|
91
94
|
commands.registerCommand("regenerateAll", regenerateAll);
|
|
@@ -95,6 +98,7 @@ commands.registerCommand("setActiveDragger", setActiveDragger);
|
|
|
95
98
|
commands.registerCommand("setDefaultViewPosition", setDefaultViewPosition);
|
|
96
99
|
commands.registerCommand("setMarkupColor", setMarkupColor);
|
|
97
100
|
commands.registerCommand("setSelected", setSelected);
|
|
101
|
+
commands.registerCommand("setSelected2", setSelected2);
|
|
98
102
|
commands.registerCommand("showAll", showAll);
|
|
99
103
|
commands.registerCommand("zoomToExtents", zoomToExtents);
|
|
100
104
|
commands.registerCommand("zoomToObjects", zoomToObjects);
|
|
@@ -119,9 +119,14 @@ export class CameraComponent implements IComponent {
|
|
|
119
119
|
};
|
|
120
120
|
|
|
121
121
|
geometryEnd = () => {
|
|
122
|
+
// do not change the camera after opening the second file in assembly
|
|
123
|
+
if (this.viewer.models.length > 1) {
|
|
124
|
+
this.switchCamera(this.viewer.camera);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
|
|
122
128
|
let camera: any;
|
|
123
129
|
|
|
124
|
-
// TODO: do not change the camera and target after opening the second model in "append" mode
|
|
125
130
|
this.viewer.scene.traverse((object: any) => {
|
|
126
131
|
if (object.isCamera)
|
|
127
132
|
if (!camera) camera = object;
|