diff --git "a/src/CAD/IFox.CAD.Shared/ExtensionMethod/\346\226\260\345\273\272\345\241\253\345\205\205/HatchConverter.cs" "b/src/CAD/IFox.CAD.Shared/ExtensionMethod/\346\226\260\345\273\272\345\241\253\345\205\205/HatchConverter.cs"
index 9e16d24191ad01a7889f42dca2ce9731c27bd02d..ab8edf42ca505e5e4a32761e19ac8401fd79f775 100644
--- "a/src/CAD/IFox.CAD.Shared/ExtensionMethod/\346\226\260\345\273\272\345\241\253\345\205\205/HatchConverter.cs"
+++ "b/src/CAD/IFox.CAD.Shared/ExtensionMethod/\346\226\260\345\273\272\345\241\253\345\205\205/HatchConverter.cs"
@@ -1,8 +1,4 @@
-namespace IFoxCAD.Cad;
-
-
-using System.Data;
-using PointV = Point2d;
+namespace IFoxCAD.Cad;
///
/// 填充边界转换器
@@ -15,7 +11,7 @@ public class HatchConverter
///
class CircleData
{
- public PointV Center;
+ public Point2d Center;
public double Radius;
///
@@ -23,21 +19,29 @@ class CircleData
///
/// 对称点1
/// 对称点2
- public CircleData(PointV symmetryAxisPoint1, PointV symmetryAxisPoint2)
+ public CircleData(Point2d symmetryAxisPoint1, Point2d symmetryAxisPoint2)
{
Center = PointEx.GetMidPointTo(symmetryAxisPoint1, symmetryAxisPoint2);
Radius = symmetryAxisPoint1.GetDistanceTo(symmetryAxisPoint2) * 0.5;
}
}
+ ///
+ /// 段段线顶点
+ ///
+ class PolyLineVertexes : List
+ {
+ }
+
///
/// 填充转换器的数据
///
class HatchConverterData
{
- public List PolyLineData;
+ public List PolyLineData;
public List CircleData;
public List SplineData;
+ public List EllipseData;
///
/// 填充转换器的数据
@@ -47,6 +51,7 @@ public HatchConverterData()
PolyLineData = new();
CircleData = new();
SplineData = new();
+ EllipseData = new();
}
}
#endregion
@@ -167,7 +172,6 @@ static void HatchLoopIsPolyline(HatchLoop loop, HatchConverterData hcData)
ArgumentNullEx.ThrowIfNull(loop);
ArgumentNullEx.ThrowIfNull(hcData);
-
// 判断为圆形:
// 上下两个圆弧,然后填充,就会生成此种填充
// 顶点数是3,凸度是半圆,两个半圆就是一个圆形
@@ -180,8 +184,10 @@ static void HatchLoopIsPolyline(HatchLoop loop, HatchConverterData hcData)
{
// 遍历多段线信息
var bvc = loop.Polyline;
+ var bvws = new PolyLineVertexes();
for (int i = 0; i < bvc.Count; i++)
- hcData.PolyLineData.Add(new BulgeVertexWidth(bvc[i]));
+ bvws.Add(new BulgeVertexWidth(bvc[i]));
+ hcData.PolyLineData.Add(bvws);
}
}
@@ -231,38 +237,79 @@ static void HatchLoopIsPolyline(HatchLoop loop, HatchConverterData hcData)
/// 收集图元信息
static void HatchLoopIsCurve2d(HatchLoop loop, HatchConverterData hcData)
{
- // 取每一段曲线,曲线可能是直线来的,但是圆弧会按照顶点来分段
- int curveIsClosed = 0;
+ int curveIsClosed = 0; // 取每一段曲线,曲线可能是直线来的,但是圆弧会按照顶点来分段
+ bool newPline = true; // 是否开始新的多段线(一个边界中可能有多条多段线)
+ bool firstIsPline = false; //遍历边界的第一个子段为多段线(遍历时不一定从多段线的首段开始)
+ PolyLineVertexes? bvws = null;
// 遍历边界的多个子段
foreach (Curve2d curve in loop.Curves)
{
// 计数用于实现闭合
curveIsClosed++;
- if (curve is NurbCurve2d spl)
- {
- // 判断为样条曲线:
- hcData.SplineData.Add(spl);
- continue;
- }
- var pts = curve.GetSamplePoints(3);
- var midPt = pts[1];
- if (curve.StartPoint.IsEqualTo(curve.EndPoint, new Tolerance(1e-6, 1e-6)))// 首尾相同,就是圆形
+ if (curve is CircularArc2d or LineSegment2d)
{
- // 判断为圆形:
- // 获取起点,然后采样三点,中间就是对称点(直径点)
- hcData.CircleData.Add(new CircleData(curve.StartPoint, midPt));
+ var pts = curve.GetSamplePoints(3);
+ var midPt = pts[1];
+
+ // 判断为多段线圆:
+ // 首尾相同,就是圆形
+ if (curve.StartPoint.IsEqualTo(curve.EndPoint, new Tolerance(1e-6, 1e-6)))
+ {
+ // 获取起点,然后采样三点,中间就是对称点(直径点)
+ hcData.CircleData.Add(new CircleData(curve.StartPoint, midPt));
+ // 添加在中部的多段线末尾点
+ if (curveIsClosed > 1 && !newPline)
+ bvws?.Add(new BulgeVertexWidth(curve.StartPoint, 0));
+ // 开始新的多段线
+ newPline = true;
+ continue;
+ }
+
+ if (curveIsClosed == 1)
+ firstIsPline = true;
+
+ if (newPline)
+ {
+ bvws = new PolyLineVertexes();
+ hcData.PolyLineData.Add(bvws);
+ newPline = false;
+ }
+
+ // 判断为多段线,圆弧或直线:
+ double bulge = curve.StartPoint.GetArcBulge(midPt, curve.EndPoint);
+ bvws?.Add(new BulgeVertexWidth(curve.StartPoint, bulge));
+
+ // 末尾点,不闭合的情况下就要获取这个
+ if (curveIsClosed == loop.Curves.Count)
+ {
+ if (firstIsPline && hcData.PolyLineData.Count > 1)
+ {
+ // 连接首尾多段线
+ hcData.PolyLineData[0].ForEach(bvw => hcData.PolyLineData[^1].Add(bvw));
+ hcData.PolyLineData.RemoveAt(0);
+ }
+ else
+ bvws?.Add(new BulgeVertexWidth(curve.EndPoint, 0));
+ }
+
continue;
}
- // 判断为多段线,圆弧:
- double bulge = curve.StartPoint.GetArcBulge(midPt, curve.EndPoint);
- hcData.PolyLineData.Add(new BulgeVertexWidth(curve.StartPoint, bulge));
+ // 判断为样条曲线:
+ if (curve is NurbCurve2d spl)
+ hcData.SplineData.Add(spl);
+
+ // 判断为椭圆:
+ if (curve is EllipticalArc2d ellipse)
+ hcData.EllipseData.Add(ellipse);
- // 末尾点,不闭合的情况下就要获取这个
- if (curveIsClosed == loop.Curves.Count)
- hcData.PolyLineData.Add(new BulgeVertexWidth(curve.EndPoint, 0));
+ // 添加在中部的多段线末尾点
+ if (curveIsClosed > 1 && !newPline)
+ bvws?.Add(new BulgeVertexWidth(curve.StartPoint, 0));
+ // 开始新的多段线
+ newPline = true;
}
}
@@ -273,70 +320,45 @@ static void HatchLoopIsCurve2d(HatchLoop loop, HatchConverterData hcData)
[Obsolete("使用带返回值的CreateBoundary替代")]
public void CreateBoundary(List outEnts)
{
+ outEnts.AddRange(CreateBoundary());
+ }
+
+ ///
+ /// 创建边界图元
+ ///
+ ///
+ public List CreateBoundary()
+ {
+ var outEnts = new List();
for (int i = 0; i < _hcDatas.Count; i++)
{
var data = _hcDatas[i];
// 生成边界:多段线
- if (data.PolyLineData.Count > 0)
+ data.PolyLineData.ForEach(bvws =>
{
- Polyline pl = new();
+ if (bvws.Count == 0) return;
+ var pl = new Polyline();
pl.SetDatabaseDefaults();
- for (int j = 0; j < data.PolyLineData.Count; j++)
- {
- pl.AddVertexAt(j,
- data.PolyLineData[j].Vertex,
- data.PolyLineData[j].Bulge,
- data.PolyLineData[j].StartWidth,
- data.PolyLineData[j].EndWidth);
- }
+ for (int j = 0; j < bvws.Count; j++)
+ pl.AddVertexAt(j, bvws[j].Vertex, bvws[j].Bulge, bvws[j].StartWidth, bvws[j].EndWidth);
outEnts.Add(pl);
- }
-
- // 生成边界:圆
- data.CircleData.ForEach(item =>
- {
- outEnts.Add(new Circle(item.Center.Point3d(), Vector3d.ZAxis, item.Radius));
});
- // 生成边界:样条曲线
- data.SplineData.ForEach(item =>
- {
- outEnts.Add(item.ToCurve());
- });
- }
-
- if (_oldHatch is not null)
- {
- outEnts.ForEach(ent =>
+ // 生成边界:椭圆
+ data.EllipseData.ForEach(item =>
{
- ent.Color = _oldHatch.Color;
- ent.Layer = _oldHatch.Layer;
+ var startParam = item.IsClockWise ? -item.EndAngle : item.StartAngle;
+ var endParam = item.IsClockWise ? -item.StartAngle : item.EndAngle;
+ var ellipse = new Ellipse(
+ item.Center.Point3d(),
+ Vector3d.ZAxis,
+ item.MajorAxis.Convert3d() * item.MajorRadius,
+ item.MinorRadius / item.MajorRadius,
+ Math.Atan2(Math.Sin(startParam) * item.MinorRadius, Math.Cos(startParam) * item.MajorRadius),
+ Math.Atan2(Math.Sin(endParam) * item.MinorRadius, Math.Cos(endParam) * item.MajorRadius));
+ outEnts.Add(ellipse);
});
- }
- }
- public List CreateBoundary()
- {
- List outEnts = new List();
- for (int i = 0; i < _hcDatas.Count; i++)
- {
- var data = _hcDatas[i];
-
- // 生成边界:多段线
- if (data.PolyLineData.Count > 0)
- {
- Polyline pl = new();
- pl.SetDatabaseDefaults();
- for (int j = 0; j < data.PolyLineData.Count; j++)
- {
- pl.AddVertexAt(j,
- data.PolyLineData[j].Vertex,
- data.PolyLineData[j].Bulge,
- data.PolyLineData[j].StartWidth,
- data.PolyLineData[j].EndWidth);
- }
- outEnts.Add(pl);
- }
// 生成边界:圆
data.CircleData.ForEach(item =>