Skip to content

Commit 25dacc8

Browse files
committed
Fix #7208. Merge duplicates patch recipe can now control merging by empty attributes.
1 parent 7cba63a commit 25dacc8

2 files changed

Lines changed: 18 additions & 4 deletions

File tree

src/ifcpatch/ifcpatch/recipes/MergeDuplicateTypes.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626

2727
class Patcher:
28-
def __init__(self, file: ifcopenshell.file, logger: Logger, attribute: str = "Tag"):
28+
def __init__(self, file: ifcopenshell.file, logger: Logger, attribute: str = "Tag", should_merge_null: bool = True):
2929
"""Merge duplicate element types via the Tag or another attribute
3030
3131
Revit is notorious for creating many duplicate element types. Element
@@ -50,6 +50,8 @@ def __init__(self, file: ifcopenshell.file, logger: Logger, attribute: str = "Ta
5050
:param attribute: The name of the attribute to merge element types based
5151
on. Typically this will be "Tag" as it stores the unique ID from the
5252
proprietary BIM software.
53+
:param should_merge_null: If True, all elements with an empty attribute
54+
will be merged. If False, they will be kept separate.
5355
5456
Example:
5557
@@ -64,12 +66,15 @@ def __init__(self, file: ifcopenshell.file, logger: Logger, attribute: str = "Ta
6466
self.file = file
6567
self.logger = logger
6668
self.attribute = attribute
69+
self.should_merge_null = should_merge_null
6770

6871
def patch(self):
69-
key = self.attribute
7072
keys: dict[Any, ifcopenshell.entity_instance] = {}
7173
for element_type in self.file.by_type("IfcTypeObject"):
72-
original_type = keys.get(getattr(element_type, key), None)
74+
key = getattr(element_type, self.attribute)
75+
if not key and not self.should_merge_null:
76+
continue
77+
original_type = keys.get(key, None)
7378
if original_type:
7479
elements = ifcopenshell.util.element.get_types(element_type)
7580
if elements:
@@ -78,7 +83,7 @@ def patch(self):
7883
ifcopenshell.util.element.replace_attribute(inverse, element_type, original_type)
7984
self.file.remove(element_type)
8085
else:
81-
keys[getattr(element_type, key)] = element_type
86+
keys[key] = element_type
8287

8388
def assign_type(
8489
self, related_objects: list[ifcopenshell.entity_instance], relating_type: ifcopenshell.entity_instance

src/ifcpatch/test/test_MergeDuplicateTypes.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,15 @@ def test_run(self):
7474
assert ifcopenshell.util.element.get_material(wall1, should_inherit=False) == None
7575
assert ifcopenshell.util.element.get_material(wall2, should_inherit=False) == None
7676

77+
def test_not_merging_empty_attributes(self):
78+
wall_type1 = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWallType", name="")
79+
wall_type2 = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWallType", name="")
80+
output = ifcpatch.execute({"file": self.file, "recipe": "MergeDuplicateTypes", "arguments": ["Name", True]})
81+
assert len(output.by_type("IfcWallType")) == 1
82+
wall_type3 = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWallType", name="")
83+
output = ifcpatch.execute({"file": self.file, "recipe": "MergeDuplicateTypes", "arguments": ["Name", False]})
84+
assert len(output.by_type("IfcWallType")) == 2
85+
7786

7887
class TestMergeDuplicateTypesIFC2X3(test.bootstrap.IFC2X3, TestMergeDuplicateTypes):
7988
pass

0 commit comments

Comments
 (0)