From 28e5af853df8e43d4851594c6a95ae0eb5e4cdf2 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Wed, 10 Nov 2021 18:01:10 +1100 Subject: [PATCH] Fix bug where an added default material was not linked and auto synced. --- src/blenderbim/blenderbim/bim/export_ifc.py | 2 +- .../bim/module/material/operator.py | 2 +- src/blenderbim/blenderbim/core/material.py | 6 ++--- src/blenderbim/blenderbim/core/tool.py | 2 -- src/blenderbim/blenderbim/tool/geometry.py | 2 +- src/blenderbim/blenderbim/tool/material.py | 8 ------- .../test/bim/feature/material.feature | 19 ++++++++++++++- src/blenderbim/test/bim/test_feature.py | 6 +++++ src/blenderbim/test/core/test_material.py | 8 +++---- src/blenderbim/test/tool/test_ifc.py | 23 +++++++++++++++++-- src/blenderbim/test/tool/test_material.py | 19 --------------- 11 files changed, 55 insertions(+), 42 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/export_ifc.py b/src/blenderbim/blenderbim/bim/export_ifc.py index 5462c508a3..6d78d53402 100644 --- a/src/blenderbim/blenderbim/bim/export_ifc.py +++ b/src/blenderbim/blenderbim/bim/export_ifc.py @@ -134,7 +134,7 @@ class IfcExporter: def sync_object_placement(self, obj): blender_matrix = np.array(obj.matrix_world) element = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id) - if (obj.scale - Vector((1., 1.,1.))).length > 1e-4: + if (obj.scale - Vector((1.0, 1.0, 1.0))).length > 1e-4: bpy.ops.bim.update_representation(obj=obj.name) return element if element.is_a("IfcGridAxis"): diff --git a/src/blenderbim/blenderbim/bim/module/material/operator.py b/src/blenderbim/blenderbim/bim/module/material/operator.py index 7d455a2b63..8fc169ff0e 100644 --- a/src/blenderbim/blenderbim/bim/module/material/operator.py +++ b/src/blenderbim/blenderbim/bim/module/material/operator.py @@ -137,7 +137,7 @@ class UnlinkMaterial(bpy.types.Operator, Operator): bl_options = {"REGISTER", "UNDO"} def _execute(self, context): - core.unlink_material(tool.Material, obj=context.active_object.active_material) + core.unlink_material(tool.Ifc, obj=context.active_object.active_material) class AssignMaterial(bpy.types.Operator): diff --git a/src/blenderbim/blenderbim/core/material.py b/src/blenderbim/blenderbim/core/material.py index 78516df6ac..88c6405e2b 100644 --- a/src/blenderbim/blenderbim/core/material.py +++ b/src/blenderbim/blenderbim/core/material.py @@ -17,11 +17,11 @@ # along with BlenderBIM Add-on. If not, see . -def unlink_material(material, obj=None): - material.unlink(obj) +def unlink_material(ifc, obj=None): + ifc.unlink(obj=obj) def add_default_material(ifc, material): obj = material.add_default_material_object() - material.link(ifc.run("material.add_material", name="Default"), obj) + ifc.link(ifc.run("material.add_material", name="Default"), obj) return obj diff --git a/src/blenderbim/blenderbim/core/tool.py b/src/blenderbim/blenderbim/core/tool.py index 13340b419e..b4f3fadb8c 100644 --- a/src/blenderbim/blenderbim/core/tool.py +++ b/src/blenderbim/blenderbim/core/tool.py @@ -121,8 +121,6 @@ class Ifc: @interface class Material: def add_default_material_object(cls): pass - def link(cls, element, obj): pass - def unlink(cls, obj): pass @interface diff --git a/src/blenderbim/blenderbim/tool/geometry.py b/src/blenderbim/blenderbim/tool/geometry.py index 8554aee628..b39dd5900b 100644 --- a/src/blenderbim/blenderbim/tool/geometry.py +++ b/src/blenderbim/blenderbim/tool/geometry.py @@ -45,7 +45,7 @@ class Geometry(blenderbim.core.tool.Geometry): @classmethod def clear_scale(cls, obj): - if (obj.scale - Vector((1., 1.,1.))).length > 1e-4: + if (obj.scale - Vector((1.0, 1.0, 1.0))).length > 1e-4: if obj.data.users == 1: context_override = {} context_override["object"] = context_override["active_object"] = obj diff --git a/src/blenderbim/blenderbim/tool/material.py b/src/blenderbim/blenderbim/tool/material.py index 79620381b9..1acb411b62 100644 --- a/src/blenderbim/blenderbim/tool/material.py +++ b/src/blenderbim/blenderbim/tool/material.py @@ -27,11 +27,3 @@ class Material(blenderbim.core.tool.Material): @classmethod def add_default_material_object(cls): return bpy.data.materials.new("Default") - - @classmethod - def link(cls, material, obj): - obj.BIMObjectProperties.ifc_definition_id = material.id() - - @classmethod - def unlink(self, obj): - obj.BIMObjectProperties.ifc_definition_id = 0 diff --git a/src/blenderbim/test/bim/feature/material.feature b/src/blenderbim/test/bim/feature/material.feature index 9a969862fb..6ef85febbd 100644 --- a/src/blenderbim/test/bim/feature/material.feature +++ b/src/blenderbim/test/bim/feature/material.feature @@ -6,7 +6,24 @@ Scenario: Add default material When I press "bim.add_default_material" Then the material "Default" exists -Scenario: Unlink object +Scenario: Add material + Given an empty IFC project + And I add a cube + And the object "Cube" is selected + And I add a material + When I press "bim.add_material" + Then the material "Material" is an IFC material + +Scenario: Remove material + Given an empty IFC project + And I add a cube + And the object "Cube" is selected + And I add a material + And I press "bim.add_material" + When I press "bim.remove_material" + Then the material "Material" is not an IFC material + +Scenario: Unlink material Given an empty IFC project And I add a cube And the object "Cube" is selected diff --git a/src/blenderbim/test/bim/test_feature.py b/src/blenderbim/test/bim/test_feature.py index 2918e78ec2..254a7c14c9 100644 --- a/src/blenderbim/test/bim/test_feature.py +++ b/src/blenderbim/test/bim/test_feature.py @@ -367,6 +367,12 @@ def the_object_name_is_not_an_ifc_element(name): assert id != 0, f"The ID is {id}" +@then(parsers.parse('the material "{name}" is an IFC material')) +def the_material_name_is_not_an_ifc_material(name): + id = the_material_name_exists(name).BIMObjectProperties.ifc_definition_id + assert id != 0, f"The ID is {id}" + + @then(parsers.parse('the material "{name}" is not an IFC material')) def the_material_name_is_not_an_ifc_material(name): id = the_material_name_exists(name).BIMObjectProperties.ifc_definition_id diff --git a/src/blenderbim/test/core/test_material.py b/src/blenderbim/test/core/test_material.py index 8fa9a9fe5e..a35a2fbf6e 100644 --- a/src/blenderbim/test/core/test_material.py +++ b/src/blenderbim/test/core/test_material.py @@ -21,14 +21,14 @@ from test.core.bootstrap import ifc, material class TestUnlinkMaterial: - def test_run(self, material): - material.unlink("obj").should_be_called() - subject.unlink_material(material, obj="obj") + def test_run(self, ifc): + ifc.unlink(obj="obj").should_be_called() + subject.unlink_material(ifc, obj="obj") class TestAddDefaultMaterial: def test_run(self, ifc, material): material.add_default_material_object().should_be_called().will_return("obj") ifc.run("material.add_material", name="Default").should_be_called().will_return("material") - material.link("material", "obj").should_be_called() + ifc.link("material", "obj").should_be_called() assert subject.add_default_material(ifc, material) == "obj" diff --git a/src/blenderbim/test/tool/test_ifc.py b/src/blenderbim/test/tool/test_ifc.py index 247694f815..fa805371a0 100644 --- a/src/blenderbim/test/tool/test_ifc.py +++ b/src/blenderbim/test/tool/test_ifc.py @@ -101,7 +101,7 @@ class TestGetObject(test.bim.bootstrap.NewFile): class TestLink(test.bim.bootstrap.NewFile): - def test_run(self): + def test_link_an_object(self): ifc = ifcopenshell.file() subject.set(ifc) element = ifc.createIfcWall() @@ -110,9 +110,18 @@ class TestLink(test.bim.bootstrap.NewFile): assert subject.get_entity(obj) == element assert subject.get_object(element) == obj + def test_link_a_material(self): + ifc = ifcopenshell.file() + subject.set(ifc) + element = ifc.createIfcMaterial() + obj = bpy.data.materials.new("Material") + subject.link(element, obj) + assert subject.get_entity(obj) == element + assert subject.get_object(element) == obj + class TestUnlink(test.bim.bootstrap.NewFile): - def test_run(self): + def test_unlink_an_object(self): ifc = ifcopenshell.file() subject.set(ifc) element = ifc.createIfcWall() @@ -122,6 +131,16 @@ class TestUnlink(test.bim.bootstrap.NewFile): assert subject.get_entity(obj) is None assert subject.get_object(element) is None + def test_unlink_a_material(self): + ifc = ifcopenshell.file() + subject.set(ifc) + element = ifc.createIfcMaterial() + obj = bpy.data.materials.new("Material") + subject.link(element, obj) + subject.unlink(element, obj) + assert subject.get_entity(obj) is None + assert subject.get_object(element) is None + def test_unlinking_using_an_object(self): ifc = ifcopenshell.file() subject.set(ifc) diff --git a/src/blenderbim/test/tool/test_material.py b/src/blenderbim/test/tool/test_material.py index cb6735797c..d8c50c09bf 100644 --- a/src/blenderbim/test/tool/test_material.py +++ b/src/blenderbim/test/tool/test_material.py @@ -34,22 +34,3 @@ class TestAddDefaultMaterialObject(NewFile): material = subject.add_default_material_object() assert isinstance(material, bpy.types.Material) assert material.name == "Default" - - -class TestLink(NewFile): - def test_run(self): - obj = bpy.data.materials.new("Material") - ifc = ifcopenshell.file() - material = ifc.createIfcMaterial() - subject.link(material, obj) - assert obj.BIMObjectProperties.ifc_definition_id == material.id() - - -class TestUnlink(NewFile): - def test_run(self): - obj = bpy.data.materials.new("Material") - ifc = ifcopenshell.file() - material = ifc.createIfcMaterial() - subject.link(material, obj) - subject.unlink(obj) - assert obj.BIMObjectProperties.ifc_definition_id == 0