@inweb/viewer-three 27.4.6 → 27.5.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 (64) hide show
  1. package/dist/extensions/components/AxesHelperComponent.js +3 -0
  2. package/dist/extensions/components/AxesHelperComponent.js.map +1 -1
  3. package/dist/extensions/components/AxesHelperComponent.min.js +1 -1
  4. package/dist/extensions/components/AxesHelperComponent.module.js +3 -0
  5. package/dist/extensions/components/AxesHelperComponent.module.js.map +1 -1
  6. package/dist/extensions/components/ExtentsHelperComponent.js +6 -2
  7. package/dist/extensions/components/ExtentsHelperComponent.js.map +1 -1
  8. package/dist/extensions/components/ExtentsHelperComponent.min.js +1 -1
  9. package/dist/extensions/components/ExtentsHelperComponent.module.js +6 -2
  10. package/dist/extensions/components/ExtentsHelperComponent.module.js.map +1 -1
  11. package/dist/extensions/components/GridHelperComponent.js +1 -0
  12. package/dist/extensions/components/GridHelperComponent.js.map +1 -1
  13. package/dist/extensions/components/GridHelperComponent.min.js +1 -1
  14. package/dist/extensions/components/GridHelperComponent.module.js +1 -0
  15. package/dist/extensions/components/GridHelperComponent.module.js.map +1 -1
  16. package/dist/extensions/components/LightHelperComponent.js +1 -0
  17. package/dist/extensions/components/LightHelperComponent.js.map +1 -1
  18. package/dist/extensions/components/LightHelperComponent.min.js +1 -1
  19. package/dist/extensions/components/LightHelperComponent.module.js +1 -0
  20. package/dist/extensions/components/LightHelperComponent.module.js.map +1 -1
  21. package/dist/viewer-three.js +1765 -438
  22. package/dist/viewer-three.js.map +1 -1
  23. package/dist/viewer-three.min.js +4 -4
  24. package/dist/viewer-three.module.js +1302 -403
  25. package/dist/viewer-three.module.js.map +1 -1
  26. package/extensions/components/AxesHelperComponent.ts +3 -0
  27. package/extensions/components/ExtentsHelperComponent.ts +5 -2
  28. package/extensions/components/GridHelperComponent.ts +1 -0
  29. package/extensions/components/LightHelperComponent.ts +1 -0
  30. package/lib/Viewer/Viewer.d.ts +5 -7
  31. package/lib/Viewer/components/CameraComponent.d.ts +1 -1
  32. package/lib/Viewer/components/ClippingPlaneComponent.d.ts +8 -0
  33. package/lib/Viewer/components/HighlighterComponent.d.ts +2 -2
  34. package/lib/Viewer/components/InfoComponent.d.ts +1 -1
  35. package/lib/Viewer/components/SectionsComponent.d.ts +15 -0
  36. package/lib/Viewer/components/WCSHelperComponent.d.ts +2 -2
  37. package/lib/Viewer/draggers/CuttingPlaneDragger.d.ts +6 -6
  38. package/lib/Viewer/draggers/OrbitDragger.d.ts +1 -1
  39. package/lib/Viewer/measurement/Snapper.d.ts +3 -3
  40. package/package.json +5 -5
  41. package/src/Viewer/Viewer.ts +50 -37
  42. package/src/Viewer/commands/index.ts +1 -1
  43. package/src/Viewer/components/BackgroundComponent.ts +1 -0
  44. package/src/Viewer/components/CameraComponent.ts +5 -6
  45. package/src/Viewer/{scenes/Helpers.ts → components/ClippingPlaneComponent.ts} +22 -12
  46. package/src/Viewer/components/HighlighterComponent.ts +9 -5
  47. package/src/Viewer/components/InfoComponent.ts +4 -4
  48. package/src/Viewer/components/SectionsComponent.ts +119 -0
  49. package/src/Viewer/components/SelectionComponent.ts +1 -1
  50. package/src/Viewer/components/WCSHelperComponent.ts +8 -6
  51. package/src/Viewer/components/index.ts +4 -0
  52. package/src/Viewer/draggers/CuttingPlaneDragger.ts +57 -34
  53. package/src/Viewer/draggers/MeasureLineDragger.ts +1 -1
  54. package/src/Viewer/draggers/OrbitDragger.ts +3 -3
  55. package/src/Viewer/helpers/SectionsHelper.js +1065 -0
  56. package/src/Viewer/helpers/WCSHelper.ts +24 -0
  57. package/src/Viewer/loaders/DynamicGltfLoader/DynamicGltfLoader.js +417 -92
  58. package/src/Viewer/loaders/DynamicGltfLoader/GltfStructure.js +75 -9
  59. package/src/Viewer/loaders/GLTFCloudDynamicLoader.ts +3 -2
  60. package/src/Viewer/loaders/GLTFFileDynamicLoader.ts +4 -2
  61. package/src/Viewer/measurement/Snapper.ts +4 -5
  62. package/src/Viewer/models/ModelImpl.ts +27 -3
  63. package/lib/Viewer/scenes/Helpers.d.ts +0 -7
  64. package/src/Viewer/postprocessing/SSAARenderPass.js +0 -245
