forked from 1b-agent/opencadstudio-upstream
fix(dimension): plain value for DIMLIM without offsets, stored angle for degenerate angular text
A limits style whose upper and lower offsets are both zero prints the plain value in AutoCAD, not a stack of two equal numbers. A three-point angular dimension whose extension point sits on its vertex has no measurable angle; AutoCAD keeps showing the angle it stored, and the text now does too instead of reading 0 degrees. Both cases came out of comparing saved picture blocks with regenerated text across a set of production drawings.
This commit is contained in:
1 parent
1474376924
commit
a30db2d4f3
1 file changed
+61
-11
+61
-11
@@ -6179,8 +6179,8 @@ fn dimension_text_parts(
|
|||||||
// lower one and no nominal, so the tolerance slot stays empty.
|
// lower one and no nominal, so the tolerance slot stays empty.
|
||||||
let value = match limits_text(dim, style, is_angular) {
|
let value = match limits_text(dim, style, is_angular) {
|
||||||
Some(limits) => limits,
|
Some(limits) => limits,
|
||||||
None if is_angular => format_angular_value(dim.measurement(), style),
|
None if is_angular => format_angular_value(display_measurement(dim), style),
|
||||||
None => format_linear_value(dim.measurement(), style),
|
None => format_linear_value(display_measurement(dim), style),
|
||||||
};
|
};
|
||||||
let primary_raw = match dim {
|
let primary_raw = match dim {
|
||||||
Dimension::Radius(_) | Dimension::LargeRadial(_) => format!("R{}", value),
|
Dimension::Radius(_) | Dimension::LargeRadial(_) => format!("R{}", value),
|
||||||
@@ -6217,11 +6217,29 @@ fn dimension_text_parts(
|
|||||||
Some((primary, tolerance_suffix))
|
Some((primary, tolerance_suffix))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The value the text reports. An angular dimension whose extension point
|
||||||
|
/// sits on its vertex has no measurable angle; AutoCAD then keeps showing the
|
||||||
|
/// angle it stored (group 42, radians) rather than 0°, and so do we.
|
||||||
|
fn display_measurement(dim: &Dimension) -> f64 {
|
||||||
|
let measured = dim.measurement();
|
||||||
|
let stored = dim.base().actual_measurement;
|
||||||
|
match dim {
|
||||||
|
Dimension::Angular2Ln(_) | Dimension::Angular3Pt(_)
|
||||||
|
if measured.abs() < 1e-9 && stored.abs() > 1e-9 =>
|
||||||
|
{
|
||||||
|
stored.to_degrees()
|
||||||
|
}
|
||||||
|
_ => measured,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// DIMLIM: the upper limit stacked over the lower one, replacing the nominal.
|
/// DIMLIM: the upper limit stacked over the lower one, replacing the nominal.
|
||||||
/// The offsets apply to the displayed number, so DIMLFAC and DIMRND come first.
|
/// The offsets apply to the displayed number, so DIMLFAC and DIMRND come first.
|
||||||
fn limits_text(dim: &Dimension, style: Option<&DimStyle>, is_angular: bool) -> Option<String> {
|
fn limits_text(dim: &Dimension, style: Option<&DimStyle>, is_angular: bool) -> Option<String> {
|
||||||
let s = style.filter(|s| s.dimlim)?;
|
// With both offsets zero AutoCAD prints the plain value, not a stack of
|
||||||
let measurement = dim.measurement();
|
// two equal numbers.
|
||||||
|
let s = style.filter(|s| s.dimlim && (s.dimtp.abs() > 1e-12 || s.dimtm.abs() > 1e-12))?;
|
||||||
|
let measurement = display_measurement(dim);
|
||||||
if is_angular {
|
if is_angular {
|
||||||
return Some(format!(
|
return Some(format!(
|
||||||
"\\S{}^{};",
|
"\\S{}^{};",
|
||||||
@@ -8058,12 +8076,6 @@ mod limits_format_tests {
|
|||||||
dimension_text_parts(&horizontal(), Some(&s)),
|
dimension_text_parts(&horizontal(), Some(&s)),
|
||||||
Some((r"\S10.02^9.92;".to_string(), None))
|
Some((r"\S10.02^9.92;".to_string(), None))
|
||||||
);
|
);
|
||||||
s.dimtp = 0.0;
|
|
||||||
s.dimtm = 0.0;
|
|
||||||
assert_eq!(
|
|
||||||
dimension_text_parts(&horizontal(), Some(&s)),
|
|
||||||
Some((r"\S10^10;".to_string(), None))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The offsets apply to the number the reader sees, which for a paper
|
// The offsets apply to the number the reader sees, which for a paper
|
||||||
@@ -8078,11 +8090,24 @@ mod limits_format_tests {
|
|||||||
Some((r"\S75.020^74.950;".to_string(), None))
|
Some((r"\S75.020^74.950;".to_string(), None))
|
||||||
);
|
);
|
||||||
s.dimrnd = 0.5;
|
s.dimrnd = 0.5;
|
||||||
|
s.dimtm = 0.0;
|
||||||
|
assert_eq!(
|
||||||
|
dimension_text_parts(&horizontal(), Some(&s)),
|
||||||
|
Some((r"\S75.020^75.000;".to_string(), None))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// DIMLIM with both offsets at zero is a plain value in AutoCAD, not a
|
||||||
|
// stack of two equal numbers.
|
||||||
|
#[test]
|
||||||
|
fn limits_without_offsets_show_the_plain_value() {
|
||||||
|
let mut s = style();
|
||||||
|
s.dimlim = true;
|
||||||
s.dimtp = 0.0;
|
s.dimtp = 0.0;
|
||||||
s.dimtm = 0.0;
|
s.dimtm = 0.0;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dimension_text_parts(&horizontal(), Some(&s)),
|
dimension_text_parts(&horizontal(), Some(&s)),
|
||||||
Some((r"\S75.000^75.000;".to_string(), None))
|
Some(("10.000".to_string(), None))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8135,6 +8160,31 @@ mod limits_format_tests {
|
|||||||
assert_eq!(text_cells(r"\S10.020^9.950; REF", 1.0), 6.0 + 4.0);
|
assert_eq!(text_cells(r"\S10.020^9.950; REF", 1.0), 6.0 + 4.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A three-point angular dimension whose first extension point coincides
|
||||||
|
// with the vertex measures nothing; the stored angle keeps the text.
|
||||||
|
#[test]
|
||||||
|
fn degenerate_angular_dimension_reports_its_stored_angle() {
|
||||||
|
use acadrust::entities::DimensionAngular3Pt;
|
||||||
|
let mut d = DimensionAngular3Pt::default();
|
||||||
|
d.angle_vertex = Vector3::new(6.0, 4.85, 0.0);
|
||||||
|
d.first_point = d.angle_vertex;
|
||||||
|
d.second_point = Vector3::new(7.0, 4.85, 0.0);
|
||||||
|
d.definition_point = Vector3::new(8.0, 5.4, 0.0);
|
||||||
|
d.base.actual_measurement = std::f64::consts::FRAC_PI_4;
|
||||||
|
let dim = Dimension::Angular3Pt(d);
|
||||||
|
let mut s = style();
|
||||||
|
s.dimadec = 0;
|
||||||
|
assert_eq!(
|
||||||
|
dimension_text_parts(&dim, Some(&s)),
|
||||||
|
Some(("45°".to_string(), None))
|
||||||
|
);
|
||||||
|
s.dimlim = true;
|
||||||
|
s.dimtp = 0.1;
|
||||||
|
s.dimtm = 0.1;
|
||||||
|
let (value, _) = dimension_text_parts(&dim, Some(&s)).unwrap();
|
||||||
|
assert!(value.starts_with(r"\S45"), "{value}");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn a_limits_stack_is_two_halves_tall() {
|
fn a_limits_stack_is_two_halves_tall() {
|
||||||
let mut s = style();
|
let mut s = style();
|
||||||
|
|||||||
Reference in new issue
Block a user