fix(trim): trim/extend against polyline boundaries
build_geos only turned Line/Arc/Circle/Ray/XLine/Ellipse/Spline into cutting-edge geometry, so a polyline contributed no boundary and a line could not be trimmed (or extended) against it — even though trimming the polyline itself against lines already worked. Explode each polyline (LwPolyline / Polyline / Polyline2D / Polyline3D) into its Line + Arc segments and add them as boundaries, tagged with the polyline's handle so the click-target self-exclusion still holds. Factored the per-entity Geo build into geo_from_entity and exposed explode_polyline_segments. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
cea84ccb64
commit
610f7f140d
2 changed files with 49 additions and 9 deletions
|
|
@ -41,6 +41,20 @@ pub fn tool() -> ToolDef {
|
||||||
|
|
||||||
// ── Geometry helpers ────────────────────────────────────────────────────────
|
// ── Geometry helpers ────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
/// Explode just the polyline family (LwPolyline / Polyline / Polyline2D /
|
||||||
|
/// Polyline3D) into Line + Arc segments. No document needed — used where a
|
||||||
|
/// polyline must be treated as its constituent edges (e.g. TRIM boundaries).
|
||||||
|
/// Returns empty for any other entity type.
|
||||||
|
pub fn explode_polyline_segments(entity: &EntityType) -> Vec<EntityType> {
|
||||||
|
match entity {
|
||||||
|
EntityType::LwPolyline(p) => explode_lwpolyline(p),
|
||||||
|
EntityType::Polyline2D(p) => explode_polyline2d(p),
|
||||||
|
EntityType::Polyline(p) => explode_polyline(p),
|
||||||
|
EntityType::Polyline3D(p) => explode_polyline3d(p),
|
||||||
|
_ => vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Decompose an entity into its constituent simple entities.
|
/// Decompose an entity into its constituent simple entities.
|
||||||
/// Returns an empty vec if the entity cannot be exploded.
|
/// Returns an empty vec if the entity cannot be exploded.
|
||||||
pub fn explode_entity(entity: &EntityType, document: &CadDocument) -> Vec<EntityType> {
|
pub fn explode_entity(entity: &EntityType, document: &CadDocument) -> Vec<EntityType> {
|
||||||
|
|
|
||||||
|
|
@ -269,11 +269,39 @@ enum Geo {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_geos(entities: &[EntityType]) -> Vec<Geo> {
|
fn build_geos(entities: &[EntityType]) -> Vec<Geo> {
|
||||||
entities
|
let mut out = Vec::new();
|
||||||
.iter()
|
for e in entities {
|
||||||
.filter_map(|e| {
|
let h = e.common().handle;
|
||||||
let h = e.common().handle;
|
match e {
|
||||||
match e {
|
// A polyline acts as a boundary through its constituent edges, so
|
||||||
|
// a Line/Arc/… can be trimmed against it. Explode into Line + Arc
|
||||||
|
// segments and tag each with the polyline's own handle (so trim
|
||||||
|
// still excludes it as the click target).
|
||||||
|
EntityType::LwPolyline(_)
|
||||||
|
| EntityType::Polyline(_)
|
||||||
|
| EntityType::Polyline2D(_)
|
||||||
|
| EntityType::Polyline3D(_) => {
|
||||||
|
for seg in crate::modules::home::modify::explode::explode_polyline_segments(e) {
|
||||||
|
if let Some(g) = geo_from_entity(h, &seg) {
|
||||||
|
out.push(g);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
if let Some(g) = geo_from_entity(h, e) {
|
||||||
|
out.push(g);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert a simple boundary entity (Line / Arc / Circle / Ray / XLine /
|
||||||
|
/// Ellipse / Spline) into a `Geo`, tagged with `h`. Returns `None` for types
|
||||||
|
/// that do not act as trim boundaries.
|
||||||
|
fn geo_from_entity(h: Handle, e: &EntityType) -> Option<Geo> {
|
||||||
|
match e {
|
||||||
EntityType::Line(l) => Some(Geo::Line {
|
EntityType::Line(l) => Some(Geo::Line {
|
||||||
handle: h,
|
handle: h,
|
||||||
p1: [l.start.x, l.start.y],
|
p1: [l.start.x, l.start.y],
|
||||||
|
|
@ -344,10 +372,8 @@ fn build_geos(entities: &[EntityType]) -> Vec<Geo> {
|
||||||
.collect();
|
.collect();
|
||||||
Some(Geo::Spline { handle: h, segs })
|
Some(Geo::Spline { handle: h, segs })
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Intersection helpers ──────────────────────────────────────────────────
|
// ── Intersection helpers ──────────────────────────────────────────────────
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue