@inweb/viewer-three 26.12.6 → 27.1.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 (43) hide show
  1. package/dist/extensions/loaders/GLTFFileLoader.js +1 -1
  2. package/dist/extensions/loaders/GLTFFileLoader.js.map +1 -1
  3. package/dist/extensions/loaders/GLTFFileLoader.min.js +1 -1
  4. package/dist/extensions/loaders/GLTFFileLoader.module.js +1 -1
  5. package/dist/extensions/loaders/GLTFFileLoader.module.js.map +1 -1
  6. package/dist/extensions/loaders/IFCXLoader.js +2 -2
  7. package/dist/extensions/loaders/IFCXLoader.js.map +1 -1
  8. package/dist/extensions/loaders/IFCXLoader.min.js +1 -1
  9. package/dist/extensions/loaders/IFCXLoader.module.js +2 -2
  10. package/dist/extensions/loaders/IFCXLoader.module.js.map +1 -1
  11. package/dist/viewer-three.js +466 -170
  12. package/dist/viewer-three.js.map +1 -1
  13. package/dist/viewer-three.min.js +2 -2
  14. package/dist/viewer-three.module.js +464 -168
  15. package/dist/viewer-three.module.js.map +1 -1
  16. package/extensions/loaders/GLTFFileLoader.ts +1 -1
  17. package/extensions/loaders/IFCX/IFCXCloudLoader.ts +1 -1
  18. package/extensions/loaders/IFCX/IFCXFileLoader.ts +1 -1
  19. package/lib/Viewer/Viewer.d.ts +2 -1
  20. package/lib/Viewer/components/ExtentsComponent.d.ts +1 -1
  21. package/lib/Viewer/loaders/DynamicGltfLoader/DynamicModelImpl.d.ts +3 -3
  22. package/lib/Viewer/measurement/Snapper.d.ts +1 -0
  23. package/lib/Viewer/measurement/UnitConverter.d.ts +20 -13
  24. package/lib/Viewer/models/IModelImpl.d.ts +2 -6
  25. package/lib/Viewer/models/ModelImpl.d.ts +4 -6
  26. package/package.json +5 -5
  27. package/src/Viewer/Viewer.ts +25 -15
  28. package/src/Viewer/commands/GetSelected2.ts +2 -2
  29. package/src/Viewer/commands/ZoomTo.ts +3 -3
  30. package/src/Viewer/components/CameraComponent.ts +4 -4
  31. package/src/Viewer/components/ExtentsComponent.ts +3 -3
  32. package/src/Viewer/components/HighlighterComponent.ts +11 -17
  33. package/src/Viewer/components/SelectionComponent.ts +14 -13
  34. package/src/Viewer/draggers/MeasureLineDragger.ts +1 -0
  35. package/src/Viewer/draggers/OrbitDragger.ts +2 -0
  36. package/src/Viewer/loaders/DynamicGltfLoader/DynamicGltfLoader.js +287 -22
  37. package/src/Viewer/loaders/DynamicGltfLoader/DynamicModelImpl.ts +94 -18
  38. package/src/Viewer/loaders/DynamicGltfLoader/GltfStructure.js +1 -1
  39. package/src/Viewer/measurement/Snapper.ts +6 -3
  40. package/src/Viewer/measurement/UnitConverter.ts +19 -12
  41. package/src/Viewer/measurement/UnitFormatter.ts +2 -2
  42. package/src/Viewer/models/IModelImpl.ts +2 -10
  43. package/src/Viewer/models/ModelImpl.ts +111 -61
