diff --git a/src/Add-on/Break.ts b/src/Add-on/Break.ts index 9b58befa2..bf3ccf449 100644 --- a/src/Add-on/Break.ts +++ b/src/Add-on/Break.ts @@ -1,4 +1,4 @@ -import { Vector3 } from "../../node_modules/@types/three"; +import { Vector3 } from "three"; import { app } from "../ApplicationServices/Application"; import { Circle } from "../DatabaseServices/Circle"; import { Curve } from "../DatabaseServices/Curve"; diff --git a/src/Add-on/DrawBoard/DrawBehindBoard.ts b/src/Add-on/DrawBoard/DrawBehindBoard.ts index 1d0a424b4..226cbf5c1 100644 --- a/src/Add-on/DrawBoard/DrawBehindBoard.ts +++ b/src/Add-on/DrawBoard/DrawBehindBoard.ts @@ -4,9 +4,9 @@ import { Board, BoardType } from '../../DatabaseServices/Board'; import { Box3Ext } from '../../Geometry/Box'; import { MoveMatrix } from '../../Geometry/GeUtils'; import { BehindHeightPositon, BoardRelativePositon, BehindBoardOption } from '../../UI/Store/BoardInterface'; -import { DrawSingleBoard } from './DrawSingleBoard'; +import { DrawBoardTool } from './DrawBoardTool'; -export class DrawBehindBoard extends DrawSingleBoard +export class DrawBehindBoard extends DrawBoardTool { protected drawType = BoardType.Behind; protected buildBoard(box: Box3Ext, opt: BehindBoardOption, ro: Matrix4) diff --git a/src/Add-on/DrawBoard/DrawBoardTool.ts b/src/Add-on/DrawBoard/DrawBoardTool.ts new file mode 100644 index 000000000..9b07e9e72 --- /dev/null +++ b/src/Add-on/DrawBoard/DrawBoardTool.ts @@ -0,0 +1,475 @@ +import { Matrix4, Mesh, Object3D, Ray, Raycaster, Vector2, Vector3 } from 'three'; +import { app } from '../../ApplicationServices/Application'; +import { arrayRemoveIf } from '../../Common/ArrayExt'; +import { Vec3DTo2D } from '../../Common/CurveUtils'; +import { Board, BoardType } from '../../DatabaseServices/Board'; +import { Command } from '../../Editor/CommandMachine'; +import { PromptStatus } from '../../Editor/PromptResult'; +import { SelectLine } from '../../Editor/SelectBox'; +import { Box3Ext } from '../../Geometry/Box'; +import { equaln } from '../../Geometry/GeUtils'; +import { GeneralSpaceParse, GeneralSpaceParse2 } from '../../Geometry/SpaceParse/GeneralSpaceParse'; +import { Viewer } from '../../GraphicsSystem/Viewer'; +import { BoardModalType } from '../../UI/Components/Board/BoardModal'; +import { BehindBoardStore, LayerBoardStore, VerticalBoardStore, BoardStore } from '../../UI/Store/BoardStore'; +import { ModalState, BoardOption } from '../../UI/Store/BoardInterface'; + +export abstract class DrawBoardTool implements Command +{ + //画板件类型,默认画层板 + protected drawType = BoardType.Layer; + async exec() + { + //原来禁用捕捉开启状态 + let oldSnapState = app.m_Editor.m_GetpointServices.snapServices.m_Disabled; + app.m_Editor.m_GetpointServices.snapServices.m_Disabled = true; + + let store: LayerBoardStore | VerticalBoardStore | BehindBoardStore; + let modalType: BoardModalType; + switch (this.drawType) + { + case BoardType.Layer: + store = LayerBoardStore.Store(); + modalType = BoardModalType.Ly; + break; + case BoardType.Vertical: + store = VerticalBoardStore.Store(); + modalType = BoardModalType.Ve; + break; + case BoardType.Behind: + store = BehindBoardStore.Store(); + modalType = BoardModalType.Be; + + } + app.m_Editor.m_ModalManage.RenderBoardModal(store, modalType); + + let state = await store.GetBoardOption(); + + if (state !== ModalState.Ok) + return; + + await this.SelectPoint(store, modalType) + + //恢复原先状态 + app.m_Editor.m_GetpointServices.snapServices.m_Disabled = oldSnapState; + } + private async SelectPoint(store: BoardStore, type: BoardModalType) + { + // 板件数据 + let opt = store.m_BoardOption; + + let view = app.m_Viewer; + + while (true) + { + let ptRes = await app.m_Editor.GetPoint({ + Msg: "点选画板区域", + KeyWordList: [{ msg: "框选", key: "S" }, { msg: "全选", key: "A" }, { msg: "放弃", key: "U" }] + }); + + if (ptRes.Status === PromptStatus.OK) + { + let brs: Board[] = []; + + let mousePt = ptRes.Value.clone(); + + view.WorldToScreen(mousePt); + + //是否选到背板 + let en = this.pointPick(mousePt, view); + //选中面法向量 + let normal: Vector3; + //鼠标在面上的交点 + let origin: Vector3; + if (en.pickObj && (en.pickObj.userData).BoardType === BoardType.Behind) + { + brs.push(en.pickObj.userData); + let res = this.getPtSurroundBoardsByPick(en, view, brs); + normal = res.normal; + origin = res.origin; + } + else + { + //选择上下左右的板 + this.getPtSurroundBoardsByMouse(mousePt, view, brs); + } + //分析点周围的空间 + if (brs.length > 1) + { + let spaceParse = new GeneralSpaceParse(brs); + await spaceParse.SpaceParse(); + + if (spaceParse.Spaces.length === 0) + { + app.m_Editor.m_CommandStore.Prompt("生成b板件失败,没分析出有效空间"); + continue; + } + + //柜子旋转矩阵 + let ro = new Matrix4().extractRotation(spaceParse.OCS); + + //存在的空间 + let spaces = spaceParse.Spaces; + + if (spaces.length > 1) + { + let ray: Ray; + //构造射线,取和射线相交的空间 + if (normal) + { + ray = new Ray(origin, normal); + } + else + { + let raycaster = new Raycaster(); + raycaster.setFromCamera({ + x: (mousePt.x / view.Width) * 2 - 1, + y: - (mousePt.y / view.Height) * 2 + 1 + }, view.Camera); + ray = raycaster.ray; + ray.origin.sub(raycaster.ray.direction.clone().multiplyScalar(1e3)); + } + arrayRemoveIf(spaces, box => + { + let b = box.clone().applyMatrix4(ro); + return !Boolean(ray.intersectBox(b, new Vector3())) + }); + } + if (spaces.length > 0) + { + let box = spaces[0]; + this.buildBoard(box, opt, ro); + } + } + else + { + app.m_Editor.m_CommandStore.Prompt("请选择有效的板件,或者周围没有效板件"); + } + + } + else if (ptRes.Status === PromptStatus.Keyword) + { + if (ptRes.StringResult === "S") + { + await this.SelectBoxes(opt); + break; + } + else if (ptRes.StringResult === "A") + { + //TODO:未完善功能 + await this.DrawInALlBoxes(opt); + break; + } + else if (ptRes.StringResult === "U") + { + break; + } + } + else + { + if (!store.isContinuous) + { + app.m_Editor.m_ModalManage.RenderBoardModal(store, type); + let state = await store.GetBoardOption(); + if (state !== ModalState.Ok) break; + } else break; + } + } + } + + /** + *获取鼠标点周围的板 + * @private + * @param {Vector3} mousePt + * @param {Viewer} view + * @param {Board[]} brs + * @memberof DrawLayerBoard + */ + private getPtSurroundBoardsByMouse(mousePt: Vector3, view: Viewer, brs: Board[]) + { + let { vMeshs, lMeshs } = this.getMeshs(view); + //获取上下左右的板 + const getBoard = (pt: Vector2, objs: Object3D[], type: string) => + { + let sl = new SelectLine(view, Vec3DTo2D(mousePt), pt); + sl.Select(objs); + this.selectSurroundBoard(sl.Enlity as Board[], type, brs) + } + + let leftPt = Vec3DTo2D(mousePt).setX(0); + getBoard(leftPt, vMeshs, "left"); + + let rightPt = Vec3DTo2D(mousePt).setX(view.Width); + getBoard(rightPt, vMeshs, "right"); + + let topPt = Vec3DTo2D(mousePt).setY(0); + getBoard(topPt, lMeshs, "top"); + + let bottomPt = Vec3DTo2D(mousePt).setY(view.Height); + getBoard(bottomPt, lMeshs, "bottom") + + } + private getPtSurroundBoardsByPick(en: { pickObj: Object3D, intersect: any }, view: Viewer, brs: Board[]) + { + let { vMeshs, lMeshs } = this.getMeshs(view); + let ro = new Matrix4().extractRotation(en.intersect.object.matrix); + let normal = en.intersect.face.normal.clone() as Vector3; + let leftDir = new Vector3().setX(normal.z); + let topDir = new Vector3().setY(normal.z) + + normal.applyMatrix4(ro); + leftDir.applyMatrix4(ro); + topDir.applyMatrix4(ro); + + let origin = en.intersect.point as Vector3; + let leftRay = new Raycaster(origin, leftDir); + let rightRay = new Raycaster(origin, leftDir.clone().negate()); + //原点往法向量方向偏移一点,保证相交 + let fuzzVec = normal.clone().multiplyScalar(1e-3); + let topRay = new Raycaster(origin.clone().add(fuzzVec), topDir); + let bottomRay = new Raycaster(origin.clone().add(fuzzVec), topDir.clone().negate()); + + const getBoard = (ray, meshs) => + { + let ints = ray.intersectObjects(meshs, false); + if (ints.length > 0) + { + brs.push(ints[0].object.userData) + } + } + getBoard(leftRay, vMeshs); + getBoard(rightRay, vMeshs); + getBoard(topRay, lMeshs); + getBoard(bottomRay, lMeshs); + + return { normal, origin }; + } + private getMeshs(view: Viewer) + { + let meshs = view.Scene.children.filter(o => o instanceof Mesh && o.userData && o.userData instanceof Board); + let vMeshs = meshs.filter(o => (o.userData).BoardType === BoardType.Vertical); + let lMeshs = meshs.filter(o => (o.userData).BoardType === BoardType.Layer); + return { vMeshs, lMeshs } + } + private selectSurroundBoard(ens: Board[], dir: string, brs: Board[]) + { + if (ens.length === 0) return; + + let boxMap: Map = new Map(); + ens.forEach(b => + { + let pt = b.MinPoint; + app.m_Viewer.WorldToScreen(pt); + boxMap.set(b, pt); + }) + + switch (dir) + { + case "left": + ens.sort((a, b) => boxMap.get(b).x - boxMap.get(a).x); + break; + case "right": + ens.sort((a, b) => boxMap.get(a).x - boxMap.get(b).x); + break; + case "top": + ens.sort((a, b) => boxMap.get(b).y - boxMap.get(a).y); + break; + case "bottom": + ens.sort((a, b) => boxMap.get(a).y - boxMap.get(b).y); + break; + } + + let en = ens[0]; + if (en && !brs.includes(en)) + { + brs.push(en) + } + } + private async SelectBoxes(opt: BoardOption) + { + let exSsRes = await app.m_Editor.GetSelection({ Msg: "请选择对象<全部选择>:", UseSelect: true }); + if (exSsRes.Status === PromptStatus.Cancel) + return; + let boardCus = exSsRes.SelectSet.SelectEntityList.filter(en => + en instanceof Board) as Board[]; + + if (boardCus.length > 0) + { + let spaceParse = new GeneralSpaceParse(boardCus); + await spaceParse.SpaceParse(); + + if (spaceParse.Spaces.length === 0) + { + app.m_Editor.m_CommandStore.Prompt("生成层板失败"); + return; + } + let ro = new Matrix4().extractRotation(spaceParse.OCS); + + let spaces = spaceParse.Spaces; + let box = await this.selectBox(spaces); + + this.buildBoard(box, opt, ro); + } + else + { + app.m_Editor.m_CommandStore.Prompt("请选择板件") + } + } + private async DrawInALlBoxes(opt: BoardOption) + { + let exSsRes = await app.m_Editor.GetSelection({ Msg: "请选择对象<全部选择>:", UseSelect: true }); + if (exSsRes.Status === PromptStatus.Cancel) + return; + let boardCus = exSsRes.SelectSet.SelectEntityList.filter(en => + en instanceof Board) as Board[]; + + if (boardCus.length > 0) + { + let spaceParse = new GeneralSpaceParse2(boardCus); + spaceParse.SpaceParse(); + + if (spaceParse.Spaces.length === 0) + { + app.m_Editor.m_CommandStore.Prompt("生成层板失败"); + return; + } + let ro = new Matrix4().extractRotation(spaceParse.OCS); + + let spaces = spaceParse.Spaces; + for (let box of spaces) + { + this.buildBoard(box, opt, ro); + } + } + else + { + app.m_Editor.m_CommandStore.Prompt("请选择板件") + } + } + + private pointPick(ptVcs: Vector3, view: Viewer) + { + let selectObjects = view.Scene.children; + + selectObjects = selectObjects.filter(o => o instanceof Mesh && o.userData && o.userData instanceof Board); + + let raycaster = new Raycaster(); + raycaster.setFromCamera({ + x: (ptVcs.x / view.Width) * 2 - 1, + y: - (ptVcs.y / view.Height) * 2 + 1 + }, view.Camera); + raycaster.ray.origin.sub(raycaster.ray.direction.clone().multiplyScalar(1e3)); + + let pickObj: Object3D; + let minDis: number; + let intersect; + for (let obj of selectObjects) + { + let intersects = []; + if (!obj.visible) continue; + obj.raycast(raycaster, intersects) + if (intersects.length > 0) + if (!minDis || minDis > intersects[0].distance) + { + pickObj = obj; + minDis = intersects[0].distance + intersect = intersects[0]; + } + } + return { pickObj, intersect }; + } + async selectBox(spaces: Box3Ext[]) + { + if (spaces.length === 1) + return spaces[0]; + + spaces.sort((b1, b2) => + { + if (equaln(b2.min.z, b1.min.z)) + { + return b1.min.y - b2.min.y; + } + return b1.min.z - b2.min.z + }); + + if (spaces.length > 2) + { + let keyWord = await app.m_Editor.GetKeyWords({ + Msg: "输入位置:", + KeyWordList: [{ key: "1", msg: "靠上" }, { key: "2", msg: "靠下" }] + }); + + if (keyWord.StringResult == "1") + { + spaces = spaces.splice(spaces.length / 2, spaces.length / 2) + } + else if (keyWord.StringResult == "2") + { + spaces = spaces.splice(0, spaces.length / 2) + } + + keyWord = await app.m_Editor.GetKeyWords({ + Msg: "输入位置:", + KeyWordList: [{ key: "3", msg: "靠前" }, { key: "4", msg: "靠后" }] + }); + if (keyWord.StringResult == "3") + { + spaces[0].min.y < spaces[1].min.y ? spaces.pop() : spaces.shift(); + } + else if (keyWord.StringResult == "4") + { + spaces[0].min.y > spaces[1].min.y ? spaces.pop() : spaces.shift(); + } + } + else + { + if (spaces[0].min.z === spaces[1].min.z) + { + let KeyWordList = [{ key: "3", msg: "靠前" }, { key: "4", msg: "靠后" }]; + let tmpPar1 = spaces[0].min.y; + let tmpPar2 = spaces[1].min.y; + + if (spaces[0].min.y === spaces[1].min.y) + { + KeyWordList = [{ key: "3", msg: "靠左" }, { key: "4", msg: "靠右" }]; + tmpPar1 = spaces[0].min.x; + tmpPar2 = spaces[1].min.x; + } + let keyWord = await app.m_Editor.GetKeyWords({ + Msg: "输入位置:", + KeyWordList + }); + if (keyWord.StringResult == "3") + { + tmpPar1 < tmpPar2 ? spaces.pop() : spaces.shift(); + } + else if (keyWord.StringResult == "4") + { + tmpPar1 > tmpPar2 ? spaces.pop() : spaces.shift(); + } + } + else + { + let keyWord = await app.m_Editor.GetKeyWords({ + Msg: "输入位置:", + KeyWordList: [{ key: "1", msg: "靠上" }, { key: "2", msg: "靠下" }] + }); + + if (keyWord.StringResult == "1") + { + spaces = spaces.splice(spaces.length / 2, spaces.length / 2) + } + else if (keyWord.StringResult == "2") + { + spaces = spaces.splice(0, spaces.length / 2) + } + } + } + return spaces[0]; + } + //构建板件 + protected buildBoard(box: Box3Ext, opt: BoardOption, ro: Matrix4) + { + + } +} diff --git a/src/Add-on/DrawBoard/DrawLayerBoard.ts b/src/Add-on/DrawBoard/DrawLayerBoard.ts index 799f1c48c..d8c265332 100644 --- a/src/Add-on/DrawBoard/DrawLayerBoard.ts +++ b/src/Add-on/DrawBoard/DrawLayerBoard.ts @@ -4,9 +4,9 @@ import { Board, BoardType } from '../../DatabaseServices/Board'; import { Box3Ext } from '../../Geometry/Box'; import { MoveMatrix } from '../../Geometry/GeUtils'; import { LayerBoardOption, BoardRelativePositon } from '../../UI/Store/BoardInterface'; -import { DrawSingleBoard } from './DrawSingleBoard'; +import { DrawBoardTool } from './DrawBoardTool'; -export class DrawLayerBoard extends DrawSingleBoard +export class DrawLayerBoard extends DrawBoardTool { //构建板件 protected buildBoard(box: Box3Ext, opt: LayerBoardOption, ro: Matrix4) diff --git a/src/Add-on/DrawBoard/DrawSingleBoard.ts b/src/Add-on/DrawBoard/DrawSingleBoard.ts index 81661e2d5..06a2fc7eb 100644 --- a/src/Add-on/DrawBoard/DrawSingleBoard.ts +++ b/src/Add-on/DrawBoard/DrawSingleBoard.ts @@ -1,475 +1,20 @@ -import { Matrix4, Mesh, Object3D, Ray, Raycaster, Vector2, Vector3 } from 'three'; +import { Vector3 } from 'three'; + import { app } from '../../ApplicationServices/Application'; -import { arrayRemoveIf } from '../../Common/ArrayExt'; -import { Vec3DTo2D } from '../../Common/CurveUtils'; import { Board, BoardType } from '../../DatabaseServices/Board'; import { Command } from '../../Editor/CommandMachine'; import { PromptStatus } from '../../Editor/PromptResult'; -import { SelectLine } from '../../Editor/SelectBox'; -import { Box3Ext } from '../../Geometry/Box'; -import { equaln } from '../../Geometry/GeUtils'; -import { GeneralSpaceParse, GeneralSpaceParse2 } from '../../Geometry/SpaceParse/GeneralSpaceParse'; -import { Viewer } from '../../GraphicsSystem/Viewer'; +import { MoveMatrix } from '../../Geometry/GeUtils'; import { BoardModalType } from '../../UI/Components/Board/BoardModal'; -import { BehindBoardStore, LayerBoardStore, VerticalBoardStore, BoardStore } from '../../UI/Store/BoardStore'; -import { ModalState, BoardOption } from '../../UI/Store/BoardInterface'; +import { SideBoardStore, SingleBoardStore } from '../../UI/Store/BoardStore'; +import { ModalState } from '../../UI/Store/BoardInterface'; + -export abstract class DrawSingleBoard implements Command +export class DrawSingleBoard implements Command { - //画板件类型,默认画层板 - protected drawType = BoardType.Layer; async exec() { - //原来禁用捕捉开启状态 - let oldSnapState = app.m_Editor.m_GetpointServices.snapServices.m_Disabled; - app.m_Editor.m_GetpointServices.snapServices.m_Disabled = true; - - let store: LayerBoardStore | VerticalBoardStore | BehindBoardStore; - let modalType: BoardModalType; - switch (this.drawType) - { - case BoardType.Layer: - store = LayerBoardStore.Store(); - modalType = BoardModalType.Ly; - break; - case BoardType.Vertical: - store = VerticalBoardStore.Store(); - modalType = BoardModalType.Ve; - break; - case BoardType.Behind: - store = BehindBoardStore.Store(); - modalType = BoardModalType.Be; - - } - app.m_Editor.m_ModalManage.RenderBoardModal(store, modalType); - - let state = await store.GetBoardOption(); - - if (state !== ModalState.Ok) - return; - - await this.SelectPoint(store, modalType) - - //恢复原先状态 - app.m_Editor.m_GetpointServices.snapServices.m_Disabled = oldSnapState; - } - private async SelectPoint(store: BoardStore, type: BoardModalType) - { - // 板件数据 - let opt = store.m_BoardOption; - - let view = app.m_Viewer; - - while (true) - { - let ptRes = await app.m_Editor.GetPoint({ - Msg: "点选画板区域", - KeyWordList: [{ msg: "框选", key: "S" }, { msg: "全选", key: "A" }, { msg: "放弃", key: "U" }] - }); - - if (ptRes.Status === PromptStatus.OK) - { - let brs: Board[] = []; - - let mousePt = ptRes.Value.clone(); - - view.WorldToScreen(mousePt); - - //是否选到背板 - let en = this.pointPick(mousePt, view); - //选中面法向量 - let normal: Vector3; - //鼠标在面上的交点 - let origin: Vector3; - if (en.pickObj && (en.pickObj.userData).BoardType === BoardType.Behind) - { - brs.push(en.pickObj.userData); - let res = this.getPtSurroundBoardsByPick(en, view, brs); - normal = res.normal; - origin = res.origin; - } - else - { - //选择上下左右的板 - this.getPtSurroundBoardsByMouse(mousePt, view, brs); - } - //分析点周围的空间 - if (brs.length > 1) - { - let spaceParse = new GeneralSpaceParse(brs); - await spaceParse.SpaceParse(); - - if (spaceParse.Spaces.length === 0) - { - app.m_Editor.m_CommandStore.Prompt("生成b板件失败,没分析出有效空间"); - continue; - } - - //柜子旋转矩阵 - let ro = new Matrix4().extractRotation(spaceParse.OCS); - - //存在的空间 - let spaces = spaceParse.Spaces; - - if (spaces.length > 1) - { - let ray: Ray; - //构造射线,取和射线相交的空间 - if (normal) - { - ray = new Ray(origin, normal); - } - else - { - let raycaster = new Raycaster(); - raycaster.setFromCamera({ - x: (mousePt.x / view.Width) * 2 - 1, - y: - (mousePt.y / view.Height) * 2 + 1 - }, view.Camera); - ray = raycaster.ray; - ray.origin.sub(raycaster.ray.direction.clone().multiplyScalar(1e3)); - } - arrayRemoveIf(spaces, box => - { - let b = box.clone().applyMatrix4(ro); - return !Boolean(ray.intersectBox(b, new Vector3())) - }); - } - if (spaces.length > 0) - { - let box = spaces[0]; - this.buildBoard(box, opt, ro); - } - } - else - { - app.m_Editor.m_CommandStore.Prompt("请选择有效的板件,或者周围没有效板件"); - } - - } - else if (ptRes.Status === PromptStatus.Keyword) - { - if (ptRes.StringResult === "S") - { - await this.SelectBoxes(opt); - break; - } - else if (ptRes.StringResult === "A") - { - //TODO:未完善功能 - await this.DrawInALlBoxes(opt); - break; - } - else if (ptRes.StringResult === "U") - { - break; - } - } - else - { - if (!store.isContinuous) - { - app.m_Editor.m_ModalManage.RenderBoardModal(store, type); - let state = await store.GetBoardOption(); - if (state !== ModalState.Ok) break; - } else break; - } - } - } - - /** - *获取鼠标点周围的板 - * @private - * @param {Vector3} mousePt - * @param {Viewer} view - * @param {Board[]} brs - * @memberof DrawLayerBoard - */ - private getPtSurroundBoardsByMouse(mousePt: Vector3, view: Viewer, brs: Board[]) - { - let { vMeshs, lMeshs } = this.getMeshs(view); - //获取上下左右的板 - const getBoard = (pt: Vector2, objs: Object3D[], type: string) => - { - let sl = new SelectLine(view, Vec3DTo2D(mousePt), pt); - sl.Select(objs); - this.selectSurroundBoard(sl.Enlity as Board[], type, brs) - } - - let leftPt = Vec3DTo2D(mousePt).setX(0); - getBoard(leftPt, vMeshs, "left"); - - let rightPt = Vec3DTo2D(mousePt).setX(view.Width); - getBoard(rightPt, vMeshs, "right"); - - let topPt = Vec3DTo2D(mousePt).setY(0); - getBoard(topPt, lMeshs, "top"); - - let bottomPt = Vec3DTo2D(mousePt).setY(view.Height); - getBoard(bottomPt, lMeshs, "bottom") - - } - private getPtSurroundBoardsByPick(en: { pickObj: Object3D, intersect: any }, view: Viewer, brs: Board[]) - { - let { vMeshs, lMeshs } = this.getMeshs(view); - let ro = new Matrix4().extractRotation(en.intersect.object.matrix); - let normal = en.intersect.face.normal.clone() as Vector3; - let leftDir = new Vector3().setX(normal.z); - let topDir = new Vector3().setY(normal.z) - - normal.applyMatrix4(ro); - leftDir.applyMatrix4(ro); - topDir.applyMatrix4(ro); - - let origin = en.intersect.point as Vector3; - let leftRay = new Raycaster(origin, leftDir); - let rightRay = new Raycaster(origin, leftDir.clone().negate()); - //原点往法向量方向偏移一点,保证相交 - let fuzzVec = normal.clone().multiplyScalar(1e-3); - let topRay = new Raycaster(origin.clone().add(fuzzVec), topDir); - let bottomRay = new Raycaster(origin.clone().add(fuzzVec), topDir.clone().negate()); - - const getBoard = (ray, meshs) => - { - let ints = ray.intersectObjects(meshs, false); - if (ints.length > 0) - { - brs.push(ints[0].object.userData) - } - } - getBoard(leftRay, vMeshs); - getBoard(rightRay, vMeshs); - getBoard(topRay, lMeshs); - getBoard(bottomRay, lMeshs); - - return { normal, origin }; - } - private getMeshs(view: Viewer) - { - let meshs = view.Scene.children.filter(o => o instanceof Mesh && o.userData && o.userData instanceof Board); - let vMeshs = meshs.filter(o => (o.userData).BoardType === BoardType.Vertical); - let lMeshs = meshs.filter(o => (o.userData).BoardType === BoardType.Layer); - return { vMeshs, lMeshs } - } - private selectSurroundBoard(ens: Board[], dir: string, brs: Board[]) - { - if (ens.length === 0) return; - - let boxMap: Map = new Map(); - ens.forEach(b => - { - let pt = b.MinPoint; - app.m_Viewer.WorldToScreen(pt); - boxMap.set(b, pt); - }) - - switch (dir) - { - case "left": - ens.sort((a, b) => boxMap.get(b).x - boxMap.get(a).x); - break; - case "right": - ens.sort((a, b) => boxMap.get(a).x - boxMap.get(b).x); - break; - case "top": - ens.sort((a, b) => boxMap.get(b).y - boxMap.get(a).y); - break; - case "bottom": - ens.sort((a, b) => boxMap.get(a).y - boxMap.get(b).y); - break; - } - - let en = ens[0]; - if (en && !brs.includes(en)) - { - brs.push(en) - } - } - private async SelectBoxes(opt: BoardOption) - { - let exSsRes = await app.m_Editor.GetSelection({ Msg: "请选择对象<全部选择>:", UseSelect: true }); - if (exSsRes.Status === PromptStatus.Cancel) - return; - let boardCus = exSsRes.SelectSet.SelectEntityList.filter(en => - en instanceof Board) as Board[]; - - if (boardCus.length > 0) - { - let spaceParse = new GeneralSpaceParse(boardCus); - await spaceParse.SpaceParse(); - - if (spaceParse.Spaces.length === 0) - { - app.m_Editor.m_CommandStore.Prompt("生成层板失败"); - return; - } - let ro = new Matrix4().extractRotation(spaceParse.OCS); - - let spaces = spaceParse.Spaces; - let box = await this.selectBox(spaces); - - this.buildBoard(box, opt, ro); - } - else - { - app.m_Editor.m_CommandStore.Prompt("请选择板件") - } - } - private async DrawInALlBoxes(opt: BoardOption) - { - let exSsRes = await app.m_Editor.GetSelection({ Msg: "请选择对象<全部选择>:", UseSelect: true }); - if (exSsRes.Status === PromptStatus.Cancel) - return; - let boardCus = exSsRes.SelectSet.SelectEntityList.filter(en => - en instanceof Board) as Board[]; - - if (boardCus.length > 0) - { - let spaceParse = new GeneralSpaceParse2(boardCus); - spaceParse.SpaceParse(); - - if (spaceParse.Spaces.length === 0) - { - app.m_Editor.m_CommandStore.Prompt("生成层板失败"); - return; - } - let ro = new Matrix4().extractRotation(spaceParse.OCS); - - let spaces = spaceParse.Spaces; - for (let box of spaces) - { - this.buildBoard(box, opt, ro); - } - } - else - { - app.m_Editor.m_CommandStore.Prompt("请选择板件") - } - } - - private pointPick(ptVcs: Vector3, view: Viewer) - { - let selectObjects = view.Scene.children; - - selectObjects = selectObjects.filter(o => o instanceof Mesh && o.userData && o.userData instanceof Board); - - let raycaster = new Raycaster(); - raycaster.setFromCamera({ - x: (ptVcs.x / view.Width) * 2 - 1, - y: - (ptVcs.y / view.Height) * 2 + 1 - }, view.Camera); - raycaster.ray.origin.sub(raycaster.ray.direction.clone().multiplyScalar(1e3)); - - let pickObj: Object3D; - let minDis: number; - let intersect; - for (let obj of selectObjects) - { - let intersects = []; - if (!obj.visible) continue; - obj.raycast(raycaster, intersects) - if (intersects.length > 0) - if (!minDis || minDis > intersects[0].distance) - { - pickObj = obj; - minDis = intersects[0].distance - intersect = intersects[0]; - } - } - return { pickObj, intersect }; - } - async selectBox(spaces: Box3Ext[]) - { - if (spaces.length === 1) - return spaces[0]; - - spaces.sort((b1, b2) => - { - if (equaln(b2.min.z, b1.min.z)) - { - return b1.min.y - b2.min.y; - } - return b1.min.z - b2.min.z - }); - - if (spaces.length > 2) - { - let keyWord = await app.m_Editor.GetKeyWords({ - Msg: "输入位置:", - KeyWordList: [{ key: "1", msg: "靠上" }, { key: "2", msg: "靠下" }] - }); - - if (keyWord.StringResult == "1") - { - spaces = spaces.splice(spaces.length / 2, spaces.length / 2) - } - else if (keyWord.StringResult == "2") - { - spaces = spaces.splice(0, spaces.length / 2) - } - - keyWord = await app.m_Editor.GetKeyWords({ - Msg: "输入位置:", - KeyWordList: [{ key: "3", msg: "靠前" }, { key: "4", msg: "靠后" }] - }); - if (keyWord.StringResult == "3") - { - spaces[0].min.y < spaces[1].min.y ? spaces.pop() : spaces.shift(); - } - else if (keyWord.StringResult == "4") - { - spaces[0].min.y > spaces[1].min.y ? spaces.pop() : spaces.shift(); - } - } - else - { - if (spaces[0].min.z === spaces[1].min.z) - { - let KeyWordList = [{ key: "3", msg: "靠前" }, { key: "4", msg: "靠后" }]; - let tmpPar1 = spaces[0].min.y; - let tmpPar2 = spaces[1].min.y; - - if (spaces[0].min.y === spaces[1].min.y) - { - KeyWordList = [{ key: "3", msg: "靠左" }, { key: "4", msg: "靠右" }]; - tmpPar1 = spaces[0].min.x; - tmpPar2 = spaces[1].min.x; - } - let keyWord = await app.m_Editor.GetKeyWords({ - Msg: "输入位置:", - KeyWordList - }); - if (keyWord.StringResult == "3") - { - tmpPar1 < tmpPar2 ? spaces.pop() : spaces.shift(); - } - else if (keyWord.StringResult == "4") - { - tmpPar1 > tmpPar2 ? spaces.pop() : spaces.shift(); - } - } - else - { - let keyWord = await app.m_Editor.GetKeyWords({ - Msg: "输入位置:", - KeyWordList: [{ key: "1", msg: "靠上" }, { key: "2", msg: "靠下" }] - }); - - if (keyWord.StringResult == "1") - { - spaces = spaces.splice(spaces.length / 2, spaces.length / 2) - } - else if (keyWord.StringResult == "2") - { - spaces = spaces.splice(0, spaces.length / 2) - } - } - } - return spaces[0]; - } - //构建板件 - protected buildBoard(box: Box3Ext, opt: BoardOption, ro: Matrix4) - { - + let store = SingleBoardStore.Store(); + app.m_Editor.m_ModalManage.RenderBoardModal(store, BoardModalType.Sg); } } diff --git a/src/Add-on/DrawBoard/DrawVerticalBoard.ts b/src/Add-on/DrawBoard/DrawVerticalBoard.ts index 23a24ab4c..72c0716d8 100644 --- a/src/Add-on/DrawBoard/DrawVerticalBoard.ts +++ b/src/Add-on/DrawBoard/DrawVerticalBoard.ts @@ -3,11 +3,11 @@ import { app } from '../../ApplicationServices/Application'; import { Board, BoardType } from '../../DatabaseServices/Board'; import { Box3Ext } from '../../Geometry/Box'; import { MoveMatrix } from '../../Geometry/GeUtils'; -import { DrawSingleBoard } from './DrawSingleBoard'; +import { DrawBoardTool } from './DrawBoardTool'; import { } from '../../UI/Store/BoardStore'; import { VerticalBoardOption, BoardRelativePositon } from '../../UI/Store/BoardInterface'; -export class DrawVerticalBoard extends DrawSingleBoard +export class DrawVerticalBoard extends DrawBoardTool { protected drawType = BoardType.Vertical; diff --git a/src/Editor/CommandRegister.ts b/src/Editor/CommandRegister.ts index 7ed0c69cd..1badada29 100644 --- a/src/Editor/CommandRegister.ts +++ b/src/Editor/CommandRegister.ts @@ -75,6 +75,7 @@ import { DrawTopBottomBoard } from '../Add-on/DrawBoard/DrawTopBottomBoard'; import { DrawBehindBoard } from '../Add-on/DrawBoard/DrawBehindBoard'; import { DrawLayerBoard } from '../Add-on/DrawBoard/DrawLayerBoard'; import { DrawVerticalBoard } from '../Add-on/DrawBoard/DrawVerticalBoard'; +import { DrawSingleBoard } from '../Add-on/DrawBoard/DrawSingleBoard'; export function registerCommand() { @@ -181,6 +182,7 @@ export function registerCommand() commandMachine.RegisterCommand("sub", new SubsractOperation()); commandMachine.RegisterCommand("pe", new Pedit()); commandMachine.RegisterCommand("join", new Command_Join()); + commandMachine.RegisterCommand("sw", new Sweep()); //画板件命令 commandMachine.RegisterCommand("zyc", new DrawLeftRight()); @@ -188,7 +190,7 @@ export function registerCommand() commandMachine.RegisterCommand("bb", new DrawBehindBoard()); commandMachine.RegisterCommand("cb", new DrawLayerBoard()); commandMachine.RegisterCommand("lb", new DrawVerticalBoard()); - commandMachine.RegisterCommand("sw", new Sweep()); + commandMachine.RegisterCommand("mb", new DrawSingleBoard()); /*******test ↓↓↓*********/ diff --git a/src/Editor/SnapDragServices.ts b/src/Editor/SnapDragServices.ts index 3e9b077c1..fa515aa8e 100644 --- a/src/Editor/SnapDragServices.ts +++ b/src/Editor/SnapDragServices.ts @@ -6,7 +6,7 @@ import { MouseKey } from '../Common/KeyEnum'; import { CADFile } from '../DatabaseServices/CADFile'; import { Entity } from '../DatabaseServices/Entity'; import { MoveMatrix } from '../Geometry/GeUtils'; -import { InputState } from './../Common/InputState'; +import { InputState } from '../Common/InputState'; import { commandMachine } from './CommandMachine'; import { Editor, EditorService } from './Editor'; import { MouseControls } from './MouseControls'; diff --git a/src/UI/Components/Board/BehindBoardModal.tsx b/src/UI/Components/Board/BehindBoardModal.tsx index e9e22cfb9..f81be745c 100644 --- a/src/UI/Components/Board/BehindBoardModal.tsx +++ b/src/UI/Components/Board/BehindBoardModal.tsx @@ -1,7 +1,7 @@ import { observer } from 'mobx-react'; import * as React from 'react'; -import { Classes, Radio, RadioGroup } from '../../../../node_modules/@blueprintjs/core'; -import { observable } from '../../../../node_modules/mobx'; +import { Classes, Radio, RadioGroup } from '@blueprintjs/core'; +import { observable } from 'mobx'; import { BehindHeightPositon, BoardRelativePositon } from '../../Store/BoardInterface'; import { BehindBoardStore } from '../../Store/BoardStore'; import { BoardConfigBlock, BoardModel, SetBoardDataBlock, SetBoardDataItem, SetBoardDataItem2 } from './BoardCommon'; diff --git a/src/UI/Components/Board/BoardCommon.tsx b/src/UI/Components/Board/BoardCommon.tsx index a84a40cdb..4a8ad424b 100644 --- a/src/UI/Components/Board/BoardCommon.tsx +++ b/src/UI/Components/Board/BoardCommon.tsx @@ -1,6 +1,6 @@ import { observer } from 'mobx-react'; import * as React from 'react'; -import { Checkbox, Classes, Radio, RadioGroup } from '../../../../node_modules/@blueprintjs/core'; +import { Checkbox, Classes, Radio, RadioGroup } from '@blueprintjs/core'; import { BoardRelativePositon, BoardOption, TBBoardOption } from '../../Store/BoardInterface'; //设置板件数据组件 diff --git a/src/UI/Components/Board/BoardModal.tsx b/src/UI/Components/Board/BoardModal.tsx index 1cd373fdd..2d3723458 100644 --- a/src/UI/Components/Board/BoardModal.tsx +++ b/src/UI/Components/Board/BoardModal.tsx @@ -1,6 +1,6 @@ import { Button, Checkbox, InputGroup, Menu, MenuItem, Popover } from '@blueprintjs/core'; import * as React from 'react'; -import { inject, observer } from '../../../../node_modules/mobx-react'; +import { inject, observer } from 'mobx-react'; import { KeyBoard } from '../../../Common/KeyEnum'; import { IndexedDbStore, StoreName } from '../../../IndexedDb/IndexedDbStore'; import { BoardOption, LayerNailOption, ModalState, TBBoardOption } from '../../Store/BoardInterface'; @@ -11,6 +11,7 @@ import { LayerBoardModal } from './LayerBoardModal'; import { LeftRightBoardModal } from './leftRightBoardModal'; import { TopBottomBoardModal } from './TopBottomBoardModal'; import { VerticalBoardModal } from './VerticalBoardModal'; +import { SingleBoardModal } from './SingleBoardModal'; export enum BoardModalType { @@ -18,7 +19,8 @@ export enum BoardModalType TB = "tb",//顶底板 Be = "be",//背板 Ly = "ly",//层板 - Ve = "ve"//立板 + Ve = "ve",//立板 + Sg = "sg",//单板 } interface BoardModalProps @@ -64,6 +66,7 @@ export class BoardModal extends React.Component], [BoardModalType.Ly, ], [BoardModalType.Ve, ], + [BoardModalType.Sg, ] ]) this.state = { configName: "默认", diff --git a/src/UI/Components/Board/SingleBoardModal.tsx b/src/UI/Components/Board/SingleBoardModal.tsx new file mode 100644 index 000000000..231cf49c4 --- /dev/null +++ b/src/UI/Components/Board/SingleBoardModal.tsx @@ -0,0 +1,23 @@ +import { observer } from "../../../../node_modules/mobx-react"; +import * as React from 'react'; +import { SingleBoardStore } from "../../Store/BoardStore"; + +export const SingleBoardModal = + (observer((props: { store?: SingleBoardStore }) => + { + let pars = new Map([["height", "柜高"], ["width", "柜深"], ["thickness", "板厚"], ["spaceSize", "总宽"]]); + return ( +
+ +
+ ) + })); diff --git a/src/UI/Store/BoardInterface.ts b/src/UI/Store/BoardInterface.ts index 6fb43573a..b0112371b 100644 --- a/src/UI/Store/BoardInterface.ts +++ b/src/UI/Store/BoardInterface.ts @@ -139,3 +139,13 @@ export interface TBBoardOption extends BoardOption offset: string, footThickness: string } +export interface SingleBoardOption extends BoardOption +{ + rotateX: string, + rotateY: string, + rotateZ: string, + SpliteHeight: string, + SpliteWidth: string, + SpliteThickness: string + +} diff --git a/src/UI/Store/BoardStore.ts b/src/UI/Store/BoardStore.ts index 748f557c6..2453a9c9d 100644 --- a/src/UI/Store/BoardStore.ts +++ b/src/UI/Store/BoardStore.ts @@ -3,7 +3,7 @@ import { observable } from 'mobx'; import { app } from '../../ApplicationServices/Application'; import * as xaop from 'xaop'; import { KeyBoard } from '../../Common/KeyEnum'; -import { ModalState, BoardOption, BehindBoardOption, BehindHeightPositon, BoardRelativePositon, LayerBoardOption, LayerNailOption, VerticalBoardOption, TBBoardOption } from './BoardInterface'; +import { ModalState, BoardOption, BehindBoardOption, BehindHeightPositon, BoardRelativePositon, LayerBoardOption, LayerNailOption, VerticalBoardOption, TBBoardOption, SingleBoardOption } from './BoardInterface'; export class BoardStore { @@ -189,3 +189,25 @@ export class VerticalBoardStore extends BoardStore return this._store; } } +export class SingleBoardStore extends BoardStore +{ + title = ""; + @observable name = "单板"; + @observable m_BoardOption: SingleBoardOption = { + height: "1200", + width: "600", + thickness: "18", + rotateX: "0", + rotateY: "0", + rotateZ: "0", + SpliteHeight: "", + SpliteWidth: "", + SpliteThickness: "" + } + private static _store: SingleBoardStore; + static Store() + { + if (!this._store) this._store = new SingleBoardStore(); + return this._store; + } +}