diff --git a/src/entities/arc.rs b/src/entities/arc.rs index b5405b1f3..74afeb614 100644 --- a/src/entities/arc.rs +++ b/src/entities/arc.rs @@ -4,7 +4,7 @@ use truck_modeling::{builder, Point3}; use crate::command::EntityTransform; use crate::entities::common::{diamond_grip, edit_prop as edit, parse_f64, square_grip}; -use crate::entities::traits::{Grippable, PropertyEditable, Transformable, TruckConvertible}; +use crate::entities::traits::TruckConvertible; use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; use crate::scene::object::{GripApply, GripDef, PropSection}; use crate::scene::wire_model::{SnapHint, TangentGeom}; @@ -219,31 +219,7 @@ impl TruckConvertible for Arc { } } -impl Grippable for Arc { - fn grips(&self) -> Vec { - grips(self) - } - - fn apply_grip(&mut self, grip_id: usize, apply: GripApply) { - apply_grip(self, grip_id, apply); - } -} - -impl PropertyEditable for Arc { - fn geometry_properties(&self, _text_style_names: &[String]) -> PropSection { - properties(self) - } - - fn apply_geom_prop(&mut self, field: &str, value: &str) { - apply_geom_prop(self, field, value); - } -} - -impl Transformable for Arc { - fn apply_transform(&mut self, t: &EntityTransform) { - apply_transform(self, t); - } -} +crate::impl_entity_basics!(Arc); impl crate::entities::traits::MassPropsCalc for acadrust::entities::Arc { fn mass_props(&self) -> crate::entities::traits::MassProps { diff --git a/src/entities/circle.rs b/src/entities/circle.rs index ec2a21045..52d6e884d 100644 --- a/src/entities/circle.rs +++ b/src/entities/circle.rs @@ -6,7 +6,7 @@ use crate::command::EntityTransform; use crate::entities::common::{ diamond_grip, edit_prop as edit, parse_f64, ro_prop as ro, square_grip, }; -use crate::entities::traits::{Grippable, PropertyEditable, Transformable, TruckConvertible}; +use crate::entities::traits::TruckConvertible; use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; use crate::scene::object::{GripApply, GripDef, PropSection}; use crate::scene::wire_model::{SnapHint, TangentGeom}; @@ -202,31 +202,7 @@ impl TruckConvertible for Circle { } } -impl Grippable for Circle { - fn grips(&self) -> Vec { - grips(self) - } - - fn apply_grip(&mut self, grip_id: usize, apply: GripApply) { - apply_grip(self, grip_id, apply); - } -} - -impl PropertyEditable for Circle { - fn geometry_properties(&self, _text_style_names: &[String]) -> PropSection { - properties(self) - } - - fn apply_geom_prop(&mut self, field: &str, value: &str) { - apply_geom_prop(self, field, value); - } -} - -impl Transformable for Circle { - fn apply_transform(&mut self, t: &EntityTransform) { - apply_transform(self, t); - } -} +crate::impl_entity_basics!(Circle); impl crate::entities::traits::MassPropsCalc for Circle { fn mass_props(&self) -> crate::entities::traits::MassProps { diff --git a/src/entities/ellipse.rs b/src/entities/ellipse.rs index d78b8c4df..5c1c938dc 100644 --- a/src/entities/ellipse.rs +++ b/src/entities/ellipse.rs @@ -4,7 +4,7 @@ use truck_modeling::{builder, BSplineCurve, Curve, Edge, KnotVec, Point3, Wire}; use crate::command::EntityTransform; use crate::entities::common::{diamond_grip, edit_prop as edit, ro_prop as ro, square_grip}; -use crate::entities::traits::{Grippable, PropertyEditable, Transformable, TruckConvertible}; +use crate::entities::traits::TruckConvertible; use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; use crate::scene::object::{GripApply, GripDef, PropSection}; use crate::scene::wire_model::SnapHint; @@ -251,31 +251,7 @@ impl TruckConvertible for Ellipse { } } -impl Grippable for Ellipse { - fn grips(&self) -> Vec { - grips(self) - } - - fn apply_grip(&mut self, grip_id: usize, apply: GripApply) { - apply_grip(self, grip_id, apply); - } -} - -impl PropertyEditable for Ellipse { - fn geometry_properties(&self, _text_style_names: &[String]) -> PropSection { - properties(self) - } - - fn apply_geom_prop(&mut self, field: &str, value: &str) { - apply_geom_prop(self, field, value); - } -} - -impl Transformable for Ellipse { - fn apply_transform(&mut self, t: &EntityTransform) { - apply_transform(self, t); - } -} +crate::impl_entity_basics!(Ellipse); impl crate::entities::traits::MassPropsCalc for acadrust::entities::Ellipse { fn mass_props(&self) -> crate::entities::traits::MassProps { diff --git a/src/entities/insert.rs b/src/entities/insert.rs index 96ea1a720..df2a211a3 100644 --- a/src/entities/insert.rs +++ b/src/entities/insert.rs @@ -5,7 +5,7 @@ use glam::Vec3; use crate::command::EntityTransform; use crate::entities::common::{edit_prop as edit, parse_f64, ro_prop as ro, square_grip}; -use crate::entities::traits::{Grippable, PropertyEditable, Transformable}; + use crate::scene::object::{GripApply, GripDef, PropSection}; use crate::scene::{block_cache, render, tessellate}; use crate::scene::wire_model::WireModel; @@ -96,31 +96,7 @@ fn apply_transform(ins: &mut Insert, t: &EntityTransform) { }); } -impl Grippable for Insert { - fn grips(&self) -> Vec { - grips(self) - } - - fn apply_grip(&mut self, grip_id: usize, apply: GripApply) { - apply_grip(self, grip_id, apply); - } -} - -impl PropertyEditable for Insert { - fn geometry_properties(&self, _text_style_names: &[String]) -> PropSection { - properties(self) - } - - fn apply_geom_prop(&mut self, field: &str, value: &str) { - apply_geom_prop(self, field, value); - } -} - -impl Transformable for Insert { - fn apply_transform(&mut self, t: &EntityTransform) { - apply_transform(self, t); - } -} +crate::impl_entity_basics!(Insert); impl crate::entities::traits::FallbackTess for Insert { fn fallback_geometry(&self, world_offset: [f64; 3]) -> crate::scene::tess_util::FallbackGeometry { diff --git a/src/entities/leader.rs b/src/entities/leader.rs index ac42d73ff..125161659 100644 --- a/src/entities/leader.rs +++ b/src/entities/leader.rs @@ -4,7 +4,7 @@ use glam::Vec3; use crate::command::EntityTransform; use crate::entities::common::{diamond_grip, edit_prop as edit, ro_prop as ro, square_grip}; -use crate::entities::traits::{Grippable, PropertyEditable, Transformable, TruckConvertible}; +use crate::entities::traits::{TruckConvertible}; use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; use crate::scene::object::{GripApply, GripDef, PropSection, PropValue, Property}; use crate::scene::wire_model::TangentGeom; @@ -455,31 +455,7 @@ impl TruckConvertible for Leader { } } -impl Grippable for Leader { - fn grips(&self) -> Vec { - grips(self) - } - - fn apply_grip(&mut self, grip_id: usize, apply: GripApply) { - apply_grip(self, grip_id, apply); - } -} - -impl PropertyEditable for Leader { - fn geometry_properties(&self, _text_style_names: &[String]) -> PropSection { - properties(self) - } - - fn apply_geom_prop(&mut self, field: &str, value: &str) { - apply_geom_prop(self, field, value); - } -} - -impl Transformable for Leader { - fn apply_transform(&mut self, t: &EntityTransform) { - apply_transform(self, t); - } -} +crate::impl_entity_basics!(Leader); /// Per-entity tessellation entry for `Leader`. Lives here so all leader /// tess code stays alongside the entity definition. Cross-entity dim diff --git a/src/entities/line.rs b/src/entities/line.rs index 5dfe7631f..d522126cc 100644 --- a/src/entities/line.rs +++ b/src/entities/line.rs @@ -6,7 +6,7 @@ use crate::command::EntityTransform; use crate::entities::common::{ diamond_grip, edit_prop as edit, parse_f64, ro_prop as ro, square_grip, }; -use crate::entities::traits::{Grippable, PropertyEditable, Transformable, TruckConvertible}; +use crate::entities::traits::TruckConvertible; use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; use crate::scene::object::{GripApply, GripDef, PropSection}; use crate::scene::wire_model::TangentGeom; @@ -156,31 +156,7 @@ impl TruckConvertible for Line { } } -impl Grippable for Line { - fn grips(&self) -> Vec { - grips(self) - } - - fn apply_grip(&mut self, grip_id: usize, apply: GripApply) { - apply_grip(self, grip_id, apply); - } -} - -impl PropertyEditable for Line { - fn geometry_properties(&self, _text_style_names: &[String]) -> PropSection { - properties(self) - } - - fn apply_geom_prop(&mut self, field: &str, value: &str) { - apply_geom_prop(self, field, value); - } -} - -impl Transformable for Line { - fn apply_transform(&mut self, t: &EntityTransform) { - apply_transform(self, t); - } -} +crate::impl_entity_basics!(Line); impl crate::entities::traits::MassPropsCalc for acadrust::entities::Line { fn mass_props(&self) -> crate::entities::traits::MassProps { diff --git a/src/entities/lwpolyline.rs b/src/entities/lwpolyline.rs index 0e7ee2015..c96d58349 100644 --- a/src/entities/lwpolyline.rs +++ b/src/entities/lwpolyline.rs @@ -6,7 +6,7 @@ use crate::command::EntityTransform; use crate::entities::common::{ diamond_grip, edit_prop as edit, parse_f64, ro_prop as ro, square_grip, }; -use crate::entities::traits::{Grippable, PropertyEditable, Transformable, TruckConvertible}; +use crate::entities::traits::{TruckConvertible}; use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; use crate::scene::object::{GripApply, GripDef, PropSection}; use crate::scene::wire_model::TangentGeom; @@ -406,31 +406,8 @@ impl TruckConvertible for LwPolyline { } } -impl Grippable for LwPolyline { - fn grips(&self) -> Vec { - grips(self) - } +crate::impl_entity_basics!(LwPolyline); - fn apply_grip(&mut self, grip_id: usize, apply: GripApply) { - apply_grip(self, grip_id, apply); - } -} - -impl PropertyEditable for LwPolyline { - fn geometry_properties(&self, _text_style_names: &[String]) -> PropSection { - properties(self) - } - - fn apply_geom_prop(&mut self, field: &str, value: &str) { - apply_geom_prop(self, field, value); - } -} - -impl Transformable for LwPolyline { - fn apply_transform(&mut self, t: &EntityTransform) { - apply_transform(self, t); - } -} pub(crate) fn wide_fills(pl: &acadrust::entities::LwPolyline) -> Vec> { let hw_const = (pl.constant_width / 2.0) as f32; let verts = &pl.vertices; diff --git a/src/entities/multileader.rs b/src/entities/multileader.rs index 777bd9c1a..3b9e272ff 100644 --- a/src/entities/multileader.rs +++ b/src/entities/multileader.rs @@ -30,7 +30,7 @@ use glam::Vec3; use crate::command::EntityTransform; use crate::entities::common::{diamond_grip, edit_prop as edit, ro_prop as ro, square_grip}; -use crate::entities::traits::{Grippable, PropertyEditable, Transformable, TruckConvertible}; +use crate::entities::traits::{TruckConvertible}; use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; use crate::scene::object::{GripApply, GripDef, PropSection, PropValue, Property}; use crate::scene::wire_model::{SnapHint, TangentGeom}; @@ -827,29 +827,7 @@ impl TruckConvertible for MultiLeader { } } -impl Grippable for MultiLeader { - fn grips(&self) -> Vec { - grips(self) - } - fn apply_grip(&mut self, grip_id: usize, apply: GripApply) { - apply_grip(self, grip_id, apply); - } -} - -impl PropertyEditable for MultiLeader { - fn geometry_properties(&self, _text_style_names: &[String]) -> PropSection { - properties(self) - } - fn apply_geom_prop(&mut self, field: &str, value: &str) { - apply_geom_prop(self, field, value); - } -} - -impl Transformable for MultiLeader { - fn apply_transform(&mut self, t: &EntityTransform) { - apply_transform(self, t); - } -} +crate::impl_entity_basics!(MultiLeader); /// Per-entity tessellation entry for `MultiLeader`. Returns multiple /// `WireModel`s (leader/dogleg + arrow fill, optional block content, diff --git a/src/entities/ole2frame.rs b/src/entities/ole2frame.rs index 52a60966f..2bb427160 100644 --- a/src/entities/ole2frame.rs +++ b/src/entities/ole2frame.rs @@ -3,7 +3,7 @@ use glam::Vec3; use crate::command::EntityTransform; use crate::entities::common::{diamond_grip, edit_prop as edit, ro_prop as ro, square_grip}; -use crate::entities::traits::{Grippable, PropertyEditable, Transformable, TruckConvertible}; +use crate::entities::traits::{TruckConvertible}; use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; use crate::scene::object::{GripApply, GripDef, PropSection}; use crate::scene::wire_model::SnapHint; @@ -178,29 +178,7 @@ impl TruckConvertible for Ole2Frame { } } -impl Grippable for Ole2Frame { - fn grips(&self) -> Vec { - grips(self) - } - fn apply_grip(&mut self, grip_id: usize, apply: GripApply) { - apply_grip(self, grip_id, apply); - } -} - -impl PropertyEditable for Ole2Frame { - fn geometry_properties(&self, _text_style_names: &[String]) -> PropSection { - properties(self) - } - fn apply_geom_prop(&mut self, field: &str, value: &str) { - apply_geom_prop(self, field, value); - } -} - -impl Transformable for Ole2Frame { - fn apply_transform(&mut self, t: &EntityTransform) { - apply_transform(self, t); - } -} +crate::impl_entity_basics!(Ole2Frame); impl crate::entities::traits::FallbackTess for Ole2Frame { fn fallback_geometry(&self, world_offset: [f64; 3]) -> crate::scene::tess_util::FallbackGeometry { diff --git a/src/entities/point.rs b/src/entities/point.rs index 71116c4b3..b29b63cf4 100644 --- a/src/entities/point.rs +++ b/src/entities/point.rs @@ -4,7 +4,7 @@ use truck_modeling::{builder, Point3}; use crate::command::EntityTransform; use crate::entities::common::{edit_prop as edit, parse_f64, square_grip}; -use crate::entities::traits::{Grippable, PropertyEditable, Transformable, TruckConvertible}; +use crate::entities::traits::TruckConvertible; use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; use crate::scene::object::{GripApply, GripDef, PropSection}; use crate::scene::wire_model::SnapHint; @@ -195,28 +195,5 @@ impl TruckConvertible for Point { } } -impl Grippable for Point { - fn grips(&self) -> Vec { - grips(self) - } +crate::impl_entity_basics!(Point); - fn apply_grip(&mut self, grip_id: usize, apply: GripApply) { - apply_grip(self, grip_id, apply); - } -} - -impl PropertyEditable for Point { - fn geometry_properties(&self, _text_style_names: &[String]) -> PropSection { - properties(self) - } - - fn apply_geom_prop(&mut self, field: &str, value: &str) { - apply_geom_prop(self, field, value); - } -} - -impl Transformable for Point { - fn apply_transform(&mut self, t: &EntityTransform) { - apply_transform(self, t); - } -} diff --git a/src/entities/spline.rs b/src/entities/spline.rs index f41eccfa3..7a2e1a52c 100644 --- a/src/entities/spline.rs +++ b/src/entities/spline.rs @@ -7,7 +7,7 @@ use truck_modeling::{ use crate::command::EntityTransform; use crate::entities::common::{ro_prop as ro, square_grip}; -use crate::entities::traits::{Grippable, PropertyEditable, Transformable, TruckConvertible}; +use crate::entities::traits::TruckConvertible; use crate::scene::acad_to_truck::{TruckEntity, TruckObject}; use crate::scene::object::{GripApply, GripDef, PropSection}; @@ -161,28 +161,5 @@ impl TruckConvertible for Spline { } } -impl Grippable for Spline { - fn grips(&self) -> Vec { - grips(self) - } +crate::impl_entity_basics!(Spline); - fn apply_grip(&mut self, grip_id: usize, apply: GripApply) { - apply_grip(self, grip_id, apply); - } -} - -impl PropertyEditable for Spline { - fn geometry_properties(&self, _text_style_names: &[String]) -> PropSection { - properties(self) - } - - fn apply_geom_prop(&mut self, field: &str, value: &str) { - apply_geom_prop(self, field, value); - } -} - -impl Transformable for Spline { - fn apply_transform(&mut self, t: &EntityTransform) { - apply_transform(self, t); - } -} diff --git a/src/entities/traits.rs b/src/entities/traits.rs index c19179807..c05f1aae6 100644 --- a/src/entities/traits.rs +++ b/src/entities/traits.rs @@ -81,6 +81,83 @@ macro_rules! dispatch { }; } +/// Generates `Grippable`, `PropertyEditable`, `Transformable` trait impls +/// that delegate to identically-named free functions in the entity's own +/// module (`grips`, `apply_grip`, `properties`, `apply_geom_prop`, +/// `apply_transform`). `properties()` is called with `self` only — for +/// text-like entities that need the document's text-style list use +/// [`impl_entity_basics_with_text_styles!`] instead. +#[macro_export] +macro_rules! impl_entity_basics { + ($T:ty) => { + impl $crate::entities::traits::Grippable for $T { + fn grips(&self) -> Vec<$crate::scene::object::GripDef> { + grips(self) + } + fn apply_grip( + &mut self, + grip_id: usize, + apply: $crate::scene::object::GripApply, + ) { + apply_grip(self, grip_id, apply); + } + } + impl $crate::entities::traits::PropertyEditable for $T { + fn geometry_properties( + &self, + _text_style_names: &[String], + ) -> $crate::scene::object::PropSection { + properties(self) + } + fn apply_geom_prop(&mut self, field: &str, value: &str) { + apply_geom_prop(self, field, value); + } + } + impl $crate::entities::traits::Transformable for $T { + fn apply_transform(&mut self, t: &$crate::command::EntityTransform) { + apply_transform(self, t); + } + } + }; +} + +/// Same as [`impl_entity_basics!`] but the entity's `properties(...)` free +/// function takes the document's text-style name list as a second +/// argument (Text, MText, …). +#[macro_export] +macro_rules! impl_entity_basics_with_text_styles { + ($T:ty) => { + impl $crate::entities::traits::Grippable for $T { + fn grips(&self) -> Vec<$crate::scene::object::GripDef> { + grips(self) + } + fn apply_grip( + &mut self, + grip_id: usize, + apply: $crate::scene::object::GripApply, + ) { + apply_grip(self, grip_id, apply); + } + } + impl $crate::entities::traits::PropertyEditable for $T { + fn geometry_properties( + &self, + text_style_names: &[String], + ) -> $crate::scene::object::PropSection { + properties(self, text_style_names) + } + fn apply_geom_prop(&mut self, field: &str, value: &str) { + apply_geom_prop(self, field, value); + } + } + impl $crate::entities::traits::Transformable for $T { + fn apply_transform(&mut self, t: &$crate::command::EntityTransform) { + apply_transform(self, t); + } + } + }; +} + impl EntityTypeOps for EntityType { fn to_truck_entity(&self, document: &CadDocument) -> Option { dispatch!(self, diff --git a/src/entities/viewport.rs b/src/entities/viewport.rs index deca61c47..186509e8c 100644 --- a/src/entities/viewport.rs +++ b/src/entities/viewport.rs @@ -5,7 +5,7 @@ use crate::command::EntityTransform; use crate::entities::common::{ diamond_grip, edit_prop as edit, parse_f64, ro_prop as ro, square_grip, }; -use crate::entities::traits::{Grippable, PropertyEditable, Transformable}; + use crate::scene::object::{GripApply, GripDef, PropSection, PropValue, Property}; // ── Standard scale options ──────────────────────────────────────────────── @@ -541,31 +541,7 @@ fn apply_transform(vp: &mut Viewport, t: &EntityTransform) { }); } -impl Grippable for Viewport { - fn grips(&self) -> Vec { - grips(self) - } - - fn apply_grip(&mut self, grip_id: usize, apply: GripApply) { - apply_grip(self, grip_id, apply); - } -} - -impl PropertyEditable for Viewport { - fn geometry_properties(&self, _text_style_names: &[String]) -> PropSection { - properties(self) - } - - fn apply_geom_prop(&mut self, field: &str, value: &str) { - apply_geom_prop(self, field, value); - } -} - -impl Transformable for Viewport { - fn apply_transform(&mut self, t: &EntityTransform) { - apply_transform(self, t); - } -} +crate::impl_entity_basics!(Viewport); impl crate::entities::traits::FallbackTess for Viewport { fn fallback_geometry(&self, world_offset: [f64; 3]) -> crate::scene::tess_util::FallbackGeometry {