forked from 1b-agent/opencadstudio-upstream
fix(model): respect typed height on cylinder and primitive creation
This commit is contained in:
1 parent
fc19afa715
commit
c35b902f3a
2 files changed
+109
-6
No files matched your search
@@ -734,10 +734,14 @@ impl CadCommand for CylinderCommand {
|
|||||||
fn point_step_accepts_keywords(&self) -> bool {
|
fn point_step_accepts_keywords(&self) -> bool {
|
||||||
matches!(
|
matches!(
|
||||||
self.step,
|
self.step,
|
||||||
Step::BaseCenter | Step::BaseRadius | Step::EllipseFirst | Step::Height
|
Step::BaseCenter | Step::BaseRadius | Step::EllipseFirst
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn dyn_commit_as_text(&self) -> bool {
|
||||||
|
matches!(self.step, Step::Height | Step::BaseDiameter)
|
||||||
|
}
|
||||||
|
|
||||||
fn on_text_input(&mut self, raw: &str) -> Option<CmdResult> {
|
fn on_text_input(&mut self, raw: &str) -> Option<CmdResult> {
|
||||||
self.on_text(raw)
|
self.on_text(raw)
|
||||||
}
|
}
|
||||||
@@ -827,3 +831,87 @@ fn push_ellipse(
|
|||||||
fn wire(name: &str, points: Vec<[f32; 3]>) -> WireModel {
|
fn wire(name: &str, points: Vec<[f32; 3]>) -> WireModel {
|
||||||
WireModel::solid(name.to_string(), points, WireModel::CYAN, false)
|
WireModel::solid(name.to_string(), points, WireModel::CYAN, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod cylinder_tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cylinder_creation_height_workflow() {
|
||||||
|
// Reset defaults
|
||||||
|
if let Ok(mut defs) = defaults().lock() {
|
||||||
|
*defs = Defaults::default();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test 1: Typing height upon creation respects the typed height
|
||||||
|
let mut command = CylinderCommand::new();
|
||||||
|
assert!(!command.dyn_commit_as_text());
|
||||||
|
|
||||||
|
// Step 1: Center
|
||||||
|
assert!(matches!(command.on_point(DVec3::ZERO), CmdResult::NeedPoint));
|
||||||
|
assert!(!command.dyn_commit_as_text());
|
||||||
|
|
||||||
|
// Step 2: Radius
|
||||||
|
assert!(matches!(
|
||||||
|
command.on_point(DVec3::new(5.0, 0.0, 0.0)),
|
||||||
|
CmdResult::NeedPoint
|
||||||
|
));
|
||||||
|
|
||||||
|
// Step 3: Height
|
||||||
|
assert!(command.dyn_commit_as_text());
|
||||||
|
assert!(!command.point_step_accepts_keywords());
|
||||||
|
|
||||||
|
let res = command.on_text_input("25.0");
|
||||||
|
let Some(CmdResult::CommitSolid { history, .. }) = res else {
|
||||||
|
panic!("expected CommitSolid");
|
||||||
|
};
|
||||||
|
let SolidHistoryOperation::Cylinder(cyl) = history else {
|
||||||
|
panic!("expected Cylinder history");
|
||||||
|
};
|
||||||
|
assert_eq!(cyl.height, 25.0);
|
||||||
|
assert_eq!(defaults().lock().unwrap().height, 25.0);
|
||||||
|
|
||||||
|
// Test 2: Create cylinder with mouse drag
|
||||||
|
let mut cmd1 = CylinderCommand::new();
|
||||||
|
cmd1.on_point(DVec3::ZERO);
|
||||||
|
cmd1.on_point(DVec3::new(4.0, 0.0, 0.0));
|
||||||
|
let res1 = cmd1.on_point(DVec3::new(0.0, 0.0, 10.0));
|
||||||
|
let CmdResult::CommitSolid { history, .. } = res1 else {
|
||||||
|
panic!("expected CommitSolid");
|
||||||
|
};
|
||||||
|
let SolidHistoryOperation::Cylinder(cyl1) = history else {
|
||||||
|
panic!("expected Cylinder history");
|
||||||
|
};
|
||||||
|
assert_eq!(cyl1.height, 10.0);
|
||||||
|
assert_eq!(defaults().lock().unwrap().height, 10.0);
|
||||||
|
|
||||||
|
// Test 3: Next cylinder with Enter respects remembered mouse-dragged height
|
||||||
|
let mut cmd2 = CylinderCommand::new();
|
||||||
|
cmd2.on_point(DVec3::ZERO);
|
||||||
|
cmd2.on_point(DVec3::new(4.0, 0.0, 0.0));
|
||||||
|
let res2 = cmd2.on_enter();
|
||||||
|
let CmdResult::CommitSolid { history, .. } = res2 else {
|
||||||
|
panic!("expected CommitSolid");
|
||||||
|
};
|
||||||
|
let SolidHistoryOperation::Cylinder(cyl2) = history else {
|
||||||
|
panic!("expected Cylinder history");
|
||||||
|
};
|
||||||
|
assert_eq!(cyl2.height, 10.0);
|
||||||
|
|
||||||
|
// Test 4: Next cylinder: typing different height respects the new typed height (not retaining 10.0)!
|
||||||
|
let mut cmd3 = CylinderCommand::new();
|
||||||
|
cmd3.on_point(DVec3::ZERO);
|
||||||
|
cmd3.on_point(DVec3::new(4.0, 0.0, 0.0));
|
||||||
|
assert!(cmd3.dyn_commit_as_text());
|
||||||
|
let res3 = cmd3.on_text_input("42.0");
|
||||||
|
let Some(CmdResult::CommitSolid { history, .. }) = res3 else {
|
||||||
|
panic!("expected CommitSolid");
|
||||||
|
};
|
||||||
|
let SolidHistoryOperation::Cylinder(cyl3) = history else {
|
||||||
|
panic!("expected Cylinder history");
|
||||||
|
};
|
||||||
|
assert_eq!(cyl3.height, 42.0);
|
||||||
|
assert_eq!(defaults().lock().unwrap().height, 42.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -2866,8 +2866,6 @@ impl CadCommand for PrimitiveCommand {
|
|||||||
ConeStep::BaseCenter
|
ConeStep::BaseCenter
|
||||||
| ConeStep::BaseRadius
|
| ConeStep::BaseRadius
|
||||||
| ConeStep::EllipseFirst
|
| ConeStep::EllipseFirst
|
||||||
| ConeStep::Height
|
|
||||||
| ConeStep::HeightAfterTopRadius
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if self.shape == Shape::Pyramid {
|
if self.shape == Shape::Pyramid {
|
||||||
@@ -2875,17 +2873,34 @@ impl CadCommand for PrimitiveCommand {
|
|||||||
self.pyramid_step,
|
self.pyramid_step,
|
||||||
PyramidStep::BaseCenter
|
PyramidStep::BaseCenter
|
||||||
| PyramidStep::BaseRadius
|
| PyramidStep::BaseRadius
|
||||||
| PyramidStep::Height
|
|
||||||
| PyramidStep::HeightAfterTopRadius
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
self.shape.rectangular()
|
self.shape.rectangular()
|
||||||
&& matches!(
|
&& matches!(
|
||||||
self.box_step,
|
self.box_step,
|
||||||
BoxStep::FirstCorner | BoxStep::OppositeCorner | BoxStep::Height
|
BoxStep::FirstCorner | BoxStep::OppositeCorner
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn dyn_commit_as_text(&self) -> bool {
|
||||||
|
if self.shape == Shape::Cone {
|
||||||
|
return matches!(
|
||||||
|
self.cone_step,
|
||||||
|
ConeStep::Height | ConeStep::HeightAfterTopRadius
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if self.shape == Shape::Pyramid {
|
||||||
|
return matches!(
|
||||||
|
self.pyramid_step,
|
||||||
|
PyramidStep::Height | PyramidStep::HeightAfterTopRadius
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if self.shape.rectangular() {
|
||||||
|
return matches!(self.box_step, BoxStep::Height);
|
||||||
|
}
|
||||||
|
self.height_step
|
||||||
|
}
|
||||||
|
|
||||||
fn on_text_input(&mut self, raw: &str) -> Option<CmdResult> {
|
fn on_text_input(&mut self, raw: &str) -> Option<CmdResult> {
|
||||||
if self.shape == Shape::Sphere {
|
if self.shape == Shape::Sphere {
|
||||||
let token = raw.trim();
|
let token = raw.trim();
|
||||||
|
|||||||
Reference in new issue
Block a user