From 8c3964305be8e9921969091173d24e1430539492 Mon Sep 17 00:00:00 2001 From: Hakan Seven Date: Mon, 27 Apr 2026 18:27:46 +0300 Subject: [PATCH] fix: convert grip positions to local space for display and hit-test Entity grips() return world-space coordinates (raw DXF values). After the world_offset change the camera view_proj is in local space, so projecting world-space grips through it gave wrong screen positions and hit-test failures. - refresh_selected_grips: subtract world_offset from every grip.world so selected_grips are stored in local (camera) space - Grip drag: cursor/snap positions are already local space; for GripApply::Absolute add world_offset back before passing to entity so entity coordinates stay in world space. Translate deltas are identical in both spaces so no conversion is needed there. Co-Authored-By: Claude Sonnet 4.6 --- src/app/properties.rs | 11 ++++++++++- src/app/update.rs | 4 +++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/app/properties.rs b/src/app/properties.rs index 47fa0ed4..76936d69 100644 --- a/src/app/properties.rs +++ b/src/app/properties.rs @@ -244,11 +244,20 @@ impl H7CAD { /// Rebuild the cached selected_grips from the current entity selection. pub(super) fn refresh_selected_grips(&mut self) { let i = self.active_tab; + let wo = self.tabs[i].scene.world_offset; let (new_handle, new_grips) = { let selected = self.tabs[i].scene.selected_entities(); if selected.len() == 1 { let (handle, entity) = selected[0]; - let grips = dispatch::grips(entity); + let grips = dispatch::grips(entity) + .into_iter() + .map(|mut g| { + g.world.x -= wo[0] as f32; + g.world.y -= wo[1] as f32; + g.world.z -= wo[2] as f32; + g + }) + .collect(); (Some(handle), grips) } else { (None, vec![]) diff --git a/src/app/update.rs b/src/app/update.rs index 978ecc83..20e94c0a 100644 --- a/src/app/update.rs +++ b/src/app/update.rs @@ -1133,10 +1133,12 @@ impl H7CAD { } } + let wo = self.tabs[i].scene.world_offset; + let wo_vec = glam::Vec3::new(wo[0] as f32, wo[1] as f32, wo[2] as f32); let apply = if grip.is_translate { GripApply::Translate(snapped - grip.last_world) } else { - GripApply::Absolute(snapped) + GripApply::Absolute(snapped + wo_vec) }; self.tabs[i].scene.apply_grip(grip.handle, grip.grip_id, apply); self.tabs[i].dirty = true;