@@ -62,7 +62,7 @@ export class HighlighterComponent implements IComponent {
62
62
  }
63
63
 
64
64
  this.viewer.addEventListener("databasechunk", this.geometryEnd);
65
- this.viewer.addEventListener("optionschange", this.optionsChange);
65
+ this.viewer.addEventListener("optionschange", this.syncOptions);
66
66
  this.viewer.addEventListener("resize", this.viewerResize);
67
67
 
68
68
  this.geometryEnd();
@@ -70,7 +70,7 @@ export class HighlighterComponent implements IComponent {
70
70
 
71
71
  dispose() {
72
72
  this.viewer.removeEventListener("databasechunk", this.geometryEnd);
73
- this.viewer.removeEventListener("optionschange", this.optionsChange);
73
+ this.viewer.removeEventListener("optionschange", this.syncOptions);
74
74
  this.viewer.removeEventListener("resize", this.viewerResize);
75
75
  }
76
76
 
@@ -143,17 +143,20 @@ export class HighlighterComponent implements IComponent {
143
143
  polygonOffset: true,
144
144
  polygonOffsetFactor: 1,
145
145
  polygonOffsetUnits: 1,
146
+ clippingPlanes: this.viewer.clippingPlanes,
146
147
  });
147
148
 
148
149
  this.edgesMaterial = new LineMaterial({
149
150
  linewidth: 1.5,
150
151
  resolution: new Vector2(window.innerWidth, window.innerHeight),
152
+ clippingPlanes: this.viewer.clippingPlanes,
151
153
  });
152
154
 
153
155
  this.lineMaterial = new LineBasicMaterial({
154
156
  transparent: true,
155
157
  depthTest: true,
156
158
  depthWrite: true,
159
+ clippingPlanes: this.viewer.clippingPlanes,
157
160
  });
158
161
 
159
162
  this.lineGlowMaterial = new LineMaterial({
@@ -161,12 +164,13 @@ export class HighlighterComponent implements IComponent {
161
164
  transparent: true,
162
165
  opacity: 0.8,
163
166
  resolution: new Vector2(window.innerWidth, window.innerHeight),
167
+ clippingPlanes: this.viewer.clippingPlanes,
164
168
  });
165
169
 
166
170
  this.syncHighlightColors();
167
171
  };
168
172
 
169
- optionsChange = () => {
173
+ syncOptions = () => {
170
174
  this.syncHighlightColors();
171
175
  this.viewer.update();
172
176
  };
@@ -198,9 +202,9 @@ export class HighlighterComponent implements IComponent {
198
202
  });
199
203
  }
200
204
 
201
- viewerResize(event: ResizeEvent) {
205
+ viewerResize = (event: ResizeEvent) => {
202
206
  this.renderTarget?.setSize(event.width, event.height);
203
207
  this.edgesMaterial?.resolution.set(event.width, event.height);
204
208
  this.lineGlowMaterial?.resolution.set(event.width, event.height);
205
- }
209
+ };
206
210
  }
