diff --git a/src/designer/model2DEditor/tools/MeasureTool.ts b/src/designer/model2DEditor/tools/MeasureTool.ts index f71e8d9..b78c56c 100644 --- a/src/designer/model2DEditor/tools/MeasureTool.ts +++ b/src/designer/model2DEditor/tools/MeasureTool.ts @@ -7,9 +7,14 @@ import type { ICursorTool } from '@/designer/model2DEditor/tools/CursorTool.ts' import type Measure from '@/model/itemType/measure/Measure.ts' import { getItemTypeByName } from '@/runtime/DefineItemType.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 +const TEMP_POINT_NAME = '_measure_temp_point' +const TMP_LABEL_NAME = '_measure_temp_label' +const TMP_TYPE = '_TMP' + /** * 用于在 threejs 中创建一系列的 object_for_measure 点,并标记他的距离 */ @@ -62,35 +67,22 @@ export default class MeasureTool implements ICursorTool { tempLabel?: CSS2DObject /** - * 存储当前测量的点数组, 用于记录所有测量点 - */ - pointArray: THREE.Vector3[] = [] - - /** * 保存上次点击时间,以便检测双击事件 * @protected */ lastClickTime: number = 0 /** - * 测量线材质 + * 测量起始点 */ - static LINE_MATERIAL = new THREE.LineBasicMaterial({ - color: 0xE63C17, - linewidth: 2, - opacity: 0.9, - transparent: true, - side: THREE.DoubleSide, - depthWrite: false, - depthTest: false - }) + startPoint?: THREE.Object3D = undefined - mode: CursorMode + /** + * 上次鼠标移动位置 + */ + lastMovePosition: THREE.Vector3 | undefined = undefined - private draggingIndex: number = -1 - private connectedLines: THREE.Line[] = [] - private connectedLabels: CSS2DObject[] = [] - private originalPosition: THREE.Vector3 = new THREE.Vector3() + mode: CursorMode /** * 测量工具初始化 @@ -105,7 +97,7 @@ export default class MeasureTool implements ICursorTool { /** * 测量工具开始, 监听鼠标事件, 变量初始化等 */ - start() { + start(startPoint?: THREE.Object3D) { pdFn = this.mousedown.bind(this) this.canvas.addEventListener('pointerdown', pdFn) pmFn = this.mousemove.bind(this) @@ -115,9 +107,9 @@ export default class MeasureTool implements ICursorTool { this.isCompleted = false this.viewport.viewerDom.style.cursor = 'crosshair' - this.pointArray = [] this.mode = this.viewport.state.cursorMode + this.startPoint = startPoint system.msg('进入测量模式') } @@ -176,36 +168,32 @@ export default class MeasureTool implements ICursorTool { return } + this.lastMovePosition = point + // 在鼠标移动时绘制临时点 if (this.tempPointMarker) { this.tempPointMarker.position.set(point.x, point.y, point.z) } else { - this.tempPointMarker = this.createPointMarker(point) + this.tempPointMarker = this.createTempPointMarker(point) 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) { - this.tempLine = this.createLine() + this.tempLine = this.measure.createLineBasic() this.viewport.scene.add(this.tempLine) } + const p0 = this.startPoint.position const line = this.tempLine const geom = line.geometry - const startPoint = this.pointArray[0] - const lastPoint = this.pointArray[this.pointArray.length - 1] - if (this.mode === Constract.CursorModeMeasureArea) { - geom.setFromPoints([lastPoint, point, startPoint]) - } else { - geom.setFromPoints([lastPoint, point]) - } + geom.setFromPoints([p0, point]) const dist = p0.distanceTo(point) 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) } @@ -237,7 +225,7 @@ export default class MeasureTool implements ICursorTool { } // 获取鼠标点击位置的三维坐标 - const point = this.viewport.getClosestIntersection(e) + const point = this.lastMovePosition if (!point) { return } @@ -250,54 +238,48 @@ export default class MeasureTool implements ICursorTool { this.lastClickTime = now // 添加正式点 - this.pointArray.push(point) - - const count = this.pointArray.length - const marker = this.createPointMarker(point) - marker.userData.point = point - marker.userData.pointIndex = count - 1 + const itemJson = { + t: this.measure.name, + a: 'ln', + tf: [ + [point.x, point.y, point.z], + [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.viewport.dragControl.setDragObjects([marker], 'push') - if (this.tempLabel && count > 1) { - // 临时 点/label/line 将作为正式的使用 - const p0 = this.pointArray[count - 2] + if (this.startPoint) { + // 如果起始点存在,则将新点添加到起始点的链接中 + 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.measure.group.add(this.tempLabel) - this.tempLabel = undefined + // 更新起始点为新添加的点 + this.startPoint = marker - // 临时线 - this.tempLine.geometry.setFromPoints([p0, point]) - this.tempLine.userData.pointIndices = [count - 2, count - 1] - this.measure.group.add(this.tempLine) - this.tempLine = undefined - } + // 删除临时线 + this.tempPointMarker && this.viewport.scene.remove(this.tempPointMarker) + this.tempPointMarker = undefined - // this.viewport.dispatchSignal('sceneGraphChanged') - } + this.tempLabel && this.viewport.scene.remove(this.tempLabel) + this.tempLabel = 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 + this.tempLine && this.viewport.scene.remove(this.tempLabel) + this.tempLine = undefined } /** * 创建点标记 */ - createPointMarker(position?: THREE.Vector3): THREE.Mesh { + createTempPointMarker(position?: THREE.Vector3): THREE.Mesh { const p = position const scale = 0.25 @@ -309,11 +291,10 @@ export default class MeasureTool implements ICursorTool { obj.position.set(p.x, p.y, p.z) } - obj.name = MeasureTool.OBJ_NAME - + obj.name = TEMP_POINT_NAME obj.userData = { mode: this.mode, - type: Constract.MeasureMarker + type: TMP_TYPE } return obj } @@ -325,6 +306,11 @@ export default class MeasureTool implements ICursorTool { addOrUpdateTempLabel(label: string, position: THREE.Vector3) { if (!this.tempLabel) { 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.tempLabel.position.set(position.x, position.y, position.z) diff --git a/src/model/itemType/ItemTypeDefine.ts b/src/model/itemType/ItemTypeDefine.ts index 399d7bf..44d9d7b 100644 --- a/src/model/itemType/ItemTypeDefine.ts +++ b/src/model/itemType/ItemTypeDefine.ts @@ -56,7 +56,7 @@ export interface ItemJson { /** * 对应 three.js 中的 uuid, 物体ID, 唯一标识, 需保证唯一 */ - id: string + id?: string /** * 物体类型, 对应 defineItemType.name @@ -76,7 +76,7 @@ export interface ItemJson { /** * 颜色, 最后初始化到 three.js 的 userData.color 中 */ - c: string + c?: string /** * 变换矩阵, 3x3矩阵, 采用Y轴向上为正, X轴向右, Z轴向前的右手坐标系 diff --git a/src/model/itemType/ItemTypeLineBase.ts b/src/model/itemType/ItemTypeLineBase.ts index 7973471..9b7e194 100644 --- a/src/model/itemType/ItemTypeLineBase.ts +++ b/src/model/itemType/ItemTypeLineBase.ts @@ -16,6 +16,10 @@ export default abstract class ItemTypeLineBase extends ItemTypeBase { private dragViewport: Viewport | undefined private dragPoint: THREE.Mesh | undefined + defaultScale: THREE.Vector3 = new THREE.Vector3(0.25, 0.1, 0.25) + defaultRotation: THREE.Vector3 = new THREE.Vector3(0, 0, 0) + defaultY = 0.1 + abstract createPointBasic(position: THREE.Vector3): THREE.Object3D abstract createLineBasic(): THREE.Line diff --git a/src/model/itemType/measure/Measure.ts b/src/model/itemType/measure/Measure.ts index a8fcb7e..1c97e5e 100644 --- a/src/model/itemType/measure/Measure.ts +++ b/src/model/itemType/measure/Measure.ts @@ -104,7 +104,7 @@ export default class Measure extends ItemTypeLineBase { const position = new THREE.Vector3().addVectors(p0, p1).multiplyScalar(0.5) const labelObj = this.createLabel(label) - labelObj.position.set(position.x, 0.1, position.z) + labelObj.position.set(position.x, position.y, position.z) labelObj.element.innerHTML = label line.userData.labelId = labelObj.uuid @@ -123,7 +123,7 @@ export default class Measure extends ItemTypeLineBase { const labelObj: CSS2DObject = findObject3DById(this.group, line.userData.labelId) as CSS2DObject if (labelObj) { - labelObj.position.set(position.x, 0.1, position.z) + labelObj.position.set(position.x, position.y, position.z) labelObj.element.innerHTML = label } else {