Correct circle size input and persistence
This commit is contained in:
parent
573ed3245e
commit
b0e464f4b4
2 changed files with 97 additions and 29 deletions
|
|
@ -5,7 +5,6 @@ use std::cell::Cell;
|
||||||
|
|
||||||
thread_local! {
|
thread_local! {
|
||||||
static CIRCLE_RADIUS: Cell<f64> = Cell::new(1.0);
|
static CIRCLE_RADIUS: Cell<f64> = Cell::new(1.0);
|
||||||
static CIRCLE_DIAM: Cell<f64> = Cell::new(2.0);
|
|
||||||
static ROTATE_ANGLE: Cell<f64> = Cell::new(0.0); // degrees
|
static ROTATE_ANGLE: Cell<f64> = Cell::new(0.0); // degrees
|
||||||
static SCALE_FACTOR: Cell<f64> = Cell::new(1.0);
|
static SCALE_FACTOR: Cell<f64> = Cell::new(1.0);
|
||||||
static OFFSET_DIST: Cell<f64> = Cell::new(1.0);
|
static OFFSET_DIST: Cell<f64> = Cell::new(1.0);
|
||||||
|
|
@ -34,7 +33,13 @@ macro_rules! accessors {
|
||||||
}
|
}
|
||||||
|
|
||||||
accessors!(get_circle_radius, set_circle_radius, CIRCLE_RADIUS);
|
accessors!(get_circle_radius, set_circle_radius, CIRCLE_RADIUS);
|
||||||
accessors!(get_circle_diam, set_circle_diam, CIRCLE_DIAM);
|
pub fn get_circle_diam() -> f64 {
|
||||||
|
get_circle_radius() * 2.0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_circle_diam(value: f64) {
|
||||||
|
set_circle_radius(value * 0.5);
|
||||||
|
}
|
||||||
accessors!(get_rotate_angle, set_rotate_angle, ROTATE_ANGLE);
|
accessors!(get_rotate_angle, set_rotate_angle, ROTATE_ANGLE);
|
||||||
accessors!(get_scale_factor, set_scale_factor, SCALE_FACTOR);
|
accessors!(get_scale_factor, set_scale_factor, SCALE_FACTOR);
|
||||||
accessors!(get_offset_dist, set_offset_dist, OFFSET_DIST);
|
accessors!(get_offset_dist, set_offset_dist, OFFSET_DIST);
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,7 @@ pub struct CircleCommand {
|
||||||
enum StepCR {
|
enum StepCR {
|
||||||
Center,
|
Center,
|
||||||
Radius(DVec3),
|
Radius(DVec3),
|
||||||
|
Diameter(DVec3),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CircleCommand {
|
impl CircleCommand {
|
||||||
|
|
@ -186,6 +187,11 @@ impl CadCommand for CircleCommand {
|
||||||
)
|
)
|
||||||
.into_owned()
|
.into_owned()
|
||||||
}
|
}
|
||||||
|
StepCR::Diameter(_) => crate::tf!(
|
||||||
|
"CIRCLE Specify diameter <{:.4}>:",
|
||||||
|
self.default_r * 2.0
|
||||||
|
)
|
||||||
|
.into_owned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -196,15 +202,16 @@ impl CadCommand for CircleCommand {
|
||||||
CmdOption::new("3P", "3P"),
|
CmdOption::new("3P", "3P"),
|
||||||
CmdOption::new("2P", "2P"),
|
CmdOption::new("2P", "2P"),
|
||||||
CmdOption::new("Ttr", "TTR"),
|
CmdOption::new("Ttr", "TTR"),
|
||||||
CmdOption::new("Ttt", "TTT"),
|
],
|
||||||
|
StepCR::Radius(_) => vec![
|
||||||
CmdOption::new(t!("Diameter").as_ref(), "D"),
|
CmdOption::new(t!("Diameter").as_ref(), "D"),
|
||||||
],
|
],
|
||||||
StepCR::Radius(_) => vec![],
|
StepCR::Diameter(_) => vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn point_step_accepts_keywords(&self) -> bool {
|
fn point_step_accepts_keywords(&self) -> bool {
|
||||||
matches!(self.step, StepCR::Center)
|
!matches!(self.step, StepCR::Diameter(_))
|
||||||
}
|
}
|
||||||
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||||
match &self.step {
|
match &self.step {
|
||||||
|
|
@ -214,27 +221,49 @@ impl CadCommand for CircleCommand {
|
||||||
}
|
}
|
||||||
StepCR::Radius(c) => {
|
StepCR::Radius(c) => {
|
||||||
let r = plane_distance(*c, pt, self.plane);
|
let r = plane_distance(*c, pt, self.plane);
|
||||||
|
if r <= 1.0e-9 {
|
||||||
|
return CmdResult::NeedPoint;
|
||||||
|
}
|
||||||
defaults::set_circle_radius(r);
|
defaults::set_circle_radius(r);
|
||||||
CmdResult::CommitAndExit(make_circle(*c, r, self.plane))
|
CmdResult::CommitAndExit(make_circle(*c, r, self.plane))
|
||||||
}
|
}
|
||||||
|
StepCR::Diameter(c) => {
|
||||||
|
let radius = plane_distance(*c, pt, self.plane);
|
||||||
|
if radius <= 1.0e-9 {
|
||||||
|
return CmdResult::NeedPoint;
|
||||||
|
}
|
||||||
|
defaults::set_circle_radius(radius);
|
||||||
|
CmdResult::CommitAndExit(make_circle(*c, radius, self.plane))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn on_enter(&mut self) -> CmdResult {
|
fn on_enter(&mut self) -> CmdResult {
|
||||||
if let StepCR::Radius(c) = &self.step {
|
match self.step {
|
||||||
let c = *c;
|
StepCR::Radius(center) => {
|
||||||
let r = self.default_r;
|
CmdResult::CommitAndExit(make_circle(center, self.default_r, self.plane))
|
||||||
return CmdResult::CommitAndExit(make_circle(c, r, self.plane));
|
}
|
||||||
|
StepCR::Diameter(center) => {
|
||||||
|
CmdResult::CommitAndExit(make_circle(center, self.default_r, self.plane))
|
||||||
|
}
|
||||||
|
StepCR::Center => CmdResult::Cancel,
|
||||||
}
|
}
|
||||||
CmdResult::Cancel
|
|
||||||
}
|
}
|
||||||
fn on_escape(&mut self) -> CmdResult {
|
fn on_escape(&mut self) -> CmdResult {
|
||||||
CmdResult::Cancel
|
CmdResult::Cancel
|
||||||
}
|
}
|
||||||
fn on_mouse_move(&mut self, pt: DVec3) -> Option<WireModel> {
|
fn on_mouse_move(&mut self, pt: DVec3) -> Option<WireModel> {
|
||||||
if let StepCR::Radius(c) = &self.step {
|
match self.step {
|
||||||
Some(circle_wire(*c, plane_distance(*c, pt, self.plane), self.plane))
|
StepCR::Radius(center) => Some(circle_wire(
|
||||||
} else {
|
center,
|
||||||
None
|
plane_distance(center, pt, self.plane),
|
||||||
|
self.plane,
|
||||||
|
)),
|
||||||
|
StepCR::Diameter(center) => Some(circle_wire(
|
||||||
|
center,
|
||||||
|
plane_distance(center, pt, self.plane),
|
||||||
|
self.plane,
|
||||||
|
)),
|
||||||
|
StepCR::Center => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn on_text_input(&mut self, text: &str) -> Option<CmdResult> {
|
fn on_text_input(&mut self, text: &str) -> Option<CmdResult> {
|
||||||
|
|
@ -245,11 +274,15 @@ impl CadCommand for CircleCommand {
|
||||||
"3P" => Some(CmdResult::Dispatch("CIRCLE_3P".into())),
|
"3P" => Some(CmdResult::Dispatch("CIRCLE_3P".into())),
|
||||||
"2P" => Some(CmdResult::Dispatch("CIRCLE_2P".into())),
|
"2P" => Some(CmdResult::Dispatch("CIRCLE_2P".into())),
|
||||||
"T" | "TTR" => Some(CmdResult::Dispatch("CIRCLE_TTR".into())),
|
"T" | "TTR" => Some(CmdResult::Dispatch("CIRCLE_TTR".into())),
|
||||||
"TTT" => Some(CmdResult::Dispatch("CIRCLE_TTT".into())),
|
|
||||||
"D" | "DIAMETER" => Some(CmdResult::Dispatch("CIRCLE_CD".into())),
|
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if let StepCR::Radius(center) = &self.step {
|
||||||
|
if matches!(text.trim().to_uppercase().as_str(), "D" | "DIAMETER") {
|
||||||
|
self.step = StepCR::Diameter(*center);
|
||||||
|
return Some(CmdResult::NeedPoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
if let StepCR::Radius(c) = &self.step {
|
if let StepCR::Radius(c) = &self.step {
|
||||||
let r: f64 = text.trim().replace(',', ".").parse().ok()?;
|
let r: f64 = text.trim().replace(',', ".").parse().ok()?;
|
||||||
if r > 0.0 {
|
if r > 0.0 {
|
||||||
|
|
@ -257,12 +290,23 @@ impl CadCommand for CircleCommand {
|
||||||
return Some(CmdResult::CommitAndExit(make_circle(*c, r, self.plane)));
|
return Some(CmdResult::CommitAndExit(make_circle(*c, r, self.plane)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if let StepCR::Diameter(c) = &self.step {
|
||||||
|
let diameter: f64 = text.trim().replace(',', ".").parse().ok()?;
|
||||||
|
if diameter > 0.0 {
|
||||||
|
defaults::set_circle_diam(diameter);
|
||||||
|
return Some(CmdResult::CommitAndExit(make_circle(
|
||||||
|
*c,
|
||||||
|
diameter * 0.5,
|
||||||
|
self.plane,
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
fn dyn_field(&self) -> DynField {
|
fn dyn_field(&self) -> DynField {
|
||||||
match self.step {
|
match self.step {
|
||||||
StepCR::Center => DynField::Point,
|
StepCR::Center => DynField::Point,
|
||||||
StepCR::Radius(_) => DynField::Distance,
|
StepCR::Radius(_) | StepCR::Diameter(_) => DynField::Distance,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -279,6 +323,12 @@ impl CadCommand for CircleCommand {
|
||||||
guide: DynGuide::Radius,
|
guide: DynGuide::Radius,
|
||||||
ref_point: None,
|
ref_point: None,
|
||||||
}),
|
}),
|
||||||
|
StepCR::Diameter(c) => Some(DynSpec {
|
||||||
|
anchor: DynAnchor::Point(c),
|
||||||
|
fields: vec![DynFieldSpec::new(DynRole::Diameter)],
|
||||||
|
guide: DynGuide::Radius,
|
||||||
|
ref_point: None,
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -312,28 +362,33 @@ impl CadCommand for CircleCDCommand {
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
match &self.step {
|
match &self.step {
|
||||||
StepCR::Center => t!("CIRCLE CD Specify center point:").into_owned(),
|
StepCR::Center => t!("CIRCLE CD Specify center point:").into_owned(),
|
||||||
StepCR::Radius(c) => crate::tf!(
|
StepCR::Diameter(c) => crate::tf!(
|
||||||
"CIRCLE CD Specify diameter or type value <{:.4}> [center ({:.3},{:.3})]:",
|
"CIRCLE CD Specify diameter or type value <{:.4}> [center ({:.3},{:.3})]:",
|
||||||
self.default_d, c.x, c.y
|
self.default_d, c.x, c.y
|
||||||
)
|
)
|
||||||
.into_owned(),
|
.into_owned(),
|
||||||
|
StepCR::Radius(_) => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||||
match &self.step {
|
match &self.step {
|
||||||
StepCR::Center => {
|
StepCR::Center => {
|
||||||
self.step = StepCR::Radius(pt);
|
self.step = StepCR::Diameter(pt);
|
||||||
CmdResult::NeedPoint
|
CmdResult::NeedPoint
|
||||||
}
|
}
|
||||||
StepCR::Radius(c) => {
|
StepCR::Diameter(c) => {
|
||||||
let d = plane_distance(*c, pt, self.plane) * 2.0;
|
let radius = plane_distance(*c, pt, self.plane);
|
||||||
defaults::set_circle_diam(d);
|
if radius <= 1.0e-9 {
|
||||||
CmdResult::CommitAndExit(make_circle(*c, d / 2.0, self.plane))
|
return CmdResult::NeedPoint;
|
||||||
|
}
|
||||||
|
defaults::set_circle_radius(radius);
|
||||||
|
CmdResult::CommitAndExit(make_circle(*c, radius, self.plane))
|
||||||
}
|
}
|
||||||
|
StepCR::Radius(_) => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn on_enter(&mut self) -> CmdResult {
|
fn on_enter(&mut self) -> CmdResult {
|
||||||
if let StepCR::Radius(c) = &self.step {
|
if let StepCR::Diameter(c) = &self.step {
|
||||||
let c = *c;
|
let c = *c;
|
||||||
let d = self.default_d;
|
let d = self.default_d;
|
||||||
return CmdResult::CommitAndExit(make_circle(c, d / 2.0, self.plane));
|
return CmdResult::CommitAndExit(make_circle(c, d / 2.0, self.plane));
|
||||||
|
|
@ -344,15 +399,18 @@ impl CadCommand for CircleCDCommand {
|
||||||
CmdResult::Cancel
|
CmdResult::Cancel
|
||||||
}
|
}
|
||||||
fn on_mouse_move(&mut self, pt: DVec3) -> Option<WireModel> {
|
fn on_mouse_move(&mut self, pt: DVec3) -> Option<WireModel> {
|
||||||
// Preview radius = distance to cursor; on commit that distance becomes the radius (diameter = 2x).
|
if let StepCR::Diameter(c) = &self.step {
|
||||||
if let StepCR::Radius(c) = &self.step {
|
Some(circle_wire(
|
||||||
Some(circle_wire(*c, plane_distance(*c, pt, self.plane), self.plane))
|
*c,
|
||||||
|
plane_distance(*c, pt, self.plane),
|
||||||
|
self.plane,
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn on_text_input(&mut self, text: &str) -> Option<CmdResult> {
|
fn on_text_input(&mut self, text: &str) -> Option<CmdResult> {
|
||||||
if let StepCR::Radius(c) = &self.step {
|
if let StepCR::Diameter(c) = &self.step {
|
||||||
let d: f64 = text.trim().replace(',', ".").parse().ok()?;
|
let d: f64 = text.trim().replace(',', ".").parse().ok()?;
|
||||||
if d > 0.0 {
|
if d > 0.0 {
|
||||||
defaults::set_circle_diam(d);
|
defaults::set_circle_diam(d);
|
||||||
|
|
@ -368,12 +426,13 @@ impl CadCommand for CircleCDCommand {
|
||||||
StepCR::Center => None,
|
StepCR::Center => None,
|
||||||
// Diameter: the box shows/accepts twice the cursor radius; resolved
|
// Diameter: the box shows/accepts twice the cursor radius; resolved
|
||||||
// back to a radius point by the host (role scaling).
|
// back to a radius point by the host (role scaling).
|
||||||
StepCR::Radius(c) => Some(DynSpec {
|
StepCR::Diameter(c) => Some(DynSpec {
|
||||||
anchor: DynAnchor::Point(c),
|
anchor: DynAnchor::Point(c),
|
||||||
fields: vec![DynFieldSpec::new(DynRole::Diameter)],
|
fields: vec![DynFieldSpec::new(DynRole::Diameter)],
|
||||||
guide: DynGuide::Radius,
|
guide: DynGuide::Radius,
|
||||||
ref_point: None,
|
ref_point: None,
|
||||||
}),
|
}),
|
||||||
|
StepCR::Radius(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -418,6 +477,10 @@ impl CadCommand for Circle2PCommand {
|
||||||
Some(p1) => {
|
Some(p1) => {
|
||||||
let center = (p1 + pt) * 0.5;
|
let center = (p1 + pt) * 0.5;
|
||||||
let radius = plane_distance(p1, pt, self.plane) / 2.0;
|
let radius = plane_distance(p1, pt, self.plane) / 2.0;
|
||||||
|
if radius <= 1.0e-9 {
|
||||||
|
return CmdResult::NeedPoint;
|
||||||
|
}
|
||||||
|
defaults::set_circle_radius(radius);
|
||||||
CmdResult::CommitAndExit(make_circle(center, radius, self.plane))
|
CmdResult::CommitAndExit(make_circle(center, radius, self.plane))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue