forked from 1b-agent/opencadstudio-upstream
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 <[email protected]>
This commit is contained in:
1 parent
848f789018
commit
43dea41498
5 files changed
+170
-177
No files matched your search
@@ -46,43 +46,51 @@ impl OpenCADStudio {
|
||||
self.accepted_snaps.last()
|
||||
}
|
||||
|
||||
/// `true` when any point the active command collected came through a
|
||||
/// layout viewport. Dimension association inference (which compares a
|
||||
/// dimension's own definition points against geometry in the *current*
|
||||
/// space) must not run in that case: the definition points are paper
|
||||
/// coordinates that correspond to no paper-sheet geometry, and the model
|
||||
/// geometry they really describe lives at completely different
|
||||
/// coordinates. PR3 replaces this guard with real viewport-aware
|
||||
/// associations built from `AcceptedSnap::source`.
|
||||
pub(crate) fn accepted_snaps_through_viewport(&self) -> bool {
|
||||
self.accepted_snaps.iter().any(AcceptedSnap::through_viewport)
|
||||
}
|
||||
|
||||
/// `Scene::infer_dimension_sources`, suppressed when the dimension's points
|
||||
/// were picked through a layout viewport (PR1).
|
||||
/// `Scene::infer_dimension_sources`, suppressed when the dimension being
|
||||
/// created measures through a layout viewport.
|
||||
///
|
||||
/// Inference works by looking for geometry near the dimension's own
|
||||
/// definition points, in whatever space it is handed. A paper-space
|
||||
/// dimension measured through a viewport has PAPER definition points that
|
||||
/// happen to sit over projected model geometry, so unguarded inference
|
||||
/// would either associate it with unrelated paper-sheet geometry at those
|
||||
/// coordinates, or match model geometry using paper coordinates. Neither is
|
||||
/// correct, and a wrong association is worse than none. Returning an empty
|
||||
/// source list makes `attach_dimension_association` a no-op.
|
||||
/// coordinates, or match model geometry using paper coordinates. Neither
|
||||
/// is correct, and a wrong association is worse than none. Returning an
|
||||
/// empty source list makes `attach_dimension_association` a no-op.
|
||||
///
|
||||
/// Deliberately minimal: PR3 replaces this with a real viewport-aware
|
||||
/// association built from `AcceptedSnap::source`.
|
||||
/// The classification is
|
||||
/// [`OpenCADStudio::dimension_measure_space`] — the *same* one that
|
||||
/// decides whether to compensate the measurement, so the two can never
|
||||
/// disagree. In particular it ignores the trailing dimension-line
|
||||
/// placement click, which routinely lands inside a viewport rectangle for
|
||||
/// an ordinary paper-space dimension and must not suppress its
|
||||
/// association.
|
||||
pub(crate) fn infer_dimension_sources_guarded(
|
||||
&self,
|
||||
tab: usize,
|
||||
dimension: Handle,
|
||||
) -> Vec<Option<Handle>> {
|
||||
if self.accepted_snaps_through_viewport() {
|
||||
if !self.dimension_association_allowed(tab) {
|
||||
return Vec::new();
|
||||
}
|
||||
self.tabs[tab].scene.infer_dimension_sources(dimension)
|
||||
}
|
||||
|
||||
/// The single gate on creating a paper-space association for the
|
||||
/// dimension the active command is committing.
|
||||
///
|
||||
/// `false` exactly when the dimension measures through (or partly through)
|
||||
/// a layout viewport, whatever supplied its sources — inference,
|
||||
/// an explicit object pick, or an explicit source list. Everything in the
|
||||
/// commit path that used to decide this for itself now asks here, so the
|
||||
/// measurement rule and the association rule cannot drift apart.
|
||||
pub(crate) fn dimension_association_allowed(&self, tab: usize) -> bool {
|
||||
matches!(
|
||||
self.dimension_measure_space(tab),
|
||||
crate::app::dim_viewport::DimensionMeasureSpace::Direct
|
||||
)
|
||||
}
|
||||
|
||||
/// Forget the accepted snaps of a finished / abandoned command.
|
||||
pub(crate) fn clear_accepted_snaps(&mut self) {
|
||||
self.accepted_snaps.clear();
|
||||
@@ -107,6 +115,15 @@ impl OpenCADStudio {
|
||||
}
|
||||
None => AcceptedSnap::free(committed),
|
||||
};
|
||||
self.push_accepted_snap(accepted);
|
||||
}
|
||||
|
||||
/// Append an already-built accepted snap, keeping the retention cap.
|
||||
///
|
||||
/// Used by paths that are not point steps (the dimension object pick
|
||||
/// resolved through a viewport) and therefore never reach the click
|
||||
/// handler.
|
||||
pub(crate) fn push_accepted_snap(&mut self, accepted: AcceptedSnap) {
|
||||
if self.accepted_snaps.len() >= MAX_ACCEPTED_SNAPS {
|
||||
self.accepted_snaps.remove(0);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user