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:
parent
08f4cc97f8
commit
7c818d15e9
12 changed files with 127 additions and 60 deletions
|
|
@ -2677,13 +2677,21 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
acadrust::EntityType::LwPolyline(p) => {
|
acadrust::EntityType::LwPolyline(p) => {
|
||||||
for v in &mut p.vertices {
|
let Some(mut world) =
|
||||||
|
crate::entities::curve::lwpolyline_world_xy(p)
|
||||||
|
else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
for v in &mut world.vertices {
|
||||||
if in_win(v.location.x, v.location.y) {
|
if in_win(v.location.x, v.location.y) {
|
||||||
v.location.x += dx;
|
v.location.x += dx;
|
||||||
v.location.y += dy;
|
v.location.y += dy;
|
||||||
stretched = true;
|
stretched = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if stretched {
|
||||||
|
*p = world;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
acadrust::EntityType::Polyline2D(p) => {
|
acadrust::EntityType::Polyline2D(p) => {
|
||||||
for v in &mut p.vertices {
|
for v in &mut p.vertices {
|
||||||
|
|
|
||||||
|
|
@ -857,33 +857,21 @@ impl OpenCADStudio {
|
||||||
use acadrust::types::Vector3;
|
use acadrust::types::Vector3;
|
||||||
let mut loops: Vec<Vec<Vector3>> = Vec::new();
|
let mut loops: Vec<Vec<Vector3>> = Vec::new();
|
||||||
for (_, e) in self.tabs[i].scene.selected_entities().iter() {
|
for (_, e) in self.tabs[i].scene.selected_entities().iter() {
|
||||||
match e {
|
let supported = matches!(
|
||||||
|
e,
|
||||||
acadrust::EntityType::LwPolyline(pl)
|
acadrust::EntityType::LwPolyline(pl)
|
||||||
if pl.is_closed && pl.vertices.len() >= 3 =>
|
if pl.is_closed && pl.vertices.len() >= 3
|
||||||
{
|
) || matches!(e, acadrust::EntityType::Circle(_));
|
||||||
loops.push(
|
if supported {
|
||||||
pl.vertices
|
let Some(curve) = crate::entities::curve::entity_curve(e) else {
|
||||||
.iter()
|
continue;
|
||||||
.map(|v| Vector3::new(v.location.x, v.location.y, 0.0))
|
};
|
||||||
.collect(),
|
loops.push(
|
||||||
);
|
crate::entities::curve::curve_points(&curve)
|
||||||
}
|
.into_iter()
|
||||||
acadrust::EntityType::Circle(c) => {
|
.map(|point| Vector3::new(point[0], point[1], point[2]))
|
||||||
let n = 64;
|
.collect(),
|
||||||
loops.push(
|
);
|
||||||
(0..n)
|
|
||||||
.map(|k| {
|
|
||||||
let a = std::f64::consts::TAU * k as f64 / n as f64;
|
|
||||||
Vector3::new(
|
|
||||||
c.center.x + c.radius * a.cos(),
|
|
||||||
c.center.y + c.radius * a.sin(),
|
|
||||||
c.center.z,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.collect(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if loops.is_empty() {
|
if loops.is_empty() {
|
||||||
|
|
|
||||||
|
|
@ -258,31 +258,22 @@ impl super::OpenCADStudio {
|
||||||
/// reusing the box primitive + the boolean union path.
|
/// reusing the box primitive + the boolean union path.
|
||||||
pub(super) fn solid_polysolid(&mut self, width: f64, height: f64) -> Task<Message> {
|
pub(super) fn solid_polysolid(&mut self, width: f64, height: f64) -> Task<Message> {
|
||||||
let i = self.active_tab;
|
let i = self.active_tab;
|
||||||
let found: Option<(Handle, Vec<[f64; 2]>, bool)> = self.tabs[i]
|
let found: Option<(Handle, Vec<[f64; 3]>)> = self.tabs[i]
|
||||||
.scene
|
.scene
|
||||||
.selected_entities()
|
.selected_entities()
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(h, _)| !self.tabs[i].scene.is_layer_locked(*h))
|
.filter(|(h, _)| !self.tabs[i].scene.is_layer_locked(*h))
|
||||||
.find_map(|(h, e)| match e {
|
.find_map(|(h, e)| match e {
|
||||||
EntityType::LwPolyline(pl) => Some((
|
EntityType::LwPolyline(_) => crate::entities::curve::entity_curve(e)
|
||||||
*h,
|
.map(|curve| (*h, crate::entities::curve::curve_points(&curve))),
|
||||||
pl.vertices
|
|
||||||
.iter()
|
|
||||||
.map(|v| [v.location.x, v.location.y])
|
|
||||||
.collect(),
|
|
||||||
pl.is_closed,
|
|
||||||
)),
|
|
||||||
_ => None,
|
_ => None,
|
||||||
});
|
});
|
||||||
let Some((handle, pts, closed)) = found else {
|
let Some((handle, pts)) = found else {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_error(crate::t!("POLYSOLID: select a polyline first.").as_ref());
|
.push_error(crate::t!("POLYSOLID: select a polyline first.").as_ref());
|
||||||
return Task::none();
|
return Task::none();
|
||||||
};
|
};
|
||||||
let mut segs: Vec<([f64; 2], [f64; 2])> = pts.windows(2).map(|w| (w[0], w[1])).collect();
|
let segs: Vec<([f64; 3], [f64; 3])> = pts.windows(2).map(|w| (w[0], w[1])).collect();
|
||||||
if closed && pts.len() > 2 {
|
|
||||||
segs.push((pts[pts.len() - 1], pts[0]));
|
|
||||||
}
|
|
||||||
let mut acc: Option<Body> = None;
|
let mut acc: Option<Body> = None;
|
||||||
let mut used = 0usize;
|
let mut used = 0usize;
|
||||||
for (a, b) in &segs {
|
for (a, b) in &segs {
|
||||||
|
|
@ -302,7 +293,7 @@ impl super::OpenCADStudio {
|
||||||
[cos, sin, 0.0],
|
[cos, sin, 0.0],
|
||||||
[-sin, cos, 0.0],
|
[-sin, cos, 0.0],
|
||||||
[0.0, 0.0, 1.0],
|
[0.0, 0.0, 1.0],
|
||||||
[a[0], a[1], 0.0],
|
[a[0], a[1], a[2]],
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
else {
|
else {
|
||||||
|
|
@ -570,15 +561,22 @@ impl super::OpenCADStudio {
|
||||||
.selected_entities()
|
.selected_entities()
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(h, _)| !self.tabs[i].scene.is_layer_locked(*h))
|
.filter(|(h, _)| !self.tabs[i].scene.is_layer_locked(*h))
|
||||||
.find_map(|(h, e)| match e {
|
.find_map(|(h, e)| {
|
||||||
EntityType::LwPolyline(pl) => Some((
|
let EntityType::LwPolyline(_) = e else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
let curve = crate::entities::curve::entity_curve(e)?;
|
||||||
|
let cadkernel::geom2d::Curve::Polyline(polyline) = &curve.curve else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
Some((
|
||||||
*h,
|
*h,
|
||||||
pl.vertices
|
polyline
|
||||||
|
.vertices
|
||||||
.iter()
|
.iter()
|
||||||
.map(|v| [v.location.x, v.location.y, 0.0])
|
.map(|vertex| curve.plane.point_at(vertex.position))
|
||||||
.collect(),
|
.collect(),
|
||||||
)),
|
))
|
||||||
_ => None,
|
|
||||||
});
|
});
|
||||||
let Some((handle, fit)) = found else {
|
let Some((handle, fit)) = found else {
|
||||||
self.command_line
|
self.command_line
|
||||||
|
|
@ -595,7 +593,7 @@ impl super::OpenCADStudio {
|
||||||
let p = |k: usize| glam::DVec3::new(fit[k][0], fit[k][1], fit[k][2]);
|
let p = |k: usize| glam::DVec3::new(fit[k][0], fit[k][1], fit[k][2]);
|
||||||
// Catmull-Rom → cubic Bézier control points: [P0, b1,b2,P1, b1,b2,P2, …].
|
// Catmull-Rom → cubic Bézier control points: [P0, b1,b2,P1, b1,b2,P2, …].
|
||||||
let mut ctrl: Vec<Vector3> = Vec::with_capacity(3 * m + 1);
|
let mut ctrl: Vec<Vector3> = Vec::with_capacity(3 * m + 1);
|
||||||
ctrl.push(Vector3::new(fit[0][0], fit[0][1], 0.0));
|
ctrl.push(Vector3::new(fit[0][0], fit[0][1], fit[0][2]));
|
||||||
for seg in 0..m {
|
for seg in 0..m {
|
||||||
let p0 = p(seg);
|
let p0 = p(seg);
|
||||||
let p1 = p(seg + 1);
|
let p1 = p(seg + 1);
|
||||||
|
|
@ -603,9 +601,9 @@ impl super::OpenCADStudio {
|
||||||
let next = if seg + 2 <= m { p(seg + 2) } else { p1 };
|
let next = if seg + 2 <= m { p(seg + 2) } else { p1 };
|
||||||
let b1 = p0 + (p1 - prev) / 6.0;
|
let b1 = p0 + (p1 - prev) / 6.0;
|
||||||
let b2 = p1 - (next - p0) / 6.0;
|
let b2 = p1 - (next - p0) / 6.0;
|
||||||
ctrl.push(Vector3::new(b1.x, b1.y, 0.0));
|
ctrl.push(Vector3::new(b1.x, b1.y, b1.z));
|
||||||
ctrl.push(Vector3::new(b2.x, b2.y, 0.0));
|
ctrl.push(Vector3::new(b2.x, b2.y, b2.z));
|
||||||
ctrl.push(Vector3::new(p1.x, p1.y, 0.0));
|
ctrl.push(Vector3::new(p1.x, p1.y, p1.z));
|
||||||
}
|
}
|
||||||
// Clamped piecewise-Bézier knots (degree 3): len == ctrl.len()+degree+1.
|
// Clamped piecewise-Bézier knots (degree 3): len == ctrl.len()+degree+1.
|
||||||
let mut knots: Vec<f64> = vec![0.0; 4];
|
let mut knots: Vec<f64> = vec![0.0; 4];
|
||||||
|
|
@ -617,7 +615,10 @@ impl super::OpenCADStudio {
|
||||||
spl.degree = 3;
|
spl.degree = 3;
|
||||||
spl.control_points = ctrl;
|
spl.control_points = ctrl;
|
||||||
spl.knots = knots;
|
spl.knots = knots;
|
||||||
spl.fit_points = fit.iter().map(|q| Vector3::new(q[0], q[1], 0.0)).collect();
|
spl.fit_points = fit
|
||||||
|
.iter()
|
||||||
|
.map(|q| Vector3::new(q[0], q[1], q[2]))
|
||||||
|
.collect();
|
||||||
// flags.rational defaults to false (non-rational) — exactly what we want.
|
// flags.rational defaults to false (non-rational) — exactly what we want.
|
||||||
self.push_undo_snapshot(i, "SPLINEFIT");
|
self.push_undo_snapshot(i, "SPLINEFIT");
|
||||||
self.tabs[i].scene.erase_entities(&[handle]);
|
self.tabs[i].scene.erase_entities(&[handle]);
|
||||||
|
|
|
||||||
|
|
@ -352,6 +352,42 @@ pub fn entity_curve_xy(entity: &EntityType) -> Option<Curve> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Re-expresses an axis-aligned LWPOLYLINE in world XY coordinates.
|
||||||
|
pub fn lwpolyline_world_xy(polyline: &LwPolylineEnt) -> Option<LwPolylineEnt> {
|
||||||
|
let normal = normalized(polyline.normal);
|
||||||
|
if normal.x.abs() > 1e-12 || normal.y.abs() > 1e-12 || normal.z.abs() <= 1e-12 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let Curve::Polyline(curve) = entity_curve_xy(&EntityType::LwPolyline(polyline.clone()))?
|
||||||
|
else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
if curve.vertices.len() != polyline.vertices.len() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut world = polyline.clone();
|
||||||
|
for (vertex, kernel) in world.vertices.iter_mut().zip(curve.vertices) {
|
||||||
|
vertex.location.x = kernel.position[0];
|
||||||
|
vertex.location.y = kernel.position[1];
|
||||||
|
vertex.bulge = kernel.bulge;
|
||||||
|
}
|
||||||
|
world.elevation = ocs_plane(polyline.normal, polyline.elevation).origin[2];
|
||||||
|
world.thickness *= normal.z;
|
||||||
|
world.normal = Vector3::new(0.0, 0.0, 1.0);
|
||||||
|
Some(world)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Normalizes only LWPOLYLINE entities; other types pass through unchanged.
|
||||||
|
pub fn entity_with_lwpolyline_world_xy(entity: &EntityType) -> EntityType {
|
||||||
|
match entity {
|
||||||
|
EntityType::LwPolyline(polyline) => lwpolyline_world_xy(polyline)
|
||||||
|
.map(EntityType::LwPolyline)
|
||||||
|
.unwrap_or_else(|| entity.clone()),
|
||||||
|
_ => entity.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// World-space wire points sampled by the kernel's angular policy.
|
/// World-space wire points sampled by the kernel's angular policy.
|
||||||
pub fn curve_points(curve: &PlanarCurve) -> Vec<[f64; 3]> {
|
pub fn curve_points(curve: &PlanarCurve) -> Vec<[f64; 3]> {
|
||||||
curve.tessellate_angle(cadkernel::tessellation::DEFAULT_ANGLE)
|
curve.tessellate_angle(cadkernel::tessellation::DEFAULT_ANGLE)
|
||||||
|
|
|
||||||
|
|
@ -1058,15 +1058,15 @@ impl crate::entities::traits::MassPropsCalc for acadrust::entities::LwPolyline {
|
||||||
.expect("an LwPolyline with at least two vertices has a planar curve");
|
.expect("an LwPolyline with at least two vertices has a planar curve");
|
||||||
let area = curve.curve.enclosed_area().abs();
|
let area = curve.curve.enclosed_area().abs();
|
||||||
let perimeter = curve.length();
|
let perimeter = curve.length();
|
||||||
let (cx, cy) = curve
|
let center = curve
|
||||||
.curve
|
.curve
|
||||||
.enclosed_centroid()
|
.enclosed_centroid()
|
||||||
.map(|point| (point[0], point[1]))
|
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
let x = p.vertices.iter().map(|v| v.location.x).sum::<f64>() / n as f64;
|
let x = p.vertices.iter().map(|v| v.location.x).sum::<f64>() / n as f64;
|
||||||
let y = p.vertices.iter().map(|v| v.location.y).sum::<f64>() / n as f64;
|
let y = p.vertices.iter().map(|v| v.location.y).sum::<f64>() / n as f64;
|
||||||
(x, y)
|
[x, y]
|
||||||
});
|
});
|
||||||
|
let [cx, cy, _] = curve.plane.point_at(center);
|
||||||
crate::entities::traits::MassProps {
|
crate::entities::traits::MassProps {
|
||||||
area,
|
area,
|
||||||
perimeter,
|
perimeter,
|
||||||
|
|
|
||||||
|
|
@ -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::Line(line) => Some(break_line(line, p1, p2)),
|
||||||
EntityType::Arc(arc) => Some(break_arc(arc, p1, p2)),
|
EntityType::Arc(arc) => Some(break_arc(arc, p1, p2)),
|
||||||
EntityType::Circle(c) => Some(break_circle(c, 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::Ellipse(e) => Some(break_ellipse(e, p1, p2)),
|
||||||
EntityType::Spline(s) => Some(break_spline(s, p1, p2)),
|
EntityType::Spline(s) => Some(break_spline(s, p1, p2)),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ use acadrust::types::Vector3;
|
||||||
use acadrust::{CadDocument, EntityType, Handle};
|
use acadrust::{CadDocument, EntityType, Handle};
|
||||||
|
|
||||||
use crate::command::{CadCommand, CmdResult};
|
use crate::command::{CadCommand, CmdResult};
|
||||||
|
use crate::entities::curve::lwpolyline_world_xy;
|
||||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||||
use glam::DVec3;
|
use glam::DVec3;
|
||||||
use crate::t;
|
use crate::t;
|
||||||
|
|
@ -188,6 +189,9 @@ pub fn normalize_entity_for_block(entity: EntityType) -> EntityType {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn explode_lwpolyline(p: &LwPolyline) -> Vec<EntityType> {
|
fn explode_lwpolyline(p: &LwPolyline) -> Vec<EntityType> {
|
||||||
|
let Some(p) = lwpolyline_world_xy(p) else {
|
||||||
|
return vec![];
|
||||||
|
};
|
||||||
let n = p.vertices.len();
|
let n = p.vertices.len();
|
||||||
if n < 2 {
|
if n < 2 {
|
||||||
return vec![];
|
return vec![];
|
||||||
|
|
|
||||||
|
|
@ -1012,6 +1012,10 @@ pub struct FilletCommand {
|
||||||
|
|
||||||
impl FilletCommand {
|
impl FilletCommand {
|
||||||
pub fn new(radius: f64, all_entities: Vec<EntityType>) -> Self {
|
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);
|
let entity_index = ModifyEntityIndex::build(&all_entities);
|
||||||
Self {
|
Self {
|
||||||
radius: radius as f64,
|
radius: radius as f64,
|
||||||
|
|
@ -1392,6 +1396,10 @@ pub struct ChamferCommand {
|
||||||
|
|
||||||
impl ChamferCommand {
|
impl ChamferCommand {
|
||||||
pub fn new(dist: f64, all_entities: Vec<EntityType>) -> Self {
|
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);
|
let entity_index = ModifyEntityIndex::build(&all_entities);
|
||||||
Self {
|
Self {
|
||||||
dist1: dist as f64,
|
dist1: dist as f64,
|
||||||
|
|
|
||||||
|
|
@ -123,6 +123,7 @@ fn segs_of(e: &EntityType) -> Option<Vec<Seg>> {
|
||||||
}])
|
}])
|
||||||
}
|
}
|
||||||
EntityType::LwPolyline(p) => {
|
EntityType::LwPolyline(p) => {
|
||||||
|
let p = crate::entities::curve::lwpolyline_world_xy(p)?;
|
||||||
if p.is_closed || p.vertices.len() < 2 {
|
if p.is_closed || p.vertices.len() < 2 {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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::Arc(a) => lengthen_arc(a, pick_pt, mode),
|
||||||
EntityType::Ellipse(e) => lengthen_ellipse(e, pick_pt, mode),
|
EntityType::Ellipse(e) => lengthen_ellipse(e, pick_pt, mode),
|
||||||
EntityType::Spline(s) => lengthen_spline(s, 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,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
// 3. Pick a point on the side to offset toward, or choose Multiple
|
// 3. Pick a point on the side to offset toward, or choose Multiple
|
||||||
// to keep offsetting the newly created result at the same distance
|
// 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 crate::modules::draw::modify::spline_ops::spline_sample_xy;
|
||||||
use acadrust::entities::LwVertex;
|
use acadrust::entities::LwVertex;
|
||||||
use acadrust::entities::{
|
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
|
/// offset passed to the algorithm is always ±1. This avoids fixed-epsilon
|
||||||
/// failures on tiny drawings and on UTM-scale coordinates.
|
/// failures on tiny drawings and on UTM-scale coordinates.
|
||||||
fn offset_lwpolylines(p: &LwPolyline, dist: f64, side_pt: Vec3) -> Vec<EntityType> {
|
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 {
|
let source = KernelPolyline {
|
||||||
closed: p.is_closed,
|
closed: p.is_closed,
|
||||||
vertices: p
|
vertices: p
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ use cadkernel::geom2d::{
|
||||||
NurbsCurve, Ray as KernelRay, Tolerance as KernelTolerance, XLine as KernelXLine,
|
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::command::{CadCommand, CmdResult};
|
||||||
use crate::modules::draw::modify::spline_ops::{
|
use crate::modules::draw::modify::spline_ops::{
|
||||||
|
|
@ -2171,6 +2171,10 @@ pub struct TrimCommand {
|
||||||
|
|
||||||
impl TrimCommand {
|
impl TrimCommand {
|
||||||
pub fn new(all_entities: Vec<EntityType>) -> Self {
|
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 entity_index = ModifyEntityIndex::build(&all_entities);
|
||||||
let geos = build_geos(&all_entities);
|
let geos = build_geos(&all_entities);
|
||||||
Self {
|
Self {
|
||||||
|
|
@ -2907,6 +2911,10 @@ pub struct ExtendCommand {
|
||||||
|
|
||||||
impl ExtendCommand {
|
impl ExtendCommand {
|
||||||
pub fn new(all_entities: Vec<EntityType>) -> Self {
|
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 entity_index = ModifyEntityIndex::build(&all_entities);
|
||||||
let geos = build_geos(&all_entities);
|
let geos = build_geos(&all_entities);
|
||||||
Self {
|
Self {
|
||||||
|
|
@ -3832,6 +3840,10 @@ pub struct ExtrimCommand {
|
||||||
|
|
||||||
impl ExtrimCommand {
|
impl ExtrimCommand {
|
||||||
pub fn new(all: Vec<(Handle, EntityType)>) -> Self {
|
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() }
|
Self { all, boundary: None, geos: Vec::new() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue