feat(ucs): orient text-bearing annotations to the active UCS

New annotations now place their text and reading geometry along the
active UCS X axis (identity = world), so they read square to the user's
coordinate system instead of world-horizontal:

- TEXT / MTEXT: rotation defaults to the UCS X angle
  (DocumentTab::ucs_rotation_angle, model space only).
- Linear dimensions: measure along the UCS axis the span is nearest, and
  bake the UCS X angle as the text rotation so the value reads square
  even under a style that forces horizontal text. DIMCONTINUE / DIMBASELINE
  derive their axis from the base dim's rotation (any angle), not a
  world H/V test.
- LEADER: the MText annotation rotates to the UCS, and the hookline runs
  along the leader's horizontal_direction (set to UCS X), used by the
  renderer instead of world horizontal.
- MLEADER: context.text_direction = UCS X drives both the text rotation
  and, in the renderer, the text side and dogleg/landing direction.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Hakan SevenandClaude Opus 4.8 committed 2026-06-22 18:18:35 +03:00
1 parent 0c2a97e17e
commit 33314a5889
10 files changed
+160 -73

No files matched your search

+3 -5
View File
@@ -71,11 +71,9 @@ impl DimBaselineCommand {
rotation: f64,
dimdli: f32,
) -> Self {
let axis = if rotation.abs() < 0.1 {
Vec3::X
} else {
Vec3::Y
};
// Measurement axis = the base dim's rotation angle (any angle, incl. a
// UCS-aligned one), not a world horizontal/vertical.
let axis = Vec3::new(rotation.cos() as f32, rotation.sin() as f32, 0.0);
let perp = Vec3::new(-axis.y, axis.x, 0.0);
let base_offset = (definition_point - p1).dot(perp);
let dimdli = if dimdli.abs() < 1e-6 {