@inweb/viewer-three 25.10.1 → 25.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/viewer-three.js +14517 -1292
- package/dist/viewer-three.js.map +1 -1
- package/dist/viewer-three.min.js +2 -2
- package/dist/viewer-three.module.js +2980 -260
- package/dist/viewer-three.module.js.map +1 -1
- package/lib/Viewer/Viewer.d.ts +41 -3
- package/lib/Viewer/commands/index.d.ts +1 -1
- package/lib/Viewer/components/SelectionComponent.d.ts +2 -2
- package/lib/Viewer/draggers/OrbitDragger.d.ts +1 -1
- package/package.json +5 -4
- package/src/Viewer/Viewer.ts +212 -21
- package/src/Viewer/commands/ClearMarkup.ts +1 -2
- package/src/Viewer/commands/{Unselect.ts → ClearSelected.ts} +4 -3
- package/src/Viewer/commands/ClearSlices.ts +1 -6
- package/src/Viewer/commands/Explode.ts +1 -1
- package/src/Viewer/commands/HideSelected.ts +2 -2
- package/src/Viewer/commands/IsolateSelected.ts +1 -1
- package/src/Viewer/commands/ResetView.ts +2 -2
- package/src/Viewer/commands/SetDefaultViewPosition.ts +8 -7
- package/src/Viewer/commands/SetSelected.ts +1 -1
- package/src/Viewer/commands/ShowAll.ts +1 -1
- package/src/Viewer/commands/index.ts +1 -1
- package/src/Viewer/components/DefaultPositionComponent.ts +1 -1
- package/src/Viewer/components/SelectionComponent.ts +9 -10
- package/src/Viewer/controls/OrbitControls.js +1007 -0
- package/src/Viewer/controls/WalkControls.ts +1 -0
- package/src/Viewer/draggers/OrbitDragger.ts +28 -4
- /package/lib/Viewer/commands/{Unselect.d.ts → ClearSelected.d.ts} +0 -0
package/lib/Viewer/Viewer.d.ts
CHANGED
|
@@ -3,10 +3,11 @@ import { GLTF } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
|
3
3
|
import { EventEmitter2 } from "@inweb/eventemitter2";
|
|
4
4
|
import { Assembly, Client, Model, File } from "@inweb/client";
|
|
5
5
|
import { CanvasEventMap, IDragger, IOptions, IViewer, IViewpoint, Options, OptionsEventMap, ViewerEventMap } from "@inweb/viewer-core";
|
|
6
|
+
import { IMarkup, IWorldTransform } from "@inweb/markup";
|
|
6
7
|
/**
|
|
7
8
|
* 3D viewer powered by {@link https://threejs.org/ | Three.js}.
|
|
8
9
|
*/
|
|
9
|
-
export declare class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMap & OptionsEventMap> implements IViewer {
|
|
10
|
+
export declare class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMap & OptionsEventMap> implements IViewer, IWorldTransform {
|
|
10
11
|
client: Client | undefined;
|
|
11
12
|
protected _options: Options;
|
|
12
13
|
private canvaseventlistener;
|
|
@@ -25,6 +26,7 @@ export declare class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMa
|
|
|
25
26
|
private components;
|
|
26
27
|
private renderNeeded;
|
|
27
28
|
private renderTime;
|
|
29
|
+
private _markup;
|
|
28
30
|
/**
|
|
29
31
|
* @param client - The `Client` instance that is used to load model reference files from the
|
|
30
32
|
* Open Cloud Server. Do not specify `Client` if you need a standalone viewer instance to
|
|
@@ -33,6 +35,12 @@ export declare class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMa
|
|
|
33
35
|
constructor(client?: Client);
|
|
34
36
|
get options(): IOptions;
|
|
35
37
|
get draggers(): string[];
|
|
38
|
+
/**
|
|
39
|
+
* 2D markup core instance used to create markups.
|
|
40
|
+
*
|
|
41
|
+
* @readonly
|
|
42
|
+
*/
|
|
43
|
+
get markup(): IMarkup;
|
|
36
44
|
initialize(canvas: HTMLCanvasElement, onProgress?: (event: ProgressEvent<EventTarget>) => void): Promise<this>;
|
|
37
45
|
dispose(): this;
|
|
38
46
|
isInitialized(): boolean;
|
|
@@ -140,12 +148,42 @@ export declare class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMa
|
|
|
140
148
|
withCredentials?: boolean;
|
|
141
149
|
}): Promise<this>;
|
|
142
150
|
clear(): this;
|
|
151
|
+
syncOverlay(): void;
|
|
152
|
+
clearOverlay(): void;
|
|
153
|
+
clearSlices(): void;
|
|
154
|
+
getSelected(): string[];
|
|
155
|
+
setSelected(handles?: string[]): void;
|
|
156
|
+
clearSelected(): void;
|
|
157
|
+
hideSelected(): void;
|
|
158
|
+
isolateSelected(): void;
|
|
159
|
+
showAll(): void;
|
|
160
|
+
explode(index?: number): void;
|
|
161
|
+
collect(): void;
|
|
143
162
|
activeDragger(): IDragger | null;
|
|
144
163
|
setActiveDragger(name?: string): IDragger | null;
|
|
145
164
|
resetActiveDragger(): void;
|
|
146
165
|
is3D(): boolean;
|
|
147
|
-
|
|
148
|
-
|
|
166
|
+
screenToWorld(position: {
|
|
167
|
+
x: number;
|
|
168
|
+
y: number;
|
|
169
|
+
}): {
|
|
170
|
+
x: number;
|
|
171
|
+
y: number;
|
|
172
|
+
z: number;
|
|
173
|
+
};
|
|
174
|
+
worldToScreen(position: {
|
|
175
|
+
x: number;
|
|
176
|
+
y: number;
|
|
177
|
+
z: number;
|
|
178
|
+
}): {
|
|
179
|
+
x: number;
|
|
180
|
+
y: number;
|
|
181
|
+
};
|
|
182
|
+
getScale(): {
|
|
183
|
+
x: number;
|
|
184
|
+
y: number;
|
|
185
|
+
z: number;
|
|
186
|
+
};
|
|
149
187
|
executeCommand(id: string, ...args: any[]): any;
|
|
150
188
|
getComponent(type: any): any;
|
|
151
189
|
drawViewpoint(viewpoint: IViewpoint): void;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import "./ApplyModelTransform";
|
|
2
2
|
import "./ClearMarkup";
|
|
3
|
+
import "./ClearSelected";
|
|
3
4
|
import "./ClearSlices";
|
|
4
5
|
import "./CreatePreview";
|
|
5
6
|
import "./Explode";
|
|
@@ -16,7 +17,6 @@ import "./SetDefaultViewPosition";
|
|
|
16
17
|
import "./SetMarkupColor";
|
|
17
18
|
import "./SetSelected";
|
|
18
19
|
import "./ShowAll";
|
|
19
|
-
import "./Unselect";
|
|
20
20
|
import "./ZoomToExtents";
|
|
21
21
|
import "./ZoomToObjects";
|
|
22
22
|
import "./ZoomToSelected";
|
|
@@ -11,8 +11,8 @@ export declare class SelectionComponent implements IDisposable {
|
|
|
11
11
|
onPointerDown: (event: PointerEvent) => void;
|
|
12
12
|
onPointerUp: (event: PointerEvent) => void;
|
|
13
13
|
onDoubleClick: (event: MouseEvent) => void;
|
|
14
|
-
getMousePosition(event: MouseEvent,
|
|
15
|
-
getPointerIntersects(
|
|
14
|
+
getMousePosition(event: MouseEvent, target: Vector2): Vector2;
|
|
15
|
+
getPointerIntersects(mouse: Vector2): Array<Intersection<Object3D>>;
|
|
16
16
|
select(object: any): void;
|
|
17
17
|
clearSelection(): void;
|
|
18
18
|
optionsChange: () => void;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
|
|
2
1
|
import type { IDisposable } from "../IDisposable";
|
|
3
2
|
import type { Viewer } from "../Viewer";
|
|
3
|
+
import { OrbitControls } from "../controls/OrbitControls.js";
|
|
4
4
|
export declare class OrbitDragger implements IDisposable {
|
|
5
5
|
protected viewer: Viewer;
|
|
6
6
|
protected orbit: OrbitControls;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inweb/viewer-three",
|
|
3
|
-
"version": "25.
|
|
3
|
+
"version": "25.11.1",
|
|
4
4
|
"description": "JavaScript library for rendering CAD and BIM files in a browser using Three.js",
|
|
5
5
|
"homepage": "https://cloud.opendesign.com/docs/index.html",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -28,9 +28,10 @@
|
|
|
28
28
|
"docs": "typedoc"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@inweb/client": "~25.
|
|
32
|
-
"@inweb/eventemitter2": "~25.
|
|
33
|
-
"@inweb/
|
|
31
|
+
"@inweb/client": "~25.11.1",
|
|
32
|
+
"@inweb/eventemitter2": "~25.11.1",
|
|
33
|
+
"@inweb/markup": "~25.11.1",
|
|
34
|
+
"@inweb/viewer-core": "~25.11.1"
|
|
34
35
|
},
|
|
35
36
|
"devDependencies": {
|
|
36
37
|
"@types/three": "^0.152.1",
|
package/src/Viewer/Viewer.ts
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
// acknowledge and accept the above terms.
|
|
22
22
|
///////////////////////////////////////////////////////////////////////////////
|
|
23
23
|
|
|
24
|
-
import { Box3, LinearToneMapping, Object3D, PerspectiveCamera, Scene, Vector3, WebGLRenderer } from "three";
|
|
24
|
+
import { Box3, LinearToneMapping, Object3D, PerspectiveCamera, Plane, Scene, Vector3, WebGLRenderer } from "three";
|
|
25
25
|
import { GLTF, GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
26
26
|
import { GLTFLoadingManager } from "./loaders/GLTFLoadingManager";
|
|
27
27
|
|
|
@@ -31,14 +31,19 @@ import {
|
|
|
31
31
|
CANVAS_EVENTS,
|
|
32
32
|
CanvasEventMap,
|
|
33
33
|
commands,
|
|
34
|
+
IClippingPlane,
|
|
35
|
+
IComponent,
|
|
34
36
|
IDragger,
|
|
35
37
|
IOptions,
|
|
38
|
+
IPerspectiveCamera,
|
|
39
|
+
IPoint,
|
|
36
40
|
IViewer,
|
|
37
41
|
IViewpoint,
|
|
38
42
|
Options,
|
|
39
43
|
OptionsEventMap,
|
|
40
44
|
ViewerEventMap,
|
|
41
45
|
} from "@inweb/viewer-core";
|
|
46
|
+
import { IMarkup, IWorldTransform, Markup } from "@inweb/markup";
|
|
42
47
|
|
|
43
48
|
import { PanDragger } from "./draggers/PanDragger";
|
|
44
49
|
import { OrbitDragger } from "./draggers/OrbitDragger";
|
|
@@ -64,7 +69,10 @@ import { WCSHelperComponent } from "./components/WCSHelperComponent";
|
|
|
64
69
|
/**
|
|
65
70
|
* 3D viewer powered by {@link https://threejs.org/ | Three.js}.
|
|
66
71
|
*/
|
|
67
|
-
export class Viewer
|
|
72
|
+
export class Viewer
|
|
73
|
+
extends EventEmitter2<ViewerEventMap & CanvasEventMap & OptionsEventMap>
|
|
74
|
+
implements IViewer, IWorldTransform
|
|
75
|
+
{
|
|
68
76
|
public client: Client | undefined;
|
|
69
77
|
protected _options: Options;
|
|
70
78
|
|
|
@@ -90,6 +98,8 @@ export class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMap & Opti
|
|
|
90
98
|
private renderNeeded: boolean;
|
|
91
99
|
private renderTime: DOMHighResTimeStamp;
|
|
92
100
|
|
|
101
|
+
private _markup: IMarkup;
|
|
102
|
+
|
|
93
103
|
/**
|
|
94
104
|
* @param client - The `Client` instance that is used to load model reference files from the
|
|
95
105
|
* Open Cloud Server. Do not specify `Client` if you need a standalone viewer instance to
|
|
@@ -126,6 +136,8 @@ export class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMap & Opti
|
|
|
126
136
|
|
|
127
137
|
this.render = this.render.bind(this);
|
|
128
138
|
this.update = this.update.bind(this);
|
|
139
|
+
|
|
140
|
+
this._markup = new Markup();
|
|
129
141
|
}
|
|
130
142
|
|
|
131
143
|
get options(): IOptions {
|
|
@@ -136,6 +148,15 @@ export class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMap & Opti
|
|
|
136
148
|
return Object.keys(this.draggerFactory);
|
|
137
149
|
}
|
|
138
150
|
|
|
151
|
+
/**
|
|
152
|
+
* 2D markup core instance used to create markups.
|
|
153
|
+
*
|
|
154
|
+
* @readonly
|
|
155
|
+
*/
|
|
156
|
+
get markup(): IMarkup {
|
|
157
|
+
return this._markup;
|
|
158
|
+
}
|
|
159
|
+
|
|
139
160
|
initialize(canvas: HTMLCanvasElement, onProgress?: (event: ProgressEvent<EventTarget>) => void): Promise<this> {
|
|
140
161
|
this.addEventListener("optionschange", (event) => this.syncOptions(event.data));
|
|
141
162
|
|
|
@@ -156,6 +177,8 @@ export class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMap & Opti
|
|
|
156
177
|
this.canvas = canvas;
|
|
157
178
|
this.canvasEvents.forEach((x) => canvas.addEventListener(x, this.canvaseventlistener));
|
|
158
179
|
|
|
180
|
+
this._markup.initialize(this.canvas, this.canvasEvents, this, this);
|
|
181
|
+
|
|
159
182
|
this.components.push(new ExtentsComponent(this));
|
|
160
183
|
this.components.push(new LightComponent(this));
|
|
161
184
|
this.components.push(new BackgroundComponent(this));
|
|
@@ -169,6 +192,7 @@ export class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMap & Opti
|
|
|
169
192
|
// this.components.push(new ExtentsHelperComponent(this));
|
|
170
193
|
|
|
171
194
|
this.syncOptions();
|
|
195
|
+
this.syncOverlay();
|
|
172
196
|
|
|
173
197
|
this.renderTime = performance.now();
|
|
174
198
|
this.render(this.renderTime);
|
|
@@ -189,11 +213,13 @@ export class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMap & Opti
|
|
|
189
213
|
this.components.forEach((component: IDisposable) => component.dispose());
|
|
190
214
|
this.components = [];
|
|
191
215
|
|
|
192
|
-
this.setActiveDragger(
|
|
216
|
+
this.setActiveDragger();
|
|
193
217
|
this.removeAllListeners();
|
|
194
218
|
|
|
195
219
|
this.clear();
|
|
196
220
|
|
|
221
|
+
this._markup.dispose();
|
|
222
|
+
|
|
197
223
|
if (this.canvas) {
|
|
198
224
|
this.canvasEvents.forEach((x) => this.canvas.removeEventListener(x, this.canvaseventlistener));
|
|
199
225
|
this.canvas = undefined;
|
|
@@ -217,23 +243,21 @@ export class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMap & Opti
|
|
|
217
243
|
if (!this.renderNeeded) return;
|
|
218
244
|
if (!this.renderer) return;
|
|
219
245
|
|
|
220
|
-
|
|
246
|
+
this.renderNeeded = false;
|
|
221
247
|
|
|
222
248
|
this.renderer.setViewport(0, 0, this.canvas.offsetWidth, this.canvas.offsetHeight);
|
|
249
|
+
this.renderer.autoClear = true;
|
|
223
250
|
this.renderer.render(this.scene, this.camera);
|
|
224
251
|
|
|
252
|
+
const clippingPlanes = this.renderer.clippingPlanes;
|
|
225
253
|
this.renderer.clippingPlanes = [];
|
|
226
254
|
this.renderer.autoClear = false;
|
|
227
255
|
this.renderer.render(this.helpers, this.camera);
|
|
256
|
+
this.renderer.clippingPlanes = clippingPlanes;
|
|
228
257
|
|
|
229
258
|
const deltaTime = (time - this.renderTime) / 1000;
|
|
230
259
|
this.renderTime = time;
|
|
231
260
|
this.emitEvent({ type: "render", time, deltaTime });
|
|
232
|
-
|
|
233
|
-
this.renderer.autoClear = true;
|
|
234
|
-
this.renderer.clippingPlanes = clippingPlanes;
|
|
235
|
-
|
|
236
|
-
this.renderNeeded = false;
|
|
237
261
|
}
|
|
238
262
|
|
|
239
263
|
public update(force = false): void {
|
|
@@ -420,8 +444,9 @@ export class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMap & Opti
|
|
|
420
444
|
this.models.push(gltf);
|
|
421
445
|
this.scene.add(gltf.scene);
|
|
422
446
|
|
|
447
|
+
this.syncOptions();
|
|
448
|
+
this.syncOverlay();
|
|
423
449
|
this.update();
|
|
424
|
-
this.resetActiveDragger();
|
|
425
450
|
|
|
426
451
|
this.emitEvent({ type: "databasechunk" });
|
|
427
452
|
this.emitEvent({ type: "geometryend", data: gltf.scene });
|
|
@@ -452,9 +477,8 @@ export class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMap & Opti
|
|
|
452
477
|
}
|
|
453
478
|
|
|
454
479
|
this.setActiveDragger();
|
|
455
|
-
|
|
456
|
-
this.
|
|
457
|
-
this.renderer.clippingPlanes = [];
|
|
480
|
+
this.clearSlices();
|
|
481
|
+
this.clearOverlay();
|
|
458
482
|
|
|
459
483
|
this.helpers.traverse(disposeObject);
|
|
460
484
|
this.helpers.clear();
|
|
@@ -465,12 +489,68 @@ export class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMap & Opti
|
|
|
465
489
|
|
|
466
490
|
this.scene.clear();
|
|
467
491
|
|
|
468
|
-
this.
|
|
492
|
+
this.syncOptions();
|
|
493
|
+
this.syncOverlay();
|
|
469
494
|
this.update(true);
|
|
470
495
|
|
|
496
|
+
this.emitEvent({ type: "clear" });
|
|
497
|
+
|
|
471
498
|
return this;
|
|
472
499
|
}
|
|
473
500
|
|
|
501
|
+
syncOverlay(): void {
|
|
502
|
+
if (!this.renderer) return;
|
|
503
|
+
|
|
504
|
+
this._markup.syncOverlay();
|
|
505
|
+
this.update();
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
clearOverlay(): void {
|
|
509
|
+
if (!this.renderer) return;
|
|
510
|
+
|
|
511
|
+
this._markup.clearOverlay();
|
|
512
|
+
this.update();
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
clearSlices(): void {
|
|
516
|
+
if (!this.renderer) return;
|
|
517
|
+
|
|
518
|
+
this.renderer.clippingPlanes = [];
|
|
519
|
+
this.update();
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
getSelected(): string[] {
|
|
523
|
+
return this.executeCommand("getSelected");
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
setSelected(handles?: string[]): void {
|
|
527
|
+
this.executeCommand("setSelected", handles);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
clearSelected(): void {
|
|
531
|
+
this.executeCommand("clearSelected");
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
hideSelected(): void {
|
|
535
|
+
this.executeCommand("hideSelected");
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
isolateSelected(): void {
|
|
539
|
+
this.executeCommand("isolateSelected");
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
showAll(): void {
|
|
543
|
+
this.executeCommand("showAll");
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
explode(index = 0): void {
|
|
547
|
+
this.executeCommand("explode", index);
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
collect(): void {
|
|
551
|
+
this.executeCommand("collect");
|
|
552
|
+
}
|
|
553
|
+
|
|
474
554
|
activeDragger(): IDragger | null {
|
|
475
555
|
return this._activeDragger;
|
|
476
556
|
}
|
|
@@ -498,6 +578,7 @@ export class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMap & Opti
|
|
|
498
578
|
.join(" ");
|
|
499
579
|
}
|
|
500
580
|
this.emitEvent({ type: "changeactivedragger", data: name });
|
|
581
|
+
this.update();
|
|
501
582
|
}
|
|
502
583
|
return this._activeDragger;
|
|
503
584
|
}
|
|
@@ -514,12 +595,34 @@ export class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMap & Opti
|
|
|
514
595
|
return true;
|
|
515
596
|
}
|
|
516
597
|
|
|
517
|
-
|
|
518
|
-
|
|
598
|
+
screenToWorld(position: { x: number; y: number }): { x: number; y: number; z: number } {
|
|
599
|
+
if (!this.renderer) return { x: position.x, y: position.y, z: 0 };
|
|
600
|
+
|
|
601
|
+
const rect = this.canvas.getBoundingClientRect();
|
|
602
|
+
const x = position.x / (rect.width / 2) - 1;
|
|
603
|
+
const y = -position.y / (rect.height / 2) + 1;
|
|
604
|
+
|
|
605
|
+
const point = new Vector3(x, y, -1);
|
|
606
|
+
point.unproject(this.camera);
|
|
607
|
+
|
|
608
|
+
return { x: point.x, y: point.y, z: point.z };
|
|
519
609
|
}
|
|
520
610
|
|
|
521
|
-
|
|
522
|
-
this.
|
|
611
|
+
worldToScreen(position: { x: number; y: number; z: number }): { x: number; y: number } {
|
|
612
|
+
if (!this.renderer) return { x: position.x, y: position.y };
|
|
613
|
+
|
|
614
|
+
const point = new Vector3(position.x, position.y, position.z);
|
|
615
|
+
point.project(this.camera);
|
|
616
|
+
|
|
617
|
+
const rect = this.canvas.getBoundingClientRect();
|
|
618
|
+
const x = (point.x + 1) * (rect.width / 2);
|
|
619
|
+
const y = (-point.y + 1) * (rect.height / 2);
|
|
620
|
+
|
|
621
|
+
return { x, y };
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
getScale(): { x: number; y: number; z: number } {
|
|
625
|
+
return { x: 1, y: 1, z: 1 };
|
|
523
626
|
}
|
|
524
627
|
|
|
525
628
|
executeCommand(id: string, ...args: any[]): any {
|
|
@@ -530,13 +633,101 @@ export class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMap & Opti
|
|
|
530
633
|
return this.components.find((component) => component instanceof type);
|
|
531
634
|
}
|
|
532
635
|
|
|
533
|
-
drawViewpoint(viewpoint: IViewpoint): void {
|
|
636
|
+
drawViewpoint(viewpoint: IViewpoint): void {
|
|
637
|
+
if (!this.renderer) return;
|
|
638
|
+
|
|
639
|
+
const getVector3FromPoint3d = ({ x, y, z }): Vector3 => new Vector3(x, y, z);
|
|
640
|
+
|
|
641
|
+
const setPerspectiveCamera = (camera: IPerspectiveCamera) => {
|
|
642
|
+
if (camera) {
|
|
643
|
+
this.camera.up.copy(getVector3FromPoint3d(camera.up_vector));
|
|
644
|
+
this.camera.fov = camera.field_of_view;
|
|
645
|
+
this.camera.position.copy(getVector3FromPoint3d(camera.view_point));
|
|
646
|
+
this.camera.lookAt(getVector3FromPoint3d(camera.direction).add(this.camera.position));
|
|
647
|
+
this.camera.updateMatrixWorld();
|
|
648
|
+
this.camera.updateProjectionMatrix();
|
|
649
|
+
}
|
|
650
|
+
};
|
|
651
|
+
|
|
652
|
+
const setClippingPlanes = (clipping_planes: IClippingPlane[]) => {
|
|
653
|
+
clipping_planes?.forEach((clipping_plane) => {
|
|
654
|
+
const plane = new Plane();
|
|
655
|
+
plane.setFromNormalAndCoplanarPoint(
|
|
656
|
+
getVector3FromPoint3d(clipping_plane.direction),
|
|
657
|
+
getVector3FromPoint3d(clipping_plane.location)
|
|
658
|
+
);
|
|
659
|
+
|
|
660
|
+
this.renderer.clippingPlanes.push(plane);
|
|
661
|
+
});
|
|
662
|
+
};
|
|
663
|
+
|
|
664
|
+
const setSelection = (selection: IComponent[]) => {
|
|
665
|
+
this.setSelected(selection?.map((component) => component.handle));
|
|
666
|
+
};
|
|
667
|
+
|
|
668
|
+
const draggerName = this._activeDragger?.name;
|
|
669
|
+
|
|
670
|
+
this.setActiveDragger();
|
|
671
|
+
this.clearSlices();
|
|
672
|
+
this.clearOverlay();
|
|
673
|
+
|
|
674
|
+
this.clearSelected();
|
|
675
|
+
this.showAll();
|
|
676
|
+
this.explode();
|
|
677
|
+
|
|
678
|
+
setPerspectiveCamera(viewpoint.perspective_camera);
|
|
679
|
+
setClippingPlanes(viewpoint.clipping_planes);
|
|
680
|
+
setSelection(viewpoint.selection);
|
|
681
|
+
this._markup.setViewpoint(viewpoint);
|
|
682
|
+
|
|
683
|
+
this.target = getVector3FromPoint3d(viewpoint.custom_fields?.camera_target ?? this.target);
|
|
684
|
+
|
|
685
|
+
this.setActiveDragger(draggerName);
|
|
686
|
+
this.emitEvent({ type: "drawviewpoint", data: viewpoint });
|
|
687
|
+
this.update();
|
|
688
|
+
}
|
|
534
689
|
|
|
535
690
|
createViewpoint(): IViewpoint {
|
|
536
|
-
|
|
691
|
+
if (!this.renderer) return {};
|
|
692
|
+
|
|
693
|
+
const getPoint3dFromVector3 = ({ x, y, z }): IPoint => ({ x, y, z });
|
|
694
|
+
|
|
695
|
+
const getPerspectiveCamera = (): IPerspectiveCamera => {
|
|
696
|
+
return {
|
|
697
|
+
view_point: getPoint3dFromVector3(this.camera.position),
|
|
698
|
+
direction: getPoint3dFromVector3(this.camera.getWorldDirection(new Vector3())),
|
|
699
|
+
up_vector: getPoint3dFromVector3(this.camera.up),
|
|
700
|
+
field_of_view: this.camera.fov,
|
|
701
|
+
};
|
|
702
|
+
};
|
|
703
|
+
|
|
704
|
+
const getClippingPlanes = (): IClippingPlane[] => {
|
|
705
|
+
const clipping_planes = [];
|
|
706
|
+
this.renderer.clippingPlanes.forEach((plane: Plane) => {
|
|
707
|
+
const clipping_plane = {
|
|
708
|
+
location: getPoint3dFromVector3(plane.coplanarPoint(new Vector3())),
|
|
709
|
+
direction: getPoint3dFromVector3(plane.normal),
|
|
710
|
+
};
|
|
711
|
+
clipping_planes.push(clipping_plane);
|
|
712
|
+
});
|
|
713
|
+
return clipping_planes;
|
|
714
|
+
};
|
|
715
|
+
|
|
716
|
+
const getSelection = (): IComponent[] => {
|
|
717
|
+
return this.getSelected().map((handle) => ({ handle }));
|
|
718
|
+
};
|
|
537
719
|
|
|
538
|
-
viewpoint
|
|
720
|
+
const viewpoint: IViewpoint = { custom_fields: {} };
|
|
721
|
+
|
|
722
|
+
viewpoint.perspective_camera = getPerspectiveCamera();
|
|
723
|
+
viewpoint.clipping_planes = getClippingPlanes();
|
|
724
|
+
viewpoint.selection = getSelection();
|
|
539
725
|
viewpoint.description = new Date().toDateString();
|
|
726
|
+
this._markup.getViewpoint(viewpoint);
|
|
727
|
+
|
|
728
|
+
viewpoint.custom_fields.camera_target = getPoint3dFromVector3(this.target);
|
|
729
|
+
|
|
730
|
+
this.emitEvent({ type: "createviewpoint", data: viewpoint });
|
|
540
731
|
|
|
541
732
|
return viewpoint;
|
|
542
733
|
}
|
|
@@ -24,6 +24,5 @@
|
|
|
24
24
|
import { commands } from "@inweb/viewer-core";
|
|
25
25
|
import type { Viewer } from "../Viewer";
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
commands("ThreeJS").registerCommand("clearMarkup", (viewer: Viewer) => console.warn("clearMarkup not implemented"));
|
|
27
|
+
commands("ThreeJS").registerCommand("clearMarkup", (viewer: Viewer) => viewer.clearOverlay());
|
|
29
28
|
commands("ThreeJS").registerCommandAlias("clearMarkup", "clearOverlay");
|
|
@@ -25,13 +25,14 @@ import { commands } from "@inweb/viewer-core";
|
|
|
25
25
|
import type { Viewer } from "../Viewer";
|
|
26
26
|
import { SelectionComponent } from "../components/SelectionComponent";
|
|
27
27
|
|
|
28
|
-
function
|
|
28
|
+
function clearSelected(viewer: Viewer): void {
|
|
29
29
|
const selection = new SelectionComponent(viewer);
|
|
30
30
|
selection.clearSelection();
|
|
31
31
|
selection.dispose();
|
|
32
32
|
|
|
33
33
|
viewer.update();
|
|
34
|
-
viewer.
|
|
34
|
+
viewer.emitEvent({ type: "select", data: undefined, handles: [] });
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
commands("ThreeJS").registerCommand("
|
|
37
|
+
commands("ThreeJS").registerCommand("clearSelected", clearSelected);
|
|
38
|
+
commands("ThreeJS").registerCommandAlias("clearSelected", "unselect");
|
|
@@ -24,9 +24,4 @@
|
|
|
24
24
|
import { commands } from "@inweb/viewer-core";
|
|
25
25
|
import type { Viewer } from "../Viewer";
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
viewer.renderer.clippingPlanes = [];
|
|
29
|
-
viewer.update();
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
commands("ThreeJS").registerCommand("clearSlices", clearSlices);
|
|
27
|
+
commands("ThreeJS").registerCommand("clearSlices", (viewer: Viewer) => viewer.clearSlices());
|
|
@@ -76,7 +76,7 @@ function explode(viewer: Viewer, index = 0): void {
|
|
|
76
76
|
viewer.models.forEach((gltf) => explodeScene(gltf.scene, index));
|
|
77
77
|
|
|
78
78
|
viewer.update();
|
|
79
|
-
viewer.
|
|
79
|
+
viewer.emitEvent({ type: "explode", data: index });
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
commands("ThreeJS").registerCommand("explode", explode);
|
|
@@ -33,8 +33,8 @@ function hideSelected(viewer: Viewer): void {
|
|
|
33
33
|
selection.dispose();
|
|
34
34
|
|
|
35
35
|
viewer.update();
|
|
36
|
-
viewer.
|
|
37
|
-
viewer.
|
|
36
|
+
viewer.emitEvent({ type: "hide" });
|
|
37
|
+
viewer.emitEvent({ type: "select", data: undefined, handles: [] });
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
commands("ThreeJS").registerCommand("hideSelected", hideSelected);
|
|
@@ -44,7 +44,7 @@ function isolateSelected(viewer: Viewer): void {
|
|
|
44
44
|
isolateObject(viewer.scene, 0);
|
|
45
45
|
|
|
46
46
|
viewer.update();
|
|
47
|
-
viewer.
|
|
47
|
+
viewer.emitEvent({ type: "isolate" });
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
commands("ThreeJS").registerCommand("isolateSelected", isolateSelected);
|
|
@@ -25,11 +25,11 @@ import { commands } from "@inweb/viewer-core";
|
|
|
25
25
|
import type { Viewer } from "../Viewer";
|
|
26
26
|
|
|
27
27
|
function resetView(viewer: Viewer): void {
|
|
28
|
-
viewer.executeCommand("setActiveDragger"
|
|
28
|
+
viewer.executeCommand("setActiveDragger");
|
|
29
29
|
viewer.executeCommand("clearSlices");
|
|
30
30
|
viewer.executeCommand("clearOverlay");
|
|
31
31
|
viewer.executeCommand("setMarkupColor");
|
|
32
|
-
viewer.executeCommand("
|
|
32
|
+
viewer.executeCommand("clearSelected");
|
|
33
33
|
viewer.executeCommand("showAll");
|
|
34
34
|
viewer.executeCommand("explode", 0);
|
|
35
35
|
viewer.executeCommand("zoomToExtents", true);
|
|
@@ -31,8 +31,8 @@ export const defaultViewPositions = {
|
|
|
31
31
|
bottom: new Vector3(0, 0, -1),
|
|
32
32
|
left: new Vector3(-1, 0, 0),
|
|
33
33
|
right: new Vector3(1, 0, 0),
|
|
34
|
-
front: new Vector3(0, 1, 0),
|
|
35
|
-
back: new Vector3(0,
|
|
34
|
+
front: new Vector3(0, -1, 0),
|
|
35
|
+
back: new Vector3(0, 1, 0),
|
|
36
36
|
sw: new Vector3(-0.5, -0.5, 1.0).normalize(),
|
|
37
37
|
se: new Vector3(0.5, -0.5, 1.0).normalize(),
|
|
38
38
|
ne: new Vector3(0.5, 0.5, 1.0).normalize(),
|
|
@@ -42,16 +42,17 @@ export const defaultViewPositions = {
|
|
|
42
42
|
function setDefaultViewPosition(viewer: Viewer, position: string): void {
|
|
43
43
|
const direction = defaultViewPositions[position] || defaultViewPositions["sw"];
|
|
44
44
|
|
|
45
|
-
const camera = viewer.camera;
|
|
46
45
|
const center = viewer.extents.getCenter(new Vector3());
|
|
47
46
|
const sphere = viewer.extents.getBoundingSphere(new Sphere());
|
|
48
|
-
const
|
|
47
|
+
const offet = direction.clone().multiplyScalar(sphere.radius);
|
|
49
48
|
|
|
50
|
-
camera.
|
|
51
|
-
camera.position.add(
|
|
52
|
-
camera.rotation.set(0, 0, 0);
|
|
49
|
+
const camera = viewer.camera;
|
|
50
|
+
camera.position.copy(center).add(offet);
|
|
53
51
|
camera.lookAt(center);
|
|
54
52
|
camera.updateProjectionMatrix();
|
|
53
|
+
camera.updateMatrixWorld();
|
|
54
|
+
|
|
55
|
+
viewer.target.copy(center);
|
|
55
56
|
|
|
56
57
|
viewer.update();
|
|
57
58
|
viewer.emit({ type: "viewposition", data: position });
|
|
@@ -38,7 +38,7 @@ function setSelected(viewer: Viewer, handles: string[] = []): void {
|
|
|
38
38
|
selection.dispose();
|
|
39
39
|
|
|
40
40
|
viewer.update();
|
|
41
|
-
viewer.
|
|
41
|
+
viewer.emitEvent({ type: "select", data: undefined, handles });
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
commands("ThreeJS").registerCommand("setSelected", setSelected);
|
|
@@ -28,7 +28,7 @@ function showAll(viewer: Viewer): void {
|
|
|
28
28
|
viewer.scene.traverse((object) => (object.visible = true));
|
|
29
29
|
|
|
30
30
|
viewer.update();
|
|
31
|
-
viewer.
|
|
31
|
+
viewer.emitEvent({ type: "showall" });
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
commands("ThreeJS").registerCommand("showAll", showAll);
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
|
|
24
24
|
import "./ApplyModelTransform";
|
|
25
25
|
import "./ClearMarkup";
|
|
26
|
+
import "./ClearSelected";
|
|
26
27
|
import "./ClearSlices";
|
|
27
28
|
import "./CreatePreview";
|
|
28
29
|
import "./Explode";
|
|
@@ -39,7 +40,6 @@ import "./SetDefaultViewPosition";
|
|
|
39
40
|
import "./SetMarkupColor";
|
|
40
41
|
import "./SetSelected";
|
|
41
42
|
import "./ShowAll";
|
|
42
|
-
import "./Unselect";
|
|
43
43
|
import "./ZoomToExtents";
|
|
44
44
|
import "./ZoomToObjects";
|
|
45
45
|
import "./ZoomToSelected";
|