mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-21 14:23:53 +00:00
remove_representation - optimizations
1) `do_not_delete` performs best when it's set 2) also_consider when `element` related elements go first, so there will be no need to traverse all other elements to see if they cover `element`'s inverses.
This commit is contained in:
@@ -39,7 +39,8 @@ def remove_representation(
|
|||||||
"""
|
"""
|
||||||
is_ifc2x3 = file.schema == "IFC2X3"
|
is_ifc2x3 = file.schema == "IFC2X3"
|
||||||
styled_items = set()
|
styled_items = set()
|
||||||
presentation_layer_assignments = set()
|
presentation_layer_assignments_items: set[ifcopenshell.entity_instance] = set()
|
||||||
|
presentation_layer_assignments_reps: set[ifcopenshell.entity_instance] = set()
|
||||||
textures = set()
|
textures = set()
|
||||||
colours = set()
|
colours = set()
|
||||||
named_profiles = set()
|
named_profiles = set()
|
||||||
@@ -48,13 +49,13 @@ def remove_representation(
|
|||||||
[styled_items.add(s) for s in subelement.StyledByItem or []]
|
[styled_items.add(s) for s in subelement.StyledByItem or []]
|
||||||
# IFC2X3 is using LayerAssignments
|
# IFC2X3 is using LayerAssignments
|
||||||
for s in subelement.LayerAssignment if not is_ifc2x3 else subelement.LayerAssignments:
|
for s in subelement.LayerAssignment if not is_ifc2x3 else subelement.LayerAssignments:
|
||||||
presentation_layer_assignments.add(s)
|
presentation_layer_assignments_items.add(s)
|
||||||
# IfcTessellatedFaceSet inverses
|
# IfcTessellatedFaceSet inverses
|
||||||
[textures.add(t) for t in getattr(subelement, "HasTextures", []) or []]
|
[textures.add(t) for t in getattr(subelement, "HasTextures", []) or []]
|
||||||
[colours.add(t) for t in getattr(subelement, "HasColours", []) or []]
|
[colours.add(t) for t in getattr(subelement, "HasColours", []) or []]
|
||||||
elif subelement.is_a("IfcRepresentation"):
|
elif subelement.is_a("IfcRepresentation"):
|
||||||
for layer in subelement.LayerAssignments:
|
for layer in subelement.LayerAssignments:
|
||||||
presentation_layer_assignments.add(layer)
|
presentation_layer_assignments_reps.add(layer)
|
||||||
elif subelement.is_a("IfcProfileDef") and subelement.ProfileName:
|
elif subelement.is_a("IfcProfileDef") and subelement.ProfileName:
|
||||||
named_profiles.add(subelement)
|
named_profiles.add(subelement)
|
||||||
|
|
||||||
@@ -62,11 +63,16 @@ def remove_representation(
|
|||||||
if should_keep_named_profiles:
|
if should_keep_named_profiles:
|
||||||
do_not_delete += named_profiles
|
do_not_delete += named_profiles
|
||||||
|
|
||||||
|
# Order matters - layer assignments may reference representation directly.
|
||||||
|
also_consider = list(presentation_layer_assignments_reps)
|
||||||
|
also_consider.extend(presentation_layer_assignments_items - presentation_layer_assignments_reps)
|
||||||
|
also_consider.extend(styled_items)
|
||||||
|
also_consider.extend(textures)
|
||||||
ifcopenshell.util.element.remove_deep2(
|
ifcopenshell.util.element.remove_deep2(
|
||||||
file,
|
file,
|
||||||
representation,
|
representation,
|
||||||
also_consider=list(styled_items | presentation_layer_assignments | colours),
|
also_consider=also_consider,
|
||||||
do_not_delete=do_not_delete,
|
do_not_delete=set(do_not_delete),
|
||||||
)
|
)
|
||||||
|
|
||||||
for texture in textures:
|
for texture in textures:
|
||||||
@@ -79,6 +85,7 @@ def remove_representation(
|
|||||||
item = element.Item
|
item = element.Item
|
||||||
if not item or item in to_delete:
|
if not item or item in to_delete:
|
||||||
file.remove(element)
|
file.remove(element)
|
||||||
|
presentation_layer_assignments = presentation_layer_assignments_reps | presentation_layer_assignments_items
|
||||||
for element in presentation_layer_assignments:
|
for element in presentation_layer_assignments:
|
||||||
if all(item in to_delete for item in element.AssignedItems):
|
if all(item in to_delete for item in element.AssignedItems):
|
||||||
file.remove(element)
|
file.remove(element)
|
||||||
|
|||||||
@@ -1434,7 +1434,7 @@ def remove_deep2(
|
|||||||
ifc_file: ifcopenshell.file,
|
ifc_file: ifcopenshell.file,
|
||||||
element: ifcopenshell.entity_instance,
|
element: ifcopenshell.entity_instance,
|
||||||
also_consider: list[ifcopenshell.entity_instance] = [],
|
also_consider: list[ifcopenshell.entity_instance] = [],
|
||||||
do_not_delete: list[ifcopenshell.entity_instance] = [],
|
do_not_delete: set[ifcopenshell.entity_instance] = set(),
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Recursively purges a subgraph safely, starting at an element
|
"""Recursively purges a subgraph safely, starting at an element
|
||||||
|
|
||||||
@@ -1462,6 +1462,8 @@ def remove_deep2(
|
|||||||
|
|
||||||
:param ifc_file: The IFC file object
|
:param ifc_file: The IFC file object
|
||||||
:param also_consider: elements to also consider as a part of a subgraph
|
:param also_consider: elements to also consider as a part of a subgraph
|
||||||
|
Order could matter for perfomance - elements that reference `element`
|
||||||
|
directly should go first for the better performance.
|
||||||
:param do_not_delete: elements to protect from deletion
|
:param do_not_delete: elements to protect from deletion
|
||||||
:param element: The starting element that defines the subgraph
|
:param element: The starting element that defines the subgraph
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user