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 <[email protected]>
This commit is contained in:
Hakan SevenandClaude Opus 4.8 committed 2026-06-12 01:06:29 +03:00
1 parent cea84ccb64
commit 610f7f140d
2 files changed
+49 -9

No files matched your search

+14
View File
@@ -41,6 +41,20 @@ pub fn tool() -> ToolDef {
// ── 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.
/// Returns an empty vec if the entity cannot be exploded.
pub fn explode_entity(entity: &EntityType, document: &CadDocument) -> Vec<EntityType> {
+35 -9
View File
@@ -269,11 +269,39 @@ enum Geo {
}
fn build_geos(entities: &[EntityType]) -> Vec<Geo> {
entities
.iter()
.filter_map(|e| {
let h = e.common().handle;
match e {
let mut out = Vec::new();
for e in entities {
let h = e.common().handle;
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 {
handle: h,
p1: [l.start.x, l.start.y],
@@ -344,10 +372,8 @@ fn build_geos(entities: &[EntityType]) -> Vec<Geo> {
.collect();
Some(Geo::Spline { handle: h, segs })
}
_ => None,
}
})
.collect()
_ => None,
}
}
// ── Intersection helpers ──────────────────────────────────────────────────