!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 { app } from '../ApplicationServices/Application';
import { Circle } from '../DatabaseServices/Circle';
import { Curve } from '../DatabaseServices/Curve'; import { Curve } from '../DatabaseServices/Curve';
import { Ellipse } from '../DatabaseServices/Ellipse';
import { Polyline } from '../DatabaseServices/Polyline';
import { Region } from '../DatabaseServices/Region'; import { Region } from '../DatabaseServices/Region';
import { Command } from '../Editor/CommandMachine'; import { Command } from '../Editor/CommandMachine';
import { PromptStatus } from '../Editor/PromptResult'; import { PromptStatus } from '../Editor/PromptResult';
@ -10,7 +7,6 @@ import { RegionParse, Route } from '../Geometry/RegionParse';
export class DrawRegion implements Command export class DrawRegion implements Command
{ {
private m_CurveMap: Map<Curve, { pl?: Polyline, used: boolean }> = new Map();
async exec() async exec()
{ {
let ssRes = await app.m_Editor.GetSelection({ UseSelect: true, Filter: { filterTypes: [Curve] } }); 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) if (ssRes.Status !== PromptStatus.OK)
return; 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[] = []; let lines: Curve[] = [];
for (let cu of cus) for (let cu of cus)
{ {
if (cu.IsClose) if (cu.IsClose)
{ {
this.m_CurveMap.set(cu, { used: true });
let reg = Region.CreateFromCurves([cu.Clone() as Curve]); let reg = Region.CreateFromCurves([cu.Clone() as Curve]);
app.m_Database.ModelSpace.Append(reg); app.m_Database.ModelSpace.Append(reg);
} cu.Erase();
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);
}
} }
else else
{
this.m_CurveMap.set(cu, { used: false });
lines.push(cu); lines.push(cu);
}
} }
if (lines.length > 0) if (lines.length > 0)
{ {
let reg = new RegionParse(lines); let reg = new RegionParse(lines);
for (let routes of reg.m_RegionsOutline) for (let routes of reg.m_RegionsOutline)
this.AddToModelSpace(routes); this.DrawRegion(routes);
for (let routes of reg.m_RegionsInternal) 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[] = []; let cus: Curve[] = [];
for (let r of routeS) for (let r of routeS)
{
this.m_CurveMap.get(r.curve).used = true;
cus.push(r.curve); cus.push(r.curve);
}
let reg = Region.CreateFromCurves(cus); let reg = Region.CreateFromCurves(cus);
app.m_Database.ModelSpace.Append(reg); if (reg)
} 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();
}
} }
} }

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

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

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

@ -1,5 +1,5 @@
import * as THREE from 'three'; 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 { CreateBoardUtil } from '../ApplicationServices/mesh/createBoard';
import { arrayLast, arrayRemoveDuplicateBySort } from '../Common/ArrayExt'; import { arrayLast, arrayRemoveDuplicateBySort } from '../Common/ArrayExt';
import { ColorMaterial } from '../Common/ColorPalette'; import { ColorMaterial } from '../Common/ColorPalette';
@ -36,6 +36,28 @@ export class Polyline extends Curve
this.m_ClosedMark = false; 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 Reverse(): this
{ {
@ -1144,7 +1166,3 @@ export class Polyline extends Curve
file.Write(this.m_ClosedMark); file.Write(this.m_ClosedMark);
} }
} }

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

@ -279,6 +279,11 @@ export class Shape
UpdateShape() UpdateShape()
{ {
this.m_Shape = this.Outline.Shape; 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)); this.m_Shape.holes.push(...this.m_Holes.map(h => h.Shape as THREE.Path));
} }
//读写文件 //读写文件

@ -1,6 +1,8 @@
import { Vector3 } from 'three'; import { Vector3 } from 'three';
import { arrayRemoveDuplicateBySort, arrayRemoveIf } from '../Common/ArrayExt';
import { Arc } from '../DatabaseServices/Arc'; import { Arc } from '../DatabaseServices/Arc';
import { Curve } from '../DatabaseServices/Curve'; import { Curve } from '../DatabaseServices/Curve';
import { Polyline } from '../DatabaseServices/Polyline';
import { Count } from './Count'; import { Count } from './Count';
import { CurveMap } from './CurveMap'; import { CurveMap } from './CurveMap';
import { angle, equalv3 } from './GeUtils'; import { angle, equalv3 } from './GeUtils';
@ -36,6 +38,9 @@ export class RegionParse
//区域列表 通常是内轮廓 //区域列表 通常是内轮廓
m_RegionsInternal: RegionRouteS = []; m_RegionsInternal: RegionRouteS = [];
//碎线 曲线进入到这里会被炸开.
m_ExpLineMap: Map<Curve, Curve[]> = new Map();
/** /**
* Creates an instance of RegionParse. * Creates an instance of RegionParse.
* @param {Curve[]} cuList . * @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> private GenerateNodeMap(cuList: Curve[]): Set<Stand>
{ {
let curveMap = new CurveMap(); 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) for (let cu of cuList)
{ {
//由于圆弧可能导致最低点计算错误的问题. //由于圆弧可能导致最低点计算错误的问题.
if (cu instanceof Arc) if (cu instanceof Arc)
{ {
let underPt = cu.Center.add(new Vector3(0, -cu.Radius)); let arcs = this.BreakArc(cu);
let param = cu.GetParamAtPoint(underPt); if (arcs.length > 1)
if (param > 0.01 && param < 0.99)
{ {
let arcs = cu.GetSplitCurves(param);
arcs.forEach(a => curveMap.addCurveToMap(a)); arcs.forEach(a => curveMap.addCurveToMap(a));
this.m_ExpLineMap.set(cu, arcs);
continue; continue;
} }
} }
@ -206,12 +263,28 @@ export class RegionParse
a2 = angle(r2.curve.GetFistDeriv(r1.curve.EndParam).negate()); a2 = angle(r2.curve.GetFistDeriv(r1.curve.EndParam).negate());
return a1 - a2; 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); 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, //起点 private FindRegion(firstS: Stand, //起点
nowStand: Stand, //当前站 nowStand: Stand, //当前站

Loading…
Cancel
Save