|
|
@ -7,9 +7,14 @@ import type { ICursorTool } from '@/designer/model2DEditor/tools/CursorTool.ts' |
|
|
import type Measure from '@/model/itemType/measure/Measure.ts' |
|
|
import type Measure from '@/model/itemType/measure/Measure.ts' |
|
|
import { getItemTypeByName } from '@/runtime/DefineItemType.ts' |
|
|
import { getItemTypeByName } from '@/runtime/DefineItemType.ts' |
|
|
import { LABEL_NAME, LINE_NAME } from '@/model/itemType/measure/Measure.ts' |
|
|
import { LABEL_NAME, LINE_NAME } from '@/model/itemType/measure/Measure.ts' |
|
|
|
|
|
import type { ItemJson } from '@/model/itemType/ItemTypeDefine.ts' |
|
|
|
|
|
|
|
|
let pdFn, pmFn, puFn, kdFn |
|
|
let pdFn, pmFn, puFn, kdFn |
|
|
|
|
|
|
|
|
|
|
|
const TEMP_POINT_NAME = '_measure_temp_point' |
|
|
|
|
|
const TMP_LABEL_NAME = '_measure_temp_label' |
|
|
|
|
|
const TMP_TYPE = '_TMP' |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* 用于在 threejs 中创建一系列的 object_for_measure 点,并标记他的距离 |
|
|
* 用于在 threejs 中创建一系列的 object_for_measure 点,并标记他的距离 |
|
|
*/ |
|
|
*/ |
|
|
@ -62,35 +67,22 @@ export default class MeasureTool implements ICursorTool { |
|
|
tempLabel?: CSS2DObject |
|
|
tempLabel?: CSS2DObject |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* 存储当前测量的点数组, 用于记录所有测量点 |
|
|
|
|
|
*/ |
|
|
|
|
|
pointArray: THREE.Vector3[] = [] |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 保存上次点击时间,以便检测双击事件 |
|
|
* 保存上次点击时间,以便检测双击事件 |
|
|
* @protected |
|
|
* @protected |
|
|
*/ |
|
|
*/ |
|
|
lastClickTime: number = 0 |
|
|
lastClickTime: number = 0 |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* 测量线材质 |
|
|
* 测量起始点 |
|
|
*/ |
|
|
*/ |
|
|
static LINE_MATERIAL = new THREE.LineBasicMaterial({ |
|
|
startPoint?: THREE.Object3D = undefined |
|
|
color: 0xE63C17, |
|
|
|
|
|
linewidth: 2, |
|
|
|
|
|
opacity: 0.9, |
|
|
|
|
|
transparent: true, |
|
|
|
|
|
side: THREE.DoubleSide, |
|
|
|
|
|
depthWrite: false, |
|
|
|
|
|
depthTest: false |
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
mode: CursorMode |
|
|
/** |
|
|
|
|
|
* 上次鼠标移动位置 |
|
|
|
|
|
*/ |
|
|
|
|
|
lastMovePosition: THREE.Vector3 | undefined = undefined |
|
|
|
|
|
|
|
|
private draggingIndex: number = -1 |
|
|
mode: CursorMode |
|
|
private connectedLines: THREE.Line[] = [] |
|
|
|
|
|
private connectedLabels: CSS2DObject[] = [] |
|
|
|
|
|
private originalPosition: THREE.Vector3 = new THREE.Vector3() |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* 测量工具初始化 |
|
|
* 测量工具初始化 |
|
|
@ -105,7 +97,7 @@ export default class MeasureTool implements ICursorTool { |
|
|
/** |
|
|
/** |
|
|
* 测量工具开始, 监听鼠标事件, 变量初始化等 |
|
|
* 测量工具开始, 监听鼠标事件, 变量初始化等 |
|
|
*/ |
|
|
*/ |
|
|
start() { |
|
|
start(startPoint?: THREE.Object3D) { |
|
|
pdFn = this.mousedown.bind(this) |
|
|
pdFn = this.mousedown.bind(this) |
|
|
this.canvas.addEventListener('pointerdown', pdFn) |
|
|
this.canvas.addEventListener('pointerdown', pdFn) |
|
|
pmFn = this.mousemove.bind(this) |
|
|
pmFn = this.mousemove.bind(this) |
|
|
@ -115,9 +107,9 @@ export default class MeasureTool implements ICursorTool { |
|
|
|
|
|
|
|
|
this.isCompleted = false |
|
|
this.isCompleted = false |
|
|
this.viewport.viewerDom.style.cursor = 'crosshair' |
|
|
this.viewport.viewerDom.style.cursor = 'crosshair' |
|
|
this.pointArray = [] |
|
|
|
|
|
|
|
|
|
|
|
this.mode = this.viewport.state.cursorMode |
|
|
this.mode = this.viewport.state.cursorMode |
|
|
|
|
|
this.startPoint = startPoint |
|
|
|
|
|
|
|
|
system.msg('进入测量模式') |
|
|
system.msg('进入测量模式') |
|
|
} |
|
|
} |
|
|
@ -176,36 +168,32 @@ export default class MeasureTool implements ICursorTool { |
|
|
return |
|
|
return |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
this.lastMovePosition = point |
|
|
|
|
|
|
|
|
// 在鼠标移动时绘制临时点
|
|
|
// 在鼠标移动时绘制临时点
|
|
|
if (this.tempPointMarker) { |
|
|
if (this.tempPointMarker) { |
|
|
this.tempPointMarker.position.set(point.x, point.y, point.z) |
|
|
this.tempPointMarker.position.set(point.x, point.y, point.z) |
|
|
} else { |
|
|
} else { |
|
|
this.tempPointMarker = this.createPointMarker(point) |
|
|
this.tempPointMarker = this.createTempPointMarker(point) |
|
|
this.viewport.scene.add(this.tempPointMarker) |
|
|
this.viewport.scene.add(this.tempPointMarker) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 移动时绘制临时线
|
|
|
// 移动时绘制临时线
|
|
|
if (this.pointArray.length > 0) { |
|
|
if (this.startPoint) { |
|
|
// 获取最后一个点
|
|
|
// 获取最后一个点
|
|
|
const p0 = this.pointArray[this.pointArray.length - 1] |
|
|
|
|
|
if (!this.tempLine) { |
|
|
if (!this.tempLine) { |
|
|
this.tempLine = this.createLine() |
|
|
this.tempLine = this.measure.createLineBasic() |
|
|
this.viewport.scene.add(this.tempLine) |
|
|
this.viewport.scene.add(this.tempLine) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const p0 = this.startPoint.position |
|
|
const line = this.tempLine |
|
|
const line = this.tempLine |
|
|
const geom = line.geometry |
|
|
const geom = line.geometry |
|
|
const startPoint = this.pointArray[0] |
|
|
geom.setFromPoints([p0, point]) |
|
|
const lastPoint = this.pointArray[this.pointArray.length - 1] |
|
|
|
|
|
if (this.mode === Constract.CursorModeMeasureArea) { |
|
|
|
|
|
geom.setFromPoints([lastPoint, point, startPoint]) |
|
|
|
|
|
} else { |
|
|
|
|
|
geom.setFromPoints([lastPoint, point]) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const dist = p0.distanceTo(point) |
|
|
const dist = p0.distanceTo(point) |
|
|
const label = `${numberToString(dist)} ${getUnitString(this.mode)}` |
|
|
const label = `${numberToString(dist)} ${getUnitString(this.mode)}` |
|
|
const position = new THREE.Vector3((point.x + p0.x) / 2, (point.y + p0.y) / 2, (point.z + p0.z) / 2) |
|
|
const position = new THREE.Vector3().addVectors(p0, point).multiplyScalar(0.5) |
|
|
this.addOrUpdateTempLabel(label, position) |
|
|
this.addOrUpdateTempLabel(label, position) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -237,7 +225,7 @@ export default class MeasureTool implements ICursorTool { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 获取鼠标点击位置的三维坐标
|
|
|
// 获取鼠标点击位置的三维坐标
|
|
|
const point = this.viewport.getClosestIntersection(e) |
|
|
const point = this.lastMovePosition |
|
|
if (!point) { |
|
|
if (!point) { |
|
|
return |
|
|
return |
|
|
} |
|
|
} |
|
|
@ -250,54 +238,48 @@ export default class MeasureTool implements ICursorTool { |
|
|
this.lastClickTime = now |
|
|
this.lastClickTime = now |
|
|
|
|
|
|
|
|
// 添加正式点
|
|
|
// 添加正式点
|
|
|
this.pointArray.push(point) |
|
|
const itemJson = { |
|
|
|
|
|
t: this.measure.name, |
|
|
const count = this.pointArray.length |
|
|
a: 'ln', |
|
|
const marker = this.createPointMarker(point) |
|
|
tf: [ |
|
|
marker.userData.point = point |
|
|
[point.x, point.y, point.z], |
|
|
marker.userData.pointIndex = count - 1 |
|
|
[this.measure.defaultRotation.x, this.measure.defaultRotation.y, this.measure.defaultRotation.z], |
|
|
|
|
|
[this.measure.defaultScale.x, this.measure.defaultScale.y, this.measure.defaultScale.z] |
|
|
|
|
|
], |
|
|
|
|
|
dt: { |
|
|
|
|
|
link: [] as string[] |
|
|
|
|
|
} |
|
|
|
|
|
} as ItemJson |
|
|
|
|
|
const marker = this.measure.createPoint(point, itemJson) |
|
|
this.measure.group.add(marker) |
|
|
this.measure.group.add(marker) |
|
|
|
|
|
|
|
|
// 把点加入拖拽控制器
|
|
|
// 把点加入拖拽控制器
|
|
|
this.viewport.dragControl.setDragObjects([marker], 'push') |
|
|
this.viewport.dragControl.setDragObjects([marker], 'push') |
|
|
|
|
|
|
|
|
if (this.tempLabel && count > 1) { |
|
|
if (this.startPoint) { |
|
|
// 临时 点/label/line 将作为正式的使用
|
|
|
// 如果起始点存在,则将新点添加到起始点的链接中
|
|
|
const p0 = this.pointArray[count - 2] |
|
|
this.startPoint.userData.link.push(marker.uuid) |
|
|
|
|
|
this.measure.createLine(this.viewport.scene, this.startPoint, marker) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
this.tempLabel.position.set((p0.x + point.x) / 2, (p0.y + point.y) / 2, (p0.z + point.z) / 2) |
|
|
// 更新起始点为新添加的点
|
|
|
this.tempLabel.userData.pointIndices = [count - 2, count - 1] |
|
|
this.startPoint = marker |
|
|
this.measure.group.add(this.tempLabel) |
|
|
|
|
|
this.tempLabel = undefined |
|
|
|
|
|
|
|
|
|
|
|
// 临时线
|
|
|
// 删除临时线
|
|
|
this.tempLine.geometry.setFromPoints([p0, point]) |
|
|
this.tempPointMarker && this.viewport.scene.remove(this.tempPointMarker) |
|
|
this.tempLine.userData.pointIndices = [count - 2, count - 1] |
|
|
this.tempPointMarker = undefined |
|
|
this.measure.group.add(this.tempLine) |
|
|
|
|
|
this.tempLine = undefined |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// this.viewport.dispatchSignal('sceneGraphChanged')
|
|
|
this.tempLabel && this.viewport.scene.remove(this.tempLabel) |
|
|
} |
|
|
this.tempLabel = undefined |
|
|
|
|
|
|
|
|
/** |
|
|
this.tempLine && this.viewport.scene.remove(this.tempLabel) |
|
|
* 创建测量线 |
|
|
this.tempLine = undefined |
|
|
*/ |
|
|
|
|
|
private createLine(): THREE.Line { |
|
|
|
|
|
const geom = new THREE.BufferGeometry() |
|
|
|
|
|
const obj = new THREE.Line(geom, MeasureTool.LINE_MATERIAL) |
|
|
|
|
|
obj.frustumCulled = false |
|
|
|
|
|
obj.name = MeasureTool.LINE_NAME |
|
|
|
|
|
obj.userData = { |
|
|
|
|
|
type: Constract.MeasureLine |
|
|
|
|
|
} |
|
|
|
|
|
return obj |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* 创建点标记 |
|
|
* 创建点标记 |
|
|
*/ |
|
|
*/ |
|
|
createPointMarker(position?: THREE.Vector3): THREE.Mesh { |
|
|
createTempPointMarker(position?: THREE.Vector3): THREE.Mesh { |
|
|
const p = position |
|
|
const p = position |
|
|
const scale = 0.25 |
|
|
const scale = 0.25 |
|
|
|
|
|
|
|
|
@ -309,11 +291,10 @@ export default class MeasureTool implements ICursorTool { |
|
|
obj.position.set(p.x, p.y, p.z) |
|
|
obj.position.set(p.x, p.y, p.z) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
obj.name = MeasureTool.OBJ_NAME |
|
|
obj.name = TEMP_POINT_NAME |
|
|
|
|
|
|
|
|
obj.userData = { |
|
|
obj.userData = { |
|
|
mode: this.mode, |
|
|
mode: this.mode, |
|
|
type: Constract.MeasureMarker |
|
|
type: TMP_TYPE |
|
|
} |
|
|
} |
|
|
return obj |
|
|
return obj |
|
|
} |
|
|
} |
|
|
@ -325,6 +306,11 @@ export default class MeasureTool implements ICursorTool { |
|
|
addOrUpdateTempLabel(label: string, position: THREE.Vector3) { |
|
|
addOrUpdateTempLabel(label: string, position: THREE.Vector3) { |
|
|
if (!this.tempLabel) { |
|
|
if (!this.tempLabel) { |
|
|
this.tempLabel = this.measure.createLabel(label) |
|
|
this.tempLabel = this.measure.createLabel(label) |
|
|
|
|
|
this.tempLabel.name = TMP_LABEL_NAME |
|
|
|
|
|
this.tempLabel.userData = { |
|
|
|
|
|
mode: this.mode, |
|
|
|
|
|
type: TMP_TYPE |
|
|
|
|
|
} |
|
|
this.viewport.scene.add(this.tempLabel) |
|
|
this.viewport.scene.add(this.tempLabel) |
|
|
} |
|
|
} |
|
|
this.tempLabel.position.set(position.x, position.y, position.z) |
|
|
this.tempLabel.position.set(position.x, position.y, position.z) |
|
|
|