mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-13 02:47:48 +00:00
Fix #7208. Merge duplicates patch recipe can now control merging by empty attributes.
This commit is contained in:
@@ -25,7 +25,7 @@ from typing import Any
|
||||
|
||||
|
||||
class Patcher:
|
||||
def __init__(self, file: ifcopenshell.file, logger: Logger, attribute: str = "Tag"):
|
||||
def __init__(self, file: ifcopenshell.file, logger: Logger, attribute: str = "Tag", should_merge_null: bool = True):
|
||||
"""Merge duplicate element types via the Tag or another attribute
|
||||
|
||||
Revit is notorious for creating many duplicate element types. Element
|
||||
@@ -50,6 +50,8 @@ class Patcher:
|
||||
:param attribute: The name of the attribute to merge element types based
|
||||
on. Typically this will be "Tag" as it stores the unique ID from the
|
||||
proprietary BIM software.
|
||||
:param should_merge_null: If True, all elements with an empty attribute
|
||||
will be merged. If False, they will be kept separate.
|
||||
|
||||
Example:
|
||||
|
||||
@@ -64,12 +66,15 @@ class Patcher:
|
||||
self.file = file
|
||||
self.logger = logger
|
||||
self.attribute = attribute
|
||||
self.should_merge_null = should_merge_null
|
||||
|
||||
def patch(self):
|
||||
key = self.attribute
|
||||
keys: dict[Any, ifcopenshell.entity_instance] = {}
|
||||
for element_type in self.file.by_type("IfcTypeObject"):
|
||||
original_type = keys.get(getattr(element_type, key), None)
|
||||
key = getattr(element_type, self.attribute)
|
||||
if not key and not self.should_merge_null:
|
||||
continue
|
||||
original_type = keys.get(key, None)
|
||||
if original_type:
|
||||
elements = ifcopenshell.util.element.get_types(element_type)
|
||||
if elements:
|
||||
@@ -78,7 +83,7 @@ class Patcher:
|
||||
ifcopenshell.util.element.replace_attribute(inverse, element_type, original_type)
|
||||
self.file.remove(element_type)
|
||||
else:
|
||||
keys[getattr(element_type, key)] = element_type
|
||||
keys[key] = element_type
|
||||
|
||||
def assign_type(
|
||||
self, related_objects: list[ifcopenshell.entity_instance], relating_type: ifcopenshell.entity_instance
|
||||
|
||||
@@ -74,6 +74,15 @@ class TestMergeDuplicateTypes(test.bootstrap.IFC4):
|
||||
assert ifcopenshell.util.element.get_material(wall1, should_inherit=False) == None
|
||||
assert ifcopenshell.util.element.get_material(wall2, should_inherit=False) == None
|
||||
|
||||
def test_not_merging_empty_attributes(self):
|
||||
wall_type1 = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWallType", name="")
|
||||
wall_type2 = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWallType", name="")
|
||||
output = ifcpatch.execute({"file": self.file, "recipe": "MergeDuplicateTypes", "arguments": ["Name", True]})
|
||||
assert len(output.by_type("IfcWallType")) == 1
|
||||
wall_type3 = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWallType", name="")
|
||||
output = ifcpatch.execute({"file": self.file, "recipe": "MergeDuplicateTypes", "arguments": ["Name", False]})
|
||||
assert len(output.by_type("IfcWallType")) == 2
|
||||
|
||||
|
||||
class TestMergeDuplicateTypesIFC2X3(test.bootstrap.IFC2X3, TestMergeDuplicateTypes):
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user