Skip to content

Commit fcc80ad

Browse files
committed
Simplify add reference image size implementation and fix segfaulting tests
Previously, there was a dance between invoke, execute, and draw. This can probably be resolved, but is a high-risk for undo bugs. This simplifies the logic flow to just a traditional _invoke -> _execute. I add a new feature test to at least make sure it does something, and this also fixes the segfault in tool tests as it no longer requires the launching of the file browser.
1 parent c6b14d1 commit fcc80ad

3 files changed

Lines changed: 23 additions & 93 deletions

File tree

src/bonsai/bonsai/bim/module/drawing/operator.py

Lines changed: 15 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -3815,91 +3815,14 @@ class AddReferenceImage(bpy.types.Operator, tool.Ifc.Operator, ImportHelper):
38153815
description="Existing object name to add a style with reference image to. If not provided will create a new object.",
38163816
options={"SKIP_SAVE"},
38173817
)
3818-
3819-
x_length: bpy.props.FloatProperty(
3820-
name="X Length",
3821-
description="Width of the reference image in project units",
3822-
default=1.0,
3823-
min=0.001,
3824-
soft_min=0.01,
3825-
precision=3,
3826-
)
3827-
y_length: bpy.props.FloatProperty(
3828-
name="Y Length",
3829-
description="Height of the reference image in project units",
3830-
default=1.0,
3831-
min=0.001,
3832-
soft_min=0.01,
3833-
precision=3,
3834-
)
3835-
3836-
show_dimensions_dialog: bpy.props.BoolProperty(default=False, options={"HIDDEN", "SKIP_SAVE"})
3818+
size: bpy.props.FloatProperty(name="Size", description="Size of the reference image", default=1.0, unit="LENGTH")
38373819

38383820
def draw(self, context):
3839-
layout = self.layout
3840-
3841-
if getattr(self, "show_dimensions_dialog", False):
3842-
if tool.Ifc.get():
3843-
length_unit = ifcopenshell.util.unit.get_project_unit(tool.Ifc.get(), "LENGTHUNIT")
3844-
if length_unit:
3845-
unit_name = ifcopenshell.util.unit.get_full_unit_name(length_unit).lower()
3846-
else:
3847-
unit_name = "project units"
3848-
layout.label(text=f"Set Reference Image Dimensions (in {unit_name}):")
3849-
else:
3850-
layout.label(text="Set Reference Image Dimensions (in project units):")
3851-
layout.separator()
3852-
layout.prop(self, "x_length")
3853-
layout.prop(self, "y_length")
3854-
else:
3855-
if Path(tool.Ifc.get_path()).is_file():
3856-
layout.prop(self, "use_relative_path")
3857-
else:
3858-
self.use_relative_path = False
3859-
layout.label(text="Save the .ifc file first ")
3860-
layout.label(text="to use relative paths.")
3861-
layout.prop(self, "override_existing_image")
3862-
layout.prop(self, "use_existing_object_by_name")
3863-
3864-
def invoke(self, context, event):
3865-
if not getattr(self, "show_dimensions_dialog", False):
3866-
context.window_manager.fileselect_add(self)
3867-
return {"RUNNING_MODAL"}
3868-
else:
3869-
return context.window_manager.invoke_props_dialog(self)
3870-
3871-
def execute(self, context):
3872-
if not getattr(self, "show_dimensions_dialog", False):
3873-
abs_path = Path(self.filepath).absolute().resolve()
3874-
if self.override_existing_image:
3875-
params = {"check_existing": True, "force_reload": True}
3876-
else:
3877-
params = {"check_existing": False}
3878-
3879-
try:
3880-
image = load_image(abs_path.name, str(abs_path.parent), **params)
3881-
3882-
image_width_px = image.size[0]
3883-
image_height_px = image.size[1]
3884-
aspect_ratio = image_width_px / image_height_px
3885-
3886-
if aspect_ratio >= 1.0:
3887-
self.x_length = 1.0
3888-
self.y_length = 1.0 / aspect_ratio
3889-
else:
3890-
self.x_length = aspect_ratio
3891-
self.y_length = 1.0
3892-
3893-
bpy.data.images.remove(image)
3894-
3895-
except Exception as e:
3896-
self.report({"ERROR"}, f"Failed to load image: {str(e)}")
3897-
return {"CANCELLED"}
3898-
3899-
self.show_dimensions_dialog = True
3900-
return context.window_manager.invoke_props_dialog(self)
3901-
3902-
return self._execute(context)
3821+
if Path(tool.Ifc.get_path()).is_file():
3822+
self.layout.prop(self, "use_relative_path")
3823+
self.layout.prop(self, "override_existing_image")
3824+
self.layout.prop(self, "use_existing_object_by_name")
3825+
self.layout.prop(self, "size")
39033826

