!2478 优化:画门板铰链偏移使用OBB校验

pull/2479/head
林三 11 months ago committed by ChenX
parent 1b7b1ea13d
commit a25e03d89a

@ -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;
}

@ -1,5 +1,5 @@
import { Box3, Vector3 } from "three";
import { BoxIntersectFuzz, IsBoxAndEntitysIntersect, RecordHingeTrSizeX, SetHingeType, SetNoPareTypeHigneName } from "../../../Add-on/DrawBoard/DrawDoorDrawer/DrawDoorTool";
import { IsBoxAndEntitysIntersect, RecordHingeTrSizeX, SetHingeType, SetNoPareTypeHigneName } from "../../../Add-on/DrawBoard/DrawDoorDrawer/DrawDoorTool";
import { IsDoor, IsHandle, IsHinge } from "../../../Add-on/HideSelect/HideSelectUtils";
import { app } from "../../../ApplicationServices/Application";
import { EBoardKeyList } from "../../../Common/BoardKeyList";
@ -369,6 +369,9 @@ export class TemplateDrawHingeTool
let hingeTemp = ironware.Template.Object as TemplateRecord;
let hingeSpace = hingeTemp.Parent.Object as TemplateRecord;
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);
@ -392,11 +395,8 @@ export class TemplateDrawHingeTool
outlinesCache.set(br, grooveOutlines);
}
const xNormal = new Vector3().setFromMatrixColumn(ironware.OCSNoClone, 0);
const isParallelToX = isParallelTo(xNormal, br.Normal);
//门板/背板 不增加误差,防止误关联
if (IsBoxAndEntitysIntersect(otherEntBox, [ironware], BoxIntersectFuzz, ocs, isDoor || (behindBoards.includes(br) && !isParallelToX)))
if (IsBoxAndEntitysIntersect([otherEnt], [ironware], ZNormal))
{
const center = inventedBox.getCenter(new Vector3).applyMatrix4(br.OCSInv).setZ(0);
if (grooveOutlines.some(c => c.PtInCurve(center)))
@ -405,7 +405,7 @@ export class TemplateDrawHingeTool
//铰链避让
if (this.hingeSet.has(ironware.Id))
{
if (isParallelToX)
if (isParallelTo(xNormal, br.Normal))
{
if (!parseTypedHinges.has(ironware.Id))
{
@ -414,7 +414,7 @@ export class TemplateDrawHingeTool
SetHingeType(br, ironware);
}
}
else if (isParallelTo(ironware.Normal, br.Normal) || !IsDoor(br)) //不是门板也判断碰撞
else if (isParallelTo(ironware.Normal, br.Normal) || !isDoor)
{
let size = realityBox.getSize(new Vector3);
@ -422,7 +422,7 @@ export class TemplateDrawHingeTool
//偏移距离
let deviationDistance = 1;
deviationDistance = this.GetHingeMoveNum(door, inventedBox, realityBox, ironware, layerBoards, verticalBoards, deviationDistance, isLROpen, behindBoards);
deviationDistance = this.GetHingeMoveNum(door, inventedBox, realityBox, ironware, layerBoards, verticalBoards, deviationDistance, isLROpen, ZNormal);
if (deviationDistance === 0)
{
moveFail = true;
@ -441,9 +441,9 @@ export class TemplateDrawHingeTool
{
if (!IsHinge(ironware)) continue;
if (!IsBoxAndEntitysIntersect(realityBox, [otherEnt], BoxIntersectFuzz, undefined, isDoor)) continue;
if (!IsBoxAndEntitysIntersect([otherEnt], [ironware], ZNormal)) continue;
if (IsDoor(otherEnt))
if (isDoor)
{
//铰链归属复合门板
ironware.RelevanceBoards.push(otherEnt.Id);
@ -451,7 +451,7 @@ export class TemplateDrawHingeTool
continue;
}
let deviationDistance = 1;
deviationDistance = this.GetHingeMoveNum(door, inventedBox, realityBox, ironware, layerBoards, verticalBoards, deviationDistance, isLROpen, behindBoards);
deviationDistance = this.GetHingeMoveNum(door, inventedBox, realityBox, ironware, layerBoards, verticalBoards, deviationDistance, isLROpen, ZNormal);
if (deviationDistance === 0)
{
@ -476,7 +476,7 @@ export class TemplateDrawHingeTool
return needUpdate;
}
private GetHingeMoveNum(door: Entity, inventedBox: Box3, realityBox: Box3, ironware: Entity, layers: Entity[], verticals: Entity[], deviationNum: number, isLROpen: boolean, behindBoards: Entity[]): number
private GetHingeMoveNum(door: Entity, inventedBox: Box3, realityBox: Box3, ironware: Entity, layers: Entity[], verticals: Entity[], deviationNum: number, isLROpen: boolean, ZNormal: Vector3): number
{
let inventedBox1 = inventedBox.clone();
let translate: Vector3;
@ -507,13 +507,9 @@ export class TemplateDrawHingeTool
let intersect = false;
if (box1Z + 100 < doorHight)
{
for (let ent of layers)
if (IsBoxAndEntitysIntersect(layers, [ironware], ZNormal, translate))
{
if (IsBoxAndEntitysIntersect(ent.BoundingBox, [ironware], BoxIntersectFuzz, undefined, behindBoards.includes(ent), translate))
{
intersect = true;
break;
}
intersect = true;
}
}
else intersect = true;
@ -530,14 +526,8 @@ export class TemplateDrawHingeTool
let intersect = false;
if (box2Z - 100 > 0)
{
for (let ent of layers)
{
if (IsBoxAndEntitysIntersect(ent.BoundingBox, [ironware], BoxIntersectFuzz, undefined, behindBoards.includes(ent), translate))
{
intersect = true;
break;
}
}
if (IsBoxAndEntitysIntersect(layers, [ironware], ZNormal, translate))
intersect = true;
}
else intersect = true;
@ -550,7 +540,7 @@ export class TemplateDrawHingeTool
else
{
deviationNum++;
return this.GetHingeMoveNum(door, inventedBox, realityBox, ironware, layers, verticals, deviationNum, isLROpen, behindBoards);
return this.GetHingeMoveNum(door, inventedBox, realityBox, ironware, layers, verticals, deviationNum, isLROpen, ZNormal);
}
}
}
@ -565,14 +555,8 @@ export class TemplateDrawHingeTool
let intersect = false;
if (box1Z + 100 < doorHight)
{
for (let ent of verticals)
{
if (IsBoxAndEntitysIntersect(ent.BoundingBox, [ironware], BoxIntersectFuzz, undefined, behindBoards.includes(ent), translate))
{
intersect = true;
break;
}
}
if (IsBoxAndEntitysIntersect(verticals, [ironware], ZNormal, translate))
intersect = true;
}
else intersect = true;
@ -588,15 +572,10 @@ export class TemplateDrawHingeTool
let intersect = false;
if (box2Z - 100 > 0)
{
for (let ent of verticals)
{
if (IsBoxAndEntitysIntersect(ent.BoundingBox, [ironware], BoxIntersectFuzz, undefined, behindBoards.includes(ent), translate))
{
intersect = true;
break;
}
}
} else intersect = true;
if (IsBoxAndEntitysIntersect(verticals, [ironware], ZNormal, translate))
intersect = true;
}
else intersect = true;
if (!intersect)
return -deviationNum * distance;
@ -607,7 +586,7 @@ export class TemplateDrawHingeTool
else
{
deviationNum++;
return this.GetHingeMoveNum(door, inventedBox, realityBox, ironware, layers, verticals, deviationNum, isLROpen, behindBoards);
return this.GetHingeMoveNum(door, inventedBox, realityBox, ironware, layers, verticals, deviationNum, isLROpen, ZNormal);
}
}
}

Loading…
Cancel
Save