mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-19 14:41:25 +00:00
Copy deep can now exclude things, useful for copying representation graphs where you don't want to duplicate the context
This commit is contained in:
@@ -190,13 +190,17 @@ def get_elements_by_material(ifc_file, material):
|
|||||||
"""
|
"""
|
||||||
Retrieves the elements related to a material.
|
Retrieves the elements related to a material.
|
||||||
|
|
||||||
|
This includes elements using the material as part of a material set or set
|
||||||
|
usage.
|
||||||
|
|
||||||
:param ifc_file: The IFC file
|
:param ifc_file: The IFC file
|
||||||
:param material: The IFC Material entity
|
:param material: The IFC Material entity
|
||||||
:return: The elements related to the material
|
:return: A list of elements using the to the material
|
||||||
|
|
||||||
Example::
|
Example::
|
||||||
material = file.by_type("IfcMaterial")[0]
|
|
||||||
elements = ifcopenshell.util.element.get_elements_by_material(file, material)
|
material = file.by_type("IfcMaterial")[0]
|
||||||
|
elements = ifcopenshell.util.element.get_elements_by_material(file, material)
|
||||||
"""
|
"""
|
||||||
results = set()
|
results = set()
|
||||||
for inverse in ifc_file.get_inverse(material):
|
for inverse in ifc_file.get_inverse(material):
|
||||||
@@ -229,9 +233,9 @@ def get_elements_by_style(ifc_file, style):
|
|||||||
:return: The elements related to the style
|
:return: The elements related to the style
|
||||||
|
|
||||||
Example::
|
Example::
|
||||||
style = file.by_type("IfcSurfaceStyle")[0]
|
|
||||||
elements = ifcopenshell.util.element.get_elements_by_style(file, style)
|
|
||||||
|
|
||||||
|
style = file.by_type("IfcSurfaceStyle")[0]
|
||||||
|
elements = ifcopenshell.util.element.get_elements_by_style(file, style)
|
||||||
"""
|
"""
|
||||||
results = set()
|
results = set()
|
||||||
inverses = list(ifc_file.get_inverse(style))
|
inverses = list(ifc_file.get_inverse(style))
|
||||||
@@ -482,6 +486,15 @@ def remove_deep2(ifc_file, element, also_consider=[], do_not_delete=[]):
|
|||||||
|
|
||||||
|
|
||||||
def copy(ifc_file, element):
|
def copy(ifc_file, element):
|
||||||
|
"""
|
||||||
|
Copy a single element. Any referenced elements are not copied.
|
||||||
|
|
||||||
|
GlobalIds are regenerated.
|
||||||
|
|
||||||
|
:param ifc_file: The IFC file object
|
||||||
|
:param element: The IFC element to copy
|
||||||
|
:return: The newly copied element
|
||||||
|
"""
|
||||||
new = ifc_file.create_entity(element.is_a())
|
new = ifc_file.create_entity(element.is_a())
|
||||||
for i, attribute in enumerate(element):
|
for i, attribute in enumerate(element):
|
||||||
if attribute is None:
|
if attribute is None:
|
||||||
@@ -493,16 +506,33 @@ def copy(ifc_file, element):
|
|||||||
return new
|
return new
|
||||||
|
|
||||||
|
|
||||||
def copy_deep(ifc_file, element):
|
def copy_deep(ifc_file, element, exclude=None):
|
||||||
|
"""
|
||||||
|
Recursively copy an element and all of its directly related subelements.
|
||||||
|
|
||||||
|
GlobalIds are regenerated.
|
||||||
|
|
||||||
|
:param ifc_file: The IFC file object
|
||||||
|
:param element: The IFC element to copy
|
||||||
|
:param exclude: An optional list of strings of IFC class names to not copy.
|
||||||
|
If any of the subelement is this class, it will not be copied and the
|
||||||
|
original instance will be referenced.
|
||||||
|
:return: The newly copied element
|
||||||
|
"""
|
||||||
new = ifc_file.create_entity(element.is_a())
|
new = ifc_file.create_entity(element.is_a())
|
||||||
for i, attribute in enumerate(element):
|
for i, attribute in enumerate(element):
|
||||||
if attribute is None:
|
if attribute is None:
|
||||||
continue
|
continue
|
||||||
if isinstance(attribute, ifcopenshell.entity_instance):
|
if isinstance(attribute, ifcopenshell.entity_instance):
|
||||||
attribute = copy_deep(ifc_file, attribute)
|
if not exclude or (exclude and not any([attribute.is_a(e) for e in exclude])):
|
||||||
|
attribute = copy_deep(ifc_file, attribute, exclude=exclude)
|
||||||
elif isinstance(attribute, tuple) and attribute and isinstance(attribute[0], ifcopenshell.entity_instance):
|
elif isinstance(attribute, tuple) and attribute and isinstance(attribute[0], ifcopenshell.entity_instance):
|
||||||
attribute = list(attribute)
|
if not exclude or (exclude and not any([attribute[0].is_a(e) for e in exclude])):
|
||||||
for j, item in enumerate(attribute):
|
attribute = list(attribute)
|
||||||
attribute[j] = copy_deep(ifc_file, item)
|
for j, item in enumerate(attribute):
|
||||||
new[i] = attribute
|
attribute[j] = copy_deep(ifc_file, item, exclude=exclude)
|
||||||
|
if new.attribute_name(i) == "GlobalId":
|
||||||
|
new[i] = ifcopenshell.guid.new()
|
||||||
|
else:
|
||||||
|
new[i] = attribute
|
||||||
return new
|
return new
|
||||||
|
|||||||
@@ -668,6 +668,7 @@ class TestCopyDeepIFC4(test.bootstrap.IFC4):
|
|||||||
element = self.file.createIfcWall(GlobalId="id", Name="name", OwnerHistory=owner)
|
element = self.file.createIfcWall(GlobalId="id", Name="name", OwnerHistory=owner)
|
||||||
element2 = subject.copy_deep(self.file, element)
|
element2 = subject.copy_deep(self.file, element)
|
||||||
assert element.OwnerHistory != element2.OwnerHistory
|
assert element.OwnerHistory != element2.OwnerHistory
|
||||||
|
assert element.GlobalId != element2.GlobalId
|
||||||
assert element.OwnerHistory.State == element2.OwnerHistory.State
|
assert element.OwnerHistory.State == element2.OwnerHistory.State
|
||||||
|
|
||||||
def test_copying_an_element_recursively_even_if_references_are_aggregated(self):
|
def test_copying_an_element_recursively_even_if_references_are_aggregated(self):
|
||||||
@@ -677,3 +678,17 @@ class TestCopyDeepIFC4(test.bootstrap.IFC4):
|
|||||||
rel2 = subject.copy_deep(self.file, rel)
|
rel2 = subject.copy_deep(self.file, rel)
|
||||||
assert rel.RelatedObjects != rel2.RelatedObjects
|
assert rel.RelatedObjects != rel2.RelatedObjects
|
||||||
assert rel.RelatedObjects[0].Name == rel2.RelatedObjects[0].Name
|
assert rel.RelatedObjects[0].Name == rel2.RelatedObjects[0].Name
|
||||||
|
|
||||||
|
def test_copying_an_element_recursively_with_an_exclude_filter(self):
|
||||||
|
owner = self.file.createIfcOwnerHistory()
|
||||||
|
owner.State = "READWRITE"
|
||||||
|
element = self.file.createIfcWall(GlobalId="id", Name="name", OwnerHistory=owner)
|
||||||
|
element2 = subject.copy_deep(self.file, element, exclude=["IfcOwnerHistory"])
|
||||||
|
assert element.OwnerHistory == element2.OwnerHistory
|
||||||
|
|
||||||
|
def test_copying_an_element_recursively_with_aggregates_with_an_exclude_filter(self):
|
||||||
|
element = self.file.createIfcWall(Name="name")
|
||||||
|
rel = self.file.createIfcRelAggregates()
|
||||||
|
rel.RelatedObjects = [element]
|
||||||
|
rel2 = subject.copy_deep(self.file, rel, exclude=["IfcWall"])
|
||||||
|
assert rel.RelatedObjects == rel2.RelatedObjects
|
||||||
|
|||||||
Reference in New Issue
Block a user