forked from 1b-agent/opencadstudio-upstream
Add a viewport frame seam for dimension association resolution
PR3 has to map a resolved model point onto the sheet, which needs the layout viewport's paper<->model mapping. PR1 (feat/viewport-snap) owns `Scene::viewport_frame` and is not visible from this branch, so this adds the minimal stand-in the shared contract in `viewport_ref.rs` describes: paper_center from the viewport rectangle's centre, model_target from the saved view target, scale from `vp_effective_scale`, twist from the saved view twist. It is fenced off in one clearly marked block with merge instructions. PR1's version is camera-derived, because it must agree with what is actually drawn — including the auto-fit rescue `camera_for_viewport` applies to stale saved views. Nothing else in PR3 reads viewport fields directly, so replacing this one function is the whole merge. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
43dea41498
commit
417e8e3676
1 file changed
+37
@@ -328,6 +328,43 @@ impl MeasurementScale {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ─────────────────────────────────────────────────────────────────────────
|
||||||
|
// MERGE SEAM — PR1 (feat/viewport-snap) owns `Scene::viewport_frame`.
|
||||||
|
//
|
||||||
|
// PR3 needs a frame to map a resolved model point onto the sheet, but PR1 is
|
||||||
|
// not visible from this branch. This is the minimal stand-in agreed in the
|
||||||
|
// shared contract: paper_center = vp.center, model_target = vp.view_target,
|
||||||
|
// scale = `vp_effective_scale`, twist = vp.twist_angle. PR1's version is
|
||||||
|
// camera-derived (it must agree with what is actually drawn, including the
|
||||||
|
// auto-fit rescue in `Scene::camera_for_viewport` for stale saved views).
|
||||||
|
//
|
||||||
|
// To merge: delete this whole block. Nothing else in PR3 reads viewport
|
||||||
|
// fields directly — every call goes through `Scene::viewport_frame`.
|
||||||
|
// ─────────────────────────────────────────────────────────────────────────
|
||||||
|
impl crate::scene::Scene {
|
||||||
|
/// The planar paper<->model mapping of layout viewport `handle`.
|
||||||
|
///
|
||||||
|
/// `None` when the handle is not a viewport, or when its scale is
|
||||||
|
/// degenerate (a zero-height view cannot map anything).
|
||||||
|
pub fn viewport_frame(&self, handle: Handle) -> Option<ViewportFrame> {
|
||||||
|
let Some(acadrust::EntityType::Viewport(vp)) = self.document.get_entity(handle) else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
let scale = crate::scene::vp_effective_scale(vp.custom_scale, vp.view_height, vp.height);
|
||||||
|
if !scale.is_finite() || scale.abs() < 1e-12 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
Some(ViewportFrame {
|
||||||
|
viewport: handle,
|
||||||
|
paper_center: DVec2::new(vp.center.x, vp.center.y),
|
||||||
|
model_target: DVec2::new(vp.view_target.x, vp.view_target.y),
|
||||||
|
scale,
|
||||||
|
twist: vp.twist_angle,
|
||||||
|
locked: vp.status.locked,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
Reference in new issue
Block a user