!168 重构绘制面域删除已使用的曲线

Merge pull request !168 from ChenX/RegionEraseUsed
pull/168/MERGE
ChenX 6 years ago
parent f981655ebf
commit 48b88c3bbf

@ -1,8 +1,5 @@
import { app } from '../ApplicationServices/Application';
import { Circle } from '../DatabaseServices/Circle';
import { Curve } from '../DatabaseServices/Curve';
import { Ellipse } from '../DatabaseServices/Ellipse';
import { Polyline } from '../DatabaseServices/Polyline';
import { Region } from '../DatabaseServices/Region';
import { Command } from '../Editor/CommandMachine';
import { PromptStatus } from '../Editor/PromptResult';
@ -10,7 +7,6 @@ import { RegionParse, Route } from '../Geometry/RegionParse';
export class DrawRegion implements Command
{
private m_CurveMap: Map<Curve, { pl?: Polyline, used: boolean }> = new Map();
async exec()
{
let ssRes = await app.m_Editor.GetSelection({ UseSelect: true, Filter: { filterTypes: [Curve] } });
@ -18,72 +14,51 @@ export class DrawRegion implements Command
if (ssRes.Status !== PromptStatus.OK)
return;
this.DrawRegionAndGetCurveMap(ssRes.SelectSet.SelectEntityList as Curve[]);
let cus = ssRes.SelectSet.SelectEntityList as Curve[];
this.DeleteCurvesMap();
this.m_CurveMap.clear();
}
DrawRegionAndGetCurveMap(cus: Curve[])
{
let lines: Curve[] = [];
for (let cu of cus)
{
if (cu.IsClose)
{
this.m_CurveMap.set(cu, { used: true });
let reg = Region.CreateFromCurves([cu.Clone() as Curve]);
app.m_Database.ModelSpace.Append(reg);
}
else if (cu instanceof Polyline)
{
for (let c of cu.Explode())
{
this.m_CurveMap.set(c, { used: false, pl: cu as Polyline });
lines.push(c);
}
cu.Erase();
}
else
{
this.m_CurveMap.set(cu, { used: false });
lines.push(cu);
}
}
if (lines.length > 0)
{
let reg = new RegionParse(lines);
for (let routes of reg.m_RegionsOutline)
this.AddToModelSpace(routes);
this.DrawRegion(routes);
for (let routes of reg.m_RegionsInternal)
this.AddToModelSpace(routes);
this.DrawRegion(routes);
for (let cu of cus)
{
if (reg.GetCueveUsed(cu))
cu.Erase();
}
for (let [, cus] of reg.m_ExpLineMap)
{
for (let c of cus)
if (!reg.GetCueveUsed(c))
app.m_Database.ModelSpace.Append(c);
}
}
}
AddToModelSpace(routeS: Set<Route>)
DrawRegion(routeS: Set<Route>)
{
let cus: Curve[] = [];
for (let r of routeS)
{
this.m_CurveMap.get(r.curve).used = true;
cus.push(r.curve);
}
let reg = Region.CreateFromCurves(cus);
app.m_Database.ModelSpace.Append(reg);
}
DeleteCurvesMap()
{
for (let [cu, status] of this.m_CurveMap)
{
if (status.pl)
{
if (status.used && !status.pl.IsErase)
status.pl.Erase();
else
app.m_Database.ModelSpace.Append(cu);
}
else if (status.used)
cu.Erase();
}
if (reg)
app.m_Database.ModelSpace.Append(reg);
}
}

@ -321,6 +321,7 @@ export class Circle extends Curve
super.ReadFile(file);
let ver = file.Read();
this.m_Radius = file.Read();
this.Update();
}
//对象将自身数据写入到文件.
WriteFile(file: CADFile)

@ -325,7 +325,6 @@ export class Entity extends CADObject
ApplyPartialUndo(undoData: CADObject)
{
super.ApplyPartialUndo(undoData);
this.Update();
}
CopyFrom(obj: CADObject)

