From 4a93fc4949ba886652ee7a0b0254654719564fff Mon Sep 17 00:00:00 2001 From: Hakan Seven Date: Thu, 2 Apr 2026 18:51:38 +0300 Subject: [PATCH] =?UTF-8?q?Feat:=20Phase=204.1/4.2=20=E2=80=94=20Polyline,?= =?UTF-8?q?=20Polyline2D,=20Polyline3D,=20Ray,=20XLine=20render=20and=20gr?= =?UTF-8?q?ips?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - polyline.rs: TruckConvertible/Grippable/PropertyEditable/Transformable for all three polyline types; Polyline2D handles bulge arcs via the same truck Wire path as LwPolyline; Polyline and Polyline3D use TruckObject::Lines for straight-segment rendering - ray.rs: Ray renders as base→+1e6; XLine renders as ±1e6; both have base-point and direction grips; mirror correctly reflects direction vector; base X/Y/Z and Dir X/Y/Z exposed in properties panel - traits.rs: dispatch all five new entity types through to_truck_entity, grips, geometry_properties, apply_geom_prop, apply_grip, apply_transform Co-Authored-By: Claude Sonnet 4.6 --- src/entities/mod.rs | 2 + src/entities/polyline.rs | 398 +++++++++++++++++++++++++++++++++++++++ src/entities/ray.rs | 255 +++++++++++++++++++++++++ src/entities/traits.rs | 45 +++++ 4 files changed, 700 insertions(+) create mode 100644 src/entities/polyline.rs create mode 100644 src/entities/ray.rs diff --git a/src/entities/mod.rs b/src/entities/mod.rs index 6d45d304d..b3778a87e 100644 --- a/src/entities/mod.rs +++ b/src/entities/mod.rs @@ -11,6 +11,8 @@ pub mod multileader; pub mod lwpolyline; pub mod mtext; pub mod point; +pub mod polyline; +pub mod ray; pub mod spline; pub mod text; mod text_support; diff --git a/src/entities/polyline.rs b/src/entities/polyline.rs new file mode 100644 index 000000000..523fe70e4 --- /dev/null +++ b/src/entities/polyline.rs @@ -0,0 +1,398 @@ +use std::f64::consts::TAU; + +use acadrust::entities::{Polyline, Polyline2D, Polyline3D}; +use glam::Vec3; +use truck_modeling::{builder, Edge, Point3, Wire}; + +use crate::command::EntityTransform; +use crate::entities::common::{edit_prop as edit, ro_prop as ro, square_grip}; +use crate::entities::traits::{Grippable, PropertyEditable, Transformable, TruckConvertible}; +use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; +use crate::scene::object::{GripApply, GripDef, PropSection, PropValue, Property}; +use crate::scene::wire_model::TangentGeom; + +// ── Polyline (old-style 3D heavy polyline) ──────────────────────────────────── + +fn tessellate_polyline(pl: &Polyline) -> TruckEntity { + let pts: Vec<[f32; 3]> = pl + .vertices + .iter() + .map(|v| [v.location.x as f32, v.location.y as f32, v.location.z as f32]) + .collect(); + + let mut points = pts.clone(); + if pl.flags.is_closed() && pts.len() >= 2 { + points.push(pts[0]); + } + + let key_verts = pts.clone(); + TruckEntity { + object: TruckObject::Lines(points), + snap_pts: vec![], + tangent_geoms: vec![], + key_vertices: key_verts, + } +} + +impl TruckConvertible for Polyline { + fn to_truck(&self, _document: &acadrust::CadDocument) -> Option { + Some(tessellate_polyline(self)) + } +} + +impl Grippable for Polyline { + fn grips(&self) -> Vec { + self.vertices + .iter() + .enumerate() + .map(|(i, v)| { + square_grip( + i, + Vec3::new(v.location.x as f32, v.location.y as f32, v.location.z as f32), + ) + }) + .collect() + } + + fn apply_grip(&mut self, grip_id: usize, apply: GripApply) { + if let Some(v) = self.vertices.get_mut(grip_id) { + match apply { + GripApply::Translate(d) => { + v.location.x += d.x as f64; + v.location.y += d.y as f64; + v.location.z += d.z as f64; + } + GripApply::Absolute(p) => { + v.location.x = p.x as f64; + v.location.y = p.y as f64; + v.location.z = p.z as f64; + } + } + } + } +} + +impl PropertyEditable for Polyline { + fn geometry_properties(&self, _text_style_names: &[String]) -> PropSection { + PropSection { + title: "Geometry".into(), + props: vec![ + ro("Vertices", "vertices", self.vertices.len().to_string()), + Property { + label: "Closed".into(), + field: "pl_closed", + value: PropValue::BoolToggle { + field: "pl_closed", + value: self.flags.is_closed(), + }, + }, + ], + } + } + + fn apply_geom_prop(&mut self, field: &str, value: &str) { + if field == "pl_closed" { + let closed = if value == "toggle" { + !self.flags.is_closed() + } else { + value == "true" + }; + self.flags.set_closed(closed); + } + } +} + +impl Transformable for Polyline { + fn apply_transform(&mut self, t: &EntityTransform) { + crate::scene::transform::apply_standard_entity_transform(self, t, |entity, p1, p2| { + for v in &mut entity.vertices { + crate::scene::transform::reflect_xy_point( + &mut v.location.x, + &mut v.location.y, + p1, + p2, + ); + } + }); + } +} + +// ── Polyline2D (heavy 2D polyline with bulge) ───────────────────────────────── + +fn tessellate_polyline2d(pl: &Polyline2D) -> TruckEntity { + let verts = &pl.vertices; + if verts.is_empty() { + return TruckEntity { + object: TruckObject::Lines(vec![]), + snap_pts: vec![], + tangent_geoms: vec![], + key_vertices: vec![], + }; + } + + let elev = pl.elevation; + let count = verts.len(); + let seg_count = if pl.is_closed() { count } else { count - 1 }; + let mut edges: Vec = Vec::new(); + let mut tangents: Vec = Vec::new(); + let mut key_verts: Vec<[f32; 3]> = Vec::new(); + + let to_pt = |v: &acadrust::entities::Vertex2D| -> Point3 { + Point3::new(v.location.x, v.location.y, elev) + }; + + for i in 0..seg_count { + let v0 = &verts[i]; + let v1 = &verts[(i + 1) % count]; + let p0 = to_pt(v0); + let p1 = to_pt(v1); + let bulge = v0.bulge; + + if bulge.abs() < 1e-9 { + let tv0 = builder::vertex(p0); + let tv1 = builder::vertex(p1); + edges.push(builder::line(&tv0, &tv1)); + tangents.push(TangentGeom::Line { + p1: [p0.x as f32, p0.y as f32, p0.z as f32], + p2: [p1.x as f32, p1.y as f32, p1.z as f32], + }); + } else { + let angle = 4.0 * bulge.atan(); + let dx = p1.x - p0.x; + let dy = p1.y - p0.y; + let d = (dx * dx + dy * dy).sqrt(); + let r = (d / 2.0) / (angle / 2.0).sin().abs(); + let mx = (p0.x + p1.x) * 0.5; + let my = (p0.y + p1.y) * 0.5; + let len = d.max(1e-12); + let px = -dy / len; + let py = dx / len; + let sagitta_sign = if bulge > 0.0 { 1.0_f64 } else { -1.0_f64 }; + let h = r - (r * r - d * d / 4.0).max(0.0).sqrt(); + let cx = mx - sagitta_sign * px * (r - h); + let cy = my - sagitta_sign * py * (r - h); + let mid_a = { + let a0 = (p0.y - cy).atan2(p0.x - cx); + let a1 = (p1.y - cy).atan2(p1.x - cx); + let (sa, mut ea) = if bulge > 0.0 { (a0, a1) } else { (a1, a0) }; + if ea < sa { + ea += TAU; + } + sa + (ea - sa) * 0.5 + }; + let p_mid = Point3::new(cx + r * mid_a.cos(), cy + r * mid_a.sin(), p0.z); + let tv0 = builder::vertex(p0); + let tv1 = builder::vertex(p1); + edges.push(builder::circle_arc(&tv0, &tv1, p_mid)); + tangents.push(TangentGeom::Circle { + center: [cx as f32, cy as f32, p0.z as f32], + radius: r as f32, + }); + } + + if i == 0 { + key_verts.push([p0.x as f32, p0.y as f32, p0.z as f32]); + } + key_verts.push([p1.x as f32, p1.y as f32, p1.z as f32]); + } + + TruckEntity { + object: TruckObject::Contour(edges.into_iter().collect::()), + snap_pts: vec![], + tangent_geoms: tangents, + key_vertices: key_verts, + } +} + +impl TruckConvertible for Polyline2D { + fn to_truck(&self, _document: &acadrust::CadDocument) -> Option { + Some(tessellate_polyline2d(self)) + } +} + +impl Grippable for Polyline2D { + fn grips(&self) -> Vec { + let elev = self.elevation as f32; + self.vertices + .iter() + .enumerate() + .map(|(i, v)| { + square_grip( + i, + Vec3::new(v.location.x as f32, v.location.y as f32, elev), + ) + }) + .collect() + } + + fn apply_grip(&mut self, grip_id: usize, apply: GripApply) { + if let Some(v) = self.vertices.get_mut(grip_id) { + match apply { + GripApply::Translate(d) => { + v.location.x += d.x as f64; + v.location.y += d.y as f64; + } + GripApply::Absolute(p) => { + v.location.x = p.x as f64; + v.location.y = p.y as f64; + } + } + } + } +} + +impl PropertyEditable for Polyline2D { + fn geometry_properties(&self, _text_style_names: &[String]) -> PropSection { + PropSection { + title: "Geometry".into(), + props: vec![ + ro("Vertices", "vertices", self.vertices.len().to_string()), + edit("Elevation", "pl2_elevation", self.elevation), + Property { + label: "Closed".into(), + field: "pl2_closed", + value: PropValue::BoolToggle { + field: "pl2_closed", + value: self.is_closed(), + }, + }, + ], + } + } + + fn apply_geom_prop(&mut self, field: &str, value: &str) { + match field { + "pl2_closed" => { + let closed = if value == "toggle" { + !self.is_closed() + } else { + value == "true" + }; + if closed { self.close(); } else { self.flags.set_closed(false); } + } + "pl2_elevation" => { + if let Ok(v) = value.trim().parse::() { + self.elevation = v; + } + } + _ => {} + } + } +} + +impl Transformable for Polyline2D { + fn apply_transform(&mut self, t: &EntityTransform) { + crate::scene::transform::apply_standard_entity_transform(self, t, |entity, p1, p2| { + for v in &mut entity.vertices { + crate::scene::transform::reflect_xy_point( + &mut v.location.x, + &mut v.location.y, + p1, + p2, + ); + } + }); + } +} + +// ── Polyline3D ──────────────────────────────────────────────────────────────── + +fn tessellate_polyline3d(pl: &Polyline3D) -> TruckEntity { + let pts: Vec<[f32; 3]> = pl + .vertices + .iter() + .map(|v| [v.position.x as f32, v.position.y as f32, v.position.z as f32]) + .collect(); + + let mut points = pts.clone(); + if pl.is_closed() && pts.len() >= 2 { + points.push(pts[0]); + } + + let key_verts = pts.clone(); + TruckEntity { + object: TruckObject::Lines(points), + snap_pts: vec![], + tangent_geoms: vec![], + key_vertices: key_verts, + } +} + +impl TruckConvertible for Polyline3D { + fn to_truck(&self, _document: &acadrust::CadDocument) -> Option { + Some(tessellate_polyline3d(self)) + } +} + +impl Grippable for Polyline3D { + fn grips(&self) -> Vec { + self.vertices + .iter() + .enumerate() + .map(|(i, v)| { + square_grip( + i, + Vec3::new(v.position.x as f32, v.position.y as f32, v.position.z as f32), + ) + }) + .collect() + } + + fn apply_grip(&mut self, grip_id: usize, apply: GripApply) { + if let Some(v) = self.vertices.get_mut(grip_id) { + match apply { + GripApply::Translate(d) => { + v.position.x += d.x as f64; + v.position.y += d.y as f64; + v.position.z += d.z as f64; + } + GripApply::Absolute(p) => { + v.position.x = p.x as f64; + v.position.y = p.y as f64; + v.position.z = p.z as f64; + } + } + } + } +} + +impl PropertyEditable for Polyline3D { + fn geometry_properties(&self, _text_style_names: &[String]) -> PropSection { + PropSection { + title: "Geometry".into(), + props: vec![ + ro("Vertices", "vertices", self.vertices.len().to_string()), + Property { + label: "Closed".into(), + field: "pl3_closed", + value: PropValue::BoolToggle { + field: "pl3_closed", + value: self.is_closed(), + }, + }, + ], + } + } + + fn apply_geom_prop(&mut self, field: &str, value: &str) { + if field == "pl3_closed" { + let closed = if value == "toggle" { !self.is_closed() } else { value == "true" }; + if closed { self.close(); } else { self.open(); } + } + } +} + +impl Transformable for Polyline3D { + fn apply_transform(&mut self, t: &EntityTransform) { + crate::scene::transform::apply_standard_entity_transform(self, t, |entity, p1, p2| { + for v in &mut entity.vertices { + crate::scene::transform::reflect_xy_point( + &mut v.position.x, + &mut v.position.y, + p1, + p2, + ); + } + }); + } +} diff --git a/src/entities/ray.rs b/src/entities/ray.rs new file mode 100644 index 000000000..a1f6277dc --- /dev/null +++ b/src/entities/ray.rs @@ -0,0 +1,255 @@ +use acadrust::entities::{Ray, XLine}; +use glam::Vec3; + +use crate::command::EntityTransform; +use crate::entities::common::{diamond_grip, edit_prop as edit, square_grip}; +use crate::entities::traits::{Grippable, PropertyEditable, Transformable, TruckConvertible}; +use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; +use crate::scene::object::{GripApply, GripDef, PropSection}; + +/// Display length used when rendering semi-infinite / infinite lines. +const DISPLAY_EXTENT: f64 = 1_000_000.0; + +// ── Ray (semi-infinite line) ────────────────────────────────────────────────── + +impl TruckConvertible for Ray { + fn to_truck(&self, _document: &acadrust::CadDocument) -> Option { + let bp = self.base_point; + let dir = self.direction; + let far = [ + (bp.x + dir.x * DISPLAY_EXTENT) as f32, + (bp.y + dir.y * DISPLAY_EXTENT) as f32, + (bp.z + dir.z * DISPLAY_EXTENT) as f32, + ]; + let start = [bp.x as f32, bp.y as f32, bp.z as f32]; + Some(TruckEntity { + object: TruckObject::Lines(vec![start, far]), + snap_pts: vec![], + tangent_geoms: vec![], + key_vertices: vec![start], + }) + } +} + +impl Grippable for Ray { + fn grips(&self) -> Vec { + let bp = &self.base_point; + let dir = &self.direction; + // Grip 0: base point (movable) + // Grip 1: a point along the direction (changes direction) + let guide_dist = 10.0_f64; + vec![ + square_grip(0, Vec3::new(bp.x as f32, bp.y as f32, bp.z as f32)), + diamond_grip( + 1, + Vec3::new( + (bp.x + dir.x * guide_dist) as f32, + (bp.y + dir.y * guide_dist) as f32, + (bp.z + dir.z * guide_dist) as f32, + ), + ), + ] + } + + fn apply_grip(&mut self, grip_id: usize, apply: GripApply) { + match (grip_id, apply) { + (0, GripApply::Translate(d)) => { + self.base_point.x += d.x as f64; + self.base_point.y += d.y as f64; + self.base_point.z += d.z as f64; + } + (0, GripApply::Absolute(p)) => { + self.base_point.x = p.x as f64; + self.base_point.y = p.y as f64; + self.base_point.z = p.z as f64; + } + (1, GripApply::Absolute(p)) => { + // New direction = grip point - base point, normalized. + let dx = p.x as f64 - self.base_point.x; + let dy = p.y as f64 - self.base_point.y; + let dz = p.z as f64 - self.base_point.z; + let len = (dx * dx + dy * dy + dz * dz).sqrt(); + if len > 1e-9 { + self.direction.x = dx / len; + self.direction.y = dy / len; + self.direction.z = dz / len; + } + } + _ => {} + } + } +} + +impl PropertyEditable for Ray { + fn geometry_properties(&self, _text_style_names: &[String]) -> PropSection { + PropSection { + title: "Geometry".into(), + props: vec![ + edit("Base X", "ray_bx", self.base_point.x), + edit("Base Y", "ray_by", self.base_point.y), + edit("Base Z", "ray_bz", self.base_point.z), + edit("Dir X", "ray_dx", self.direction.x), + edit("Dir Y", "ray_dy", self.direction.y), + edit("Dir Z", "ray_dz", self.direction.z), + ], + } + } + + fn apply_geom_prop(&mut self, field: &str, value: &str) { + let Ok(v) = value.trim().parse::() else { return }; + match field { + "ray_bx" => self.base_point.x = v, + "ray_by" => self.base_point.y = v, + "ray_bz" => self.base_point.z = v, + "ray_dx" => { self.direction.x = v; } + "ray_dy" => { self.direction.y = v; } + "ray_dz" => { self.direction.z = v; } + _ => {} + } + } +} + +impl Transformable for Ray { + fn apply_transform(&mut self, t: &EntityTransform) { + crate::scene::transform::apply_standard_entity_transform(self, t, |entity, p1, p2| { + crate::scene::transform::reflect_xy_point( + &mut entity.base_point.x, + &mut entity.base_point.y, + p1, + p2, + ); + // Mirror the direction: negate the component perpendicular to mirror axis. + let ax = (p2.x - p1.x) as f64; + let ay = (p2.y - p1.y) as f64; + let len2 = ax * ax + ay * ay; + if len2 > 1e-12 { + let d = &mut entity.direction; + let dot = d.x * ax + d.y * ay; + d.x = 2.0 * dot * ax / len2 - d.x; + d.y = 2.0 * dot * ay / len2 - d.y; + } + }); + } +} + +// ── XLine (construction line, infinite) ────────────────────────────────────── + +impl TruckConvertible for XLine { + fn to_truck(&self, _document: &acadrust::CadDocument) -> Option { + let bp = self.base_point; + let dir = self.direction; + let far_pos = [ + (bp.x + dir.x * DISPLAY_EXTENT) as f32, + (bp.y + dir.y * DISPLAY_EXTENT) as f32, + (bp.z + dir.z * DISPLAY_EXTENT) as f32, + ]; + let far_neg = [ + (bp.x - dir.x * DISPLAY_EXTENT) as f32, + (bp.y - dir.y * DISPLAY_EXTENT) as f32, + (bp.z - dir.z * DISPLAY_EXTENT) as f32, + ]; + Some(TruckEntity { + object: TruckObject::Lines(vec![far_neg, far_pos]), + snap_pts: vec![], + tangent_geoms: vec![], + key_vertices: vec![[bp.x as f32, bp.y as f32, bp.z as f32]], + }) + } +} + +impl Grippable for XLine { + fn grips(&self) -> Vec { + let bp = &self.base_point; + let dir = &self.direction; + let guide_dist = 10.0_f64; + vec![ + square_grip(0, Vec3::new(bp.x as f32, bp.y as f32, bp.z as f32)), + diamond_grip( + 1, + Vec3::new( + (bp.x + dir.x * guide_dist) as f32, + (bp.y + dir.y * guide_dist) as f32, + (bp.z + dir.z * guide_dist) as f32, + ), + ), + ] + } + + fn apply_grip(&mut self, grip_id: usize, apply: GripApply) { + match (grip_id, apply) { + (0, GripApply::Translate(d)) => { + self.base_point.x += d.x as f64; + self.base_point.y += d.y as f64; + self.base_point.z += d.z as f64; + } + (0, GripApply::Absolute(p)) => { + self.base_point.x = p.x as f64; + self.base_point.y = p.y as f64; + self.base_point.z = p.z as f64; + } + (1, GripApply::Absolute(p)) => { + let dx = p.x as f64 - self.base_point.x; + let dy = p.y as f64 - self.base_point.y; + let dz = p.z as f64 - self.base_point.z; + let len = (dx * dx + dy * dy + dz * dz).sqrt(); + if len > 1e-9 { + self.direction.x = dx / len; + self.direction.y = dy / len; + self.direction.z = dz / len; + } + } + _ => {} + } + } +} + +impl PropertyEditable for XLine { + fn geometry_properties(&self, _text_style_names: &[String]) -> PropSection { + PropSection { + title: "Geometry".into(), + props: vec![ + edit("Base X", "xl_bx", self.base_point.x), + edit("Base Y", "xl_by", self.base_point.y), + edit("Base Z", "xl_bz", self.base_point.z), + edit("Dir X", "xl_dx", self.direction.x), + edit("Dir Y", "xl_dy", self.direction.y), + edit("Dir Z", "xl_dz", self.direction.z), + ], + } + } + + fn apply_geom_prop(&mut self, field: &str, value: &str) { + let Ok(v) = value.trim().parse::() else { return }; + match field { + "xl_bx" => self.base_point.x = v, + "xl_by" => self.base_point.y = v, + "xl_bz" => self.base_point.z = v, + "xl_dx" => { self.direction.x = v; } + "xl_dy" => { self.direction.y = v; } + "xl_dz" => { self.direction.z = v; } + _ => {} + } + } +} + +impl Transformable for XLine { + fn apply_transform(&mut self, t: &EntityTransform) { + crate::scene::transform::apply_standard_entity_transform(self, t, |entity, p1, p2| { + crate::scene::transform::reflect_xy_point( + &mut entity.base_point.x, + &mut entity.base_point.y, + p1, + p2, + ); + let ax = (p2.x - p1.x) as f64; + let ay = (p2.y - p1.y) as f64; + let len2 = ax * ax + ay * ay; + if len2 > 1e-12 { + let d = &mut entity.direction; + let dot = d.x * ax + d.y * ay; + d.x = 2.0 * dot * ax / len2 - d.x; + d.y = 2.0 * dot * ay / len2 - d.y; + } + }); + } +} diff --git a/src/entities/traits.rs b/src/entities/traits.rs index 00fa94fd7..a201474da 100644 --- a/src/entities/traits.rs +++ b/src/entities/traits.rs @@ -41,6 +41,11 @@ impl EntityTypeOps for EntityType { EntityType::Ellipse(ellipse) => TruckConvertible::to_truck(ellipse, document), EntityType::Spline(spline) => TruckConvertible::to_truck(spline, document), EntityType::LwPolyline(pline) => TruckConvertible::to_truck(pline, document), + EntityType::Polyline(pl) => TruckConvertible::to_truck(pl, document), + EntityType::Polyline2D(pl) => TruckConvertible::to_truck(pl, document), + EntityType::Polyline3D(pl) => TruckConvertible::to_truck(pl, document), + EntityType::Ray(ray) => TruckConvertible::to_truck(ray, document), + EntityType::XLine(xl) => TruckConvertible::to_truck(xl, document), EntityType::Text(text) => TruckConvertible::to_truck(text, document), EntityType::MText(text) => TruckConvertible::to_truck(text, document), EntityType::Leader(leader) => TruckConvertible::to_truck(leader, document), @@ -56,6 +61,11 @@ impl EntityTypeOps for EntityType { EntityType::Arc(arc) => Grippable::grips(arc), EntityType::Ellipse(ellipse) => Grippable::grips(ellipse), EntityType::LwPolyline(pline) => Grippable::grips(pline), + EntityType::Polyline(pl) => Grippable::grips(pl), + EntityType::Polyline2D(pl) => Grippable::grips(pl), + EntityType::Polyline3D(pl) => Grippable::grips(pl), + EntityType::Ray(ray) => Grippable::grips(ray), + EntityType::XLine(xl) => Grippable::grips(xl), EntityType::Point(pt) => Grippable::grips(pt), EntityType::Spline(spline) => Grippable::grips(spline), EntityType::Text(text) => Grippable::grips(text), @@ -89,6 +99,26 @@ impl EntityTypeOps for EntityType { pline, text_style_names, )), + EntityType::Polyline(pl) => Some(PropertyEditable::geometry_properties( + pl, + text_style_names, + )), + EntityType::Polyline2D(pl) => Some(PropertyEditable::geometry_properties( + pl, + text_style_names, + )), + EntityType::Polyline3D(pl) => Some(PropertyEditable::geometry_properties( + pl, + text_style_names, + )), + EntityType::Ray(ray) => Some(PropertyEditable::geometry_properties( + ray, + text_style_names, + )), + EntityType::XLine(xl) => Some(PropertyEditable::geometry_properties( + xl, + text_style_names, + )), EntityType::Hatch(hatch) => Some(PropertyEditable::geometry_properties( hatch, text_style_names, @@ -139,6 +169,11 @@ impl EntityTypeOps for EntityType { PropertyEditable::apply_geom_prop(ellipse, field, value) } EntityType::LwPolyline(pline) => PropertyEditable::apply_geom_prop(pline, field, value), + EntityType::Polyline(pl) => PropertyEditable::apply_geom_prop(pl, field, value), + EntityType::Polyline2D(pl) => PropertyEditable::apply_geom_prop(pl, field, value), + EntityType::Polyline3D(pl) => PropertyEditable::apply_geom_prop(pl, field, value), + EntityType::Ray(ray) => PropertyEditable::apply_geom_prop(ray, field, value), + EntityType::XLine(xl) => PropertyEditable::apply_geom_prop(xl, field, value), EntityType::Hatch(hatch) => PropertyEditable::apply_geom_prop(hatch, field, value), EntityType::Point(pt) => PropertyEditable::apply_geom_prop(pt, field, value), EntityType::Spline(spline) => PropertyEditable::apply_geom_prop(spline, field, value), @@ -160,6 +195,11 @@ impl EntityTypeOps for EntityType { EntityType::Arc(arc) => Grippable::apply_grip(arc, grip_id, apply), EntityType::Ellipse(ellipse) => Grippable::apply_grip(ellipse, grip_id, apply), EntityType::LwPolyline(pline) => Grippable::apply_grip(pline, grip_id, apply), + EntityType::Polyline(pl) => Grippable::apply_grip(pl, grip_id, apply), + EntityType::Polyline2D(pl) => Grippable::apply_grip(pl, grip_id, apply), + EntityType::Polyline3D(pl) => Grippable::apply_grip(pl, grip_id, apply), + EntityType::Ray(ray) => Grippable::apply_grip(ray, grip_id, apply), + EntityType::XLine(xl) => Grippable::apply_grip(xl, grip_id, apply), EntityType::Point(pt) => Grippable::apply_grip(pt, grip_id, apply), EntityType::Spline(spline) => Grippable::apply_grip(spline, grip_id, apply), EntityType::Text(text) => Grippable::apply_grip(text, grip_id, apply), @@ -181,6 +221,11 @@ impl EntityTypeOps for EntityType { EntityType::Insert(ins) => Transformable::apply_transform(ins, t), EntityType::Line(line) => Transformable::apply_transform(line, t), EntityType::LwPolyline(pline) => Transformable::apply_transform(pline, t), + EntityType::Polyline(pl) => Transformable::apply_transform(pl, t), + EntityType::Polyline2D(pl) => Transformable::apply_transform(pl, t), + EntityType::Polyline3D(pl) => Transformable::apply_transform(pl, t), + EntityType::Ray(ray) => Transformable::apply_transform(ray, t), + EntityType::XLine(xl) => Transformable::apply_transform(xl, t), EntityType::MText(text) => Transformable::apply_transform(text, t), EntityType::Point(pt) => Transformable::apply_transform(pt, t), EntityType::Spline(spline) => Transformable::apply_transform(spline, t),