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..43a56d6bb58a9a16defcb881a663a4c1f319df3c 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,4 +1,4 @@ -namespace IFoxCAD.Cad; +namespace IFoxCAD.Cad; using System.Data; @@ -35,9 +35,10 @@ public CircleData(PointV symmetryAxisPoint1, PointV symmetryAxisPoint2) /// class HatchConverterData { - public List PolyLineData; + public List> PolyLineData; public List CircleData; public List SplineData; + public List EllipseData; /// /// 填充转换器的数据 @@ -47,6 +48,7 @@ public HatchConverterData() PolyLineData = new(); CircleData = new(); SplineData = new(); + EllipseData = new(); } } #endregion @@ -180,8 +182,10 @@ static void HatchLoopIsPolyline(HatchLoop loop, HatchConverterData hcData) { // 遍历多段线信息 var bvc = loop.Polyline; + var bvws = new List(); 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 +235,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; //遍历边界的第一个子段为多段线(遍历时不一定从多段线的首段开始) + List? 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 List(); + 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[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 +318,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 =>