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 <[email protected]>
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)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
Reference in new issue
Block a user