feat(ucs): per-viewport UCS applied inside floating viewports
Extend UCS support to in-viewport (MSPACE) editing through the existing single-converter structure: one active_ucs drives every UCS-aware system, now in the Model tab AND inside a floating viewport. - Single predicate DocumentTab::editing_model_space() (Model tab or active viewport) replaces the model-only gate in ucs_wire_affine, ucs_rotation_angle, ucs_grid_basis, viewcube_ucs_mat, the coordinate readout and the cursor-plane pick. - Per-viewport UCS: refresh_active_ucs() sets active_ucs to the pane's UCS on every transition (the entered viewport's own UCS from its ucs_origin/x_axis/y_axis/ucs_per_viewport fields, the header model UCS in the Model tab, none in plain paper); persist_active_ucs() writes changes back to the viewport entity or the header so they round-trip. Wired into EnterViewport/ExitViewport, layout switch, load and the UCS command. - Visuals: grid_views now returns each pane's handle so every content viewport's grid aligns to its own UCS; the UCS icon draws inside the active viewport projected through the viewport camera. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
a66d873e51
commit
295d3b1b5d
5 changed files with 164 additions and 33 deletions
|
|
@ -5688,6 +5688,9 @@ impl OpenCADStudio {
|
|||
self.tabs[i].scene.active_viewport = None;
|
||||
self.tabs[i].scene.set_current_layout(name);
|
||||
self.tabs[i].scene.deselect_all();
|
||||
// UCS follows the pane: model header UCS in the Model tab, none
|
||||
// in plain paper space (a viewport's UCS is adopted on entry).
|
||||
self.tabs[i].refresh_active_ucs();
|
||||
self.tabs[i].scene.restore_saved_camera();
|
||||
self.tabs[i].last_synced_camera_gen = self.tabs[i].scene.camera_generation;
|
||||
// Grid/snap are per-view: load the layout we just entered (its
|
||||
|
|
@ -6213,6 +6216,8 @@ impl OpenCADStudio {
|
|||
self.tabs[i].scene.normalize_active_viewport_view();
|
||||
// Grid/snap follow the entered viewport.
|
||||
self.adopt_view_display(i);
|
||||
// Adopt the entered viewport's own per-viewport UCS.
|
||||
self.tabs[i].refresh_active_ucs();
|
||||
self.refresh_properties();
|
||||
self.command_line.push_output("MSPACE");
|
||||
Task::none()
|
||||
|
|
@ -6225,6 +6230,8 @@ impl OpenCADStudio {
|
|||
self.tabs[i].scene.active_viewport = None;
|
||||
// Grid/snap return to the paper sheet's own state.
|
||||
self.adopt_view_display(i);
|
||||
// Paper space has no UCS — drop the viewport's UCS.
|
||||
self.tabs[i].refresh_active_ucs();
|
||||
self.refresh_properties();
|
||||
self.command_line.push_output("PSPACE");
|
||||
Task::none()
|
||||
|
|
@ -8323,12 +8330,19 @@ impl OpenCADStudio {
|
|||
p: iced::Point,
|
||||
bounds: iced::Rectangle,
|
||||
) -> glam::DVec3 {
|
||||
let plane = self.tabs[i].active_ucs.as_ref().map(|ucs| {
|
||||
(
|
||||
ucs_z_axis(ucs),
|
||||
glam::DVec3::new(ucs.origin.x, ucs.origin.y, ucs.origin.z),
|
||||
)
|
||||
});
|
||||
// Constrain to the UCS plane only where the UCS applies (model space or
|
||||
// inside a viewport); plain paper space uses the target plane.
|
||||
let plane = self
|
||||
.tabs[i]
|
||||
.active_ucs
|
||||
.as_ref()
|
||||
.filter(|_| self.tabs[i].editing_model_space())
|
||||
.map(|ucs| {
|
||||
(
|
||||
ucs_z_axis(ucs),
|
||||
glam::DVec3::new(ucs.origin.x, ucs.origin.y, ucs.origin.z),
|
||||
)
|
||||
});
|
||||
let pick = |cam: &crate::scene::view::camera::Camera| match plane {
|
||||
Some((normal, origin)) => cam.pick_on_plane(p, bounds, normal, origin),
|
||||
None => cam.pick_on_target_plane(p, bounds),
|
||||
|
|
|
|||
Loading…
Reference in a new issue