acadrust 0.3.4

A pure Rust library for reading and writing CAD files in DXF format (ASCII and Binary) and DWG format (Binary).
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
//! Graphical entity types.
//!
//! This module contains all 41 supported CAD entity types — from simple
//! primitives ([`Line`], [`Circle`], [`Arc`]) through complex objects
//! ([`Hatch`], [`Spline`], [`MultiLeader`], [`Mesh`]).
//!
//! Every entity carries [`EntityCommon`] data (layer, color, line weight,
//! handle, etc.) alongside its type-specific fields.
//!
//! Entities are stored in [`CadDocument`](crate::document::CadDocument) and
//! wrapped in the [`EntityType`] enum for heterogeneous collections.

use crate::types::{BoundingBox3D, Color, Handle, LineWeight, Transform, Transparency, Vector3};

pub mod point;
pub mod line;
pub mod circle;
pub mod arc;
pub mod ellipse;
pub mod polyline;
pub mod polyline3d;
pub mod lwpolyline;
pub mod text;
pub mod mtext;
pub mod spline;
pub mod dimension;
pub mod hatch;
pub mod solid;
pub mod face3d;
pub mod insert;
pub mod block;
pub mod ray;
pub mod xline;
pub mod viewport;
pub mod attribute_definition;
pub mod attribute_entity;
pub mod leader;
pub mod multileader;
pub mod mline;
pub mod mesh;
pub mod raster_image;
pub mod solid3d;
pub mod acis;
pub mod table;
pub mod tolerance;
pub mod polyface_mesh;
pub mod wipeout;
pub mod shape;
pub mod underlay;
pub mod seqend;
pub mod ole2frame;
pub mod polygon_mesh;
pub mod unknown_entity;
pub mod explode;
pub mod translate;
pub mod transform;
pub mod mirror;

pub use point::Point;
pub use line::Line;
pub use circle::Circle;
pub use arc::Arc;
pub use ellipse::Ellipse;
pub use polyline::{Polyline, Polyline2D, Vertex2D, Vertex3D, PolylineFlags, VertexFlags, SmoothSurfaceType};
pub use polyline3d::{Polyline3D, Vertex3DPolyline, Polyline3DFlags};
pub use lwpolyline::{LwPolyline, LwVertex};
pub use text::{Text, TextHorizontalAlignment, TextVerticalAlignment};
pub use mtext::{MText, AttachmentPoint, DrawingDirection};
pub use spline::{Spline, SplineFlags};
pub use dimension::*;
pub use hatch::*;
pub use solid::Solid;
pub use face3d::{Face3D, InvisibleEdgeFlags};
pub use insert::Insert;
pub use block::{Block, BlockEnd};
pub use ray::Ray;
pub use xline::XLine;
pub use viewport::{Viewport, ViewportStatusFlags, ViewportRenderMode, StandardView, GridFlags};
pub use attribute_definition::{AttributeDefinition, AttributeFlags, HorizontalAlignment, VerticalAlignment, MTextFlag};
pub use attribute_entity::AttributeEntity;
pub use leader::{Leader, LeaderPathType, LeaderCreationType, HooklineDirection};
pub use multileader::{
    MultiLeader, MultiLeaderBuilder, MultiLeaderAnnotContext,
    LeaderRoot, LeaderLine, BlockAttribute, StartEndPointPair,
    LeaderContentType, MultiLeaderPathType, TextAttachmentType, TextAngleType,
    BlockContentConnectionType, TextAttachmentDirectionType, TextAttachmentPointType,
    TextAlignmentType, FlowDirectionType, LineSpacingStyle,
    MultiLeaderPropertyOverrideFlags, LeaderLinePropertyOverrideFlags,
};
pub use mline::{
    MLine, MLineBuilder, MLineVertex, MLineSegment,
    MLineStyle, MLineStyleElement, MLineJustification, MLineFlags, MLineStyleFlags,
};
pub use mesh::{Mesh, MeshBuilder, MeshEdge, MeshFace};
pub use raster_image::{
    RasterImage, RasterImageBuilder, ImageDefinition, ClipBoundary,
    ClipMode, ClipType, ImageDisplayFlags, ImageDisplayQuality, ResolutionUnit,
};
pub use solid3d::{
    Solid3D, Region, Body, Wire, Silhouette, AcisData,
    WireType, AcisVersion,
};
pub use table::{
    Table, TableBuilder, TableCell, TableRow, TableColumn,
    CellContent, CellValue, CellStyle, CellBorder, CellRange,
    CellType, CellValueType, ValueUnitType, BorderType,
    TableCellContentType, CellStyleType, BreakFlowDirection,
    CellEdgeFlags, CellStateFlags, CellStylePropertyFlags,
    BorderPropertyFlags, ContentLayoutFlags, BreakOptionFlags,
};
pub use tolerance::{Tolerance, gdt_symbols};
pub use polyface_mesh::{
    PolyfaceMesh, PolyfaceVertex, PolyfaceFace,
    PolyfaceMeshFlags, PolyfaceVertexFlags, PolyfaceSmoothType,
};
pub use wipeout::{
    Wipeout, WipeoutDisplayFlags, WipeoutClipType, WipeoutClipMode,
};
pub use shape::{Shape, standard_shapes, gdt_shapes};
pub use underlay::{
    Underlay, UnderlayDefinition, UnderlayType, UnderlayDisplayFlags,
    PdfUnderlay, DwfUnderlay, DgnUnderlay,
    PdfUnderlayDefinition, DwfUnderlayDefinition, DgnUnderlayDefinition,
};
pub use seqend::Seqend;
pub use ole2frame::{Ole2Frame, OleObjectType};
pub use polygon_mesh::{
    PolygonMesh as PolygonMeshEntity, PolygonMeshVertex, PolygonMeshFlags, SurfaceSmoothType,
};
pub use unknown_entity::UnknownEntity;

