diff --git a/src/bonsai/bonsai/bim/module/drawing/operator.py b/src/bonsai/bonsai/bim/module/drawing/operator.py index f92f7e0085..144a687af6 100644 --- a/src/bonsai/bonsai/bim/module/drawing/operator.py +++ b/src/bonsai/bonsai/bim/module/drawing/operator.py @@ -3815,91 +3815,14 @@ class AddReferenceImage(bpy.types.Operator, tool.Ifc.Operator, ImportHelper): description="Existing object name to add a style with reference image to. If not provided will create a new object.", options={"SKIP_SAVE"}, ) - - x_length: bpy.props.FloatProperty( - name="X Length", - description="Width of the reference image in project units", - default=1.0, - min=0.001, - soft_min=0.01, - precision=3, - ) - y_length: bpy.props.FloatProperty( - name="Y Length", - description="Height of the reference image in project units", - default=1.0, - min=0.001, - soft_min=0.01, - precision=3, - ) - - show_dimensions_dialog: bpy.props.BoolProperty(default=False, options={"HIDDEN", "SKIP_SAVE"}) + size: bpy.props.FloatProperty(name="Size", description="Size of the reference image", default=1.0, unit="LENGTH") def draw(self, context): - layout = self.layout - - if getattr(self, "show_dimensions_dialog", False): - if tool.Ifc.get(): - length_unit = ifcopenshell.util.unit.get_project_unit(tool.Ifc.get(), "LENGTHUNIT") - if length_unit: - unit_name = ifcopenshell.util.unit.get_full_unit_name(length_unit).lower() - else: - unit_name = "project units" - layout.label(text=f"Set Reference Image Dimensions (in {unit_name}):") - else: - layout.label(text="Set Reference Image Dimensions (in project units):") - layout.separator() - layout.prop(self, "x_length") - layout.prop(self, "y_length") - else: - if Path(tool.Ifc.get_path()).is_file(): - layout.prop(self, "use_relative_path") - else: - self.use_relative_path = False - layout.label(text="Save the .ifc file first ") - layout.label(text="to use relative paths.") - layout.prop(self, "override_existing_image") - layout.prop(self, "use_existing_object_by_name") - - def invoke(self, context, event): - if not getattr(self, "show_dimensions_dialog", False): - context.window_manager.fileselect_add(self) - return {"RUNNING_MODAL"} - else: - return context.window_manager.invoke_props_dialog(self) - - def execute(self, context): - if not getattr(self, "show_dimensions_dialog", False): - abs_path = Path(self.filepath).absolute().resolve() - if self.override_existing_image: - params = {"check_existing": True, "force_reload": True} - else: - params = {"check_existing": False} - - try: - image = load_image(abs_path.name, str(abs_path.parent), **params) - - image_width_px = image.size[0] - image_height_px = image.size[1] - aspect_ratio = image_width_px / image_height_px - - if aspect_ratio >= 1.0: - self.x_length = 1.0 - self.y_length = 1.0 / aspect_ratio - else: - self.x_length = aspect_ratio - self.y_length = 1.0 - - bpy.data.images.remove(image) - - except Exception as e: - self.report({"ERROR"}, f"Failed to load image: {str(e)}") - return {"CANCELLED"} - - self.show_dimensions_dialog = True - return context.window_manager.invoke_props_dialog(self) - - return self._execute(context) + if Path(tool.Ifc.get_path()).is_file(): + self.layout.prop(self, "use_relative_path") + self.layout.prop(self, "override_existing_image") + self.layout.prop(self, "use_existing_object_by_name") + self.layout.prop(self, "size") def _execute(self, context): space = tool.Blender.get_view3d_space() @@ -3920,11 +3843,19 @@ class AddReferenceImage(bpy.types.Operator, tool.Ifc.Operator, ImportHelper): params = {"check_existing": False} image = load_image(abs_path.name, str(abs_path.parent), **params) + aspect_ratio = image.size[0] / image.size[1] + if aspect_ratio >= 1.0: # Landscape + x_length = self.size + y_length = self.size / aspect_ratio + else: + x_length = self.size / aspect_ratio + y_length = self.size + def bm_add_image_plane(mesh): bm = tool.Blender.get_bmesh_for_mesh(mesh, clean=True) unit_scale = ifcopenshell.util.unit.calculate_unit_scale(ifc_file) - plane_scale = Vector((self.x_length * unit_scale / 2.0, self.y_length * unit_scale / 2.0, 1.0)) + plane_scale = Vector((x_length / 2.0, y_length / 2.0, 1.0)) matrix = Matrix.LocRotScale(None, None, plane_scale) bmesh.ops.create_grid(bm, x_segments=1, y_segments=1, size=1, matrix=matrix, calc_uvs=False) @@ -4028,8 +3959,6 @@ class AddReferenceImage(bpy.types.Operator, tool.Ifc.Operator, ImportHelper): tool.Style.reload_material_from_ifc(material) tool.Geometry.record_object_materials(obj) - return {"FINISHED"} - class ConvertSVGToDXF(bpy.types.Operator): bl_idname = "bim.convert_svg_to_dxf" diff --git a/src/bonsai/test/bim/feature/drawing.feature b/src/bonsai/test/bim/feature/drawing.feature index 6a24168e4b..b7b78e748d 100644 --- a/src/bonsai/test/bim/feature/drawing.feature +++ b/src/bonsai/test/bim/feature/drawing.feature @@ -3,12 +3,6 @@ Feature: Drawing Scenario: Duplicate drawing Given an empty IFC project - And I add a cube - And the object "Cube" is selected - And I look at the "Class" panel - And I set the "Products" property to "IfcElement" - And I set the "Class" property to "IfcWall" - And I click "Assign IFC Class" And I save IFC project And I look at the "Drawings" panel And I click "IMPORT" @@ -315,3 +309,10 @@ Scenario: Create sheet - with a drawing added to it And I click "IMAGE_PLANE" When I click "OUTPUT" Then the file "{ifc_dir}/sheets/A01 - UNTITLED.svg" should contain "IfcWall" + +Scenario: Add reference image + Given an empty IFC project + And I save IFC project + When I press "bim.add_reference_image(filepath='{cwd}/test/files/image.jpg')" + Then the object "IfcAnnotation/image" exists + And the object "IfcAnnotation/image" dimensions are "1.0,0.565,0." diff --git a/src/bonsai/test/tool/test_drawing.py b/src/bonsai/test/tool/test_drawing.py index 8501b5b9ea..b0d2756198 100644 --- a/src/bonsai/test/tool/test_drawing.py +++ b/src/bonsai/test/tool/test_drawing.py @@ -938,7 +938,7 @@ class TestAddReferenceImage(NewFile): obj = bpy.data.objects["IfcAnnotation/image"] assert obj is not None - assert tool.Cad.are_vectors_equal(obj.dimensions, Vector((3.53982, 2.0, 0.0))) + assert tool.Cad.are_vectors_equal(obj.dimensions, Vector((1.0, 0.565, 0.0))) material = obj.active_material assert material