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
//! Unknown entity type for round-trip preservation.
//!
//! When the reader encounters an entity type that is not directly supported,
//! it captures the common entity properties (handle, layer, color, …) and
//! the raw record data so the entity can be written back losslessly.
//!
//! For DWG files, the entire merged-stream record is stored in
//! [`raw_dwg_data`](UnknownEntity::raw_dwg_data) together with the
//! original DWG type code. The writer emits these bytes verbatim,
//! preserving the entity exactly as it was in the source file.
//!
//! For DXF files, the entity-specific group-code pairs are stored in
//! [`raw_dxf_codes`](UnknownEntity::raw_dxf_codes) so they can be
//! written back alongside the common entity data.
use crate::entities::{Entity, EntityCommon};
use crate::types::{BoundingBox3D, Color, Handle, LineWeight, Transform, Transparency, Vector3};
/// An entity whose type is not directly supported by the library.
///
/// Preserves the DXF/DWG type name and common entity properties.
/// When raw data is available (DWG `raw_dwg_data` or DXF
/// `raw_dxf_codes`), the entity is written back losslessly.
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct UnknownEntity {
/// Common entity data (handle, layer, color, reactors, …).
pub common: EntityCommon,
/// The DXF type name as it appeared in the file (e.g. `"ACAD_PROXY_ENTITY"`).
pub dxf_name: String,
/// DWG object type code (from the binary record header).
/// `0` if the entity did not come from a DWG file.
pub dwg_type_code: i16,
/// Raw DWG merged-stream record bytes.
///
/// This is the exact payload between the ModularShort length prefix
/// and the CRC-16 trailer. When present the writer emits these
/// bytes verbatim (with fresh framing) so the entity survives a
/// roundtrip without any data loss.
#[cfg_attr(feature = "serde", serde(skip))]
pub raw_dwg_data: Option<Vec<u8>>,
/// Handle-stream bit count for R2010+ DWG records.
///
/// Stored alongside `raw_dwg_data` because R2010+ records require
/// a ModularChar(handle_bits) field in the framing header.
pub dwg_handle_bits: i64,
/// Raw DXF entity-specific group-code pairs.
///
/// Each entry is `(group_code, value_string)`. When present the
/// DXF writer emits the common entity header followed by these
/// pairs, reproducing the original entity content.
#[cfg_attr(feature = "serde", serde(skip))]
pub raw_dxf_codes: Option<Vec<(i32, String)>>,
}
impl UnknownEntity {
/// Create a new unknown entity with the given DXF type name.
pub fn new(dxf_name: impl Into<String>) -> Self {
Self {
common: EntityCommon::new(),
dxf_name: dxf_name.into(),
dwg_type_code: 0,
raw_dwg_data: None,
dwg_handle_bits: 0,
raw_dxf_codes: None,
}
}
}
impl Entity for UnknownEntity {
fn handle(&self) -> Handle { self.common.handle }
fn set_handle(&mut self, handle: Handle) { self.common.handle = handle; }
fn layer(&self) -> &str { &self.common.layer }
fn set_layer(&mut self, layer: String) { self.common.layer = layer; }
fn color(&self) -> Color { self.common.color }
fn set_color(&mut self, color: Color) { self.common.color = color; }
fn line_weight(&self) -> LineWeight { self.common.line_weight }
fn set_line_weight(&mut self, weight: LineWeight) { self.common.line_weight = weight; }
fn transparency(&self) -> Transparency { self.common.transparency }
fn set_transparency(&mut self, transparency: Transparency) { self.common.transparency = transparency; }
fn is_invisible(&self) -> bool { self.common.invisible }
fn set_invisible(&mut self, invisible: bool) { self.common.invisible = invisible; }
fn bounding_box(&self) -> BoundingBox3D { BoundingBox3D::from_point(Vector3::ZERO) }
fn translate(&mut self, _offset: Vector3) { super::translate::translate_unknown(self, _offset); }
fn entity_type(&self) -> &'static str { "UNKNOWN" }
fn apply_transform(&mut self, _transform: &Transform) { super::transform::transform_unknown(self, _transform); }
}