|
|
|
@ -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<Board, Box3Ext> = new WeakMap();
|
|
|
|
|
|
|
|
|
@ -454,59 +481,110 @@ export class DrawDoorTool
|
|
|
|
|
|
|
|
|
|
let outlinesCache = new WeakMap<Board, ExtureContourCurve[]>();
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|