Files
IfcOpenShell/src/ifcopenshell-python/ifcopenshell/api/geometry/remove_representation.py
T
Andrej730 25d8fff5fd remove_representation - small optimizations
check schema version instead of accessing attribute directly (hasattr under the hood is just doing getattr and checking whether it returns AttributeError), so one less IFC access

Similar thing with element.Item to access IFC just once.
2025-02-20 19:12:24 +05:00

85 lines
3.5 KiB
Python

# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell.util.element
def remove_representation(
file: ifcopenshell.file, representation: ifcopenshell.entity_instance, should_keep_named_profiles: bool = True
) -> None:
"""Remove a representation.
Also purges representation items and their related elements
like IfcStyledItem, tessellated facesets colours and UV map.
By default, named profiles are assumed to be significant (i.e. curated as
part of a profile library) and will not be removed.
:param representation: IfcRepresentation to remove.
Note that it's expected that IfcRepresentation won't be in use
before calling this method (in such elements as IfcProductRepresentation, IfcShapeAspect)
otherwise representation won't be removed.
:param should_keep_named_profiles: If true, named profile defs will not be
removed as they are assumed to be significant.
"""
is_ifc2x3 = file.schema == "IFC2X3"
styled_items = set()
presentation_layer_assignments = set()
textures = set()
colours = set()
named_profiles = set()
for subelement in file.traverse(representation):
if subelement.is_a("IfcRepresentationItem"):
[styled_items.add(s) for s in subelement.StyledByItem or []]
# IFC2X3 is using LayerAssignments
for s in subelement.LayerAssignment if not is_ifc2x3 else subelement.LayerAssignments:
presentation_layer_assignments.add(s)
# IfcTessellatedFaceSet inverses
[textures.add(t) for t in getattr(subelement, "HasTextures", []) or []]
[colours.add(t) for t in getattr(subelement, "HasColours", []) or []]
elif subelement.is_a("IfcRepresentation"):
for layer in subelement.LayerAssignments:
presentation_layer_assignments.add(layer)
elif subelement.is_a("IfcProfileDef") and subelement.ProfileName:
named_profiles.add(subelement)
do_not_delete = file.by_type("IfcGeometricRepresentationContext")
if should_keep_named_profiles:
do_not_delete += named_profiles
ifcopenshell.util.element.remove_deep2(
file,
representation,
also_consider=list(styled_items | presentation_layer_assignments | colours),
do_not_delete=do_not_delete,
)
for texture in textures:
ifcopenshell.util.element.remove_deep2(file, texture)
for colour in colours:
ifcopenshell.util.element.remove_deep2(file, colour)
to_delete = file.to_delete or set()
for element in styled_items:
item = element.Item
if not item or item in to_delete:
file.remove(element)
for element in presentation_layer_assignments:
if all(item in to_delete for item in element.AssignedItems):
file.remove(element)