mirror of
https://github.com/storytold/cadcraft.git
synced 2026-10-26 20:06:50 -06:00
Tolerances and alternate units copied the primary number format, so they were
rounded by DIMRND and took DIMZIN's zero suppression: DIMRND 0.5 turned a
±0.1 tolerance into ±0.0000, and 10.3 in showed as [261.50] mm. Tolerances are
no longer rounded and use DIMTZIN. Alternate units use the new DIMALTRND
(rounding), DIMALTU (unit format) and DIMALTZ (zero suppression). The new
variables can be set with SETVAR, DIMSTYLE and overrides. A DXF keeps them as
DIMSTYLE group codes 148, 273, 284 and 285.
DIMPOST is a prefix/suffix for linear dimensions, so angular dimensions no
longer get it ("90°mm"). A text override still wraps the angle.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
74 lines
3.2 KiB
Rust
74 lines
3.2 KiB
Rust
//! Dimension text formatting (issue #373): DIMRND rounds the measurement only, tolerances use
|
|
//! DIMTZIN, alternate units DIMALTRND/DIMALTU/DIMALTZ, and DIMPOST is not added to angles.
|
|
|
|
use cadcraft_doc::{DimKind, DimStyle, Dimension};
|
|
use cadcraft_geom::Vec3;
|
|
use cadcraft_render::dimension_geometry;
|
|
|
|
fn linear(len: f64) -> Dimension {
|
|
Dimension {
|
|
kind: DimKind::Linear { rotation: 0.0 },
|
|
defpt: Vec3::new(0.0, 5.0, 0.0),
|
|
text_mid: Vec3::ZERO,
|
|
p13: Vec3::ZERO,
|
|
p14: Vec3::new(len, 0.0, 0.0),
|
|
p15: Vec3::ZERO,
|
|
p16: Vec3::ZERO,
|
|
text: String::new(),
|
|
style: "Standard".into(),
|
|
measurement: 0.0,
|
|
text_rotation: 0.0,
|
|
user_text_pos: false,
|
|
block: None,
|
|
overrides: Default::default(),
|
|
assoc: Vec::new(),
|
|
}
|
|
}
|
|
|
|
fn text(d: &Dimension, vars: serde_json::Value) -> String {
|
|
let mut st = DimStyle::default();
|
|
let rejected = st.apply_fields(vars.as_object().unwrap());
|
|
assert!(rejected.is_empty(), "unknown variables {rejected:?}");
|
|
dimension_geometry(d, &st, 1.0).value
|
|
}
|
|
|
|
#[test]
|
|
fn dimrnd_rounds_neither_tolerances_nor_alternate_units() {
|
|
let d = linear(10.3);
|
|
let tol = serde_json::json!({"DIMRND": 0.5, "DIMDEC": 2, "DIMTOL": 1, "DIMTP": 0.1, "DIMTM": 0.1, "DIMTDEC": 2});
|
|
assert_eq!(text(&d, tol), "10.50±0.10");
|
|
let dev = serde_json::json!({"DIMRND": 0.5, "DIMDEC": 2, "DIMTOL": 1, "DIMTP": 0.1, "DIMTM": 0.2, "DIMTDEC": 2});
|
|
assert_eq!(text(&d, dev), "10.50+0.10/-0.20");
|
|
// Tolerance zeros follow DIMTZIN, not DIMZIN.
|
|
let tzin = serde_json::json!({"DIMZIN": 8, "DIMDEC": 2, "DIMTOL": 1, "DIMTP": 0.1, "DIMTM": 0.1, "DIMTDEC": 2});
|
|
assert_eq!(text(&d, tzin.clone()), "10.3±0.10");
|
|
let mut tzin8 = tzin;
|
|
tzin8["DIMTZIN"] = 8.into();
|
|
assert_eq!(text(&d, tzin8), "10.3±0.1");
|
|
|
|
// 10.3 in = 261.62 mm: DIMRND 0.5 rounds the primary value only.
|
|
assert_eq!(text(&d, serde_json::json!({"DIMRND": 0.5, "DIMDEC": 1, "DIMALT": 1})), "10.5 [261.62]");
|
|
// DIMALTRND rounds the alternate value.
|
|
assert_eq!(text(&d, serde_json::json!({"DIMDEC": 1, "DIMALT": 1, "DIMALTRND": 0.5})), "10.3 [261.50]");
|
|
// DIMALTZ, not DIMZIN, suppresses alternate zeros.
|
|
assert_eq!(text(&linear(10.0), serde_json::json!({"DIMZIN": 8, "DIMALT": 1})), "10 [254.00]");
|
|
assert_eq!(text(&linear(10.0), serde_json::json!({"DIMALT": 1, "DIMALTZ": 8})), "10.0000 [254]");
|
|
// DIMALTU: alternate units in their own format (7 = fractional, not stacked).
|
|
assert_eq!(text(&linear(2.0), serde_json::json!({"DIMALT": 1, "DIMALTF": 0.25, "DIMALTU": 7, "DIMALTD": 2})), "2.0000 [1/2]");
|
|
}
|
|
|
|
#[test]
|
|
fn dimpost_is_not_added_to_angular_dimensions() {
|
|
let mut a = linear(0.0);
|
|
a.kind = DimKind::Angular3P;
|
|
a.p15 = Vec3::ZERO;
|
|
a.p13 = Vec3::new(10.0, 0.0, 0.0);
|
|
a.p14 = Vec3::new(0.0, 10.0, 0.0);
|
|
a.defpt = Vec3::new(3.0, 3.0, 0.0);
|
|
assert_eq!(text(&a, serde_json::json!({"DIMPOST": "<>mm"})), "90°");
|
|
// Linear dimensions keep it, and an angular text override still wraps the angle.
|
|
assert_eq!(text(&linear(10.0), serde_json::json!({"DIMPOST": "<>mm", "DIMDEC": 1})), "10.0mm");
|
|
a.text = "<> TYP".into();
|
|
assert_eq!(text(&a, serde_json::json!({"DIMPOST": "<>mm"})), "90° TYP");
|
|
}
|