|
|
|
@ -3,12 +3,15 @@ import { toJS } from "mobx";
|
|
|
|
|
import { Box3, Matrix4, Vector3 } from "three";
|
|
|
|
|
import { app } from "../../../ApplicationServices/Application";
|
|
|
|
|
import { EBoardKeyList } from "../../../Common/BoardKeyList";
|
|
|
|
|
import { Solid3D } from "../../../Common/InterfereUtil";
|
|
|
|
|
import { DuplicateRecordCloning } from "../../../Common/Status";
|
|
|
|
|
import { ExtrudeHole } from "../../../DatabaseServices/3DSolid/ExtrudeHole";
|
|
|
|
|
import { SweepSolid } from "../../../DatabaseServices/3DSolid/SweepSolid";
|
|
|
|
|
import { CADObject } from "../../../DatabaseServices/CADObject";
|
|
|
|
|
import { Board } from "../../../DatabaseServices/Entity/Board";
|
|
|
|
|
import { BoardOpenDir, BoardType } from "../../../DatabaseServices/Entity/BoardInterface";
|
|
|
|
|
import { Entity } from '../../../DatabaseServices/Entity/Entity';
|
|
|
|
|
import { ExtrudeContourCurve } from "../../../DatabaseServices/Entity/Extrude";
|
|
|
|
|
import { ExtrudeContourCurve, ExtrudeSolid } from "../../../DatabaseServices/Entity/Extrude";
|
|
|
|
|
import { HardwareCompositeEntity } from "../../../DatabaseServices/Hardware/HardwareCompositeEntity";
|
|
|
|
|
import { ObjectId } from "../../../DatabaseServices/ObjectId";
|
|
|
|
|
import { TemplateParam } from "../../../DatabaseServices/Template/Param/TemplateParam";
|
|
|
|
@ -18,6 +21,7 @@ import { GetOnlineTemplate } from "../../../DatabaseServices/Template/TempateUti
|
|
|
|
|
import { TemplateRecord } from "../../../DatabaseServices/Template/TemplateRecord";
|
|
|
|
|
import { Box3Ext } from "../../../Geometry/Box";
|
|
|
|
|
import { equaln, isParallelTo } from "../../../Geometry/GeUtils";
|
|
|
|
|
import { OBB } from "../../../Geometry/OBB/obb";
|
|
|
|
|
import { ISpaceParse } from "../../../Geometry/SpaceParse/ISpaceParse";
|
|
|
|
|
import { AppToaster } from "../../../UI/Components/Toaster";
|
|
|
|
|
import { DoorStore, IHingeRule, openDirTitle } from "../../../UI/Store/DoorDrawerStore/DoorStore";
|
|
|
|
@ -35,9 +39,6 @@ import { IsDoor, IsHandle, IsHinge } from "../../HideSelect/HideSelectUtils";
|
|
|
|
|
* */
|
|
|
|
|
const MoveNum: number = 8;
|
|
|
|
|
|
|
|
|
|
//绘制出的铰链与层板(左右开门时)或立板(上下开门时)最低间距 或偏移后最低间距
|
|
|
|
|
export const BoxIntersectFuzz: number = 5;
|
|
|
|
|
|
|
|
|
|
export class DrawDoorTool
|
|
|
|
|
{
|
|
|
|
|
/**id模板对应表*/
|
|
|
|
@ -615,6 +616,9 @@ export class DrawDoorTool
|
|
|
|
|
let ironBox = ironware.BoundingBox;//box
|
|
|
|
|
let ironBoxInDoorSpace = ironware.GetBoundingBoxInMtx(scsInv);//box in door scs
|
|
|
|
|
|
|
|
|
|
const xNormal = new Vector3().setFromMatrixColumn(ironware.OCSNoClone, 0);
|
|
|
|
|
const ZNormal = new Vector3().setFromMatrixColumn(ironware.OCSNoClone, 2);
|
|
|
|
|
|
|
|
|
|
for (let otherEnt of allOtherEntitys)
|
|
|
|
|
{
|
|
|
|
|
const isDoor = IsDoor(otherEnt);
|
|
|
|
@ -638,11 +642,8 @@ export class DrawDoorTool
|
|
|
|
|
br2GrooveOutlinesCache.set(br, grooveOutlines);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const xNormal = new Vector3().setFromMatrixColumn(ironware.OCSNoClone, 0);
|
|
|
|
|
const isParallelToX = isParallelTo(xNormal, br.Normal);
|
|
|
|
|
|
|
|
|
|
//门板/背板 不增加误差,防止误关联
|
|
|
|
|
if (IsBoxAndEntitysIntersect(brBox, [ironware], BoxIntersectFuzz, undefined, isDoor || (behindBoards.includes(br) && !isParallelToX)))
|
|
|
|
|
//铰链Z轴延伸 与其他实体相交判断
|
|
|
|
|
if (IsBoxAndEntitysIntersect([br], [ironware], ZNormal))
|
|
|
|
|
{
|
|
|
|
|
const center = ironBox.getCenter(new Vector3).applyMatrix4(br.OCSInv).setZ(0);
|
|
|
|
|
if (grooveOutlines.some(c => c.PtInCurve(center)))//五金的中心在造型内部
|
|
|
|
@ -651,7 +652,7 @@ export class DrawDoorTool
|
|
|
|
|
//铰链避让
|
|
|
|
|
if (this.hingeSet.has(ironware.Id))//如果是铰链
|
|
|
|
|
{
|
|
|
|
|
if (isParallelToX)
|
|
|
|
|
if (isParallelTo(xNormal, br.Normal))
|
|
|
|
|
{
|
|
|
|
|
if (!parseTypedHinges.has(ironware.Id))
|
|
|
|
|
{
|
|
|
|
@ -660,7 +661,7 @@ export class DrawDoorTool
|
|
|
|
|
SetHingeType(br, ironware);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (isParallelTo(ironware.Normal, br.Normal) || !isDoor) //不是门板也判断碰撞
|
|
|
|
|
else if (isParallelTo(ironware.Normal, br.Normal) || !isDoor)
|
|
|
|
|
{
|
|
|
|
|
let deviationNum = 1; //偏移次数
|
|
|
|
|
let hingeTr = ironware.Template.Object as TemplateRecord;
|
|
|
|
@ -670,12 +671,12 @@ export class DrawDoorTool
|
|
|
|
|
if (isUpDownDoor)
|
|
|
|
|
{
|
|
|
|
|
if (RecordHingeTrSizeX(hingeTr2Size_Map, hingeTr, size.x)) continue;
|
|
|
|
|
deviationNum = this.GetHingeMoveNum(doorWidth, ironBoxInDoorSpace, ironBox, ironware, verticalBoards, this.option.deviation, deviationNum, isUpDownDoor, behindBoards);
|
|
|
|
|
deviationNum = this.GetHingeMoveNum(doorWidth, ironBoxInDoorSpace, ironBox, ironware, verticalBoards, this.option.deviation, deviationNum, isUpDownDoor, ZNormal);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (RecordHingeTrSizeX(hingeTr2Size_Map, hingeTr, size.z)) continue;
|
|
|
|
|
deviationNum = this.GetHingeMoveNum(doorHight, ironBoxInDoorSpace, ironBox, ironware, layerBoards, this.option.deviation, deviationNum, isUpDownDoor, behindBoards);
|
|
|
|
|
deviationNum = this.GetHingeMoveNum(doorHight, ironBoxInDoorSpace, ironBox, ironware, layerBoards, this.option.deviation, deviationNum, isUpDownDoor, ZNormal);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (deviationNum === 0)
|
|
|
|
@ -697,7 +698,7 @@ export class DrawDoorTool
|
|
|
|
|
{
|
|
|
|
|
if (!IsHinge(ironware)) continue;
|
|
|
|
|
|
|
|
|
|
if (!IsBoxAndEntitysIntersect(ironBox, [otherEnt], BoxIntersectFuzz, undefined, isDoor)) continue;
|
|
|
|
|
if (!IsBoxAndEntitysIntersect([otherEnt], [ironware], ZNormal)) continue;
|
|
|
|
|
if (isDoor)
|
|
|
|
|
{
|
|
|
|
|
//铰链归属复合门板
|
|
|
|
@ -715,13 +716,13 @@ export class DrawDoorTool
|
|
|
|
|
{
|
|
|
|
|
let doorWidth = doorBox.getSize(new Vector3).x;
|
|
|
|
|
if (RecordHingeTrSizeX(hingeTr2Size_Map, hingeTr, ironSize.x)) continue;
|
|
|
|
|
deviationNum = this.GetHingeMoveNum(doorWidth, ironBoxInDoorSpace, ironBox, ironware, verticalBoards, this.option.deviation, deviationNum, isUpDownDoor, behindBoards);
|
|
|
|
|
deviationNum = this.GetHingeMoveNum(doorWidth, ironBoxInDoorSpace, ironBox, ironware, verticalBoards, this.option.deviation, deviationNum, isUpDownDoor, ZNormal);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
let doorHight = doorBox.getSize(new Vector3).z;
|
|
|
|
|
if (RecordHingeTrSizeX(hingeTr2Size_Map, hingeTr, ironSize.z)) continue;
|
|
|
|
|
deviationNum = this.GetHingeMoveNum(doorHight, ironBoxInDoorSpace, ironBox, ironware, layerBoards, this.option.deviation, deviationNum, isUpDownDoor, behindBoards);
|
|
|
|
|
deviationNum = this.GetHingeMoveNum(doorHight, ironBoxInDoorSpace, ironBox, ironware, layerBoards, this.option.deviation, deviationNum, isUpDownDoor, ZNormal);
|
|
|
|
|
}
|
|
|
|
|
if (deviationNum === 0)
|
|
|
|
|
{
|
|
|
|
@ -909,7 +910,7 @@ export class DrawDoorTool
|
|
|
|
|
* @return {*} {number}
|
|
|
|
|
* @memberof DrawDoorTool
|
|
|
|
|
*/
|
|
|
|
|
private GetHingeMoveNum(doorSpecs: number, inventedBox: Box3, realityBox: Box3, ironware: Entity, checkEnts: Entity[], distance: number, deviationNum: number, isUpDownDoor: boolean, behindBoards: Entity[]): number
|
|
|
|
|
private GetHingeMoveNum(doorSpecs: number, inventedBox: Box3, realityBox: Box3, ironware: Entity, checkEnts: Entity[], distance: number, deviationNum: number, isUpDownDoor: boolean, ZNormal: Vector3): number
|
|
|
|
|
{
|
|
|
|
|
let box1 = inventedBox.clone();
|
|
|
|
|
let box1Info: number;
|
|
|
|
@ -932,14 +933,8 @@ export class DrawDoorTool
|
|
|
|
|
let intersect = false;
|
|
|
|
|
if (box1Info + (isUpDownDoor ? 10 : 100) < doorSpecs)
|
|
|
|
|
{
|
|
|
|
|
for (let ent of checkEnts)
|
|
|
|
|
{
|
|
|
|
|
if (IsBoxAndEntitysIntersect(ent.BoundingBox, [ironware], BoxIntersectFuzz, undefined, behindBoards.includes(ent), translate))
|
|
|
|
|
{
|
|
|
|
|
intersect = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (IsBoxAndEntitysIntersect(checkEnts, [ironware], ZNormal, translate))
|
|
|
|
|
intersect = true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
intersect = true;
|
|
|
|
@ -947,10 +942,10 @@ export class DrawDoorTool
|
|
|
|
|
if (!intersect)
|
|
|
|
|
return deviationNum;
|
|
|
|
|
else
|
|
|
|
|
return this.MoveAgain(doorSpecs, inventedBox, realityBox, ironware, checkEnts, distance, deviationNum, isUpDownDoor, behindBoards);
|
|
|
|
|
return this.MoveAgain(doorSpecs, inventedBox, realityBox, ironware, checkEnts, distance, deviationNum, isUpDownDoor, ZNormal);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private MoveAgain(doorSpecs: number, inventedBox: Box3, realityBox: Box3, ironware: Entity, checkEnts: Entity[], distance: number, deviationNum: number, isUpDownDoor: boolean, behindBoards: Entity[]): number
|
|
|
|
|
private MoveAgain(doorSpecs: number, inventedBox: Box3, realityBox: Box3, ironware: Entity, checkEnts: Entity[], distance: number, deviationNum: number, isUpDownDoor: boolean, ZNormal: Vector3): number
|
|
|
|
|
{
|
|
|
|
|
let box2 = inventedBox.clone();
|
|
|
|
|
let box2Info: number;
|
|
|
|
@ -972,14 +967,8 @@ export class DrawDoorTool
|
|
|
|
|
let intersect = false;
|
|
|
|
|
if (box2Info - (isUpDownDoor ? 10 : 100) > 0)
|
|
|
|
|
{
|
|
|
|
|
for (let ent of checkEnts)
|
|
|
|
|
{
|
|
|
|
|
if (IsBoxAndEntitysIntersect(ent.BoundingBox, [ironware], BoxIntersectFuzz, undefined, behindBoards.includes(ent), translate))
|
|
|
|
|
{
|
|
|
|
|
intersect = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (IsBoxAndEntitysIntersect(checkEnts, [ironware], ZNormal, translate))
|
|
|
|
|
intersect = true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
intersect = true;
|
|
|
|
@ -993,7 +982,7 @@ export class DrawDoorTool
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
deviationNum++;
|
|
|
|
|
return this.GetHingeMoveNum(doorSpecs, inventedBox, realityBox, ironware, checkEnts, distance, deviationNum, isUpDownDoor, behindBoards);
|
|
|
|
|
return this.GetHingeMoveNum(doorSpecs, inventedBox, realityBox, ironware, checkEnts, distance, deviationNum, isUpDownDoor, ZNormal);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -1041,44 +1030,83 @@ export function SetHingeType(br: Board, ironware: HardwareCompositeEntity): void
|
|
|
|
|
ironware.HardwareOption.name = "半盖铰链";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//OBB增加10容差
|
|
|
|
|
export function getFuzzOBB(obb: OBB, normalizeZ: Vector3, isParallel: boolean, parentIntersectEntOCS: Matrix4, isExtrudeSolid: boolean): OBB
|
|
|
|
|
{
|
|
|
|
|
let addSize = isParallel ? new Vector3(0, 0, 10) : new Vector3(-0.1, -0.1, 10);
|
|
|
|
|
if (!isExtrudeSolid)
|
|
|
|
|
addSize.applyMatrix4(parentIntersectEntOCS.clone().setPosition(0, 0, 0));
|
|
|
|
|
let halfSizes = obb.halfSizes.add(addSize.applyMatrix4((obb.ocs).clone().setPosition(0, 0, 0)));
|
|
|
|
|
let ocs = obb.ocs.clone();
|
|
|
|
|
let vz = normalizeZ.clone().multiplyScalar(10);
|
|
|
|
|
|
|
|
|
|
if (!isParallel)
|
|
|
|
|
{
|
|
|
|
|
const XNormal = new Vector3().setFromMatrixColumn(ocs, 0).multiplyScalar(0.1);
|
|
|
|
|
const YNormal = new Vector3().setFromMatrixColumn(ocs, 1).multiplyScalar(0.1);
|
|
|
|
|
const ZNormal = new Vector3().setFromMatrixColumn(ocs, 2).multiplyScalar(0.1);
|
|
|
|
|
ocs.elements[12] += XNormal.x;
|
|
|
|
|
ocs.elements[13] += XNormal.y;
|
|
|
|
|
ocs.elements[14] += XNormal.z;
|
|
|
|
|
ocs.elements[12] += YNormal.x;
|
|
|
|
|
ocs.elements[13] += YNormal.y;
|
|
|
|
|
ocs.elements[14] += YNormal.z;
|
|
|
|
|
ocs.elements[12] += ZNormal.x;
|
|
|
|
|
ocs.elements[13] += ZNormal.y;
|
|
|
|
|
ocs.elements[14] += ZNormal.z;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ocs.elements[12] -= Math.abs(vz.x);
|
|
|
|
|
ocs.elements[13] -= Math.abs(vz.y);
|
|
|
|
|
ocs.elements[14] -= Math.abs(vz.z);
|
|
|
|
|
|
|
|
|
|
return new OBB(ocs, halfSizes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param enBox 实体的世界坐标系盒子
|
|
|
|
|
* @param checkEnts 校验的实体列表
|
|
|
|
|
* @param intersectEnts 这里规定是铰链列表
|
|
|
|
|
* @param parentOCS 父空间的坐标系
|
|
|
|
|
* @param ZNormal 铰链Z向量方向
|
|
|
|
|
* @param translate checkEnts偏移
|
|
|
|
|
*/
|
|
|
|
|
export function IsBoxAndEntitysIntersect(enBox: Box3, checkEnts: Entity[], fuzz?: number, parentOCS?: Matrix4, isDoor?: boolean, translate?: Vector3): boolean
|
|
|
|
|
export function IsBoxAndEntitysIntersect(checkEnts: Entity[], intersectEnts: Entity[], ZNormal: Vector3, translate?: Vector3, parentIntersectEntOCS?: Matrix4, parentcheckEntOCS?: Matrix4, isParallel?: boolean): boolean
|
|
|
|
|
{
|
|
|
|
|
for (let checkEnt of checkEnts)
|
|
|
|
|
{
|
|
|
|
|
if (checkEnt instanceof HardwareCompositeEntity)
|
|
|
|
|
{
|
|
|
|
|
let ocs = checkEnt.OCSNoClone;
|
|
|
|
|
if (parentOCS) ocs = new Matrix4().multiplyMatrices(parentOCS, ocs);
|
|
|
|
|
let ocs = checkEnt.OCS;
|
|
|
|
|
if (parentcheckEntOCS) ocs = new Matrix4().multiplyMatrices(parentcheckEntOCS, ocs);
|
|
|
|
|
let ents = checkEnt.Entitys.filter(ent => ent instanceof ExtrudeHole || ent instanceof SweepSolid || ent instanceof ExtrudeSolid || ent instanceof HardwareCompositeEntity);
|
|
|
|
|
|
|
|
|
|
if (IsBoxAndEntitysIntersect(enBox, checkEnt.Entitys, fuzz, ocs, isDoor, translate))
|
|
|
|
|
return true;
|
|
|
|
|
return IsBoxAndEntitysIntersect(ents, intersectEnts, ZNormal, translate, undefined, ocs, isParallel);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
let box = checkEnt.BoundingBox.clone() as Box3Ext;
|
|
|
|
|
if (parentOCS) box.applyMatrix4(parentOCS);
|
|
|
|
|
if (translate) box.translate(translate);
|
|
|
|
|
if (isDoor)
|
|
|
|
|
{
|
|
|
|
|
let newBox = box.clone().intersect(enBox);
|
|
|
|
|
//部分情况 Box3Ext.Volume错误用原生方法求体积
|
|
|
|
|
let size = newBox.getSize(new Vector3);
|
|
|
|
|
if (size.x * size.y * size.z > 1e-6)
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
let newCheckEnt = checkEnt.Clone() as Solid3D;
|
|
|
|
|
if (parentcheckEntOCS) newCheckEnt.ApplyMatrix(parentcheckEntOCS);
|
|
|
|
|
|
|
|
|
|
for (let intersectEnt of intersectEnts)
|
|
|
|
|
{
|
|
|
|
|
if (box.intersectsBox(enBox, fuzz))
|
|
|
|
|
return true;
|
|
|
|
|
if (intersectEnt instanceof HardwareCompositeEntity)
|
|
|
|
|
{
|
|
|
|
|
let ocs = intersectEnt.OCS;
|
|
|
|
|
if (parentIntersectEntOCS) ocs = new Matrix4().multiplyMatrices(parentIntersectEntOCS, ocs);
|
|
|
|
|
let ents = intersectEnt.Entitys.filter(ent => ent instanceof ExtrudeHole || ent instanceof SweepSolid || ent instanceof ExtrudeSolid || ent instanceof HardwareCompositeEntity);
|
|
|
|
|
if (IsBoxAndEntitysIntersect([newCheckEnt], ents, ZNormal, translate, ocs, undefined, isParallelTo(new Vector3().setFromMatrixColumn(ocs, 0), newCheckEnt.Normal)))
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
let ent = intersectEnt.Clone() as Solid3D;
|
|
|
|
|
if (parentIntersectEntOCS) ent.ApplyMatrix(parentIntersectEntOCS);
|
|
|
|
|
if (translate) ent.ApplyMatrix(new Matrix4().setPosition(translate));
|
|
|
|
|
|
|
|
|
|
let obb = getFuzzOBB(newCheckEnt.OBB, ZNormal, isParallel, parentIntersectEntOCS, newCheckEnt instanceof ExtrudeSolid);
|
|
|
|
|
if (obb.intersectsOBB(ent.OBB))
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|