forked from 1b-agent/opencadstudio-upstream
fix(modify): preserve polyline extrusion frames
This commit is contained in:
1 parent
9654986a0a
commit
5c3aa1c25c
3 files changed
+143
-21
No files matched your search
@@ -153,6 +153,11 @@ fn explode_polyline2d(p: &Polyline2D) -> Vec<EntityType> {
|
||||
let closed = p.is_closed();
|
||||
let n_segs = if closed { n } else { n - 1 };
|
||||
let elevation = p.elevation;
|
||||
let normal = DVec3::new(p.normal.x, p.normal.y, p.normal.z)
|
||||
.try_normalize()
|
||||
.unwrap_or(DVec3::Z);
|
||||
let normal = Vector3::new(normal.x, normal.y, normal.z);
|
||||
let plane = crate::entities::curve::ocs_plane(normal.clone(), elevation);
|
||||
|
||||
let mut result = Vec::new();
|
||||
for i in 0..n_segs {
|
||||
@@ -164,15 +169,25 @@ fn explode_polyline2d(p: &Polyline2D) -> Vec<EntityType> {
|
||||
if v0.bulge.abs() < 1e-10 {
|
||||
let mut common = p.common.clone();
|
||||
common.handle = Handle::NULL;
|
||||
let start = plane.point_at(p0);
|
||||
let end = plane.point_at(p1);
|
||||
result.push(EntityType::Line(LineEnt {
|
||||
common,
|
||||
start: Vector3::new(p0[0], p0[1], elevation),
|
||||
end: Vector3::new(p1[0], p1[1], elevation),
|
||||
start: Vector3::new(start[0], start[1], start[2]),
|
||||
end: Vector3::new(end[0], end[1], end[2]),
|
||||
thickness: p.thickness,
|
||||
normal: normal.clone(),
|
||||
..LineEnt::new()
|
||||
}));
|
||||
} else if let Some(arc) = bulge_to_arc(p0, p1, v0.bulge, elevation, &p.common, p.thickness)
|
||||
{
|
||||
} else if let Some(arc) = bulge_to_arc(
|
||||
p0,
|
||||
p1,
|
||||
v0.bulge,
|
||||
elevation,
|
||||
&p.common,
|
||||
p.thickness,
|
||||
normal.clone(),
|
||||
) {
|
||||
result.push(arc);
|
||||
}
|
||||
}
|
||||
@@ -240,12 +255,21 @@ fn explode_lwpolyline(p: &LwPolyline) -> Vec<EntityType> {
|
||||
start: Vector3::new(p0[0], p0[1], elevation),
|
||||
end: Vector3::new(p1[0], p1[1], elevation),
|
||||
thickness: p.thickness,
|
||||
normal: p.normal.clone(),
|
||||
..LineEnt::new()
|
||||
};
|
||||
result.push(EntityType::Line(line));
|
||||
} else {
|
||||
// Arc segment from bulge
|
||||
if let Some(arc) = bulge_to_arc(p0, p1, v0.bulge, elevation, &p.common, p.thickness) {
|
||||
if let Some(arc) = bulge_to_arc(
|
||||
p0,
|
||||
p1,
|
||||
v0.bulge,
|
||||
elevation,
|
||||
&p.common,
|
||||
p.thickness,
|
||||
p.normal.clone(),
|
||||
) {
|
||||
result.push(arc);
|
||||
}
|
||||
}
|
||||
@@ -262,6 +286,7 @@ fn bulge_to_arc(
|
||||
elevation: f64,
|
||||
common_src: &EntityCommon,
|
||||
thickness: f64,
|
||||
normal: Vector3,
|
||||
) -> Option<EntityType> {
|
||||
let ba = crate::entities::common::BulgeArc::from_bulge(p0, p1, bulge)?;
|
||||
|
||||
@@ -285,6 +310,7 @@ fn bulge_to_arc(
|
||||
start_angle,
|
||||
end_angle,
|
||||
thickness,
|
||||
normal,
|
||||
..ArcEnt::new()
|
||||
};
|
||||
Some(EntityType::Arc(arc))
|
||||
@@ -1763,4 +1789,28 @@ mod tests {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn explode_keeps_polyline2d_extrusion() {
|
||||
use acadrust::entities::Vertex2D;
|
||||
|
||||
let mut pl = Polyline2D::new();
|
||||
pl.vertices = vec![
|
||||
Vertex2D::new(Vector3::new(0.0, 0.0, 0.0)),
|
||||
Vertex2D::new(Vector3::new(10.0, 0.0, 0.0)),
|
||||
];
|
||||
pl.elevation = 2.0;
|
||||
pl.thickness = -4.0;
|
||||
pl.normal = Vector3::new(1.0, 0.0, 0.0);
|
||||
|
||||
let pieces = explode_polyline_segments(&EntityType::Polyline2D(pl));
|
||||
let Some(EntityType::Line(line)) = pieces.first() else {
|
||||
panic!("expected one line");
|
||||
};
|
||||
assert_eq!(pieces.len(), 1);
|
||||
assert_eq!(line.normal, Vector3::new(1.0, 0.0, 0.0));
|
||||
assert!((line.thickness + 4.0).abs() < 1e-12);
|
||||
assert!((line.start.x - 2.0).abs() < 1e-12);
|
||||
assert!((line.end.x - 2.0).abs() < 1e-12);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user