mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-24 15:07:38 +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:
|
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
|
"""Merge duplicate element types via the Tag or another attribute
|
||||||
|
|
||||||
Revit is notorious for creating many duplicate element types. Element
|
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
|
: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
|
on. Typically this will be "Tag" as it stores the unique ID from the
|
||||||
proprietary BIM software.
|
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:
|
Example:
|
||||||
|
|
||||||
@@ -64,12 +66,15 @@ class Patcher:
|
|||||||
self.file = file
|
self.file = file
|
||||||
self.logger = logger
|
self.logger = logger
|
||||||
self.attribute = attribute
|
self.attribute = attribute
|
||||||
|
self.should_merge_null = should_merge_null
|
||||||
|
|
||||||
def patch(self):
|
def patch(self):
|
||||||
key = self.attribute
|
|
||||||
keys: dict[Any, ifcopenshell.entity_instance] = {}
|
keys: dict[Any, ifcopenshell.entity_instance] = {}
|
||||||
for element_type in self.file.by_type("IfcTypeObject"):
|
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:
|
if original_type:
|
||||||
elements = ifcopenshell.util.element.get_types(element_type)
|
elements = ifcopenshell.util.element.get_types(element_type)
|
||||||
if elements:
|
if elements:
|
||||||
@@ -78,7 +83,7 @@ class Patcher:
|
|||||||
ifcopenshell.util.element.replace_attribute(inverse, element_type, original_type)
|
ifcopenshell.util.element.replace_attribute(inverse, element_type, original_type)
|
||||||
self.file.remove(element_type)
|
self.file.remove(element_type)
|
||||||
else:
|
else:
|
||||||
keys[getattr(element_type, key)] = element_type
|
keys[key] = element_type
|
||||||
|
|
||||||
def assign_type(
|
def assign_type(
|
||||||
self, related_objects: list[ifcopenshell.entity_instance], relating_type: ifcopenshell.entity_instance
|
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(wall1, should_inherit=False) == None
|
||||||
assert ifcopenshell.util.element.get_material(wall2, 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):
|
class TestMergeDuplicateTypesIFC2X3(test.bootstrap.IFC2X3, TestMergeDuplicateTypes):
|
||||||
pass
|
pass
|
||||||
|
|||||||
Reference in New Issue
Block a user