@@ -62,7 +62,7 @@ export class GLTFFileLoader extends Loader {
62
62
  const gltf = await loader.loadAsync(this.manager.fileURL, progress);
63
63
  if (!this.viewer.scene) return this;
64
64
 
65
- let handle = 0;
65
+ let handle = 1;
66
66
  gltf.scene.traverse((object) => {
67
67
  object.userData = { handle: handle + "", ...object.userData };
68
68
  handle++;
@@ -56,7 +56,7 @@ export class IFCXCloudLoader extends Loader {
56
56
  const scene: Scene = await parse(json);
57
57
  clear();
58
58
 
59
- let handle = 0;
59
+ let handle = 1;
60
60
  scene.traverse((object) => {
61
61
  object.userData = { handle: handle + "", ...object.userData };
62
62
  handle++;
@@ -56,7 +56,7 @@ export class IFCXFileLoader extends Loader {
56
56
  const scene = await loader.loadAsync(manager.fileURL, progress);
57
57
  if (!this.viewer.scene) return this;
58
58
 
59
- let handle = 0;
59
+ let handle = 1;
60
60
  scene.traverse((object) => {
61
61
  object.userData = { handle: handle + "", ...object.userData };
62
62
  handle++;
@@ -39,6 +39,7 @@ export declare class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMa
39
39
  target: Vector3;
40
40
  private _activeDragger;
41
41
  private _components;
42
+ private _updateDelay;
42
43
  private _renderNeeded;
43
44
  private _renderTime;
44
45
  private _markup;
@@ -61,7 +62,7 @@ export declare class Viewer extends EventEmitter2<ViewerEventMap & CanvasEventMa
61
62
  isInitialized(): boolean;
62
63
  setSize(width: number, height: number, updateStyle?: boolean): void;
63
64
  update(force?: boolean): void;
64
- render(time?: DOMHighResTimeStamp, force?: boolean): void;
65
+ render(time?: DOMHighResTimeStamp): void;
65
66
  loadReferences(model: Model | File | Assembly): Promise<this>;
66
67
  /**
67
68
  * Loads a file into the viewer.
@@ -4,5 +4,5 @@ export declare class ExtentsComponent implements IComponent {
4
4
  private viewer;
5
5
  constructor(viewer: Viewer);
6
6
  dispose(): void;
7
- syncExtents: () => void;
7
+ syncExtents: (event: any) => void;
8
8
  }
@@ -8,13 +8,13 @@ export declare class DynamicModelImpl extends ModelImpl {
8
8
  getExtents(target: Box3): Box3;
9
9
  getObjects(): Object3D[];
10
10
  getVisibleObjects(): Object3D[];
11
- hasObject(object: any): boolean;
12
11
  getObjectsByHandles(handles: string | string[]): Object3D[];
13
12
  getHandlesByObjects(objects: Object3D | Object3D[]): string[];
14
13
  hideObjects(objects: Object3D | Object3D[]): this;
15
14
  isolateObjects(objects: Object3D | Object3D[]): this;
16
15
  showObjects(objects: Object3D | Object3D[]): this;
17
16
  showAllObjects(): this;
18
- showOriginalObjects(objects: Object3D | Object3D[]): this;
19
- hideOriginalObjects(objects: Object3D | Object3D[]): this;
17
+ highlightObjects(objects: Object3D | Object3D[]): this;
18
+ unhighlightObjects(objects: Object3D | Object3D[]): this;
19
+ explode(scale?: number, coeff?: number): this;
20
20
  }
@@ -3,6 +3,7 @@ export declare class Snapper {
3
3
  camera: Camera;
4
4
  renderer: WebGLRenderer;
5
5
  canvas: HTMLCanvasElement;
6
+ threshold: number;
6
7
  private raycaster;
7
8
  private detectRadiusInPixels;
8
9
  private edgesCache;
@@ -1,62 +1,69 @@
1
- export declare const ModelUnits: {
1
+ export declare const DisplayUnits: {
2
2
  Meters: {
3
3
  name: string;
4
- type: string;
4
+ symbol: string;
5
5
  scale: number;
6
6
  };
7
7
  Centimeters: {
8
8
  name: string;
9
- type: string;
9
+ symbol: string;
10
10
  scale: number;
11
11
  };
12
12
  Millimeters: {
13
13
  name: string;
14
- type: string;
14
+ symbol: string;
15
15
  scale: number;
16
16
  };
17
17
  Feet: {
18
18
  name: string;
19
- type: string;
19
+ symbol: string;
20
20
  scale: number;
21
21
  };
22
22
  Inches: {
23
23
  name: string;
24
- type: string;
24
+ symbol: string;
25
25
  scale: number;
26
26
  };
27
27
  Yards: {
28
28
  name: string;
29
- type: string;
29
+ symbol: string;
30
30
  scale: number;
31
31
  };
32
32
  Kilometers: {
33
33
  name: string;
34
- type: string;
34
+ symbol: string;
35
35
  scale: number;
36
36
  };
37
37
  Miles: {
38
38
  name: string;
39
- type: string;
39
+ symbol: string;
40
40
  scale: number;
41
41
  };
42
42
  Micrometers: {
43
43
  name: string;
44
- type: string;
44
+ symbol: string;
45
45
  scale: number;
46
46
  };
47
47
  Mils: {
48
48
  name: string;
49
- type: string;
49
+ symbol: string;
50
50
  scale: number;
51
51
  };
52
52
  MicroInches: {
53
53
  name: string;
54
- type: string;
54
+ symbol: string;
55
55
  scale: number;
56
56
  };
57
57
  Default: {
58
58
  name: string;
59
- type: string;
59
+ symbol: string;
60
+ scale: number;
61
+ };
62
+ };
63
+ export declare const ModelUnits: {
64
+ Default: {
65
+ name: string;
66
+ symbol: string;
60
67
  scale: number;
61
68
  };
62
69
  };
@@ -13,10 +13,6 @@ export interface IModelImpl extends IModel {
13
13
  getExtents(target: Box3): Box3;
14
14
  getObjects(): Object3D[];
15
15
  getVisibleObjects(): Object3D[];
16
- hasObject(object: Object3D): boolean;
17
- hasHandle(handle: string): boolean;
18
- getOwnObjects(objects: Object3D | Object3D[]): Object3D[];
19
- getOwnHandles(handles: string | string[]): string[];
20
16
  getObjectsByHandles(handles: string | string[]): Object3D[];
21
17
  getHandlesByObjects(objects: Object3D | Object3D[]): string[];
22
18
  hideObjects(objects: Object3D | Object3D[]): this;
@@ -24,7 +20,7 @@ export interface IModelImpl extends IModel {
24
20
  isolateObjects(objects: Object3D | Object3D[]): this;
25
21
  showObjects(objects: Object3D | Object3D[]): this;
26
22
  showAllObjects(): this;
27
- showOriginalObjects(objects: Object3D | Object3D[]): this;
28
- hideOriginalObjects(objects: Object3D | Object3D[]): this;
23
+ highlightObjects(objects: Object3D | Object3D[]): this;
24
+ unhighlightObjects(objects: Object3D | Object3D[]): this;
29
25
  explode(scale: number, coeff?: number): this;
30
26
  }
@@ -4,6 +4,8 @@ import { IModelImpl } from "./IModelImpl";
4
4
  export declare class ModelImpl implements IModelImpl {
5
5
  id: string;
6
6
  scene: Object3D;
7
+ private handleToObjects;
8
+ private originalObjects;
7
9
  constructor(scene: Object3D);
8
10
  dispose(): void;
9
11
  getUnits(): string;
@@ -14,10 +16,6 @@ export declare class ModelImpl implements IModelImpl {
14
16
  getExtents(target: Box3): Box3;
15
17
  getObjects(): Object3D[];
16
18
  getVisibleObjects(): Object3D[];
17
- hasObject(object: Object3D): boolean;
18
- hasHandle(handle: string): boolean;
19
- getOwnObjects(objects: Object3D | Object3D[]): Object3D[];
20
- getOwnHandles(handles: string | string[]): string[];
21
19
  getObjectsByHandles(handles: string | string[]): Object3D[];
22
20
  getHandlesByObjects(objects: Object3D | Object3D[]): string[];
23
21
  hideObjects(objects: Object3D | Object3D[]): this;
@@ -25,7 +23,7 @@ export declare class ModelImpl implements IModelImpl {
25
23
  isolateObjects(objects: Object3D | Object3D[]): this;
26
24
  showObjects(objects: Object3D | Object3D[]): this;
27
25
  showAllObjects(): this;
28
- showOriginalObjects(objects: Object3D | Object3D[]): this;
29
- hideOriginalObjects(objects: Object3D | Object3D[]): this;
26
+ highlightObjects(objects: Object3D | Object3D[]): this;
27
+ unhighlightObjects(objects: Object3D | Object3D[]): this;
30
28
  explode(scale?: number, coeff?: number): this;
31
29
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inweb/viewer-three",
3
- "version": "26.12.6",
3
+ "version": "27.1.0",
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",
@@ -35,10 +35,10 @@
35
35
  "docs": "typedoc"
36
36
  },
37
37
  "dependencies": {
38
- "@inweb/client": "~26.12.6",
39
- "@inweb/eventemitter2": "~26.12.6",
40
- "@inweb/markup": "~26.12.6",
41
- "@inweb/viewer-core": "~26.12.6"
38
+ "@inweb/client": "~27.1.0",
39
+ "@inweb/eventemitter2": "~27.1.0",
40
+ "@inweb/markup": "~27.1.0",
41
+ "@inweb/viewer-core": "~27.1.0"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@types/three": "^0.180.0",
@@ -109,6 +109,7 @@ export class Viewer
109
109
  private _activeDragger: IDragger | null;
110
110
  private _components: IComponent[];
111
111
 
112
+ private _updateDelay: number;
112
113
  private _renderNeeded: boolean;
113
114
  private _renderTime: DOMHighResTimeStamp;
114
115
 
@@ -137,6 +138,7 @@ export class Viewer
137
138
  this._activeDragger = null;
138
139
  this._components = [];
139
140
 
141
+ this._updateDelay = 1000;
140
142
  this._renderNeeded = false;
141
143
  this._renderTime = 0;
142
144
 
@@ -175,9 +177,9 @@ export class Viewer
175
177
  const rect = canvas.parentElement.getBoundingClientRect();
176
178
  const width = rect.width || 1;
177
179
  const height = rect.height || 1;
178
- const aspect = width / height;
180
+ const aspectRatio = width / height;
179
181
 
180
- this.camera = new PerspectiveCamera(45, aspect, 0.001, 1000);
182
+ this.camera = new PerspectiveCamera(45, aspectRatio, 0.001, 1000);
181
183
  this.camera.up.set(0, 1, 0);
182
184
  this.camera.position.set(0, 0, 1);
183
185
  this.camera.lookAt(this.target);
@@ -293,15 +295,15 @@ export class Viewer
293
295
  if (!this.renderer) return;
294
296
 
295
297
  const camera = this.camera as any;
296
- const aspect = width / height;
298
+ const aspectRatio = width / height;
297
299
 
298
300
  if (camera.isPerspectiveCamera) {
299
- camera.aspect = aspect;
301
+ camera.aspect = aspectRatio;
300
302
  camera.updateProjectionMatrix();
301
303
  }
302
304
  if (camera.isOrthographicCamera) {
303
- camera.left = camera.bottom * aspect;
304
- camera.right = camera.top * aspect;
305
+ camera.left = camera.bottom * aspectRatio;
306
+ camera.right = camera.top * aspectRatio;
305
307
  camera.updateProjectionMatrix();
306
308
  }
307
309
 
@@ -313,16 +315,20 @@ export class Viewer
313
315
  }
314
316
 
315
317
  update(force = false): void {
318
+ const time = performance.now();
319
+ force = force || time - this._renderTime >= this._updateDelay;
320
+
316
321
  this._renderNeeded = true;
317
- if (force) this.render();
318
- this.emitEvent({ type: "update", data: force });
322
+ if (force) this.render(time);
323
+
324
+ this.emitEvent({ type: "update", force });
319
325
  }
320
326
 
321
327
  // Internal render routines
322
328
 
323
- render(time?: DOMHighResTimeStamp, force = false): void {
329
+ render(time?: DOMHighResTimeStamp): void {
324
330
  if (!this.renderer) return;
325
- if (!this._renderNeeded && !force) return;
331
+ if (!this._renderNeeded) return;
326
332
 
327
333
  if (!time) time = performance.now();
328
334
  const deltaTime = (time - this._renderTime) / 1000;
@@ -671,13 +677,13 @@ export class Viewer
671
677
  if (orthogonal_camera) {
672
678
  const extentsSize = this.extents.getBoundingSphere(new Sphere()).radius * 2;
673
679
  const rendererSize = this.renderer.getSize(new Vector2());
674
- const aspect = rendererSize.x / rendererSize.y;
680
+ const aspectRatio = rendererSize.x / rendererSize.y;
675
681
 
676
682
  const camera = new OrthographicCamera();
677
683
  camera.top = orthogonal_camera.field_height / 2;
678
684
  camera.bottom = -orthogonal_camera.field_height / 2;
679
- camera.left = camera.bottom * aspect;
680
- camera.right = camera.top * aspect;
685
+ camera.left = camera.bottom * aspectRatio;
686
+ camera.right = camera.top * aspectRatio;
681
687
  camera.near = 0;
682
688
  camera.far = extentsSize * 1000;
683
689
  camera.zoom = orthogonal_camera.view_to_world_scale;
@@ -693,6 +699,7 @@ export class Viewer
693
699
  this.helpersPass.camera = camera;
694
700
  this.ssaaRenderPass.camera = camera;
695
701
 
702
+ this.options.cameraMode = "orthographic";
696
703
  this.emitEvent({ type: "changecameramode", mode: "orthographic" });
697
704
  }
698
705
  };
@@ -701,11 +708,11 @@ export class Viewer
701
708
  if (perspective_camera) {
702
709
  const extentsSize = this.extents.getBoundingSphere(new Sphere()).radius * 2;
703
710
  const rendererSize = this.renderer.getSize(new Vector2());
704
- const aspect = rendererSize.x / rendererSize.y;
711
+ const aspectRatio = rendererSize.x / rendererSize.y;
705
712
 
706
713
  const camera = new PerspectiveCamera();
707
714
  camera.fov = perspective_camera.field_of_view;
708
- camera.aspect = aspect;
715
+ camera.aspect = aspectRatio;
709
716
  camera.near = extentsSize / 1000;
710
717
  camera.far = extentsSize * 1000;
711
718
  camera.updateProjectionMatrix();
@@ -720,6 +727,7 @@ export class Viewer
720
727
  this.helpersPass.camera = camera;
721
728
  this.ssaaRenderPass.camera = camera;
722
729
 
730
+ this.options.cameraMode = "perspective";
723
731
  this.emitEvent({ type: "changecameramode", mode: "perspective" });
724
732
  }
725
733
  };
@@ -760,6 +768,8 @@ export class Viewer
760
768
 
761
769
  this.target.copy(getVector3FromPoint3d(viewpoint.custom_fields?.camera_target ?? this.target));
762
770
 
771
+ this.syncOverlay();
772
+
763
773
  this.setActiveDragger(draggerName);
764
774
  this.emitEvent({ type: "drawviewpoint", data: viewpoint });
765
775
  this.update();
@@ -27,8 +27,8 @@ export function getSelected2(viewer: Viewer): string[] {
27
27
  const handles2 = [];
28
28
 
29
29
  viewer.models.forEach((model) => {
30
- handles2.push(...model.getHandlesByObjects(viewer.selected));
30
+ handles2.push(model.getHandlesByObjects(viewer.selected));
31
31
  });
32
32
 
33
- return handles2;
33
+ return handles2.flat();
34
34
  }
@@ -31,7 +31,7 @@ export function zoomTo(viewer: Viewer, box: Box3): void {
31
31
  const boxSize = box.getBoundingSphere(new Sphere()).radius;
32
32
 
33
33
  const rendererSize = viewer.renderer.getSize(new Vector2());
34
- const aspect = rendererSize.x / rendererSize.y;
34
+ const aspectRatio = rendererSize.x / rendererSize.y;
35
35
 
36
36
  const camera = viewer.camera as any;
37
37
 
@@ -46,8 +46,8 @@ export function zoomTo(viewer: Viewer, box: Box3): void {
46
46
  if (camera.isOrthographicCamera) {
47
47
  camera.top = boxSize;
48
48
  camera.bottom = -boxSize;
49
- camera.left = camera.bottom * aspect;
50
- camera.right = camera.top * aspect;
49
+ camera.left = camera.bottom * aspectRatio;
50
+ camera.right = camera.top * aspectRatio;
51
51
  camera.zoom = 1;
52
52
  camera.updateProjectionMatrix();
53
53
 
@@ -49,16 +49,16 @@ export class CameraComponent implements IComponent {
49
49
  switchCamera(camera: any) {
50
50
  const extentsSize = this.viewer.extents.getBoundingSphere(new Sphere()).radius * 2 || 1;
51
51
  const rendererSize = this.viewer.renderer.getSize(new Vector2());
52
- const aspect = rendererSize.x / rendererSize.y;
52
+ const aspectRatio = rendererSize.x / rendererSize.y;
53
53
 
54
54
  if (camera.isPerspectiveCamera) {
55
- camera.aspect = aspect;
55
+ camera.aspect = aspectRatio;
56
56
  camera.near = extentsSize / 1000;
57
57
  camera.far = extentsSize * 1000;
58
58
  }
59
59
  if (camera.isOrthographicCamera) {
60
- camera.left = camera.bottom * aspect;
61
- camera.right = camera.top * aspect;
60
+ camera.left = camera.bottom * aspectRatio;
61
+ camera.right = camera.top * aspectRatio;
62
62
  camera.near = 0;
63
63
  camera.far = extentsSize * 1000;
64
64
  }
@@ -50,13 +50,13 @@ export class ExtentsComponent implements IComponent {
50
50
  this.viewer.off("showall", this.syncExtents);
51
51
  }
52
52
 
53
- syncExtents = () => {
53
+ syncExtents = (event) => {
54
54
  const extents = new Box3();
55
55
  this.viewer.models.forEach((model) => model.getExtents(extents));
56
56
  this.viewer.extents.copy(extents);
57
57
 
58
- // do not change target after opening the second file in assembly
59
- if (this.viewer.models.length > 1) return;
58
+ if (event.type !== "databasechunk" && event.target !== "clear") return;
59
+ if (this.viewer.models.length > 1) return; // do not change target in assembly mode
60
60
 
61
61
  this.viewer.extents.getCenter(this.viewer.target);
62
62
  };
@@ -78,12 +78,12 @@ export class HighlighterComponent implements IComponent {
78
78
  const { edgesVisibility } = this.viewer.options;
79
79
 
80
80
  if (!Array.isArray(objects)) objects = [objects];
81
- if (!objects.length) return;
81
+ if (objects.length === 0) return;
82
82
 
83
83
  objects
84
84
  .filter((object) => !object.userData.isEdge) // <- filtering server generated edges
85
85
  .forEach((object: any) => {
86
- if (object.isHighlighted) return;
86
+ if (object.userData.isHighlighted) return;
87
87
 
88
88
  if (object.isLine || object.isLineSegments) {
89
89
  const positions = object.geometry.attributes.position.array;
@@ -93,48 +93,42 @@ export class HighlighterComponent implements IComponent {
93
93
  : HighlighterUtils.fromNonIndexedLine(positions, object.isLineSegments);
94
94
 
95
95
  const wireframe = new Wireframe(lineGeometry, this.lineGlowMaterial);
96
- wireframe.position.copy(object.position);
97
- wireframe.rotation.copy(object.rotation);
98
- wireframe.scale.copy(object.scale);
99
96
  wireframe.visible = edgesVisibility;
97
+ wireframe.userData.isHighlightWireframe = true;
100
98
 
101
- object.parent.add(wireframe);
99
+ object.add(wireframe);
102
100
  object.userData.highlightWireframe = wireframe;
103
-
104
101
  object.userData.originalMaterial = object.material;
105
102
  object.material = this.lineMaterial;
106
- object.isHighlighted = true;
103
+ object.userData.isHighlighted = true;
107
104
  } else if (object.isMesh) {
108
105
  const edgesGeometry = new EdgesGeometry(object.geometry, 89);
109
106
  const lineGeometry = new LineSegmentsGeometry().fromEdgesGeometry(edgesGeometry);
110
107
 
111
108
  const wireframe = new Wireframe(lineGeometry, this.edgesMaterial);
112
- wireframe.position.copy(object.position);
113
- wireframe.rotation.copy(object.rotation);
114
- wireframe.scale.copy(object.scale);
115
109
  wireframe.visible = edgesVisibility;
110
+ wireframe.userData.isHighlightWireframe = true;
116
111
 
117
- object.parent.add(wireframe);
112
+ object.add(wireframe);
118
113
  object.userData.highlightWireframe = wireframe;
119
-
120
114
  object.userData.originalMaterial = object.material;
121
115
  object.material = this.facesMaterial;
122
- object.isHighlighted = true;
116
+ object.userData.isHighlighted = true;
123
117
  }
124
118
  });
125
119
  }
126
120
 
127
121
  unhighlight(objects: Object3D | Object3D[]) {
128
122
  if (!Array.isArray(objects)) objects = [objects];
129
- if (!objects.length) return;
123
+ if (objects.length === 0) return;
130
124
 
131
125
  objects.forEach((object: any) => {
132
- if (!object.isHighlighted) return;
126
+ if (!object.userData.isHighlighted) return;
133
127
 
134
- object.isHighlighted = false;
135
128
  object.material = object.userData.originalMaterial;
136
129
  object.userData.highlightWireframe.removeFromParent();
137
130
 
131
+ delete object.userData.isHighlighted;
138
132
  delete object.userData.originalMaterial;
139
133
  delete object.userData.highlightWireframe;
140
134
  });
@@ -21,7 +21,7 @@
21
21
  // acknowledge and accept the above terms.
22
22
  ///////////////////////////////////////////////////////////////////////////////
23
23
 
24
- import { Object3D, Vector2 } from "three";
24
+ import { Object3D, Vector2, Vector3 } from "three";
25
25
 
26
26
  import type { IComponent } from "@inweb/viewer-core";
27
27
  import type { Viewer } from "../Viewer";
@@ -64,6 +64,7 @@ export class SelectionComponent implements IComponent {
64
64
  if (upPosition.distanceTo(this.downPosition) !== 0) return;
65
65
 
66
66
  const snapper = new Snapper(this.viewer.camera, this.viewer.renderer, this.viewer.canvas);
67
+ snapper.threshold = this.viewer.extents.getSize(new Vector3()).length() / 10000;
67
68
 
68
69
  let intersections = [];
69
70
  this.viewer.models.forEach((model) => {
@@ -107,13 +108,13 @@ export class SelectionComponent implements IComponent {
107
108
  }
108
109
 
109
110
  if (!Array.isArray(objects)) objects = [objects];
110
- if (!objects.length) return;
111
+ if (objects.length === 0) return;
111
112
 
112
- model.showOriginalObjects(objects);
113
+ model.highlightObjects(objects);
113
114
  this.highlighter.highlight(objects);
114
115
 
115
- objects.forEach((object: any) => this.viewer.selected.push(object));
116
- objects.forEach((object: any) => (object.isSelected = true));
116
+ objects.forEach((object) => this.viewer.selected.push(object));
117
+ objects.forEach((object) => (object.userData.isSelected = true));
117
118
  }
118
119
 
119
120
  deselect(objects: Object3D | Object3D[], model?: IModelImpl) {
@@ -123,30 +124,30 @@ export class SelectionComponent implements IComponent {
123
124
  }
124
125
 
125
126
  if (!Array.isArray(objects)) objects = [objects];
126
- if (!objects.length) return;
127
+ if (objects.length === 0) return;
127
128
 
129
+ model.unhighlightObjects(objects);
128
130
  this.highlighter.unhighlight(objects);
129
- model.hideOriginalObjects(objects);
130
131
 
131
132
  this.viewer.selected = this.viewer.selected.filter((x) => !objects.includes(x));
132
- objects.forEach((object: any) => (object.isSelected = false));
133
+ objects.forEach((object) => (object.userData.isSelected = false));
133
134
  }
134
135
 
135
136
  toggleSelection(objects: Object3D | Object3D[], model?: IModelImpl) {
136
137
  if (!Array.isArray(objects)) objects = [objects];
137
- if (!objects.length) return;
138
+ if (objects.length === 0) return;
138
139
 
139
- if ((objects[0] as any).isSelected) this.deselect(objects, model);
140
+ if (objects[0].userData.isSelected) this.deselect(objects, model);
140
141
  else this.select(objects, model);
141
142
  }
142
143
 
143
144
  clearSelection() {
144
- if (!this.viewer.selected.length) return;
145
+ if (this.viewer.selected.length === 0) return;
145
146
 
147
+ this.viewer.models.forEach((model) => model.unhighlightObjects(this.viewer.selected));
146
148
  this.highlighter.unhighlight(this.viewer.selected);
147
- this.viewer.models.forEach((model) => model.hideOriginalObjects(this.viewer.selected));
148
149
 
149
- this.viewer.selected.forEach((object: any) => (object.isSelected = false));
150
+ this.viewer.selected.forEach((object) => (object.userData.isSelected = false));
150
151
  this.viewer.selected.length = 0;
151
152
  }
152
153
 
@@ -50,6 +50,7 @@ export class MeasureLineDragger extends OrbitDragger {
50
50
  this.overlay.addLine(this.line);
51
51
 
52
52
  this.snapper = new Snapper(viewer.camera, viewer.renderer, viewer.canvas);
53
+ this.snapper.threshold = viewer.extents.getSize(new Vector3()).length() / 10000;
53
54
 
54
55
  this.objects = [];
55
56
  this.updateObjects();
@@ -43,6 +43,7 @@ export class OrbitDragger implements IDragger {
43
43
  this.changed = false;
44
44
  this.viewer = viewer;
45
45
  this.viewer.addEventListener("databasechunk", this.updateControls);
46
+ this.viewer.addEventListener("clear", this.updateControls);
46
47
  this.viewer.on("viewposition", this.updateControls);
47
48
  this.viewer.addEventListener("zoom", this.updateControls);
48
49
  this.viewer.addEventListener("drawviewpoint", this.updateControls);
@@ -56,6 +57,7 @@ export class OrbitDragger implements IDragger {
56
57
 
57
58
  dispose(): void {
58
59
  this.viewer.removeEventListener("databasechunk", this.updateControls);
60
+ this.viewer.removeEventListener("clear", this.updateControls);
59
61
  this.viewer.off("viewposition", this.updateControls);
60
62
  this.viewer.removeEventListener("zoom", this.updateControls);
61
63
  this.viewer.removeEventListener("drawviewpoint", this.updateControls);