forked from 1b-agent/opencadstudio-upstream
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:
1 parent
cea84ccb64
commit
610f7f140d
2 files changed
+49
-9
No files matched your search
@@ -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> {
|
||||
|
||||
@@ -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 ──────────────────────────────────────────────────
|
||||
|
||||
Reference in new issue
Block a user