@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.
@@ -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
- getSelected(): string[];
148
- setSelected(handles?: string[]): void;
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, position: Vector2): Vector2;
15
- getPointerIntersects(position: Vector2): Array<Intersection<Object3D>>;
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.10.1",
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.10.1",
32
- "@inweb/eventemitter2": "~25.10.1",
33
- "@inweb/viewer-core": "~25.10.1"
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",
@@ -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 extends EventEmitter2<ViewerEventMap & CanvasEventMap & OptionsEventMap> implements IViewer {
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
- const clippingPlanes = this.renderer.clippingPlanes;
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.selected = [];
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.emitEvent({ type: "clear" });
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
- getSelected(): string[] {
518
- return this.executeCommand("getSelected");
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
- setSelected(handles?: string[]): void {
522
- this.executeCommand("setSelected", handles);
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
- const viewpoint: IViewpoint = {};
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.snapshot = { data: this.canvas?.toDataURL("image/jpeg", 0.25) };
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
- // markup should be as a separate library
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 unselect(viewer: Viewer): void {
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.emit({ type: "select", data: undefined, handles: [] });
34
+ viewer.emitEvent({ type: "select", data: undefined, handles: [] });
35
35
  }
36
36
 
37
- commands("ThreeJS").registerCommand("unselect", unselect);
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
- function clearSlices(viewer: Viewer) {
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.emit({ type: "explode", data: index });
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.emit({ type: "hide" });
37
- viewer.emit({ type: "select", data: undefined, handles: [] });
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.emit({ type: "isolate" });
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("unselect");
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, -1, 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 offset = new Vector3().copy(direction).multiplyScalar(sphere.radius);
47
+ const offet = direction.clone().multiplyScalar(sphere.radius);
49
48
 
50
- camera.position.copy(center);
51
- camera.position.add(offset);
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.emit({ type: "select", data: undefined, handles });
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.emit({ type: "showall" });
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";