forked from 1b-agent/opencadstudio-upstream
aliases: import AutoCAD PGP files and support UCS-follow workflows
This commit is contained in:
1 parent
2414721c14
commit
d19c797685
39 files changed
+818
-30
No files matched your search
@@ -55,7 +55,7 @@ impl CadCommand for UcsCommand {
|
||||
fn prompt(&self) -> String {
|
||||
match self.option.as_deref() {
|
||||
None => {
|
||||
t!("UCS option [Face/OBject/World/View/3Point/Z/X/Y/Origin/Save/Delete] or name:")
|
||||
t!("UCS specify new origin or [Face/OBject/World/View/3Point/Z/X/Y/Origin/Save/Delete] or name:")
|
||||
.into_owned()
|
||||
}
|
||||
Some("Z") => t!("UCS rotation angle about Z (degrees):").into_owned(),
|
||||
@@ -81,7 +81,10 @@ impl CadCommand for UcsCommand {
|
||||
|
||||
fn on_text_input(&mut self, text: &str) -> Option<CmdResult> {
|
||||
let t = text.trim();
|
||||
if matches!(self.option.as_deref(), Some("3POINT") | Some("3P"))
|
||||
// Coordinate input is handled by the point-input pipeline, just like a
|
||||
// click. With no option selected, it starts the default three-point UCS.
|
||||
if (self.option.is_none()
|
||||
|| matches!(self.option.as_deref(), Some("3POINT") | Some("3P")))
|
||||
&& crate::app::helpers::parse_coord(t).is_some()
|
||||
{
|
||||
return None;
|
||||
@@ -94,6 +97,20 @@ impl CadCommand for UcsCommand {
|
||||
return Some(CmdResult::Dispatch("UCS LIST".into()));
|
||||
}
|
||||
let up = t.to_uppercase();
|
||||
// Accept the Spanish labels shown by the localized prompt as
|
||||
// well as international option keywords. Only normalize the
|
||||
// option token, never the value/name supplied in the next step.
|
||||
let up = match up.trim_start_matches('_') {
|
||||
"UNIVERSAL" | "U" => "WORLD",
|
||||
"VISTA" => "VIEW",
|
||||
"CARA" => "FACE",
|
||||
"OBJETO" => "OBJECT",
|
||||
"ORIGEN" => "ORIGIN",
|
||||
"GUARDAR" | "G" => "SAVE",
|
||||
"ELIMINAR" | "E" => "DELETE",
|
||||
"3" | "3PUNTOS" | "3 PUNTOS" => "3POINT",
|
||||
value => value,
|
||||
}.to_owned();
|
||||
if Self::is_zero_arg(&up) {
|
||||
Some(CmdResult::Dispatch(format!("UCS {up}")))
|
||||
} else if Self::takes_value(&up) || Self::takes_point(&up) {
|
||||
@@ -111,6 +128,11 @@ impl CadCommand for UcsCommand {
|
||||
}
|
||||
|
||||
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||
// AutoCAD accepts the new origin immediately after UCS/SCP. Do not
|
||||
// silently ignore that first click while waiting for an option keyword.
|
||||
if self.option.is_none() {
|
||||
self.option = Some("3POINT".into());
|
||||
}
|
||||
if matches!(self.option.as_deref(), Some("3POINT") | Some("3P")) {
|
||||
self.points.push(pt);
|
||||
if self.points.len() < 3 {
|
||||
@@ -131,8 +153,7 @@ impl CadCommand for UcsCommand {
|
||||
points[2].z,
|
||||
));
|
||||
}
|
||||
// A clicked point only makes sense for the Origin option; otherwise a
|
||||
// stray click is ignored (keep waiting for the typed keyword / value).
|
||||
// Other point-taking options retain their explicit behavior.
|
||||
if matches!(self.option.as_deref(), Some(o) if Self::takes_point(o)) {
|
||||
self.option.take();
|
||||
return CmdResult::Dispatch(format!("UCS ORIGINW {},{},{}", pt.x, pt.y, pt.z));
|
||||
@@ -149,3 +170,51 @@ impl CadCommand for UcsCommand {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn bare_ucs_accepts_origin_then_x_then_xy_without_option() {
|
||||
let mut cmd = UcsCommand::new();
|
||||
assert!(matches!(cmd.on_point(DVec3::new(10.0, 20.0, 0.0)), CmdResult::NeedPoint));
|
||||
assert_eq!(cmd.points.len(), 1);
|
||||
assert!(matches!(cmd.on_point(DVec3::new(11.0, 20.0, 0.0)), CmdResult::NeedPoint));
|
||||
match cmd.on_point(DVec3::new(10.0, 21.0, 0.0)) {
|
||||
CmdResult::Dispatch(command) => assert_eq!(
|
||||
command, "UCS 3POINTW 10,20,0|11,20,0|10,21,0"
|
||||
),
|
||||
_ => panic!("three clicks must dispatch the new UCS"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn initial_coordinate_is_delegated_to_point_pipeline() {
|
||||
let mut cmd = UcsCommand::new();
|
||||
assert!(cmd.on_text_input("10,20,0").is_none());
|
||||
assert!(matches!(cmd.on_point(DVec3::new(10.0, 20.0, 0.0)), CmdResult::NeedPoint));
|
||||
assert_eq!(cmd.points.len(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn explicit_origin_still_changes_only_origin() {
|
||||
let mut cmd = UcsCommand::new();
|
||||
assert!(matches!(cmd.on_text_input("O"), Some(CmdResult::NeedPoint)));
|
||||
match cmd.on_point(DVec3::new(10.0, 20.0, 0.0)) {
|
||||
CmdResult::Dispatch(command) => assert_eq!(command, "UCS ORIGINW 10,20,0"),
|
||||
_ => panic!("explicit Origin must dispatch after one point"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn spanish_and_international_options_work() {
|
||||
for option in ["Universal", "U", "_World"] {
|
||||
let mut cmd = UcsCommand::new();
|
||||
assert!(matches!(cmd.on_text_input(option), Some(CmdResult::Dispatch(s)) if s == "UCS WORLD"));
|
||||
}
|
||||
let mut cmd = UcsCommand::new();
|
||||
assert!(matches!(cmd.on_text_input("Guardar"), Some(CmdResult::NeedPoint)));
|
||||
assert!(matches!(cmd.on_text_input("MiPlano"), Some(CmdResult::Dispatch(s)) if s == "UCS SAVE MiPlano"));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user