cargo fmt

This commit is contained in:
Hakan committed 2026-05-12 10:36:15 +03:00
1 parent 468cbde5e1
commit ca07268c7c
204 files changed
+13997 -5525

No files matched your search

+25 -20
View File
@@ -37,13 +37,15 @@ impl AlignedDimensionCommand {
}
impl CadCommand for AlignedDimensionCommand {
fn name(&self) -> &'static str { "DIMALIGNED" }
fn name(&self) -> &'static str {
"DIMALIGNED"
}
fn prompt(&self) -> String {
match self.step {
Step::First => "DIMALIGNED Specify first extension line origin:".into(),
Step::Second(_) => "DIMALIGNED Specify second extension line origin:".into(),
Step::DimLine { .. } => "DIMALIGNED Specify dimension line location:".into(),
Step::First => "DIMALIGNED Specify first extension line origin:".into(),
Step::Second(_) => "DIMALIGNED Specify second extension line origin:".into(),
Step::DimLine { .. } => "DIMALIGNED Specify dimension line location:".into(),
}
}
@@ -65,13 +67,11 @@ impl CadCommand for AlignedDimensionCommand {
let offset = (dx * dx + dy * dy).sqrt();
dim.set_offset(offset);
dim.base.definition_point = v3(pt);
dim.base.text_middle_point = v3(
Vec3::new(
(p1.x + p2.x) * 0.5,
(p1.y + p2.y) * 0.5,
(p1.z + p2.z) * 0.5,
)
);
dim.base.text_middle_point = v3(Vec3::new(
(p1.x + p2.x) * 0.5,
(p1.y + p2.y) * 0.5,
(p1.z + p2.z) * 0.5,
));
dim.base.insertion_point = dim.base.text_middle_point;
dim.base.actual_measurement = dim.measurement();
CmdResult::CommitAndExit(EntityType::Dimension(Dimension::Aligned(dim)))
@@ -79,7 +79,9 @@ impl CadCommand for AlignedDimensionCommand {
}
}
fn on_enter(&mut self) -> CmdResult { CmdResult::Cancel }
fn on_enter(&mut self) -> CmdResult {
CmdResult::Cancel
}
fn on_mouse_move(&mut self, pt: Vec3) -> Option<WireModel> {
let (p1, p2) = match self.step {
@@ -123,11 +125,14 @@ fn preview_aligned(p1: Vec3, p2: Vec3, dim_pt: Vec3) -> WireModel {
WireModel {
name: "dimaligned_preview".into(),
points: vec![
[p1.x, p1.y, p1.z], [d1.x, d1.y, d1.z],
[p1.x, p1.y, p1.z],
[d1.x, d1.y, d1.z],
[f32::NAN, 0.0, 0.0],
[p2.x, p2.y, p2.z], [d2.x, d2.y, d2.z],
[p2.x, p2.y, p2.z],
[d2.x, d2.y, d2.z],
[f32::NAN, 0.0, 0.0],
[d1.x, d1.y, d1.z], [d2.x, d2.y, d2.z],
[d1.x, d1.y, d1.z],
[d2.x, d2.y, d2.z],
],
color: WireModel::CYAN,
selected: false,
@@ -137,10 +142,10 @@ fn preview_aligned(p1: Vec3, p2: Vec3, dim_pt: Vec3) -> WireModel {
snap_pts: vec![],
tangent_geoms: vec![],
aci: 0,
key_vertices: vec![],
aabb: WireModel::UNBOUNDED_AABB,
plinegen: true,
vp_scissor: None,
fill_tris: vec![],
key_vertices: vec![],
aabb: WireModel::UNBOUNDED_AABB,
plinegen: true,
vp_scissor: None,
fill_tris: vec![],
}
}
+21 -10
View File
@@ -21,8 +21,15 @@ pub fn tool() -> ToolDef {
enum Step {
Vertex,
FirstRay(Vec3),
SecondRay { vertex: Vec3, first: Vec3 },
ArcPoint { vertex: Vec3, first: Vec3, second: Vec3 },
SecondRay {
vertex: Vec3,
first: Vec3,
},
ArcPoint {
vertex: Vec3,
first: Vec3,
second: Vec3,
},
}
pub struct AngularDimensionCommand {
@@ -95,9 +102,13 @@ impl CadCommand for AngularDimensionCommand {
match self.step {
Step::Vertex => None,
Step::FirstRay(vertex) => Some(preview_wire(vec![vertex, pt])),
Step::SecondRay { vertex, first } => {
Some(preview_wire(vec![vertex, first, Vec3::new(f32::NAN, f32::NAN, f32::NAN), vertex, pt]))
}
Step::SecondRay { vertex, first } => Some(preview_wire(vec![
vertex,
first,
Vec3::new(f32::NAN, f32::NAN, f32::NAN),
vertex,
pt,
])),
Step::ArcPoint {
vertex,
first,
@@ -123,11 +134,11 @@ fn preview_wire(points: Vec<Vec3>) -> WireModel {
snap_pts: vec![],
tangent_geoms: vec![],
aci: 0,
key_vertices: vec![],
aabb: WireModel::UNBOUNDED_AABB,
plinegen: true,
vp_scissor: None,
fill_tris: vec![],
key_vertices: vec![],
aabb: WireModel::UNBOUNDED_AABB,
plinegen: true,
vp_scissor: None,
fill_tris: vec![],
}
}
+32 -12
View File
@@ -32,17 +32,23 @@ pub struct DdeditCommand {
impl DdeditCommand {
pub fn new() -> Self {
Self { step: DdeditStep::PickEntity }
Self {
step: DdeditStep::PickEntity,
}
}
/// Start with a pre-picked entity (for double-click use).
pub fn with_handle(handle: Handle, current: String) -> Self {
Self { step: DdeditStep::EnterText { handle, current } }
Self {
step: DdeditStep::EnterText { handle, current },
}
}
}
impl CadCommand for DdeditCommand {
fn name(&self) -> &'static str { "DDEDIT" }
fn name(&self) -> &'static str {
"DDEDIT"
}
fn prompt(&self) -> String {
match &self.step {
@@ -58,10 +64,15 @@ impl CadCommand for DdeditCommand {
}
fn on_entity_pick(&mut self, handle: Handle, _pt: Vec3) -> CmdResult {
if handle.is_null() { return CmdResult::NeedPoint; }
if handle.is_null() {
return CmdResult::NeedPoint;
}
// The current value will be filled in by the caller (commands.rs dispatch)
// via on_text_input once the entity is known. Store handle here.
self.step = DdeditStep::EnterText { handle, current: String::new() };
self.step = DdeditStep::EnterText {
handle,
current: String::new(),
};
CmdResult::NeedPoint
}
@@ -75,23 +86,32 @@ impl CadCommand for DdeditCommand {
_ => return None,
};
// Empty input → keep existing text
let new_text = if text.trim().is_empty() { current } else { text.to_string() };
let new_text = if text.trim().is_empty() {
current
} else {
text.to_string()
};
Some(CmdResult::DdeditEntity { handle, new_text })
}
fn on_point(&mut self, _pt: Vec3) -> CmdResult { CmdResult::NeedPoint }
fn on_enter(&mut self) -> CmdResult { CmdResult::Cancel }
fn on_escape(&mut self) -> CmdResult { CmdResult::Cancel }
fn on_point(&mut self, _pt: Vec3) -> CmdResult {
CmdResult::NeedPoint
}
fn on_enter(&mut self) -> CmdResult {
CmdResult::Cancel
}
fn on_escape(&mut self) -> CmdResult {
CmdResult::Cancel
}
}
/// Extract the text content from a Text or MText entity.
pub fn entity_text(entity: &EntityType) -> Option<String> {
match entity {
EntityType::Text(t) => Some(t.value.clone()),
EntityType::Text(t) => Some(t.value.clone()),
EntityType::MText(t) => Some(t.value.clone()),
EntityType::AttributeDefinition(a) => Some(a.default_value.clone()),
EntityType::AttributeEntity(a) => Some(a.get_value().to_string()),
EntityType::AttributeEntity(a) => Some(a.get_value().to_string()),
_ => None,
}
}
+19 -13
View File
@@ -32,18 +32,22 @@ pub struct DiameterDimensionCommand {
impl DiameterDimensionCommand {
pub fn new() -> Self {
Self { step: Step::CenterPoint }
Self {
step: Step::CenterPoint,
}
}
}
impl CadCommand for DiameterDimensionCommand {
fn name(&self) -> &'static str { "DIMDIAMETER" }
fn name(&self) -> &'static str {
"DIMDIAMETER"
}
fn prompt(&self) -> String {
match self.step {
Step::CenterPoint => "DIMDIAMETER Specify center point:".into(),
Step::ArcPoint(_) => "DIMDIAMETER Specify point on circle:".into(),
Step::TextPoint {..} => "DIMDIAMETER Specify dimension line location:".into(),
Step::CenterPoint => "DIMDIAMETER Specify center point:".into(),
Step::ArcPoint(_) => "DIMDIAMETER Specify point on circle:".into(),
Step::TextPoint { .. } => "DIMDIAMETER Specify dimension line location:".into(),
}
}
@@ -59,9 +63,9 @@ impl CadCommand for DiameterDimensionCommand {
}
Step::TextPoint { center, arc_pt } => {
let mut dim = DimensionDiameter::new(v3(center), v3(arc_pt));
dim.base.definition_point = v3(arc_pt);
dim.base.definition_point = v3(arc_pt);
dim.base.text_middle_point = v3(pt);
dim.base.insertion_point = v3(pt);
dim.base.insertion_point = v3(pt);
dim.leader_length = arc_pt.distance(pt) as f64;
dim.base.actual_measurement = dim.measurement();
CmdResult::CommitAndExit(EntityType::Dimension(Dimension::Diameter(dim)))
@@ -69,7 +73,9 @@ impl CadCommand for DiameterDimensionCommand {
}
}
fn on_enter(&mut self) -> CmdResult { CmdResult::Cancel }
fn on_enter(&mut self) -> CmdResult {
CmdResult::Cancel
}
fn on_mouse_move(&mut self, pt: Vec3) -> Option<WireModel> {
match self.step {
@@ -99,10 +105,10 @@ fn preview_line(a: Vec3, b: Vec3) -> WireModel {
snap_pts: vec![],
tangent_geoms: vec![],
aci: 0,
key_vertices: vec![],
aabb: WireModel::UNBOUNDED_AABB,
plinegen: true,
vp_scissor: None,
fill_tris: vec![],
key_vertices: vec![],
aabb: WireModel::UNBOUNDED_AABB,
plinegen: true,
vp_scissor: None,
fill_tris: vec![],
}
}
+12 -4
View File
@@ -61,7 +61,11 @@ impl DimBaselineCommand {
/// `definition_point` — dim-line position of the base dim (defines perpendicular side).
/// `rotation` — 0.0 = horizontal, PI/2 = vertical.
pub fn from_base(p1: Vec3, _p2: Vec3, definition_point: Vec3, rotation: f64) -> Self {
let axis = if rotation.abs() < 0.1 { Vec3::X } else { Vec3::Y };
let axis = if rotation.abs() < 0.1 {
Vec3::X
} else {
Vec3::Y
};
let perp = Vec3::new(-axis.y, axis.x, 0.0);
let base_offset = (definition_point - p1).dot(perp);
// Next baseline dim goes one DIMDLI further from the baseline.
@@ -77,7 +81,9 @@ impl DimBaselineCommand {
}
impl CadCommand for DimBaselineCommand {
fn name(&self) -> &'static str { "DIMBASELINE" }
fn name(&self) -> &'static str {
"DIMBASELINE"
}
fn prompt(&self) -> String {
if !self.ready {
@@ -126,9 +132,11 @@ impl CadCommand for DimBaselineCommand {
Some(WireModel {
name: "dimbase_preview".into(),
points: vec![
[p1.x, p1.y, p1.z], [dim_line_pt.x, dim_line_pt.y, dim_line_pt.z],
[p1.x, p1.y, p1.z],
[dim_line_pt.x, dim_line_pt.y, dim_line_pt.z],
[f32::NAN, 0.0, 0.0],
[pt.x, pt.y, pt.z], [dim_line_pt2.x, dim_line_pt2.y, dim_line_pt2.z],
[pt.x, pt.y, pt.z],
[dim_line_pt2.x, dim_line_pt2.y, dim_line_pt2.z],
[f32::NAN, 0.0, 0.0],
[dim_line_pt.x, dim_line_pt.y, dim_line_pt.z],
[dim_line_pt2.x, dim_line_pt2.y, dim_line_pt2.z],
+12 -4
View File
@@ -59,7 +59,11 @@ impl DimContinueCommand {
/// `rotation` — 0.0 = horizontal dim, PI/2 = vertical dim.
pub fn from_base(p1: Vec3, p2: Vec3, definition_point: Vec3, rotation: f64) -> Self {
// Axis unit vector along the measurement direction.
let axis = if rotation.abs() < 0.1 { Vec3::X } else { Vec3::Y };
let axis = if rotation.abs() < 0.1 {
Vec3::X
} else {
Vec3::Y
};
// Perpendicular unit vector toward the dim line.
let perp = Vec3::new(-axis.y, axis.x, 0.0);
let dim_offset = (definition_point - p1).dot(perp);
@@ -74,7 +78,9 @@ impl DimContinueCommand {
}
impl CadCommand for DimContinueCommand {
fn name(&self) -> &'static str { "DIMCONTINUE" }
fn name(&self) -> &'static str {
"DIMCONTINUE"
}
fn prompt(&self) -> String {
if !self.ready {
@@ -123,9 +129,11 @@ impl CadCommand for DimContinueCommand {
Some(WireModel {
name: "dimcont_preview".into(),
points: vec![
[p1.x, p1.y, p1.z], [dim_line_pt.x, dim_line_pt.y, dim_line_pt.z],
[p1.x, p1.y, p1.z],
[dim_line_pt.x, dim_line_pt.y, dim_line_pt.z],
[f32::NAN, 0.0, 0.0],
[pt.x, pt.y, pt.z], [dim_line_pt2.x, dim_line_pt2.y, dim_line_pt2.z],
[pt.x, pt.y, pt.z],
[dim_line_pt2.x, dim_line_pt2.y, dim_line_pt2.z],
[f32::NAN, 0.0, 0.0],
[dim_line_pt.x, dim_line_pt.y, dim_line_pt.z],
[dim_line_pt2.x, dim_line_pt2.y, dim_line_pt2.z],
+18 -6
View File
@@ -37,24 +37,34 @@ pub struct DimBreakCommand {
impl DimBreakCommand {
pub fn new() -> Self {
Self { step: Step::PickDim }
Self {
step: Step::PickDim,
}
}
}
impl CadCommand for DimBreakCommand {
fn name(&self) -> &'static str { "DIMBREAK" }
fn name(&self) -> &'static str {
"DIMBREAK"
}
fn prompt(&self) -> String {
match &self.step {
Step::PickDim => "DIMBREAK Select dimension to break:".into(),
Step::PickCrossing { .. } => "DIMBREAK Select object to break at, or Enter for Auto:".into(),
Step::PickCrossing { .. } => {
"DIMBREAK Select object to break at, or Enter for Auto:".into()
}
}
}
fn needs_entity_pick(&self) -> bool { true }
fn needs_entity_pick(&self) -> bool {
true
}
fn on_entity_pick(&mut self, handle: Handle, _pt: Vec3) -> CmdResult {
if handle.is_null() { return CmdResult::NeedPoint; }
if handle.is_null() {
return CmdResult::NeedPoint;
}
match &self.step {
Step::PickDim => {
self.step = Step::PickCrossing { dim_handle: handle };
@@ -71,7 +81,9 @@ impl CadCommand for DimBreakCommand {
}
}
fn on_point(&mut self, _pt: Vec3) -> CmdResult { CmdResult::NeedPoint }
fn on_point(&mut self, _pt: Vec3) -> CmdResult {
CmdResult::NeedPoint
}
fn on_enter(&mut self) -> CmdResult {
// Auto mode: apply to all crossings
+18 -6
View File
@@ -32,17 +32,23 @@ pub struct DimEditCommand {
impl DimEditCommand {
pub fn new() -> Self {
Self { step: Step::PickDim }
Self {
step: Step::PickDim,
}
}
}
impl CadCommand for DimEditCommand {
fn name(&self) -> &'static str { "DIMEDIT" }
fn name(&self) -> &'static str {
"DIMEDIT"
}
fn prompt(&self) -> String {
match &self.step {
Step::PickDim => "DIMEDIT Select dimension:".into(),
Step::EnterText { .. } => "DIMEDIT Enter text override (blank = reset to measured):".into(),
Step::EnterText { .. } => {
"DIMEDIT Enter text override (blank = reset to measured):".into()
}
}
}
@@ -51,7 +57,9 @@ impl CadCommand for DimEditCommand {
}
fn on_entity_pick(&mut self, handle: Handle, _pt: Vec3) -> CmdResult {
if handle.is_null() { return CmdResult::NeedPoint; }
if handle.is_null() {
return CmdResult::NeedPoint;
}
self.step = Step::EnterText { handle };
CmdResult::NeedPoint
}
@@ -70,6 +78,10 @@ impl CadCommand for DimEditCommand {
Some(CmdResult::DdeditEntity { handle, new_text })
}
fn on_point(&mut self, _pt: Vec3) -> CmdResult { CmdResult::NeedPoint }
fn on_enter(&mut self) -> CmdResult { CmdResult::Cancel }
fn on_point(&mut self, _pt: Vec3) -> CmdResult {
CmdResult::NeedPoint
}
fn on_enter(&mut self) -> CmdResult {
CmdResult::Cancel
}
}
+12 -4
View File
@@ -33,12 +33,16 @@ pub struct DimJogLineCommand {
impl DimJogLineCommand {
pub fn new() -> Self {
Self { step: Step::PickDim }
Self {
step: Step::PickDim,
}
}
}
impl CadCommand for DimJogLineCommand {
fn name(&self) -> &'static str { "DIMJOGLINE" }
fn name(&self) -> &'static str {
"DIMJOGLINE"
}
fn prompt(&self) -> String {
match &self.step {
@@ -52,7 +56,9 @@ impl CadCommand for DimJogLineCommand {
}
fn on_entity_pick(&mut self, handle: Handle, _pt: Vec3) -> CmdResult {
if handle.is_null() { return CmdResult::NeedPoint; }
if handle.is_null() {
return CmdResult::NeedPoint;
}
self.step = Step::PickJogPos { handle };
CmdResult::NeedPoint
}
@@ -69,7 +75,9 @@ impl CadCommand for DimJogLineCommand {
CmdResult::NeedPoint
}
fn on_enter(&mut self) -> CmdResult { CmdResult::Cancel }
fn on_enter(&mut self) -> CmdResult {
CmdResult::Cancel
}
fn on_mouse_move(&mut self, pt: Vec3) -> Option<WireModel> {
if !matches!(self.step, Step::PickJogPos { .. }) {
+30 -9
View File
@@ -34,18 +34,24 @@ pub struct DimSpaceCommand {
impl DimSpaceCommand {
pub fn new() -> Self {
Self { step: Step::PickBase }
Self {
step: Step::PickBase,
}
}
}
impl CadCommand for DimSpaceCommand {
fn name(&self) -> &'static str { "DIMSPACE" }
fn name(&self) -> &'static str {
"DIMSPACE"
}
fn prompt(&self) -> String {
match &self.step {
Step::PickBase => "DIMSPACE Select base dimension:".into(),
Step::PickOthers { others, .. } =>
format!("DIMSPACE Select dimension to space ({} selected, Enter when done):", others.len()),
Step::PickOthers { others, .. } => format!(
"DIMSPACE Select dimension to space ({} selected, Enter when done):",
others.len()
),
Step::EnterSpacing { .. } => "DIMSPACE Enter value (0 = auto):".into(),
}
}
@@ -55,10 +61,15 @@ impl CadCommand for DimSpaceCommand {
}
fn on_entity_pick(&mut self, handle: Handle, _pt: Vec3) -> CmdResult {
if handle.is_null() { return CmdResult::NeedPoint; }
if handle.is_null() {
return CmdResult::NeedPoint;
}
match &mut self.step {
Step::PickBase => {
self.step = Step::PickOthers { base: handle, others: vec![] };
self.step = Step::PickOthers {
base: handle,
others: vec![],
};
CmdResult::NeedPoint
}
Step::PickOthers { others, .. } => {
@@ -84,13 +95,23 @@ impl CadCommand for DimSpaceCommand {
use acadrust::entities::XLine;
let mut xl = XLine::default();
let handles_str: Vec<String> = o.iter().map(|h| h.value().to_string()).collect();
xl.common.layer = format!("__DIMSPACE__{},{},{}", b.value(), handles_str.join(";"), spacing);
return Some(CmdResult::ReplaceEntity(b, vec![acadrust::EntityType::XLine(xl)]));
xl.common.layer = format!(
"__DIMSPACE__{},{},{}",
b.value(),
handles_str.join(";"),
spacing
);
return Some(CmdResult::ReplaceEntity(
b,
vec![acadrust::EntityType::XLine(xl)],
));
}
None
}
fn on_point(&mut self, _pt: Vec3) -> CmdResult { CmdResult::NeedPoint }
fn on_point(&mut self, _pt: Vec3) -> CmdResult {
CmdResult::NeedPoint
}
fn on_enter(&mut self) -> CmdResult {
match &self.step {
+22 -8
View File
@@ -24,7 +24,10 @@ pub fn tool() -> ToolDef {
enum Step {
PickDim,
PickTextPos { handle: Handle, entity: Option<EntityType> },
PickTextPos {
handle: Handle,
entity: Option<EntityType>,
},
}
pub struct DimTeditCommand {
@@ -33,13 +36,16 @@ pub struct DimTeditCommand {
impl DimTeditCommand {
pub fn new() -> Self {
Self { step: Step::PickDim }
Self {
step: Step::PickDim,
}
}
}
impl CadCommand for DimTeditCommand {
fn name(&self) -> &'static str { "DIMTEDIT" }
fn name(&self) -> &'static str {
"DIMTEDIT"
}
fn prompt(&self) -> String {
match &self.step {
@@ -53,8 +59,13 @@ impl CadCommand for DimTeditCommand {
}
fn on_entity_pick(&mut self, handle: Handle, _pt: Vec3) -> CmdResult {
if handle.is_null() { return CmdResult::NeedPoint; }
self.step = Step::PickTextPos { handle, entity: None };
if handle.is_null() {
return CmdResult::NeedPoint;
}
self.step = Step::PickTextPos {
handle,
entity: None,
};
CmdResult::NeedPoint
}
@@ -63,7 +74,8 @@ impl CadCommand for DimTeditCommand {
let h = *handle;
if let Some(mut ent) = entity.take() {
if let EntityType::Dimension(ref mut d) = ent {
let new_pt = acadrust::types::Vector3::new(pt.x as f64, pt.y as f64, pt.z as f64);
let new_pt =
acadrust::types::Vector3::new(pt.x as f64, pt.y as f64, pt.z as f64);
d.base_mut().text_middle_point = new_pt;
d.base_mut().insertion_point = new_pt;
}
@@ -76,7 +88,9 @@ impl CadCommand for DimTeditCommand {
}
}
fn on_enter(&mut self) -> CmdResult { CmdResult::Cancel }
fn on_enter(&mut self) -> CmdResult {
CmdResult::Cancel
}
fn on_mouse_move(&mut self, pt: Vec3) -> Option<WireModel> {
if !matches!(self.step, Step::PickTextPos { .. }) {
+62 -29
View File
@@ -39,25 +39,36 @@ pub struct LeaderCommand {
impl LeaderCommand {
pub fn new() -> Self {
Self { step: Step::CollectPoints { verts: Vec::new() } }
Self {
step: Step::CollectPoints { verts: Vec::new() },
}
}
}
impl CadCommand for LeaderCommand {
fn name(&self) -> &'static str { "LEADER" }
fn name(&self) -> &'static str {
"LEADER"
}
fn prompt(&self) -> String {
match &self.step {
Step::CollectPoints { verts } if verts.is_empty() =>
"LEADER Specify arrowhead point:".into(),
Step::CollectPoints { verts } =>
format!("LEADER Specify next point [{} pts — Enter to finish]:", verts.len()),
Step::AskCreationType { .. } =>
"LEADER Annotation type [None/Text/Block/Tolerance] <Text>:".into(),
Step::AskText { verts } =>
format!("LEADER Annotation text [{} pts — blank = skip]:", verts.len()),
Step::AskBlock { verts } =>
format!("LEADER Block name [{} pts — blank = skip]:", verts.len()),
Step::CollectPoints { verts } if verts.is_empty() => {
"LEADER Specify arrowhead point:".into()
}
Step::CollectPoints { verts } => format!(
"LEADER Specify next point [{} pts — Enter to finish]:",
verts.len()
),
Step::AskCreationType { .. } => {
"LEADER Annotation type [None/Text/Block/Tolerance] <Text>:".into()
}
Step::AskText { verts } => format!(
"LEADER Annotation text [{} pts — blank = skip]:",
verts.len()
),
Step::AskBlock { verts } => {
format!("LEADER Block name [{} pts — blank = skip]:", verts.len())
}
}
}
@@ -74,7 +85,9 @@ impl CadCommand for LeaderCommand {
fn on_enter(&mut self) -> CmdResult {
if let Step::CollectPoints { verts } = &self.step {
if verts.len() < 2 { return CmdResult::Cancel; }
if verts.len() < 2 {
return CmdResult::Cancel;
}
let verts = verts.clone();
self.step = Step::AskCreationType { verts };
CmdResult::NeedPoint
@@ -91,7 +104,9 @@ impl CadCommand for LeaderCommand {
match parse_ct(text) {
LeaderCreationType::NoAnnotation | LeaderCreationType::WithTolerance => {
let ct = parse_ct(text);
Some(CmdResult::CommitAndExit(EntityType::Leader(build_leader(&verts, ct))))
Some(CmdResult::CommitAndExit(EntityType::Leader(build_leader(
&verts, ct,
))))
}
LeaderCreationType::WithBlock => {
self.step = Step::AskBlock { verts };
@@ -109,7 +124,11 @@ impl CadCommand for LeaderCommand {
if text.is_empty() {
return Some(CmdResult::CommitAndExit(EntityType::Leader(leader)));
}
let mtext = build_mtext(text, landing_pt(&verts, leader.text_height), leader.text_height);
let mtext = build_mtext(
text,
landing_pt(&verts, leader.text_height),
leader.text_height,
);
Some(CmdResult::ReplaceMany(
vec![],
vec![EntityType::Leader(leader), EntityType::MText(mtext)],
@@ -131,11 +150,15 @@ impl CadCommand for LeaderCommand {
}
}
fn on_escape(&mut self) -> CmdResult { CmdResult::Cancel }
fn on_escape(&mut self) -> CmdResult {
CmdResult::Cancel
}
fn on_mouse_move(&mut self, pt: Vec3) -> Option<WireModel> {
if let Step::CollectPoints { verts } = &self.step {
if verts.is_empty() { return None; }
if verts.is_empty() {
return None;
}
let mut pts = verts.clone();
pts.push(pt);
Some(preview_wire(&pts))
@@ -149,14 +172,16 @@ impl CadCommand for LeaderCommand {
fn parse_ct(s: &str) -> LeaderCreationType {
match s.to_ascii_uppercase().as_str() {
"N" | "NONE" => LeaderCreationType::NoAnnotation,
"B" | "BLOCK" => LeaderCreationType::WithBlock,
"TL"| "TOLERANCE" => LeaderCreationType::WithTolerance,
_ => LeaderCreationType::WithText,
"N" | "NONE" => LeaderCreationType::NoAnnotation,
"B" | "BLOCK" => LeaderCreationType::WithBlock,
"TL" | "TOLERANCE" => LeaderCreationType::WithTolerance,
_ => LeaderCreationType::WithText,
}
}
fn v3(p: Vec3) -> Vector3 { Vector3::new(p.x as f64, p.y as f64, p.z as f64) }
fn v3(p: Vec3) -> Vector3 {
Vector3::new(p.x as f64, p.y as f64, p.z as f64)
}
fn build_leader(verts: &[Vec3], ct: LeaderCreationType) -> Leader {
let mut l = Leader::from_vertices(verts.iter().map(|p| v3(*p)).collect());
@@ -200,11 +225,11 @@ fn preview_wire(pts: &[Vec3]) -> WireModel {
snap_pts: vec![],
tangent_geoms: vec![],
aci: 0,
key_vertices: vec![],
aabb: WireModel::UNBOUNDED_AABB,
plinegen: true,
vp_scissor: None,
fill_tris: vec![],
key_vertices: vec![],
aabb: WireModel::UNBOUNDED_AABB,
plinegen: true,
vp_scissor: None,
fill_tris: vec![],
}
}
@@ -215,7 +240,15 @@ pub fn arrowhead_wings(tip: Vec3, next: Vec3, size: f32) -> [Vec3; 2] {
let angle = std::f32::consts::PI / 6.0;
let (s, c) = angle.sin_cos();
[
Vec3::new(tip.x + (dx*c - dy*s)*size, tip.y + (dx*s + dy*c)*size, tip.z),
Vec3::new(tip.x + (dx*c + dy*s)*size, tip.y + (-dx*s + dy*c)*size, tip.z),
Vec3::new(
tip.x + (dx * c - dy * s) * size,
tip.y + (dx * s + dy * c) * size,
tip.z,
),
Vec3::new(
tip.x + (dx * c + dy * s) * size,
tip.y + (-dx * s + dy * c) * size,
tip.z,
),
]
}
+5 -5
View File
@@ -111,11 +111,11 @@ fn preview_wire(points: Vec<Vec3>) -> WireModel {
snap_pts: vec![],
tangent_geoms: vec![],
aci: 0,
key_vertices: vec![],
aabb: WireModel::UNBOUNDED_AABB,
plinegen: true,
vp_scissor: None,
fill_tris: vec![],
key_vertices: vec![],
aabb: WireModel::UNBOUNDED_AABB,
plinegen: true,
vp_scissor: None,
fill_tris: vec![],
}
}
+51 -24
View File
@@ -36,21 +36,30 @@ pub struct MLeaderCommand {
impl MLeaderCommand {
pub fn new() -> Self {
Self { step: Step::CollectPoints { verts: Vec::new() } }
Self {
step: Step::CollectPoints { verts: Vec::new() },
}
}
}
impl CadCommand for MLeaderCommand {
fn name(&self) -> &'static str { "MLEADER" }
fn name(&self) -> &'static str {
"MLEADER"
}
fn prompt(&self) -> String {
match &self.step {
Step::CollectPoints { verts } if verts.is_empty() =>
"MLEADER Specify arrowhead point:".into(),
Step::CollectPoints { verts } =>
format!("MLEADER Specify next point [{} pts — Enter to finish]:", verts.len()),
Step::AskText { verts } =>
format!("MLEADER Enter annotation text [{} pts — blank = no text]:", verts.len()),
Step::CollectPoints { verts } if verts.is_empty() => {
"MLEADER Specify arrowhead point:".into()
}
Step::CollectPoints { verts } => format!(
"MLEADER Specify next point [{} pts — Enter to finish]:",
verts.len()
),
Step::AskText { verts } => format!(
"MLEADER Enter annotation text [{} pts — blank = no text]:",
verts.len()
),
}
}
@@ -67,7 +76,9 @@ impl CadCommand for MLeaderCommand {
fn on_enter(&mut self) -> CmdResult {
if let Step::CollectPoints { verts } = &self.step {
if verts.len() < 2 { return CmdResult::Cancel; }
if verts.len() < 2 {
return CmdResult::Cancel;
}
let verts = verts.clone();
self.step = Step::AskText { verts };
CmdResult::NeedPoint
@@ -86,11 +97,15 @@ impl CadCommand for MLeaderCommand {
}
}
fn on_escape(&mut self) -> CmdResult { CmdResult::Cancel }
fn on_escape(&mut self) -> CmdResult {
CmdResult::Cancel
}
fn on_mouse_move(&mut self, pt: Vec3) -> Option<WireModel> {
if let Step::CollectPoints { verts } = &self.step {
if verts.is_empty() { return None; }
if verts.is_empty() {
return None;
}
let mut pts = verts.clone();
pts.push(pt);
Some(preview_wire(&pts))
@@ -102,7 +117,9 @@ impl CadCommand for MLeaderCommand {
// ── Helpers ─────────────────────────────────────────────────────────────────
fn v3(p: Vec3) -> Vector3 { Vector3::new(p.x as f64, p.y as f64, p.z as f64) }
fn v3(p: Vec3) -> Vector3 {
Vector3::new(p.x as f64, p.y as f64, p.z as f64)
}
fn build_mleader(text: &str, verts: &[Vec3]) -> MultiLeader {
// Last vertex = content/text location; remaining = leader line points
@@ -115,13 +132,15 @@ fn build_mleader(text: &str, verts: &[Vec3]) -> MultiLeader {
let mut ml = MultiLeader::with_text(text, content_v3, leader_v3);
// Match Leader entity defaults
ml.text_height = 2.5;
ml.context.text_height = 2.5;
ml.arrowhead_size = 2.5;
ml.dogleg_length = 2.5;
ml.text_height = 2.5;
ml.context.text_height = 2.5;
ml.arrowhead_size = 2.5;
ml.dogleg_length = 2.5;
// Direction: from last leader pt toward content
if let (Some(last_leader), Some(root)) = (leader_pts.last(), ml.context.leader_roots.first_mut()) {
if let (Some(last_leader), Some(root)) =
(leader_pts.last(), ml.context.leader_roots.first_mut())
{
let dx = (content_pt.x - last_leader.x) as f64;
let dy = (content_pt.y - last_leader.y) as f64;
let len = (dx * dx + dy * dy).sqrt().max(1e-9);
@@ -153,11 +172,11 @@ fn preview_wire(pts: &[Vec3]) -> WireModel {
snap_pts: vec![],
tangent_geoms: vec![],
aci: 0,
key_vertices: vec![],
aabb: WireModel::UNBOUNDED_AABB,
plinegen: true,
vp_scissor: None,
fill_tris: vec![],
key_vertices: vec![],
aabb: WireModel::UNBOUNDED_AABB,
plinegen: true,
vp_scissor: None,
fill_tris: vec![],
}
}
@@ -168,7 +187,15 @@ fn arrowhead_wings(tip: Vec3, next: Vec3, size: f32) -> [Vec3; 2] {
let angle = std::f32::consts::PI / 6.0;
let (s, c) = angle.sin_cos();
[
Vec3::new(tip.x + (dx*c - dy*s)*size, tip.y + (dx*s + dy*c)*size, tip.z),
Vec3::new(tip.x + (dx*c + dy*s)*size, tip.y + (-dx*s + dy*c)*size, tip.z),
Vec3::new(
tip.x + (dx * c - dy * s) * size,
tip.y + (dx * s + dy * c) * size,
tip.z,
),
Vec3::new(
tip.x + (dx * c + dy * s) * size,
tip.y + (-dx * s + dy * c) * size,
tip.z,
),
]
}
+160 -58
View File
@@ -16,7 +16,8 @@ use crate::scene::wire_model::WireModel;
// ── MLEADERADD ────────────────────────────────────────────────────────────────
pub const ICON_ADD: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/mleader_add.svg"));
pub const ICON_ADD: IconKind =
IconKind::Svg(include_bytes!("../../../assets/icons/mleader_add.svg"));
pub fn tool_add() -> ToolDef {
ToolDef {
@@ -29,8 +30,15 @@ pub fn tool_add() -> ToolDef {
enum AddStep {
PickMLeader,
PickArrowhead { handle: Handle, entity: Option<EntityType> },
CollectPoints { handle: Handle, entity: EntityType, pts: Vec<Vec3> },
PickArrowhead {
handle: Handle,
entity: Option<EntityType>,
},
CollectPoints {
handle: Handle,
entity: EntityType,
pts: Vec<Vec3>,
},
}
pub struct MLeaderAddCommand {
@@ -38,20 +46,26 @@ pub struct MLeaderAddCommand {
}
impl MLeaderAddCommand {
pub fn new() -> Self { Self { step: AddStep::PickMLeader } }
pub fn new() -> Self {
Self {
step: AddStep::PickMLeader,
}
}
}
impl CadCommand for MLeaderAddCommand {
fn name(&self) -> &'static str { "MLEADERADD" }
fn name(&self) -> &'static str {
"MLEADERADD"
}
fn prompt(&self) -> String {
match &self.step {
AddStep::PickMLeader => "MLEADERADD Select a multileader:".into(),
AddStep::PickArrowhead { .. } => "MLEADERADD Specify arrowhead location:".into(),
AddStep::CollectPoints { pts, .. } =>
format!("MLEADERADD Specify next leader point ({} pts, Enter to finish):", pts.len()),
AddStep::CollectPoints { pts, .. } => format!(
"MLEADERADD Specify next leader point ({} pts, Enter to finish):",
pts.len()
),
}
}
@@ -60,8 +74,13 @@ impl CadCommand for MLeaderAddCommand {
}
fn on_entity_pick(&mut self, handle: Handle, _pt: Vec3) -> CmdResult {
if handle.is_null() { return CmdResult::NeedPoint; }
self.step = AddStep::PickArrowhead { handle, entity: None };
if handle.is_null() {
return CmdResult::NeedPoint;
}
self.step = AddStep::PickArrowhead {
handle,
entity: None,
};
CmdResult::NeedPoint
}
@@ -70,7 +89,11 @@ impl CadCommand for MLeaderAddCommand {
AddStep::PickArrowhead { handle, entity } => {
if let Some(ent) = entity.take() {
let h = *handle;
self.step = AddStep::CollectPoints { handle: h, entity: ent, pts: vec![pt] };
self.step = AddStep::CollectPoints {
handle: h,
entity: ent,
pts: vec![pt],
};
return CmdResult::NeedPoint;
}
CmdResult::NeedPoint
@@ -84,12 +107,20 @@ impl CadCommand for MLeaderAddCommand {
}
fn on_enter(&mut self) -> CmdResult {
if let AddStep::CollectPoints { handle, entity, pts } = &mut self.step {
if pts.len() < 1 { return CmdResult::Cancel; }
if let AddStep::CollectPoints {
handle,
entity,
pts,
} = &mut self.step
{
if pts.len() < 1 {
return CmdResult::Cancel;
}
let h = *handle;
if let EntityType::MultiLeader(ref mut ml) = entity {
// Add a new leader root with the collected points
let points: Vec<Vector3> = pts.iter()
let points: Vec<Vector3> = pts
.iter()
.map(|p| Vector3::new(p.x as f64, p.y as f64, p.z as f64))
.collect();
let root = ml.context.add_leader_root();
@@ -120,7 +151,8 @@ impl CadCommand for MLeaderAddCommand {
// ── MLEADERREMOVE ─────────────────────────────────────────────────────────────
pub const ICON_REMOVE: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/mleader_remove.svg"));
pub const ICON_REMOVE: IconKind =
IconKind::Svg(include_bytes!("../../../assets/icons/mleader_remove.svg"));
pub fn tool_remove() -> ToolDef {
ToolDef {
@@ -133,7 +165,10 @@ pub fn tool_remove() -> ToolDef {
enum RemoveStep {
PickMLeader,
PickLeaderToRemove { handle: Handle, entity: Option<EntityType> },
PickLeaderToRemove {
handle: Handle,
entity: Option<EntityType>,
},
}
pub struct MLeaderRemoveCommand {
@@ -141,18 +176,24 @@ pub struct MLeaderRemoveCommand {
}
impl MLeaderRemoveCommand {
pub fn new() -> Self { Self { step: RemoveStep::PickMLeader } }
pub fn new() -> Self {
Self {
step: RemoveStep::PickMLeader,
}
}
}
impl CadCommand for MLeaderRemoveCommand {
fn name(&self) -> &'static str { "MLEADERREMOVE" }
fn name(&self) -> &'static str {
"MLEADERREMOVE"
}
fn prompt(&self) -> String {
match &self.step {
RemoveStep::PickMLeader => "MLEADERREMOVE Select a multileader:".into(),
RemoveStep::PickLeaderToRemove { .. } => "MLEADERREMOVE Click near the leader line to remove:".into(),
RemoveStep::PickLeaderToRemove { .. } => {
"MLEADERREMOVE Click near the leader line to remove:".into()
}
}
}
@@ -161,8 +202,13 @@ impl CadCommand for MLeaderRemoveCommand {
}
fn on_entity_pick(&mut self, handle: Handle, _pt: Vec3) -> CmdResult {
if handle.is_null() { return CmdResult::NeedPoint; }
self.step = RemoveStep::PickLeaderToRemove { handle, entity: None };
if handle.is_null() {
return CmdResult::NeedPoint;
}
self.step = RemoveStep::PickLeaderToRemove {
handle,
entity: None,
};
CmdResult::NeedPoint
}
@@ -173,15 +219,17 @@ impl CadCommand for MLeaderRemoveCommand {
if let EntityType::MultiLeader(ref mut ml) = ent {
// Remove the leader root whose first point is closest to `pt`
let pick = Vector3::new(pt.x as f64, pt.y as f64, pt.z as f64);
let best = ml.context.leader_roots.iter().enumerate()
let best = ml
.context
.leader_roots
.iter()
.enumerate()
.filter_map(|(i, root)| {
root.lines.first()
.and_then(|l| l.points.first())
.map(|p| {
let dx = p.x - pick.x;
let dz = p.z - pick.z;
(i, dx * dx + dz * dz)
})
root.lines.first().and_then(|l| l.points.first()).map(|p| {
let dx = p.x - pick.x;
let dz = p.z - pick.z;
(i, dx * dx + dz * dz)
})
})
.min_by(|a, b| a.1.partial_cmp(&b.1).unwrap_or(std::cmp::Ordering::Equal));
if let Some((idx, _)) = best {
@@ -196,8 +244,12 @@ impl CadCommand for MLeaderRemoveCommand {
CmdResult::NeedPoint
}
fn on_enter(&mut self) -> CmdResult { CmdResult::Cancel }
fn on_mouse_move(&mut self, _pt: Vec3) -> Option<WireModel> { None }
fn on_enter(&mut self) -> CmdResult {
CmdResult::Cancel
}
fn on_mouse_move(&mut self, _pt: Vec3) -> Option<WireModel> {
None
}
fn inject_picked_entity(&mut self, entity: EntityType) {
if let RemoveStep::PickLeaderToRemove { entity: slot, .. } = &mut self.step {
@@ -208,7 +260,8 @@ impl CadCommand for MLeaderRemoveCommand {
// ── MLEADERALIGN ─────────────────────────────────────────────────────────────
pub const ICON_ALIGN: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/mleader_align.svg"));
pub const ICON_ALIGN: IconKind =
IconKind::Svg(include_bytes!("../../../assets/icons/mleader_align.svg"));
pub fn tool_align() -> ToolDef {
ToolDef {
@@ -230,17 +283,29 @@ pub struct MLeaderAlignCommand {
}
impl MLeaderAlignCommand {
pub fn new() -> Self { Self { step: AlignStep::Gathering } }
pub fn new() -> Self {
Self {
step: AlignStep::Gathering,
}
}
}
impl CadCommand for MLeaderAlignCommand {
fn name(&self) -> &'static str { "MLEADERALIGN" }
fn name(&self) -> &'static str {
"MLEADERALIGN"
}
fn prompt(&self) -> String {
match &self.step {
AlignStep::Gathering => "MLEADERALIGN Select multileaders to align (Enter when done):".into(),
AlignStep::PickDirection { .. } => "MLEADERALIGN Specify direction — pick start point:".into(),
AlignStep::PickEndDir { .. } => "MLEADERALIGN Specify end point of alignment direction:".into(),
AlignStep::Gathering => {
"MLEADERALIGN Select multileaders to align (Enter when done):".into()
}
AlignStep::PickDirection { .. } => {
"MLEADERALIGN Specify direction — pick start point:".into()
}
AlignStep::PickEndDir { .. } => {
"MLEADERALIGN Specify end point of alignment direction:".into()
}
}
}
@@ -249,7 +314,9 @@ impl CadCommand for MLeaderAlignCommand {
}
fn on_selection_complete(&mut self, handles: Vec<Handle>) -> CmdResult {
if handles.is_empty() { return CmdResult::Cancel; }
if handles.is_empty() {
return CmdResult::Cancel;
}
self.step = AlignStep::PickDirection { handles };
CmdResult::NeedPoint
}
@@ -258,7 +325,10 @@ impl CadCommand for MLeaderAlignCommand {
match &mut self.step {
AlignStep::PickDirection { handles } => {
let h = handles.clone();
self.step = AlignStep::PickEndDir { handles: h, from: pt };
self.step = AlignStep::PickEndDir {
handles: h,
from: pt,
};
CmdResult::NeedPoint
}
AlignStep::PickEndDir { handles, from } => {
@@ -268,8 +338,14 @@ impl CadCommand for MLeaderAlignCommand {
use acadrust::entities::XLine;
let mut xl = XLine::default();
let hstr: Vec<String> = h.iter().map(|hh| hh.value().to_string()).collect();
xl.common.layer = format!("__MLEADERALIGN__{};{:.4},{:.4};{:.4},{:.4}",
hstr.join(","), f.x, f.z, pt.x, pt.z);
xl.common.layer = format!(
"__MLEADERALIGN__{};{:.4},{:.4};{:.4},{:.4}",
hstr.join(","),
f.x,
f.z,
pt.x,
pt.z
);
// Use first handle as the "replaced" entity (sentinel)
if let Some(&first) = h.first() {
return CmdResult::ReplaceEntity(first, vec![EntityType::XLine(xl)]);
@@ -280,13 +356,18 @@ impl CadCommand for MLeaderAlignCommand {
}
}
fn on_enter(&mut self) -> CmdResult { CmdResult::Cancel }
fn on_mouse_move(&mut self, _pt: Vec3) -> Option<WireModel> { None }
fn on_enter(&mut self) -> CmdResult {
CmdResult::Cancel
}
fn on_mouse_move(&mut self, _pt: Vec3) -> Option<WireModel> {
None
}
}
// ── MLEADERCOLLECT ────────────────────────────────────────────────────────────
pub const ICON_COLLECT: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/mleader_collect.svg"));
pub const ICON_COLLECT: IconKind =
IconKind::Svg(include_bytes!("../../../assets/icons/mleader_collect.svg"));
pub fn tool_collect() -> ToolDef {
ToolDef {
@@ -307,16 +388,26 @@ pub struct MLeaderCollectCommand {
}
impl MLeaderCollectCommand {
pub fn new() -> Self { Self { step: CollectStep::Gathering } }
pub fn new() -> Self {
Self {
step: CollectStep::Gathering,
}
}
}
impl CadCommand for MLeaderCollectCommand {
fn name(&self) -> &'static str { "MLEADERCOLLECT" }
fn name(&self) -> &'static str {
"MLEADERCOLLECT"
}
fn prompt(&self) -> String {
match &self.step {
CollectStep::Gathering => "MLEADERCOLLECT Select multileaders to collect (Enter when done):".into(),
CollectStep::PickLocation { .. } => "MLEADERCOLLECT Specify collected multileader location:".into(),
CollectStep::Gathering => {
"MLEADERCOLLECT Select multileaders to collect (Enter when done):".into()
}
CollectStep::PickLocation { .. } => {
"MLEADERCOLLECT Specify collected multileader location:".into()
}
}
}
@@ -325,7 +416,9 @@ impl CadCommand for MLeaderCollectCommand {
}
fn on_selection_complete(&mut self, handles: Vec<Handle>) -> CmdResult {
if handles.is_empty() { return CmdResult::Cancel; }
if handles.is_empty() {
return CmdResult::Cancel;
}
self.step = CollectStep::PickLocation { handles };
CmdResult::NeedPoint
}
@@ -338,7 +431,12 @@ impl CadCommand for MLeaderCollectCommand {
use acadrust::entities::XLine;
let mut xl = XLine::default();
let hstr: Vec<String> = h.iter().map(|hh| hh.value().to_string()).collect();
xl.common.layer = format!("__MLEADERCOLLECT__{};{:.4},{:.4}", hstr.join(","), pt.x, pt.z);
xl.common.layer = format!(
"__MLEADERCOLLECT__{};{:.4},{:.4}",
hstr.join(","),
pt.x,
pt.z
);
if let Some(&first) = h.first() {
return CmdResult::ReplaceEntity(first, vec![EntityType::XLine(xl)]);
}
@@ -346,8 +444,12 @@ impl CadCommand for MLeaderCollectCommand {
CmdResult::NeedPoint
}
fn on_enter(&mut self) -> CmdResult { CmdResult::Cancel }
fn on_mouse_move(&mut self, _pt: Vec3) -> Option<WireModel> { None }
fn on_enter(&mut self) -> CmdResult {
CmdResult::Cancel
}
fn on_mouse_move(&mut self, _pt: Vec3) -> Option<WireModel> {
None
}
}
// ── Shared helpers ────────────────────────────────────────────────────────────
@@ -366,9 +468,9 @@ fn preview_wire(pts: &[Vec3]) -> WireModel {
aci: 0,
key_vertices: vec![],
aabb: WireModel::UNBOUNDED_AABB,
plinegen: true,
vp_scissor: None,
fill_tris: vec![],
plinegen: true,
vp_scissor: None,
fill_tris: vec![],
}
}
+55 -40
View File
@@ -1,9 +1,9 @@
// Annotate module — dimension, text, leader, table, and markup tools.
pub mod aligned_dim;
pub mod angular_dim;
pub mod data_extract;
pub mod data_link;
pub mod angular_dim;
pub mod ddedit;
pub mod diameter_dim;
pub mod dim_baseline;
@@ -38,7 +38,7 @@ impl CadModule for AnnotateModule {
}
fn ribbon_groups(&self) -> Vec<RibbonGroup> {
use crate::modules::home::draw::{wipeout, revcloud};
use crate::modules::home::draw::{revcloud, wipeout};
vec![
// ── Text ─────────────────────────────────────────────────────
@@ -51,7 +51,7 @@ impl CadModule for AnnotateModule {
icon: mtext::ICON,
items: vec![
(mtext::tool().id, mtext::tool().label, mtext::tool().icon),
(text::tool().id, text::tool().label, text::tool().icon),
(text::tool().id, text::tool().label, text::tool().icon),
(ddedit::tool().id, ddedit::tool().label, ddedit::tool().icon),
],
default: "MTEXT",
@@ -60,16 +60,14 @@ impl CadModule for AnnotateModule {
style_key: StyleKey::TextStyle,
combo_id: "TEXT_STYLE_COMBO",
manager_cmd: Some("STYLE"),
rows: vec![
vec![
crate::modules::ToolDef {
id: "FIND",
label: "Find",
icon: crate::modules::IconKind::Svg(include_bytes!("../../../assets/icons/find.svg")),
event: crate::modules::ModuleEvent::Command("FIND".to_string()),
},
],
],
rows: vec![vec![crate::modules::ToolDef {
id: "FIND",
label: "Find",
icon: crate::modules::IconKind::Svg(include_bytes!(
"../../../assets/icons/find.svg"
)),
event: crate::modules::ModuleEvent::Command("FIND".to_string()),
}]],
},
],
},
@@ -82,12 +80,36 @@ impl CadModule for AnnotateModule {
label: "Dimension",
icon: linear_dim::ICON,
items: vec![
(linear_dim::tool().id, linear_dim::tool().label, linear_dim::tool().icon),
(aligned_dim::tool().id, aligned_dim::tool().label, aligned_dim::tool().icon),
(angular_dim::tool().id, angular_dim::tool().label, angular_dim::tool().icon),
(radius_dim::tool().id, radius_dim::tool().label, radius_dim::tool().icon),
(diameter_dim::tool().id, diameter_dim::tool().label, diameter_dim::tool().icon),
(ordinate_dim::tool().id, ordinate_dim::tool().label, ordinate_dim::tool().icon),
(
linear_dim::tool().id,
linear_dim::tool().label,
linear_dim::tool().icon,
),
(
aligned_dim::tool().id,
aligned_dim::tool().label,
aligned_dim::tool().icon,
),
(
angular_dim::tool().id,
angular_dim::tool().label,
angular_dim::tool().icon,
),
(
radius_dim::tool().id,
radius_dim::tool().label,
radius_dim::tool().icon,
),
(
diameter_dim::tool().id,
diameter_dim::tool().label,
diameter_dim::tool().icon,
),
(
ordinate_dim::tool().id,
ordinate_dim::tool().label,
ordinate_dim::tool().icon,
),
(qdim::tool().id, qdim::tool().label, qdim::tool().icon),
],
default: "DIMLINEAR",
@@ -97,11 +119,7 @@ impl CadModule for AnnotateModule {
combo_id: "DIM_STYLE_COMBO",
manager_cmd: Some("DIMSTYLE"),
rows: vec![
vec![
qdim::tool(),
dim_continue::tool(),
dim_baseline::tool(),
],
vec![qdim::tool(), dim_continue::tool(), dim_baseline::tool()],
vec![
tolerance_cmd::tool(),
dimedit::tool(),
@@ -123,8 +141,16 @@ impl CadModule for AnnotateModule {
label: "Multileader",
icon: mleader_cmd::ICON,
items: vec![
(mleader_cmd::tool().id, mleader_cmd::tool().label, mleader_cmd::tool().icon),
(leader_cmd::tool().id, leader_cmd::tool().label, leader_cmd::tool().icon),
(
mleader_cmd::tool().id,
mleader_cmd::tool().label,
mleader_cmd::tool().icon,
),
(
leader_cmd::tool().id,
leader_cmd::tool().label,
leader_cmd::tool().icon,
),
],
default: "MLEADER",
},
@@ -133,14 +159,8 @@ impl CadModule for AnnotateModule {
combo_id: "MLEADER_STYLE_COMBO",
manager_cmd: Some("MLEADERSTYLE"),
rows: vec![
vec![
mleader_edit::tool_add(),
mleader_edit::tool_remove(),
],
vec![
mleader_edit::tool_align(),
mleader_edit::tool_collect(),
],
vec![mleader_edit::tool_add(), mleader_edit::tool_remove()],
vec![mleader_edit::tool_align(), mleader_edit::tool_collect()],
],
},
],
@@ -154,12 +174,7 @@ impl CadModule for AnnotateModule {
style_key: StyleKey::TableStyle,
combo_id: "TABLE_STYLE_COMBO",
manager_cmd: Some("TABLESTYLE"),
rows: vec![
vec![
data_extract::tool(),
data_link::tool(),
],
],
rows: vec![vec![data_extract::tool(), data_link::tool()]],
},
],
},
+12 -4
View File
@@ -37,12 +37,16 @@ pub struct OrdinateDimCommand {
impl OrdinateDimCommand {
pub fn new() -> Self {
Self { step: Step::FeaturePoint }
Self {
step: Step::FeaturePoint,
}
}
}
impl CadCommand for OrdinateDimCommand {
fn name(&self) -> &'static str { "DIMORDINATE" }
fn name(&self) -> &'static str {
"DIMORDINATE"
}
fn prompt(&self) -> String {
match self.step {
@@ -71,8 +75,12 @@ impl CadCommand for OrdinateDimCommand {
}
}
fn on_enter(&mut self) -> CmdResult { CmdResult::Cancel }
fn on_preview_wires(&mut self, _pt: Vec3) -> Vec<WireModel> { vec![] }
fn on_enter(&mut self) -> CmdResult {
CmdResult::Cancel
}
fn on_preview_wires(&mut self, _pt: Vec3) -> Vec<WireModel> {
vec![]
}
}
fn v3(p: Vec3) -> Vector3 {
+15 -10
View File
@@ -37,14 +37,16 @@ pub struct QdimCommand {
impl QdimCommand {
pub fn new() -> Self {
Self { step: Step::Gathering }
Self {
step: Step::Gathering,
}
}
}
impl CadCommand for QdimCommand {
fn name(&self) -> &'static str { "QDIM" }
fn name(&self) -> &'static str {
"QDIM"
}
fn prompt(&self) -> String {
match &self.step {
@@ -76,7 +78,9 @@ impl CadCommand for QdimCommand {
}
}
fn on_enter(&mut self) -> CmdResult { CmdResult::Cancel }
fn on_enter(&mut self) -> CmdResult {
CmdResult::Cancel
}
fn on_mouse_move(&mut self, pt: Vec3) -> Option<WireModel> {
if !matches!(self.step, Step::PlaceLine { .. }) {
@@ -85,10 +89,7 @@ impl CadCommand for QdimCommand {
let d = 0.5_f32;
Some(WireModel {
name: "qdim_preview".into(),
points: vec![
[pt.x - d * 3.0, pt.y, pt.z],
[pt.x + d * 3.0, pt.y, pt.z],
],
points: vec![[pt.x - d * 3.0, pt.y, pt.z], [pt.x + d * 3.0, pt.y, pt.z]],
color: WireModel::CYAN,
selected: false,
pattern_length: 0.0,
@@ -114,7 +115,11 @@ pub fn make_linear_dim(p1: Vec3, p2: Vec3, dim_pt: Vec3) -> EntityType {
// Determine axis: horizontal if Δx > Δz, else vertical
let dx = (p2.x - p1.x).abs();
let dz = (p2.z - p1.z).abs();
dim.rotation = if dz > dx { std::f64::consts::FRAC_PI_2 } else { 0.0 };
dim.rotation = if dz > dx {
std::f64::consts::FRAC_PI_2
} else {
0.0
};
dim.definition_point = v(dim_pt);
dim.base.definition_point = v(dim_pt);
let text_pos = (p1 + p2) * 0.5;
+5 -5
View File
@@ -110,10 +110,10 @@ fn preview_wire(points: Vec<Vec3>) -> WireModel {
snap_pts: vec![],
tangent_geoms: vec![],
aci: 0,
key_vertices: vec![],
aabb: WireModel::UNBOUNDED_AABB,
plinegen: true,
vp_scissor: None,
fill_tris: vec![],
key_vertices: vec![],
aabb: WireModel::UNBOUNDED_AABB,
plinegen: true,
vp_scissor: None,
fill_tris: vec![],
}
}
+29 -14
View File
@@ -44,18 +44,26 @@ pub struct TableCommand {
impl TableCommand {
pub fn new() -> Self {
Self { step: Step::Columns }
Self {
step: Step::Columns,
}
}
}
impl CadCommand for TableCommand {
fn name(&self) -> &'static str { "TABLE" }
fn name(&self) -> &'static str {
"TABLE"
}
fn prompt(&self) -> String {
match &self.step {
Step::Columns => format!("TABLE Enter number of columns [{DEFAULT_COLS}]:"),
Step::Rows { cols } => format!("TABLE Enter number of rows (incl. header) [{DEFAULT_ROWS}] ({cols} cols):"),
Step::Insertion { cols, rows } => format!("TABLE Specify insertion point [{cols}×{rows}]:"),
Step::Rows { cols } => format!(
"TABLE Enter number of rows (incl. header) [{DEFAULT_ROWS}] ({cols} cols):"
),
Step::Insertion { cols, rows } => {
format!("TABLE Specify insertion point [{cols}×{rows}]:")
}
}
}
@@ -98,7 +106,10 @@ impl CadCommand for TableCommand {
}
Step::Rows { cols } => {
let cols = *cols;
self.step = Step::Insertion { cols, rows: DEFAULT_ROWS };
self.step = Step::Insertion {
cols,
rows: DEFAULT_ROWS,
};
CmdResult::NeedPoint
}
Step::Insertion { .. } => CmdResult::Cancel,
@@ -130,10 +141,14 @@ impl CadCommand for TableCommand {
Some(WireModel {
name: "table_preview".into(),
points: vec![
[x, y, z], [x + w, y, z],
[x + w, y, z], [x + w, y, z - h],
[x + w, y, z - h], [x, y, z - h],
[x, y, z - h], [x, y, z],
[x, y, z],
[x + w, y, z],
[x + w, y, z],
[x + w, y, z - h],
[x + w, y, z - h],
[x, y, z - h],
[x, y, z - h],
[x, y, z],
],
color: WireModel::CYAN,
selected: false,
@@ -143,11 +158,11 @@ impl CadCommand for TableCommand {
snap_pts: vec![],
tangent_geoms: vec![],
aci: 0,
key_vertices: vec![],
aabb: WireModel::UNBOUNDED_AABB,
plinegen: true,
vp_scissor: None,
fill_tris: vec![],
key_vertices: vec![],
aabb: WireModel::UNBOUNDED_AABB,
plinegen: true,
vp_scissor: None,
fill_tris: vec![],
})
} else {
None
+7 -3
View File
@@ -40,7 +40,9 @@ impl ToleranceCommand {
}
impl CadCommand for ToleranceCommand {
fn name(&self) -> &'static str { "TOLERANCE" }
fn name(&self) -> &'static str {
"TOLERANCE"
}
fn prompt(&self) -> String {
match &self.step {
@@ -84,9 +86,11 @@ impl CadCommand for ToleranceCommand {
Some(WireModel {
name: "tolerance_preview".into(),
points: vec![
[pt.x - d, pt.y, pt.z], [pt.x + d, pt.y, pt.z],
[pt.x - d, pt.y, pt.z],
[pt.x + d, pt.y, pt.z],
[f32::NAN, 0.0, 0.0],
[pt.x, pt.y, pt.z - d], [pt.x, pt.y, pt.z + d],
[pt.x, pt.y, pt.z - d],
[pt.x, pt.y, pt.z + d],
],
color: WireModel::CYAN,
selected: false,