@inweb/viewer-three 27.4.7 → 27.6.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 (94) 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 +2 -1
  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 +2 -1
  20. package/dist/extensions/components/LightHelperComponent.module.js.map +1 -1
  21. package/dist/extensions/components/StatsPanelComponent.js +0 -1
  22. package/dist/extensions/components/StatsPanelComponent.js.map +1 -1
  23. package/dist/extensions/components/StatsPanelComponent.min.js +1 -1
  24. package/dist/extensions/components/StatsPanelComponent.module.js +0 -1
  25. package/dist/extensions/components/StatsPanelComponent.module.js.map +1 -1
  26. package/dist/extensions/loaders/GLTFCloudLoader.js +7 -2
  27. package/dist/extensions/loaders/GLTFCloudLoader.js.map +1 -1
  28. package/dist/extensions/loaders/GLTFCloudLoader.min.js +1 -1
  29. package/dist/extensions/loaders/GLTFCloudLoader.module.js +7 -2
  30. package/dist/extensions/loaders/GLTFCloudLoader.module.js.map +1 -1
  31. package/dist/extensions/loaders/GLTFFileLoader.js +2 -1
  32. package/dist/extensions/loaders/GLTFFileLoader.js.map +1 -1
  33. package/dist/extensions/loaders/GLTFFileLoader.min.js +1 -1
  34. package/dist/extensions/loaders/GLTFFileLoader.module.js +2 -1
  35. package/dist/extensions/loaders/GLTFFileLoader.module.js.map +1 -1
  36. package/dist/extensions/loaders/IFCXLoader.js +10 -5
  37. package/dist/extensions/loaders/IFCXLoader.js.map +1 -1
  38. package/dist/extensions/loaders/IFCXLoader.min.js +1 -1
  39. package/dist/extensions/loaders/IFCXLoader.module.js +10 -5
  40. package/dist/extensions/loaders/IFCXLoader.module.js.map +1 -1
  41. package/dist/viewer-three.js +1901 -569
  42. package/dist/viewer-three.js.map +1 -1
  43. package/dist/viewer-three.min.js +4 -4
  44. package/dist/viewer-three.module.js +1366 -451
  45. package/dist/viewer-three.module.js.map +1 -1
  46. package/extensions/components/AxesHelperComponent.ts +3 -0
  47. package/extensions/components/ExtentsHelperComponent.ts +5 -2
  48. package/extensions/components/GridHelperComponent.ts +1 -0
  49. package/extensions/components/LightHelperComponent.ts +2 -1
  50. package/extensions/components/StatsPanelComponent.ts +0 -1
  51. package/extensions/loaders/GLTFCloudLoader.ts +8 -2
  52. package/extensions/loaders/GLTFFileLoader.ts +3 -2
  53. package/extensions/loaders/IFCX/IFCXFileLoader.ts +11 -5
  54. package/lib/Viewer/Viewer.d.ts +6 -8
  55. package/lib/Viewer/components/CameraComponent.d.ts +1 -1
  56. package/lib/Viewer/components/ClippingPlaneComponent.d.ts +8 -0
  57. package/lib/Viewer/components/HighlighterComponent.d.ts +2 -2
  58. package/lib/Viewer/components/InfoComponent.d.ts +1 -1
  59. package/lib/Viewer/components/SectionsComponent.d.ts +15 -0
  60. package/lib/Viewer/components/WCSHelperComponent.d.ts +2 -2
  61. package/lib/Viewer/draggers/CuttingPlaneDragger.d.ts +6 -6
  62. package/lib/Viewer/draggers/OrbitDragger.d.ts +1 -1
  63. package/lib/Viewer/measurement/Snapper.d.ts +4 -4
  64. package/package.json +5 -5
  65. package/src/Viewer/Viewer.ts +59 -48
  66. package/src/Viewer/commands/GetSelected2.ts +1 -1
  67. package/src/Viewer/commands/SetSelected.ts +1 -1
  68. package/src/Viewer/commands/index.ts +1 -1
  69. package/src/Viewer/components/BackgroundComponent.ts +2 -1
  70. package/src/Viewer/components/CameraComponent.ts +6 -7
  71. package/src/Viewer/components/CanvasRemoveComponent.ts +0 -1
  72. package/src/Viewer/{scenes/Helpers.ts → components/ClippingPlaneComponent.ts} +22 -12
  73. package/src/Viewer/components/HighlighterComponent.ts +9 -5
  74. package/src/Viewer/components/HighlighterUtils.ts +2 -2
  75. package/src/Viewer/components/InfoComponent.ts +4 -4
  76. package/src/Viewer/components/SectionsComponent.ts +119 -0
  77. package/src/Viewer/components/SelectionComponent.ts +5 -3
  78. package/src/Viewer/components/WCSHelperComponent.ts +8 -6
  79. package/src/Viewer/components/index.ts +4 -0
  80. package/src/Viewer/draggers/CuttingPlaneDragger.ts +57 -34
  81. package/src/Viewer/draggers/MeasureLineDragger.ts +1 -1
  82. package/src/Viewer/draggers/OrbitDragger.ts +3 -3
  83. package/src/Viewer/helpers/SectionsHelper.js +1061 -0
  84. package/src/Viewer/helpers/WCSHelper.ts +31 -5
  85. package/src/Viewer/loaders/DynamicGltfLoader/DynamicGltfLoader.js +417 -92
  86. package/src/Viewer/loaders/DynamicGltfLoader/DynamicModelImpl.ts +19 -14
  87. package/src/Viewer/loaders/DynamicGltfLoader/GltfStructure.js +76 -9
  88. package/src/Viewer/loaders/GLTFBinaryParser.ts +2 -2
  89. package/src/Viewer/loaders/GLTFCloudDynamicLoader.ts +3 -2
  90. package/src/Viewer/loaders/GLTFFileDynamicLoader.ts +6 -4
  91. package/src/Viewer/measurement/Snapper.ts +6 -7
  92. package/src/Viewer/models/ModelImpl.ts +65 -28
  93. package/lib/Viewer/scenes/Helpers.d.ts +0 -7
  94. package/src/Viewer/postprocessing/SSAARenderPass.js +0 -245
