!451 自动标注的优化

pull/451/MERGE
肖诗雅 5 years ago committed by ChenX
parent a78851c73c
commit 8603e83fb5

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

@ -7,6 +7,8 @@ import { JigUtils } from "../../Editor/JigUtils";
import { AlignedDimension } from "../../DatabaseServices/Dimension/AlignedDimension";
import { CoordinateSystem } from "../../Geometry/CoordinateSystem";
import { Command_AutoDimBrs } from "./AutoDimBrs";
import { Math as TMath } from "three";
import { equaln } from "../../Geometry/GeUtils";
enum Direction
{
@ -16,6 +18,7 @@ enum Direction
top = 8
}
const DEG90 = TMath.radToDeg(Math.PI / 2);//90°
export class Command_FastDimBrs implements Command
{
async exec()
@ -30,6 +33,21 @@ export class Command_FastDimBrs implements Command
let brs = enRes.SelectSet.SelectEntityList as Board[];
//排除旋转角度非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;
}
app.Editor.Prompt(`可标注板件数: ${brs.length}`);
let autoDim = new Command_AutoDimBrs();
let ucs = app.Editor.UCSMatrix;

@ -220,13 +220,13 @@ export class OBB
// intersectsAABB(box: THREE.Box3): boolean
// intersectsSphere(sphere: THREE.Sphere): boolean
// intersectsOBB(box: OBB): boolean;
// intersectsPlane(plane: THREE.Plane): boolean
// intersectsRay(ray: THREE.Ray): boolean
// intersectRay(ray: THREE.Ray): THREE.Vector3
// intersectSphere(sphere: THREE.Sphere): THREE.Vector3
// size(optionalTarget: THREE.Vector3): THREE.Vector3
// intersectsPlane(plane: Plane): boolean
// intersectsRay(ray: Ray): boolean
// intersectRay(ray: Ray): Vector3
// intersectSphere(sphere: Sphere): Vector3
// size(optionalTarget: Vector3): Vector3
// translate(offset: THREE.Vector3): OBB
// translate(offset: Vector3): OBB
// copy(obb: OBB): OBB
// clone(obb: OBB): OBB

@ -82,8 +82,8 @@ export class TopToolBar extends React.Component<{}, {}>
{ svg: IconEnum.Circle, title: "半径标注", command: "DIMRAD" },
{ svg: IconEnum.Diameter, title: "直径标注", command: "DIMDIA" },
{ svg: IconEnum.AutoDim, title: "柜体标注", command: "AUTODIMBRS" },
{ svg: IconEnum.FastDim, title: "自由标注", command: "AUTODIMBRS" },
{ svg: IconEnum.DelDim, title: "快速删除", command: "AUTODIMBRS" },
{ svg: IconEnum.FastDim, title: "自由标注", command: "FASTDIMBRS" },
{ svg: IconEnum.DelDim, title: "快速删除", command: "DELETEDIM" },
]
store.iconList.light = [
{ svg: IconEnum.SpotLamp, title: "射灯", command: "SL" },

Loading…
Cancel
Save