@ -1,9 +1,10 @@
import * as THREE from 'three';
import { Box3, Geometry, Matrix4, Object3D, Shape, Vector3 } from 'three';
import { Box3, BufferGeometry, Matrix4, Object3D, Shape, Vector3 } from 'three';
import { arraySortByNumber } from '../Common/ArrayExt';
import { ColorMaterial } from '../Common/ColorPalette';
import { Vec3DTo2D } from '../Common/CurveUtils';
import { Status } from '../Common/Status';
import { BufferGeometryUtils } from '../Geometry/BufferGeometryUtils';
import { equalv3, isParallelTo, MoveMatrix } from '../Geometry/GeUtils';
import { RenderType } from '../GraphicsSystem/Enum';
import { IntersectLineAndArc, IntersectLineAndCircle, IntersectLineAndLine, IntersectOption, IntersectPolylineAndCurve, reverseIntersectOption } from '../GraphicsSystem/IntersectWith';
@ -39,21 +40,15 @@ export class Line extends Curve
}
InitDrawObject(renderType: RenderType = RenderType.Wireframe): Object3D
{
let geo = new Geometry();
geo.vertices.push(this.m_StartPoint, this.m_EndPoint);
return new THREE.Line(geo, ColorMaterial.GetLineMaterial(this.ColorIndex));
return new THREE.Line(
BufferGeometryUtils.CreateFromPts([this.m_StartPoint, this.m_EndPoint]),
ColorMaterial.GetLineMaterial(this.ColorIndex));
}
UpdateDrawObject(type: RenderType, en: Object3D)
{
let lineObj = en as THREE.Line;
let geo = lineObj.geometry as THREE.Geometry;
geo.vertices[0].copy(this.m_StartPoint);
geo.vertices[1].copy(this.m_EndPoint);
geo.verticesNeedUpdate = true;
BufferGeometryUtils.UpdatePts(lineObj.geometry as BufferGeometry, [this.m_StartPoint, this.m_EndPoint]);
}
GetSnapPoints(): Array<THREE.Vector3>
@ -295,6 +290,7 @@ export class Line extends Curve
let ver = file.Read();//1
this.m_StartPoint.fromArray(file.Read());
this.m_EndPoint.fromArray(file.Read());
this.Update();
}
//对象将自身数据写入到文件.
WriteFile(file: CADFile)

@ -1,5 +1,5 @@
import * as THREE from 'three';
import { Box3, Geometry, Matrix4, Object3D, Vector2, Vector3 } from 'three';
import { Box3, Geometry, Matrix4, Object3D, Vector2, Vector3, Matrix3 } from 'three';
import { CreateBoardUtil } from '../ApplicationServices/mesh/createBoard';
import { arrayLast, arrayRemoveDuplicateBySort } from '../Common/ArrayExt';
import { ColorMaterial } from '../Common/ColorPalette';
@ -36,6 +36,28 @@ export class Polyline extends Curve
this.m_ClosedMark = false;
}
/**
* Updates matrix to
* @param m
*/
UpdateMatrixTo(m: Matrix4)
{
this.WriteAllObjectRecord();
let p = new Vector3().setFromMatrixPosition(m);
p.applyMatrix4(this.OCSInv);
if (equaln(p.z, 0))
{
let tm = matrixAlignCoordSys(this.OCS, m);
for (let p of this.m_LineData)
{
let p3 = Vec2DTo3D(p.pt);
p3.applyMatrix4(tm);
p.pt.set(p3.x, p3.y);
}
this.OCS = m;
}
}
//翻转曲线,首尾调换
Reverse(): this
{
@ -1144,7 +1166,3 @@ export class Polyline extends Curve
file.Write(this.m_ClosedMark);
}
}