@@ -23,6 +23,7 @@
23
23
 
24
24
  import {
25
25
  Box3,
26
+ Group,
26
27
  LinearSRGBColorSpace,
27
28
  // LinearToneMapping,
28
29
  Object3D,
@@ -34,12 +35,13 @@ import {
34
35
  Vector2,
35
36
  Vector3,
36
37
  WebGLRenderer,
38
+ WebGLRenderTarget,
37
39
  } from "three";
38
40
  import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer.js";
39
41
  import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass.js";
40
42
  import { FXAAPass } from "three/examples/jsm/postprocessing/FXAAPass.js";
41
43
  import { SMAAPass } from "three/examples/jsm/postprocessing/SMAAPass.js";
42
- import { SSAARenderPass } from "./postprocessing/SSAARenderPass.js";
44
+ import { SSAARenderPass } from "three/examples/jsm/postprocessing/SSAARenderPass.js";
43
45
  import { OutputPass } from "three/examples/jsm/postprocessing/OutputPass.js";
44
46
 
45
47
  import { EventEmitter2 } from "@inweb/eventemitter2";
@@ -72,7 +74,6 @@ import { commands } from "./commands";
72
74
  import { components } from "./components";
73
75
  import { loaders } from "./loaders";
74
76
  import { IModelImpl } from "./models/IModelImpl";
75
- import { Helpers } from "./scenes/Helpers";
76
77
 
77
78
  /**
78
79
  * 3D viewer powered by {@link https://threejs.org/ | Three.js}.
@@ -92,11 +93,10 @@ export class Viewer
92
93
  private canvaseventlistener: (event: any) => void;
93
94
 
94
95
  public scene: Scene | undefined;
95
- public helpers: Helpers | undefined;
96
+ public helpers: Group | undefined;
96
97
  public camera: PerspectiveCamera | OrthographicCamera | undefined;
97
98
  public renderer: WebGLRenderer | undefined;
98
99
  public renderPass: RenderPass | undefined;
99
- public helpersPass: RenderPass | undefined;
100
100
  public fxaaPass: FXAAPass | undefined;
101
101
  public smaaPass: SMAAPass | undefined;
102
102
  public ssaaRenderPass: SSAARenderPass | undefined;
@@ -105,11 +105,11 @@ export class Viewer
105
105
  public selected: Object3D[];
106
106
  public extents: Box3;
107
107
  public target: Vector3;
108
+ public clippingPlanes: Plane[];
108
109
 
109
110
  private _activeDragger: IDragger | null;
110
111
  private _components: IComponent[];
111
112
 
112
- private _updateDelay: number;
113
113
  private _renderNeeded: boolean;
114
114
  private _renderTime: DOMHighResTimeStamp;
115
115
 
@@ -134,11 +134,11 @@ export class Viewer
134
134
  this.selected = [];
135
135
  this.extents = new Box3();
136
136
  this.target = new Vector3(0, 0, 0);
137
+ this.clippingPlanes = [];
137
138
 
138
139
  this._activeDragger = null;
139
140
  this._components = [];
140
141
 
141
- this._updateDelay = 1000;
142
142
  this._renderNeeded = false;
143
143
  this._renderTime = 0;
144
144
 
@@ -171,7 +171,10 @@ export class Viewer
171
171
  this.addEventListener("optionschange", (event) => this.syncOptions(event.data));
172
172
 
173
173
  this.scene = new Scene();
174
- this.helpers = new Helpers();
174
+
175
+ this.helpers = new Group();
176
+ this.helpers.name = "Helpers";
177
+ this.scene.add(this.helpers);
175
178
 
176
179
  const pixelRatio = window.devicePixelRatio;
177
180
  const rect = canvas.parentElement.getBoundingClientRect();
@@ -191,25 +194,26 @@ export class Viewer
191
194
  alpha: true,
192
195
  preserveDrawingBuffer: true,
193
196
  powerPreference: "high-performance",
194
- logarithmicDepthBuffer: true,
197
+ logarithmicDepthBuffer: true, // <- required for sections filling
195
198
  });
196
199
  this.renderer.setPixelRatio(pixelRatio);
197
200
  this.renderer.setSize(width, height);
198
201
  this.renderer.outputColorSpace = LinearSRGBColorSpace;
199
202
  // this.renderer.toneMapping = LinearToneMapping;
203
+ this.renderer.localClippingEnabled = true;
200
204
 
201
205
  this.renderPass = new RenderPass(this.scene, this.camera);
202
- this.helpersPass = new RenderPass(this.helpers, this.camera);
203
- this.helpersPass.clear = false;
204
206
  this.fxaaPass = new FXAAPass();
205
207
  this.smaaPass = new SMAAPass();
206
- this.ssaaRenderPass = new SSAARenderPass([this.scene, this.helpers], this.camera);
208
+ this.ssaaRenderPass = new SSAARenderPass(this.scene, this.camera);
207
209
  this.ssaaRenderPass.unbiased = true;
208
210
  this.outputPass = new OutputPass();
209
211
 
210
- this.composer = new EffectComposer(this.renderer);
212
+ const renderTarget = new WebGLRenderTarget(1, 1, { samples: 4 });
213
+ renderTarget.texture.name = "EffectComposer.rt1";
214
+
215
+ this.composer = new EffectComposer(this.renderer, renderTarget);
211
216
  this.composer.addPass(this.renderPass);
212
- this.composer.addPass(this.helpersPass);
213
217
  this.composer.addPass(this.smaaPass);
214
218
  this.composer.addPass(this.fxaaPass);
215
219
  this.composer.addPass(this.ssaaRenderPass);
@@ -222,7 +226,8 @@ export class Viewer
222
226
  this._markup.initialize(this.canvas, this.canvasEvents, this, this);
223
227
 
224
228
  for (const name of components.getComponents().keys()) {
225
- this._components.push(components.createComponent(name, this));
229
+ const component = components.createComponent(name, this);
230
+ if (component) this._components.push(component);
226
231
  }
227
232
 
228
233
  this.syncOptions();
@@ -252,7 +257,7 @@ export class Viewer
252
257
  this.setActiveDragger();
253
258
 
254
259
  this._components.forEach((component: IComponent) => component.dispose());
255
- this._components = [];
260
+ this._components.length = 0;
256
261
 
257
262
  this._markup.dispose();
258
263
 
@@ -263,7 +268,6 @@ export class Viewer
263
268
 
264
269
  if (this.composer) this.composer.dispose();
265
270
  if (this.renderPass) this.renderPass.dispose();
266
- if (this.helpersPass) this.helpersPass.dispose();
267
271
  if (this.fxaaPass) this.fxaaPass.dispose();
268
272
  if (this.smaaPass) this.smaaPass.dispose();
269
273
  if (this.ssaaRenderPass) this.ssaaRenderPass.dispose();
@@ -275,7 +279,6 @@ export class Viewer
275
279
  this.camera = undefined;
276
280
  this.renderer = undefined;
277
281
  this.renderPass = undefined;
278
- this.helpersPass = undefined;
279
282
  this.fxaaPass = undefined;
280
283
  this.smaaPass = undefined;
281
284
  this.ssaaRenderPass = undefined;
@@ -312,14 +315,14 @@ export class Viewer
312
315
  this.update(true);
313
316
  }
314
317
 
315
- update(force = false): void {
318
+ update(force: boolean | number = false): void {
316
319
  const time = performance.now();
317
- force = force || time - this._renderTime >= this._updateDelay;
320
+ if (typeof force === "number" && time - this._renderTime >= force) force = true;
318
321
 
319
322
  this._renderNeeded = true;
320
323
  if (force) this.render(time);
321
324
 
322
- this.emitEvent({ type: "update", force });
325
+ this.emitEvent({ type: "update", force: !!force });
323
326
  }
324
327
 
325
328
  // Internal render routines
@@ -337,12 +340,7 @@ export class Viewer
337
340
  this.renderer.info.autoReset = false;
338
341
  this.renderer.info.reset();
339
342
 
340
- if (this.options.antialiasing === true || this.options.antialiasing === "msaa") {
341
- this.renderer.render(this.scene, this.camera);
342
- this.renderer.render(this.helpers, this.camera);
343
- } else {
344
- this.composer.render(deltaTime);
345
- }
343
+ this.composer.render(deltaTime);
346
344
 
347
345
  this.emitEvent({ type: "render", time, deltaTime });
348
346
  }
@@ -461,7 +459,7 @@ export class Viewer
461
459
  if (!format && typeof file === "string") format = file.split(".").pop();
462
460
  if (!format && file instanceof globalThis.File) format = file.name.split(".").pop();
463
461
 
464
- const loader: ILoader = loaders.createLoader(this, model, format);
462
+ const loader: ILoader | null = loaders.createLoader(this, model, format);
465
463
  if (!loader) throw new Error(`Format not supported (${format})`);
466
464
  this.loaders.push(loader);
467
465
 
@@ -495,14 +493,16 @@ export class Viewer
495
493
  this.clearSelected();
496
494
 
497
495
  this.loaders.forEach((loader) => loader.dispose());
498
- this.loaders = [];
496
+ this.loaders.length = 0;
499
497
 
500
498
  this.models.forEach((model) => model.dispose());
501
- this.models = [];
499
+ this.models.length = 0;
502
500
 
503
- this.scene.clear();
504
501
  this.helpers.clear();
505
502
 
503
+ this.scene.clear();
504
+ this.scene.add(this.helpers);
505
+
506
506
  this.extents.makeEmpty();
507
507
 
508
508
  this.syncOptions();
@@ -524,9 +524,19 @@ export class Viewer
524
524
  this.fxaaPass.enabled = options.antialiasing === "fxaa";
525
525
  this.smaaPass.enabled = options.antialiasing === "smaa";
526
526
  this.ssaaRenderPass.enabled = options.antialiasing === "ssaa";
527
+ this.renderPass.enabled = options.antialiasing !== "ssaa";
528
+
529
+ const samples = options.antialiasing === true || options.antialiasing === "msaa" ? 4 : 0;
530
+
531
+ if (this.composer.renderTarget1.samples !== samples) {
532
+ const size = this.renderer.getSize(new Vector2());
533
+
534
+ const newRenderTarget = new WebGLRenderTarget(1, 1, { samples });
535
+ newRenderTarget.texture.name = "EffectComposer.rt1";
527
536
 
528
- this.renderPass.enabled = !this.ssaaRenderPass.enabled;
529
- this.helpersPass.enabled = !this.ssaaRenderPass.enabled;
537
+ this.composer.reset(newRenderTarget);
538
+ this.composer.setSize(size.x, size.y);
539
+ }
530
540
 
531
541
  this.update();
532
542
  }
@@ -550,8 +560,9 @@ export class Viewer
550
560
  clearSlices(): void {
551
561
  if (!this.renderer) return;
552
562
 
553
- this.renderer.clippingPlanes = [];
563
+ this.clippingPlanes.length = 0;
554
564
 
565
+ this.emitEvent({ type: "changecuttingplanes" });
555
566
  this.emitEvent({ type: "clearslices" });
556
567
  this.update();
557
568
  }
@@ -602,8 +613,8 @@ export class Viewer
602
613
 
603
614
  setActiveDragger(name = ""): IDragger | null {
604
615
  if (!this._activeDragger || this._activeDragger.name !== name) {
605
- const oldDragger = this._activeDragger;
606
- let newDragger = null;
616
+ const oldDragger: IDragger | null = this._activeDragger;
617
+ let newDragger: IDragger | null = null;
607
618
 
608
619
  if (this._activeDragger) {
609
620
  this._activeDragger.dispose();
@@ -634,8 +645,8 @@ export class Viewer
634
645
  }
635
646
  }
636
647
 
637
- getComponent(name: string): IComponent {
638
- return this._components.find((component) => component.name === name);
648
+ getComponent(name: string): IComponent | null {
649
+ return this._components.find((component) => component.name === name) || null;
639
650
  }
640
651
 
641
652
  drawViewpoint(viewpoint: IViewpoint): void {
@@ -643,7 +654,7 @@ export class Viewer
643
654
 
644
655
  const getVector3FromPoint3d = ({ x, y, z }): Vector3 => new Vector3(x, y, z);
645
656
 
646
- const setOrthogonalCamera = (orthogonal_camera: IOrthogonalCamera) => {
657
+ const setOrthogonalCamera = (orthogonal_camera?: IOrthogonalCamera) => {
647
658
  if (orthogonal_camera) {
648
659
  const extentsSize = this.extents.getSize(new Vector3()).length() || 1;
649
660
  const rendererSize = this.renderer.getSize(new Vector2());
@@ -666,7 +677,6 @@ export class Viewer
666
677
 
667
678
  this.camera = camera;
668
679
  this.renderPass.camera = camera;
669
- this.helpersPass.camera = camera;
670
680
  this.ssaaRenderPass.camera = camera;
671
681
 
672
682
  this.options.cameraMode = "orthographic";
@@ -674,7 +684,7 @@ export class Viewer
674
684
  }
675
685
  };
676
686
 
677
- const setPerspectiveCamera = (perspective_camera: IPerspectiveCamera) => {
687
+ const setPerspectiveCamera = (perspective_camera?: IPerspectiveCamera) => {
678
688
  if (perspective_camera) {
679
689
  const extentsSize = this.extents.getSize(new Vector3()).length() || 1;
680
690
  const rendererSize = this.renderer.getSize(new Vector2());
@@ -694,7 +704,6 @@ export class Viewer
694
704
 
695
705
  this.camera = camera;
696
706
  this.renderPass.camera = camera;
697
- this.helpersPass.camera = camera;
698
707
  this.ssaaRenderPass.camera = camera;
699
708
 
700
709
  this.options.cameraMode = "perspective";
@@ -702,7 +711,7 @@ export class Viewer
702
711
  }
703
712
  };
704
713
 
705
- const setClippingPlanes = (clipping_planes: IClippingPlane[]) => {
714
+ const setClippingPlanes = (clipping_planes?: IClippingPlane[]) => {
706
715
  if (clipping_planes) {
707
716
  clipping_planes.forEach((clipping_plane) => {
708
717
  const plane = new Plane();
@@ -711,8 +720,10 @@ export class Viewer
711
720
  getVector3FromPoint3d(clipping_plane.location)
712
721
  );
713
722
 
714
- this.renderer.clippingPlanes.push(plane);
723
+ this.clippingPlanes.push(plane);
715
724
  });
725
+
726
+ this.emitEvent({ type: "changecuttingplanes" });
716
727
  }
717
728
  };
718
729
 
@@ -725,8 +736,8 @@ export class Viewer
725
736
  this.setActiveDragger();
726
737
  this.clearSlices();
727
738
  this.clearOverlay();
728
-
729
739
  this.clearSelected();
740
+
730
741
  this.showAll();
731
742
  this.explode();
732
743
 
@@ -751,7 +762,7 @@ export class Viewer
751
762
 
752
763
  const getPoint3dFromVector3 = ({ x, y, z }): IPoint => ({ x, y, z });
753
764
 
754
- const getOrthogonalCamera = (): IOrthogonalCamera => {
765
+ const getOrthogonalCamera = (): IOrthogonalCamera | undefined => {
755
766
  if (this.camera["isOrthographicCamera"])
756
767
  return {
757
768
  view_point: getPoint3dFromVector3(this.camera.position),
@@ -764,7 +775,7 @@ export class Viewer
764
775
  else return undefined;
765
776
  };
766
777
 
767
- const getPerspectiveCamera = (): IPerspectiveCamera => {
778
+ const getPerspectiveCamera = (): IPerspectiveCamera | undefined => {
768
779
  if (this.camera["isPerspectiveCamera"])
769
780
  return {
770
781
  view_point: getPoint3dFromVector3(this.camera.position),
@@ -776,8 +787,8 @@ export class Viewer
776
787
  };
777
788
 
778
789
  const getClippingPlanes = (): IClippingPlane[] => {
779
- const clipping_planes = [];
780
- this.renderer.clippingPlanes.forEach((plane: Plane) => {
790
+ const clipping_planes: IClippingPlane[] = [];
791
+ this.clippingPlanes.forEach((plane: Plane) => {
781
792
  const clipping_plane = {
782
793
  location: getPoint3dFromVector3(plane.coplanarPoint(new Vector3())),
783
794
  direction: getPoint3dFromVector3(plane.normal),
@@ -24,7 +24,7 @@
24
24
  import type { Viewer } from "../Viewer";
25
25
 
26
26
  export function getSelected2(viewer: Viewer): string[] {
27
- const handles2 = [];
27
+ const handles2: string[][] = [];
28
28
 
29
29
  viewer.models.forEach((model) => {
30
30
  handles2.push(model.getHandlesByObjects(viewer.selected));
@@ -24,7 +24,7 @@
24
24
  import type { Viewer } from "../Viewer";
25
25
 
26
26
  export function setSelected(viewer: Viewer, handles: string[] = []): void {
27
- const handles2 = [];
27
+ const handles2: string[] = [];
28
28
 
29
29
  handles.forEach((handle) => {
30
30
  if (handle.includes(":")) {
@@ -110,8 +110,8 @@ commands.registerCommand("left", (viewer) => setDefaultViewPosition(viewer, "lef
110
110
  commands.registerCommand("right", (viewer) => setDefaultViewPosition(viewer, "right"));
111
111
  commands.registerCommand("front", (viewer) => setDefaultViewPosition(viewer, "front"));
112
112
  commands.registerCommand("back", (viewer) => setDefaultViewPosition(viewer, "back"));
113
- commands.registerCommand("sw", (viewer) => setDefaultViewPosition(viewer, "sw"));
114
113
  commands.registerCommand("se", (viewer) => setDefaultViewPosition(viewer, "se"));
114
+ commands.registerCommand("sw", (viewer) => setDefaultViewPosition(viewer, "sw"));
115
115
  commands.registerCommand("ne", (viewer) => setDefaultViewPosition(viewer, "ne"));
116
116
  commands.registerCommand("nw", (viewer) => setDefaultViewPosition(viewer, "nw"));
117
117
 
@@ -42,11 +42,12 @@ export class BackgroundComponent implements IComponent {
42
42
 
43
43
  dispose() {
44
44
  this.viewer.removeEventListener("optionschange", this.syncOptions);
45
- this.viewer.scene.background = undefined;
45
+ this.viewer.scene.background = null;
46
46
  }
47
47
 
48
48
  syncOptions = () => {
49
49
  this.backgroundColor.setHex(0xffffff);
50
50
  this.viewer.renderer.setClearColor(this.backgroundColor);
51
+ this.viewer.update();
51
52
  };
52
53
  }
@@ -32,14 +32,14 @@ export class CameraComponent implements IComponent {
32
32
  constructor(viewer: Viewer) {
33
33
  this.viewer = viewer;
34
34
  this.viewer.addEventListener("databasechunk", this.geometryEnd);
35
- this.viewer.addEventListener("optionschange", this.optionsChange);
36
- this.viewer.addEventListener("initialize", this.optionsChange);
35
+ this.viewer.addEventListener("optionschange", this.syncOptions);
36
+ this.viewer.addEventListener("initialize", this.syncOptions);
37
37
  }
38
38
 
39
39
  dispose() {
40
40
  this.viewer.removeEventListener("databasechunk", this.geometryEnd);
41
- this.viewer.removeEventListener("optionschange", this.optionsChange);
42
- this.viewer.removeEventListener("initialize", this.optionsChange);
41
+ this.viewer.removeEventListener("optionschange", this.syncOptions);
42
+ this.viewer.removeEventListener("initialize", this.syncOptions);
43
43
  }
44
44
 
45
45
  getCameraMode(camera: any): CameraMode {
@@ -67,7 +67,6 @@ export class CameraComponent implements IComponent {
67
67
 
68
68
  this.viewer.camera = camera;
69
69
  this.viewer.renderPass.camera = camera;
70
- this.viewer.helpersPass.camera = camera;
71
70
  this.viewer.ssaaRenderPass.camera = camera;
72
71
 
73
72
  this.viewer.update();
@@ -81,7 +80,7 @@ export class CameraComponent implements IComponent {
81
80
 
82
81
  const target = this.viewer.target.clone();
83
82
 
84
- let camera: PerspectiveCamera | OrthographicCamera;
83
+ let camera: PerspectiveCamera | OrthographicCamera | null = null;
85
84
 
86
85
  if (currentCamera.isOrthographicCamera) {
87
86
  const fov = currentCamera.userData.fov || 45;
@@ -114,7 +113,7 @@ export class CameraComponent implements IComponent {
114
113
  this.viewer.emitEvent({ type: "changecameramode", mode });
115
114
  }
116
115
 
117
- optionsChange = () => {
116
+ syncOptions = () => {
118
117
  this.switchCameraMode(this.viewer.options.cameraMode);
119
118
  };
120
119
 
@@ -36,7 +36,6 @@ export class CanvasRemoveComponent implements IComponent {
36
36
 
37
37
  dispose() {
38
38
  this.mutationObserver.disconnect();
39
- this.mutationObserver = undefined;
40
39
  }
41
40
 
42
41
  cleanupViewer = (mutations: MutationRecord[]) => {
@@ -21,22 +21,32 @@
21
21
  // acknowledge and accept the above terms.
22
22
  ///////////////////////////////////////////////////////////////////////////////
23
23
 
24
- import { Scene, WebGLRenderer } from "three";
24
+ import { IComponent } from "@inweb/viewer-core";
25
+ import type { Viewer } from "../Viewer";
25
26
 
26
- export class Helpers extends Scene {
27
- private oldAutoClear = false;
28
- private oldClippingPlanes = [];
27
+ export class ClippingPlaneComponent implements IComponent {
28
+ protected viewer: Viewer;
29
29
 
30
- override onBeforeRender(renderer: WebGLRenderer): void {
31
- this.oldAutoClear = renderer.autoClear;
32
- this.oldClippingPlanes = renderer.clippingPlanes;
30
+ constructor(viewer: Viewer) {
31
+ this.viewer = viewer;
33
32
 
34
- renderer.autoClear = false;
35
- renderer.clippingPlanes = [];
33
+ this.viewer.addEventListener("geometryend", this.applyClippingPlanes);
34
+ this.viewer.addEventListener("changecuttingplanes", this.applyClippingPlanes);
36
35
  }
37
36
 
38
- override onAfterRender(renderer: WebGLRenderer): void {
39
- renderer.clippingPlanes = this.oldClippingPlanes;
40
- renderer.autoClear = this.oldAutoClear;
37
+ dispose() {
38
+ this.viewer.removeEventListener("geometryend", this.applyClippingPlanes);
39
+ this.viewer.removeEventListener("changecuttingplanes", this.applyClippingPlanes);
41
40
  }
41
+
42
+ applyClippingPlanes = () => {
43
+ this.viewer.models.forEach((model) => {
44
+ model.scene.traverse((object: any) => {
45
+ if (object.material) {
46
+ const materials = Array.isArray(object.material) ? object.material : [object.material];
47
+ materials.forEach((material) => (material.clippingPlanes = this.viewer.clippingPlanes));
48
+ }
49
+ });
50
+ });
51
+ };
42
52
  }
@@ -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 HighlighterUtils {
40
40
 
41
41
  static fromIndexedLine(positions: Float32Array, indices: number[]) {
42
42
  const lineGeometry = new LineSegmentsGeometry();
43
- const segments = [];
43
+ const segments: number[] = [];
44
44
 
45
45
  for (let i = 0; i < indices.length; i += 2) {
46
46
  const idx1 = indices[i] * 3;
@@ -68,7 +68,7 @@ export class HighlighterUtils {
68
68
 
69
69
  static fromNonIndexedLine(positions: Float32Array, isLineSegments: boolean) {
70
70
  const lineGeometry = new LineSegmentsGeometry();
71
- const segments = [];
71
+ const segments: number[] = [];
72
72
 
73
73
  if (isLineSegments) {
74
74
  for (let i = 0; i < positions.length; i += 6) {
@@ -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;