fl-web-component 2.0.15 → 2.0.17
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 +5 -1
- package/dist/fl-web-component.common.js +702 -236
- package/dist/fl-web-component.common.js.map +1 -1
- package/dist/fl-web-component.css +1 -1
- package/package.json +1 -1
- package/packages/components/com-flcanvas/index.vue +17 -0
- package/packages/components/com-graphics/index.vue +63 -12
- package/src/utils/threejs/measure-angle.js +172 -41
- package/src/utils/threejs/measure-area.js +144 -46
- package/src/utils/threejs/measure-distance.js +135 -18
- package/src/utils/threejs/measure-height.js +59 -15
|
@@ -2,10 +2,11 @@ import * as THREE from 'three';
|
|
|
2
2
|
import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer';
|
|
3
3
|
import { Message } from 'element-ui';
|
|
4
4
|
var _this = null;
|
|
5
|
-
var MeasureArea = function (renderer, scene, camera, width, height) {
|
|
5
|
+
var MeasureArea = function (renderer, scene, camera, width, height, options = {}) {
|
|
6
6
|
this.renderer = renderer;
|
|
7
7
|
this.scene = scene;
|
|
8
8
|
this.camera = camera;
|
|
9
|
+
this.pickRoots = options.pickRoots || null;
|
|
9
10
|
this.pointArray = []; // 保存当前操作所添加的点
|
|
10
11
|
this.raycaster = new THREE.Raycaster();
|
|
11
12
|
this.points = []; // 保存页面中所添加的点
|
|
@@ -16,13 +17,14 @@ var MeasureArea = function (renderer, scene, camera, width, height) {
|
|
|
16
17
|
this.tempLabel = undefined;
|
|
17
18
|
this.tipsLabel = undefined;
|
|
18
19
|
this.isCompleted = false;
|
|
20
|
+
this.hasTempPoint = false;
|
|
19
21
|
this.timer = null;
|
|
20
22
|
this.polygonMesh = undefined;
|
|
21
23
|
this.polygons = [];
|
|
22
24
|
this.width = width;
|
|
23
25
|
this.height = height;
|
|
24
26
|
this.firstTime = 0;
|
|
25
|
-
this.measureName = 'measureObj'
|
|
27
|
+
this.measureName = 'measureObj';
|
|
26
28
|
// 创建一个辅助平面来捕获鼠标事件
|
|
27
29
|
this.plane = new THREE.Plane(new THREE.Vector3(0, 0, 1), 0);
|
|
28
30
|
};
|
|
@@ -43,7 +45,99 @@ MeasureArea.prototype = {
|
|
|
43
45
|
this.width = width;
|
|
44
46
|
this.height = height;
|
|
45
47
|
},
|
|
46
|
-
|
|
48
|
+
getPickRoots() {
|
|
49
|
+
const roots = typeof _this.pickRoots === 'function' ? _this.pickRoots() : _this.pickRoots;
|
|
50
|
+
if (Array.isArray(roots) && roots.length > 0) {
|
|
51
|
+
return roots.filter(Boolean);
|
|
52
|
+
}
|
|
53
|
+
if (roots) {
|
|
54
|
+
return [roots];
|
|
55
|
+
}
|
|
56
|
+
return _this.scene && _this.scene.children ? _this.scene.children : [];
|
|
57
|
+
},
|
|
58
|
+
isExcludedIntersection(object) {
|
|
59
|
+
let current = object;
|
|
60
|
+
while (current) {
|
|
61
|
+
const userData = current.userData || {};
|
|
62
|
+
if (current.visible === false) return true;
|
|
63
|
+
if (current.name === _this.measureName || userData.isMeasureObject === true) return true;
|
|
64
|
+
if (userData.transformControlHelper === true || userData.outlineProxy === true) return true;
|
|
65
|
+
if (current.isCamera || current.isLight) return true;
|
|
66
|
+
if (
|
|
67
|
+
typeof current.type === 'string' &&
|
|
68
|
+
(/Helper$/i.test(current.type) ||
|
|
69
|
+
current.type === 'CSS2DObject' ||
|
|
70
|
+
current.type === 'TransformControlsRoot')
|
|
71
|
+
) {
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
current = current.parent;
|
|
75
|
+
}
|
|
76
|
+
return false;
|
|
77
|
+
},
|
|
78
|
+
markMeasureObject(object) {
|
|
79
|
+
object.name = this.measureName;
|
|
80
|
+
if (!object.userData) {
|
|
81
|
+
object.userData = {};
|
|
82
|
+
}
|
|
83
|
+
object.userData.isMeasureObject = true;
|
|
84
|
+
return object;
|
|
85
|
+
},
|
|
86
|
+
disposeObject(object) {
|
|
87
|
+
if (!object) return;
|
|
88
|
+
if (object.geometry) {
|
|
89
|
+
object.geometry.dispose();
|
|
90
|
+
}
|
|
91
|
+
if (object.material) {
|
|
92
|
+
object.material.dispose();
|
|
93
|
+
}
|
|
94
|
+
this.scene.remove(object);
|
|
95
|
+
},
|
|
96
|
+
removeArrayItem(array, item) {
|
|
97
|
+
if (!item) return;
|
|
98
|
+
const index = array.indexOf(item);
|
|
99
|
+
if (index !== -1) {
|
|
100
|
+
array.splice(index, 1);
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
clearTempMeasure() {
|
|
104
|
+
if (this.hasTempPoint && this.pointArray.length > 0) {
|
|
105
|
+
this.pointArray.pop();
|
|
106
|
+
}
|
|
107
|
+
this.removeArrayItem(this.points, this.tempPoints);
|
|
108
|
+
this.removeArrayItem(this.polyline, this.tempLine);
|
|
109
|
+
this.disposeObject(this.tempPoints);
|
|
110
|
+
this.disposeObject(this.tempLine);
|
|
111
|
+
this.tempPoints = undefined;
|
|
112
|
+
this.tempLine = undefined;
|
|
113
|
+
this.hasTempPoint = false;
|
|
114
|
+
this.updateAreaMeasure();
|
|
115
|
+
},
|
|
116
|
+
updateAreaMeasure() {
|
|
117
|
+
if (this.pointArray.length <= 2) {
|
|
118
|
+
this.removeArrayItem(this.polygons, this.polygonMesh);
|
|
119
|
+
this.removeArrayItem(this.labels, this.tempLabel);
|
|
120
|
+
this.disposeObject(this.polygonMesh);
|
|
121
|
+
this.disposeObject(this.tempLabel);
|
|
122
|
+
this.polygonMesh = undefined;
|
|
123
|
+
this.tempLabel = undefined;
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
const area = this.calculateArea(this.pointArray);
|
|
127
|
+
this.createPolygon(this.pointArray);
|
|
128
|
+
if (!this.polygonMesh) return;
|
|
129
|
+
this.polygonMesh.geometry.computeBoundingSphere();
|
|
130
|
+
const center = this.polygonMesh.geometry.boundingSphere.center;
|
|
131
|
+
if (this.tempLabel) {
|
|
132
|
+
this.tempLabel.element.textContent = this.numberToString(area);
|
|
133
|
+
this.tempLabel.position.set(center.x, center.y, center.z);
|
|
134
|
+
} else {
|
|
135
|
+
this.tempLabel = this.createLabel('measure-label', this.numberToString(area), center);
|
|
136
|
+
this.labels.push(this.tempLabel);
|
|
137
|
+
this.scene.add(this.tempLabel);
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
getPosition(e, options = {}) {
|
|
47
141
|
const mouse = new THREE.Vector2();
|
|
48
142
|
const elRect = this.renderer.domElement.getBoundingClientRect();
|
|
49
143
|
const canvasX = e.clientX - elRect.left;
|
|
@@ -53,11 +147,17 @@ MeasureArea.prototype = {
|
|
|
53
147
|
mouse.y = -(canvasY / elRect.height) * 2.0 + 1.0;
|
|
54
148
|
|
|
55
149
|
_this.raycaster.setFromCamera(mouse, _this.camera);
|
|
56
|
-
let intersects = _this.raycaster
|
|
150
|
+
let intersects = _this.raycaster
|
|
151
|
+
.intersectObjects(_this.getPickRoots(), true)
|
|
152
|
+
.filter(item => item && item.object && !_this.isExcludedIntersection(item.object));
|
|
57
153
|
if (intersects.length > 0) {
|
|
58
154
|
return { point: intersects[0].point, isModel: true };
|
|
59
155
|
}
|
|
60
156
|
|
|
157
|
+
if (options.allowPlaneFallback === false) {
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
|
|
61
161
|
// 如果没有交点,构建一个基于最后一个确认点且面向相机的平面
|
|
62
162
|
if (_this.pointArray && _this.pointArray.length > 0) {
|
|
63
163
|
const lastPoint =
|
|
@@ -92,7 +192,7 @@ MeasureArea.prototype = {
|
|
|
92
192
|
});
|
|
93
193
|
const lineGeometry = new THREE.BufferGeometry().setFromPoints([p1, p2]);
|
|
94
194
|
const line = new THREE.Line(lineGeometry, lineMaterial);
|
|
95
|
-
|
|
195
|
+
this.markMeasureObject(line);
|
|
96
196
|
line.renderOrder = 999;
|
|
97
197
|
line.frustumCulled = false;
|
|
98
198
|
return line;
|
|
@@ -102,7 +202,7 @@ MeasureArea.prototype = {
|
|
|
102
202
|
div.className = name;
|
|
103
203
|
div.textContent = text;
|
|
104
204
|
const divLabel = new CSS2DObject(div);
|
|
105
|
-
|
|
205
|
+
this.markMeasureObject(divLabel);
|
|
106
206
|
divLabel.position.set(position.x, position.y, position.z);
|
|
107
207
|
return divLabel;
|
|
108
208
|
},
|
|
@@ -111,9 +211,12 @@ MeasureArea.prototype = {
|
|
|
111
211
|
const positionResult = _this.getPosition(e);
|
|
112
212
|
if (positionResult) {
|
|
113
213
|
const point = positionResult.point;
|
|
114
|
-
_this.
|
|
115
|
-
|
|
116
|
-
|
|
214
|
+
if (_this.hasTempPoint) {
|
|
215
|
+
_this.pointArray.splice(_this.pointArray.length - 1, 1, point);
|
|
216
|
+
} else {
|
|
217
|
+
_this.pointArray.push(point);
|
|
218
|
+
_this.hasTempPoint = true;
|
|
219
|
+
}
|
|
117
220
|
const length = _this.pointArray.length;
|
|
118
221
|
if (_this.tempPoints) {
|
|
119
222
|
_this.tempPoints.position.set(point.x, point.y, point.z);
|
|
@@ -132,29 +235,7 @@ MeasureArea.prototype = {
|
|
|
132
235
|
_this.polyline.push(_this.tempLine);
|
|
133
236
|
_this.scene.add(_this.tempLine);
|
|
134
237
|
}
|
|
135
|
-
|
|
136
|
-
const area = _this.calculateArea(_this.pointArray);
|
|
137
|
-
_this.createPolygon(_this.pointArray);
|
|
138
|
-
if (_this.tempLabel) {
|
|
139
|
-
_this.polygonMesh.geometry.computeBoundingSphere();
|
|
140
|
-
_this.tempLabel.element.textContent = _this.numberToString(area); // + '㎡'
|
|
141
|
-
_this.tempLabel.position.set(
|
|
142
|
-
_this.polygonMesh.geometry.boundingSphere.center.x,
|
|
143
|
-
_this.polygonMesh.geometry.boundingSphere.center.y,
|
|
144
|
-
_this.polygonMesh.geometry.boundingSphere.center.z
|
|
145
|
-
);
|
|
146
|
-
} else {
|
|
147
|
-
_this.polygonMesh.geometry.computeBoundingSphere();
|
|
148
|
-
console.log(_this.polygonMesh.geometry);
|
|
149
|
-
_this.tempLabel = _this.createLabel(
|
|
150
|
-
'measure-label',
|
|
151
|
-
area,
|
|
152
|
-
_this.polygonMesh.geometry.boundingSphere.center
|
|
153
|
-
);
|
|
154
|
-
_this.labels.push(_this.tempLabel);
|
|
155
|
-
_this.scene.add(_this.tempLabel);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
238
|
+
_this.updateAreaMeasure();
|
|
158
239
|
if (_this.tipsLabel) {
|
|
159
240
|
_this.tipsLabel.position.set(point.x + 0.1, point.y, point.z + 0.05);
|
|
160
241
|
}
|
|
@@ -165,7 +246,7 @@ MeasureArea.prototype = {
|
|
|
165
246
|
div.className = 'tips-label';
|
|
166
247
|
div.textContent = label;
|
|
167
248
|
const tipsLabel = new CSS2DObject(div);
|
|
168
|
-
|
|
249
|
+
this.markMeasureObject(tipsLabel);
|
|
169
250
|
tipsLabel.position.set(position.x + 0.1, position.y, position.z + 0.05);
|
|
170
251
|
return tipsLabel;
|
|
171
252
|
},
|
|
@@ -181,13 +262,20 @@ MeasureArea.prototype = {
|
|
|
181
262
|
clearTimeout(_this.timer);
|
|
182
263
|
_this.timer = setTimeout(() => {
|
|
183
264
|
_this.isCompleted = false;
|
|
184
|
-
const positionResult = _this.getPosition(e);
|
|
265
|
+
const positionResult = _this.getPosition(e, { allowPlaneFallback: false });
|
|
266
|
+
if (!positionResult || !positionResult.isModel) {
|
|
267
|
+
_this.clearTempMeasure();
|
|
268
|
+
Message.warning('请点击模型进行测量');
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
185
271
|
if (positionResult) {
|
|
186
|
-
const { point
|
|
187
|
-
if (
|
|
188
|
-
|
|
189
|
-
|
|
272
|
+
const { point } = positionResult;
|
|
273
|
+
if (_this.hasTempPoint && _this.pointArray.length > 0) {
|
|
274
|
+
_this.pointArray.splice(_this.pointArray.length - 1, 1, point);
|
|
275
|
+
} else {
|
|
276
|
+
_this.pointArray.push(point);
|
|
190
277
|
}
|
|
278
|
+
_this.hasTempPoint = false;
|
|
191
279
|
if (_this.tipsLabel) {
|
|
192
280
|
_this.tipsLabel.position.set(point.x + 0.01, point.y, point.z + 0.05);
|
|
193
281
|
} else {
|
|
@@ -202,8 +290,20 @@ MeasureArea.prototype = {
|
|
|
202
290
|
_this.points.push(geom);
|
|
203
291
|
_this.scene.add(geom);
|
|
204
292
|
}
|
|
293
|
+
const length = _this.pointArray.length;
|
|
294
|
+
if (length > 1) {
|
|
295
|
+
const p1 = _this.pointArray[length - 2];
|
|
296
|
+
const p2 = _this.pointArray[length - 1];
|
|
297
|
+
if (_this.tempLine) {
|
|
298
|
+
_this.tempLine.geometry.setFromPoints([p1, p2]);
|
|
299
|
+
} else {
|
|
300
|
+
_this.tempLine = _this.createLine(p1, p2);
|
|
301
|
+
_this.polyline.push(_this.tempLine);
|
|
302
|
+
_this.scene.add(_this.tempLine);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
205
305
|
_this.tempLine = undefined;
|
|
206
|
-
_this.
|
|
306
|
+
_this.updateAreaMeasure();
|
|
207
307
|
}
|
|
208
308
|
}, 0);
|
|
209
309
|
}
|
|
@@ -217,16 +317,13 @@ MeasureArea.prototype = {
|
|
|
217
317
|
clearTimeout(_this.timer);
|
|
218
318
|
const positionResult = _this.getPosition(e);
|
|
219
319
|
if (positionResult) {
|
|
220
|
-
|
|
320
|
+
_this.clearTempMeasure();
|
|
221
321
|
_this.isCompleted = true;
|
|
222
|
-
if (_this.tempPoints) {
|
|
223
|
-
_this.tempPoints.position.set(point.x, point.y, point.z);
|
|
224
|
-
_this.tempPoints = undefined;
|
|
225
|
-
}
|
|
226
322
|
_this.tempLine = undefined;
|
|
227
323
|
_this.tempLabel = undefined;
|
|
228
324
|
_this.polygonMesh = undefined;
|
|
229
325
|
_this.pointArray.splice(0);
|
|
326
|
+
_this.hasTempPoint = false;
|
|
230
327
|
_this.renderer.domElement.removeEventListener('mousemove', _this.mousemove);
|
|
231
328
|
}
|
|
232
329
|
},
|
|
@@ -247,6 +344,7 @@ MeasureArea.prototype = {
|
|
|
247
344
|
this.tempPoints = undefined;
|
|
248
345
|
this.tempLabel = undefined;
|
|
249
346
|
this.tempLine = undefined;
|
|
347
|
+
this.hasTempPoint = false;
|
|
250
348
|
this.scene.remove(this.tipsLabel);
|
|
251
349
|
this.tipsLabel = undefined;
|
|
252
350
|
}
|
|
@@ -265,6 +363,7 @@ MeasureArea.prototype = {
|
|
|
265
363
|
this.tempPoints = undefined;
|
|
266
364
|
this.tempLabel = undefined;
|
|
267
365
|
this.tempLine = undefined;
|
|
366
|
+
this.hasTempPoint = false;
|
|
268
367
|
this.scene.remove(this.tipsLabel);
|
|
269
368
|
this.tipsLabel = undefined;
|
|
270
369
|
},
|
|
@@ -326,8 +425,7 @@ MeasureArea.prototype = {
|
|
|
326
425
|
});
|
|
327
426
|
const mesh = new THREE.Mesh(geom, material);
|
|
328
427
|
mesh.frustumCulled = false;
|
|
329
|
-
|
|
330
|
-
mesh.name = _this.measureName;
|
|
428
|
+
_this.markMeasureObject(mesh);
|
|
331
429
|
_this.polygonMesh = mesh;
|
|
332
430
|
_this.scene.add(mesh);
|
|
333
431
|
_this.polygons.push(mesh);
|
|
@@ -2,10 +2,11 @@ import * as THREE from 'three';
|
|
|
2
2
|
import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer';
|
|
3
3
|
import { Message } from 'element-ui';
|
|
4
4
|
var _this = null;
|
|
5
|
-
var MeasureDistance = function (renderer, scene, camera, width, height) {
|
|
5
|
+
var MeasureDistance = function (renderer, scene, camera, width, height, options = {}) {
|
|
6
6
|
this.renderer = renderer;
|
|
7
7
|
this.scene = scene;
|
|
8
8
|
this.camera = camera;
|
|
9
|
+
this.pickRoots = options.pickRoots || null;
|
|
9
10
|
this.pointArray = []; // 保存当前操作所添加的点
|
|
10
11
|
this.raycaster = new THREE.Raycaster();
|
|
11
12
|
this.points = []; // 保存页面中所添加的点
|
|
@@ -16,11 +17,12 @@ var MeasureDistance = function (renderer, scene, camera, width, height) {
|
|
|
16
17
|
this.tempLabel = undefined;
|
|
17
18
|
this.tipsLabel = undefined;
|
|
18
19
|
this.isCompleted = false;
|
|
20
|
+
this.hasTempPoint = false;
|
|
19
21
|
this.timer = null;
|
|
20
22
|
this.width = width;
|
|
21
23
|
this.height = height;
|
|
22
24
|
this.firstTime = 0;
|
|
23
|
-
this.measureName = 'measureObj'
|
|
25
|
+
this.measureName = 'measureObj';
|
|
24
26
|
// 创建一个辅助平面来捕获鼠标事件
|
|
25
27
|
this.plane = new THREE.Plane(new THREE.Vector3(0, 0, 1), 0);
|
|
26
28
|
};
|
|
@@ -41,7 +43,78 @@ MeasureDistance.prototype = {
|
|
|
41
43
|
this.width = width;
|
|
42
44
|
this.height = height;
|
|
43
45
|
},
|
|
44
|
-
|
|
46
|
+
getPickRoots() {
|
|
47
|
+
const roots = typeof _this.pickRoots === 'function' ? _this.pickRoots() : _this.pickRoots;
|
|
48
|
+
if (Array.isArray(roots) && roots.length > 0) {
|
|
49
|
+
return roots.filter(Boolean);
|
|
50
|
+
}
|
|
51
|
+
if (roots) {
|
|
52
|
+
return [roots];
|
|
53
|
+
}
|
|
54
|
+
return _this.scene && _this.scene.children ? _this.scene.children : [];
|
|
55
|
+
},
|
|
56
|
+
isExcludedIntersection(object) {
|
|
57
|
+
let current = object;
|
|
58
|
+
while (current) {
|
|
59
|
+
const userData = current.userData || {};
|
|
60
|
+
if (current.visible === false) return true;
|
|
61
|
+
if (current.name === _this.measureName || userData.isMeasureObject === true) return true;
|
|
62
|
+
if (userData.transformControlHelper === true || userData.outlineProxy === true) return true;
|
|
63
|
+
if (current.isCamera || current.isLight) return true;
|
|
64
|
+
if (
|
|
65
|
+
typeof current.type === 'string' &&
|
|
66
|
+
(/Helper$/i.test(current.type) ||
|
|
67
|
+
current.type === 'CSS2DObject' ||
|
|
68
|
+
current.type === 'TransformControlsRoot')
|
|
69
|
+
) {
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
current = current.parent;
|
|
73
|
+
}
|
|
74
|
+
return false;
|
|
75
|
+
},
|
|
76
|
+
markMeasureObject(object) {
|
|
77
|
+
object.name = this.measureName;
|
|
78
|
+
if (!object.userData) {
|
|
79
|
+
object.userData = {};
|
|
80
|
+
}
|
|
81
|
+
object.userData.isMeasureObject = true;
|
|
82
|
+
return object;
|
|
83
|
+
},
|
|
84
|
+
disposeObject(object) {
|
|
85
|
+
if (!object) return;
|
|
86
|
+
if (object.geometry) {
|
|
87
|
+
object.geometry.dispose();
|
|
88
|
+
}
|
|
89
|
+
if (object.material) {
|
|
90
|
+
object.material.dispose();
|
|
91
|
+
}
|
|
92
|
+
this.scene.remove(object);
|
|
93
|
+
},
|
|
94
|
+
removeArrayItem(array, item) {
|
|
95
|
+
if (!item) return;
|
|
96
|
+
const index = array.indexOf(item);
|
|
97
|
+
if (index !== -1) {
|
|
98
|
+
array.splice(index, 1);
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
clearTempMeasure() {
|
|
102
|
+
// 清理未确认的预览点,避免空点位残留在回退平面上。
|
|
103
|
+
if (this.hasTempPoint && this.pointArray.length > 0) {
|
|
104
|
+
this.pointArray.pop();
|
|
105
|
+
}
|
|
106
|
+
this.removeArrayItem(this.points, this.tempPoints);
|
|
107
|
+
this.removeArrayItem(this.polyline, this.tempLine);
|
|
108
|
+
this.removeArrayItem(this.labels, this.tempLabel);
|
|
109
|
+
this.disposeObject(this.tempPoints);
|
|
110
|
+
this.disposeObject(this.tempLine);
|
|
111
|
+
this.disposeObject(this.tempLabel);
|
|
112
|
+
this.tempPoints = undefined;
|
|
113
|
+
this.tempLine = undefined;
|
|
114
|
+
this.tempLabel = undefined;
|
|
115
|
+
this.hasTempPoint = false;
|
|
116
|
+
},
|
|
117
|
+
getPosition(e, options = {}) {
|
|
45
118
|
const mouse = new THREE.Vector2();
|
|
46
119
|
const elRect = this.renderer.domElement.getBoundingClientRect();
|
|
47
120
|
const canvasX = e.clientX - elRect.left;
|
|
@@ -51,11 +124,17 @@ MeasureDistance.prototype = {
|
|
|
51
124
|
mouse.y = -(canvasY / elRect.height) * 2.0 + 1.0;
|
|
52
125
|
|
|
53
126
|
_this.raycaster.setFromCamera(mouse, this.camera);
|
|
54
|
-
let intersects = _this.raycaster
|
|
127
|
+
let intersects = _this.raycaster
|
|
128
|
+
.intersectObjects(_this.getPickRoots(), true)
|
|
129
|
+
.filter(item => item && item.object && !_this.isExcludedIntersection(item.object));
|
|
55
130
|
if (intersects.length > 0) {
|
|
56
131
|
return { point: intersects[0].point, isModel: true };
|
|
57
132
|
}
|
|
58
133
|
|
|
134
|
+
if (options.allowPlaneFallback === false) {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
|
|
59
138
|
// 如果没有交点,构建一个基于最后一个确认点且面向相机的平面
|
|
60
139
|
if (_this.pointArray && _this.pointArray.length > 0) {
|
|
61
140
|
const lastPoint =
|
|
@@ -91,7 +170,7 @@ MeasureDistance.prototype = {
|
|
|
91
170
|
});
|
|
92
171
|
const lineGeometry = new THREE.BufferGeometry().setFromPoints([p1, p2]);
|
|
93
172
|
const line = new THREE.Line(lineGeometry, lineMaterial);
|
|
94
|
-
|
|
173
|
+
this.markMeasureObject(line);
|
|
95
174
|
line.renderOrder = 999;
|
|
96
175
|
line.frustumCulled = false;
|
|
97
176
|
return line;
|
|
@@ -101,7 +180,7 @@ MeasureDistance.prototype = {
|
|
|
101
180
|
div.className = name;
|
|
102
181
|
div.textContent = text;
|
|
103
182
|
const divLabel = new CSS2DObject(div);
|
|
104
|
-
|
|
183
|
+
this.markMeasureObject(divLabel);
|
|
105
184
|
divLabel.position.set(position.x, position.y, position.z);
|
|
106
185
|
return divLabel;
|
|
107
186
|
},
|
|
@@ -110,9 +189,12 @@ MeasureDistance.prototype = {
|
|
|
110
189
|
const positionResult = _this.getPosition(e);
|
|
111
190
|
if (positionResult) {
|
|
112
191
|
const point = positionResult.point;
|
|
113
|
-
_this.
|
|
114
|
-
|
|
115
|
-
|
|
192
|
+
if (_this.hasTempPoint) {
|
|
193
|
+
_this.pointArray.splice(_this.pointArray.length - 1, 1, point);
|
|
194
|
+
} else {
|
|
195
|
+
_this.pointArray.push(point);
|
|
196
|
+
_this.hasTempPoint = true;
|
|
197
|
+
}
|
|
116
198
|
const length = _this.pointArray.length;
|
|
117
199
|
if (_this.tempPoints) {
|
|
118
200
|
_this.tempPoints.position.set(point.x, point.y, point.z);
|
|
@@ -149,7 +231,7 @@ MeasureDistance.prototype = {
|
|
|
149
231
|
div.className = 'tips-label';
|
|
150
232
|
div.textContent = label;
|
|
151
233
|
const tipsLabel = new CSS2DObject(div);
|
|
152
|
-
|
|
234
|
+
this.markMeasureObject(tipsLabel);
|
|
153
235
|
tipsLabel.position.set(position.x + 0.1, position.y, position.z + 0.05);
|
|
154
236
|
return tipsLabel;
|
|
155
237
|
},
|
|
@@ -157,7 +239,6 @@ MeasureDistance.prototype = {
|
|
|
157
239
|
this.firstTime = new Date().getTime();
|
|
158
240
|
},
|
|
159
241
|
click(e) {
|
|
160
|
-
console.log(_this.points)
|
|
161
242
|
let lastTime = new Date().getTime();
|
|
162
243
|
if (lastTime - this.firstTime < 300) {
|
|
163
244
|
if (_this.isCompleted) {
|
|
@@ -166,14 +247,20 @@ MeasureDistance.prototype = {
|
|
|
166
247
|
clearTimeout(_this.timer);
|
|
167
248
|
_this.timer = setTimeout(() => {
|
|
168
249
|
_this.isCompleted = false;
|
|
169
|
-
const positionResult = _this.getPosition(e);
|
|
250
|
+
const positionResult = _this.getPosition(e, { allowPlaneFallback: false });
|
|
251
|
+
if (!positionResult || !positionResult.isModel) {
|
|
252
|
+
_this.clearTempMeasure();
|
|
253
|
+
Message.warning('请点击模型进行测量');
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
170
256
|
if (positionResult) {
|
|
171
|
-
const { point
|
|
172
|
-
if (
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
257
|
+
const { point } = positionResult;
|
|
258
|
+
if (_this.hasTempPoint && _this.pointArray.length > 0) {
|
|
259
|
+
_this.pointArray.splice(_this.pointArray.length - 1, 1, point);
|
|
260
|
+
} else {
|
|
261
|
+
_this.pointArray.push(point);
|
|
176
262
|
}
|
|
263
|
+
_this.hasTempPoint = false;
|
|
177
264
|
if (_this.tipsLabel) {
|
|
178
265
|
_this.tipsLabel.position.set(point.x + 0.1, point.y, point.z + 0.05);
|
|
179
266
|
} else {
|
|
@@ -188,9 +275,35 @@ MeasureDistance.prototype = {
|
|
|
188
275
|
_this.points.push(geom);
|
|
189
276
|
_this.scene.add(geom);
|
|
190
277
|
}
|
|
278
|
+
const length = _this.pointArray.length;
|
|
279
|
+
if (length > 1) {
|
|
280
|
+
const p1 = _this.pointArray[length - 2];
|
|
281
|
+
const p2 = _this.pointArray[length - 1];
|
|
282
|
+
const dist = p1.distanceTo(p2);
|
|
283
|
+
const label = `${_this.numberToString(dist)}`;
|
|
284
|
+
const position = new THREE.Vector3(
|
|
285
|
+
(p1.x + p2.x) / 2,
|
|
286
|
+
(p1.y + p2.y) / 2,
|
|
287
|
+
(p1.z + p2.z) / 2
|
|
288
|
+
);
|
|
289
|
+
if (_this.tempLine) {
|
|
290
|
+
_this.tempLine.geometry.setFromPoints([p1, p2]);
|
|
291
|
+
} else {
|
|
292
|
+
_this.tempLine = _this.createLine(p1, p2);
|
|
293
|
+
_this.polyline.push(_this.tempLine);
|
|
294
|
+
_this.scene.add(_this.tempLine);
|
|
295
|
+
}
|
|
296
|
+
if (_this.tempLabel) {
|
|
297
|
+
_this.tempLabel.element.textContent = label;
|
|
298
|
+
_this.tempLabel.position.set(position.x, position.y, position.z);
|
|
299
|
+
} else {
|
|
300
|
+
_this.tempLabel = _this.createLabel('measure-label', label, position);
|
|
301
|
+
_this.labels.push(_this.tempLabel);
|
|
302
|
+
_this.scene.add(_this.tempLabel);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
191
305
|
_this.tempLine = undefined;
|
|
192
306
|
_this.tempLabel = undefined;
|
|
193
|
-
_this.pointArray.push(point);
|
|
194
307
|
}
|
|
195
308
|
});
|
|
196
309
|
}
|
|
@@ -204,11 +317,13 @@ MeasureDistance.prototype = {
|
|
|
204
317
|
clearTimeout(_this.timer);
|
|
205
318
|
const positionResult = _this.getPosition(e);
|
|
206
319
|
if (positionResult) {
|
|
320
|
+
_this.clearTempMeasure();
|
|
207
321
|
_this.isCompleted = true;
|
|
208
322
|
_this.tempPoints = undefined;
|
|
209
323
|
_this.tempLine = undefined;
|
|
210
324
|
_this.tempLabel = undefined;
|
|
211
325
|
_this.pointArray.splice(0);
|
|
326
|
+
_this.hasTempPoint = false;
|
|
212
327
|
_this.renderer.domElement.removeEventListener('mousemove', _this.mousemove);
|
|
213
328
|
}
|
|
214
329
|
},
|
|
@@ -228,6 +343,7 @@ MeasureDistance.prototype = {
|
|
|
228
343
|
this.tempPoints = undefined;
|
|
229
344
|
this.tempLabel = undefined;
|
|
230
345
|
this.tempLine = undefined;
|
|
346
|
+
this.hasTempPoint = false;
|
|
231
347
|
this.scene.remove(this.tipsLabel);
|
|
232
348
|
this.tipsLabel = undefined;
|
|
233
349
|
this.firstTime = 0;
|
|
@@ -245,6 +361,7 @@ MeasureDistance.prototype = {
|
|
|
245
361
|
this.tempPoints = undefined;
|
|
246
362
|
this.tempLabel = undefined;
|
|
247
363
|
this.tempLine = undefined;
|
|
364
|
+
this.hasTempPoint = false;
|
|
248
365
|
this.scene.remove(this.tipsLabel);
|
|
249
366
|
this.tipsLabel = undefined;
|
|
250
367
|
this.firstTime = 0;
|