@inweb/viewer-three 25.9.8 → 25.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/README.md +26 -18
  2. package/dist/viewer-three.js +9963 -6031
  3. package/dist/viewer-three.js.map +1 -1
  4. package/dist/viewer-three.min.js +3 -2
  5. package/dist/viewer-three.module.js +2648 -353
  6. package/dist/viewer-three.module.js.map +1 -1
  7. package/lib/Viewer/IDisposable.d.ts +6 -0
  8. package/lib/Viewer/Viewer.d.ts +119 -14
  9. package/lib/Viewer/commands/ApplyModelTransform.d.ts +1 -0
  10. package/lib/Viewer/commands/ClearMarkup.d.ts +1 -0
  11. package/lib/Viewer/commands/ClearSelected.d.ts +1 -0
  12. package/lib/Viewer/commands/ClearSlices.d.ts +1 -0
  13. package/lib/Viewer/commands/CreatePreview.d.ts +1 -0
  14. package/lib/Viewer/commands/Explode.d.ts +1 -0
  15. package/lib/Viewer/commands/GetDefaultViewPositions.d.ts +1 -0
  16. package/lib/Viewer/commands/GetModels.d.ts +1 -0
  17. package/lib/Viewer/commands/GetSelected.d.ts +1 -0
  18. package/lib/Viewer/commands/HideSelected.d.ts +1 -0
  19. package/lib/Viewer/commands/IsolateSelected.d.ts +1 -0
  20. package/lib/Viewer/commands/RegenerateAll.d.ts +1 -0
  21. package/lib/Viewer/commands/ResetView.d.ts +1 -0
  22. package/lib/Viewer/commands/SelectModel.d.ts +1 -0
  23. package/lib/Viewer/commands/SetActiveDragger.d.ts +1 -0
  24. package/lib/Viewer/commands/SetDefaultViewPosition.d.ts +13 -0
  25. package/lib/Viewer/commands/SetMarkupColor.d.ts +1 -0
  26. package/lib/Viewer/commands/SetSelected.d.ts +1 -0
  27. package/lib/Viewer/commands/ShowAll.d.ts +1 -0
  28. package/lib/Viewer/commands/ZoomToExtents.d.ts +1 -0
  29. package/lib/Viewer/commands/ZoomToObjects.d.ts +1 -0
  30. package/lib/Viewer/commands/ZoomToSelected.d.ts +1 -0
  31. package/lib/Viewer/commands/index.d.ts +22 -0
  32. package/lib/Viewer/components/AxesHelperComponent.d.ts +10 -0
  33. package/lib/Viewer/components/BackgroundComponent.d.ts +4 -4
  34. package/lib/Viewer/components/{DefaultCameraPositionComponent.d.ts → DefaultPositionComponent.d.ts} +3 -2
  35. package/lib/Viewer/components/ExtentsComponent.d.ts +8 -0
  36. package/lib/Viewer/components/ExtentsHelperComponent.d.ts +9 -0
  37. package/lib/Viewer/components/LightComponent.d.ts +5 -5
  38. package/lib/Viewer/components/RenderLoopComponent.d.ts +3 -3
  39. package/lib/Viewer/components/ResizeCanvasComponent.d.ts +2 -2
  40. package/lib/Viewer/components/SelectionComponent.d.ts +19 -0
  41. package/lib/Viewer/components/ViewPositionComponent.d.ts +31 -0
  42. package/lib/Viewer/components/WCSHelperComponent.d.ts +9 -0
  43. package/lib/Viewer/controls/WalkControls.d.ts +26 -0
  44. package/lib/Viewer/draggers/CuttingPlaneDragger.d.ts +17 -0
  45. package/lib/Viewer/draggers/CuttingPlaneXAxis.d.ts +5 -0
  46. package/lib/Viewer/draggers/CuttingPlaneYAxis.d.ts +5 -0
  47. package/lib/Viewer/draggers/CuttingPlaneZAxis.d.ts +5 -0
  48. package/lib/Viewer/draggers/OrbitDragger.d.ts +10 -6
  49. package/lib/Viewer/draggers/WalkDragger.d.ts +7 -33
  50. package/lib/Viewer/helpers/PlaneHelper.d.ts +11 -0
  51. package/lib/Viewer/helpers/WCSHelper.d.ts +10 -0
  52. package/lib/Viewer/loaders/GLTFLoadingManager.d.ts +3 -3
  53. package/lib/index.d.ts +1 -0
  54. package/package.json +6 -5
  55. package/src/Viewer/IDisposable.ts +29 -0
  56. package/src/Viewer/Viewer.ts +240 -49
  57. package/src/Viewer/commands/ApplyModelTransform.ts +33 -0
  58. package/src/Viewer/commands/ClearMarkup.ts +29 -0
  59. package/src/Viewer/commands/ClearSelected.ts +38 -0
  60. package/src/Viewer/commands/ClearSlices.ts +32 -0
  61. package/src/Viewer/commands/CreatePreview.ts +32 -0
  62. package/src/Viewer/commands/Explode.ts +83 -0
  63. package/src/Viewer/commands/GetDefaultViewPositions.ts +31 -0
  64. package/src/Viewer/commands/GetModels.ts +32 -0
  65. package/src/Viewer/commands/GetSelected.ts +31 -0
  66. package/src/Viewer/commands/HideSelected.ts +40 -0
  67. package/src/Viewer/commands/IsolateSelected.ts +50 -0
  68. package/src/Viewer/commands/RegenerateAll.ts +32 -0
  69. package/src/Viewer/commands/ResetView.ts +41 -0
  70. package/src/Viewer/commands/SelectModel.ts +32 -0
  71. package/src/Viewer/commands/SetActiveDragger.ts +29 -0
  72. package/src/Viewer/commands/SetDefaultViewPosition.ts +83 -0
  73. package/src/Viewer/commands/SetMarkupColor.ts +30 -0
  74. package/src/Viewer/commands/SetSelected.ts +44 -0
  75. package/src/Viewer/commands/ShowAll.ts +34 -0
  76. package/src/Viewer/commands/ZoomToExtents.ts +47 -0
  77. package/src/Viewer/commands/ZoomToObjects.ts +55 -0
  78. package/src/Viewer/commands/ZoomToSelected.ts +51 -0
  79. package/src/Viewer/commands/index.ts +45 -0
  80. package/src/Viewer/components/AxesHelperComponent.ts +70 -0
  81. package/src/Viewer/components/BackgroundComponent.ts +9 -7
  82. package/src/Viewer/components/{DefaultCameraPositionComponent.ts → DefaultPositionComponent.ts} +11 -22
  83. package/src/Viewer/components/ExtentsComponent.ts +54 -0
  84. package/src/Viewer/components/ExtentsHelperComponent.ts +58 -0
  85. package/src/Viewer/components/LightComponent.ts +14 -10
  86. package/src/Viewer/components/RenderLoopComponent.ts +6 -6
  87. package/src/Viewer/components/ResizeCanvasComponent.ts +2 -2
  88. package/src/Viewer/components/SelectionComponent.ts +132 -0
  89. package/src/Viewer/components/ViewPositionComponent.ts +165 -0
  90. package/src/Viewer/components/WCSHelperComponent.ts +46 -0
  91. package/src/Viewer/controls/OrbitControls.js +1007 -0
  92. package/src/Viewer/controls/WalkControls.ts +222 -0
  93. package/src/Viewer/draggers/CuttingPlaneDragger.ts +110 -0
  94. package/src/Viewer/draggers/CuttingPlaneXAxis.ts +33 -0
  95. package/src/Viewer/draggers/CuttingPlaneYAxis.ts +33 -0
  96. package/src/Viewer/draggers/CuttingPlaneZAxis.ts +33 -0
  97. package/src/Viewer/draggers/OrbitDragger.ts +70 -23
  98. package/src/Viewer/draggers/PanDragger.ts +4 -3
  99. package/src/Viewer/draggers/WalkDragger.ts +27 -216
  100. package/src/Viewer/draggers/ZoomDragger.ts +4 -3
  101. package/src/Viewer/helpers/PlaneHelper.ts +99 -0
  102. package/src/Viewer/helpers/WCSHelper.ts +119 -0
  103. package/src/Viewer/loaders/GLTFLoadingManager.ts +6 -6
  104. package/src/index.ts +2 -0
  105. package/lib/Viewer/IComponent.d.ts +0 -3
  106. package/lib/Viewer/components/ObjectSelectionComponent.d.ts +0 -16
  107. package/lib/Viewer/draggers/ClippingPlaneDragger.d.ts +0 -17
  108. package/src/Viewer/IComponent.ts +0 -3
  109. package/src/Viewer/components/ObjectSelectionComponent.ts +0 -105
  110. package/src/Viewer/draggers/ClippingPlaneDragger.ts +0 -120
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inweb/viewer-three",
3
- "version": "25.9.8",
3
+ "version": "25.11.0",
4
4
  "description": "3D viewer powered by Three.js",
