Regenerate viewport dimensions when the viewport view changes

Panning, zooming, twisting or rescaling a layout viewport moves model
geometry across the sheet without touching that geometry, so nothing in
the ordinary entity-change path noticed and the dimensions drawn through
the viewport stayed where they were — detached from what they measure.

`Scene::notify_viewport_changed` announces the viewport itself as a
modified entity. That is all it takes: every trans-space reference
carries the viewport handle as the first link of its chain, so the
dependency lookup in `refresh_associative_dimensions` already finds the
associations from there, and the refresh re-places and re-measures them.

Called from each mutator that changes the paper<->model mapping: pan,
zoom, fit-to-bounds, view normalisation on entering MSPACE, the
view-direction/twist snaps, the viewcube camera path, and both
annotation-scale setters.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
Christopher OverbeckandClaude Fable 5.1 committed 2026-09-15 12:46:04 -05:00
1 parent e8246031fd
commit f80130560e
3 files changed
+32 -2

No files matched your search

+3
View File
@@ -567,6 +567,9 @@ impl Scene {
viewport.view_target.x = center.x;
viewport.view_target.y = center.y;
viewport.view_target.z = center.z;
// Panning a viewport moves model geometry across the sheet; the
// dimensions drawn through it follow.
self.notify_viewport_changed(handle);
} else {
self.camera.borrow_mut().target = center;
}
+8
View File
@@ -5296,6 +5296,10 @@ impl Scene {
self.document
.set_viewport_annotation_scale(viewport, scale_handle);
// Viewport scale changed: the dimensions drawn on the sheet
// through it measure the same model geometry at a new paper
// size and have to be re-placed.
self.notify_viewport_changed(viewport);
self.resident_wire_sets.borrow_mut().clear();
self.bump_geometry();
@@ -5349,6 +5353,10 @@ impl Scene {
vp.view_height = vp.height / factor;
self.document
.set_viewport_annotation_scale(viewport, scale_handle);
// Viewport scale changed: the dimensions drawn on the sheet
// through it measure the same model geometry at a new paper
// size and have to be re-placed.
self.notify_viewport_changed(viewport);
self.resident_wire_sets.borrow_mut().clear();
self.bump_geometry();
true
+21 -2
View File
@@ -259,6 +259,9 @@ impl Scene {
vp.view_height = eff_h;
}
}
// A viewport's view changed, so every dimension drawn on the
// sheet through it has to be re-placed and re-measured.
self.notify_viewport_changed(vp_handle);
}
/// Fit model-space bounds into the active floating viewport without moving
@@ -297,6 +300,7 @@ impl Scene {
viewport.custom_scale = viewport.height / viewport.view_height;
}
}
self.notify_viewport_changed(viewport_handle);
self.camera_generation += 1;
true
}
@@ -348,6 +352,9 @@ impl Scene {
vp.view_target.y += model_delta.y as f64;
vp.view_target.z += model_delta.z as f64;
}
// A viewport's view changed, so every dimension drawn on the
// sheet through it has to be re-placed and re-measured.
self.notify_viewport_changed(vp_handle);
}
/// Zoom the active viewport's model-space view by `steps` notches.
@@ -397,6 +404,9 @@ impl Scene {
}
}
}
// A viewport's view changed, so every dimension drawn on the
// sheet through it has to be re-placed and re-measured.
self.notify_viewport_changed(vp_handle);
}
/// Orbit the active viewport's view direction by the given screen-pixel delta.
@@ -474,6 +484,9 @@ impl Scene {
vp.view_direction.z = dir.z as f64;
vp.twist_angle = twist;
}
// Twisting a viewport rotates model geometry on the sheet; the
// dimensions drawn through it follow.
self.notify_viewport_changed(vp_handle);
}
/// Mutate the active viewport's camera through a closure, then re-encode the
@@ -502,6 +515,7 @@ impl Scene {
.normalize_or(glam::Vec3::Y);
let roll = up0.cross(desired_up).dot(dir).atan2(up0.dot(desired_up));
let twist = -roll as f64;
let mut changed = false;
if let Some(acadrust::EntityType::Viewport(vp)) = self.document.get_entity_mut(vp_handle) {
if vp.status.locked {
return false;
@@ -514,9 +528,14 @@ impl Scene {
tmp.projection == view::camera::Projection::Perspective;
vp.lens_length =
(12.0 / (tmp.fov_y * 0.5).tan().max(1e-6)) as f64;
return true;
changed = true;
}
false
if changed {
// The view (and with it the sheet placement of everything drawn
// through this viewport) moved.
self.notify_viewport_changed(vp_handle);
}
changed
}
/// Render mode of the active paper-space viewport, or `None` when no