39043827
def _execute(self, context):
39053828
space = tool.Blender.get_view3d_space()
@@ -3920,11 +3843,19 @@ def _execute(self, context):
39203843
params = {"check_existing": False}
39213844
image = load_image(abs_path.name, str(abs_path.parent), **params)
39223845

3846+
aspect_ratio = image.size[0] / image.size[1]
3847+
if aspect_ratio >= 1.0: # Landscape
3848+
x_length = self.size
3849+
y_length = self.size / aspect_ratio
3850+
else:
3851+
x_length = self.size / aspect_ratio
3852+
y_length = self.size
3853+
39233854
def bm_add_image_plane(mesh):
39243855
bm = tool.Blender.get_bmesh_for_mesh(mesh, clean=True)
39253856

39263857
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(ifc_file)
3927-
plane_scale = Vector((self.x_length * unit_scale / 2.0, self.y_length * unit_scale / 2.0, 1.0))
3858+
plane_scale = Vector((x_length / 2.0, y_length / 2.0, 1.0))
39283859
matrix = Matrix.LocRotScale(None, None, plane_scale)
39293860
bmesh.ops.create_grid(bm, x_segments=1, y_segments=1, size=1, matrix=matrix, calc_uvs=False)
39303861

@@ -4028,8 +3959,6 @@ def bm_add_image_plane(mesh):
40283959
tool.Style.reload_material_from_ifc(material)
40293960
tool.Geometry.record_object_materials(obj)
40303961

4031-
return {"FINISHED"}
4032-
40333962

40343963
class ConvertSVGToDXF(bpy.types.Operator):
40353964
bl_idname = "bim.convert_svg_to_dxf"

src/bonsai/test/bim/feature/drawing.feature

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,6 @@ Feature: Drawing
33

44
Scenario: Duplicate drawing
55
Given an empty IFC project
6-
And I add a cube
7-
And the object "Cube" is selected
8-
And I look at the "Class" panel
9-
And I set the "Products" property to "IfcElement"
10-
And I set the "Class" property to "IfcWall"
11-
And I click "Assign IFC Class"
126
And I save IFC project
137
And I look at the "Drawings" panel
148
And I click "IMPORT"
@@ -315,3 +309,10 @@ Scenario: Create sheet - with a drawing added to it
315309
And I click "IMAGE_PLANE"
316310
When I click "OUTPUT"
317311
Then the file "{ifc_dir}/sheets/A01 - UNTITLED.svg" should contain "IfcWall"
312+
313+
Scenario: Add reference image
314+
Given an empty IFC project
315+
And I save IFC project
316+
When I press "bim.add_reference_image(filepath='{cwd}/test/files/image.jpg')"
317+
Then the object "IfcAnnotation/image" exists
318+
And the object "IfcAnnotation/image" dimensions are "1.0,0.565,0."

src/bonsai/test/tool/test_drawing.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -938,7 +938,7 @@ def test_run(self):
938938

939939
obj = bpy.data.objects["IfcAnnotation/image"]
940940
assert obj is not None
941-
assert tool.Cad.are_vectors_equal(obj.dimensions, Vector((3.53982, 2.0, 0.0)))
941+
assert tool.Cad.are_vectors_equal(obj.dimensions, Vector((1.0, 0.565, 0.0)))
942942

943943
material = obj.active_material
944944
assert material

0 commit comments

Comments
 (0)