|
|
|
@ -6,9 +6,33 @@ import { Board } from "../../DatabaseServices/Entity/Board";
|
|
|
|
|
import { Command } from "../../Editor/CommandMachine";
|
|
|
|
|
import { PromptStatus } from "../../Editor/PromptResult";
|
|
|
|
|
import { CoordinateSystem } from "../../Geometry/CoordinateSystem";
|
|
|
|
|
import { equalnn, equaln } from "../../Geometry/GeUtils";
|
|
|
|
|
import { equalnn, equaln, isParallelTo } from "../../Geometry/GeUtils";
|
|
|
|
|
import { JigUtils } from "../../Editor/JigUtils";
|
|
|
|
|
import { SurroundOutlineParse } from "../../Geometry/SpaceParse/SurroundOutlineParse";
|
|
|
|
|
import { ViewChange } from "../ViewChange";
|
|
|
|
|
import { Polyline } from "../../DatabaseServices/Entity/Polyline";
|
|
|
|
|
import { Curve } from "../../DatabaseServices/Entity/Curve";
|
|
|
|
|
import { BoardType } from "../Erp/Models/CadBlock";
|
|
|
|
|
import { Entity } from "../../DatabaseServices/Entity/Entity";
|
|
|
|
|
import { OBB } from "../../Geometry/OBB/obb";
|
|
|
|
|
import { Math as TMath } from "three";
|
|
|
|
|
|
|
|
|
|
interface DirPls
|
|
|
|
|
{
|
|
|
|
|
left: Curve[];
|
|
|
|
|
right: Curve[];
|
|
|
|
|
top: Curve[];
|
|
|
|
|
bottom: Curve[];
|
|
|
|
|
}
|
|
|
|
|
interface DirBrs
|
|
|
|
|
{
|
|
|
|
|
left: Board[];
|
|
|
|
|
right: Board[];
|
|
|
|
|
top: Board[];
|
|
|
|
|
bottom: Board[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const DEG90 = TMath.radToDeg(Math.PI / 2);//90°
|
|
|
|
|
export class Command_AutoDimBrs implements Command
|
|
|
|
|
{
|
|
|
|
|
async exec()
|
|
|
|
@ -16,30 +40,35 @@ export class Command_AutoDimBrs implements Command
|
|
|
|
|
//选择板件
|
|
|
|
|
let enRes = await app.Editor.GetSelection({
|
|
|
|
|
Msg: "选择需要标注的柜体",
|
|
|
|
|
Filter: { filterTypes: [Board] }
|
|
|
|
|
Filter: {
|
|
|
|
|
filterFunction: (_object, board: Entity) =>
|
|
|
|
|
{
|
|
|
|
|
return (board instanceof Board && (board.BoardType !== BoardType.Behind));
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (enRes.Status === PromptStatus.Cancel)
|
|
|
|
|
if (enRes.Status !== PromptStatus.OK)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
let brs = enRes.SelectSet.SelectEntityList as Board[];
|
|
|
|
|
|
|
|
|
|
//原数据转二维数组[[br0],[br1],[br2],[br3],[br4]...],并记录每组的Box
|
|
|
|
|
let brBoxs: Box3[] = [];
|
|
|
|
|
let brRes: Board[][] = brs.map(item =>
|
|
|
|
|
let brGroups: Board[][] = brs.map(item =>
|
|
|
|
|
{
|
|
|
|
|
brBoxs.push(item.BoundingBox);
|
|
|
|
|
return [item];
|
|
|
|
|
});
|
|
|
|
|
for (let i = 0; i < brRes.length; i++)
|
|
|
|
|
for (let i = 0; i < brGroups.length; i++)
|
|
|
|
|
{
|
|
|
|
|
for (let j = i + 1; j < brRes.length; j++)
|
|
|
|
|
for (let j = i + 1; j < brGroups.length; j++)
|
|
|
|
|
{
|
|
|
|
|
//如有合并则重新开始
|
|
|
|
|
if (brBoxs[i].intersectsBox(brBoxs[j]))
|
|
|
|
|
{
|
|
|
|
|
brRes[i] = [...brRes[i], ...brRes[j]];
|
|
|
|
|
brGroups[i] = [...brGroups[i], ...brGroups[j]];
|
|
|
|
|
brBoxs[i].union(brBoxs[j]);
|
|
|
|
|
brRes.splice(j, 1);
|
|
|
|
|
brGroups.splice(j, 1);
|
|
|
|
|
brBoxs.splice(j, 1);
|
|
|
|
|
i = -1;
|
|
|
|
|
break;
|
|
|
|
@ -47,26 +76,104 @@ export class Command_AutoDimBrs implements Command
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (let brs of brRes)
|
|
|
|
|
for (let brs of brGroups)
|
|
|
|
|
{
|
|
|
|
|
let spaceOcs = brs[0].SpaceOCS;
|
|
|
|
|
let cs = new CoordinateSystem().CopyForm(spaceOcs);
|
|
|
|
|
|
|
|
|
|
//排除旋转角度非90度倍数的板件
|
|
|
|
|
brs = brs.filter(b => (
|
|
|
|
|
equaln((TMath.radToDeg(b.Rotation.x) + 90) % (DEG90), 0)
|
|
|
|
|
&& equaln((TMath.radToDeg(b.Rotation.y) + 90) % (DEG90), 0)
|
|
|
|
|
&& equaln((TMath.radToDeg(b.Rotation.z) + 90) % (DEG90), 0)
|
|
|
|
|
));
|
|
|
|
|
|
|
|
|
|
if (brs.length === 0)
|
|
|
|
|
{
|
|
|
|
|
app.Editor.Prompt(`可标注板件数: 0, 已退出`);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let right = new Matrix4()
|
|
|
|
|
.makeBasis(cs.YAxis, cs.XAxis.clone().negate(), cs.ZAxis)
|
|
|
|
|
.copyPosition(spaceOcs);
|
|
|
|
|
let front = new Matrix4()
|
|
|
|
|
.makeBasis(cs.ZAxis, cs.XAxis.clone().negate(), cs.YAxis.clone().negate())
|
|
|
|
|
.copyPosition(spaceOcs);
|
|
|
|
|
|
|
|
|
|
this.DrawDim(brs, spaceOcs);
|
|
|
|
|
//绘制右侧标注(俯视图)
|
|
|
|
|
this.DrawDim(brs, right, -Math.PI);
|
|
|
|
|
this.DrawDim(brs, front, -Math.PI);
|
|
|
|
|
//绘制前视图的标注
|
|
|
|
|
await this.DrawFrontDim(brs, -Math.PI);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* 绘制前视图的标注
|
|
|
|
|
* @param brs 需要绘制前视图标注的板件
|
|
|
|
|
* @param textRo 字体旋转角度(弧度形式)
|
|
|
|
|
*/
|
|
|
|
|
async DrawFrontDim(brs: Board[], textRo: number)
|
|
|
|
|
{
|
|
|
|
|
//构造绘制坐标
|
|
|
|
|
let spaceOcs = brs[0].SpaceOCS;
|
|
|
|
|
let cs = new CoordinateSystem().CopyForm(spaceOcs);
|
|
|
|
|
|
|
|
|
|
let drawCS_right = new Matrix4()
|
|
|
|
|
.makeBasis(cs.ZAxis, cs.XAxis.clone().negate(), cs.YAxis)
|
|
|
|
|
.copyPosition(spaceOcs);
|
|
|
|
|
let drawCS_left = new Matrix4()
|
|
|
|
|
.makeBasis(cs.ZAxis.clone().negate(), cs.XAxis, cs.YAxis)
|
|
|
|
|
.copyPosition(spaceOcs);
|
|
|
|
|
let drawCS_top = new Matrix4()
|
|
|
|
|
.makeBasis(cs.XAxis.clone().negate(), cs.ZAxis.clone().negate(), cs.YAxis)
|
|
|
|
|
.copyPosition(spaceOcs);
|
|
|
|
|
let drawCS_bottom = new Matrix4()
|
|
|
|
|
.makeBasis(cs.XAxis, cs.ZAxis, cs.YAxis)
|
|
|
|
|
.copyPosition(spaceOcs);
|
|
|
|
|
|
|
|
|
|
//获得外轮廓
|
|
|
|
|
let viewDir = cs.YAxis;
|
|
|
|
|
let oldUCS = app.Editor.UCSMatrix;
|
|
|
|
|
let viewChange = new ViewChange(viewDir);
|
|
|
|
|
viewChange.UcsLookAt(viewDir);
|
|
|
|
|
let spaceParse = new SurroundOutlineParse(brs);
|
|
|
|
|
await spaceParse.Parse();
|
|
|
|
|
app.Editor.UCSMatrix = oldUCS;
|
|
|
|
|
|
|
|
|
|
let pl = new Polyline();
|
|
|
|
|
for (let cu of spaceParse.m_Outlines)
|
|
|
|
|
{
|
|
|
|
|
pl.Join(cu);
|
|
|
|
|
cu.Erase();
|
|
|
|
|
}
|
|
|
|
|
pl.CloseMark = true;
|
|
|
|
|
|
|
|
|
|
//分析外轮廓上下左右并得到上下左右的板件
|
|
|
|
|
let dirPls = this.JudgeOutlineDirection(pl, cs);
|
|
|
|
|
let dirBrs: DirBrs = { right: [], left: [], top: [], bottom: [] };
|
|
|
|
|
|
|
|
|
|
for (let key in dirPls)
|
|
|
|
|
{
|
|
|
|
|
for (let i = 0; i < dirPls[key].length; i++)
|
|
|
|
|
{
|
|
|
|
|
let l = dirPls[key][i] as Curve;
|
|
|
|
|
let xv = l.EndPoint.sub(l.StartPoint);
|
|
|
|
|
let zv = viewDir;
|
|
|
|
|
let yv = zv.clone().cross(xv);
|
|
|
|
|
let ocs = new Matrix4().makeBasis(xv.normalize(), yv.negate().normalize(), zv.normalize());
|
|
|
|
|
ocs.setPosition(l.StartPoint);
|
|
|
|
|
|
|
|
|
|
let cuObb = new OBB(ocs, new Vector3(l.Length, 20, 20).multiplyScalar(0.5));
|
|
|
|
|
dirBrs[key].push(...brs.filter(b => cuObb.intersectsOBB(b.OBB)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//绘制标注
|
|
|
|
|
if (dirBrs.top.length > 0) this.DrawDim(dirBrs.top, drawCS_top, textRo);
|
|
|
|
|
if (dirBrs.right.length > 0) this.DrawDim(dirBrs.right, drawCS_right, textRo);
|
|
|
|
|
if (dirBrs.left.length > 0) this.DrawDim(dirBrs.left, drawCS_left, textRo);
|
|
|
|
|
if (dirBrs.bottom.length > 0) this.DrawDim(dirBrs.bottom, drawCS_bottom);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 绘制标注
|
|
|
|
|
* @param brs
|
|
|
|
|
* @param drawCS 绘制标注的坐标系
|
|
|
|
|
*/
|
|
|
|
@ -80,9 +187,6 @@ export class Command_AutoDimBrs implements Command
|
|
|
|
|
let drawCSInv = new Matrix4().getInverse(drawCS);
|
|
|
|
|
for (let br of brs)
|
|
|
|
|
{
|
|
|
|
|
//排除酒格
|
|
|
|
|
if (!(equaln(br.Rotation.x, 0) && equaln(br.Rotation.y, 0) && equaln(br.Rotation.z, 0)))
|
|
|
|
|
continue;
|
|
|
|
|
let mtx = new Matrix4().multiplyMatrices(drawCSInv, br.OCS);
|
|
|
|
|
let box = br.BoundingBoxInOCS.applyMatrix4(mtx);
|
|
|
|
|
foots.push(box.min.x, box.max.x);
|
|
|
|
@ -91,15 +195,30 @@ export class Command_AutoDimBrs implements Command
|
|
|
|
|
maxZ = Math.max(maxZ, box.max.z);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!needJig)
|
|
|
|
|
minZ = 0;
|
|
|
|
|
|
|
|
|
|
arraySortByNumber(foots);
|
|
|
|
|
arrayRemoveDuplicateBySort(foots, equalnn(1));
|
|
|
|
|
|
|
|
|
|
let drawY = minY - 20;
|
|
|
|
|
let armY = drawY - 100;
|
|
|
|
|
let z = useMaxZ ? maxZ : minZ;
|
|
|
|
|
let drawYTotal = minY - 120;
|
|
|
|
|
let armYTotal = drawYTotal - 100;
|
|
|
|
|
|
|
|
|
|
if (!needJig)
|
|
|
|
|
{
|
|
|
|
|
//draw总长
|
|
|
|
|
let alDimTotal = new AlignedDimension(
|
|
|
|
|
new Vector3(foots[0], drawYTotal, z),
|
|
|
|
|
new Vector3(foots[foots.length - 1], drawYTotal, z),
|
|
|
|
|
new Vector3(foots[0], armYTotal, z),
|
|
|
|
|
new Vector3(foots[foots.length - 1], armYTotal, z)
|
|
|
|
|
);
|
|
|
|
|
if (textRotation)
|
|
|
|
|
alDimTotal.TextRotation = textRotation;
|
|
|
|
|
|
|
|
|
|
alDimTotal.ApplyMatrix(drawCS);
|
|
|
|
|
app.Database.ModelSpace.Append(alDimTotal);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//draw
|
|
|
|
|
for (let i = 0; i < foots.length - 1; i++)
|
|
|
|
@ -128,4 +247,36 @@ export class Command_AutoDimBrs implements Command
|
|
|
|
|
}
|
|
|
|
|
return als;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 判断轮廓的上下左右
|
|
|
|
|
* @param pl 轮廓(多段线)
|
|
|
|
|
* @param cs 参照坐标系
|
|
|
|
|
* @memberof Command_AutoDimBrs
|
|
|
|
|
*/
|
|
|
|
|
JudgeOutlineDirection(pl: Polyline, cs: CoordinateSystem): DirPls
|
|
|
|
|
{
|
|
|
|
|
let clockWise = pl.Area2 < 0;//true为顺时针 false为逆时针
|
|
|
|
|
let res: DirPls = { right: [], left: [], top: [], bottom: [] };
|
|
|
|
|
for (let i = 0; i < pl.EndParam; i++)
|
|
|
|
|
{
|
|
|
|
|
let cu = pl.GetCurveAtParam(i);
|
|
|
|
|
let derv = cu.GetFistDeriv(0).normalize();
|
|
|
|
|
if (isParallelTo(derv, cs.XAxis))
|
|
|
|
|
{
|
|
|
|
|
if (derv.dot(cs.XAxis) > 0)
|
|
|
|
|
clockWise ? res.top.push(cu) : res.bottom.push(cu);
|
|
|
|
|
else
|
|
|
|
|
clockWise ? res.bottom.push(cu) : res.top.push(cu);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (derv.dot(cs.ZAxis) < 0)
|
|
|
|
|
clockWise ? res.right.push(cu) : res.left.push(cu);
|
|
|
|
|
else
|
|
|
|
|
clockWise ? res.left.push(cu) : res.right.push(cu);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|