From eafa158ca0cd5ba2ca22b5e588b0375cab2efbce Mon Sep 17 00:00:00 2001 From: Bruno Postle Date: Sat, 4 Jul 2026 09:34:05 +0100 Subject: [PATCH] Allow drawing generation in background mode is_drawing_active() required an open VIEW_3D area purely as a poll() gate for bim.create_drawing, even though SVG generation is ifcopenshell.geom-based with no viewport dependency; skip that check when bpy.app.background is true, since a viewport is neither obtainable nor meaningful there. Interactive behaviour is unchanged. Generated with the assistance of an AI coding tool. --- src/bonsai/bonsai/tool/drawing.py | 14 +++++++------- src/bonsai/test/tool/test_drawing.py | 24 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/bonsai/bonsai/tool/drawing.py b/src/bonsai/bonsai/tool/drawing.py index 5b969b102f..c43aa9e73e 100644 --- a/src/bonsai/bonsai/tool/drawing.py +++ b/src/bonsai/bonsai/tool/drawing.py @@ -2440,13 +2440,13 @@ class Drawing(bonsai.core.tool.Drawing): @classmethod def is_drawing_active(cls) -> bool: camera = bpy.context.scene.camera - area = tool.Blender.get_view3d_area() - return bool( - camera is not None - and camera.type == "CAMERA" - and tool.Blender.get_ifc_definition_id(camera) - and area is not None - ) + if not (camera is not None and camera.type == "CAMERA" and tool.Blender.get_ifc_definition_id(camera)): + return False + # A VIEW_3D area is meaningless (and unobtainable) in background + # mode, but isn't otherwise required to generate a drawing. + if bpy.app.background: + return True + return tool.Blender.get_view3d_area() is not None @classmethod def is_camera_orthographic(cls) -> bool: diff --git a/src/bonsai/test/tool/test_drawing.py b/src/bonsai/test/tool/test_drawing.py index 57ac52424f..9d69fe51f6 100644 --- a/src/bonsai/test/tool/test_drawing.py +++ b/src/bonsai/test/tool/test_drawing.py @@ -1038,3 +1038,27 @@ class TestAddReferenceImage(NewFile): uv_node = material_nodes["Texture Coordinate"] assert len(uv_node.outputs["Generated"].links[:]) == 1 + + +class TestIsDrawingActive(NewFile): + def test_no_active_camera(self): + bpy.context.scene.camera = None + assert subject.is_drawing_active() is False + + def test_active_camera_without_ifc_definition(self): + bpy.context.scene.camera = subject.create_camera("Camera", mathutils.Matrix(), "PERSPECTIVE", "PLAN_VIEW") + assert subject.is_drawing_active() is False + + def test_ifc_linked_camera_in_background_mode(self): + ifc = ifcopenshell.file() + tool.Ifc.set(ifc) + camera_obj = subject.create_camera("Camera", mathutils.Matrix(), "PERSPECTIVE", "PLAN_VIEW") + drawing = ifc.createIfcAnnotation(ObjectType="DRAWING") + tool.Ifc.link(drawing, camera_obj) + bpy.context.scene.camera = camera_obj + + # The test suite itself runs Blender in background mode, where no + # VIEW_3D area can ever exist -- this is exactly the case the fix + # addresses, so this assertion documents that assumption. + assert bpy.app.background is True + assert subject.is_drawing_active() is True