5
5
  "homepage": "https://cloud.opendesign.com/docs/index.html",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -24,12 +24,13 @@
24
24
  ],
25
25
  "scripts": {
26
26
  "build": "rollup -c rollup.config.js",
27
- "test": "karma start karma.conf.js"
27
+ "test": "karma start karma.conf.js",
28
+ "docs": "typedoc"
28
29
  },
29
30
  "dependencies": {
30
- "@inweb/client": "~25.9.8",
31
- "@inweb/eventemitter2": "~25.9.8",
32
- "@inweb/viewer-core": "~25.9.8"
31
+ "@inweb/client": "~25.11.0",
32
+ "@inweb/eventemitter2": "~25.11.0",
33
+ "@inweb/viewer-core": "~25.11.0"
33
34
  },
34
35
  "devDependencies": {
35
36
  "@types/three": "^0.152.1",
@@ -0,0 +1,29 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2002-2024, 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-2024 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
+ /**
25
+ * An object that performs a cleanup operation when `.dispose()` is called.
26
+ */
27
+ export interface IDisposable {
28
+ dispose(): void;
29
+ }
@@ -21,8 +21,12 @@
21
21
  // acknowledge and accept the above terms.
22
22
  ///////////////////////////////////////////////////////////////////////////////
23
23
 
24
+ import { Box3, LinearToneMapping, Object3D, PerspectiveCamera, Scene, Vector3, WebGLRenderer } from "three";
25
+ import { GLTF, GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
26
+ import { GLTFLoadingManager } from "./loaders/GLTFLoadingManager";
27
+
24
28
  import { EventEmitter2 } from "@inweb/eventemitter2";
25
- import { Assembly, Client, File, Model } from "@inweb/client";
29
+ import { Assembly, Client, Model, File } from "@inweb/client";
26
30
  import {
27
31
  CANVAS_EVENTS,
28
32
  CanvasEventMap,
@@ -35,68 +39,88 @@ import {
35
39
  OptionsEventMap,
36
40
  ViewerEventMap,
37
41
  } from "@inweb/viewer-core";
38
- import * as THREE from "three";
39
- import { GLTF, GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
40
- import { GLTFLoadingManager } from "./loaders/GLTFLoadingManager";
41
42
 
42
43
  import { PanDragger } from "./draggers/PanDragger";
43
44
  import { OrbitDragger } from "./draggers/OrbitDragger";
44
45
  import { ZoomDragger } from "./draggers/ZoomDragger";
45
46
  import { WalkDragger } from "./draggers/WalkDragger";
46
- import { ClippingPlaneDragger } from "./draggers/ClippingPlaneDragger";
47
+ import { CuttingPlaneXAxisDragger } from "./draggers/CuttingPlaneXAxis";
48
+ import { CuttingPlaneYAxisDragger } from "./draggers/CuttingPlaneYAxis";
49
+ import { CuttingPlaneZAxisDragger } from "./draggers/CuttingPlaneZAxis";
47
50
 
48
- import { IComponent } from "./IComponent";
51
+ import { IDisposable } from "./IDisposable";
52
+ import { ExtentsComponent } from "./components/ExtentsComponent";
49
53
  import { LightComponent } from "./components/LightComponent";
50
54
  import { BackgroundComponent } from "./components/BackgroundComponent";
51
- import { DefaultCameraPositionComponent } from "./components/DefaultCameraPositionComponent";
55
+ import { DefaultPositionComponent } from "./components/DefaultPositionComponent";
52
56
  import { ResizeCanvasComponent } from "./components/ResizeCanvasComponent";
53
57
  import { RenderLoopComponent } from "./components/RenderLoopComponent";
54
- // import { ObjectSelectionComponent } from "./components/ObjectSelectionComponent";
55
-
58
+ import { SelectionComponent } from "./components/SelectionComponent";
59
+ // import { ViewPositionComponent } from "./components/ViewPositionComponent";
60
+ import { WCSHelperComponent } from "./components/WCSHelperComponent";
61
+ // import { AxesHelperComponent } from "./components/AxesHelperComponent";
62
+ // import { ExtentsHelperComponent } from "./components/ExtentsHelperComponent";
63
+
64
+ /**
65
+ * 3D viewer powered by {@link https://threejs.org/ | Three.js}.
66
+ */
56
67
  export class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMap & OptionsEventMap> implements IViewer {
57
68
  public client: Client | undefined;
58
- private _options: Options;
69
+ protected _options: Options;
59
70
 
60
71
  private canvaseventlistener: (event: any) => void;
61
72
 
62
73
  public canvas: HTMLCanvasElement | undefined;
63
74
  public canvasEvents: string[];
64
75
 
65
- public scene: THREE.Scene | undefined;
66
- public camera: THREE.PerspectiveCamera | undefined;
67
- public renderer: THREE.WebGLRenderer | undefined;
76
+ public scene: Scene | undefined;
77
+ public helpers: Scene | undefined;
78
+ public camera: PerspectiveCamera | undefined;
79
+ public renderer: WebGLRenderer | undefined;
68
80
  public models: Array<GLTF>;
69
- public selectedObjects: Array<any>;
81
+ public selected: Array<Object3D>;
82
+ public extents: Box3;
83
+ public target: Vector3;
70
84
 
71
85
  private draggerFactory: Record<string, any>;
72
86
  private _activeDragger: IDragger | null;
73
87
 
74
- private components: Array<IComponent>;
88
+ private components: Array<IDisposable>;
75
89
 
76
- private renderNeeded = false;
90
+ private renderNeeded: boolean;
77
91
  private renderTime: DOMHighResTimeStamp;
78
92
 
93
+ /**
94
+ * @param client - The `Client` instance that is used to load model reference files from the
95
+ * Open Cloud Server. Do not specify `Client` if you need a standalone viewer instance to
96
+ * view `glTF` files from the web or from local computer.
97
+ */
79
98
  constructor(client?: Client) {
80
99
  super();
81
100
  this._options = new Options(this);
82
101
 
83
102
  this.client = client;
84
103
 
85
- this.canvasEvents = CANVAS_EVENTS.slice();
104
+ this.canvasEvents = CANVAS_EVENTS;
86
105
  this.canvaseventlistener = (event: Event) => this.emit(event);
87
106
 
107
+ this.extents = new Box3();
108
+ this.target = new Vector3();
109
+
88
110
  this.draggerFactory = {
89
111
  Pan: PanDragger,
90
112
  Zoom: ZoomDragger,
91
113
  Orbit: OrbitDragger,
92
114
  Walk: WalkDragger,
93
- Clipping: ClippingPlaneDragger,
115
+ CuttingPlaneXAxis: CuttingPlaneXAxisDragger,
116
+ CuttingPlaneYAxis: CuttingPlaneYAxisDragger,
117
+ CuttingPlaneZAxis: CuttingPlaneZAxisDragger,
94
118
  };
95
119
  this._activeDragger = null;
96
120
 
97
121
  this.models = [];
98
122
  this.components = [];
99
- this.selectedObjects = [];
123
+ this.selected = [];
100
124
 
101
125
  this.renderTime = 0;
102
126
 
@@ -104,7 +128,7 @@ export class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMap & Opti
104
128
  this.update = this.update.bind(this);
105
129
  }
106
130
 
107
- get options(): Options {
131
+ get options(): IOptions {
108
132
  return this._options;
109
133
  }
110
134
 
@@ -112,38 +136,45 @@ export class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMap & Opti
112
136
  return Object.keys(this.draggerFactory);
113
137
  }
114
138
 
115
- initialize(canvas: HTMLCanvasElement, onProgress?: (event: ProgressEvent) => void): Promise<this> {
139
+ initialize(canvas: HTMLCanvasElement, onProgress?: (event: ProgressEvent<EventTarget>) => void): Promise<this> {
116
140
  this.addEventListener("optionschange", (event) => this.syncOptions(event.data));
117
141
 
118
- this.scene = new THREE.Scene();
142
+ this.scene = new Scene();
143
+ this.helpers = new Scene();
119
144
 
120
145
  const rect = canvas.parentElement.getBoundingClientRect();
121
146
  const width = rect.width || 1;
122
147
  const height = rect.height || 1;
123
- this.camera = new THREE.PerspectiveCamera(45, width / height, 0.01, 1000);
148
+ this.camera = new PerspectiveCamera(45, width / height, 0.01, 1000);
124
149
  this.camera.up.set(0, 0, 1);
125
150
 
126
- this.renderer = new THREE.WebGLRenderer({ canvas, antialias: true });
151
+ this.renderer = new WebGLRenderer({ canvas, antialias: true, preserveDrawingBuffer: true });
127
152
  this.renderer.setPixelRatio(window.devicePixelRatio);
128
153
  this.renderer.setSize(width, height);
129
- this.renderer.toneMapping = THREE.LinearToneMapping;
154
+ this.renderer.toneMapping = LinearToneMapping;
130
155
 
131
156
  this.canvas = canvas;
132
157
  this.canvasEvents.forEach((x) => canvas.addEventListener(x, this.canvaseventlistener));
133
158
 
159
+ this.components.push(new ExtentsComponent(this));
134
160
  this.components.push(new LightComponent(this));
135
161
  this.components.push(new BackgroundComponent(this));
136
- this.components.push(new DefaultCameraPositionComponent(this));
162
+ // this.components.push(new ViewPositionComponent(this));
163
+ this.components.push(new DefaultPositionComponent(this));
137
164
  this.components.push(new ResizeCanvasComponent(this));
138
- this.components.push(new RenderLoopComponent(this as any));
139
- // this.components.push(new ObjectSelectionComponent(this as any));
165
+ this.components.push(new RenderLoopComponent(this));
166
+ this.components.push(new SelectionComponent(this));
167
+ this.components.push(new WCSHelperComponent(this));
168
+ // this.components.push(new AxesHelperComponent(this));
169
+ // this.components.push(new ExtentsHelperComponent(this));
140
170
 
141
171
  this.syncOptions();
142
172
 
143
173
  this.renderTime = performance.now();
144
174
  this.render(this.renderTime);
145
175
 
146
- if (onProgress) onProgress(new ProgressEvent("progress", { lengthComputable: true, loaded: 1, total: 1 }));
176
+ if (typeof onProgress === "function")
177
+ onProgress(new ProgressEvent("progress", { lengthComputable: true, loaded: 1, total: 1 }));
147
178
 
148
179
  this.emitEvent({ type: "initializeprogress", data: 1, loaded: 1, total: 1 });
149
180
  this.emitEvent({ type: "initialize" });
@@ -155,12 +186,14 @@ export class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMap & Opti
155
186
  this.cancel();
156
187
  this.emitEvent({ type: "dispose" });
157
188
 
158
- this.components.forEach((component: IComponent) => component.dispose());
189
+ this.components.forEach((component: IDisposable) => component.dispose());
159
190
  this.components = [];
160
191
 
161
192
  this.setActiveDragger("");
162
193
  this.removeAllListeners();
163
194
 
195
+ this.clear();
196
+
164
197
  if (this.canvas) {
165
198
  this.canvasEvents.forEach((x) => this.canvas.removeEventListener(x, this.canvaseventlistener));
166
199
  this.canvas = undefined;
@@ -171,6 +204,7 @@ export class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMap & Opti
171
204
  this.renderer = undefined;
172
205
  this.camera = undefined;
173
206
  this.scene = undefined;
207
+ this.helpers = undefined;
174
208
 
175
209
  return this;
176
210
  }
@@ -182,12 +216,19 @@ export class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMap & Opti
182
216
  public render(time: DOMHighResTimeStamp): void {
183
217
  if (!this.renderNeeded) return;
184
218
  if (!this.renderer) return;
185
- if (!this.scene) return;
186
- if (!this.camera) return;
187
219
 
188
- this.renderer.render(this.scene, this.camera);
189
220
  this.renderNeeded = false;
190
221
 
222
+ this.renderer.setViewport(0, 0, this.canvas.offsetWidth, this.canvas.offsetHeight);
223
+ this.renderer.autoClear = true;
224
+ this.renderer.render(this.scene, this.camera);
225
+
226
+ const clippingPlanes = this.renderer.clippingPlanes;
227
+ this.renderer.clippingPlanes = [];
228
+ this.renderer.autoClear = false;
229
+ this.renderer.render(this.helpers, this.camera);
230
+ this.renderer.clippingPlanes = clippingPlanes;
231
+
191
232
  const deltaTime = (time - this.renderTime) / 1000;
192
233
  this.renderTime = time;
193
234
  this.emitEvent({ type: "render", time, deltaTime });
@@ -208,7 +249,30 @@ export class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMap & Opti
208
249
  return Promise.resolve(this);
209
250
  }
210
251
 
211
- async open(file: File | Assembly | Model): Promise<this> {
252
+ /**
253
+ * Loads a file from Open Cloud Server into the viewer.
254
+ *
255
+ * The file geometry data on the server must be converted to `glTF` format.
256
+ *
257
+ * This method requires a `Client` instance to be specified when creating the viewer to load
258
+ * model reference files from the Open Cloud Server. For a standalone viewer instance use
259
+ * {@link openGltfFile | openGltfFile()}.
260
+ *
261
+ * Fires:
262
+ *
263
+ * - {@link OpenEvent | open}
264
+ * - {@link GeometryStartEvent | geometrystart}
265
+ * - {@link GeometryProgressEvent | geometryprogress}
266
+ * - {@link DatabaseChunkEvent | databasechunk}
267
+ * - {@link GeometryChunkEvent | geometrychunk}
268
+ * - {@link GeometryEndEvent | geometryend}
269
+ * - {@link GeometryErrorEvent | geometryerror}
270
+ *
271
+ * @param file - File, assembly or specific model to load. If a `File` instance with multiple
272
+ * models is specified, the default model will be loaded. If there is no default model,
273
+ * first availiable model will be loaded.
274
+ */
275
+ async open(file: Model | File | Assembly): Promise<this> {
212
276
  if (!this.renderer) return this;
213
277
 
214
278
  this.cancel();
@@ -240,9 +304,40 @@ export class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMap & Opti
240
304
  return this;
241
305
  }
242
306
 
307
+ /**
308
+ * Loads a `glTF` file into the viewer.
309
+ *
310
+ * Fires:
311
+ *
312
+ * - {@link OpenEvent | open}
313
+ * - {@link GeometryStartEvent | geometrystart}
314
+ * - {@link GeometryProgressEvent | geometryprogress}
315
+ * - {@link DatabaseChunkEvent | databasechunk}
316
+ * - {@link GeometryEndEvent | geometryend}
317
+ * - {@link GeometryErrorEvent | geometryerror}
318
+ *
319
+ * @param file - File URL or binary data buffer to load.
320
+ * @param externalData - External resource map such as binary data buffers or images. Each
321
+ * resource should be represented by a `uri` and a corresponding resource URL, or
322
+ * {@link https://developer.mozilla.org/docs/Web/API/File | Web API File} object, or
323
+ * {@link https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer | ArrayBuffer}
324
+ * or {@link https://developer.mozilla.org/docs/Web/API/Blob/Blob | Blob}, or
325
+ * {@link https://developer.mozilla.org/docs/Web/HTTP/Basics_of_HTTP/Data_URIs | Data URL} string,
326
+ * @param params - Loader parameters.
327
+ * @param params.path - The base path from which to find subsequent glTF resources such as
328
+ * textures and .bin data files. If not defined, the base path of the file URL will be used.
329
+ * @param params.requestHeader - The
330
+ * {@link https://developer.mozilla.org/docs/Glossary/Request_header | request header} used
331
+ * in HTTP request.
332
+ * @param params.crossOrigin - The crossOrigin string to implement CORS for loading the url
333
+ * from a different domain that allows CORS. Default is `anonymous`.
334
+ * @param params.withCredentials - Whether the XMLHttpRequest uses credentials such as
335
+ * cookies, authorization headers or TLS client certificates. See
336
+ * {@link https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/withCredentials | XMLHttpRequest.withCredentials}.
337
+ */
243
338
  openGltfFile(
244
- file: string | ArrayBuffer | Blob,
245
- externalData: Map<string, string | ArrayBuffer | Blob> = new Map(),
339
+ file: string | globalThis.File | ArrayBuffer | Blob,
340
+ externalData: Map<string, string | globalThis.File | ArrayBuffer | Blob> = new Map(),
246
341
  params: {
247
342
  path?: string;
248
343
  requestHeader?: HeadersInit;
@@ -260,9 +355,40 @@ export class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMap & Opti
260
355
  return this.loadGltfFile(file, externalData, params);
261
356
  }
262
357
 
358
+ /**
359
+ * Appends a `glTF` file to the existing opened file.
360
+ *
361
+ * Fires:
362
+ *
363
+ * - {@link OpenEvent | open}
364
+ * - {@link GeometryStartEvent | geometrystart}
365
+ * - {@link GeometryProgressEvent | geometryprogress}
366
+ * - {@link DatabaseChunkEvent | databasechunk}
367
+ * - {@link GeometryEndEvent | geometryend}
368
+ * - {@link GeometryErrorEvent | geometryerror}
369
+ *
370
+ * @param file - File URL or binary data buffer to load.
371
+ * @param externalData - External resource map such as binary data buffers or images. Each
372
+ * resource should be represented by a `uri` and a corresponding resource URL, or
373
+ * {@link https://developer.mozilla.org/docs/Web/API/File | Web API File} object, or
374
+ * {@link https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer | ArrayBuffer}
375
+ * or {@link https://developer.mozilla.org/docs/Web/API/Blob/Blob | Blob}, or
376
+ * {@link https://developer.mozilla.org/docs/Web/HTTP/Basics_of_HTTP/Data_URIs | Data URL} string,
377
+ * @param params - Loader parameters.
378
+ * @param params.path - The base path from which to find subsequent glTF resources such as
379
+ * textures and .bin data files.
380
+ * @param params.requestHeader - The
381
+ * {@link https://developer.mozilla.org/docs/Glossary/Request_header | request header} used
382
+ * in HTTP request.
383
+ * @param params.crossOrigin - The crossOrigin string to implement CORS for loading the url
384
+ * from a different domain that allows CORS. Default is `anonymous`.
385
+ * @param params.withCredentials - Whether the XMLHttpRequest uses credentials such as
386
+ * cookies, authorization headers or TLS client certificates. See
387
+ * {@link https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/withCredentials | XMLHttpRequest.withCredentials}.
388
+ */
263
389
  async loadGltfFile(
264
- file: string | ArrayBuffer | Blob,
265
- externalData: Map<string, string | ArrayBuffer | Blob> = new Map(),
390
+ file: string | globalThis.File | ArrayBuffer | Blob,
391
+ externalData: Map<string, string | globalThis.File | ArrayBuffer | Blob> = new Map(),
266
392
  params: {
267
393
  path?: string;
268
394
  requestHeader?: HeadersInit;
@@ -291,11 +417,13 @@ export class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMap & Opti
291
417
 
292
418
  this.models.push(gltf);
293
419
  this.scene.add(gltf.scene);
420
+
294
421
  this.update();
422
+ this.resetActiveDragger();
295
423
 
296
424
  this.emitEvent({ type: "databasechunk" });
297
425
  this.emitEvent({ type: "geometryend", data: gltf.scene });
298
- } catch (error: any) {
426
+ } catch (error) {
299
427
  this.emitEvent({ type: "geometryerror", data: error });
300
428
  throw error;
301
429
  } finally {
@@ -306,6 +434,8 @@ export class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMap & Opti
306
434
  }
307
435
 
308
436
  clear(): this {
437
+ if (!this.renderer) return this;
438
+
309
439
  function disposeMaterial(material: any) {
310
440
  const materials = Array.isArray(material) ? material : [material];
311
441
  materials.forEach((material: any) => {
@@ -319,33 +449,85 @@ export class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMap & Opti
319
449
  if (object.material) disposeMaterial(object.material);
320
450
  }
321
451
 
322
- this.selectedObjects = [];
452
+ this.setActiveDragger();
453
+
454
+ this.selected = [];
455
+ this.renderer.clippingPlanes = [];
456
+
457
+ this.helpers.traverse(disposeObject);
458
+ this.helpers.clear();
323
459
 
324
460
  this.models.forEach((gltf) => gltf.scene.traverse(disposeObject));
325
461
  this.models.forEach((gltf) => gltf.scene.removeFromParent());
326
462
  this.models = [];
327
463
 
328
- this.update();
464
+ this.scene.clear();
465
+
329
466
  this.emitEvent({ type: "clear" });
467
+ this.update(true);
330
468
 
331
469
  return this;
332
470
  }
333
471
 
472
+ getSelected(): string[] {
473
+ return this.executeCommand("getSelected");
474
+ }
475
+
476
+ setSelected(handles?: string[]): void {
477
+ this.executeCommand("setSelected", handles);
478
+ }
479
+
480
+ clearSelected(): void {
481
+ this.executeCommand("clearSelected");
482
+ }
483
+
484
+ hideSelected(): void {
485
+ this.executeCommand("hideSelected");
486
+ }
487
+
488
+ isolateSelected(): void {
489
+ this.executeCommand("isolateSelected");
490
+ }
491
+
492
+ showAll(): void {
493
+ this.executeCommand("showAll");
494
+ }
495
+
496
+ explode(index = 0): void {
497
+ this.executeCommand("explode", index);
498
+ }
499
+
500
+ collect(): void {
501
+ this.executeCommand("collect");
502
+ }
503
+
334
504
  activeDragger(): IDragger | null {
335
505
  return this._activeDragger;
336
506
  }
337
507
 
338
- setActiveDragger(name: string): IDragger | null {
508
+ setActiveDragger(name = ""): IDragger | null {
339
509
  if (!this._activeDragger || this._activeDragger.name !== name) {
340
510
  if (this._activeDragger) {
341
511
  this._activeDragger.dispose();
342
512
  this._activeDragger = null;
343
513
  }
344
- const Constructor = this.draggerFactory[name];
345
- if (Constructor) {
346
- this._activeDragger = new Constructor(this);
347
- this._activeDragger.name = name;
514
+ if (this.isInitialized()) {
515
+ const Constructor = this.draggerFactory[name];
516
+ if (Constructor) {
517
+ this._activeDragger = new Constructor(this);
518
+ this._activeDragger.name = name;
519
+ }
348
520
  }
521
+ const canvas = this.canvas;
522
+ if (canvas) {
523
+ canvas.className = canvas.className
524
+ .split(" ")
525
+ .filter((x) => !x.startsWith("oda-cursor-"))
526
+ .filter((x) => x)
527
+ .concat(`oda-cursor-${name.toLowerCase()}`)
528
+ .join(" ");
529
+ }
530
+ this.emitEvent({ type: "changeactivedragger", data: name });
349
531
  }
350
532
  return this._activeDragger;
351
533
  }
@@ -353,22 +535,31 @@ export class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMap & Opti
353
535
  resetActiveDragger(): void {
354
536
  const dragger = this._activeDragger;
355
537
  if (dragger) {
356
- this.setActiveDragger("");
538
+ this.setActiveDragger();
357
539
  this.setActiveDragger(dragger.name);
358
540
  }
359
541
  }
360
542
 
361
543
  is3D(): boolean {
362
- return false;
544
+ return true;
363
545
  }
364
546
 
365
547
  executeCommand(id: string, ...args: any[]): any {
366
548
  return commands("ThreeJS").executeCommand(id, this, ...args);
367
549
  }
368
550
 
551
+ getComponent(type): any {
552
+ return this.components.find((component) => component instanceof type);
553
+ }
554
+
369
555
  drawViewpoint(viewpoint: IViewpoint): void {}
370
556
 
371
557
  createViewpoint(): IViewpoint {
372
- return {};
558
+ const viewpoint: IViewpoint = {};
559
+
560
+ viewpoint.snapshot = { data: this.canvas?.toDataURL("image/jpeg", 0.25) };
561
+ viewpoint.description = new Date().toDateString();
562
+
563
+ return viewpoint;
373
564
  }
374
565
  }
@@ -0,0 +1,33 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2002-2024, 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-2024 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 { Model, File, Assembly } from "@inweb/client";
25
+ import { commands } from "@inweb/viewer-core";
26
+ import type { Viewer } from "../Viewer";
27
+
28
+ // gltf root object don't have model handle
29
+ function applyModelTransform(viewer: Viewer, model: Model | File | Assembly) {
30
+ console.warn("applyModelTransform not implemented");
31
+ }
32
+
33
+ commands("ThreeJS").registerCommand("applyModelTransform", applyModelTransform);
@@ -0,0 +1,29 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2002-2024, 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-2024 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 { commands } from "@inweb/viewer-core";
25
+ import type { Viewer } from "../Viewer";
26
+
27
+ // markup should be as a separate library
28
+ commands("ThreeJS").registerCommand("clearMarkup", (viewer: Viewer) => console.warn("clearMarkup not implemented"));
29
+ commands("ThreeJS").registerCommandAlias("clearMarkup", "clearOverlay");
@@ -0,0 +1,38 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2002-2024, 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-2024 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 { commands } from "@inweb/viewer-core";
25
+ import type { Viewer } from "../Viewer";
26
+ import { SelectionComponent } from "../components/SelectionComponent";
27
+
28
+ function clearSelected(viewer: Viewer): void {
29
+ const selection = new SelectionComponent(viewer);
30
+ selection.clearSelection();
31
+ selection.dispose();
32
+
33
+ viewer.update();
34
+ viewer.emitEvent({ type: "select", data: undefined, handles: [] });
35
+ }
36
+
37
+ commands("ThreeJS").registerCommand("clearSelected", clearSelected);
38
+ commands("ThreeJS").registerCommandAlias("clearSelected", "unselect");