@inweb/viewer-three 26.6.6 → 26.6.7
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.
- package/dist/plugins/components/AxesHelperComponent.js +5 -5
- package/dist/plugins/components/AxesHelperComponent.js.map +1 -1
- package/dist/plugins/components/AxesHelperComponent.min.js +1 -1
- package/dist/plugins/components/AxesHelperComponent.module.js +5 -5
- package/dist/plugins/components/AxesHelperComponent.module.js.map +1 -1
- package/dist/plugins/components/ExtentsHelperComponent.js +15 -7
- package/dist/plugins/components/ExtentsHelperComponent.js.map +1 -1
- package/dist/plugins/components/ExtentsHelperComponent.min.js +1 -1
- package/dist/plugins/components/ExtentsHelperComponent.module.js +15 -7
- package/dist/plugins/components/ExtentsHelperComponent.module.js.map +1 -1
- package/dist/plugins/components/LightHelperComponent.js +5 -5
- package/dist/plugins/components/LightHelperComponent.js.map +1 -1
- package/dist/plugins/components/LightHelperComponent.min.js +1 -1
- package/dist/plugins/components/LightHelperComponent.module.js +5 -5
- package/dist/plugins/components/LightHelperComponent.module.js.map +1 -1
- package/dist/plugins/loaders/GLTFCloudLoader.js +4840 -0
- package/dist/plugins/loaders/GLTFCloudLoader.js.map +1 -0
- package/dist/plugins/loaders/GLTFCloudLoader.min.js +1 -0
- package/dist/plugins/loaders/GLTFCloudLoader.module.js +49 -0
- package/dist/plugins/loaders/GLTFCloudLoader.module.js.map +1 -0
- package/dist/plugins/loaders/IFCXLoader.js +12 -6
- package/dist/plugins/loaders/IFCXLoader.js.map +1 -1
- package/dist/plugins/loaders/IFCXLoader.min.js +1 -1
- package/dist/plugins/loaders/IFCXLoader.module.js +13 -7
- package/dist/plugins/loaders/IFCXLoader.module.js.map +1 -1
- package/dist/viewer-three.js +3131 -459
- package/dist/viewer-three.js.map +1 -1
- package/dist/viewer-three.min.js +2 -2
- package/dist/viewer-three.module.js +2326 -264
- package/dist/viewer-three.module.js.map +1 -1
- package/lib/Viewer/Viewer.d.ts +6 -5
- package/lib/Viewer/components/HighlighterComponent.d.ts +4 -3
- package/lib/Viewer/components/SelectionComponent.d.ts +8 -5
- package/lib/Viewer/draggers/CuttingPlaneDragger.d.ts +1 -1
- package/lib/Viewer/loaders/DynamicGltfLoader/DynamicModelImpl.d.ts +20 -0
- package/lib/Viewer/loaders/GLTFCloudDynamicLoader.d.ts +15 -0
- package/lib/Viewer/model/IModelImpl.d.ts +27 -0
- package/lib/Viewer/model/ModelImpl.d.ts +30 -0
- package/lib/Viewer/model/index.d.ts +2 -0
- package/lib/index.d.ts +1 -0
- package/package.json +11 -7
- package/plugins/components/AxesHelperComponent.ts +5 -5
- package/plugins/components/ExtentsHelperComponent.ts +15 -7
- package/plugins/components/LightHelperComponent.ts +5 -5
- package/{src/Viewer/loaders/GLTFCloudModelLoader.ts → plugins/loaders/GLTFCloudLoader.ts} +15 -12
- package/plugins/loaders/{IFCXCloudFileLoader.ts → IFCXCloudLoader.ts} +8 -4
- package/plugins/loaders/IFCXFileLoader.ts +7 -3
- package/plugins/loaders/IFCXLoader.ts +2 -2
- package/src/Viewer/Viewer.ts +32 -36
- package/src/Viewer/commands/ClearSelected.ts +2 -3
- package/src/Viewer/commands/Explode.ts +1 -47
- package/src/Viewer/commands/GetModels.ts +1 -1
- package/src/Viewer/commands/GetSelected.ts +3 -1
- package/src/Viewer/commands/HideSelected.ts +3 -4
- package/src/Viewer/commands/IsolateSelected.ts +1 -7
- package/src/Viewer/commands/SelectModel.ts +9 -1
- package/src/Viewer/commands/SetSelected.ts +8 -10
- package/src/Viewer/commands/ShowAll.ts +1 -1
- package/src/Viewer/components/BackgroundComponent.ts +1 -0
- package/src/Viewer/components/ExtentsComponent.ts +5 -3
- package/src/Viewer/components/HighlighterComponent.ts +79 -48
- package/src/Viewer/components/SelectionComponent.ts +67 -21
- package/src/Viewer/draggers/CuttingPlaneDragger.ts +7 -3
- package/src/Viewer/draggers/MeasureLineDragger.ts +2 -0
- package/src/Viewer/loaders/DynamicGltfLoader/DynamicGltfLoader.js +1628 -0
- package/src/Viewer/loaders/DynamicGltfLoader/DynamicModelImpl.ts +102 -0
- package/src/Viewer/loaders/DynamicGltfLoader/GltfStructure.js +450 -0
- package/src/Viewer/loaders/GLTFCloudDynamicLoader.ts +145 -0
- package/src/Viewer/loaders/GLTFFileLoader.ts +7 -2
- package/src/Viewer/loaders/index.ts +2 -2
- package/src/Viewer/model/IModelImpl.ts +67 -0
- package/src/Viewer/model/ModelImpl.ts +215 -0
- package/src/Viewer/model/index.ts +25 -0
- package/src/index.ts +1 -0
- package/lib/Viewer/loaders/GLTFCloudModelLoader.d.ts +0 -8
|
@@ -21,56 +21,10 @@
|
|
|
21
21
|
// acknowledge and accept the above terms.
|
|
22
22
|
///////////////////////////////////////////////////////////////////////////////
|
|
23
23
|
|
|
24
|
-
import { Box3, Vector3 } from "three";
|
|
25
24
|
import type { Viewer } from "../Viewer";
|
|
26
25
|
|
|
27
|
-
function calcExplodeDepth(object, depth: number): number {
|
|
28
|
-
let res = depth;
|
|
29
|
-
object.children.forEach((x) => {
|
|
30
|
-
const objectDepth = calcExplodeDepth(x, depth + 1);
|
|
31
|
-
if (res < objectDepth) res = objectDepth;
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
object.originalPosition = object.position.clone();
|
|
35
|
-
object.originalCenter = new Box3().setFromObject(object).getCenter(new Vector3());
|
|
36
|
-
object.isExplodeLocked = depth > 2 && object.children.length === 0;
|
|
37
|
-
|
|
38
|
-
return res;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function explodeModel(scene, scale = 0, coeff = 4) {
|
|
42
|
-
scale /= 100;
|
|
43
|
-
|
|
44
|
-
if (!scene.explodeDepth) scene.explodeDepth = calcExplodeDepth(scene, 1);
|
|
45
|
-
const maxDepth = scene.explodeDepth;
|
|
46
|
-
|
|
47
|
-
const scaledExplodeDepth = scale * maxDepth + 1;
|
|
48
|
-
const explodeDepth = 0 | scaledExplodeDepth;
|
|
49
|
-
const currentSegmentFraction = scaledExplodeDepth - explodeDepth;
|
|
50
|
-
|
|
51
|
-
function explodeObject(object, depth: number) {
|
|
52
|
-
object.position.copy(object.originalPosition);
|
|
53
|
-
|
|
54
|
-
if (depth > 0 && depth <= explodeDepth && !object.isExplodeLocked) {
|
|
55
|
-
let objectScale = scale * coeff;
|
|
56
|
-
if (depth === explodeDepth) objectScale *= currentSegmentFraction;
|
|
57
|
-
|
|
58
|
-
const parentCenter = object.parent.originalCenter;
|
|
59
|
-
const objectCenter = object.originalCenter;
|
|
60
|
-
const objectOffset = objectCenter.clone().sub(parentCenter).multiplyScalar(objectScale);
|
|
61
|
-
|
|
62
|
-
object.position.add(objectOffset);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
object.children.forEach((x) => explodeObject(x, depth + 1));
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
explodeObject(scene, 0);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
26
|
export function explode(viewer: Viewer, index = 0): void {
|
|
72
|
-
viewer.models.forEach((model) =>
|
|
73
|
-
viewer.scene.updateMatrixWorld();
|
|
27
|
+
viewer.models.forEach((model) => model.explode(index));
|
|
74
28
|
|
|
75
29
|
viewer.update();
|
|
76
30
|
viewer.emitEvent({ type: "explode", data: index });
|
|
@@ -24,5 +24,7 @@
|
|
|
24
24
|
import type { Viewer } from "../Viewer";
|
|
25
25
|
|
|
26
26
|
export function getSelected(viewer: Viewer): string[] {
|
|
27
|
-
|
|
27
|
+
const handles = [];
|
|
28
|
+
viewer.models.forEach((model) => handles.push(...model.getHandlesByObjects(viewer.selected)));
|
|
29
|
+
return handles;
|
|
28
30
|
}
|
|
@@ -22,14 +22,13 @@
|
|
|
22
22
|
///////////////////////////////////////////////////////////////////////////////
|
|
23
23
|
|
|
24
24
|
import type { Viewer } from "../Viewer";
|
|
25
|
-
import { SelectionComponent } from "../components/SelectionComponent";
|
|
25
|
+
import type { SelectionComponent } from "../components/SelectionComponent";
|
|
26
26
|
|
|
27
27
|
export function hideSelected(viewer: Viewer): void {
|
|
28
|
-
viewer.
|
|
28
|
+
viewer.models.forEach((model) => model.hideObjects(viewer.selected));
|
|
29
29
|
|
|
30
|
-
const selection =
|
|
30
|
+
const selection = viewer.getComponent("SelectionComponent") as SelectionComponent;
|
|
31
31
|
selection.clearSelection();
|
|
32
|
-
selection.dispose();
|
|
33
32
|
|
|
34
33
|
viewer.update();
|
|
35
34
|
viewer.emitEvent({ type: "hide" });
|
|
@@ -24,13 +24,7 @@
|
|
|
24
24
|
import type { Viewer } from "../Viewer";
|
|
25
25
|
|
|
26
26
|
export function isolateSelected(viewer: Viewer): void {
|
|
27
|
-
|
|
28
|
-
viewer.selected.forEach((object) => {
|
|
29
|
-
visibleSet.add(object);
|
|
30
|
-
object.traverseAncestors((object2) => visibleSet.add(object2));
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
viewer.scene.traverse((object) => (object.visible = visibleSet.has(object)));
|
|
27
|
+
viewer.models.forEach((model) => model.isolateObjects(viewer.selected));
|
|
34
28
|
|
|
35
29
|
viewer.update();
|
|
36
30
|
viewer.emitEvent({ type: "isolate" });
|
|
@@ -22,8 +22,16 @@
|
|
|
22
22
|
///////////////////////////////////////////////////////////////////////////////
|
|
23
23
|
|
|
24
24
|
import type { Viewer } from "../Viewer";
|
|
25
|
+
import type { SelectionComponent } from "../components/SelectionComponent";
|
|
25
26
|
|
|
26
27
|
export function selectModel(viewer: Viewer, handle: string): void {
|
|
27
|
-
|
|
28
|
+
const selection = viewer.getComponent("SelectionComponent") as SelectionComponent;
|
|
29
|
+
selection.clearSelection();
|
|
30
|
+
|
|
31
|
+
viewer.models
|
|
32
|
+
.filter((model) => model.handle === handle)
|
|
33
|
+
.forEach((model) => selection.select(model.getObjects(), model));
|
|
34
|
+
|
|
35
|
+
viewer.update();
|
|
28
36
|
viewer.emit({ type: "select", data: [] });
|
|
29
37
|
}
|
|
@@ -22,20 +22,18 @@
|
|
|
22
22
|
///////////////////////////////////////////////////////////////////////////////
|
|
23
23
|
|
|
24
24
|
import type { Viewer } from "../Viewer";
|
|
25
|
+
import type { SelectionComponent } from "../components/SelectionComponent";
|
|
25
26
|
|
|
26
27
|
export function setSelected(viewer: Viewer, handles: string[] = []): void {
|
|
27
|
-
const
|
|
28
|
-
const objects = [];
|
|
29
|
-
viewer.scene.traverseVisible((child) => {
|
|
30
|
-
if (handleSet.has(child.userData?.handle)) objects.push(child);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
const selection: any = viewer.getComponent("SelectionComponent");
|
|
34
|
-
if (!selection) return;
|
|
35
|
-
|
|
28
|
+
const selection = viewer.getComponent("SelectionComponent") as SelectionComponent;
|
|
36
29
|
selection.clearSelection();
|
|
37
|
-
|
|
30
|
+
|
|
31
|
+
viewer.models.forEach((model) => {
|
|
32
|
+
const objects = model.getObjectsByHandles(handles);
|
|
33
|
+
selection.select(objects, model);
|
|
34
|
+
});
|
|
38
35
|
|
|
39
36
|
viewer.update();
|
|
37
|
+
viewer.emitEvent({ type: "show" });
|
|
40
38
|
viewer.emitEvent({ type: "select", data: undefined, handles });
|
|
41
39
|
}
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
import type { Viewer } from "../Viewer";
|
|
25
25
|
|
|
26
26
|
export function showAll(viewer: Viewer): void {
|
|
27
|
-
viewer.
|
|
27
|
+
viewer.models.forEach((model) => model.showAllObjects());
|
|
28
28
|
|
|
29
29
|
viewer.update();
|
|
30
30
|
viewer.emitEvent({ type: "showall" });
|
|
@@ -34,8 +34,9 @@ export class ExtentsComponent implements IComponent {
|
|
|
34
34
|
this.viewer.addEventListener("databasechunk", this.syncExtents);
|
|
35
35
|
this.viewer.addEventListener("clear", this.syncExtents);
|
|
36
36
|
this.viewer.on("explode", this.syncExtents);
|
|
37
|
-
this.viewer.on("isolate", this.syncExtents);
|
|
38
37
|
this.viewer.on("hide", this.syncExtents);
|
|
38
|
+
this.viewer.on("isolate", this.syncExtents);
|
|
39
|
+
this.viewer.on("show", this.syncExtents);
|
|
39
40
|
this.viewer.on("showall", this.syncExtents);
|
|
40
41
|
}
|
|
41
42
|
|
|
@@ -43,14 +44,15 @@ export class ExtentsComponent implements IComponent {
|
|
|
43
44
|
this.viewer.removeEventListener("databasechunk", this.syncExtents);
|
|
44
45
|
this.viewer.removeEventListener("clear", this.syncExtents);
|
|
45
46
|
this.viewer.off("explode", this.syncExtents);
|
|
46
|
-
this.viewer.off("isolate", this.syncExtents);
|
|
47
47
|
this.viewer.off("hide", this.syncExtents);
|
|
48
|
+
this.viewer.off("isolate", this.syncExtents);
|
|
49
|
+
this.viewer.off("show", this.syncExtents);
|
|
48
50
|
this.viewer.off("showall", this.syncExtents);
|
|
49
51
|
}
|
|
50
52
|
|
|
51
53
|
syncExtents = () => {
|
|
52
54
|
const extents = new Box3();
|
|
53
|
-
this.viewer.
|
|
55
|
+
this.viewer.models.forEach((model) => model.getExtents(extents));
|
|
54
56
|
|
|
55
57
|
this.viewer.extents.copy(extents);
|
|
56
58
|
};
|
|
@@ -21,7 +21,17 @@
|
|
|
21
21
|
// acknowledge and accept the above terms.
|
|
22
22
|
///////////////////////////////////////////////////////////////////////////////
|
|
23
23
|
|
|
24
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
Color,
|
|
26
|
+
EdgesGeometry,
|
|
27
|
+
LineBasicMaterial,
|
|
28
|
+
MeshBasicMaterial,
|
|
29
|
+
Object3D,
|
|
30
|
+
RGBAFormat,
|
|
31
|
+
UnsignedByteType,
|
|
32
|
+
Vector2,
|
|
33
|
+
WebGLRenderTarget,
|
|
34
|
+
} from "three";
|
|
25
35
|
import { LineSegmentsGeometry } from "three/examples/jsm/lines/LineSegmentsGeometry.js";
|
|
26
36
|
import { Wireframe } from "three/examples/jsm/lines/Wireframe.js";
|
|
27
37
|
import { LineMaterial } from "three/examples/jsm/lines/LineMaterial.js";
|
|
@@ -32,6 +42,7 @@ import { HighlighterUtils } from "./HighlighterUtils";
|
|
|
32
42
|
|
|
33
43
|
export class HighlighterComponent implements IComponent {
|
|
34
44
|
protected viewer: Viewer;
|
|
45
|
+
public renderTarget: WebGLRenderTarget;
|
|
35
46
|
public highlightMaterial: MeshBasicMaterial;
|
|
36
47
|
public outlineMaterial: LineMaterial;
|
|
37
48
|
public highlightLineMaterial: LineBasicMaterial;
|
|
@@ -40,6 +51,17 @@ export class HighlighterComponent implements IComponent {
|
|
|
40
51
|
constructor(viewer: Viewer) {
|
|
41
52
|
this.viewer = viewer;
|
|
42
53
|
|
|
54
|
+
const gl2 = viewer.canvas.getContext("webgl2");
|
|
55
|
+
if (gl2) {
|
|
56
|
+
const size = viewer.renderer.getSize(new Vector2());
|
|
57
|
+
this.renderTarget = new WebGLRenderTarget(size.x, size.y, {
|
|
58
|
+
format: RGBAFormat,
|
|
59
|
+
stencilBuffer: false,
|
|
60
|
+
samples: 4,
|
|
61
|
+
type: UnsignedByteType,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
43
65
|
this.viewer.addEventListener("databasechunk", this.geometryEnd);
|
|
44
66
|
this.viewer.addEventListener("optionschange", this.optionsChange);
|
|
45
67
|
this.viewer.addEventListener("resize", this.viewerResize);
|
|
@@ -53,54 +75,64 @@ export class HighlighterComponent implements IComponent {
|
|
|
53
75
|
this.viewer.removeEventListener("resize", this.viewerResize);
|
|
54
76
|
}
|
|
55
77
|
|
|
56
|
-
highlight(
|
|
57
|
-
if (
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
78
|
+
highlight(objects: Object3D | Object3D[]) {
|
|
79
|
+
if (!Array.isArray(objects)) objects = [objects];
|
|
80
|
+
if (!objects.length) return;
|
|
81
|
+
|
|
82
|
+
objects.forEach((object: any) => {
|
|
83
|
+
if (object.isHighlighted) return;
|
|
84
|
+
|
|
85
|
+
if (object.isLine || object.isLineSegments) {
|
|
86
|
+
const positions = object.geometry.attributes.position.array;
|
|
87
|
+
const indices = object.geometry.index ? object.geometry.index.array : null;
|
|
88
|
+
const lineGeometry = indices
|
|
89
|
+
? HighlighterUtils.fromIndexedLine(positions, indices)
|
|
90
|
+
: HighlighterUtils.fromNonIndexedLine(positions, object.isLineSegments);
|
|
91
|
+
|
|
92
|
+
const wireframe = new Wireframe(lineGeometry, this.highlightLineGlowMaterial);
|
|
93
|
+
wireframe.position.copy(object.position);
|
|
94
|
+
wireframe.rotation.copy(object.rotation);
|
|
95
|
+
wireframe.scale.copy(object.scale);
|
|
96
|
+
|
|
97
|
+
object.parent.add(wireframe);
|
|
98
|
+
|
|
99
|
+
object.userData.highlightwireframe = wireframe;
|
|
100
|
+
object.userData.originalMaterial = object.material;
|
|
101
|
+
object.material = this.highlightLineMaterial;
|
|
102
|
+
object.isHighlighted = true;
|
|
103
|
+
} else if (object.isMesh) {
|
|
104
|
+
const edgesGeometry = new EdgesGeometry(object.geometry, 30);
|
|
105
|
+
const lineGeometry = new LineSegmentsGeometry().fromEdgesGeometry(edgesGeometry);
|
|
106
|
+
|
|
107
|
+
const wireframe = new Wireframe(lineGeometry, this.outlineMaterial);
|
|
108
|
+
wireframe.position.copy(object.position);
|
|
109
|
+
wireframe.rotation.copy(object.rotation);
|
|
110
|
+
wireframe.scale.copy(object.scale);
|
|
111
|
+
|
|
112
|
+
object.parent.add(wireframe);
|
|
113
|
+
|
|
114
|
+
object.userData.highlightwireframe = wireframe;
|
|
115
|
+
object.userData.originalMaterial = object.material;
|
|
116
|
+
object.material = this.highlightMaterial;
|
|
117
|
+
object.isHighlighted = true;
|
|
118
|
+
}
|
|
119
|
+
});
|
|
93
120
|
}
|
|
94
121
|
|
|
95
|
-
unhighlight(
|
|
96
|
-
if (!
|
|
122
|
+
unhighlight(objects: Object3D | Object3D[]) {
|
|
123
|
+
if (!Array.isArray(objects)) objects = [objects];
|
|
124
|
+
if (!objects.length) return;
|
|
97
125
|
|
|
98
|
-
object
|
|
99
|
-
|
|
100
|
-
object.userData.highlightwireframe.removeFromParent();
|
|
126
|
+
objects.forEach((object: any) => {
|
|
127
|
+
if (!object.isHighlighted) return;
|
|
101
128
|
|
|
102
|
-
|
|
103
|
-
|
|
129
|
+
object.isHighlighted = false;
|
|
130
|
+
object.material = object.userData.originalMaterial;
|
|
131
|
+
object.userData.highlightwireframe.removeFromParent();
|
|
132
|
+
|
|
133
|
+
delete object.userData.originalMaterial;
|
|
134
|
+
delete object.userData.highlightwireframe;
|
|
135
|
+
});
|
|
104
136
|
}
|
|
105
137
|
|
|
106
138
|
geometryEnd = () => {
|
|
@@ -152,8 +184,7 @@ export class HighlighterComponent implements IComponent {
|
|
|
152
184
|
};
|
|
153
185
|
|
|
154
186
|
viewerResize(event: ResizeEvent) {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
this.outlineMaterial.resolution.set(event.width, event.height);
|
|
187
|
+
this.renderTarget?.setSize(event.width, event.height);
|
|
188
|
+
this.outlineMaterial?.resolution.set(event.width, event.height);
|
|
158
189
|
}
|
|
159
190
|
}
|
|
@@ -23,9 +23,10 @@
|
|
|
23
23
|
|
|
24
24
|
import { Intersection, Object3D, Raycaster, Vector2 } from "three";
|
|
25
25
|
|
|
26
|
-
import { IComponent } from "@inweb/viewer-core";
|
|
27
|
-
import { Viewer } from "../Viewer";
|
|
28
|
-
import {
|
|
26
|
+
import type { IComponent } from "@inweb/viewer-core";
|
|
27
|
+
import type { Viewer } from "../Viewer";
|
|
28
|
+
import type { IModelImpl } from "../model";
|
|
29
|
+
import type { HighlighterComponent } from "./HighlighterComponent";
|
|
29
30
|
|
|
30
31
|
export class SelectionComponent implements IComponent {
|
|
31
32
|
protected viewer: Viewer;
|
|
@@ -61,12 +62,26 @@ export class SelectionComponent implements IComponent {
|
|
|
61
62
|
if (!event.isPrimary) return;
|
|
62
63
|
|
|
63
64
|
const upPosition = this.getMousePosition(event, new Vector2());
|
|
64
|
-
if (this.downPosition
|
|
65
|
+
if (upPosition.distanceTo(this.downPosition) !== 0) return;
|
|
65
66
|
|
|
66
|
-
|
|
67
|
+
let intersections = [];
|
|
68
|
+
this.viewer.models.forEach((model) => {
|
|
69
|
+
const objects = model.getVisibleObjects();
|
|
70
|
+
const intersects = this.getPointerIntersects(upPosition, objects);
|
|
71
|
+
intersections.push(...intersects.map((x) => ({ ...x, model })));
|
|
72
|
+
});
|
|
73
|
+
intersections = intersections.sort((a, b) => a.distance - b.distance);
|
|
74
|
+
|
|
75
|
+
if (!event.shiftKey) this.clearSelection();
|
|
67
76
|
|
|
68
|
-
|
|
69
|
-
|
|
77
|
+
if (intersections.length > 0) {
|
|
78
|
+
const model = intersections[0].model;
|
|
79
|
+
const handles = model.getHandlesByObjects(intersections[0].object);
|
|
80
|
+
const objects = model.getObjectsByHandles(handles);
|
|
81
|
+
|
|
82
|
+
if (!event.shiftKey) this.select(objects, model);
|
|
83
|
+
else this.toggleSelection(objects, model);
|
|
84
|
+
}
|
|
70
85
|
|
|
71
86
|
this.viewer.update();
|
|
72
87
|
this.viewer.emitEvent({ type: "select", data: undefined, handles: this.viewer.getSelected() });
|
|
@@ -82,7 +97,7 @@ export class SelectionComponent implements IComponent {
|
|
|
82
97
|
return target.set(event.clientX, event.clientY);
|
|
83
98
|
}
|
|
84
99
|
|
|
85
|
-
getPointerIntersects(mouse: Vector2): Array<Intersection<Object3D>> {
|
|
100
|
+
getPointerIntersects(mouse: Vector2, objects: Object3D[]): Array<Intersection<Object3D>> {
|
|
86
101
|
const rect = this.viewer.canvas.getBoundingClientRect();
|
|
87
102
|
const x = ((mouse.x - rect.left) / rect.width) * 2 - 1;
|
|
88
103
|
const y = (-(mouse.y - rect.top) / rect.height) * 2 + 1;
|
|
@@ -90,9 +105,6 @@ export class SelectionComponent implements IComponent {
|
|
|
90
105
|
const coords = new Vector2(x, y);
|
|
91
106
|
this.raycaster.setFromCamera(coords, this.viewer.camera);
|
|
92
107
|
|
|
93
|
-
const objects = [];
|
|
94
|
-
this.viewer.scene.traverseVisible((child) => objects.push(child));
|
|
95
|
-
|
|
96
108
|
this.raycaster.params = this.raycaster.params = {
|
|
97
109
|
Mesh: {},
|
|
98
110
|
Line: { threshold: 0.25 },
|
|
@@ -105,24 +117,58 @@ export class SelectionComponent implements IComponent {
|
|
|
105
117
|
return this.raycaster.intersectObjects(objects, false);
|
|
106
118
|
}
|
|
107
119
|
|
|
108
|
-
select(
|
|
109
|
-
if (
|
|
120
|
+
select(objects: Object3D | Object3D[], model?: IModelImpl) {
|
|
121
|
+
if (!model) {
|
|
122
|
+
this.viewer.models.forEach((model) => this.select(objects, model));
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (!Array.isArray(objects)) objects = [objects];
|
|
127
|
+
if (!objects.length) return;
|
|
128
|
+
|
|
129
|
+
model.showObjects(objects);
|
|
130
|
+
model.showOriginalObjects(objects);
|
|
131
|
+
this.highlighter.highlight(objects);
|
|
132
|
+
|
|
133
|
+
objects.forEach((object: any) => this.viewer.selected.push(object));
|
|
134
|
+
objects.forEach((object: any) => (object.isSelected = true));
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
deselect(objects: Object3D | Object3D[], model?: IModelImpl) {
|
|
138
|
+
if (!model) {
|
|
139
|
+
this.viewer.models.forEach((model) => this.select(objects, model));
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (!Array.isArray(objects)) objects = [objects];
|
|
144
|
+
if (!objects.length) return;
|
|
145
|
+
|
|
146
|
+
this.highlighter.unhighlight(objects);
|
|
147
|
+
model.hideOriginalObjects(objects);
|
|
148
|
+
|
|
149
|
+
this.viewer.selected = this.viewer.selected.filter((x) => !objects.includes(x));
|
|
150
|
+
objects.forEach((object: any) => (object.isSelected = false));
|
|
151
|
+
}
|
|
110
152
|
|
|
111
|
-
|
|
112
|
-
|
|
153
|
+
toggleSelection(objects: Object3D | Object3D[], model?: IModelImpl) {
|
|
154
|
+
if (!Array.isArray(objects)) objects = [objects];
|
|
155
|
+
if (!objects.length) return;
|
|
113
156
|
|
|
114
|
-
this.
|
|
157
|
+
if ((objects[0] as any).isSelected) this.deselect(objects, model);
|
|
158
|
+
else this.select(objects, model);
|
|
115
159
|
}
|
|
116
160
|
|
|
117
161
|
clearSelection() {
|
|
118
|
-
this.viewer.selected.
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
162
|
+
if (!this.viewer.selected.length) return;
|
|
163
|
+
|
|
164
|
+
this.highlighter.unhighlight(this.viewer.selected);
|
|
165
|
+
this.viewer.models.forEach((model) => model.hideOriginalObjects(this.viewer.selected));
|
|
166
|
+
|
|
167
|
+
this.viewer.selected.forEach((object: any) => (object.isSelected = false));
|
|
122
168
|
this.viewer.selected.length = 0;
|
|
123
169
|
}
|
|
124
170
|
|
|
125
171
|
initHighlighter = () => {
|
|
126
|
-
this.highlighter = this.viewer.getComponent("HighlighterComponent") as
|
|
172
|
+
this.highlighter = this.viewer.getComponent("HighlighterComponent") as HighlighterComponent;
|
|
127
173
|
};
|
|
128
174
|
}
|
|
@@ -62,13 +62,17 @@ export class CuttingPlaneDragger extends OrbitDragger {
|
|
|
62
62
|
this.transform.addEventListener("dragging-changed", this.transformDrag);
|
|
63
63
|
this.viewer.helpers.add(this.transform.getHelper());
|
|
64
64
|
|
|
65
|
-
this.viewer.on("explode", this.
|
|
65
|
+
this.viewer.on("explode", this.updatePlaneSize);
|
|
66
|
+
this.viewer.on("show", this.updatePlaneSize);
|
|
67
|
+
this.viewer.on("showall", this.updatePlaneSize);
|
|
66
68
|
this.viewer.canvas.addEventListener("dblclick", this.onDoubleClick, true);
|
|
67
69
|
this.viewer.update();
|
|
68
70
|
}
|
|
69
71
|
|
|
70
72
|
override dispose() {
|
|
71
|
-
this.viewer.off("explode", this.
|
|
73
|
+
this.viewer.off("explode", this.updatePlaneSize);
|
|
74
|
+
this.viewer.off("show", this.updatePlaneSize);
|
|
75
|
+
this.viewer.off("showAll", this.updatePlaneSize);
|
|
72
76
|
this.viewer.canvas.removeEventListener("dblclick", this.onDoubleClick, true);
|
|
73
77
|
|
|
74
78
|
this.transform.removeEventListener("change", this.transformChange);
|
|
@@ -97,7 +101,7 @@ export class CuttingPlaneDragger extends OrbitDragger {
|
|
|
97
101
|
this.orbit.enabled = !event.value;
|
|
98
102
|
};
|
|
99
103
|
|
|
100
|
-
|
|
104
|
+
updatePlaneSize = () => {
|
|
101
105
|
this.planeHelper.size = this.viewer.extents.getSize(new Vector3()).length();
|
|
102
106
|
this.viewer.update();
|
|
103
107
|
};
|
|
@@ -54,6 +54,7 @@ export class MeasureLineDragger extends OrbitDragger {
|
|
|
54
54
|
this.viewer.addEventListener("render", this.renderOverlay);
|
|
55
55
|
this.viewer.addEventListener("hide", this.updateSnapper);
|
|
56
56
|
this.viewer.addEventListener("isolate", this.updateSnapper);
|
|
57
|
+
this.viewer.addEventListener("show", this.updateSnapper);
|
|
57
58
|
this.viewer.addEventListener("showall", this.updateSnapper);
|
|
58
59
|
}
|
|
59
60
|
|
|
@@ -67,6 +68,7 @@ export class MeasureLineDragger extends OrbitDragger {
|
|
|
67
68
|
this.viewer.removeEventListener("render", this.renderOverlay);
|
|
68
69
|
this.viewer.removeEventListener("hide", this.updateSnapper);
|
|
69
70
|
this.viewer.removeEventListener("isolate", this.updateSnapper);
|
|
71
|
+
this.viewer.removeEventListener("show", this.updateSnapper);
|
|
70
72
|
this.viewer.removeEventListener("showall", this.updateSnapper);
|
|
71
73
|
|
|
72
74
|
this.overlay.detach();
|