/// Base trait for all CAD entities
pub trait Entity {
    /// Get the entity's unique handle
    fn handle(&self) -> Handle;

    /// Set the entity's handle
    fn set_handle(&mut self, handle: Handle);

    /// Get the entity's layer name
    fn layer(&self) -> &str;

    /// Set the entity's layer name
    fn set_layer(&mut self, layer: String);

    /// Get the entity's color
    fn color(&self) -> Color;

    /// Set the entity's color
    fn set_color(&mut self, color: Color);

    /// Get the entity's line weight
    fn line_weight(&self) -> LineWeight;

    /// Set the entity's line weight
    fn set_line_weight(&mut self, weight: LineWeight);

    /// Get the entity's transparency
    fn transparency(&self) -> Transparency;

    /// Set the entity's transparency
    fn set_transparency(&mut self, transparency: Transparency);

    /// Check if the entity is invisible
    fn is_invisible(&self) -> bool;

    /// Set the entity's visibility
    fn set_invisible(&mut self, invisible: bool);

    /// Get the bounding box of the entity
    fn bounding_box(&self) -> BoundingBox3D;

    /// Transform the entity by a translation vector
    fn translate(&mut self, offset: Vector3);

    /// Get the entity type name
    fn entity_type(&self) -> &'static str;
    
    /// Apply a general transform to the entity
    /// 
    /// This is the main transformation method. Default implementation
    /// only supports translation for backward compatibility.
    fn apply_transform(&mut self, transform: &Transform) {
        // Default: extract translation and apply
        let origin = Vector3::ZERO;
        let translated = transform.apply(origin);
        self.translate(translated);
    }
    
    /// Apply rotation around an axis
    fn apply_rotation(&mut self, axis: Vector3, angle: f64) {
        self.apply_transform(&Transform::from_rotation(axis, angle));
    }
    
    /// Apply uniform scaling
    fn apply_scaling(&mut self, scale: f64) {
        self.apply_transform(&Transform::from_scale(scale));
    }
    
    /// Apply non-uniform scaling
    fn apply_scaling_xyz(&mut self, scale: Vector3) {
        self.apply_transform(&Transform::from_scaling(scale));
    }
    
    /// Apply scaling with a specific origin point
    fn apply_scaling_with_origin(&mut self, scale: Vector3, origin: Vector3) {
        self.apply_transform(&Transform::from_scaling_with_origin(scale, origin));
    }
    