@ -16,17 +16,17 @@ import { matrixAlignCoordSys } from '../Common/Matrix4Utils';
export class Region extends Entity
{
private m_ShapeManager: ShapeManager = new ShapeManager();
static CreateFromCurves(cus: Curve[]): Region
static CreateFromCurves(cus: Curve[]): Region | undefined
{
let shapes = Contour.GetAllContour(cus).map(out => new Shape(out));
let reg = new Region();
if (shapes.length > 0)
{
let reg = new Region();
//MarkX:曲线同面域一起移动
reg.ApplyMatrix(shapes[0].Outline.Curve.OCS);
reg.ShapeManager.AppendShapeList(shapes);
return reg;
}
reg.ShapeManager.AppendShapeList(shapes);
return reg;
}
//如果需要修改获取到的属性,需要Clone后进行操作,否则会对原实体进行破坏
@ -110,7 +110,6 @@ export class Region extends Entity
if (this.IsCoplaneTo(otherRegion))
{
this.WriteAllObjectRecord();
otherRegion.ShapeApplyMatrix(matrixAlignCoordSys(otherRegion.OCS, this.OCS));
let oldOcs = this.OCS;
//把形状曲线转移到二维屏幕计算后还原回来

@ -279,6 +279,11 @@ export class Shape
UpdateShape()
{
this.m_Shape = this.Outline.Shape;
this.Holes.forEach(h =>
{
if (h.Curve instanceof Polyline)
h.Curve.UpdateMatrixTo(this.Outline.Curve.OCS);
});
this.m_Shape.holes.push(...this.m_Holes.map(h => h.Shape as THREE.Path));
}
//读写文件

@ -1,6 +1,8 @@
import { Vector3 } from 'three';
import { arrayRemoveDuplicateBySort, arrayRemoveIf } from '../Common/ArrayExt';
import { Arc } from '../DatabaseServices/Arc';
import { Curve } from '../DatabaseServices/Curve';
import { Polyline } from '../DatabaseServices/Polyline';
import { Count } from './Count';
import { CurveMap } from './CurveMap';
import { angle, equalv3 } from './GeUtils';
@ -36,6 +38,9 @@ export class RegionParse
//区域列表 通常是内轮廓
m_RegionsInternal: RegionRouteS = [];
//碎线 曲线进入到这里会被炸开.
m_ExpLineMap: Map<Curve, Curve[]> = new Map();
/**
* Creates an instance of RegionParse.
* @param {Curve[]} cuList .
@ -70,6 +75,24 @@ export class RegionParse
}
}
/**
* 线使
* @param cu
* @returns true if cueve used
*/
GetCueveUsed(cu: Curve): boolean
{
if (this.m_ExpLineMap.has(cu))
{
let use = this.m_ExpLineMap.get(cu).some(c => this.m_CountCu.GetCount(c) > 0);
if (!use)
this.m_ExpLineMap.delete(cu);
return use;
}
else
return this.m_CountCu.GetCount(cu) > 0;
}
/**
* 使,,.
* .
@ -172,17 +195,51 @@ export class RegionParse
private GenerateNodeMap(cuList: Curve[]): Set<Stand>
{
let curveMap = new CurveMap();
//将多段线炸开
let plcus: Curve[] = [];
arrayRemoveIf(cuList, c =>
{
if (c instanceof Polyline)
{
let cus = c.Explode();
//如果为圆弧,提前打断
let arcs: Arc[] = [];
arrayRemoveIf(cus, c =>
{
if (c instanceof Arc)
{
let arcBrs = this.BreakArc(c);
if (arcBrs.length > 1)
{
arcs.push(...arcBrs);
return true;
}
}
return false;
});
//加入到计算
cus.push(...arcs);
this.m_ExpLineMap.set(c, cus);
plcus.push(...cus);
return true;
}
return false;
});
cuList.push(...plcus);
for (let cu of cuList)
{
//由于圆弧可能导致最低点计算错误的问题.
if (cu instanceof Arc)
{
let underPt = cu.Center.add(new Vector3(0, -cu.Radius));
let param = cu.GetParamAtPoint(underPt);
if (param > 0.01 && param < 0.99)
let arcs = this.BreakArc(cu);
if (arcs.length > 1)
{
let arcs = cu.GetSplitCurves(param);
arcs.forEach(a => curveMap.addCurveToMap(a));
this.m_ExpLineMap.set(cu, arcs);
continue;
}
}
@ -206,12 +263,28 @@ export class RegionParse
a2 = angle(r2.curve.GetFistDeriv(r1.curve.EndParam).negate());
return a1 - a2;
})
});
//移除重复的线
arrayRemoveDuplicateBySort(s.routes, (r1, r2) =>
{
return r1.to === r2.to && r1.curve.constructor.name === r2.curve.constructor.name;
});
});
return new Set(curveMap.Stands);
}
private BreakArc(arc: Arc)
{
let underPt = arc.Center.add(new Vector3(0, -arc.Radius));
let param = arc.GetParamAtPoint(underPt);
if (param > 0.01 && param < 0.99)
return arc.GetSplitCurves(param);
else
return [arc];
}
//寻找闭合轮廓,下一站总是使用逆时针规划.
private FindRegion(firstS: Stand, //起点
nowStand: Stand, //当前站

Loading…
Cancel
Save