mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-05 23:41:44 +00:00
drawing: compute cut/fill intersection once per CutDecorator object
recalculate_cut() and recalculate_fill() each ran is_intersecting_camera(), which builds a bmesh and scans every vertex. When a redraw recalculated both (camera moved, cache miss, or the object selected) that was two full intersection tests per object per frame for the same answer. Compute it once in decorate() and pass it to both, and skip the test entirely when neither recalculation is needed. Never more tests than before, identical result since the camera can't move within a frame. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1825,23 +1825,35 @@ class CutDecorator:
|
|||||||
|
|
||||||
# Currently selected objects must be recalculated as they may be being moved / edited.
|
# 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 the camera is selected, we also recalculate as the user may be moving the camera.
|
||||||
|
is_selected = obj.select_get()
|
||||||
|
recalc_cut = not has_cut_cache or is_selected or self.camera_moved
|
||||||
|
recalc_fill = not has_fill_cache or is_selected or self.camera_moved
|
||||||
|
if not (recalc_cut or recalc_fill):
|
||||||
|
return
|
||||||
|
|
||||||
if not has_cut_cache or obj.select_get() or self.camera_moved:
|
# The intersection test builds a bmesh and scans every vertex; both recalculations need
|
||||||
self.recalculate_cut(context, obj, element)
|
# the same answer, so compute it once here rather than once in each.
|
||||||
if not has_fill_cache or obj.select_get() or self.camera_moved:
|
is_intersecting = tool.Drawing.is_intersecting_camera(obj, context.scene.camera)
|
||||||
self.recalculate_fill(context, obj, element)
|
if recalc_cut:
|
||||||
|
self.recalculate_cut(context, obj, element, is_intersecting)
|
||||||
|
if recalc_fill:
|
||||||
|
self.recalculate_fill(context, obj, element, is_intersecting)
|
||||||
|
|
||||||
def recalculate_cut(self, context, obj: bpy.types.Object, element: ifcopenshell.entity_instance) -> None:
|
def recalculate_cut(
|
||||||
if tool.Drawing.is_intersecting_camera(obj, context.scene.camera):
|
self, context, obj: bpy.types.Object, element: ifcopenshell.entity_instance, is_intersecting: bool
|
||||||
|
) -> None:
|
||||||
|
if is_intersecting:
|
||||||
verts, edges = tool.Drawing.bisect_mesh(obj, context.scene.camera)
|
verts, edges = tool.Drawing.bisect_mesh(obj, context.scene.camera)
|
||||||
DecoratorData.cut_cache[element.id()] = (verts, edges)
|
DecoratorData.cut_cache[element.id()] = (verts, edges)
|
||||||
else:
|
else:
|
||||||
DecoratorData.cut_cache[element.id()] = (False, False)
|
DecoratorData.cut_cache[element.id()] = (False, False)
|
||||||
|
|
||||||
def recalculate_fill(self, context, obj: bpy.types.Object, element: ifcopenshell.entity_instance) -> None:
|
def recalculate_fill(
|
||||||
|
self, context, obj: bpy.types.Object, element: ifcopenshell.entity_instance, is_intersecting: bool
|
||||||
|
) -> None:
|
||||||
element_id = element.id()
|
element_id = element.id()
|
||||||
|
|
||||||
if not tool.Drawing.is_intersecting_camera(obj, context.scene.camera):
|
if not is_intersecting:
|
||||||
DecoratorData.fill_cache[element_id] = {}
|
DecoratorData.fill_cache[element_id] = {}
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user