From be22c44a3f7e5619525fabfdeaee2396fd0f4159 Mon Sep 17 00:00:00 2001 From: bklronin Date: Tue, 7 Jul 2026 22:40:40 +0200 Subject: [PATCH] - Added save file foramt - Split main.py refactor --- src/fluency/rendering/occ_renderer.py | 39 ++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/src/fluency/rendering/occ_renderer.py b/src/fluency/rendering/occ_renderer.py index 0e48a3e..1a184ea 100644 --- a/src/fluency/rendering/occ_renderer.py +++ b/src/fluency/rendering/occ_renderer.py @@ -1385,6 +1385,8 @@ class OCCRenderer(Renderer): """Show a small marker sphere at *position* as a snap indicator. Returns an object id that can be removed later. + The *size* is auto-scaled by camera distance so the marker stays + visible at any zoom level. """ if self._context is None: return None @@ -1393,7 +1395,8 @@ class OCCRenderer(Renderer): from OCP.AIS import AIS_Shape from OCP.Quantity import Quantity_Color, Quantity_TOC_RGB try: - sphere = BRepPrimAPI_MakeSphere(gp_Pnt(*position), size).Shape() + scaled_size = size * self._get_gizmo_scale(position) + sphere = BRepPrimAPI_MakeSphere(gp_Pnt(*position), scaled_size).Shape() ais = AIS_Shape(sphere) c = color or (1.0, 0.6, 0.0) # orange ais.SetColor(Quantity_Color(c[0], c[1], c[2], Quantity_TOC_RGB)) @@ -1423,6 +1426,31 @@ class OCCRenderer(Renderer): # ─── Smart Entity Picker Gizmo ───────────────────────────────────────── + def _get_gizmo_scale(self, position: Tuple[float, float, float]) -> float: + """Compute a scale factor so gizmos stay a consistent % of screen size. + + Scales gizmo sizes proportional to the camera-to-gizmo distance, so + the gizmo appears roughly the same physical size on screen regardless + of zoom level. Returns a multiplier applied to the base gizmo sizes. + """ + if self._view is None: + return 1.0 + try: + eye = self._view.Eye() + eye_x, eye_y, eye_z = float(eye.X()), float(eye.Y()), float(eye.Z()) + dx = position[0] - eye_x + dy = position[1] - eye_y + dz = position[2] - eye_z + distance = (dx * dx + dy * dy + dz * dz) ** 0.5 + # Reference distance at which the original hardcoded sizes (2.8 sphere, + # 15.0 axis) looked right. Scale linearly with distance. + reference_distance = 50.0 + scale = distance / reference_distance + # Clamp to avoid absurdly large or tiny gizmos. + return max(0.3, min(scale, 8.0)) + except Exception: + return 1.0 + def clear_entity_gizmo(self) -> None: """Remove all gizmo display objects (markers, axes, highlights).""" had_any = bool(self._gizmo_objects) @@ -1472,6 +1500,9 @@ class OCCRenderer(Renderer): return self.clear_entity_gizmo() + # Screen-relative scale: keeps gizmo visible regardless of zoom level. + gizmo_scale = self._get_gizmo_scale(position) + from OCP.gp import gp_Pnt, gp_Dir, gp_Ax2, gp_Circ from OCP.BRepBuilderAPI import BRepBuilderAPI_MakeEdge from OCP.AIS import AIS_Shape @@ -1517,13 +1548,13 @@ class OCCRenderer(Renderer): ): continue cc = default_colors.get(cand.get("type", ""), (0.7, 0.7, 0.7)) - _make_sphere(cpos, cc, 1.4) # dim, small + _make_sphere(cpos, cc, 1.4 * gizmo_scale) # dim, small # ── 1. Bright primary marker (sphere) ── - _make_sphere(position, gizmo_color, 2.8) + _make_sphere(position, gizmo_color, 2.8 * gizmo_scale) # ── 2. Axis indicator lines (primary only) ── - axis_length = 15.0 + axis_length = 15.0 * gizmo_scale def _make_axis_line( origin: Tuple[float, float, float],