Feat: EXPLODE for Polyline, Polyline2D (bulge→Arc), Polyline3D → Lines
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
7c3cf7accc
commit
fa4fcf3c10
1 changed files with 82 additions and 0 deletions
|
|
@ -12,6 +12,7 @@ use std::f64::consts::TAU;
|
||||||
|
|
||||||
use acadrust::entities::EntityCommon;
|
use acadrust::entities::EntityCommon;
|
||||||
use acadrust::entities::{Arc as ArcEnt, Circle as CircleEnt, Line as LineEnt, LwPolyline};
|
use acadrust::entities::{Arc as ArcEnt, Circle as CircleEnt, Line as LineEnt, LwPolyline};
|
||||||
|
use acadrust::entities::{Polyline, Polyline2D};
|
||||||
use acadrust::types::Vector3;
|
use acadrust::types::Vector3;
|
||||||
use acadrust::{CadDocument, EntityType, Handle};
|
use acadrust::{CadDocument, EntityType, Handle};
|
||||||
|
|
||||||
|
|
@ -37,6 +38,9 @@ pub fn tool() -> ToolDef {
|
||||||
pub fn explode_entity(entity: &EntityType, document: &CadDocument) -> Vec<EntityType> {
|
pub fn explode_entity(entity: &EntityType, document: &CadDocument) -> Vec<EntityType> {
|
||||||
match entity {
|
match entity {
|
||||||
EntityType::LwPolyline(p) => explode_lwpolyline(p),
|
EntityType::LwPolyline(p) => explode_lwpolyline(p),
|
||||||
|
EntityType::Polyline2D(p) => explode_polyline2d(p),
|
||||||
|
EntityType::Polyline(p) => explode_polyline(p),
|
||||||
|
EntityType::Polyline3D(p) => explode_polyline3d(p),
|
||||||
EntityType::Insert(ins) => ins
|
EntityType::Insert(ins) => ins
|
||||||
.explode_from_document(document)
|
.explode_from_document(document)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
@ -46,6 +50,84 @@ pub fn explode_entity(entity: &EntityType, document: &CadDocument) -> Vec<Entity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn explode_polyline(p: &Polyline) -> Vec<EntityType> {
|
||||||
|
let n = p.vertices.len();
|
||||||
|
if n < 2 {
|
||||||
|
return vec![];
|
||||||
|
}
|
||||||
|
let closed = p.flags.is_closed();
|
||||||
|
let n_segs = if closed { n } else { n - 1 };
|
||||||
|
let mut result = Vec::new();
|
||||||
|
for i in 0..n_segs {
|
||||||
|
let v0 = &p.vertices[i];
|
||||||
|
let v1 = &p.vertices[(i + 1) % n];
|
||||||
|
let mut common = p.common.clone();
|
||||||
|
common.handle = Handle::NULL;
|
||||||
|
result.push(EntityType::Line(LineEnt {
|
||||||
|
common,
|
||||||
|
start: v0.location.clone(),
|
||||||
|
end: v1.location.clone(),
|
||||||
|
..LineEnt::new()
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
fn explode_polyline3d(p: &acadrust::entities::Polyline3D) -> Vec<EntityType> {
|
||||||
|
let n = p.vertices.len();
|
||||||
|
if n < 2 {
|
||||||
|
return vec![];
|
||||||
|
}
|
||||||
|
let closed = p.is_closed();
|
||||||
|
let n_segs = if closed { n } else { n - 1 };
|
||||||
|
let mut result = Vec::new();
|
||||||
|
for i in 0..n_segs {
|
||||||
|
let v0 = &p.vertices[i];
|
||||||
|
let v1 = &p.vertices[(i + 1) % n];
|
||||||
|
let mut common = p.common.clone();
|
||||||
|
common.handle = Handle::NULL;
|
||||||
|
result.push(EntityType::Line(LineEnt {
|
||||||
|
common,
|
||||||
|
start: v0.position.clone(),
|
||||||
|
end: v1.position.clone(),
|
||||||
|
..LineEnt::new()
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
fn explode_polyline2d(p: &Polyline2D) -> Vec<EntityType> {
|
||||||
|
let n = p.vertices.len();
|
||||||
|
if n < 2 {
|
||||||
|
return vec![];
|
||||||
|
}
|
||||||
|
let closed = p.is_closed();
|
||||||
|
let n_segs = if closed { n } else { n - 1 };
|
||||||
|
let elevation = p.elevation;
|
||||||
|
|
||||||
|
let mut result = Vec::new();
|
||||||
|
for i in 0..n_segs {
|
||||||
|
let v0 = &p.vertices[i];
|
||||||
|
let v1 = &p.vertices[(i + 1) % n];
|
||||||
|
let p0 = [v0.location.x, v0.location.y];
|
||||||
|
let p1 = [v1.location.x, v1.location.y];
|
||||||
|
|
||||||
|
if v0.bulge.abs() < 1e-10 {
|
||||||
|
let mut common = p.common.clone();
|
||||||
|
common.handle = Handle::NULL;
|
||||||
|
result.push(EntityType::Line(LineEnt {
|
||||||
|
common,
|
||||||
|
start: Vector3::new(p0[0], p0[1], elevation),
|
||||||
|
end: Vector3::new(p1[0], p1[1], elevation),
|
||||||
|
..LineEnt::new()
|
||||||
|
}));
|
||||||
|
} else if let Some(arc) = bulge_to_arc(p0, p1, v0.bulge, elevation, &p.common) {
|
||||||
|
result.push(arc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
pub fn normalize_insert_entity(mut entity: EntityType) -> EntityType {
|
pub fn normalize_insert_entity(mut entity: EntityType) -> EntityType {
|
||||||
match &mut entity {
|
match &mut entity {
|
||||||
EntityType::Arc(arc) => {
|
EntityType::Arc(arc) => {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue