diff --git a/src/app/commands.rs b/src/app/commands.rs index 7620fadd4..5c3f3e8b3 100644 --- a/src/app/commands.rs +++ b/src/app/commands.rs @@ -332,6 +332,13 @@ impl H7CAD { self.tabs[i].active_cmd = Some(Box::new(new_cmd)); } + "MLINE"|"ML" => { + use crate::modules::home::draw::mline::MlineCommand; + let cmd_obj = MlineCommand::new(); + self.command_line.push_info(&cmd_obj.prompt()); + self.tabs[i].active_cmd = Some(Box::new(cmd_obj)); + } + cmd if cmd == "WIPEOUT" || cmd == "WO" || cmd.starts_with("WIPEOUT ") => { use crate::modules::home::draw::wipeout::WipeoutCommand; let args = cmd.split_once(' ').map(|(_, r)| r.trim().to_uppercase()).unwrap_or_default(); diff --git a/src/modules/home/draw/mline.rs b/src/modules/home/draw/mline.rs new file mode 100644 index 000000000..da290bfeb --- /dev/null +++ b/src/modules/home/draw/mline.rs @@ -0,0 +1,123 @@ +// MLINE command — create a multiline (parallel lines). +// +// Workflow: pick vertices, Enter to finish. +// Text input (when >= 1 point picked): +// C / CLOSE → close and commit +// S → set scale factor then continue picking + +use acadrust::entities::MLine; +use acadrust::types::Vector3; +use acadrust::EntityType; +use glam::Vec3; + +use crate::command::{CadCommand, CmdResult}; +use crate::scene::wire_model::WireModel; + +pub struct MlineCommand { + points: Vec, + scale: f64, + waiting_scale: bool, +} + +impl MlineCommand { + pub fn new() -> Self { + Self { points: vec![], scale: 1.0, waiting_scale: false } + } +} + +impl CadCommand for MlineCommand { + fn name(&self) -> &'static str { "MLINE" } + + fn prompt(&self) -> String { + if self.waiting_scale { + "MLINE Enter scale factor:".into() + } else if self.points.is_empty() { + format!("MLINE Specify start point (scale={:.2}):", self.scale) + } else { + format!("MLINE Specify next point ({} pts, Enter to finish, C to close, S to set scale):", self.points.len()) + } + } + + fn wants_text_input(&self) -> bool { + self.waiting_scale || !self.points.is_empty() + } + + fn on_text_input(&mut self, text: &str) -> Option { + // Waiting for scale value + if self.waiting_scale { + let v: f64 = text.trim().replace(',', ".").parse().ok().filter(|&v: &f64| v > 0.0)?; + self.scale = v; + self.waiting_scale = false; + return Some(CmdResult::NeedPoint); + } + + let up = text.trim().to_uppercase(); + + // Close command + if (up == "C" || up == "CLOSE") && self.points.len() >= 3 { + let entity = build_mline(&self.points, self.scale, true); + return Some(CmdResult::CommitAndExit(entity)); + } + + // Scale: "S" alone → prompt for value + if up == "S" { + self.waiting_scale = true; + return Some(CmdResult::NeedPoint); + } + + // Scale: "S " inline + if let Some(rest) = up.strip_prefix("S ") { + if let Ok(v) = rest.trim().replace(',', ".").parse::() { + if v > 0.0 { self.scale = v; } + return Some(CmdResult::NeedPoint); + } + } + + None + } + + fn on_point(&mut self, pt: Vec3) -> CmdResult { + self.points.push(pt); + CmdResult::NeedPoint + } + + fn on_enter(&mut self) -> CmdResult { + if self.points.len() < 2 { + return CmdResult::Cancel; + } + let entity = build_mline(&self.points, self.scale, false); + CmdResult::CommitAndExit(entity) + } + + fn on_mouse_move(&mut self, pt: Vec3) -> Option { + if self.points.is_empty() { return None; } + let mut pts: Vec<[f32; 3]> = + self.points.iter().map(|p| [p.x, p.y, p.z]).collect(); + pts.push([pt.x, pt.y, pt.z]); + Some(WireModel { + name: "mline_preview".into(), + points: pts, + color: WireModel::CYAN, + selected: false, + pattern_length: 0.0, + pattern: [0.0; 8], + line_weight_px: 1.0, + snap_pts: vec![], + tangent_geoms: vec![], + key_vertices: vec![], + }) + } +} + +fn build_mline(pts: &[Vec3], scale: f64, closed: bool) -> EntityType { + let verts: Vec = pts.iter() + .map(|p| Vector3::new(p.x as f64, p.z as f64, p.y as f64)) + .collect(); + let mut mline = if closed { + MLine::closed_from_points(&verts) + } else { + MLine::from_points(&verts) + }; + mline.scale_factor = scale; + EntityType::MLine(mline) +} diff --git a/src/modules/home/draw/mod.rs b/src/modules/home/draw/mod.rs index 2a174081b..6e9269261 100644 --- a/src/modules/home/draw/mod.rs +++ b/src/modules/home/draw/mod.rs @@ -4,6 +4,7 @@ pub mod donut; pub mod ellipse; pub mod hatch; pub mod line; +pub mod mline; pub mod point; pub mod polyline; pub mod ray;