    /// Apply a mirror transform with entity-specific corrections
    ///
    /// Override this for entities that need post-processing after mirroring
    /// (e.g., arc angle swaps, bulge negation, face winding reversal).
    fn apply_mirror(&mut self, transform: &Transform) {
        self.apply_transform(transform);
    }
    
    /// Mirror the entity across the YZ plane (negate X coordinates)
    fn mirror_x(&mut self) {
        self.apply_mirror(&Transform::from_mirror_x());
    }
    
    /// Mirror the entity across the XZ plane (negate Y coordinates)
    fn mirror_y(&mut self) {
        self.apply_mirror(&Transform::from_mirror_y());
    }
    
    /// Mirror the entity across the XY plane (negate Z coordinates)
    fn mirror_z(&mut self) {
        self.apply_mirror(&Transform::from_mirror_z());
    }
    
    /// Mirror the entity across a line defined by two points (in the XY plane)
    fn mirror_about_line(&mut self, p1: Vector3, p2: Vector3) {
        self.apply_mirror(&Transform::from_mirror_line(p1, p2));
    }
    
    /// Mirror the entity across an arbitrary plane
    fn mirror_about_plane(&mut self, point: Vector3, normal: Vector3) {
        self.apply_mirror(&Transform::from_mirror_plane(point, normal));
    }
}

/// Common entity data shared by all entities
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct EntityCommon {
    /// Unique handle
    pub handle: Handle,
    /// Layer name
    pub layer: String,
    /// Color
    pub color: Color,
    /// Line weight
    pub line_weight: LineWeight,
    /// Linetype name (empty string = "ByLayer")
    pub linetype: String,
    /// Linetype scale factor (default 1.0)
    pub linetype_scale: f64,
    /// Transparency
    pub transparency: Transparency,
    /// Visibility flag
    pub invisible: bool,
    /// Extended data (XDATA)
    pub extended_data: crate::xdata::ExtendedData,
    /// Raw entity graphic data bytes (stored for DWG round-trip; None otherwise).
    #[cfg_attr(feature = "serde", serde(skip))]
    pub graphic_data: Option<Vec<u8>>,
    /// Reactor handles — objects attached as reactors ({ACAD_REACTORS})
    pub reactors: Vec<Handle>,
    /// Extended dictionary handle ({ACAD_XDICTIONARY}) — hard-owner handle to a Dictionary
    pub xdictionary_handle: Option<Handle>,
    /// Owner handle (soft pointer, code 330)
    pub owner_handle: Handle,

    // ── DWG round-trip fields (not exposed via DXF) ──
    /// Material flags (BB: 00=bylayer, 01=byblock, 10=reserved, 11=handle) — R2007+
    #[cfg_attr(feature = "serde", serde(skip))]
    pub material_flags: u8,
    /// Material handle (only valid when material_flags == 0b11) — R2007+
    #[cfg_attr(feature = "serde", serde(skip))]
    pub material_handle: Option<Handle>,
    /// Shadow flags (RC) — R2007+
    #[cfg_attr(feature = "serde", serde(skip))]
    pub shadow_flags: u8,
    /// Plotstyle flags (BB: 00=bylayer, 01=byblock, 10=reserved, 11=handle) — R2000+
    #[cfg_attr(feature = "serde", serde(skip))]
    pub plotstyle_flags: u8,
    /// Plotstyle handle (only valid when plotstyle_flags == 0b11) — R2000+
    #[cfg_attr(feature = "serde", serde(skip))]
    pub plotstyle_handle: Option<Handle>,
    /// Entity mode (0=owned, 1=paper, 2=model) — raw DWG value for round-trip
    #[cfg_attr(feature = "serde", serde(skip))]
    pub entity_mode: Option<u8>,
}

