diff --git a/src/designer/Constract.ts b/src/designer/Constract.ts
index 8a10162..afd4a7e 100644
--- a/src/designer/Constract.ts
+++ b/src/designer/Constract.ts
@@ -13,6 +13,8 @@ export default Object.freeze({
// 测量相关的光标模式
CursorModeMeasure: 'measure',
+ CursorModeConveyor: 'conveyor',
+
// 选择模式
CursorModeSelectByRec: 'selectByRec'
})
\ No newline at end of file
diff --git a/src/designer/Viewport.ts b/src/designer/Viewport.ts
index f58d2bd..8c742b4 100644
--- a/src/designer/Viewport.ts
+++ b/src/designer/Viewport.ts
@@ -33,6 +33,8 @@ export default class Viewport {
dragControl: EsDragControls
animationFrameId: any = null
+ //搭配 state.cursorMode = xxx 之后, currentTool.start(第一个参数) 使用
+ toolStartObject: THREE.Object3D | null = null
currentTool: Toolbox | null = null
tools: ITool[] = [
new MouseMoveInspect()
@@ -223,7 +225,8 @@ export default class Viewport {
}
if (this.currentTool) {
- this.currentTool.start()
+ this.currentTool.start(this.toolStartObject)
+ this.toolStartObject = null
}
}))
diff --git a/src/designer/model2DEditor/Model2DEditor.vue b/src/designer/model2DEditor/Model2DEditor.vue
index c4c5999..44dfac4 100644
--- a/src/designer/model2DEditor/Model2DEditor.vue
+++ b/src/designer/model2DEditor/Model2DEditor.vue
@@ -37,6 +37,10 @@
state.cursorMode = Constract.CursorModeMeasure">
+
+ state.cursorMode = Constract.CursorModeConveyor">
{
// 判断 object 是否是有效的 Object3D, 并且是当前 viewport 的对象
@@ -40,76 +42,78 @@ export function quickCopyByMouse() {
const distance = object.position.distanceTo(new THREE.Vector3(x, 0, z))
if (distance < 0.2) {
// 找到一个有效点,执行复制操作
- toolbox.start(object)
- system.msg('复制成功')
+ viewport.toolStartObject = object
+ viewport.state.cursorMode = object.userData.type
+ // toolbox.start(object)
+ system.msg('连线成功')
return true
}
}
return false
})
- */
-}
-
-/**
- * 查找射线周围指定半径内的对象
- */
-export function findObjectsInRadius(viewport: Viewport,
- point: THREE.Vector2,
- radius: number,
- lines: { object: THREE.Object3D, distance: number }[],
- points: { object: THREE.Object3D, distance: number }[]
-): void {
- const ray = new THREE.Raycaster()
- ray.setFromCamera(point, viewport.camera)
-
- viewport.dragControl._dragObjects.forEach(obj => {
- if (obj instanceof THREE.Points) {
- // 处理点云:遍历每个点
- const distance = distanceToRay(ray, point)
- if (distance <= radius) {
- points.push({ object: obj, distance })
- }
-
- } else if (obj instanceof THREE.Line) {
- // 处理线段:计算线段到射线的最近距离
- const distance = getLineDistanceToRay(ray, obj)
- if (distance <= radius) {
- lines.push({ object: obj, distance })
- }
- }
- })
-}
-
-/**
- * 计算点到射线的最短距离
- */
-function distanceToRay(ray: THREE.Raycaster, point: THREE.Vector2) {
- const closestPoint = new THREE.Vector3()
- ray.closestPointToPoint(point, closestPoint)
- return point.distanceTo(closestPoint)
}
-/**
- * 计算线段到射线的最短距离
- */
-function getLineDistanceToRay(ray: THREE.Raycaster, line: THREE.Line) {
- const lineStart = new THREE.Vector3()
- const lineEnd = new THREE.Vector3()
- line.geometry.attributes.position.getXYZ(0, lineStart)
- line.geometry.attributes.position.getXYZ(1, lineEnd)
- line.localToWorld(lineStart)
- line.localToWorld(lineEnd)
-
- const lineSegment = new THREE.Line3(lineStart, lineEnd)
- const closestOnRay = new THREE.Vector3()
- const closestOnLine = new THREE.Vector3()
- THREE.Line3.prototype.closestPointsRayLine ??= function(ray, line, closestOnRay, closestOnLine) {
- // 实现射线与线段最近点计算(需自定义或使用数学库)
- }
-
- lineSegment.closestPointsRayLine(ray, true, closestOnRay, closestOnLine)
- return closestOnRay.distanceTo(closestOnLine)
-}
+//
+// /**
+// * 查找射线周围指定半径内的对象
+// */
+// export function findObjectsInRadius(viewport: Viewport,
+// point: THREE.Vector2,
+// radius: number,
+// lines: { object: THREE.Object3D, distance: number }[],
+// points: { object: THREE.Object3D, distance: number }[]
+// ): void {
+// const ray = new THREE.Raycaster()
+// ray.setFromCamera(point, viewport.camera)
+//
+// viewport.dragControl._dragObjects.forEach(obj => {
+// if (obj instanceof THREE.Points) {
+// // 处理点云:遍历每个点
+// const distance = distanceToRay(ray, point)
+// if (distance <= radius) {
+// points.push({ object: obj, distance })
+// }
+//
+// } else if (obj instanceof THREE.Line) {
+// // 处理线段:计算线段到射线的最近距离
+// const distance = getLineDistanceToRay(ray, obj)
+// if (distance <= radius) {
+// lines.push({ object: obj, distance })
+// }
+// }
+// })
+// }
+//
+// /**
+// * 计算点到射线的最短距离
+// */
+// function distanceToRay(ray: THREE.Raycaster, point: THREE.Vector2) {
+// const closestPoint = new THREE.Vector3()
+// ray.closestPointToPoint(point, closestPoint)
+// return point.distanceTo(closestPoint)
+// }
+//
+// /**
+// * 计算线段到射线的最短距离
+// */
+// function getLineDistanceToRay(ray: THREE.Raycaster, line: THREE.Line) {
+// const lineStart = new THREE.Vector3()
+// const lineEnd = new THREE.Vector3()
+// line.geometry.attributes.position.getXYZ(0, lineStart)
+// line.geometry.attributes.position.getXYZ(1, lineEnd)
+// line.localToWorld(lineStart)
+// line.localToWorld(lineEnd)
+//
+// const lineSegment = new THREE.Line3(lineStart, lineEnd)
+// const closestOnRay = new THREE.Vector3()
+// const closestOnLine = new THREE.Vector3()
+// THREE.Line3.prototype.closestPointsRayLine ??= function(ray, line, closestOnRay, closestOnLine) {
+// // 实现射线与线段最近点计算(需自定义或使用数学库)
+// }
+//
+// lineSegment.closestPointsRayLine(ray, true, closestOnRay, closestOnLine)
+// return closestOnRay.distanceTo(closestOnLine)
+// }
/**
* 考虑吸附的情况下计算鼠标事件位置
diff --git a/src/model/WorldModel.ts b/src/model/WorldModel.ts
index 11829a8..86a2d72 100644
--- a/src/model/WorldModel.ts
+++ b/src/model/WorldModel.ts
@@ -7,6 +7,7 @@ import type Viewport from '@/designer/Viewport.ts'
import { loadSceneFromJson } from '@/model/ModelUtils.ts'
import MeasureMeta from './itemType/measure/MeasureMeta'
+import ConveyorMeta from './itemType/line/conveyor/ConveyorMeta'
import type { IGridHelper } from '@/model/WorldModelType.ts'
/**
@@ -53,7 +54,8 @@ export default class WorldModel {
init() {
return Promise.all([
- MeasureMeta.clazz.init(this)
+ MeasureMeta.clazz.init(this),
+ ConveyorMeta.clazz.init(this)
]).then(() => {
console.log('世界模型初始化完成')
diff --git a/src/model/itemType/Toolbox.ts b/src/model/itemType/Toolbox.ts
index 4e59f07..96d217f 100644
--- a/src/model/itemType/Toolbox.ts
+++ b/src/model/itemType/Toolbox.ts
@@ -218,7 +218,6 @@ export default abstract class Toolbox {
if (e.button === 2) {
// 右键点击, 完成绘图操作
this.viewport.state.cursorMode = 'normal'
- this.stop()
} else if (e.button === 0) {
// 左键点击, 添加点
diff --git a/src/model/itemType/line/conveyor/Conveyor.ts b/src/model/itemType/line/conveyor/Conveyor.ts
new file mode 100644
index 0000000..d631c8a
--- /dev/null
+++ b/src/model/itemType/line/conveyor/Conveyor.ts
@@ -0,0 +1,82 @@
+import * as THREE from 'three'
+import { Material } from 'three'
+import ItemTypeLine from '@/model/itemType/ItemTypeLine.ts'
+import WorldModel from '@/model/WorldModel.ts'
+import Viewport from '@/designer/Viewport.ts'
+import ToolboxLine from '@/model/itemType/ToolboxLine.ts'
+import ConveyorToolbox from './ConveyorToolbox.ts'
+import { Line2 } from 'three/examples/jsm/lines/Line2.js'
+import { LineGeometry } from 'three/examples/jsm/lines/LineGeometry.js'
+import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial.js'
+
+export default class Conveyor extends ItemTypeLine {
+ defaultScale: THREE.Vector3 = new THREE.Vector3(0.25, 0.1, 0.25)
+ defaultRotation: THREE.Vector3 = new THREE.Vector3(0, 0, 0)
+
+ pointMaterial!: Material
+
+ lineMaterial!: LineMaterial
+
+ static POINT_NAME = 'conveyor_point'
+ static LINE_NAME = 'conveyor_line'
+
+ override init(worldModel: WorldModel): Promise {
+ super.init(worldModel)
+
+ this.lineMaterial = new LineMaterial({
+ color: 0xE63C17, // 主颜色
+ linewidth: 2, // 实际可用的线宽
+ vertexColors: true, // 启用顶点颜色
+ dashed: false,
+ alphaToCoverage: true
+ })
+
+ this.pointMaterial = new THREE.MeshBasicMaterial({ color: 0x303133, transparent: true, opacity: 0.9 })
+
+ return Promise.resolve()
+ }
+
+ getDefaultScale(): THREE.Vector3 {
+ return this.defaultScale
+ }
+
+ getDefaultRotation(): THREE.Vector3 {
+ return this.defaultRotation
+ }
+
+ createToolbox(viewport: Viewport): ToolboxLine {
+ const toolbox = new ConveyorToolbox()
+ toolbox.init(viewport, this)
+ //@ts-ignore
+ return toolbox
+ }
+
+ /**
+ * 创建测量点
+ */
+ createPointBasic(position?: THREE.Vector3): THREE.Object3D {
+ const p = position
+ const scale = 0.25
+
+ const tt = new THREE.BoxGeometry(1, 1, 1)
+ const obj = new THREE.Mesh(tt, this.pointMaterial)
+ obj.scale.set(scale, 0.1, scale)
+ if (p) {
+ obj.position.set(p.x, p.y, p.z)
+ }
+ obj.name = Conveyor.POINT_NAME
+ return obj
+ }
+
+ /**
+ * 创建测量线
+ */
+ createLineBasic(): Line2 {
+ const geom = new LineGeometry()
+ const obj = new Line2(geom, this.lineMaterial)
+ obj.frustumCulled = false
+ obj.name = Conveyor.LINE_NAME
+ obj.uuid = THREE.MathUtils.generateUUID()
+ return obj
+ }
+}
\ No newline at end of file
diff --git a/src/model/itemType/line/conveyor/ConveyorMeta.ts b/src/model/itemType/line/conveyor/ConveyorMeta.ts
new file mode 100644
index 0000000..f5f600b
--- /dev/null
+++ b/src/model/itemType/line/conveyor/ConveyorMeta.ts
@@ -0,0 +1,9 @@
+import { defineItemType } from '@/runtime/DefineItemType.ts'
+import Conveyor from './Conveyor.ts'
+
+export default defineItemType({
+ name: 'conveyor',
+ label: '输送线',
+ actionType: 'ln',
+ clazz: new Conveyor()
+})
\ No newline at end of file
diff --git a/src/model/itemType/line/conveyor/ConveyorToolbox.ts b/src/model/itemType/line/conveyor/ConveyorToolbox.ts
new file mode 100644
index 0000000..1e62d44
--- /dev/null
+++ b/src/model/itemType/line/conveyor/ConveyorToolbox.ts
@@ -0,0 +1,16 @@
+import ToolboxLine from '@/model/itemType/ToolboxLine.ts'
+import type Conveyor from './Conveyor.ts'
+
+/**
+ * 测量工具箱,用于处理测量相关的操作
+ */
+export default class ConveyorToolbox extends ToolboxLine {
+
+ constructor() {
+ super()
+ }
+
+ get conveyor(): Conveyor {
+ return this._itemType
+ }
+}
\ No newline at end of file