@@ -40,7 +40,7 @@ export class InfoComponent implements IComponent {
40
40
  this.frames = 0;
41
41
  this.viewer.addEventListener("initialize", this.initialize);
42
42
  this.viewer.addEventListener("clear", this.clear);
43
- this.viewer.addEventListener("optionschange", this.optionsChange);
43
+ this.viewer.addEventListener("optionschange", this.syncOptions);
44
44
  this.viewer.addEventListener("geometrystart", this.geometryStart);
45
45
  this.viewer.addEventListener("databasechunk", this.databaseChunk);
46
46
  this.viewer.addEventListener("geometryend", this.geometryEnd);
@@ -52,7 +52,7 @@ export class InfoComponent implements IComponent {
52
52
  dispose() {
53
53
  this.viewer.removeEventListener("initialize", this.initialize);
54
54
  this.viewer.removeEventListener("clear", this.clear);
55
- this.viewer.removeEventListener("optionschange", this.optionsChange);
55
+ this.viewer.removeEventListener("optionschange", this.syncOptions);
56
56
  this.viewer.removeEventListener("geometrystart", this.geometryStart);
57
57
  this.viewer.removeEventListener("databasechunk", this.databaseChunk);
58
58
  this.viewer.removeEventListener("geometryend", this.geometryEnd);
@@ -79,7 +79,7 @@ export class InfoComponent implements IComponent {
79
79
 
80
80
  this.resize();
81
81
 
82
- this.optionsChange({ data: this.viewer.options });
82
+ this.syncOptions({ data: this.viewer.options });
83
83
  };
84
84
 
85
85
  clear = () => {
@@ -108,7 +108,7 @@ export class InfoComponent implements IComponent {
108
108
  this.viewer.info.memory.usedJSHeapSize = 0;
109
109
  };
110
110
 
111
- optionsChange = ({ data: options }) => {
111
+ syncOptions = ({ data: options }) => {
112
112
  if (options.antialiasing === false) this.viewer.info.render.antialiasing = "";
113
113
  else if (options.antialiasing === true) this.viewer.info.render.antialiasing = "mxaa";
114
114
  else this.viewer.info.render.antialiasing = options.antialiasing;
@@ -0,0 +1,119 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2002-2026, 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
+ // private 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-2026 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 { IComponent, RGB, ResizeEvent } from "@inweb/viewer-core";
25
+ import type { Viewer } from "../Viewer";
26
+ import { SectionsHelper } from "../helpers/SectionsHelper.js";
27
+ import { Object3D } from "three";
28
+
29
+ export class SectionsComponent implements IComponent {
30
+ private viewer: Viewer;
31
+ private sectionsHelper: SectionsHelper;
32
+ private updateTimerId = 0;
33
+ private updateDelay = 250;
34
+
35
+ constructor(viewer: Viewer) {
36
+ this.sectionsHelper = new SectionsHelper();
37
+
38
+ this.viewer = viewer;
39
+ this.viewer.addEventListener("initialize", this.syncHelper);
40
+ this.viewer.addEventListener("databasechunk", this.syncHelper);
41
+ this.viewer.addEventListener("drawviewpoint", this.syncHelper);
42
+ this.viewer.addEventListener("changecuttingplanes", this.syncSections);
43
+ this.viewer.addEventListener("explode", this.syncSections);
44
+ this.viewer.addEventListener("hide", this.syncSections);
45
+ this.viewer.addEventListener("isolate", this.syncSections);
46
+ this.viewer.addEventListener("show", this.syncSections);
47
+ this.viewer.addEventListener("showall", this.syncSections);
48
+ this.viewer.addEventListener("resize", this.viewerResize);
49
+ this.viewer.addEventListener("optionschange", this.syncOptions);
50
+
51
+ this.syncOptions();
52
+ }
53
+
54
+ dispose() {
55
+ clearTimeout(this.updateTimerId);
56
+
57
+ this.sectionsHelper.removeFromParent();
58
+ this.sectionsHelper.dispose();
59
+
60
+ this.viewer.removeEventListener("initialize", this.syncHelper);
61
+ this.viewer.removeEventListener("databasechunk", this.syncHelper);
62
+ this.viewer.removeEventListener("drawviewpoint", this.syncHelper);
63
+ this.viewer.removeEventListener("changecuttingplanes", this.syncSections);
64
+ this.viewer.removeEventListener("explode", this.syncSections);
65
+ this.viewer.removeEventListener("hide", this.syncSections);
66
+ this.viewer.removeEventListener("isolate", this.syncSections);
67
+ this.viewer.removeEventListener("show", this.syncSections);
68
+ this.viewer.removeEventListener("showall", this.syncSections);
69
+ this.viewer.removeEventListener("resize", this.viewerResize);
70
+ this.viewer.removeEventListener("optionschange", this.syncOptions);
71
+ }
72
+
73
+ syncOptions = () => {
74
+ function rgbToHex(c: any): string {
75
+ const hex = (v = 0) => v.toString(16).padStart(2, "0");
76
+ return "#" + hex(c.r) + hex(c.g) + hex(c.b);
77
+ }
78
+
79
+ const options = this.viewer.options;
80
+ const flags = this.sectionsHelper.flags;
81
+
82
+ flags.fillEnabled = options.enableSectionFill;
83
+ flags.fillColor = rgbToHex(options.sectionFillColor);
84
+ flags.useObjFillColor = options.sectionUseObjectColor;
85
+ flags.hatchEnabled = options.enableSectionHatch;
86
+ flags.hatchColor = rgbToHex(options.sectionHatchColor);
87
+ flags.hatchScale = options.sectionHatchScale;
88
+ flags.outlineEnabled = options.enableSectionOutline;
89
+ flags.outlineColor = rgbToHex(options.sectionOutlineColor);
90
+ flags.outlineWidth = options.sectionOutlineWidth;
91
+
92
+ this.syncSections();
93
+ };
94
+
95
+ syncHelper = () => {
96
+ this.sectionsHelper.removeFromParent();
97
+ this.viewer.helpers.add(this.sectionsHelper);
98
+ };
99
+
100
+ syncSections = () => {
101
+ this.sectionsHelper.visible = false;
102
+ clearTimeout(this.updateTimerId);
103
+ this.updateTimerId = window.setTimeout(this.updateSections, this.updateDelay);
104
+ };
105
+
106
+ viewerResize = (event: ResizeEvent) => {
107
+ this.sectionsHelper.setSize(event.width, event.height);
108
+ };
109
+
110
+ updateSections = () => {
111
+ const objects: Object3D[][] = [];
112
+ this.viewer.models.forEach((model) => objects.push(model.getVisibleObjects()));
113
+ const objects2 = objects.flat();
114
+
115
+ this.sectionsHelper.update(objects2, this.viewer.extents, this.viewer.clippingPlanes);
116
+ this.sectionsHelper.visible = true;
117
+ this.viewer.update();
118
+ };
119
+ }
@@ -65,7 +65,7 @@ export class SelectionComponent implements IComponent {
65
65
 
66
66
  const extentsSize = this.viewer.extents.getSize(new Vector3()).length() || 1;
67
67
 
68
- const snapper = new Snapper(this.viewer.camera, this.viewer.renderer, this.viewer.canvas);
68
+ const snapper = new Snapper(this.viewer.camera, this.viewer.clippingPlanes, this.viewer.canvas);
69
69
  snapper.threshold = extentsSize / 10000;
70
70
 
71
71
  let intersections = [];
@@ -26,27 +26,29 @@ import type { Viewer } from "../Viewer";
26
26
  import { WCSHelper } from "../helpers/WCSHelper";
27
27
 
28
28
  export class WCSHelperComponent implements IComponent {
29
- private wcsHelper: WCSHelper;
30
29
  private viewer: Viewer;
30
+ private wcsHelper: WCSHelper;
31
31
 
32
32
  constructor(viewer: Viewer) {
33
33
  this.wcsHelper = new WCSHelper(viewer.camera);
34
+
34
35
  this.viewer = viewer;
35
- this.viewer.addEventListener("databasechunk", this.geometryEnd);
36
- this.viewer.addEventListener("drawviewpoint", this.geometryEnd);
36
+ this.viewer.addEventListener("databasechunk", this.syncHelper);
37
+ this.viewer.addEventListener("drawviewpoint", this.syncHelper);
37
38
  this.viewer.addEventListener("render", this.viewerRender);
38
39
  this.viewer.addEventListener("changecameramode", this.updateHelperCamera);
39
40
  }
40
41
 
41
42
  dispose() {
42
- this.viewer.removeEventListener("databasechunk", this.geometryEnd);
43
- this.viewer.removeEventListener("drawviewpoint", this.geometryEnd);
43
+ this.viewer.removeEventListener("databasechunk", this.syncHelper);
44
+ this.viewer.removeEventListener("drawviewpoint", this.syncHelper);
44
45
  this.viewer.removeEventListener("render", this.viewerRender);
45
46
  this.viewer.removeEventListener("changecameramode", this.updateHelperCamera);
47
+
46
48
  this.wcsHelper.dispose();
47
49
  }
48
50
 
49
- geometryEnd = () => {
51
+ syncHelper = () => {
50
52
  this.wcsHelper.dispose();
51
53
  this.wcsHelper = new WCSHelper(this.viewer.camera);
52
54
  };
@@ -33,6 +33,8 @@ import { CanvasRemoveComponent } from "./CanvasRemoveComponent";
33
33
  import { RenderLoopComponent } from "./RenderLoopComponent";
34
34
  import { HighlighterComponent } from "./HighlighterComponent";
35
35
  import { SelectionComponent } from "./SelectionComponent";
36
+ import { ClippingPlaneComponent } from "./ClippingPlaneComponent";
37
+ import { SectionsComponent } from "./SectionsComponent";
36
38
  import { WCSHelperComponent } from "./WCSHelperComponent";
37
39
  import { ResetComponent } from "./ResetComponent";
38
40
 
@@ -88,5 +90,7 @@ components.registerComponent("CanvasRemoveComponent", (viewer) => new CanvasRemo
88
90
  components.registerComponent("RenderLoopComponent", (viewer) => new RenderLoopComponent(viewer));
89
91
  components.registerComponent("HighlighterComponent", (viewer) => new HighlighterComponent(viewer));
90
92
  components.registerComponent("SelectionComponent", (viewer) => new SelectionComponent(viewer));
93
+ components.registerComponent("ClippingPlaneComponent", (viewer) => new ClippingPlaneComponent(viewer));
94
+ components.registerComponent("SectionsComponent", (viewer) => new SectionsComponent(viewer));
91
95
  components.registerComponent("WCSHelperComponent", (viewer) => new WCSHelperComponent(viewer));
92
96
  components.registerComponent("ResetComponent", (viewer) => new ResetComponent(viewer));
@@ -31,9 +31,8 @@ import { Snapper } from "../measurement/Snapper";
31
31
  import { OrbitDragger } from "./OrbitDragger";
32
32
 
33
33
  export class CuttingPlaneDragger extends OrbitDragger {
34
- protected clippingPlanes: Plane[];
35
34
  protected helpers: PlaneHelper2[] = [];
36
- protected activeHelper: PlaneHelper2 = null;
35
+ protected activeHelper: PlaneHelper2 | undefined = undefined;
37
36
  protected snapper: Snapper;
38
37
  protected downPosition: Vector2;
39
38
  protected position0: Vector3;
@@ -44,14 +43,11 @@ export class CuttingPlaneDragger extends OrbitDragger {
44
43
  constructor(viewer: Viewer) {
45
44
  super(viewer);
46
45
 
47
- if (!viewer.renderer.clippingPlanes) viewer.renderer.clippingPlanes = [];
48
-
49
- this.clippingPlanes = viewer.renderer.clippingPlanes;
50
- this.clippingPlanes.forEach((plane) => this.addHelper(plane));
46
+ viewer.clippingPlanes.forEach((plane) => this.addHelper(plane));
51
47
 
52
48
  const extentsSize = viewer.extents.getSize(new Vector3()).length() || 1;
53
49
 
54
- this.snapper = new Snapper(viewer.camera, viewer.renderer, viewer.canvas);
50
+ this.snapper = new Snapper(viewer.camera, viewer.clippingPlanes, viewer.canvas);
55
51
  this.snapper.threshold = extentsSize / 10000;
56
52
 
57
53
  this.downPosition = new Vector2();
@@ -64,7 +60,8 @@ export class CuttingPlaneDragger extends OrbitDragger {
64
60
  this.translate.showX = false;
65
61
  this.translate.showY = false;
66
62
  this.translate.showZ = true;
67
- this.translate.addEventListener("change", this.transformChange);
63
+ this.translate.addEventListener("change", this.transformUpdate);
64
+ this.translate.addEventListener("objectChange", this.transformChange);
68
65
  this.translate.addEventListener("dragging-changed", this.translateDrag);
69
66
  this.viewer.helpers.add(this.translate.getHelper());
70
67
 
@@ -74,21 +71,26 @@ export class CuttingPlaneDragger extends OrbitDragger {
74
71
  this.rotate.showX = true;
75
72
  this.rotate.showY = true;
76
73
  this.rotate.showZ = false;
77
- this.rotate.addEventListener("change", this.transformChange);
74
+ this.rotate.addEventListener("change", this.transformUpdate);
75
+ this.rotate.addEventListener("objectChange", this.transformChange);
78
76
  this.rotate.addEventListener("dragging-changed", this.rotateDrag);
79
77
  this.viewer.helpers.add(this.rotate.getHelper());
80
78
 
81
79
  this.setActiveHelper(this.helpers[this.helpers.length - 1]);
82
80
 
83
- this.viewer.addEventListener("explode", this.updatePlaneSize);
84
- this.viewer.addEventListener("show", this.updatePlaneSize);
85
- this.viewer.addEventListener("showall", this.updatePlaneSize);
86
- this.viewer.addEventListener("changecameramode", this.updateTransformCamera);
81
+ this.viewer.addEventListener("explode", this.syncHelpers);
82
+ this.viewer.addEventListener("hide", this.syncHelpers);
83
+ this.viewer.addEventListener("isolate", this.syncHelpers);
84
+ this.viewer.addEventListener("show", this.syncHelpers);
85
+ this.viewer.addEventListener("showall", this.syncHelpers);
87
86
  this.viewer.addEventListener("clearslices", this.clearHelpers);
87
+ this.viewer.addEventListener("changecameramode", this.updateTransformCamera);
88
+
88
89
  this.viewer.canvas.addEventListener("pointerdown", this.onPointerDown, true);
89
90
  this.viewer.canvas.addEventListener("pointerup", this.onPointerUp, true);
90
91
  this.viewer.canvas.addEventListener("pointercancel", this.onPointerCancel, true);
91
92
  this.viewer.canvas.addEventListener("dblclick", this.onDoubleClick, true);
93
+
92
94
  window.addEventListener("keydown", this.onKeyDown);
93
95
  window.addEventListener("keyup", this.onKeyUp);
94
96
 
@@ -96,25 +98,31 @@ export class CuttingPlaneDragger extends OrbitDragger {
96
98
  }
97
99
 
98
100
  override dispose() {
99
- this.viewer.removeEventListener("explode", this.updatePlaneSize);
100
- this.viewer.removeEventListener("show", this.updatePlaneSize);
101
- this.viewer.removeEventListener("showall", this.updatePlaneSize);
102
- this.viewer.removeEventListener("changecameramode", this.updateTransformCamera);
101
+ this.viewer.removeEventListener("explode", this.syncHelpers);
102
+ this.viewer.removeEventListener("hide", this.syncHelpers);
103
+ this.viewer.removeEventListener("isolate", this.syncHelpers);
104
+ this.viewer.removeEventListener("show", this.syncHelpers);
105
+ this.viewer.removeEventListener("showall", this.syncHelpers);
103
106
  this.viewer.removeEventListener("clearslices", this.clearHelpers);
107
+ this.viewer.removeEventListener("changecameramode", this.updateTransformCamera);
108
+
104
109
  this.viewer.canvas.removeEventListener("pointerdown", this.onPointerDown, true);
105
110
  this.viewer.canvas.removeEventListener("pointerup", this.onPointerUp, true);
106
111
  this.viewer.canvas.removeEventListener("pointercancel", this.onPointerCancel, true);
107
112
  this.viewer.canvas.removeEventListener("dblclick", this.onDoubleClick, true);
113
+
108
114
  window.removeEventListener("keydown", this.onKeyDown);
109
115
  window.removeEventListener("keyup", this.onKeyUp);
110
116
 
111
- this.translate.removeEventListener("change", this.transformChange);
117
+ this.translate.removeEventListener("change", this.transformUpdate);
118
+ this.translate.removeEventListener("objectChange", this.transformChange);
112
119
  this.translate.removeEventListener("dragging-changed", this.translateDrag);
113
120
  this.translate.getHelper().removeFromParent();
114
121
  this.translate.detach();
115
122
  this.translate.dispose();
116
123
 
117
- this.rotate.removeEventListener("change", this.transformChange);
124
+ this.rotate.removeEventListener("change", this.transformUpdate);
125
+ this.rotate.removeEventListener("objectChange", this.transformChange);
118
126
  this.rotate.removeEventListener("dragging-changed", this.rotateDrag);
119
127
  this.rotate.getHelper().removeFromParent();
120
128
  this.rotate.detach();
@@ -124,12 +132,16 @@ export class CuttingPlaneDragger extends OrbitDragger {
124
132
  helper.removeFromParent();
125
133
  helper.dispose();
126
134
  });
127
- this.helpers = [];
128
- this.activeHelper = null;
135
+ this.helpers.length = 0;
136
+ this.activeHelper = undefined;
129
137
 
130
138
  super.dispose();
131
139
  }
132
140
 
141
+ transformUpdate = () => {
142
+ this.viewer.update();
143
+ };
144
+
133
145
  transformChange = () => {
134
146
  if (!this.activeHelper) return;
135
147
 
@@ -137,6 +149,7 @@ export class CuttingPlaneDragger extends OrbitDragger {
137
149
  plane.normal.copy(new Vector3(0, 0, -1)).applyQuaternion(this.activeHelper.quaternion);
138
150
  plane.constant = -this.activeHelper.position.dot(plane.normal);
139
151
 
152
+ this.viewer.emitEvent({ type: "changecuttingplanes" });
140
153
  this.viewer.update();
141
154
 
142
155
  this.changed = true; // <- cancel context menu
@@ -152,16 +165,16 @@ export class CuttingPlaneDragger extends OrbitDragger {
152
165
  this.translate.enabled = !event.value;
153
166
  };
154
167
 
155
- updatePlaneSize = () => {
168
+ syncHelpers = () => {
156
169
  const extentsSize = this.viewer.extents.getSize(new Vector3()).length() || 1;
157
- this.helpers.forEach((planeHelper) => (planeHelper.size = extentsSize));
158
- this.viewer.update();
159
- };
170
+ const extentsCenter = this.viewer.extents.getCenter(new Vector3());
160
171
 
161
- updateTransformCamera = () => {
162
- this.translate.camera = this.viewer.camera;
163
- this.rotate.camera = this.viewer.camera;
164
- this.snapper.camera = this.viewer.camera;
172
+ this.helpers.forEach((planeHelper) => {
173
+ planeHelper.size = extentsSize;
174
+ planeHelper.position.copy(planeHelper.plane.projectPoint(extentsCenter, new Vector3()));
175
+ });
176
+
177
+ this.viewer.update();
165
178
  };
166
179
 
167
180
  clearHelpers = () => {
@@ -171,11 +184,17 @@ export class CuttingPlaneDragger extends OrbitDragger {
171
184
  helper.removeFromParent();
172
185
  helper.dispose();
173
186
  });
174
- this.helpers = [];
187
+ this.helpers.length = 0;
175
188
 
176
189
  this.viewer.update();
177
190
  };
178
191
 
192
+ updateTransformCamera = () => {
193
+ this.translate.camera = this.viewer.camera;
194
+ this.rotate.camera = this.viewer.camera;
195
+ this.snapper.camera = this.viewer.camera;
196
+ };
197
+
179
198
  onKeyDown = (event: KeyboardEvent) => {
180
199
  if (event.key === "Shift") this.rotate.setRotationSnap(Math.PI / 4);
181
200
  if (event.key === "Delete" || event.key === "Backspace") this.deleteActivePlane();
@@ -209,7 +228,7 @@ export class CuttingPlaneDragger extends OrbitDragger {
209
228
  this.viewer.canvas.dispatchEvent(new PointerEvent("pointerup", event));
210
229
  };
211
230
 
212
- onDoubleClick = (event: PointerEvent) => {
231
+ onDoubleClick = (event: MouseEvent) => {
213
232
  if (!this.activeHelper) return;
214
233
 
215
234
  const mousePosition = this.snapper.getMousePosition(event, new Vector2());
@@ -287,10 +306,12 @@ export class CuttingPlaneDragger extends OrbitDragger {
287
306
  const constant = -extentsCenter.dot(normal);
288
307
 
289
308
  const plane = new Plane(normal, constant);
290
- this.clippingPlanes.push(plane);
309
+ this.viewer.clippingPlanes.push(plane);
291
310
 
292
311
  const helper = this.addHelper(plane);
293
312
  this.setActiveHelper(helper);
313
+
314
+ this.viewer.emitEvent({ type: "changecuttingplanes" });
294
315
  }
295
316
 
296
317
  addPlaneX() {
@@ -310,13 +331,15 @@ export class CuttingPlaneDragger extends OrbitDragger {
310
331
 
311
332
  const helper = this.activeHelper;
312
333
 
313
- const index = this.clippingPlanes.indexOf(helper.plane);
314
- if (index !== -1) this.clippingPlanes.splice(index, 1);
334
+ const index = this.viewer.clippingPlanes.indexOf(helper.plane);
335
+ if (index !== -1) this.viewer.clippingPlanes.splice(index, 1);
315
336
 
316
337
  this.helpers = this.helpers.filter((x) => x !== helper);
317
338
  helper.removeFromParent();
318
339
  helper.dispose();
319
340
 
320
341
  this.setActiveHelper(this.helpers[this.helpers.length - 1]);
342
+
343
+ this.viewer.emitEvent({ type: "changecuttingplanes" });
321
344
  }
322
345
  }
@@ -51,7 +51,7 @@ export class MeasureLineDragger extends OrbitDragger {
51
51
 
52
52
  const extentsSize = this.viewer.extents.getSize(new Vector3()).length() || 1;
53
53
 
54
- this.snapper = new Snapper(viewer.camera, viewer.renderer, viewer.canvas);
54
+ this.snapper = new Snapper(viewer.camera, viewer.clippingPlanes, viewer.canvas);
55
55
  this.snapper.threshold = extentsSize / 10000;
56
56
 
57
57
  this.objects = [];
@@ -48,7 +48,7 @@ export class OrbitDragger implements IDragger {
48
48
  this.viewer.addEventListener("zoom", this.updateControls);
49
49
  this.viewer.addEventListener("drawviewpoint", this.updateControls);
50
50
  this.viewer.addEventListener("changecameramode", this.updateControlsCamera);
51
- this.viewer.addEventListener("optionschange", this.optionsChange);
51
+ this.viewer.addEventListener("optionschange", this.updateZoomSpeed);
52
52
  this.viewer.addEventListener("contextmenu", this.stopContextMenu);
53
53
  this.updateControls();
54
54
  this.updateControlsCamera();
@@ -61,7 +61,7 @@ export class OrbitDragger implements IDragger {
61
61
  this.viewer.removeEventListener("zoom", this.updateControls);
62
62
  this.viewer.removeEventListener("drawviewpoint", this.updateControls);
63
63
  this.viewer.removeEventListener("changecameramode", this.updateControlsCamera);
64
- this.viewer.removeEventListener("optionschange", this.optionsChange);
64
+ this.viewer.removeEventListener("optionschange", this.updateZoomSpeed);
65
65
  this.viewer.removeEventListener("contextmenu", this.stopContextMenu);
66
66
 
67
67
  this.orbit.removeEventListener("start", this.controlsStart);
@@ -81,7 +81,7 @@ export class OrbitDragger implements IDragger {
81
81
  this.orbit.update();
82
82
  };
83
83
 
84
- optionsChange = ({ data: options }) => {
84
+ updateZoomSpeed = ({ data: options }) => {
85
85
  this.orbit.zoomSpeed = Math.abs(this.orbit.zoomSpeed) * (options.reverseZoomWheel ? -1 : 1);
86
86
  };
87
87