fix(dimension): render diameter text and shrink point markers (#139)

Two issues in a file whose dimensions carry baked *D### blocks.

Missing diameter text: the baked MText values are "\U+220520" /
"\U+220510" — the \U+2205 (⌀) escape immediately followed by the literal
digits "20"/"10". The MText parser read up to six hex digits for a \U+
escape, so it greedily consumed "220520" = 0x220520, which is past the
maximum code point, char::from_u32 returned None, and the whole text
dropped. A \U+ escape is exactly four hex digits; read four so the symbol
decodes and the trailing digits stay literal. (Angular "90\U+00B0" only
worked because its escape sits at the end of the string.)

Node artifacts: PDMODE=0 points were drawn as a fixed 0.1-world-unit "+",
which in a small drawing turned the 31 dimension def-points on the
Defpoints layer into visible crosses. Size the dot from world-per-pixel
(~1 px, zoom-adaptive via the tessellation cache key) to match the near-
invisible dot other CAD apps draw.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Hakan Seven 2026-06-25 18:22:35 +03:00
commit 7086a79c79
2 changed files with 18 additions and 3 deletions

View file

@ -515,8 +515,14 @@ pub fn parse_mtext_paragraphs_ex(
chars.next();
if chars.peek() == Some(&'+') {
chars.next();
let mut hex = String::with_capacity(6);
for _ in 0..6 {
// A `\U+XXXX` escape is exactly four hex digits (a BMP
// code point). Reading more greedily swallows the
// following literal characters — e.g. the diameter
// value `\U+220520` ("⌀20") was parsed as code point
// 0x220520, which is out of range, so the whole text
// vanished. (#139)
let mut hex = String::with_capacity(4);
for _ in 0..4 {
match chars.peek() {
Some(&c) if c.is_ascii_hexdigit() => {
hex.push(chars.next().unwrap());

View file

@ -286,7 +286,16 @@ pub fn tessellate(
let result = tessellate_vertex(&v);
match result {
TruckTessResult::Point([x, y, z], [xl, yl, zl]) => {
let s = 0.1_f32;
// A PDMODE=0 point is a single dot. Size its marker to
// ~1 px so it reads as a dot rather than a large
// world-space "+" in small drawings — otherwise the
// dimension def-points on the Defpoints layer litter
// the view with crosses. The tessellation cache keys on
// world-per-pixel, so this re-sizes on zoom and stays a
// constant on-screen size. (#139)
let s = world_per_pixel
.map(|w| (w * 0.75).max(1e-6))
.unwrap_or(0.1);
let snap_pts = te.snap_pts;
let key_vertices: Vec<[f64; 3]> = te
.key_vertices