diff --git a/src/Add-on/DrawBoard/DrawDoorDrawer/DrawDoorDrawerTool.ts b/src/Add-on/DrawBoard/DrawDoorDrawer/DrawDoorDrawerTool.ts index 1ba0ad386..621ebc295 100644 --- a/src/Add-on/DrawBoard/DrawDoorDrawer/DrawDoorDrawerTool.ts +++ b/src/Add-on/DrawBoard/DrawDoorDrawer/DrawDoorDrawerTool.ts @@ -1,5 +1,6 @@ +import { Intent } from "@blueprintjs/core"; import { toJS } from "mobx"; -import { Vector3 } from "three"; +import { Box3, Matrix4, Vector3 } from "three"; import { app } from "../../../ApplicationServices/Application"; import { EBoardKeyList } from "../../../Common/BoardKeyList"; import { DuplicateRecordCloning } from "../../../Common/Status"; @@ -15,12 +16,16 @@ import { TemplateRecord } from "../../../DatabaseServices/Template/TemplateRecor import { Box3Ext } from "../../../Geometry/Box"; import { equaln, isParallelTo } from "../../../Geometry/GeUtils"; import { ISpaceParse } from "../../../Geometry/SpaceParse/ISpaceParse"; +import { AppToaster } from "../../../UI/Components/Toaster"; import { BoardOpenDir, BoardProcessOption, BoardType, DrillType } from "../../../UI/Store/BoardInterface"; import { DoorStore, openDirTitle } from "../../../UI/Store/DoorDrawerStore/DoorStore"; import { DisableChangeParName, DoorOpenDir, HandleHorPos, HandleVePos, IDoorConfigOption, IDoorInfo } from "../../../UI/Store/DoorInterface"; import { ITemplateParam } from "../../../UI/Store/RightPanelStore/TemplateParamPanelStore"; +import { IsDoor, IsHandle, IsHinge } from "../../HideSelect/HideSelectUtils"; import { Entity } from './../../../DatabaseServices/Entity/Entity'; +const MoveNum = 8; + export class DrawDoorTool { /**id模板对应表*/ @@ -438,13 +443,35 @@ export class DrawDoorTool { let brs: Board[] = []; let comEntitys: HardwareCompositeEntity[] = []; + let doors: Entity[] = []; + let layers: Entity[] = []; + let HCEBoard: Entity[] = []; for (let en of allEntitys) { if (en instanceof Board) + { brs.push(en); + if (en.BoardType === BoardType.Layer) + layers.push(en); + } else if (en instanceof HardwareCompositeEntity) - comEntitys.push(en); + { + if (IsHinge(en)) + comEntitys.push(en); + if (!IsHinge(en) && !IsHandle(en) && !IsDoor(en)) + { + layers.push(en); + HCEBoard.push(en); + } + } + if (IsDoor(en)) + doors.push(en); } + let ocs = doors[0].SpaceOCSInv; + let doorBox: Box3 = doors[0].GetBoundingBoxInMtx(ocs); + + for (let i = 1; i < doors.length; i++) + doorBox.union(doors[i].GetBoundingBoxInMtx(ocs)); //获取门板空间 let brBoxCache: WeakMap = new WeakMap(); @@ -454,59 +481,110 @@ export class DrawDoorTool let outlinesCache = new WeakMap(); + let moveFail = false; + for (let en of comEntitys) { let enBox = en.BoundingBox; - for (let br of brs) + for (let board of [...brs, ...HCEBoard]) { - let brBox = brBoxCache.get(br); - if (!brBox) - { - brBox = br.BoundingBox; - brBoxCache.set(br, brBox); - } - - //五金是否和挖孔造型有碰撞 #I2DPFO - let grooveOutlines = outlinesCache.get(br); - if (!grooveOutlines) + if (board instanceof Board) { - const grooves = br.Grooves.filter(g => equaln(g.Thickness, br.Thickness)); - grooveOutlines = grooves.map(g => g.ContourCurve.Clone().ApplyMatrix(g.OCS).ApplyMatrix(br.OCSInv).Z0()); - outlinesCache.set(br, grooveOutlines); - } + let br = board as Board; + let brBox = brBoxCache.get(br); + if (!brBox) + { + brBox = br.BoundingBox; + brBoxCache.set(br, brBox); + } - if (brBox.clone().intersect(enBox).isSolid()) - { - const center = enBox.getCenter(new Vector3).applyMatrix4(br.OCSInv).setZ(0); - if (grooveOutlines.some(c => c.PtInCurve(center))) - continue; + //五金是否和挖孔造型有碰撞 #I2DPFO + let grooveOutlines = outlinesCache.get(br); + if (!grooveOutlines) + { + const grooves = br.Grooves.filter(g => equaln(g.Thickness, br.Thickness)); + grooveOutlines = grooves.map(g => g.ContourCurve.Clone().ApplyMatrix(g.OCS).ApplyMatrix(br.OCSInv).Z0()); + outlinesCache.set(br, grooveOutlines); + } - if (this.hingeSet.has(en.Id)) + if (brBox.clone().intersect(enBox).isSolid()) { - let x = new Vector3().setFromMatrixColumn(en.OCS, 0); - if (isParallelTo(x, br.Normal)) + const center = enBox.getCenter(new Vector3).applyMatrix4(br.OCSInv).setZ(0); + if (grooveOutlines.some(c => c.PtInCurve(center))) + continue; + + if (this.hingeSet.has(en.Id)) { - if (!usedHinge.has(en.Id)) + let x = new Vector3().setFromMatrixColumn(en.OCS, 0); + if (isParallelTo(x, br.Normal)) { - usedHinge.add(en.Id); - this.SetHingeType(br, en); + if (!usedHinge.has(en.Id)) + { + usedHinge.add(en.Id); + this.SetHingeType(br, en); + } + } + else if (isParallelTo(en.Normal, br.Normal)) + { + let hingeTemp = en.Template.Object as TemplateRecord; + let hingeSpace = hingeTemp.Parent.Object as TemplateRecord; + let size = enBox.getSize(new Vector3); + + let enBoxMtx = en.GetBoundingBoxInMtx(ocs); + + let distance = Math.max(size.x, size.z) / 2; + let doorHight = doorBox.getSize(new Vector3).z; + let number = 1; + number = this.GetHingeMoveNum(doorHight, enBoxMtx, layers, distance, ocs, number); + if (number === 0) + { + moveFail = true; + en.Erase(); + continue; + } + hingeSpace.GetParam("SY").value = distance * number; //超出情况往下偏移 + needUpdate = true; + continue; } } - else if (isParallelTo(en.Normal, br.Normal)) - { - let hingeTemp = en.Template.Object as TemplateRecord; - let hingeSpace = hingeTemp.Parent.Object as TemplateRecord; - let size = enBox.getSize(new Vector3); - hingeSpace.GetParam("SY").value = Math.max(size.x, size.z); - needUpdate = true; - continue; - } + br.RelativeHardware.push(en.Id); + en.RelevanceBoards.push(br.Id); } - br.RelativeHardware.push(en.Id); - en.RelevanceBoards.push(br.Id); + } + else if (board instanceof HardwareCompositeEntity) //复合实体 + { + let brBox = board.BoundingBox; + if (!brBox.intersectsBox(enBox)) continue; + + let hingeTemp = en.Template.Object as TemplateRecord; + let hingeSpace = hingeTemp.Parent.Object as TemplateRecord; + let size = enBox.getSize(new Vector3); + + let enBoxMtx = en.GetBoundingBoxInMtx(ocs); + + let distance = Math.max(size.x, size.z) / 2; + let doorHight = doorBox.getSize(new Vector3).z; + let number = 1; + number = this.GetHingeMoveNum(doorHight, enBoxMtx, layers, distance, ocs, number); + if (number === 0) + { + moveFail = true; + en.Erase(); + continue; + } + hingeSpace.GetParam("SY").value = distance * number; //超出情况往下偏移 + needUpdate = true; + continue; } } } + if (moveFail) + AppToaster.show({ + message: "部分铰链偏移未找到合适位置,自动删除", + timeout: 5000, + intent: Intent.WARNING, + }); + this.hingeSet.forEach(e => { if (!usedHinge.has(e)) @@ -531,14 +609,14 @@ export class DrawDoorTool { let box = this.spaceParse.SpaceBox.clone(); let spaceBoardSet = new Set(this.spaceParse.Boards); - let allBoards = app.Database.ModelSpace.Entitys.filter(e => !e.IsErase && e instanceof Board) as Board[]; + let allBoards = app.Database.ModelSpace.Entitys.filter(e => !e.IsErase && (e instanceof Board || e instanceof HardwareCompositeEntity)) as Entity[]; for (let br of allBoards) { - if (spaceBoardSet.has(br)) continue; + if (spaceBoardSet.has(br as Board)) continue; let b = br.BoundingBox.applyMatrix4(this.spaceParse.SpaceOCSInv); if (b.intersectsBox(box)) { - spaceBoardSet.add(br); + spaceBoardSet.add(br as Board); } } return [...spaceBoardSet]; @@ -648,4 +726,78 @@ export class DrawDoorTool return BoardOpenDir.None; } } + + + /** + *上下偏移判断位置是否超出门板 或与其他层板碰撞 上下上下尝试n个单位后停止 + * + * @private + * @param {number} doorHight 门板高度 + * @param {Box3} enBox 铰链空间box + * @param {Entity[]} layers 所有层板 + * @param {number} distance 一次偏移量 + * @param {Matrix4} ocs + * @param {number} number 偏移次数 正负表方向 上下 + * @return {*} {number} + * @memberof DrawDoorTool + */ + private GetHingeMoveNum(doorHight: number, enBox: Box3, layers: Entity[], distance: number, ocs: Matrix4, number: number): number + { + let box1 = enBox.clone(); + box1.translate(new Vector3(0, 0, distance * number)); + let box1Z = box1.getCenter(new Vector3).z; + + if (box1Z + 100 < doorHight) + { + if (!this.IsIntersects(box1, layers, ocs)) + return number; + else + return this.MoveAgain(doorHight, enBox, layers, distance, ocs, number); + } + else + return this.MoveAgain(doorHight, enBox, layers, distance, ocs, number); + } + + private MoveAgain(doorHight: number, enBox: Box3, layers: Entity[], distance: number, ocs: Matrix4, number: number): number + { + let box2 = enBox.clone(); + box2.translate(new Vector3(0, 0, distance * -number)); + let box2Z = box2.getCenter(new Vector3).z; + if (box2Z - 100 > 0) + { + if (!this.IsIntersects(box2, layers, ocs)) + return -number; + else + { + if (number === MoveNum) + + return 0; + else + { + number++; + return this.GetHingeMoveNum(doorHight, enBox, layers, distance, ocs, number); + } + } + } + else + { + if (number === MoveNum) + return 0; + else + { + number++; + return this.GetHingeMoveNum(doorHight, enBox, layers, distance, ocs, number); + } + } + } + private IsIntersects(enBox: Box3, layers: Entity[], ocs: Matrix4): boolean + { + for (let en of layers) + { + let box = en.GetBoundingBoxInMtx(ocs); + if (box.intersectsBox(enBox, 10)) + return true; + } + return false; + } }