impl EntityCommon {
    /// Create new common entity data with defaults
    pub fn new() -> Self {
        EntityCommon {
            handle: Handle::NULL,
            layer: "0".to_string(),
            color: Color::ByLayer,
            line_weight: LineWeight::ByLayer,
            linetype: String::new(),
            linetype_scale: 1.0,
            transparency: Transparency::OPAQUE,
            invisible: false,
            extended_data: crate::xdata::ExtendedData::new(),
            graphic_data: None,
            reactors: Vec::new(),
            xdictionary_handle: None,
            owner_handle: Handle::NULL,
            material_flags: 0,
            material_handle: None,
            shadow_flags: 0,
            plotstyle_flags: 0,
            plotstyle_handle: None,
            entity_mode: None,
        }
    }

    /// Create with a specific layer
    pub fn with_layer(layer: impl Into<String>) -> Self {
        EntityCommon {
            layer: layer.into(),
            ..Self::new()
        }
    }

    /// Check whether a linetype name is set (not empty and not "ByLayer")
    pub fn has_linetype(&self) -> bool {
        !self.linetype.is_empty() && self.linetype != "ByLayer"
    }
}

impl Default for EntityCommon {
    fn default() -> Self {
        Self::new()
    }
}

/// Enumeration of all entity types for type-safe storage
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum EntityType {
    /// Point entity
    Point(Point),
    /// Line entity
    Line(Line),
    /// Circle entity
    Circle(Circle),
    /// Arc entity
    Arc(Arc),
    /// Ellipse entity
    Ellipse(Ellipse),
    /// 3D Polyline entity
    Polyline(Polyline),
    /// 2D Polyline entity (heavy polyline)
    Polyline2D(Polyline2D),
    /// 3D Polyline entity (new style)
    Polyline3D(Polyline3D),
    /// Lightweight polyline entity
    LwPolyline(LwPolyline),
    /// Text entity
    Text(Text),
    /// Multi-line text entity
    MText(MText),
    /// Spline entity
    Spline(Spline),
    /// Dimension entity
    Dimension(Dimension),
    /// Hatch entity
    Hatch(Hatch),
    /// Solid entity
    Solid(Solid),
    /// 3D Face entity
    Face3D(Face3D),
    /// Insert entity (block reference)
    Insert(Insert),
    /// Block entity (block definition start)
    Block(Block),
    /// BlockEnd entity (block definition end)
    BlockEnd(BlockEnd),
    /// Ray entity (semi-infinite line)
    Ray(Ray),
    /// XLine entity (construction line, infinite)
    XLine(XLine),
    /// Viewport entity (paper space viewport)
    Viewport(Viewport),
    /// Attribute definition entity
    AttributeDefinition(AttributeDefinition),
    /// Attribute entity (block attribute instance)
    AttributeEntity(AttributeEntity),
    /// Leader entity
    Leader(Leader),
    /// MultiLeader entity
    MultiLeader(MultiLeader),
    /// MLine (multiline) entity
    MLine(MLine),
    /// Mesh entity
    Mesh(Mesh),
    /// RasterImage entity
    RasterImage(RasterImage),
    /// Solid3D entity
    Solid3D(Solid3D),
    /// Region entity
    Region(Region),
    /// Body entity
    Body(Body),
    /// Table entity
    Table(Table),
    /// Tolerance entity (geometric tolerancing)
    Tolerance(Tolerance),
    /// PolyfaceMesh entity
    PolyfaceMesh(PolyfaceMesh),
    /// Wipeout entity
    Wipeout(Wipeout),
    /// Shape entity
    Shape(Shape),
    /// Underlay entity (PDF, DWF, DGN)
    Underlay(Underlay),
    /// End-of-sequence marker
    Seqend(Seqend),
    /// OLE2 embedded object
    Ole2Frame(Ole2Frame),
    /// Polygon mesh (3D surface mesh)
    PolygonMesh(PolygonMeshEntity),
    /// Unknown / unsupported entity type (common fields only)
    Unknown(UnknownEntity),
}

