Use viewport snap frame and accepted snaps for dimension measurement

Removes PR2's two seams now that PR1 (viewport snapping) is underneath.

* `Scene::viewport_frame` is PR1's camera-derived implementation. The
  viewport-record version is gone; PR1's returns `None` for oblique /
  perspective viewports, which is what we want — every entry point in
  `viewport_dim_seam` then declines rather than guessing a planar
  mapping. `viewport_dim_seam` is now just the dimension object-pick
  path, and its module doc says so.

* There is one accepted-snap store: PR1's `OpenCADStudio::accepted_snaps`.
  PR2's parallel `dim_accepted_snaps` (and its command-name ownership
  tracking, which PR1's clear-on-command-start/end already does) is
  deleted, along with the `record_dimension_accepted_snap` seam.
  `accepted_snap_for_point` reads PR1's list.

  Two things layer on top:
  - the explicit object pick is not a point step, so it still records its
    own snaps, now through `push_accepted_snap` into PR1's list, and now
    carrying the picked entity handle + block path as a `SnapSourceRef`
    so PR3 can associate it;
  - a typed coordinate carries no snap, so `measure_snap` re-attaches the
    content viewport under a snap that is free *and* source-less. That
    keeps `DIMLINEAR` with typed coordinates inside a 1:10 viewport
    measuring the model, without ever reinterpreting a real paper-sheet
    snap that happens to sit over a viewport.

* One association gate, not two. `dimension_association_allowed` is the
  single predicate, derived from the same `dimension_measure_space`
  classification that decides whether to compensate the measurement, so
  the two can never disagree. `infer_dimension_sources_guarded` delegates
  to it, and the commit path's "commit unassociated when measured through
  a viewport" condition is now that predicate rather than a second,
  independently-computed bool. It also covers the explicit-pick and
  explicit-source-list branches, which the old inference-only guard did
  not. Because the classification ignores the trailing dimension-line
  placement click, an ordinary paper dimension whose placement click lands
  inside a viewport rectangle keeps its association.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Christopher OverbeckandClaude Fable 5.1 committed 2026-09-15 12:45:59 -05:00
1 parent 848f789018
commit 43dea41498
5 files changed
+170 -177

No files matched your search

+1 -9
View File
@@ -9,7 +9,7 @@ pub(crate) mod config;
pub use automation::{export_headless, serve};
mod command_driver;
pub(crate) mod commands;
mod dim_viewport;
pub(crate) mod dim_viewport;
mod document;
mod drafting_settings;
pub(crate) mod expr_eval;
@@ -509,12 +509,6 @@ pub(super) struct OpenCADStudio {
cursor_size: i32,
/// Selection-box size setting (PICKBOX, 0..=50).
pick_box: i32,
/// PR2: accepted snaps for the points the active dimension command has
/// collected, in collection order. Transient command state — the committed
/// result is an ordinary dimension entity, so undo/redo needs nothing here.
pub(crate) dim_accepted_snaps: Vec<crate::scene::viewport_ref::AcceptedSnap>,
/// Name of the command `dim_accepted_snaps` belongs to.
pub(crate) dim_accepted_snaps_owner: Option<String>,
/// Use REFEDIT rather than BEDIT when double-clicking an attribute-free block.
double_click_block_refedit: bool,
/// Open ATTEDIT when double-clicking a block with attributes.
@@ -3641,8 +3635,6 @@ impl OpenCADStudio {
zoom_factor: 60,
cursor_size: 5,
pick_box: 3,
dim_accepted_snaps: Vec::new(),
dim_accepted_snaps_owner: None,
double_click_block_refedit: false,
double_click_block_attedit: true,
grip_object_limit: settings::DEFAULT_GRIP_OBJECT_LIMIT,