Commit Graph
13 Commits
Author SHA1 Message Date
kevin9327andClaude Opus 5 743a25b76a fix(plot-style): keep custom lineweights at full precision when saving
Saving a plot style table wrote every value of its custom lineweight table
with two decimals, so a pen such as 0.035 mm came back as 0.04 mm after a
save and reload, and every color using it plotted with the wrong weight.

Write the lineweights in full, through the same formatting the scale factor
already uses, which keeps the decimal point on a whole value.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 07:09:27 +09:00
kevin9327andClaude Opus 5 c13e86b87d fix(dimension): draw linear and aligned dimensions in their own plane off world Z
A linear or aligned dimension whose normal is not world Z was drawn and
exploded as if it lay in world XY. The builders read the offset and the
extension directions in XY only, so a dimension turned into a working plane
such as XZ lost its offset (now along Z): the dimension line fell onto the
measured points and the extension lines stuck out along world Y.

Move such a dimension into its own OCS before building it and map the result
back onto its plane, as arc length and large radial dimensions already do,
for both tessellation and EXPLODE.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 07:00:47 +09:00
kevin9327andClaude Opus 5 85e942bdd2 fix(step): keep the own plane of small triangles
The vertex-normal fallback compared the cross product's length with
f64::EPSILON, an area-scale threshold, so a valid triangle small enough
fell back to the leaning vertex normal again. Fall back only when the
cross product is zero.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 20:45:11 +09:00
kevin9327andClaude Opus 5 d77a3bd774 fix(stl): keep the own normal of small facets
The vertex-normal fallback compared the cross product's length with
f32::EPSILON, an area-scale threshold, so a valid facet with 1e-4 edges
(cross product 1e-8) took the leaning vertex normal again. Fall back only
when the cross product is zero.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 20:37:49 +09:00
kevin9327andClaude Opus 5 762705f4a4 fix(plot-style): keep the full scale factor when saving a plot style table
PlotStyleTable::to_text wrote scale_factor with one decimal, and saving
from the plot style panel rewrites the whole loaded table. A table with
apply_factor on and scale_factor=0.25 came back as 0.2, thinning every
scaled lineweight by a fifth.

Write the factor in full, keeping the decimal point on a whole value.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 20:29:03 +09:00
kevin9327andClaude Opus 5 96a54b809c fix(linetypes): load .lin definitions whose header has no description
In a .lin file the description is optional and the comma goes with it, so
"*PLAIN" followed by "A,.5,-.25" is a complete definition. parse only kept
a header that contained a comma, so such a linetype was dropped silently
and a CENTERLTYPE naming it then reported that it was not loaded.

Take the whole header as the name when there is no comma.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 20:19:20 +09:00
kevin9327andClaude Opus 5 6219af60ed fix(stl): write each facet's own normal
build_stl took the facet normal from the first vertex's normal whenever the
mesh had normals. On smoothed meshes (tessellated curved solids, OBJ imports
with vn) that normal leans off the triangle, while STL defines the facet
normal as the triangle's own unit normal.

Use the triangle's own normal, and keep the vertex normal only for a
triangle with no area. Meshes without normals export as before.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 20:11:30 +09:00
kevin9327andClaude Opus 5 bc3e63ff53 fix(step): place each exported face on its triangle's own plane
build_step took the PLANE normal from the first vertex's normal whenever
the mesh had normals. On smoothed meshes (tessellated curved solids, OBJ
imports with vn) that normal leans off the triangle, so the plane missed
two of the face's corners and the first edge was no longer perpendicular
to the placement axis.

Use the triangle's own normal, and keep the vertex normal only for a
triangle with no area. Meshes without normals export as before.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 20:04:00 +09:00
kevin9327andClaude Opus 5 23cd448c7f fix(dimension): rotate and mirror dimensions in working planes off world Z
With a working plane other than world XY, ROTATE and MIRROR handed a
non-ordinate dimension to acadrust's Entity::apply_transform, which only
translates those dimension types by where the transform sends the origin.
The definition points, plane and angles stayed unturned, so the dimension
jumped back once its block was baked again.

Send both through the existing Affine branch, which ALIGN already uses and
which transforms points, normal and stored angles together. The world-Z
paths are unchanged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 19:52:20 +09:00
kevin9327andClaude Opus 5 d6a6b26675 fix(step): export mesh vertices with their low residual at large coordinates
Scene meshes store each position as an f32 half plus a low residual so
geometry stays precise at survey coordinates, and the renderer adds the
two back together. STEP export read only the f32 half. Near x = 500000
that half steps in 1/32 units, so a solid at 500000.123 was written as
500000.125, and the edge directions and planes were built from the same
snapped points.

Build each exported vertex from both halves in f64 and derive directions
and the fallback face normal from those. Meshes without a residual export
as before.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 08:59:58 +09:00
kevin9327andClaude Opus 5 977cdd4888 fix(obj): give faces without usable normals their face normal on import
IMPORTOBJ only computed face normals when the file listed no normals at
all. When a file did list some, a face that omitted its normal indices,
or pointed at an index past the end of the list, kept a zero normal. That
zero reaches the mesh shader, which normalizes it for lighting.

Track which vertices got a normal from the file and give the rest their
face normal. Supplied normals are kept, and a file without normals is
handled as before.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 08:51:03 +09:00
kevin9327andClaude Opus 5 19a0ac79ab fix(units): drop the minus sign from lengths and angles that round to zero
Rotating geometry leaves float noise in coordinates: turning the point
(0, 10) by 180 degrees gives X = -1.2246e-15. Rust formats that as
"-0.0000", so Properties showed "-0.0000" (or -0", -0d0'0", -0g) for a
value that is zero at the drawing's precision.

format_length and format_angle now drop the sign when every printed digit
is zero. Values that still show a digit keep it, and scientific notation
is unaffected.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 08:40:20 +09:00
kevin9327andClaude Opus 5 019447d9b5 fix(dimension): keep the linear measurement axis through ROTATE and MIRROR
ROTATE and MIRROR in the drawing plane moved a linear dimension's points
but left its stored rotation (the axis it measures along) unchanged. A
horizontal dimension rotated 90 degrees then measured its now-vertical
points along X and its value dropped to 0; mirroring about a slanted line
did the same. Polar ARRAY goes through the same path.

Turn the axis by the rotation angle, and reflect it about the mirror line.
A zero-length mirror line still leaves the dimension untouched.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 08:29:31 +09:00