impl EntityType {
    /// Get a reference to the entity trait object
    pub fn as_entity(&self) -> &dyn Entity {
        match self {
            EntityType::Point(e) => e,
            EntityType::Line(e) => e,
            EntityType::Circle(e) => e,
            EntityType::Arc(e) => e,
            EntityType::Ellipse(e) => e,
            EntityType::Polyline(e) => e,
            EntityType::Polyline2D(e) => e,
            EntityType::Polyline3D(e) => e,
            EntityType::LwPolyline(e) => e,
            EntityType::Text(e) => e,
            EntityType::MText(e) => e,
            EntityType::Spline(e) => e,
            EntityType::Dimension(e) => e,
            EntityType::Hatch(e) => e,
            EntityType::Solid(e) => e,
            EntityType::Face3D(e) => e,
            EntityType::Insert(e) => e,
            EntityType::Block(e) => e,
            EntityType::BlockEnd(e) => e,
            EntityType::Ray(e) => e,
            EntityType::XLine(e) => e,
            EntityType::Viewport(e) => e,
            EntityType::AttributeDefinition(e) => e,
            EntityType::AttributeEntity(e) => e,
            EntityType::Leader(e) => e,
            EntityType::MultiLeader(e) => e,
            EntityType::MLine(e) => e,
            EntityType::Mesh(e) => e,
            EntityType::RasterImage(e) => e,
            EntityType::Solid3D(e) => e,
            EntityType::Region(e) => e,
            EntityType::Body(e) => e,
            EntityType::Table(e) => e,
            EntityType::Tolerance(e) => e,
            EntityType::PolyfaceMesh(e) => e,
            EntityType::Wipeout(e) => e,
            EntityType::Shape(e) => e,
            EntityType::Underlay(e) => e,
            EntityType::Seqend(e) => e,
            EntityType::Ole2Frame(e) => e,
            EntityType::PolygonMesh(e) => e,
            EntityType::Unknown(e) => e,
        }
    }

    /// Get a mutable reference to the entity trait object
    pub fn as_entity_mut(&mut self) -> &mut dyn Entity {
        match self {
            EntityType::Point(e) => e,
            EntityType::Line(e) => e,
            EntityType::Circle(e) => e,
            EntityType::Arc(e) => e,
            EntityType::Ellipse(e) => e,
            EntityType::Polyline(e) => e,
            EntityType::Polyline2D(e) => e,
            EntityType::Polyline3D(e) => e,
            EntityType::LwPolyline(e) => e,
            EntityType::MText(e) => e,
            EntityType::Text(e) => e,
            EntityType::Spline(e) => e,
            EntityType::Dimension(e) => e,
            EntityType::Hatch(e) => e,
            EntityType::Solid(e) => e,
            EntityType::Face3D(e) => e,
            EntityType::Insert(e) => e,
            EntityType::Block(e) => e,
            EntityType::BlockEnd(e) => e,
            EntityType::Ray(e) => e,
            EntityType::XLine(e) => e,
            EntityType::Viewport(e) => e,
            EntityType::AttributeDefinition(e) => e,
            EntityType::AttributeEntity(e) => e,
            EntityType::Leader(e) => e,
            EntityType::MultiLeader(e) => e,
            EntityType::MLine(e) => e,
            EntityType::Mesh(e) => e,
            EntityType::RasterImage(e) => e,
            EntityType::Solid3D(e) => e,
            EntityType::Region(e) => e,
            EntityType::Body(e) => e,
            EntityType::Table(e) => e,
            EntityType::Tolerance(e) => e,
            EntityType::PolyfaceMesh(e) => e,
            EntityType::Wipeout(e) => e,
            EntityType::Shape(e) => e,
            EntityType::Underlay(e) => e,
            EntityType::Seqend(e) => e,
            EntityType::Ole2Frame(e) => e,
            EntityType::PolygonMesh(e) => e,
            EntityType::Unknown(e) => e,
        }
    }

