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
// SPDX-License-Identifier: ISC
use crate::point::Point3;
use crate::value::GroupValue;
use alloc::vec::Vec;
/// A VERTEX entity within a [`Polyline`].
#[derive(Debug, Clone, Copy, Default)]
pub struct Vertex {
/// Vertex location.
pub location: Point3,
/// Bulge factor.
///
/// The tangent of one quarter of the arc's included angle for the
/// segment starting at this vertex. Zero means a straight segment.
/// Positive values produce counter-clockwise arcs; negative values
/// produce clockwise arcs. A bulge of 1.0 is a semicircle.
pub bulge: f64,
/// Starting width for this segment.
pub start_width: f64,
/// Ending width for this segment.
pub end_width: f64,
/// Curve fit tangent direction in degrees.
pub tangent_direction: f64,
/// Vertex flags.
///
/// `0b1` = extra vertex from curve fitting, `0b10` = curve fit
/// tangent defined, `0b1000` = spline vertex from spline fitting,
/// `0b1_0000` = spline frame control point,
/// `0b100_0000` = 3D polyline vertex,
/// `0b1000_0000` = polyface mesh face record.
pub flags: i16,
/// Polyface vertex indices.
///
/// Used only when this vertex is a polyface face record
/// (`flags & 0b1000_0000`). Each element is a 1-based index into
/// the polyline's vertex list. Negative values indicate the edge
/// following that vertex is invisible.
pub polyface_vertex_index: [i16; 4],
}
impl Vertex {
pub(crate) fn feed(&mut self, code: u16, val: &GroupValue) {
match code {
70 => {
if let Some(v) = val.as_i16() {
self.flags = v;
}
}
71 => {
if let Some(v) = val.as_i16() {
self.polyface_vertex_index[0] = v;
}
}
72 => {
if let Some(v) = val.as_i16() {
self.polyface_vertex_index[1] = v;
}
}
73 => {
if let Some(v) = val.as_i16() {
self.polyface_vertex_index[2] = v;
}
}
74 => {
if let Some(v) = val.as_i16() {
self.polyface_vertex_index[3] = v;
}
}
_ => {
if let Some(f) = val.as_f64() {
match code {
10 => self.location.x = f,
20 => self.location.y = f,
30 => self.location.z = f,
40 => self.start_width = f,
41 => self.end_width = f,
42 => self.bulge = f,
50 => self.tangent_direction = f,
_ => {}
}
}
}
}
}
}
/// A POLYLINE entity.
///
/// Covers 2D/3D polylines, polygon meshes (`0b1_0000`), and polyface
/// meshes (`0b100_0000`). Child VERTEX entities are collected between
/// the POLYLINE and its SEQEND.
#[derive(Debug, Clone, Default)]
pub struct Polyline {
/// Polyline flags.
///
/// `0b1` = closed in M direction, `0b10` = curve-fit vertices
/// added, `0b100` = spline-fit vertices added,
/// `0b1000` = 3D polyline, `0b1_0000` = polygon mesh,
/// `0b10_0000` = closed in N direction (mesh),
/// `0b100_0000` = polyface mesh.
pub flags: i16,
/// Mesh M vertex count.
pub vertex_count_m: i16,
/// Mesh N vertex count.
pub vertex_count_n: i16,
/// Smooth surface density M.
pub smooth_surface_density_m: i16,
/// Smooth surface density N.
pub smooth_surface_density_n: i16,
/// Surface type.
pub surface_type: i16,
/// Elevation for 2D polylines.
pub elevation: f64,
/// Extrusion thickness.
pub thickness: f64,
/// Default start width.
pub start_width: f64,
/// Default end width.
pub end_width: f64,
/// Child VERTEX entities collected between POLYLINE and SEQEND.
pub vertices: Vec<Vertex>,
}
impl Polyline {
/// Returns `true` if the closed flag (`0b1`) is set.
pub fn is_closed(&self) -> bool {
self.flags & 1 != 0
}
pub(crate) fn feed(&mut self, code: u16, val: &GroupValue) {
match code {
70 => {
if let Some(v) = val.as_i16() {
self.flags = v;
}
}
71 => {
if let Some(v) = val.as_i16() {
self.vertex_count_m = v;
}
}
72 => {
if let Some(v) = val.as_i16() {
self.vertex_count_n = v;
}
}
73 => {
if let Some(v) = val.as_i16() {
self.smooth_surface_density_m = v;
}
}
74 => {
if let Some(v) = val.as_i16() {
self.smooth_surface_density_n = v;
}
}
75 => {
if let Some(v) = val.as_i16() {
self.surface_type = v;
}
}
_ => {
if let Some(f) = val.as_f64() {
match code {
30 => self.elevation = f,
39 => self.thickness = f,
40 => self.start_width = f,
41 => self.end_width = f,
_ => {}
}
}
}
}
}
}