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

DomCR / ACadSharp / 14131057904

28 Mar 2025 02:21PM UTC coverage: 76.347% (-0.05%) from 76.393%
14131057904

Pull #596

github

web-flow
Merge 8bf2c916c into caff69749
Pull Request #596: issue 595 attributes fix

5563 of 8000 branches covered (69.54%)

Branch coverage included in aggregate %.

4 of 4 new or added lines in 1 file covered. (100.0%)

21 existing lines in 3 files now uncovered.

22005 of 28109 relevant lines covered (78.28%)

74686.1 hits per line

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

82.93
/src/ACadSharp/Entities/Insert.cs
1
using ACadSharp.Attributes;
2
using ACadSharp.Tables;
3
using CSMath;
4
using CSUtilities.Extensions;
5
using System;
6
using System.Linq;
7
using System.Xml.Linq;
8

9
namespace ACadSharp.Entities
10
{
11
        /// <summary>
12
        /// Represents a <see cref="Insert"/> entity.
13
        /// </summary>
14
        /// <remarks>
15
        /// Object name <see cref="DxfFileToken.EntityInsert"/> <br/>
16
        /// Dxf class name <see cref="DxfSubclassMarker.Insert"/>
17
        /// </remarks>
18
        [DxfName(DxfFileToken.EntityInsert)]
19
        [DxfSubClass(DxfSubclassMarker.Insert)]
20
        public class Insert : Entity
21
        {
22
                /// <summary>
23
                /// Attributes from the block reference
24
                /// </summary>
25
                /// <remarks>
26
                /// If an attribute should be added in this collection a definition will be added into the block reference as well
27
                /// </remarks>
28
                public SeqendCollection<AttributeEntity> Attributes { get; private set; }
13,519✔
29

30
                /// <summary>
31
                /// Gets the insert block definition.
32
                /// </summary>
33
                [DxfCodeValue(DxfReferenceType.Name, 2)]
34
                public BlockRecord Block { get; internal set; }
11,543✔
35

36
                /// <summary>
37
                /// Column count
38
                /// </summary>
39
                [DxfCodeValue(DxfReferenceType.Optional, 70)]
40
                public ushort ColumnCount { get; set; } = 1;
7,451✔
41

42
                /// <summary>
43
                /// Column spacing
44
                /// </summary>
45
                [DxfCodeValue(DxfReferenceType.Optional, 44)]
46
                public double ColumnSpacing { get; set; } = 0;
7,193✔
47

48
                /// <summary>
49
                /// True if the insert has attribute entities in it
50
                /// </summary>
51
                [DxfCodeValue(DxfReferenceType.Ignored, 66)]
52
                public bool HasAttributes { get { return this.Attributes.Any(); } }
831✔
53

54
                /// <inheritdoc/>
55
                public override bool HasDynamicSubclass => true;
2✔
56

57
                /// <summary>
58
                /// A 3D WCS coordinate representing the insertion or origin point.
59
                /// </summary>
60
                [DxfCodeValue(10, 20, 30)]
61
                public XYZ InsertPoint { get; set; } = XYZ.Zero;
39,228✔
62

63
                /// <summary>
64
                /// Flag is true for multiple insertion of the same block.
65
                /// </summary>
66
                public bool IsMultiple { get { return this.RowCount > 1 || this.ColumnCount > 1; } }
846✔
67

68
                /// <summary>
69
                /// Specifies the three-dimensional normal unit vector for the object.
70
                /// </summary>
71
                [DxfCodeValue(210, 220, 230)]
72
                public XYZ Normal { get; set; } = XYZ.AxisZ;
8,847✔
73

74
                /// <inheritdoc/>
75
                public override string ObjectName => DxfFileToken.EntityInsert;
393✔
76

77
                /// <inheritdoc/>
78
                public override ObjectType ObjectType
79
                {
80
                        get
81
                        {
17✔
82
                                if (this.IsMultiple)
17✔
83
                                {
16✔
84
                                        return ObjectType.MINSERT;
16✔
85
                                }
86
                                else
87
                                {
1✔
88
                                        return ObjectType.INSERT;
1✔
89
                                }
90
                        }
17✔
91
                }
92

93
                /// <summary>
94
                /// Specifies the rotation angle for the object.
95
                /// </summary>
96
                /// <value>
97
                /// The rotation angle in radians.
98
                /// </value>
99
                [DxfCodeValue(DxfReferenceType.IsAngle, 50)]
100
                public double Rotation { get; set; } = 0.0;
9,296✔
101

102
                /// <summary>
103
                /// Row count
104
                /// </summary>
105
                [DxfCodeValue(DxfReferenceType.Optional, 71)]
106
                public ushort RowCount { get; set; } = 1;
7,475✔
107

108
                /// <summary>
109
                /// Row spacing
110
                /// </summary>
111
                [DxfCodeValue(DxfReferenceType.Optional, 45)]
112
                public double RowSpacing { get; set; } = 0;
7,193✔
113

114
                /// <inheritdoc/>
115
                public override string SubclassMarker => this.IsMultiple ? DxfSubclassMarker.MInsert : DxfSubclassMarker.Insert;
257!
116

117
                /// <summary>
118
                /// X scale factor.
119
                /// </summary>
120
                [DxfCodeValue(41)]
121
                public double XScale
122
                {
123
                        get
124
                        {
311✔
125
                                return this._xscale;
311✔
126
                        }
311✔
127
                        set
128
                        {
3,753✔
129
                                if (value.Equals(0))
3,753✔
130
                                {
1✔
131
                                        string name = nameof(this.XScale);
1✔
132
                                        throw new ArgumentOutOfRangeException(name, value, $"{name} value must be none zero.");
1✔
133
                                }
134
                                this._xscale = value;
3,752✔
135
                        }
3,752✔
136
                }
137

138
                /// <summary>
139
                /// Y scale factor.
140
                /// </summary>
141
                [DxfCodeValue(42)]
142
                public double YScale
143
                {
144
                        get
145
                        {
275✔
146
                                return this._yscale;
275✔
147
                        }
275✔
148
                        set
149
                        {
3,549✔
150
                                if (value.Equals(0))
3,549✔
151
                                {
1✔
152
                                        string name = nameof(this.YScale);
1✔
153
                                        throw new ArgumentOutOfRangeException(name, value, $"{name} value must be none zero.");
1✔
154
                                }
155
                                this._yscale = value;
3,548✔
156
                        }
3,548✔
157
                }
158

159
                /// <summary>
160
                /// Z scale factor.
161
                /// </summary>
162
                [DxfCodeValue(43)]
163
                public double ZScale
164
                {
165
                        get
166
                        {
268✔
167
                                return this._zscale;
268✔
168
                        }
268✔
169
                        set
170
                        {
3,549✔
171
                                if (value.Equals(0))
3,549✔
172
                                {
1✔
173
                                        string name = nameof(this.ZScale);
1✔
174
                                        throw new ArgumentOutOfRangeException(name, value, $"{name} value must be none zero.");
1✔
175
                                }
176
                                this._zscale = value;
3,548✔
177
                        }
3,548✔
178
                }
179

180
                private double _xscale = 1;
6,903✔
181

182
                private double _yscale = 1;
6,903✔
183

184
                private double _zscale = 1;
6,903✔
185

186
                /// <summary>
187
                /// Constructor to reference an insert to a block record
188
                /// </summary>
189
                /// <param name="block">Block Record to reference</param>
190
                /// <exception cref="ArgumentNullException"></exception>
191
                public Insert(BlockRecord block) : this()
21✔
192
                {
21✔
193
                        if (block is null) throw new ArgumentNullException(nameof(block));
21!
194

195
                        if (block.Document != null)
21✔
196
                        {
2✔
197
                                this.Block = (BlockRecord)block.Clone();
2✔
198
                        }
2✔
199
                        else
200
                        {
19✔
201
                                this.Block = block;
19✔
202
                        }
19✔
203

204
                        foreach (var item in block.AttributeDefinitions)
69✔
205
                        {
3✔
206
                                this.Attributes.Add(new AttributeEntity(item));
3✔
207
                        }
3✔
208
                }
21✔
209

210
                internal Insert() : base()
6,903✔
211
                {
6,903✔
212
                        this.Attributes = new SeqendCollection<AttributeEntity>(this);
6,903✔
213
                }
6,903✔
214

215
                /// <inheritdoc/>
216
                public override CadObject Clone()
217
                {
31✔
218
                        Insert clone = (Insert)base.Clone();
31✔
219

220
                        clone.Block = (BlockRecord)this.Block?.Clone();
31✔
221

222
                        clone.Attributes = new SeqendCollection<AttributeEntity>(clone);
31✔
223
                        foreach (var att in this.Attributes)
95✔
224
                        {
1✔
225
                                clone.Attributes.Add((AttributeEntity)att.Clone());
1✔
226
                        }
1✔
227

228
                        return clone;
31✔
229
                }
31✔
230

231
                /// <inheritdoc/>
232
                public override BoundingBox GetBoundingBox()
233
                {
3✔
234
                        BoundingBox box = this.Block.GetBoundingBox();
3✔
235

236
                        var scale = new XYZ(this.XScale, this.YScale, this.ZScale);
3✔
237
                        var min = box.Min * scale + this.InsertPoint;
3✔
238
                        var max = box.Max * scale + this.InsertPoint;
3✔
239

240
                        return new BoundingBox(min, max);
3✔
241
                }
3✔
242

243
                /// <summary>
244
                /// Get the transform that will be applied to the entities in the <see cref="BlockRecord"/> when this entity is processed.
245
                /// </summary>
246
                /// <returns></returns>
247
                public Transform GetTransform()
248
                {
1✔
249
                        XYZ scale = new XYZ(XScale, YScale, ZScale);
1✔
250

251
                        //TODO: Apply rotation
252
                        return new Transform(this.InsertPoint, scale, XYZ.Zero);
1✔
253
                }
1✔
254

255
                /// <summary>
256
                /// Updates all attribute definitions contained in the block reference as <see cref="AttributeDefinition"/> entities in the insert.
257
                /// </summary>
258
                /// <remarks>
259
                /// This will update the attributes based on their <see cref="AttributeBase.Tag"/>.
260
                /// </remarks>
261
                public void UpdateAttributes()
UNCOV
262
                {
×
UNCOV
263
                        var atts = this.Attributes.ToArray();
×
264

UNCOV
265
                        foreach (AttributeEntity att in atts)
×
266
                        {
×
267
                                //Tags are not unique, is it needed? check how the different applications link the atts
268
                                if (!this.Block.AttributeDefinitions.Select(d => d.Tag).Contains(att.Tag))
×
269
                                {
×
270
                                        this.Attributes.Remove(att);
×
271
                                }
×
272
                        }
×
273

UNCOV
274
                        foreach (AttributeDefinition attdef in this.Block.AttributeDefinitions)
×
UNCOV
275
                        {
×
UNCOV
276
                                if (!this.Attributes.Select(d => d.Tag).Contains(attdef.Tag))
×
UNCOV
277
                                {
×
UNCOV
278
                                        AttributeEntity att = new AttributeEntity(attdef);
×
279

UNCOV
280
                                        this.Attributes.Add(att);
×
UNCOV
281
                                }
×
UNCOV
282
                        }
×
UNCOV
283
                }
×
284

285
                internal override void AssignDocument(CadDocument doc)
286
                {
4,192✔
287
                        base.AssignDocument(doc);
4,192✔
288

289
                        doc.RegisterCollection(this.Attributes);
4,192✔
290

291
                        //Should only be triggered for internal use
292
                        if (this.Block == null)
4,192✔
293
                                return;
4,075✔
294

295
                        if (doc.BlockRecords.TryGetValue(this.Block.Name, out BlockRecord blk))
117✔
296
                        {
27✔
297
                                this.Block = blk;
27✔
298
                        }
27✔
299
                        else
300
                        {
90✔
301
                                doc.BlockRecords.Add(this.Block);
90✔
302
                        }
90✔
303
                }
4,192✔
304

305
                internal override void UnassignDocument()
306
                {
82✔
307
                        this.Block = (BlockRecord)this.Block.Clone();
82✔
308
                        this.Document.UnregisterCollection(this.Attributes);
82✔
309

310
                        base.UnassignDocument();
82✔
311
                }
82✔
312
        }
313
}
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