    /// Get a reference to the entity's common data
    pub fn common(&self) -> &EntityCommon {
        match self {
            EntityType::Point(e) => &e.common,
            EntityType::Line(e) => &e.common,
            EntityType::Circle(e) => &e.common,
            EntityType::Arc(e) => &e.common,
            EntityType::Ellipse(e) => &e.common,
            EntityType::Polyline(e) => &e.common,
            EntityType::Polyline2D(e) => &e.common,
            EntityType::Polyline3D(e) => &e.common,
            EntityType::LwPolyline(e) => &e.common,
            EntityType::Text(e) => &e.common,
            EntityType::MText(e) => &e.common,
            EntityType::Spline(e) => &e.common,
            EntityType::Dimension(e) => &e.base().common,
            EntityType::Hatch(e) => &e.common,
            EntityType::Solid(e) => &e.common,
            EntityType::Face3D(e) => &e.common,
            EntityType::Insert(e) => &e.common,
            EntityType::Block(e) => &e.common,
            EntityType::BlockEnd(e) => &e.common,
            EntityType::Ray(e) => &e.common,
            EntityType::XLine(e) => &e.common,
            EntityType::Viewport(e) => &e.common,
            EntityType::AttributeDefinition(e) => &e.common,
            EntityType::AttributeEntity(e) => &e.common,
            EntityType::Leader(e) => &e.common,
            EntityType::MultiLeader(e) => &e.common,
            EntityType::MLine(e) => &e.common,
            EntityType::Mesh(e) => &e.common,
            EntityType::RasterImage(e) => &e.common,
            EntityType::Solid3D(e) => &e.common,
            EntityType::Region(e) => &e.common,
            EntityType::Body(e) => &e.common,
            EntityType::Table(e) => &e.common,
            EntityType::Tolerance(e) => &e.common,
            EntityType::PolyfaceMesh(e) => &e.common,
            EntityType::Wipeout(e) => &e.common,
            EntityType::Shape(e) => &e.common,
            EntityType::Underlay(e) => &e.common,
            EntityType::Seqend(e) => &e.common,
            EntityType::Ole2Frame(e) => &e.common,
            EntityType::PolygonMesh(e) => &e.common,
            EntityType::Unknown(e) => &e.common,
        }
    }

    /// Get a mutable reference to the entity's common data
    pub fn common_mut(&mut self) -> &mut EntityCommon {
        match self {
            EntityType::Point(e) => &mut e.common,
            EntityType::Line(e) => &mut e.common,
            EntityType::Circle(e) => &mut e.common,
            EntityType::Arc(e) => &mut e.common,
            EntityType::Ellipse(e) => &mut e.common,
            EntityType::Polyline(e) => &mut e.common,
            EntityType::Polyline2D(e) => &mut e.common,
            EntityType::Polyline3D(e) => &mut e.common,
            EntityType::LwPolyline(e) => &mut e.common,
            EntityType::Text(e) => &mut e.common,
            EntityType::MText(e) => &mut e.common,
            EntityType::Spline(e) => &mut e.common,
            EntityType::Dimension(e) => &mut e.base_mut().common,
            EntityType::Hatch(e) => &mut e.common,
            EntityType::Solid(e) => &mut e.common,
            EntityType::Face3D(e) => &mut e.common,
            EntityType::Insert(e) => &mut e.common,
            EntityType::Block(e) => &mut e.common,
            EntityType::BlockEnd(e) => &mut e.common,
            EntityType::Ray(e) => &mut e.common,
            EntityType::XLine(e) => &mut e.common,
            EntityType::Viewport(e) => &mut e.common,
            EntityType::AttributeDefinition(e) => &mut e.common,
            EntityType::AttributeEntity(e) => &mut e.common,
            EntityType::Leader(e) => &mut e.common,
            EntityType::MultiLeader(e) => &mut e.common,
            EntityType::MLine(e) => &mut e.common,
            EntityType::Mesh(e) => &mut e.common,
            EntityType::RasterImage(e) => &mut e.common,
            EntityType::Solid3D(e) => &mut e.common,
            EntityType::Region(e) => &mut e.common,
            EntityType::Body(e) => &mut e.common,
            EntityType::Table(e) => &mut e.common,
            EntityType::Tolerance(e) => &mut e.common,
            EntityType::PolyfaceMesh(e) => &mut e.common,
            EntityType::Wipeout(e) => &mut e.common,
            EntityType::Shape(e) => &mut e.common,
            EntityType::Underlay(e) => &mut e.common,
            EntityType::Seqend(e) => &mut e.common,
            EntityType::Ole2Frame(e) => &mut e.common,
            EntityType::PolygonMesh(e) => &mut e.common,
            EntityType::Unknown(e) => &mut e.common,
        }
    }
}