mirror of https://gitee.com/cf-fz/WebCAD.git
!2425 功能:组合模块 命令TemplateGroup
parent
27ad1f8275
commit
b910d02332
@ -0,0 +1,984 @@
|
||||
import { Intent } from "@blueprintjs/core";
|
||||
import { Matrix4, Vector3 } from "three";
|
||||
import { app } from "../ApplicationServices/Application";
|
||||
import { arrayLast, arrayRemoveIf } from "../Common/ArrayExt";
|
||||
import { CADObject } from "../DatabaseServices/CADObject";
|
||||
import { Entity } from "../DatabaseServices/Entity/Entity";
|
||||
import { ObjectId } from "../DatabaseServices/ObjectId";
|
||||
import { PositioningTemporary } from "../DatabaseServices/Template/Positioning/PositioningTemporary";
|
||||
import { TemplateVisualSpace } from "../DatabaseServices/Template/ProgramTempate/TemplateVisualSpace";
|
||||
import { TemplateRecord } from "../DatabaseServices/Template/TemplateRecord";
|
||||
import { TemplateSplitType } from "../DatabaseServices/Template/TemplateType";
|
||||
import { Command } from "../Editor/CommandMachine";
|
||||
import { PromptStatus } from "../Editor/PromptResult";
|
||||
import { Box3Ext } from "../Geometry/Box";
|
||||
import { CoordinateSystem } from "../Geometry/CoordinateSystem";
|
||||
import { GetEulerAngle, equaln, isParallelTo, isPerpendicularityTo } from "../Geometry/GeUtils";
|
||||
import { AppToaster } from "../UI/Components/Toaster";
|
||||
|
||||
const FUZZ = 1e-3;
|
||||
|
||||
//模块空间关系
|
||||
enum SplitType
|
||||
{
|
||||
X = 0,
|
||||
Y = 1,
|
||||
Z = 2,
|
||||
C = 3,//包含
|
||||
I = 4,//相交
|
||||
}
|
||||
|
||||
export class Command_TemplateGroup implements Command
|
||||
{
|
||||
async exec()
|
||||
{
|
||||
let ssRes = await app.Editor.GetSelection({ Filter: { filterTypes: [Entity] }, AllowNone: false });
|
||||
if (ssRes.Status !== PromptStatus.OK) return;
|
||||
|
||||
let ents = ssRes.SelectSet?.SelectEntityList as Entity[];
|
||||
|
||||
//获取模块根节点过滤相同的
|
||||
let temps = new Set<TemplateRecord>();
|
||||
for (let ent of ents)
|
||||
{
|
||||
let temp = GetRootTemp(ent.Template?.Object as TemplateRecord);
|
||||
if (temp) temps.add(temp);
|
||||
}
|
||||
|
||||
if (temps.size < 2)
|
||||
{
|
||||
AppToaster.show({
|
||||
message: "所选模块数量小于2,无法组合!",
|
||||
timeout: 5000,
|
||||
intent: Intent.WARNING,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
let tempArray = Array.from(temps);
|
||||
|
||||
//取一个X轴向量与世界坐标X向量平行的模块
|
||||
let EXP_TEMP = tempArray.find((temp: TemplateRecord) =>
|
||||
{
|
||||
let xNormal = new Vector3().setFromMatrixColumn(temp.Positioning.SpaceCS, 0);
|
||||
return isParallelTo(xNormal, new Vector3(1));
|
||||
});
|
||||
|
||||
//没有就选第一个
|
||||
if (!EXP_TEMP) EXP_TEMP = tempArray[0];
|
||||
|
||||
const XNormal = new Vector3().setFromMatrixColumn(EXP_TEMP.Positioning.SpaceCS, 0);
|
||||
|
||||
//是否都与该模块向量平行
|
||||
const IsALLParallel = tempArray.every((temp) =>
|
||||
{
|
||||
const XNormal2 = new Vector3().setFromMatrixColumn(temp.Positioning.SpaceCS, 0);
|
||||
if (isParallelTo(XNormal2, XNormal) || isPerpendicularityTo(XNormal2, XNormal))
|
||||
return true;
|
||||
});
|
||||
|
||||
if (!IsALLParallel)
|
||||
{
|
||||
AppToaster.show({
|
||||
message: "所选模块中有自身空间坐标系不符要求,无法组合!",
|
||||
timeout: 5000,
|
||||
intent: Intent.WARNING,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const BackOCS = EXP_TEMP.Positioning.SpaceCS;
|
||||
const OCSInv = new Matrix4().getInverse(EXP_TEMP.Positioning.SpaceCS);
|
||||
const RMtx = new Matrix4().extractRotation(EXP_TEMP.Positioning.SpaceCS);
|
||||
|
||||
//组合模块的Box和Size
|
||||
const NewTempArray = [];
|
||||
const NewTempSpaceBox = new Box3Ext();
|
||||
|
||||
for (let temp of tempArray)
|
||||
{
|
||||
let xNormal = new Vector3().setFromMatrixColumn(temp.Positioning.SpaceCS, 0);
|
||||
let isParallel = isParallelTo(XNormal, xNormal);
|
||||
|
||||
let positioning = temp.Positioning;
|
||||
let tempPt = new Vector3().applyMatrix4(positioning.SpaceCS).applyMatrix4(OCSInv);
|
||||
|
||||
//不平行的模块放到一个占位空间里面
|
||||
if (!isParallel)
|
||||
temp = NestLevelTemp(temp);
|
||||
|
||||
let newPositioning = new PositioningTemporary();
|
||||
newPositioning.SpaceSize = positioning.SpaceSize;
|
||||
newPositioning.SpaceCS = positioning.SpaceCS.setPosition(tempPt).multiply(new Matrix4().getInverse(RMtx));
|
||||
|
||||
temp.Positioning = newPositioning;
|
||||
|
||||
let box = new Box3Ext(new Vector3(), newPositioning.SpaceSize.clone());
|
||||
box.applyMatrix4(newPositioning.SpaceCS);
|
||||
temp.__CacheBox__ = box;
|
||||
temp.__CacheSize__ = newPositioning.SpaceSize;
|
||||
|
||||
if (!isParallel)
|
||||
SetTempPosition(temp.__CacheBox__, temp.Children[0].Object as TemplateRecord);
|
||||
|
||||
NewTempSpaceBox.union(box);
|
||||
NewTempArray.push(temp);
|
||||
}
|
||||
const NewTempSpaceSize = NewTempSpaceBox.getSize(new Vector3);
|
||||
|
||||
//验证所选模块空间关系及排序
|
||||
{
|
||||
//判断两个模块空间关系
|
||||
let spaceType = BoxSplitType(NewTempArray[0].__CacheBox__, NewTempArray[1].__CacheBox__);
|
||||
|
||||
if (spaceType > 2)
|
||||
{
|
||||
AppToaster.show({
|
||||
message: "存在模块相交,无法组合!",
|
||||
timeout: 5000,
|
||||
intent: Intent.DANGER,
|
||||
});
|
||||
return;
|
||||
}
|
||||
NewTempArray.sort((a, b) =>
|
||||
{
|
||||
let b1 = a.__CacheBox__;
|
||||
let b2 = b.__CacheBox__;
|
||||
if (spaceType === SplitType.X)
|
||||
return b1.min.x - b2.min.x;
|
||||
else if (spaceType === SplitType.Y)
|
||||
return b1.min.y - b2.min.y;
|
||||
else if (spaceType === SplitType.Z)
|
||||
return b1.min.z - b2.min.z;
|
||||
});
|
||||
}
|
||||
|
||||
//挨个组合
|
||||
let rootTemp: TemplateRecord;
|
||||
let newCreateTemp = new Set<TemplateRecord>();
|
||||
let masterTemp = NewTempArray.shift();
|
||||
|
||||
while (NewTempArray.length)
|
||||
{
|
||||
let secondTemp = NewTempArray.shift();
|
||||
let box1 = masterTemp.__CacheBox__;
|
||||
let box2 = secondTemp.__CacheBox__;
|
||||
|
||||
const SpaceBox = box1.clone().union(box2);
|
||||
const SpaceSize = SpaceBox.getSize(new Vector3);
|
||||
|
||||
//判断两个模块空间关系
|
||||
let spaceType = BoxSplitType(box1, box2);
|
||||
|
||||
if (spaceType === SplitType.X)
|
||||
{
|
||||
//X轴切割并补充BOX
|
||||
rootTemp = await SplitBoxOfX(SpaceBox, [box1, box2], masterTemp, secondTemp, newCreateTemp);
|
||||
rootTemp.SplitType = TemplateSplitType.X;
|
||||
}
|
||||
else if (spaceType === SplitType.Z)
|
||||
{
|
||||
//Z轴切割并补充BOX
|
||||
rootTemp = await SplitBoxOfZ(SpaceBox, [box1, box2], masterTemp, secondTemp, newCreateTemp);
|
||||
rootTemp.SplitType = TemplateSplitType.Z;
|
||||
}
|
||||
else if (spaceType === SplitType.Y)
|
||||
{
|
||||
//Y轴切割并补充BOX
|
||||
rootTemp = await SplitBoxOfY(SpaceBox, [box1, box2], masterTemp, secondTemp, newCreateTemp);
|
||||
rootTemp.SplitType = TemplateSplitType.Y;
|
||||
}
|
||||
|
||||
let positioning = new PositioningTemporary();
|
||||
positioning.SpaceCS = new Matrix4().setPosition(SpaceBox.min);
|
||||
positioning.SpaceSize = SpaceSize;
|
||||
rootTemp.Positioning = positioning;
|
||||
|
||||
masterTemp = rootTemp;
|
||||
}
|
||||
|
||||
//初始化pos
|
||||
rootTemp.LParam.expr = NewTempSpaceSize.x;
|
||||
rootTemp.WParam.expr = NewTempSpaceSize.y;
|
||||
rootTemp.HParam.expr = NewTempSpaceSize.z;
|
||||
rootTemp.PXParam.expr = 0;
|
||||
rootTemp.PYParam.expr = 0;
|
||||
rootTemp.PZParam.expr = 0;
|
||||
|
||||
SetSplitTypeDiv(rootTemp);
|
||||
|
||||
for (let children of rootTemp.Children)
|
||||
SetSplitTypeParam(rootTemp.SplitType, children.Object as TemplateRecord);
|
||||
|
||||
let minPt = new Vector3().applyMatrix4(rootTemp.Positioning.SpaceCS);
|
||||
minPt.applyMatrix4(BackOCS);
|
||||
rootTemp.Positioning.SpaceCS = rootTemp.Positioning.SpaceCS.multiply(BackOCS).setPosition(minPt);
|
||||
|
||||
await rootTemp.UpdateTemplateTree();
|
||||
}
|
||||
}
|
||||
|
||||
//对存在旋转分量柜体增加父级嵌套
|
||||
function NestLevelTemp(temp: TemplateRecord): TemplateVisualSpace
|
||||
{
|
||||
let newTemplateVisualSpace = new TemplateVisualSpace();
|
||||
newTemplateVisualSpace.Name = "占位空间";
|
||||
newTemplateVisualSpace.InitBaseParams();
|
||||
newTemplateVisualSpace.Children.push(temp.Id);
|
||||
app.Database.TemplateTable.Append(newTemplateVisualSpace);
|
||||
|
||||
let boxSize = temp.Positioning.SpaceSize;
|
||||
boxSize.applyMatrix4(temp.Positioning.SpaceCS.clone().setPosition(0, 0, 0));
|
||||
|
||||
newTemplateVisualSpace.LParam.expr = Math.abs(boxSize.x);
|
||||
newTemplateVisualSpace.WParam.expr = Math.abs(boxSize.y);
|
||||
newTemplateVisualSpace.HParam.expr = Math.abs(boxSize.z);
|
||||
newTemplateVisualSpace.__CacheSize__ = new Vector3(Math.abs(boxSize.x), Math.abs(boxSize.y), Math.abs(boxSize.z));
|
||||
|
||||
return newTemplateVisualSpace;
|
||||
}
|
||||
|
||||
//添加两个模块间的占位空间
|
||||
function AddSpaceBoxes(needAddVisualSpaceBox: Box3Ext[], newTemp: TemplateRecord, temp?: TemplateRecord)
|
||||
{
|
||||
for (let box of needAddVisualSpaceBox)
|
||||
{
|
||||
if (!box && temp)
|
||||
{
|
||||
newTemp.Children.push(temp.Id);
|
||||
SetSplitTypeParam(newTemp.SplitType, temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (equaln(box.min.x, box.max.x, 1e-2) || equaln(box.min.y, box.max.y, 1e-2) || equaln(box.min.z, box.max.z, 1e-2)) continue;
|
||||
let newTemplateVisualSpace = new TemplateVisualSpace();
|
||||
newTemplateVisualSpace.Name = "占位空间";
|
||||
newTemplateVisualSpace.InitBaseParams();
|
||||
app.Database.TemplateTable.Append(newTemplateVisualSpace);
|
||||
newTemp.Children.push(newTemplateVisualSpace.Id);
|
||||
let boxSize = box.getSize(new Vector3);
|
||||
newTemplateVisualSpace.LParam.expr = boxSize.x;
|
||||
newTemplateVisualSpace.WParam.expr = boxSize.y;
|
||||
newTemplateVisualSpace.HParam.expr = boxSize.z;
|
||||
newTemplateVisualSpace.__CacheSize__ = boxSize;
|
||||
SetSplitTypeParam(newTemp.SplitType, newTemplateVisualSpace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function SetTempPosition(spaceBox: Box3Ext, temp: TemplateRecord)
|
||||
{
|
||||
let positioning = temp.Positioning;
|
||||
let box = new Box3Ext(new Vector3(), positioning.SpaceSize.clone()).applyMatrix4(positioning.SpaceCS);
|
||||
let pos = spaceBox.min.clone().applyMatrix4(new Matrix4().getInverse(positioning.SpaceCS));
|
||||
let fuzz = box.min.clone().applyMatrix4(new Matrix4().getInverse(positioning.SpaceCS));
|
||||
pos.subVectors(fuzz, pos);
|
||||
let cds = new CoordinateSystem().CopyForm(positioning.SpaceCS);
|
||||
let ro = GetEulerAngle(cds.XAxis, cds.YAxis, cds.ZAxis);
|
||||
|
||||
temp.RXParam.expr = ro.roX;
|
||||
temp.RYParam.expr = ro.roY;
|
||||
temp.RZParam.expr = ro.roZ;
|
||||
|
||||
temp.LParam.expr = "_L";
|
||||
temp.WParam.expr = "_W";
|
||||
temp.HParam.expr = "_H";
|
||||
}
|
||||
|
||||
//设置_DIV参数 相同类型尺寸使用 _DIV 参数 没有相同最后一个占位空间使用 _DIV
|
||||
function SetSplitTypeDiv(temp: TemplateRecord)
|
||||
{
|
||||
let childrens = [...temp.Children];
|
||||
if (childrens.length)
|
||||
for (let children of childrens)
|
||||
{
|
||||
let temp = children.Object;
|
||||
if (temp && !temp.IsErase)
|
||||
SetSplitTypeDiv(children.Object as TemplateRecord);
|
||||
}
|
||||
|
||||
let visualSpaceTemps = temp.Children.filter(obj => (obj.Object as TemplateRecord).Name === "占位空间");
|
||||
|
||||
if (temp.SplitType === TemplateSplitType.X)
|
||||
{
|
||||
let SameX: ObjectId<CADObject>[][] = [];
|
||||
while (childrens.length)
|
||||
{
|
||||
let childrenTemp = childrens.pop();
|
||||
let same = [childrenTemp];
|
||||
arrayRemoveIf(childrens, (t) =>
|
||||
{
|
||||
if (equaln(childrenTemp.Object.__CacheSize__?.x, t.Object.__CacheSize__?.x, FUZZ))
|
||||
{
|
||||
same.push(t);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
SameX.push(same);
|
||||
}
|
||||
SameX.sort((a, b) => b.length - a.length);
|
||||
//柜体X轴都相等 或者相等的有最大值 [3,2,2,1,1]
|
||||
if (SameX.length === 1 || (SameX.length > 1 && SameX[0].length > SameX[1].length))
|
||||
{
|
||||
for (let obj of SameX[0])
|
||||
{
|
||||
let temp = obj.Object as TemplateRecord;
|
||||
temp.LParam.expr = "_DIV";
|
||||
}
|
||||
}
|
||||
else if (SameX.every(t => t.length === 1)) //都不相等
|
||||
{
|
||||
let temp = SameX[0][0].Object as TemplateRecord;
|
||||
temp.LParam.expr = "_DIV";
|
||||
}
|
||||
//多个相同的 选用小尺寸
|
||||
else if (SameX[0].length === SameX[1].length)
|
||||
{
|
||||
let sameGroup = SameX.filter(b => b.length === SameX[0].length);
|
||||
sameGroup.sort((a, b) => a[0].Object.__CacheSize__.x - b[0].Object.__CacheSize__.x);
|
||||
for (let objs of sameGroup.filter(t => t[0].Object.__CacheSize__.x === sameGroup[0][0].Object.__CacheSize__.x))
|
||||
{
|
||||
for (let obj of objs)
|
||||
{
|
||||
let temp = obj.Object as TemplateRecord;
|
||||
temp.LParam.expr = "_DIV";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (visualSpaceTemps.length)
|
||||
(arrayLast(visualSpaceTemps).Object as TemplateRecord).LParam.expr = "_DIV";
|
||||
}
|
||||
}
|
||||
else if (temp.SplitType === TemplateSplitType.Y)
|
||||
{
|
||||
let SameY: ObjectId<CADObject>[][] = [];
|
||||
while (childrens.length)
|
||||
{
|
||||
let childrenTemp = childrens.pop();
|
||||
let same = [childrenTemp];
|
||||
arrayRemoveIf(childrens, (t) =>
|
||||
{
|
||||
if (equaln(childrenTemp.Object.__CacheSize__?.y, t.Object.__CacheSize__?.y, FUZZ))
|
||||
{
|
||||
same.push(t);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
SameY.push(same);
|
||||
}
|
||||
SameY.sort((a, b) => b.length - a.length);
|
||||
if (SameY.length === 1 || (SameY.length > 1 && SameY[0].length > SameY[1].length))
|
||||
{
|
||||
for (let obj of SameY[0])
|
||||
{
|
||||
let temp = obj.Object as TemplateRecord;
|
||||
temp.WParam.expr = "_DIV";
|
||||
}
|
||||
}
|
||||
else if (SameY.every(t => t.length === 1)) //都不相等
|
||||
{
|
||||
let temp = SameY[0][0].Object as TemplateRecord;
|
||||
temp.WParam.expr = "_DIV";
|
||||
}
|
||||
//多个相同的 选用小尺寸
|
||||
else if (SameY[0].length === SameY[1].length)
|
||||
{
|
||||
let sameGroup = SameY.filter(b => b.length === SameY[0].length);
|
||||
sameGroup.sort((a, b) => a[0].Object.__CacheSize__.y - b[0].Object.__CacheSize__.y);
|
||||
for (let objs of sameGroup.filter(t => t[0].Object.__CacheSize__.y === sameGroup[0][0].Object.__CacheSize__.y))
|
||||
{
|
||||
for (let obj of objs)
|
||||
{
|
||||
let temp = obj.Object as TemplateRecord;
|
||||
temp.WParam.expr = "_DIV";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (visualSpaceTemps.length)
|
||||
(arrayLast(visualSpaceTemps).Object as TemplateRecord).WParam.expr = "_DIV";
|
||||
}
|
||||
}
|
||||
else if (temp.SplitType === TemplateSplitType.Z)
|
||||
{
|
||||
let SameZ: ObjectId<CADObject>[][] = [];
|
||||
while (childrens.length)
|
||||
{
|
||||
let childrenTemp = childrens.pop();
|
||||
let same = [childrenTemp];
|
||||
arrayRemoveIf(childrens, (t) =>
|
||||
{
|
||||
if (equaln(childrenTemp.Object.__CacheSize__?.z, t.Object.__CacheSize__?.z, FUZZ))
|
||||
{
|
||||
same.push(t);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
SameZ.push(same);
|
||||
}
|
||||
SameZ.sort((a, b) => b.length - a.length);
|
||||
if (SameZ.length === 1 || (SameZ.length > 1 && SameZ[0].length > SameZ[1].length))
|
||||
{
|
||||
for (let obj of SameZ[0])
|
||||
{
|
||||
let temp = obj.Object as TemplateRecord;
|
||||
temp.HParam.expr = "_DIV";
|
||||
}
|
||||
}
|
||||
else if (SameZ.every(t => t.length === 1)) //都不相等
|
||||
{
|
||||
let temp = SameZ[0][0].Object as TemplateRecord;
|
||||
temp.HParam.expr = "_DIV";
|
||||
}
|
||||
//多个相同的 选用小尺寸
|
||||
else if (SameZ[0].length === SameZ[1].length)
|
||||
{
|
||||
let sameGroup = SameZ.filter(b => b.length === SameZ[0].length);
|
||||
sameGroup.sort((a, b) => a[0].Object.__CacheSize__.z - b[0].Object.__CacheSize__.z);
|
||||
for (let objs of sameGroup.filter(t => t[0].Object.__CacheSize__.z === sameGroup[0][0].Object.__CacheSize__.z))
|
||||
{
|
||||
for (let obj of objs)
|
||||
{
|
||||
let temp = obj.Object as TemplateRecord;
|
||||
temp.HParam.expr = "_DIV";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (visualSpaceTemps.length)
|
||||
(arrayLast(visualSpaceTemps).Object as TemplateRecord).HParam.expr = "_DIV";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//根据切割类型设置参数
|
||||
function SetSplitTypeParam(splitType: TemplateSplitType, temp: TemplateRecord)
|
||||
{
|
||||
if (splitType === TemplateSplitType.X)
|
||||
{
|
||||
temp.WParam.expr = "_W";
|
||||
temp.HParam.expr = "_H";
|
||||
if (!temp.PXParam.expr && !temp.PYParam.expr && !temp.PZParam.expr)
|
||||
temp.PXParam.expr = "_POS";
|
||||
}
|
||||
else if (splitType === TemplateSplitType.Y)
|
||||
{
|
||||
temp.LParam.expr = "_L";
|
||||
temp.HParam.expr = "_H";
|
||||
if (!temp.PXParam.expr && !temp.PYParam.expr && !temp.PZParam.expr)
|
||||
temp.PYParam.expr = "_POS";
|
||||
}
|
||||
else if (splitType === TemplateSplitType.Z)
|
||||
{
|
||||
temp.LParam.expr = "_L";
|
||||
temp.WParam.expr = "_W";
|
||||
if (!temp.PXParam.expr && !temp.PYParam.expr && !temp.PZParam.expr)
|
||||
temp.PZParam.expr = "_POS";
|
||||
}
|
||||
}
|
||||
|
||||
function GetRootTemp(temp: TemplateRecord): TemplateRecord
|
||||
{
|
||||
let parentTemp = temp?.Parent?.Object as TemplateRecord;
|
||||
if (parentTemp)
|
||||
{
|
||||
return GetRootTemp(parentTemp);
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
//判断两个盒子空间位置关系
|
||||
function BoxSplitType(box1: Box3Ext, box2: Box3Ext): SplitType
|
||||
{
|
||||
let bMin1 = box1.min;
|
||||
let bMin2 = box2.min;
|
||||
|
||||
let bMax1 = box1.max;
|
||||
let bMax2 = box2.max;
|
||||
let intersectBoxV = box1.clone().intersect(box2).Volume;
|
||||
if (intersectBoxV > FUZZ)
|
||||
{
|
||||
if (equaln(intersectBoxV, box1.Volume, FUZZ) || equaln(intersectBoxV, box2.Volume, FUZZ))
|
||||
return SplitType.C;
|
||||
else
|
||||
return SplitType.I;
|
||||
}
|
||||
else if (bMax1.z - bMin2.z < FUZZ || bMax2.z - bMin1.z < FUZZ)
|
||||
return SplitType.Z;
|
||||
else if (bMax1.x - bMin2.x < FUZZ || bMax2.x - bMin1.x < FUZZ)
|
||||
return SplitType.X;
|
||||
else
|
||||
return SplitType.Y;
|
||||
}
|
||||
|
||||
async function SplitBoxOfX(spaceBox: Box3Ext, boxes: Box3Ext[], firstTemp: TemplateRecord, secondTemp: TemplateRecord, newCreateTemp: Set<TemplateRecord>): Promise<TemplateRecord>
|
||||
{
|
||||
let box1: Box3Ext = boxes[0].clone();
|
||||
let box2: Box3Ext = boxes[1].clone();
|
||||
let temp1: TemplateRecord = firstTemp;
|
||||
let temp2: TemplateRecord = secondTemp;
|
||||
const Reverse = box1.min.x > box2.max.x;
|
||||
|
||||
//组合后的顶层节点
|
||||
let rootTemp: TemplateRecord;
|
||||
|
||||
if (Reverse)
|
||||
{
|
||||
box1 = boxes[1].clone();
|
||||
box2 = boxes[0].clone();
|
||||
temp1 = secondTemp;
|
||||
temp2 = firstTemp;
|
||||
}
|
||||
|
||||
let bMin2 = box2.min;
|
||||
let bMax1 = box1.max;
|
||||
|
||||
let min = spaceBox.min;
|
||||
let max = spaceBox.max;
|
||||
|
||||
const AddTopBottomBox = (box: Box3Ext, temp: TemplateRecord) =>
|
||||
{
|
||||
let groupTemp = temp;
|
||||
let bMin = box.min;
|
||||
let bMax = box.max;
|
||||
|
||||
let newVisualSpaceBoxes: Box3Ext[] = [];
|
||||
|
||||
if (bMin.z - min.z > FUZZ)
|
||||
newVisualSpaceBoxes.push(new Box3Ext(new Vector3(bMin.x, bMin.y, min.z), new Vector3(bMax.x, bMax.y, bMin.z)));
|
||||
|
||||
newVisualSpaceBoxes.push(undefined);
|
||||
|
||||
if (max.z - bMax.z > FUZZ)
|
||||
newVisualSpaceBoxes.push(new Box3Ext(new Vector3(bMin.x, bMin.y, bMax.z), new Vector3(bMax.x, bMax.y, max.z)));
|
||||
|
||||
if (newVisualSpaceBoxes.length > 1)
|
||||
{
|
||||
let newTemp = new TemplateVisualSpace();
|
||||
newTemp.Name = "组合模板";
|
||||
newTemp.InitBaseParams();
|
||||
app.Database.TemplateTable.Append(newTemp);
|
||||
|
||||
//组合模块的Box和Size
|
||||
const NewTempSpaceBox = box.clone();
|
||||
for (let newSpaceBox of newVisualSpaceBoxes)
|
||||
if (newSpaceBox)
|
||||
NewTempSpaceBox.union(newSpaceBox);
|
||||
|
||||
const BoxSize = NewTempSpaceBox.getSize(new Vector3);
|
||||
|
||||
newTemp.SplitType = TemplateSplitType.Z;
|
||||
AddSpaceBoxes(newVisualSpaceBoxes, newTemp, temp);
|
||||
|
||||
let positioning = new PositioningTemporary();
|
||||
positioning.SpaceCS = new Matrix4().setPosition(NewTempSpaceBox.min);
|
||||
positioning.SpaceSize = BoxSize;
|
||||
newTemp.Positioning = positioning;
|
||||
newTemp.__CacheSize__ = BoxSize;
|
||||
newTemp.__CacheBox__ = NewTempSpaceBox;
|
||||
groupTemp = newTemp;
|
||||
}
|
||||
|
||||
return groupTemp;
|
||||
};
|
||||
|
||||
const AddFrontBackBox = (box: Box3Ext, temp: TemplateRecord) =>
|
||||
{
|
||||
let bMin = box.min;
|
||||
let bMax = box.max;
|
||||
let groupTemp = temp;
|
||||
|
||||
let newVisualSpaceBoxes: Box3Ext[] = [];
|
||||
|
||||
if (bMin.y - min.y > FUZZ)
|
||||
newVisualSpaceBoxes.push(new Box3Ext(new Vector3(bMin.x, min.y, min.z), new Vector3(bMax.x, bMin.y, max.z)));
|
||||
|
||||
newVisualSpaceBoxes.push(undefined);
|
||||
|
||||
if (max.y - bMax.y > FUZZ)
|
||||
newVisualSpaceBoxes.push(new Box3Ext(new Vector3(bMin.x, bMax.y, min.z), new Vector3(bMax.x, max.y, max.z)));
|
||||
|
||||
if (newVisualSpaceBoxes.length > 1)
|
||||
{
|
||||
let newTemp = new TemplateVisualSpace();
|
||||
newTemp.Name = "组合模板";
|
||||
newTemp.InitBaseParams();
|
||||
app.Database.TemplateTable.Append(newTemp);
|
||||
|
||||
//组合模块的Box和Size
|
||||
const NewTempSpaceBox = box.clone();
|
||||
|
||||
for (let spaceBox of newVisualSpaceBoxes)
|
||||
if (spaceBox)
|
||||
NewTempSpaceBox.union(spaceBox);
|
||||
|
||||
const BoxSize = NewTempSpaceBox.getSize(new Vector3);
|
||||
newTemp.SplitType = TemplateSplitType.Y;
|
||||
|
||||
AddSpaceBoxes(newVisualSpaceBoxes, newTemp, temp);
|
||||
let positioning = new PositioningTemporary();
|
||||
positioning.SpaceCS = new Matrix4().setPosition(NewTempSpaceBox.min);
|
||||
positioning.SpaceSize = BoxSize;
|
||||
newTemp.Positioning = positioning;
|
||||
newTemp.__CacheSize__ = BoxSize;
|
||||
newTemp.__CacheBox__ = NewTempSpaceBox;
|
||||
groupTemp = newTemp;
|
||||
}
|
||||
|
||||
return groupTemp;
|
||||
};
|
||||
|
||||
temp1 = AddTopBottomBox(box1, temp1);
|
||||
temp1 = AddFrontBackBox(box1, temp1);
|
||||
|
||||
//两模块中间
|
||||
let midBox = new Box3Ext(new Vector3(bMax1.x, min.y, min.z), new Vector3(bMin2.x, max.y, max.z));
|
||||
|
||||
temp2 = AddTopBottomBox(box2, temp2);
|
||||
temp2 = AddFrontBackBox(box2, temp2);
|
||||
|
||||
if (temp1.SplitType === TemplateSplitType.X && newCreateTemp.has(temp1))
|
||||
{
|
||||
rootTemp = temp1;
|
||||
AddSpaceBoxes([midBox], rootTemp);
|
||||
rootTemp.Children.push(temp2.Id);
|
||||
}
|
||||
else
|
||||
{
|
||||
//组合后的顶层节点
|
||||
rootTemp = new TemplateVisualSpace();
|
||||
rootTemp.Name = "组合模板";
|
||||
rootTemp.InitBaseParams();
|
||||
app.Database.TemplateTable.Append(rootTemp);
|
||||
rootTemp.Children.push(temp1.Id);
|
||||
AddSpaceBoxes([midBox], rootTemp);
|
||||
rootTemp.Children.push(temp2.Id);
|
||||
newCreateTemp.add(rootTemp);
|
||||
}
|
||||
|
||||
await temp1.UpdateTemplateTree();
|
||||
if (!(temp1.SplitType === TemplateSplitType.X && newCreateTemp.has(temp1)))
|
||||
await temp2.UpdateTemplateTree();
|
||||
|
||||
rootTemp.__CacheBox__ = spaceBox;
|
||||
rootTemp.__CacheSize__ = spaceBox.getSize(new Vector3);
|
||||
|
||||
return rootTemp;
|
||||
}
|
||||
|
||||
async function SplitBoxOfY(spaceBox: Box3Ext, boxes: Box3Ext[], firstTemp: TemplateRecord, secondTemp: TemplateRecord, newCreateTemp: Set<TemplateRecord>): Promise<TemplateRecord>
|
||||
{
|
||||
let box1: Box3Ext = boxes[0].clone();
|
||||
let box2: Box3Ext = boxes[1].clone();
|
||||
let temp1: TemplateRecord = firstTemp;
|
||||
let temp2: TemplateRecord = secondTemp;
|
||||
const Reverse = box1.min.y > box2.max.y;
|
||||
|
||||
//组合后的顶层节点
|
||||
let rootTemp: TemplateRecord;
|
||||
|
||||
if (Reverse)
|
||||
{
|
||||
box1 = boxes[1].clone();
|
||||
box2 = boxes[0].clone();
|
||||
temp1 = secondTemp;
|
||||
temp2 = firstTemp;
|
||||
}
|
||||
|
||||
let bMin2 = box2.min;
|
||||
let bMax1 = box1.max;
|
||||
|
||||
let min = spaceBox.min;
|
||||
let max = spaceBox.max;
|
||||
|
||||
|
||||
const AddTopBottomBox = (box: Box3Ext, temp: TemplateRecord) =>
|
||||
{
|
||||
let groupTemp = temp;
|
||||
let bMin = box.min;
|
||||
let bMax = box.max;
|
||||
|
||||
let newVisualSpaceBoxes: Box3Ext[] = [];
|
||||
|
||||
if (bMin.z - min.z > FUZZ)
|
||||
newVisualSpaceBoxes.push(new Box3Ext(new Vector3(min.x, bMin.y, min.z), new Vector3(max.x, bMax.y, bMin.z)));
|
||||
|
||||
newVisualSpaceBoxes.push(undefined);
|
||||
|
||||
if (max.z - bMax.z > FUZZ)
|
||||
newVisualSpaceBoxes.push(new Box3Ext(new Vector3(min.x, bMin.y, bMax.z), new Vector3(max.x, bMax.y, max.z)));
|
||||
|
||||
if (newVisualSpaceBoxes.length > 1)
|
||||
{
|
||||
let newTemp = new TemplateVisualSpace();
|
||||
newTemp.Name = "组合模板";
|
||||
newTemp.InitBaseParams();
|
||||
app.Database.TemplateTable.Append(newTemp);
|
||||
|
||||
//组合模块的Box和Size
|
||||
const NewTempSpaceBox = box.clone();
|
||||
for (let newSpaceBox of newVisualSpaceBoxes)
|
||||
if (newSpaceBox)
|
||||
NewTempSpaceBox.union(newSpaceBox);
|
||||
|
||||
const BoxSize = NewTempSpaceBox.getSize(new Vector3);
|
||||
|
||||
newTemp.SplitType = TemplateSplitType.Z;
|
||||
AddSpaceBoxes(newVisualSpaceBoxes, newTemp, temp);
|
||||
|
||||
let positioning = new PositioningTemporary();
|
||||
positioning.SpaceCS = new Matrix4().setPosition(NewTempSpaceBox.min);
|
||||
positioning.SpaceSize = BoxSize;
|
||||
newTemp.Positioning = positioning;
|
||||
newTemp.__CacheSize__ = BoxSize;
|
||||
newTemp.__CacheBox__ = NewTempSpaceBox;
|
||||
groupTemp = newTemp;
|
||||
}
|
||||
|
||||
return groupTemp;
|
||||
};
|
||||
|
||||
const AddLeftRightBox = (box: Box3Ext, temp: TemplateRecord) =>
|
||||
{
|
||||
let bMin = box.min;
|
||||
let bMax = box.max;
|
||||
let groupTemp = temp;
|
||||
|
||||
let newVisualSpaceBoxes: Box3Ext[] = [];
|
||||
|
||||
if (bMin.x - min.x > FUZZ)
|
||||
newVisualSpaceBoxes.push(new Box3Ext(new Vector3(min.x, bMin.y, bMin.z), new Vector3(bMin.x, bMax.y, bMax.z)));
|
||||
|
||||
newVisualSpaceBoxes.push(undefined);
|
||||
|
||||
if (max.x - bMax.x > FUZZ)
|
||||
newVisualSpaceBoxes.push(new Box3Ext(new Vector3(bMax.x, bMin.y, bMin.z), new Vector3(max.x, bMax.y, bMax.z)));
|
||||
|
||||
if (newVisualSpaceBoxes.length > 1)
|
||||
{
|
||||
let newTemp = new TemplateVisualSpace();
|
||||
newTemp.Name = "组合模板";
|
||||
newTemp.InitBaseParams();
|
||||
app.Database.TemplateTable.Append(newTemp);
|
||||
|
||||
//组合模块的Box和Size
|
||||
const NewTempSpaceBox = box.clone();
|
||||
|
||||
for (let spaceBox of newVisualSpaceBoxes)
|
||||
if (spaceBox)
|
||||
NewTempSpaceBox.union(spaceBox);
|
||||
else
|
||||
NewTempSpaceBox.union(box);
|
||||
const BoxSize = NewTempSpaceBox.getSize(new Vector3);
|
||||
newTemp.SplitType = TemplateSplitType.X;
|
||||
|
||||
AddSpaceBoxes(newVisualSpaceBoxes, newTemp, temp);
|
||||
let positioning = new PositioningTemporary();
|
||||
positioning.SpaceCS = new Matrix4().setPosition(NewTempSpaceBox.min);
|
||||
positioning.SpaceSize = BoxSize;
|
||||
newTemp.Positioning = positioning;
|
||||
newTemp.__CacheSize__ = BoxSize;
|
||||
newTemp.__CacheBox__ = NewTempSpaceBox;
|
||||
groupTemp = newTemp;
|
||||
}
|
||||
|
||||
return groupTemp;
|
||||
};
|
||||
|
||||
temp1 = AddLeftRightBox(box1, temp1);
|
||||
temp1 = AddTopBottomBox(box1, temp1);
|
||||
|
||||
//两模块中间
|
||||
let midBox = new Box3Ext(new Vector3(min.x, bMax1.y, min.z), new Vector3(max.x, bMin2.y, max.z));
|
||||
|
||||
temp2 = AddLeftRightBox(box2, temp2);
|
||||
temp2 = AddTopBottomBox(box2, temp2);
|
||||
|
||||
if (temp1.SplitType === TemplateSplitType.Y && newCreateTemp.has(temp1))
|
||||
{
|
||||
rootTemp = temp1;
|
||||
AddSpaceBoxes([midBox], rootTemp);
|
||||
rootTemp.Children.push(temp2.Id);
|
||||
}
|
||||
else
|
||||
{
|
||||
//组合后的顶层节点
|
||||
rootTemp = new TemplateVisualSpace();
|
||||
rootTemp.Name = "组合模板";
|
||||
rootTemp.InitBaseParams();
|
||||
app.Database.TemplateTable.Append(rootTemp);
|
||||
rootTemp.Children.push(temp1.Id);
|
||||
AddSpaceBoxes([midBox], rootTemp);
|
||||
rootTemp.Children.push(temp2.Id);
|
||||
newCreateTemp.add(rootTemp);
|
||||
}
|
||||
|
||||
await temp1.UpdateTemplateTree();
|
||||
if (!(temp1.SplitType === TemplateSplitType.Y && newCreateTemp.has(temp1)))
|
||||
await temp2.UpdateTemplateTree();
|
||||
|
||||
rootTemp.__CacheBox__ = spaceBox;
|
||||
rootTemp.__CacheSize__ = spaceBox.getSize(new Vector3);
|
||||
|
||||
return rootTemp;
|
||||
}
|
||||
|
||||
async function SplitBoxOfZ(spaceBox: Box3Ext, boxes: Box3Ext[], firstTemp: TemplateRecord, secondTemp: TemplateRecord, newCreateTemp: Set<TemplateRecord>): Promise<TemplateRecord>
|
||||
{
|
||||
let box1: Box3Ext = boxes[0].clone();
|
||||
let box2: Box3Ext = boxes[1].clone();
|
||||
let temp1: TemplateRecord = firstTemp;
|
||||
let temp2: TemplateRecord = secondTemp;
|
||||
const Reverse = box1.min.z > box2.max.z;
|
||||
|
||||
//组合后的顶层节点
|
||||
let rootTemp: TemplateRecord;
|
||||
|
||||
if (Reverse)
|
||||
{
|
||||
box1 = boxes[1].clone();
|
||||
box2 = boxes[0].clone();
|
||||
temp1 = secondTemp;
|
||||
temp2 = firstTemp;
|
||||
}
|
||||
|
||||
let bMin2 = box2.min;
|
||||
let bMax1 = box1.max;
|
||||
|
||||
let min = spaceBox.min;
|
||||
let max = spaceBox.max;
|
||||
|
||||
const AddLeftRightBox = (box: Box3Ext, temp: TemplateRecord) =>
|
||||
{
|
||||
let groupTemp = temp;
|
||||
let bMin = box.min;
|
||||
let bMax = box.max;
|
||||
|
||||
let newVisualSpaceBoxes: Box3Ext[] = [];
|
||||
|
||||
if (bMin.x - min.x > FUZZ)
|
||||
newVisualSpaceBoxes.push(new Box3Ext(new Vector3(min.x, bMin.y, bMin.z), new Vector3(bMin.x, bMax.y, bMax.z)));
|
||||
|
||||
newVisualSpaceBoxes.push(undefined);
|
||||
|
||||
if (max.x - bMax.x > FUZZ)
|
||||
newVisualSpaceBoxes.push(new Box3Ext(new Vector3(bMax.x, bMin.y, bMin.z), new Vector3(max.x, bMax.y, bMax.z)));
|
||||
|
||||
if (newVisualSpaceBoxes.length > 1)
|
||||
{
|
||||
let newTemp = new TemplateVisualSpace();
|
||||
newTemp.Name = "组合模板";
|
||||
newTemp.InitBaseParams();
|
||||
app.Database.TemplateTable.Append(newTemp);
|
||||
|
||||
//组合模块的Box和Size
|
||||
const NewTempSpaceBox = box.clone();
|
||||
for (let newSpaceBox of newVisualSpaceBoxes)
|
||||
if (newSpaceBox)
|
||||
NewTempSpaceBox.union(newSpaceBox);
|
||||
|
||||
const BoxSize = NewTempSpaceBox.getSize(new Vector3);
|
||||
|
||||
newTemp.SplitType = TemplateSplitType.X;
|
||||
AddSpaceBoxes(newVisualSpaceBoxes, newTemp, temp);
|
||||
|
||||
let positioning = new PositioningTemporary();
|
||||
positioning.SpaceCS = new Matrix4().setPosition(NewTempSpaceBox.min);
|
||||
positioning.SpaceSize = BoxSize;
|
||||
newTemp.Positioning = positioning;
|
||||
newTemp.__CacheSize__ = BoxSize;
|
||||
newTemp.__CacheBox__ = NewTempSpaceBox;
|
||||
groupTemp = newTemp;
|
||||
}
|
||||
|
||||
return groupTemp;
|
||||
};
|
||||
|
||||
const AddFrontBackBox = (box: Box3Ext, temp: TemplateRecord) =>
|
||||
{
|
||||
let bMin = box.min;
|
||||
let bMax = box.max;
|
||||
let groupTemp = temp;
|
||||
|
||||
let newVisualSpaceBoxes: Box3Ext[] = [];
|
||||
|
||||
if (bMin.y - min.y > FUZZ)
|
||||
newVisualSpaceBoxes.push(new Box3Ext(new Vector3(min.x, min.y, bMin.z), new Vector3(max.x, bMin.y, bMax.z)));
|
||||
|
||||
newVisualSpaceBoxes.push(undefined);
|
||||
|
||||
if (max.y - bMax.y > FUZZ)
|
||||
newVisualSpaceBoxes.push(new Box3Ext(new Vector3(min.x, bMax.y, bMin.z), new Vector3(max.x, max.y, bMax.z)));
|
||||
|
||||
if (newVisualSpaceBoxes.length > 1)
|
||||
{
|
||||
let newTemp = new TemplateVisualSpace();
|
||||
newTemp.Name = "组合模板";
|
||||
newTemp.InitBaseParams();
|
||||
app.Database.TemplateTable.Append(newTemp);
|
||||
|
||||
//组合模块的Box和Size
|
||||
const NewTempSpaceBox = box.clone();
|
||||
|
||||
for (let spaceBox of newVisualSpaceBoxes)
|
||||
if (spaceBox)
|
||||
NewTempSpaceBox.union(spaceBox);
|
||||
else
|
||||
NewTempSpaceBox.union(box);
|
||||
const BoxSize = NewTempSpaceBox.getSize(new Vector3);
|
||||
newTemp.SplitType = TemplateSplitType.Y;
|
||||
|
||||
AddSpaceBoxes(newVisualSpaceBoxes, newTemp, temp);
|
||||
let positioning = new PositioningTemporary();
|
||||
positioning.SpaceCS = new Matrix4().setPosition(NewTempSpaceBox.min);
|
||||
positioning.SpaceSize = BoxSize;
|
||||
newTemp.Positioning = positioning;
|
||||
newTemp.__CacheSize__ = BoxSize;
|
||||
newTemp.__CacheBox__ = NewTempSpaceBox;
|
||||
groupTemp = newTemp;
|
||||
}
|
||||
|
||||
return groupTemp;
|
||||
};
|
||||
|
||||
temp1 = AddLeftRightBox(box1, temp1);
|
||||
temp1 = AddFrontBackBox(box1, temp1);
|
||||
|
||||
//两模块中间
|
||||
let midBox = new Box3Ext(new Vector3(min.x, min.y, bMax1.z), new Vector3(max.x, max.y, bMin2.z));
|
||||
|
||||
temp2 = AddLeftRightBox(box2, temp2);
|
||||
temp2 = AddFrontBackBox(box2, temp2);
|
||||
|
||||
if (temp1.SplitType === TemplateSplitType.Z && newCreateTemp.has(temp1))
|
||||
{
|
||||
rootTemp = temp1;
|
||||
AddSpaceBoxes([midBox], rootTemp);
|
||||
rootTemp.Children.push(temp2.Id);
|
||||
}
|
||||
else
|
||||
{
|
||||
//组合后的顶层节点
|
||||
rootTemp = new TemplateVisualSpace();
|
||||
rootTemp.Name = "组合模板";
|
||||
rootTemp.InitBaseParams();
|
||||
app.Database.TemplateTable.Append(rootTemp);
|
||||
rootTemp.Children.push(temp1.Id);
|
||||
AddSpaceBoxes([midBox], rootTemp);
|
||||
rootTemp.Children.push(temp2.Id);
|
||||
newCreateTemp.add(rootTemp);
|
||||
}
|
||||
|
||||
await temp1.UpdateTemplateTree();
|
||||
if (!(temp1.SplitType === TemplateSplitType.Z && newCreateTemp.has(temp1)))
|
||||
await temp2.UpdateTemplateTree();
|
||||
|
||||
rootTemp.__CacheBox__ = spaceBox;
|
||||
rootTemp.__CacheSize__ = spaceBox.getSize(new Vector3);
|
||||
|
||||
return rootTemp;
|
||||
}
|
Loading…
Reference in new issue