!2425 功能:组合模块 命令TemplateGroup

pull/2511/head
林三 9 months ago committed by ChenX
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;
}

@ -381,4 +381,5 @@ export enum CommandNames
Show2DPathObject = "SHOW2DPATHOBJECT",//显示二维刀路差集
Hide2DPathObject = "HIDE2DPATHOBJECT",//隐藏二维刀路差集
PickUp2DModelCsgs = "PICKUP2DMODELCSGS",//提取二维刀路的刀具轮廓
TemplateGroup = "TEMPLATEGROUP" //模块组合
}

@ -215,6 +215,7 @@ import { ShowEditorBBS } from "../Add-on/showModal/ShowModal";
import { ChangeColorByRoomCabinet } from "../Add-on/ChangeColorByRoomOrCabinet/ChangeColorByRoomOrCabinet";
import { Command_RemovePolylineRepeatPos } from "../Add-on/Cmd_RemovePolylineRepeatPos";
import { Command_PickUp2DModelCsgs } from "../Add-on/Command_PickUp2DModelCsgs";
import { Command_TemplateGroup } from "../Add-on/Command_TemplateGroup";
import { ApplyModel2ToBoard } from "../Add-on/DrawBoard/ApplyModel2ToBoard";
import { ParseHandle } from "../Add-on/DrawBoard/ParseHandle";
import { ParseHinge } from "../Add-on/DrawBoard/ParseHinge";
@ -677,6 +678,7 @@ export function registerCommand()
commandMachine.RegisterCommand(CommandNames.TemplateDesign, new ShowTemplateDesign());
commandMachine.RegisterCommand(CommandNames.templateDelete, new Command_DeleteTemplate());
commandMachine.RegisterCommand(CommandNames.TemplateCheck, new Command_TemplateSearch(true));
commandMachine.RegisterCommand(CommandNames.TemplateGroup, new Command_TemplateGroup());
commandMachine.RegisterCommand(CommandNames.SpliteTemplate, new Command_SplitTemplate());
commandMachine.RegisterCommand("SplitTemplateX", new Command_SplitTemplateByDir(0));
commandMachine.RegisterCommand(CommandNames.SplitTemplateY, new Command_SplitTemplateByDir(1));

@ -177,6 +177,7 @@ export class TopToolBar extends React.Component<{}, {}>
{ svg: IconEnum.ModuleManage, title: "模块管理", command: CommandNames.Template },
{ svg: IconEnum.ReviewTemplate, title: "模板审核", command: CommandNames.TemplateCheck },
{ svg: IconEnum.HoleModule, title: "排钻模块", command: CommandNames.HoleTemplate },
{ svg: IconEnum.TemplateGroup, title: "组合模块", command: CommandNames.TemplateGroup },
];
store.iconList.commodity = [
{ svg: IconEnum.CommodityManage, title: "共享模块", command: CommandNames.TemplateSearch },

@ -244,5 +244,5 @@ export enum IconEnum
DrawGirder = "DrawGirder.svg",//画房梁
BoardInfoDim = "BoardInfoDim.svg",//板件标注
Modeling = "Modeling.svg",//一键建模
TemplateGroup = "TemplateGroup.svg"//组合模块
TemplateGroup = "TemplateGroup.svg",//模块组合
}

Loading…
Cancel
Save