• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

DomCR / ACadSharp / 18314169605

07 Oct 2025 01:24PM UTC coverage: 77.952% (-0.06%) from 78.015%
18314169605

push

github

web-flow
Merge pull request #813 from DomCR/polyline-refactor

Polyline refactor

6797 of 9463 branches covered (71.83%)

Branch coverage included in aggregate %.

90 of 112 new or added lines in 10 files covered. (80.36%)

46 existing lines in 4 files now uncovered.

26133 of 32781 relevant lines covered (79.72%)

109153.14 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

44.37
/src/ACadSharp/Entities/PolyLine.cs
1
using ACadSharp.Attributes;
2
using CSMath;
3
using CSUtilities.Extensions;
4
using System.Collections.Generic;
5
using System.Linq;
6

7
namespace ACadSharp.Entities
8
{
9
        /// <summary>
10
        /// Represents a <see cref="Polyline{T}"/> entity.
11
        /// </summary>
12
        [DxfName(DxfFileToken.EntityPolyline)]
13
        [DxfSubClass(null, true)]
14
        public abstract class Polyline<T> : Entity, IPolyline
15
                where T : Entity, IVertex
16
        {
17
                /// <inheritdoc/>
18
                [DxfCodeValue(30)]
19
                public double Elevation { get; set; } = 0.0;
23,075✔
20

21
                /// <summary>
22
                /// End width.
23
                /// </summary>
24
                [DxfCodeValue(41)]
25
                public double EndWidth { get; set; } = 0.0;
22,535✔
26

27
                /// <summary>
28
                /// Polyline flags.
29
                /// </summary>
30
                [DxfCodeValue(70)]
31
                public PolylineFlags Flags { get => this._flags; set => this._flags = value; }
825✔
32

33
                /// <inheritdoc/>
34
                public bool IsClosed
35
                {
36
                        get
37
                        {
1✔
38
                                return this.Flags.HasFlag(PolylineFlags.ClosedPolylineOrClosedPolygonMeshInM) || this.Flags.HasFlag(PolylineFlags.ClosedPolygonMeshInN);
1!
39
                        }
1✔
40
                        set
41
                        {
65✔
42
                                if (value)
65✔
43
                                {
19✔
44
                                        this._flags.AddFlag(PolylineFlags.ClosedPolylineOrClosedPolygonMeshInM);
19✔
45
                                        this._flags.AddFlag(PolylineFlags.ClosedPolygonMeshInN);
19✔
46
                                }
19✔
47
                                else
48
                                {
46✔
49
                                        this._flags.RemoveFlag(PolylineFlags.ClosedPolylineOrClosedPolygonMeshInM);
46✔
50
                                        this._flags.RemoveFlag(PolylineFlags.ClosedPolygonMeshInN);
46✔
51
                                }
46✔
52
                        }
65✔
53
                }
54

55
                /// <inheritdoc/>
56
                [DxfCodeValue(210, 220, 230)]
57
                public XYZ Normal { get; set; } = XYZ.AxisZ;
22,619✔
58

59
                /// <inheritdoc/>
60
                public override string ObjectName => DxfFileToken.EntityPolyline;
2,736✔
61

62
                /// <summary>
63
                /// Curves and smooth surface type.
64
                /// </summary>
65
                [DxfCodeValue(75)]
66
                public SmoothSurfaceType SmoothSurface { get; set; }
92✔
67

68
                /// <summary>
69
                /// Start width.
70
                /// </summary>
71
                [DxfCodeValue(40)]
72
                public double StartWidth { get; set; } = 0.0;
22,535✔
73

74
                /// <inheritdoc/>
75
                [DxfCodeValue(39)]
76
                public double Thickness { get; set; } = 0.0;
22,535✔
77

78
                /// <summary>
79
                /// Vertices that form this polyline.
80
                /// </summary>
81
                /// <remarks>
82
                /// Each <see cref="Vertex"/> has it's own unique handle.
83
                /// </remarks>
84
                public SeqendCollection<T> Vertices { get; private set; }
537,895✔
85

86
                /// <inheritdoc/>
87
                IEnumerable<IVertex> IPolyline.Vertices { get { return this.Vertices; } }
186✔
88

89
                private PolylineFlags _flags;
90

91
                /// <summary>
92
                /// Default constructor.
93
                /// </summary>
94
                public Polyline() : base()
22,500✔
95
                {
22,500✔
96
                        this.Vertices = new SeqendCollection<T>(this);
22,500✔
97
                }
22,500✔
98

99
                public Polyline(IEnumerable<T> vertices, bool isClosed) : this()
19✔
100
                {
19✔
101
                        if (vertices == null)
19!
102
                                throw new System.ArgumentException("The vertices enumerable cannot be null or empty", nameof(vertices));
×
103

104
                        this.Vertices.AddRange(vertices);
19✔
105
                        this.IsClosed = isClosed;
19✔
106
                }
19✔
107

108
                /// <inheritdoc/>
109
                public override void ApplyTransform(Transform transform)
110
                {
×
111
                        var newNormal = this.transformNormal(transform, this.Normal);
×
112

113
                        this.getWorldMatrix(transform, this.Normal, newNormal, out Matrix3 transOW, out Matrix3 transWO);
×
114

115
                        foreach (var vertex in this.Vertices)
×
116
                        {
×
NEW
117
                                XYZ v = transOW * vertex.Location.Convert<XYZ>();
×
118
                                v = transform.ApplyTransform(v);
×
119
                                v = transWO * v;
×
120
                                vertex.Location = v;
×
121
                        }
×
122

123
                        this.Normal = newNormal;
×
124
                }
×
125

126
                /// <inheritdoc/>
127
                public override CadObject Clone()
128
                {
10✔
129
                        Polyline<T> clone = (Polyline<T>)base.Clone();
10✔
130

131
                        clone.Vertices = new SeqendCollection<T>(clone);
10✔
132
                        foreach (T v in this.Vertices)
36✔
133
                        {
3✔
134
                                clone.Vertices.Add((T)v.Clone());
3✔
135
                        }
3✔
136

137
                        return clone;
10✔
138
                }
10✔
139

140
                /// <inheritdoc/>
141
                public override BoundingBox GetBoundingBox()
142
                {
3✔
143
                        //TODO: can a polyline have only 1 vertex?
144
                        if (this.Vertices.Count < 2)
3!
145
                        {
3✔
146
                                return BoundingBox.Null;
3✔
147
                        }
148

NEW
149
                        XYZ first = this.Vertices[0].Location.Convert<XYZ>();
×
NEW
150
                        XYZ second = this.Vertices[1].Location.Convert<XYZ>();
×
151

152
                        XYZ min = new XYZ(System.Math.Min(first.X, second.X), System.Math.Min(first.Y, second.Y), System.Math.Min(first.Z, second.Z));
×
153
                        XYZ max = new XYZ(System.Math.Max(first.X, second.X), System.Math.Max(first.Y, second.Y), System.Math.Max(first.Z, second.Z));
×
154

155
                        for (int i = 2; i < this.Vertices.Count; i++)
×
156
                        {
×
NEW
157
                                XYZ curr = this.Vertices[i].Location.Convert<XYZ>();
×
158

159
                                min = new XYZ(System.Math.Min(min.X, curr.X), System.Math.Min(min.Y, curr.Y), System.Math.Min(min.Z, curr.Z));
×
160
                                max = new XYZ(System.Math.Max(max.X, curr.X), System.Math.Max(max.Y, curr.Y), System.Math.Max(max.Z, curr.Z));
×
161
                        }
×
162

163
                        return new BoundingBox(min, max);
×
164
                }
3✔
165

166
                internal static IEnumerable<Entity> Explode(IPolyline polyline)
UNCOV
167
                {
×
168
                        //Generic explode method for Polyline2D and LwPolyline
UNCOV
169
                        List<Entity> entities = new List<Entity>();
×
170

UNCOV
171
                        for (int i = 0; i < polyline.Vertices.Count(); i++)
×
UNCOV
172
                        {
×
UNCOV
173
                                IVertex curr = polyline.Vertices.ElementAt(i);
×
UNCOV
174
                                IVertex next = polyline.Vertices.ElementAtOrDefault(i + 1);
×
175

UNCOV
176
                                if (next == null && polyline.IsClosed)
×
UNCOV
177
                                {
×
UNCOV
178
                                        next = polyline.Vertices.First();
×
UNCOV
179
                                }
×
UNCOV
180
                                else if (next == null)
×
UNCOV
181
                                {
×
UNCOV
182
                                        break;
×
183
                                }
184

UNCOV
185
                                Entity e = null;
×
UNCOV
186
                                if (curr.Bulge == 0)
×
UNCOV
187
                                {
×
188
                                        //Is a line
UNCOV
189
                                        e = new Line
×
UNCOV
190
                                        {
×
UNCOV
191
                                                StartPoint = curr.Location.Convert<XYZ>(),
×
UNCOV
192
                                                EndPoint = next.Location.Convert<XYZ>(),
×
UNCOV
193
                                                Normal = polyline.Normal,
×
UNCOV
194
                                                Thickness = polyline.Thickness,
×
UNCOV
195
                                        };
×
UNCOV
196
                                }
×
197
                                else
UNCOV
198
                                {
×
UNCOV
199
                                        XY p1 = curr.Location.Convert<XY>();
×
UNCOV
200
                                        XY p2 = next.Location.Convert<XY>();
×
201

202
                                        //Is an arc
UNCOV
203
                                        Arc arc = Arc.CreateFromBulge(p1, p2, curr.Bulge);
×
UNCOV
204
                                        arc.Center = new XYZ(arc.Center.X, arc.Center.Y, polyline.Elevation);
×
UNCOV
205
                                        arc.Normal = polyline.Normal;
×
UNCOV
206
                                        arc.Thickness = polyline.Thickness;
×
207

UNCOV
208
                                        e = arc;
×
UNCOV
209
                                }
×
210

UNCOV
211
                                polyline.MatchProperties(e);
×
212

UNCOV
213
                                entities.Add(e);
×
UNCOV
214
                        }
×
215

UNCOV
216
                        return entities;
×
UNCOV
217
                }
×
218

219
                internal override void AssignDocument(CadDocument doc)
220
                {
10,806✔
221
                        base.AssignDocument(doc);
10,806✔
222
                        doc.RegisterCollection(this.Vertices);
10,806✔
223
                }
10,806✔
224

225
                internal override void UnassignDocument()
226
                {
52✔
227
                        this.Document.UnregisterCollection(this.Vertices);
52✔
228
                        base.UnassignDocument();
52✔
229
                }
52✔
230
        }
231
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc