fix(geometry): honor polyline OCS in commands

Route editing and derived geometry through kernel world-space curves.\n\nRefs #797\nRefs #798\nRefs #799
This commit is contained in:
Hakan Seven 2026-08-18 22:09:48 +03:00
commit 7c818d15e9
12 changed files with 127 additions and 60 deletions

View file

@ -41,7 +41,10 @@ pub fn break_entity(entity: &EntityType, p1: DVec3, p2: DVec3) -> Option<Vec<Ent
EntityType::Line(line) => Some(break_line(line, p1, p2)),
EntityType::Arc(arc) => Some(break_arc(arc, p1, p2)),
EntityType::Circle(c) => Some(break_circle(c, p1, p2)),
EntityType::LwPolyline(p) => Some(break_lwpolyline(p, p1, p2)),
EntityType::LwPolyline(p) => {
let p = crate::entities::curve::lwpolyline_world_xy(p)?;
Some(break_lwpolyline(&p, p1, p2))
}
EntityType::Ellipse(e) => Some(break_ellipse(e, p1, p2)),
EntityType::Spline(s) => Some(break_spline(s, p1, p2)),
_ => None,

View file

@ -27,6 +27,7 @@ use acadrust::types::Vector3;
use acadrust::{CadDocument, EntityType, Handle};
use crate::command::{CadCommand, CmdResult};
use crate::entities::curve::lwpolyline_world_xy;
use crate::modules::{IconKind, ModuleEvent, ToolDef};
use glam::DVec3;
use crate::t;
@ -188,6 +189,9 @@ pub fn normalize_entity_for_block(entity: EntityType) -> EntityType {
}
fn explode_lwpolyline(p: &LwPolyline) -> Vec<EntityType> {
let Some(p) = lwpolyline_world_xy(p) else {
return vec![];
};
let n = p.vertices.len();
if n < 2 {
return vec![];

View file

@ -1012,6 +1012,10 @@ pub struct FilletCommand {
impl FilletCommand {
pub fn new(radius: f64, all_entities: Vec<EntityType>) -> Self {
let all_entities: Vec<EntityType> = all_entities
.iter()
.map(crate::entities::curve::entity_with_lwpolyline_world_xy)
.collect();
let entity_index = ModifyEntityIndex::build(&all_entities);
Self {
radius: radius as f64,
@ -1392,6 +1396,10 @@ pub struct ChamferCommand {
impl ChamferCommand {
pub fn new(dist: f64, all_entities: Vec<EntityType>) -> Self {
let all_entities: Vec<EntityType> = all_entities
.iter()
.map(crate::entities::curve::entity_with_lwpolyline_world_xy)
.collect();
let entity_index = ModifyEntityIndex::build(&all_entities);
Self {
dist1: dist as f64,

View file

@ -123,6 +123,7 @@ fn segs_of(e: &EntityType) -> Option<Vec<Seg>> {
}])
}
EntityType::LwPolyline(p) => {
let p = crate::entities::curve::lwpolyline_world_xy(p)?;
if p.is_closed || p.vertices.len() < 2 {
return None;
}

View file

@ -158,7 +158,10 @@ pub fn lengthen_entity(entity: &EntityType, pick_pt: Vec3, mode: &LenMode) -> Op
EntityType::Arc(a) => lengthen_arc(a, pick_pt, mode),
EntityType::Ellipse(e) => lengthen_ellipse(e, pick_pt, mode),
EntityType::Spline(s) => lengthen_spline(s, pick_pt, mode),
EntityType::LwPolyline(p) => lengthen_lwpoly(p, pick_pt, mode),
EntityType::LwPolyline(p) => {
let p = crate::entities::curve::lwpolyline_world_xy(p)?;
lengthen_lwpoly(&p, pick_pt, mode)
}
_ => None,
}
}

View file

@ -10,7 +10,7 @@
// 3. Pick a point on the side to offset toward, or choose Multiple
// to keep offsetting the newly created result at the same distance
use crate::entities::curve::entity_curve;
use crate::entities::curve::{entity_curve, lwpolyline_world_xy};
use crate::modules::draw::modify::spline_ops::spline_sample_xy;
use acadrust::entities::LwVertex;
use acadrust::entities::{
@ -160,6 +160,9 @@ fn offset_arc(a: &ArcEnt, dist: f64, side_pt: Vec3) -> Option<EntityType> {
/// offset passed to the algorithm is always ±1. This avoids fixed-epsilon
/// failures on tiny drawings and on UTM-scale coordinates.
fn offset_lwpolylines(p: &LwPolyline, dist: f64, side_pt: Vec3) -> Vec<EntityType> {
let Some(p) = lwpolyline_world_xy(p) else {
return Vec::new();
};
let source = KernelPolyline {
closed: p.is_closed,
vertices: p

View file

@ -35,7 +35,7 @@ use cadkernel::geom2d::{
NurbsCurve, Ray as KernelRay, Tolerance as KernelTolerance, XLine as KernelXLine,
};
use crate::entities::curve::entity_curve_xy;
use crate::entities::curve::{entity_curve_xy, entity_with_lwpolyline_world_xy};
use crate::command::{CadCommand, CmdResult};
use crate::modules::draw::modify::spline_ops::{
@ -2171,6 +2171,10 @@ pub struct TrimCommand {
impl TrimCommand {
pub fn new(all_entities: Vec<EntityType>) -> Self {
let all_entities: Vec<EntityType> = all_entities
.iter()
.map(entity_with_lwpolyline_world_xy)
.collect();
let entity_index = ModifyEntityIndex::build(&all_entities);
let geos = build_geos(&all_entities);
Self {
@ -2907,6 +2911,10 @@ pub struct ExtendCommand {
impl ExtendCommand {
pub fn new(all_entities: Vec<EntityType>) -> Self {
let all_entities: Vec<EntityType> = all_entities
.iter()
.map(entity_with_lwpolyline_world_xy)
.collect();
let entity_index = ModifyEntityIndex::build(&all_entities);
let geos = build_geos(&all_entities);
Self {
@ -3832,6 +3840,10 @@ pub struct ExtrimCommand {
impl ExtrimCommand {
pub fn new(all: Vec<(Handle, EntityType)>) -> Self {
let all = all
.into_iter()
.map(|(handle, entity)| (handle, entity_with_lwpolyline_world_xy(&entity)))
.collect();
Self { all, boundary: None, geos: Vec::new() }
}
}