@inweb/viewer-three 26.10.6 → 26.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -4
- package/dist/{plugins → extensions}/components/AxesHelperComponent.js +23 -1
- package/dist/extensions/components/AxesHelperComponent.js.map +1 -0
- package/dist/extensions/components/AxesHelperComponent.min.js +24 -0
- package/dist/{plugins → extensions}/components/AxesHelperComponent.module.js +24 -2
- package/dist/extensions/components/AxesHelperComponent.module.js.map +1 -0
- package/dist/{plugins → extensions}/components/ExtentsHelperComponent.js +18 -0
- package/dist/extensions/components/ExtentsHelperComponent.js.map +1 -0
- package/dist/{plugins/components/AxesHelperComponent.min.js → extensions/components/ExtentsHelperComponent.min.js} +1 -1
- package/dist/{plugins → extensions}/components/ExtentsHelperComponent.module.js +19 -1
- package/dist/extensions/components/ExtentsHelperComponent.module.js.map +1 -0
- package/dist/extensions/components/GridHelperComponent.js.map +1 -0
- package/dist/extensions/components/GridHelperComponent.module.js.map +1 -0
- package/dist/extensions/components/LightHelperComponent.js.map +1 -0
- package/dist/extensions/components/LightHelperComponent.module.js.map +1 -0
- package/dist/extensions/components/RoomEnvironmentComponent.js.map +1 -0
- package/dist/extensions/components/RoomEnvironmentComponent.module.js.map +1 -0
- package/dist/extensions/components/StatsPanelComponent.js.map +1 -0
- package/dist/extensions/components/StatsPanelComponent.module.js.map +1 -0
- package/dist/{plugins → extensions}/loaders/GLTFCloudLoader.js +2 -3
- package/dist/extensions/loaders/GLTFCloudLoader.js.map +1 -0
- package/dist/{plugins → extensions}/loaders/GLTFCloudLoader.min.js +1 -1
- package/dist/{plugins → extensions}/loaders/GLTFCloudLoader.module.js +2 -3
- package/dist/extensions/loaders/GLTFCloudLoader.module.js.map +1 -0
- package/dist/extensions/loaders/GLTFFileLoader.js +2499 -0
- package/dist/extensions/loaders/GLTFFileLoader.js.map +1 -0
- package/dist/extensions/loaders/GLTFFileLoader.min.js +24 -0
- package/dist/extensions/loaders/GLTFFileLoader.module.js +74 -0
- package/dist/extensions/loaders/GLTFFileLoader.module.js.map +1 -0
- package/dist/{plugins → extensions}/loaders/IFCXLoader.js +5 -7
- package/dist/extensions/loaders/IFCXLoader.js.map +1 -0
- package/dist/{plugins → extensions}/loaders/IFCXLoader.min.js +1 -1
- package/dist/{plugins → extensions}/loaders/IFCXLoader.module.js +5 -7
- package/dist/extensions/loaders/IFCXLoader.module.js.map +1 -0
- package/dist/{plugins → extensions}/loaders/PotreeLoader.js +1 -2
- package/dist/extensions/loaders/PotreeLoader.js.map +1 -0
- package/dist/{plugins → extensions}/loaders/PotreeLoader.min.js +1 -1
- package/dist/{plugins → extensions}/loaders/PotreeLoader.module.js +1 -2
- package/dist/extensions/loaders/PotreeLoader.module.js.map +1 -0
- package/dist/viewer-three.js +1015 -2926
- package/dist/viewer-three.js.map +1 -1
- package/dist/viewer-three.min.js +3 -3
- package/dist/viewer-three.module.js +847 -356
- package/dist/viewer-three.module.js.map +1 -1
- package/{plugins → extensions}/components/AxesHelperComponent.ts +31 -2
- package/{plugins → extensions}/components/ExtentsHelperComponent.ts +25 -0
- package/{plugins → extensions}/loaders/GLTFCloudLoader.ts +2 -3
- package/{src/Viewer → extensions}/loaders/GLTFFileLoader.ts +21 -12
- package/{plugins → extensions}/loaders/IFCX/IFCXCloudLoader.ts +5 -5
- package/{plugins → extensions}/loaders/IFCX/IFCXFileLoader.ts +3 -4
- package/{plugins → extensions}/loaders/Potree/PotreeFileLoader.ts +3 -4
- package/lib/Viewer/Viewer.d.ts +27 -20
- package/lib/Viewer/commands/GetSelected2.d.ts +2 -0
- package/lib/Viewer/commands/SelectModel.d.ts +1 -1
- package/lib/Viewer/commands/SetSelected2.d.ts +2 -0
- package/lib/Viewer/components/SelectionComponent.d.ts +1 -3
- package/lib/Viewer/components/index.d.ts +6 -6
- package/lib/Viewer/draggers/MeasureLineDragger.d.ts +7 -1
- package/lib/Viewer/loaders/DynamicGltfLoader/DynamicModelImpl.d.ts +0 -1
- package/lib/Viewer/loaders/GLTFBinaryExtension.d.ts +5 -0
- package/lib/Viewer/loaders/GLTFCloudDynamicLoader.d.ts +2 -2
- package/lib/Viewer/loaders/{GLTFFileLoader.d.ts → GLTFFileDynamicLoader.d.ts} +7 -1
- package/lib/Viewer/loaders/GLTFLoadingManager.d.ts +4 -3
- package/lib/Viewer/loaders/RangesLoader.d.ts +15 -0
- package/lib/Viewer/loaders/index.d.ts +22 -14
- package/lib/Viewer/measurement/Snapper.d.ts +15 -0
- package/lib/Viewer/measurement/UnitConverter.d.ts +63 -0
- package/lib/Viewer/measurement/UnitFormatter.d.ts +4 -0
- package/lib/Viewer/models/IModelImpl.d.ts +10 -8
- package/lib/Viewer/models/ModelImpl.d.ts +7 -5
- package/package.json +11 -11
- package/src/Viewer/Viewer.ts +120 -88
- package/src/Viewer/commands/ClearSelected.ts +3 -1
- package/src/Viewer/commands/GetModels.ts +1 -1
- package/src/Viewer/commands/GetSelected.ts +2 -2
- package/src/Viewer/commands/GetSelected2.ts +34 -0
- package/src/Viewer/commands/HideSelected.ts +3 -1
- package/src/Viewer/commands/SelectModel.ts +5 -5
- package/src/Viewer/commands/SetSelected.ts +9 -10
- package/src/Viewer/commands/SetSelected2.ts +42 -0
- package/src/Viewer/commands/ZoomToObjects.ts +5 -6
- package/src/Viewer/commands/ZoomToSelected.ts +3 -1
- package/src/Viewer/commands/index.ts +4 -0
- package/src/Viewer/components/CameraComponent.ts +6 -1
- package/src/Viewer/components/ExtentsComponent.ts +4 -1
- package/src/Viewer/components/SelectionComponent.ts +7 -30
- package/src/Viewer/components/index.ts +6 -6
- package/src/Viewer/draggers/MeasureLineDragger.ts +84 -226
- package/src/Viewer/loaders/DynamicGltfLoader/DynamicGltfLoader.js +263 -34
- package/src/Viewer/loaders/DynamicGltfLoader/DynamicModelImpl.ts +20 -10
- package/src/Viewer/loaders/DynamicGltfLoader/GltfStructure.js +4 -1
- package/src/Viewer/loaders/GLTFBinaryExtension.ts +91 -0
- package/src/Viewer/loaders/GLTFCloudDynamicLoader.ts +13 -19
- package/src/Viewer/loaders/GLTFFileDynamicLoader.ts +145 -0
- package/src/Viewer/loaders/GLTFLoadingManager.ts +5 -4
- package/src/Viewer/loaders/RangesLoader.ts +95 -0
- package/src/Viewer/loaders/index.ts +24 -16
- package/src/Viewer/measurement/Snapper.ts +208 -0
- package/src/Viewer/measurement/UnitConverter.ts +47 -0
- package/src/Viewer/measurement/UnitFormatter.ts +95 -0
- package/src/Viewer/models/IModelImpl.ts +15 -8
- package/src/Viewer/models/ModelImpl.ts +48 -17
- package/src/index-umd.ts +1 -1
- package/dist/plugins/components/AxesHelperComponent.js.map +0 -1
- package/dist/plugins/components/AxesHelperComponent.module.js.map +0 -1
- package/dist/plugins/components/ExtentsHelperComponent.js.map +0 -1
- package/dist/plugins/components/ExtentsHelperComponent.min.js +0 -24
- package/dist/plugins/components/ExtentsHelperComponent.module.js.map +0 -1
- package/dist/plugins/components/GridHelperComponent.js.map +0 -1
- package/dist/plugins/components/GridHelperComponent.module.js.map +0 -1
- package/dist/plugins/components/LightHelperComponent.js.map +0 -1
- package/dist/plugins/components/LightHelperComponent.module.js.map +0 -1
- package/dist/plugins/components/RoomEnvironmentComponent.js.map +0 -1
- package/dist/plugins/components/RoomEnvironmentComponent.module.js.map +0 -1
- package/dist/plugins/components/StatsPanelComponent.js.map +0 -1
- package/dist/plugins/components/StatsPanelComponent.module.js.map +0 -1
- package/dist/plugins/loaders/GLTFCloudLoader.js.map +0 -1
- package/dist/plugins/loaders/GLTFCloudLoader.module.js.map +0 -1
- package/dist/plugins/loaders/IFCXLoader.js.map +0 -1
- package/dist/plugins/loaders/IFCXLoader.module.js.map +0 -1
- package/dist/plugins/loaders/PotreeLoader.js.map +0 -1
- package/dist/plugins/loaders/PotreeLoader.module.js.map +0 -1
- /package/dist/{plugins → extensions}/components/GridHelperComponent.js +0 -0
- /package/dist/{plugins → extensions}/components/GridHelperComponent.min.js +0 -0
- /package/dist/{plugins → extensions}/components/GridHelperComponent.module.js +0 -0
- /package/dist/{plugins → extensions}/components/LightHelperComponent.js +0 -0
- /package/dist/{plugins → extensions}/components/LightHelperComponent.min.js +0 -0
- /package/dist/{plugins → extensions}/components/LightHelperComponent.module.js +0 -0
- /package/dist/{plugins → extensions}/components/RoomEnvironmentComponent.js +0 -0
- /package/dist/{plugins → extensions}/components/RoomEnvironmentComponent.min.js +0 -0
- /package/dist/{plugins → extensions}/components/RoomEnvironmentComponent.module.js +0 -0
- /package/dist/{plugins → extensions}/components/StatsPanelComponent.js +0 -0
- /package/dist/{plugins → extensions}/components/StatsPanelComponent.min.js +0 -0
- /package/dist/{plugins → extensions}/components/StatsPanelComponent.module.js +0 -0
- /package/{plugins → extensions}/components/GridHelperComponent.ts +0 -0
- /package/{plugins → extensions}/components/LightHelperComponent.ts +0 -0
- /package/{plugins → extensions}/components/RoomEnvironmentComponent.ts +0 -0
- /package/{plugins → extensions}/components/StatsPanelComponent.ts +0 -0
- /package/{plugins → extensions}/loaders/IFCX/IFCXLoader.ts +0 -0
- /package/{plugins → extensions}/loaders/IFCX/index.ts +0 -0
- /package/{plugins → extensions}/loaders/IFCX/render.js +0 -0
- /package/{plugins → extensions}/loaders/Potree/PotreeModelImpl.ts +0 -0
- /package/{plugins → extensions}/loaders/Potree/index.ts +0 -0
|
@@ -21,32 +21,24 @@
|
|
|
21
21
|
// acknowledge and accept the above terms.
|
|
22
22
|
///////////////////////////////////////////////////////////////////////////////
|
|
23
23
|
|
|
24
|
-
import {
|
|
25
|
-
Camera,
|
|
26
|
-
EdgesGeometry,
|
|
27
|
-
Intersection,
|
|
28
|
-
Line3,
|
|
29
|
-
MathUtils,
|
|
30
|
-
Matrix4,
|
|
31
|
-
Object3D,
|
|
32
|
-
Plane,
|
|
33
|
-
Raycaster,
|
|
34
|
-
Vector2,
|
|
35
|
-
Vector3,
|
|
36
|
-
Vector4,
|
|
37
|
-
} from "three";
|
|
24
|
+
import { Camera, MathUtils, Matrix4, Object3D, Vector2, Vector3, Vector4 } from "three";
|
|
38
25
|
|
|
39
26
|
import type { Viewer } from "../Viewer";
|
|
40
27
|
import { OrbitDragger } from "./OrbitDragger";
|
|
28
|
+
import { convertUnits } from "../measurement/UnitConverter";
|
|
29
|
+
import { formatDistance } from "../measurement/UnitFormatter";
|
|
30
|
+
import { Snapper } from "../measurement/Snapper";
|
|
41
31
|
|
|
42
|
-
const
|
|
43
|
-
const DESKTOP_SNAP_DISTANCE = 10;
|
|
44
|
-
const MOBILE_SNAP_DISTANCE = 50;
|
|
32
|
+
const _downPoint = new Vector2();
|
|
45
33
|
|
|
46
34
|
export class MeasureLineDragger extends OrbitDragger {
|
|
47
35
|
private overlay: MeasureOverlay;
|
|
48
36
|
private line: MeasureLine;
|
|
49
|
-
private snapper:
|
|
37
|
+
private snapper: Snapper;
|
|
38
|
+
private objects: Object3D[];
|
|
39
|
+
private scale = 1.0;
|
|
40
|
+
private units = "";
|
|
41
|
+
private precision: any = 2;
|
|
50
42
|
|
|
51
43
|
constructor(viewer: Viewer) {
|
|
52
44
|
super(viewer);
|
|
@@ -54,11 +46,15 @@ export class MeasureLineDragger extends OrbitDragger {
|
|
|
54
46
|
this.overlay = new MeasureOverlay(viewer.camera, viewer.canvas);
|
|
55
47
|
this.overlay.attach();
|
|
56
48
|
|
|
57
|
-
this.line = new MeasureLine(this.overlay);
|
|
49
|
+
this.line = new MeasureLine(this.overlay, this.scale, this.units, this.precision);
|
|
58
50
|
this.overlay.addLine(this.line);
|
|
59
51
|
|
|
60
|
-
this.snapper = new
|
|
61
|
-
|
|
52
|
+
this.snapper = new Snapper(viewer.camera, viewer.renderer, viewer.canvas);
|
|
53
|
+
|
|
54
|
+
this.objects = [];
|
|
55
|
+
this.updateObjects();
|
|
56
|
+
|
|
57
|
+
this.updateUnits();
|
|
62
58
|
|
|
63
59
|
this.viewer.canvas.addEventListener("pointerdown", this.onPointerDown);
|
|
64
60
|
this.viewer.canvas.addEventListener("pointermove", this.onPointerMove);
|
|
@@ -67,11 +63,12 @@ export class MeasureLineDragger extends OrbitDragger {
|
|
|
67
63
|
this.viewer.canvas.addEventListener("pointerleave", this.onPointerLeave);
|
|
68
64
|
|
|
69
65
|
this.viewer.addEventListener("render", this.renderOverlay);
|
|
70
|
-
this.viewer.addEventListener("hide", this.
|
|
71
|
-
this.viewer.addEventListener("isolate", this.
|
|
72
|
-
this.viewer.addEventListener("show", this.
|
|
73
|
-
this.viewer.addEventListener("showall", this.
|
|
66
|
+
this.viewer.addEventListener("hide", this.updateObjects);
|
|
67
|
+
this.viewer.addEventListener("isolate", this.updateObjects);
|
|
68
|
+
this.viewer.addEventListener("show", this.updateObjects);
|
|
69
|
+
this.viewer.addEventListener("showall", this.updateObjects);
|
|
74
70
|
this.viewer.addEventListener("changecameramode", this.updateSnapperCamera);
|
|
71
|
+
this.viewer.addEventListener("optionschange", this.updateUnits);
|
|
75
72
|
}
|
|
76
73
|
|
|
77
74
|
override dispose() {
|
|
@@ -82,13 +79,14 @@ export class MeasureLineDragger extends OrbitDragger {
|
|
|
82
79
|
this.viewer.canvas.removeEventListener("pointerleave", this.onPointerLeave);
|
|
83
80
|
|
|
84
81
|
this.viewer.removeEventListener("render", this.renderOverlay);
|
|
85
|
-
this.viewer.removeEventListener("hide", this.
|
|
86
|
-
this.viewer.removeEventListener("isolate", this.
|
|
87
|
-
this.viewer.removeEventListener("show", this.
|
|
88
|
-
this.viewer.removeEventListener("showall", this.
|
|
82
|
+
this.viewer.removeEventListener("hide", this.updateObjects);
|
|
83
|
+
this.viewer.removeEventListener("isolate", this.updateObjects);
|
|
84
|
+
this.viewer.removeEventListener("show", this.updateObjects);
|
|
85
|
+
this.viewer.removeEventListener("showall", this.updateObjects);
|
|
89
86
|
this.viewer.removeEventListener("changecameramode", this.updateSnapperCamera);
|
|
87
|
+
this.viewer.removeEventListener("optionschange", this.updateUnits);
|
|
90
88
|
|
|
91
|
-
this.
|
|
89
|
+
this.objects.length = 0;
|
|
92
90
|
|
|
93
91
|
this.overlay.detach();
|
|
94
92
|
this.overlay.dispose();
|
|
@@ -99,7 +97,8 @@ export class MeasureLineDragger extends OrbitDragger {
|
|
|
99
97
|
onPointerDown = (event: PointerEvent) => {
|
|
100
98
|
if (event.button !== 0) return;
|
|
101
99
|
|
|
102
|
-
|
|
100
|
+
const mouse = this.snapper.getMousePosition(event, _downPoint);
|
|
101
|
+
this.line.startPoint = this.snapper.getSnapPoint(mouse, this.objects);
|
|
103
102
|
this.line.render();
|
|
104
103
|
|
|
105
104
|
this.viewer.canvas.setPointerCapture(event.pointerId);
|
|
@@ -109,7 +108,8 @@ export class MeasureLineDragger extends OrbitDragger {
|
|
|
109
108
|
onPointerMove = (event: PointerEvent) => {
|
|
110
109
|
if (this.orbit.enabled && this.orbit.state !== -1) return;
|
|
111
110
|
|
|
112
|
-
const
|
|
111
|
+
const mouse = this.snapper.getMousePosition(event, _downPoint);
|
|
112
|
+
const snapPoint = this.snapper.getSnapPoint(mouse, this.objects);
|
|
113
113
|
if (snapPoint && this.line.endPoint && snapPoint.equals(this.line.endPoint)) return;
|
|
114
114
|
|
|
115
115
|
this.line.endPoint = snapPoint;
|
|
@@ -119,8 +119,8 @@ export class MeasureLineDragger extends OrbitDragger {
|
|
|
119
119
|
};
|
|
120
120
|
|
|
121
121
|
onPointerUp = (event: PointerEvent) => {
|
|
122
|
-
if (this.line.startPoint && this.line.endPoint && this.line.getDistance()
|
|
123
|
-
this.line = new MeasureLine(this.overlay);
|
|
122
|
+
if (this.line.startPoint && this.line.endPoint && this.line.getDistance() > 0) {
|
|
123
|
+
this.line = new MeasureLine(this.overlay, this.scale, this.units, this.precision);
|
|
124
124
|
this.overlay.addLine(this.line);
|
|
125
125
|
} else {
|
|
126
126
|
this.line.startPoint = undefined;
|
|
@@ -141,204 +141,50 @@ export class MeasureLineDragger extends OrbitDragger {
|
|
|
141
141
|
this.line.render();
|
|
142
142
|
};
|
|
143
143
|
|
|
144
|
+
clearOverlay = () => {
|
|
145
|
+
this.overlay.clear();
|
|
146
|
+
|
|
147
|
+
this.line = new MeasureLine(this.overlay, this.scale, this.units, this.precision);
|
|
148
|
+
this.overlay.addLine(this.line);
|
|
149
|
+
};
|
|
150
|
+
|
|
144
151
|
renderOverlay = () => {
|
|
145
152
|
this.overlay.render();
|
|
146
153
|
};
|
|
147
154
|
|
|
148
|
-
|
|
149
|
-
this.
|
|
155
|
+
updateObjects = () => {
|
|
156
|
+
this.objects.length = 0;
|
|
157
|
+
this.viewer.models.forEach((model) => {
|
|
158
|
+
model.getVisibleObjects().forEach((object) => this.objects.push(object));
|
|
159
|
+
});
|
|
150
160
|
};
|
|
151
161
|
|
|
152
162
|
updateSnapperCamera = () => {
|
|
153
163
|
this.snapper.camera = this.viewer.camera;
|
|
154
164
|
this.overlay.camera = this.viewer.camera;
|
|
155
165
|
};
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
const _vertex = new Vector3();
|
|
159
|
-
const _start = new Vector3();
|
|
160
|
-
const _end = new Vector3();
|
|
161
|
-
const _line = new Line3();
|
|
162
|
-
const _center = new Vector3();
|
|
163
|
-
const _projection = new Vector3();
|
|
164
|
-
|
|
165
|
-
class MeasureSnapper {
|
|
166
|
-
public camera: Camera;
|
|
167
|
-
private canvas: HTMLCanvasElement;
|
|
168
|
-
private objects: Object3D[];
|
|
169
|
-
private clippingPlanes: Plane[];
|
|
170
|
-
private raycaster: Raycaster;
|
|
171
|
-
private detectRadiusInPixels: number;
|
|
172
|
-
private edgesCache: WeakMap<any, EdgesGeometry>;
|
|
173
|
-
|
|
174
|
-
constructor(camera: Camera, canvas: HTMLCanvasElement) {
|
|
175
|
-
this.camera = camera;
|
|
176
|
-
this.canvas = canvas;
|
|
177
|
-
this.objects = [];
|
|
178
|
-
this.clippingPlanes = [];
|
|
179
|
-
this.raycaster = new Raycaster();
|
|
180
|
-
this.detectRadiusInPixels = this.isMobile() ? MOBILE_SNAP_DISTANCE : DESKTOP_SNAP_DISTANCE;
|
|
181
|
-
this.edgesCache = new WeakMap();
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
dispose() {
|
|
185
|
-
this.objects = [];
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
isMobile(): boolean {
|
|
189
|
-
if (typeof navigator === "undefined") return false;
|
|
190
|
-
|
|
191
|
-
// ===================== AI-CODE-START ======================
|
|
192
|
-
// Source: Claude Sonnet 4
|
|
193
|
-
// Date: 2025-09-09
|
|
194
|
-
// Reviewer: roman.mochalov@opendesign.com
|
|
195
|
-
// Issue: CLOUD-5799
|
|
196
|
-
|
|
197
|
-
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent);
|
|
198
|
-
|
|
199
|
-
// ===================== AI-CODE-END ======================
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
getMousePosition(event: MouseEvent, target: Vector2): Vector2 {
|
|
203
|
-
return target.set(event.clientX, event.clientY);
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
getPointerIntersects(mouse: Vector2): Array<Intersection<Object3D>> {
|
|
207
|
-
const rect = this.canvas.getBoundingClientRect();
|
|
208
|
-
const x = ((mouse.x - rect.left) / rect.width) * 2 - 1;
|
|
209
|
-
const y = (-(mouse.y - rect.top) / rect.height) * 2 + 1;
|
|
210
|
-
|
|
211
|
-
const coords = new Vector2(x, y);
|
|
212
|
-
this.raycaster.setFromCamera(coords, this.camera);
|
|
213
|
-
|
|
214
|
-
this.raycaster.params = {
|
|
215
|
-
Mesh: {},
|
|
216
|
-
Line: { threshold: 0.05 },
|
|
217
|
-
Line2: { threshold: 0.05 },
|
|
218
|
-
LOD: {},
|
|
219
|
-
Points: { threshold: 0.01 },
|
|
220
|
-
Sprite: {},
|
|
221
|
-
};
|
|
222
|
-
|
|
223
|
-
let intersects = this.raycaster.intersectObjects(this.objects, false);
|
|
224
|
-
|
|
225
|
-
this.clippingPlanes.forEach((plane) => {
|
|
226
|
-
intersects = intersects.filter((intersect) => plane.distanceToPoint(intersect.point) >= 0);
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
return intersects;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
getDetectRadius(point: Vector3): number {
|
|
233
|
-
const camera: any = this.camera;
|
|
234
|
-
|
|
235
|
-
// ===================== AI-CODE-START ======================
|
|
236
|
-
// Source: Gemini 2.5 Pro
|
|
237
|
-
// Date: 2025-08-27
|
|
238
|
-
// Reviewer: roman.mochalov@opendesign.com
|
|
239
|
-
// Issue: CLOUD-5799
|
|
240
|
-
// Notes: Originally AI-generated, modified manually
|
|
241
166
|
|
|
242
|
-
|
|
243
|
-
|
|
167
|
+
updateUnits = () => {
|
|
168
|
+
const model = this.viewer.models[0];
|
|
169
|
+
const units = this.viewer.options.rulerUnit ?? "Default";
|
|
170
|
+
const precision = this.viewer.options.rulerPrecision ?? "Default";
|
|
244
171
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
if (camera.isPerspectiveCamera) {
|
|
252
|
-
const distance = camera.position.distanceTo(point);
|
|
253
|
-
const fieldHeight = 2 * Math.tan(MathUtils.degToRad(camera.fov * 0.5)) * distance;
|
|
254
|
-
|
|
255
|
-
const canvasHeight = this.canvas.height;
|
|
256
|
-
const worldUnitsPerPixel = fieldHeight / canvasHeight;
|
|
257
|
-
|
|
258
|
-
return this.detectRadiusInPixels * worldUnitsPerPixel;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
// ===================== AI-CODE-END ======================
|
|
262
|
-
|
|
263
|
-
return 0.1;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
getSnapPoint(event: PointerEvent): Vector3 {
|
|
267
|
-
const mouse = this.getMousePosition(event, new Vector2());
|
|
268
|
-
|
|
269
|
-
const intersections = this.getPointerIntersects(mouse);
|
|
270
|
-
if (intersections.length === 0) return undefined;
|
|
271
|
-
|
|
272
|
-
// ===================== AI-CODE-START ======================
|
|
273
|
-
// Source: Gemini 2.5 Pro
|
|
274
|
-
// Date: 2025-08-20
|
|
275
|
-
// Reviewer: roman.mochalov@opendesign.com
|
|
276
|
-
// Issue: CLOUD-5799
|
|
277
|
-
// Notes: Originally AI-generated, modified manually
|
|
278
|
-
|
|
279
|
-
const object: any = intersections[0].object;
|
|
280
|
-
const intersectionPoint = intersections[0].point;
|
|
281
|
-
const localPoint = object.worldToLocal(intersectionPoint.clone());
|
|
282
|
-
|
|
283
|
-
let snapPoint: Vector3;
|
|
284
|
-
let snapDistance = this.getDetectRadius(intersectionPoint);
|
|
285
|
-
|
|
286
|
-
const geometry = object.geometry;
|
|
287
|
-
|
|
288
|
-
const positions = geometry.attributes.position.array;
|
|
289
|
-
for (let i = 0; i < positions.length; i += 3) {
|
|
290
|
-
_vertex.set(positions[i], positions[i + 1], positions[i + 2]);
|
|
291
|
-
const distance = _vertex.distanceTo(localPoint);
|
|
292
|
-
if (distance < snapDistance) {
|
|
293
|
-
snapDistance = distance;
|
|
294
|
-
snapPoint = _vertex.clone();
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
if (snapPoint) return object.localToWorld(snapPoint);
|
|
298
|
-
|
|
299
|
-
let edges = this.edgesCache.get(geometry);
|
|
300
|
-
if (!edges) {
|
|
301
|
-
edges = new EdgesGeometry(geometry);
|
|
302
|
-
this.edgesCache.set(geometry, edges);
|
|
172
|
+
if (units === "Default") {
|
|
173
|
+
this.scale = model.getUnitScale();
|
|
174
|
+
this.units = model.getUnitString();
|
|
175
|
+
} else {
|
|
176
|
+
this.scale = convertUnits(model.getUnits(), units, 1);
|
|
177
|
+
this.units = units;
|
|
303
178
|
}
|
|
304
179
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
_line.set(_start, _end);
|
|
310
|
-
|
|
311
|
-
_line.getCenter(_center);
|
|
312
|
-
const centerDistance = _center.distanceTo(localPoint);
|
|
313
|
-
if (centerDistance < snapDistance) {
|
|
314
|
-
snapDistance = centerDistance;
|
|
315
|
-
snapPoint = _center.clone();
|
|
316
|
-
continue;
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
_line.closestPointToPoint(localPoint, true, _projection);
|
|
320
|
-
const lineDistance = _projection.distanceTo(localPoint);
|
|
321
|
-
if (lineDistance < snapDistance) {
|
|
322
|
-
snapDistance = lineDistance;
|
|
323
|
-
snapPoint = _projection.clone();
|
|
324
|
-
}
|
|
180
|
+
if (precision === "Default") {
|
|
181
|
+
this.precision = model.getPrecision();
|
|
182
|
+
} else {
|
|
183
|
+
this.precision = precision;
|
|
325
184
|
}
|
|
326
|
-
if (snapPoint) return object.localToWorld(snapPoint);
|
|
327
|
-
|
|
328
|
-
// ===================== AI-CODE-END ======================
|
|
329
185
|
|
|
330
|
-
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
setFromViewer(viewer: Viewer) {
|
|
334
|
-
this.objects.length = 0;
|
|
335
|
-
viewer.models.forEach((model) => {
|
|
336
|
-
model.getVisibleObjects().forEach((object) => this.objects.push(object));
|
|
337
|
-
});
|
|
338
|
-
|
|
339
|
-
this.camera = viewer.camera;
|
|
340
|
-
this.clippingPlanes = viewer.renderer.clippingPlanes || [];
|
|
341
|
-
}
|
|
186
|
+
this.overlay.updateLineUnits(this.scale, this.units, this.precision);
|
|
187
|
+
};
|
|
342
188
|
}
|
|
343
189
|
|
|
344
190
|
class MeasureOverlay {
|
|
@@ -356,6 +202,10 @@ class MeasureOverlay {
|
|
|
356
202
|
this.resizeObserver = new ResizeObserver(this.resizeContainer);
|
|
357
203
|
}
|
|
358
204
|
|
|
205
|
+
dispose() {
|
|
206
|
+
this.clear();
|
|
207
|
+
}
|
|
208
|
+
|
|
359
209
|
attach() {
|
|
360
210
|
this.container = document.createElement("div");
|
|
361
211
|
this.container.id = "measure-container";
|
|
@@ -370,10 +220,6 @@ class MeasureOverlay {
|
|
|
370
220
|
this.resizeObserver.observe(this.canvas);
|
|
371
221
|
}
|
|
372
222
|
|
|
373
|
-
dispose() {
|
|
374
|
-
this.clear();
|
|
375
|
-
}
|
|
376
|
-
|
|
377
223
|
detach() {
|
|
378
224
|
this.resizeObserver.disconnect();
|
|
379
225
|
|
|
@@ -383,7 +229,7 @@ class MeasureOverlay {
|
|
|
383
229
|
|
|
384
230
|
clear() {
|
|
385
231
|
this.lines.forEach((line) => line.dispose());
|
|
386
|
-
this.lines =
|
|
232
|
+
this.lines.length = 0;
|
|
387
233
|
}
|
|
388
234
|
|
|
389
235
|
render() {
|
|
@@ -403,6 +249,14 @@ class MeasureOverlay {
|
|
|
403
249
|
this.lines = this.lines.filter((x) => x !== line);
|
|
404
250
|
}
|
|
405
251
|
|
|
252
|
+
updateLineUnits(scale: number, units: string, precision: any) {
|
|
253
|
+
this.lines.forEach((line) => {
|
|
254
|
+
line.scale = scale;
|
|
255
|
+
line.units = units;
|
|
256
|
+
line.precision = precision;
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
|
|
406
260
|
resizeContainer = () => {
|
|
407
261
|
const { offsetLeft, offsetTop, offsetWidth, offsetHeight } = this.canvas;
|
|
408
262
|
|
|
@@ -430,8 +284,9 @@ class MeasureLine {
|
|
|
430
284
|
public endPoint: Vector3;
|
|
431
285
|
|
|
432
286
|
public id = MathUtils.generateUUID();
|
|
433
|
-
public
|
|
434
|
-
public
|
|
287
|
+
public scale: number;
|
|
288
|
+
public units: string;
|
|
289
|
+
public precision: any;
|
|
435
290
|
public size = 10.0;
|
|
436
291
|
public lineWidth = 2;
|
|
437
292
|
|
|
@@ -443,8 +298,11 @@ class MeasureLine {
|
|
|
443
298
|
font: "1rem system-ui",
|
|
444
299
|
};
|
|
445
300
|
|
|
446
|
-
constructor(overlay: MeasureOverlay) {
|
|
301
|
+
constructor(overlay: MeasureOverlay, scale: number, units: string, precision: any) {
|
|
447
302
|
this.overlay = overlay;
|
|
303
|
+
this.scale = scale;
|
|
304
|
+
this.units = units;
|
|
305
|
+
this.precision = precision;
|
|
448
306
|
|
|
449
307
|
this.elementStartPoint = overlay.container.appendChild(document.createElement("div"));
|
|
450
308
|
this.elementEndPoint = overlay.container.appendChild(document.createElement("div"));
|
|
@@ -511,10 +369,10 @@ class MeasureLine {
|
|
|
511
369
|
|
|
512
370
|
const distance = this.getDistance();
|
|
513
371
|
|
|
514
|
-
this.elementLabel.style.display = visible && distance
|
|
372
|
+
this.elementLabel.style.display = visible && distance > 0 ? "block" : "none";
|
|
515
373
|
this.elementLabel.style.left = `${point.x}px`;
|
|
516
374
|
this.elementLabel.style.top = `${point.y}px`;
|
|
517
|
-
this.elementLabel.innerHTML =
|
|
375
|
+
this.elementLabel.innerHTML = formatDistance(distance, this.units, this.precision);
|
|
518
376
|
} else {
|
|
519
377
|
this.elementLabel.style.display = "none";
|
|
520
378
|
}
|