From 3f2703ca212d94e36d8a2bad9bf22f0194a91db3 Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Wed, 3 Jul 2024 12:48:35 +0500 Subject: [PATCH] tool.Geometry method for adding a data to an empty object --- src/blenderbim/blenderbim/core/tool.py | 2 +- src/blenderbim/blenderbim/tool/geometry.py | 20 ++++++++++++++------ src/blenderbim/test/core/test_geometry.py | 8 ++++---- src/blenderbim/test/tool/test_geometry.py | 3 ++- 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/blenderbim/blenderbim/core/tool.py b/src/blenderbim/blenderbim/core/tool.py index 7c8582faa0..c8ca87e744 100644 --- a/src/blenderbim/blenderbim/core/tool.py +++ b/src/blenderbim/blenderbim/core/tool.py @@ -400,7 +400,7 @@ class Geometry: def record_object_position(cls, obj): pass def remove_connection(cls, connection): pass def rename_object(cls, obj, name): pass - def replace_object_with_empty(cls, obj): pass + def recreate_object_with_data(cls, obj, data): pass def replace_object_data_globally(cls, old_data, new_data): pass def resolve_mapped_representation(cls, representation): pass def run_geometry_update_representation(cls, obj=None): pass diff --git a/src/blenderbim/blenderbim/tool/geometry.py b/src/blenderbim/blenderbim/tool/geometry.py index bf39e32075..c35b59ef11 100644 --- a/src/blenderbim/blenderbim/tool/geometry.py +++ b/src/blenderbim/blenderbim/tool/geometry.py @@ -690,13 +690,20 @@ class Geometry(blenderbim.core.tool.Geometry): obj.name = name @classmethod - def replace_object_with_empty(cls, obj: bpy.types.Object) -> None: - """Recreate a Blender object as an empty object. + def recreate_object_with_data(cls, obj: bpy.types.Object, data: Union[bpy.types.ID, None]) -> bpy.types.Object: + """Recreate a Blender object with the provided `data`. This method is useful when an object should no longer have associated - data (in Blender, you cannot simply assign .data to None). Note that the - object's original data is not handled by this method and should be + data (in Blender, you cannot simply assign .data to None). + Or if object is an empty and should now have a data. + + The object's original data is not handled by this method and should be processed separately to avoid leaving orphan data. + + Original `obj` is deleted and becomes invalid and should be replaced + with an object returned by this method. + + :return: The newly recreated object. """ element = tool.Ifc.get_entity(obj) name = obj.name @@ -704,7 +711,7 @@ class Geometry(blenderbim.core.tool.Geometry): tool.Ifc.unlink(element=element) obj.name = ifcopenshell.guid.new() - new_obj = bpy.data.objects.new(name, None) + new_obj = bpy.data.objects.new(name, data) if element: tool.Ifc.link(element, new_obj) @@ -712,6 +719,7 @@ class Geometry(blenderbim.core.tool.Geometry): collection.objects.link(new_obj) new_obj.matrix_world = obj.matrix_world bpy.data.objects.remove(obj) + return new_obj @classmethod def resolve_mapped_representation( @@ -885,7 +893,7 @@ class Geometry(blenderbim.core.tool.Geometry): # `representation` is the only representation for object. if new_representation is None: - cls.replace_object_with_empty(obj) + cls.recreate_object_with_data(obj, None) return blenderbim.core.geometry.switch_representation( diff --git a/src/blenderbim/test/core/test_geometry.py b/src/blenderbim/test/core/test_geometry.py index 87dfbc4f67..c55033b857 100644 --- a/src/blenderbim/test/core/test_geometry.py +++ b/src/blenderbim/test/core/test_geometry.py @@ -321,9 +321,9 @@ class TestRemoveRepresentation: geometry.has_data_users("data").should_be_called().will_return(True) geometry.get_elements_of_type("type").should_be_called().will_return(["element"]) ifc.get_object("element").should_be_called().will_return("obj") - geometry.replace_object_with_empty("obj").should_be_called() + geometry.recreate_object_with_data("obj").should_be_called() ifc.get_object("type").should_be_called().will_return("type_obj") - geometry.replace_object_with_empty("type_obj").should_be_called() + geometry.recreate_object_with_data("type_obj").should_be_called() ifc.run("geometry.unassign_representation", product="type", representation="representation").should_be_called() ifc.run("geometry.remove_representation", representation="representation").should_be_called() geometry.delete_data("data").should_be_called() @@ -344,7 +344,7 @@ class TestRemoveRepresentation: geometry.get_element_type("element").should_be_called().will_return(None) geometry.get_representation_data("representation").should_be_called().will_return("data") geometry.has_data_users("data").should_be_called().will_return(True) - geometry.replace_object_with_empty("obj").should_be_called() + geometry.recreate_object_with_data("obj").should_be_called() ifc.run( "geometry.unassign_representation", product="element", representation="representation" ).should_be_called() @@ -359,7 +359,7 @@ class TestRemoveRepresentation: geometry.is_type_product("element").should_be_called().will_return(False) geometry.get_representation_data("representation").should_be_called().will_return("data") geometry.has_data_users("data").should_be_called().will_return(True) - geometry.replace_object_with_empty("obj").should_be_called() + geometry.recreate_object_with_data("obj").should_be_called() ifc.run( "geometry.unassign_representation", product="element", representation="representation" ).should_be_called() diff --git a/src/blenderbim/test/tool/test_geometry.py b/src/blenderbim/test/tool/test_geometry.py index 098843d17f..834ccd8687 100644 --- a/src/blenderbim/test/tool/test_geometry.py +++ b/src/blenderbim/test/tool/test_geometry.py @@ -375,6 +375,7 @@ class TestRenameObject(NewFile): assert obj.name == "name" +# TODO: add a test class TestReplaceObjectWithEmpty(NewFile): def test_run(self): ifc = ifcopenshell.file() @@ -384,7 +385,7 @@ class TestReplaceObjectWithEmpty(NewFile): bpy.context.scene.collection.objects.link(obj) element = ifc.createIfcWall() tool.Ifc.link(element, obj) - subject.replace_object_with_empty(obj) + subject.recreate_object_with_data(obj, None) obj = bpy.data.objects.get("Object") assert obj.users_collection[0] == bpy.context.scene.collection assert tool.Ifc.get_entity(obj) == element