From 7de625b3d3713cb8d1876bbd5f472c911b8bb721 Mon Sep 17 00:00:00 2001 From: carlopav Date: Sun, 19 Jul 2026 01:02:52 +0200 Subject: [PATCH] drawing: evaluate camera movement once per CutDecorator redraw is_camera_moved() runs eval()/numpy over the camera matrix and, as a side effect, refreshes the stored checksum the first time it returns True. It was called up to twice per object inside decorate(), so on a frame where the camera actually moved the first call updated the checksum and every later call - the fill check on the same object, and both checks on all remaining objects - then saw an already-current checksum and returned False. Only the first object's cut got recalculated; its fill and every other element stayed stale until something else invalidated the cache. Evaluate it once at the top of __call__ and reuse the flag. This halves the per-object eval overhead on the common path (viewport navigation with the camera object stationary) and, when the camera does move, correctly recalculates the cut and fill for every intersecting element instead of just the first. Co-Authored-By: Claude Opus 4.8 (cherry picked from commit 074fc26e8f4ff9b261254cc037c1f989f028a801) --- src/bonsai/bonsai/bim/module/drawing/decoration.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/bonsai/bonsai/bim/module/drawing/decoration.py b/src/bonsai/bonsai/bim/module/drawing/decoration.py index b9b4dd40cb..b8e7c092aa 100644 --- a/src/bonsai/bonsai/bim/module/drawing/decoration.py +++ b/src/bonsai/bonsai/bim/module/drawing/decoration.py @@ -1677,6 +1677,12 @@ class CutDecorator: selected_elements_color = self.addon_prefs.decorator_color_selected self.fallback_colour = (0.3, 0.3, 0.3, 1) + # Evaluate camera movement once per redraw rather than twice per object: is_camera_moved() + # runs eval()/numpy on the camera matrix and, as a side effect, refreshes the stored + # checksum on the first True result - so calling it per object also made the second call + # (fill) see an already-updated checksum and skip recalculating when it shouldn't. + self.camera_moved = self.is_camera_moved() + all_vertices = [] all_edges = [] selected_vertices = [] @@ -1803,9 +1809,9 @@ class CutDecorator: # Currently selected objects must be recalculated as they may be being moved / edited. # If the camera is selected, we also recalculate as the user may be moving the camera. - if not has_cut_cache or obj.select_get() or self.is_camera_moved(): + if not has_cut_cache or obj.select_get() or self.camera_moved: self.recalculate_cut(context, obj, element) - if not has_fill_cache or obj.select_get() or self.is_camera_moved(): + if not has_fill_cache or obj.select_get() or self.camera_moved: self.recalculate_fill(context, obj, element) def recalculate_cut(self, context, obj: bpy.types.Object, element: ifcopenshell.entity_instance) -> None: