diff --git a/src/components/Model3DView.vue b/src/components/Model3DView.vue index 110e9db..2f38a72 100644 --- a/src/components/Model3DView.vue +++ b/src/components/Model3DView.vue @@ -386,6 +386,7 @@ function createGroundStore() { side: THREE.DoubleSide // 双面渲染:ml-citation{ref="5,8" data="citationList"} }); const planeMesh = new THREE.Mesh(planeGeometry, material); + planeMesh.rotateX(Math.PI / 2) scene.add(planeMesh); } @@ -928,4 +929,4 @@ function cleanupThree() { } } - \ No newline at end of file + diff --git a/src/core/Constract.ts b/src/core/Constract.ts index 34d4c0a..a26486d 100644 --- a/src/core/Constract.ts +++ b/src/core/Constract.ts @@ -1,4 +1,4 @@ -export default Object.freeze({ +const Constract = Object.freeze({ // 光标相关 CursorModeNormal: 'normal', @@ -17,7 +17,14 @@ export default Object.freeze({ CursorModeMeasure: 'measure', CursorModeWay: 'way', CursorModeGstore: 'gstore', + CursorModeRack: 'rack', // 选择模式 - CursorModeSelectByRec: 'selectByRec' + CursorModeSelectByRec: 'selectByRec', + + HEIGHT_GSTORE: 0.03, + HEIGHT_MEASURE: 0.02, + HEIGHT_RACK: 0, + HEIGHT_WAY: 0.01 }) +export default Constract diff --git a/src/core/ModelUtils.ts b/src/core/ModelUtils.ts index 3abd3ec..23bfa18 100644 --- a/src/core/ModelUtils.ts +++ b/src/core/ModelUtils.ts @@ -6,6 +6,7 @@ import { computeBoundsTree, disposeBoundsTree } from 'three-mesh-bvh' import { Vector2 } from 'three/src/math/Vector2' import type Toolbox from '@/model/itemType/Toolbox.ts' import EventBus from '@/runtime/EventBus.ts' +import Decimal from 'decimal.js' /** * 确保所有实体之间的关系满足一致性: @@ -140,7 +141,27 @@ export function deletePointByKeyboard() { const entityId = viewport.state.selectedEntityId if (!entityId) { - system.msg('没有选中任何点') + const multiSelectedEntityIds = viewport.state.multiSelectedEntityIds + if (!multiSelectedEntityIds && multiSelectedEntityIds.length === 0) { + system.msg('请选中要删除的实体', 'error') + return + } + + const stateManager = viewport.stateManager + stateManager.beginStateUpdate() + const deleteItems = _.remove(stateManager.vdata.items, (item) => multiSelectedEntityIds.includes(item.id)) + stateManager.endStateUpdate() + if (deleteItems.length === 0) { + system.msg('没有找到要删除的实体', 'error') + } else { + system.msg('删除了 ' + deleteItems.length + ' 个实体') + } + for (const deleteEntityId of multiSelectedEntityIds) { + EventBus.dispatch('entityDeleted', { + deleteEntityId: deleteEntityId + }) + viewport.selectInspect.clearRedSelectionBoxes() + } return } @@ -161,6 +182,7 @@ export function deletePointByKeyboard() { }) system.msg('删除 [' + entityId + ']') + viewport.selectInspect.clearSelectionBox() } export function escByKeyboard() { @@ -453,3 +475,21 @@ function loadObject3DFromJson(items: ItemJson[]): THREE.Object3D[] { return result } + +/** + * 十进制求和 + * @param collection + * @param iteratee + */ +export function decimalSumBy(collection: ArrayLike | null | undefined, iteratee?: ((value: T) => number)): number { + + let sum = new Decimal(0) + _.forEach(collection, (t)=>{ + if (typeof iteratee === 'function') { + sum = sum.add(new Decimal(iteratee(t))) + } else { + sum = sum.add(new Decimal(t)) + } + }) + return sum.toNumber() +} diff --git a/src/core/controls/SelectInspect.ts b/src/core/controls/SelectInspect.ts index 62c3eff..cd41f10 100644 --- a/src/core/controls/SelectInspect.ts +++ b/src/core/controls/SelectInspect.ts @@ -167,7 +167,7 @@ export default class SelectInspect implements IControls { * 更新选中对象的包围盒线框 */ updateSelectionBox(selectedObject: THREE.Object3D) { - this.disposeSelectionBox() + this.clearSelectionBox() if (!selectedObject) { return @@ -214,11 +214,12 @@ export default class SelectInspect implements IControls { puFn = undefined // 销毁选择工具 - this.disposeSelectionBox() + this.clearSelectionBox() this.disposeRect() + this.clearRedSelectionBoxes() } - disposeSelectionBox() { + clearSelectionBox() { if (this.selectionBox) { this.viewport.scene.remove(this.selectionBox) this.selectionBox.geometry.dispose() @@ -311,7 +312,7 @@ export default class SelectInspect implements IControls { if (Date.now() - clickTime < 200) { // 如果是点击事件,触发选中逻辑 const objects: THREE.Object3D[] = this.viewport.entityManager.getObjectByCanvasMouse(event) - if (objects.length > 0) { + if (objects.length > 0 && objects[0]?.userData?.entityId) { console.log('mouseClick', objects) const object = objects[0] const entityId = object.userData.entityId diff --git a/src/core/engine/Viewport.ts b/src/core/engine/Viewport.ts index c87036f..8928f32 100644 --- a/src/core/engine/Viewport.ts +++ b/src/core/engine/Viewport.ts @@ -37,10 +37,12 @@ export default class Viewport { dragControl: any // EsDragControls animationFrameId: any = null scene: SceneHelp + selectInspect = new SelectInspect() + mouseMoveInspect = new MouseMoveInspect() tools: IControls[] = [ - new MouseMoveInspect(), - new SelectInspect() + markRaw(this.selectInspect), + markRaw(this.mouseMoveInspect) ] // 状态管理器 diff --git a/src/core/manager/WorldModel.ts b/src/core/manager/WorldModel.ts index 8b6f429..ce62347 100644 --- a/src/core/manager/WorldModel.ts +++ b/src/core/manager/WorldModel.ts @@ -4,6 +4,7 @@ import EventBus from '@/runtime/EventBus' import Measure from '@/modules/measure' import Way from '@/modules/way' import Gstore from '@/modules/gstore' +import Rack from '@/modules/rack' import StateManager from '@/core/manager/StateManager.ts' export interface WorldModelState { @@ -64,7 +65,8 @@ export default class WorldModel { return Promise.all([ Measure, Way, - Gstore + Gstore, + Rack ]).then(() => { console.log('世界模型初始化完成') @@ -155,4 +157,4 @@ export default class WorldModel { } return Promise.reject('楼层不存在, catalogCode=' + catalogCode) } -} \ No newline at end of file +} diff --git a/src/editor/Model2DEditor.vue b/src/editor/Model2DEditor.vue index 136f18f..e30834e 100644 --- a/src/editor/Model2DEditor.vue +++ b/src/editor/Model2DEditor.vue @@ -53,6 +53,14 @@ :type="state?.cursorMode===Constract.CursorModeGstore?'primary':''" @click="()=>state.cursorMode = Constract.CursorModeGstore"> + + + +
- 属性面板 - - - - +
- + + +
@@ -75,13 +78,18 @@ export default { }, mixins: [IWidgets], data() { - return { itemTypeMeta: null, searchKeyword: '' } }, computed: { + t() { + return this.selectedItem ? ('(' + this.selectedItem.t + ')') : '' + }, + selectedItem() { + return this.state?.selectedItem + }, selectedObject() { return this.state?.selectedObject }, @@ -91,24 +99,24 @@ export default { }, methods: { selectedObjectChanged(state) { - const data = state.selectedItem; - console.log("selectedObjectChanged data", data) - if(data) { + const data = state.selectedItem + console.log('selectedObjectChanged data', data) + if (data) { this.viewport.stateManager.beginStateUpdate() const item = _.find(this.viewport.stateManager.vdata.items, item => item.id === data.id) // item.tf[0][0] = item.tf[0][0] / 2; - console.log("selectedObjectChanged item", item) + console.log('selectedObjectChanged item', item) // _.extend(item, data) this.viewport.stateManager.endStateUpdate() } - }, + } }, mounted() { - EventBus.on("selectedObjectChanged", this.selectedObjectChanged); + EventBus.on('selectedObjectChanged', this.selectedObjectChanged) }, unmounted() { - EventBus.off("selectedObjectChanged", this.selectedObjectChanged); - }, + EventBus.off('selectedObjectChanged', this.selectedObjectChanged) + } }