Aggregate data types

This commit is contained in:
Thomas Krijnen
2026-01-14 13:59:07 +01:00
parent ffcc02fb99
commit 9147938c36
3 changed files with 14 additions and 12 deletions
@@ -60,9 +60,9 @@ def remove_representation(
elif subelement.is_a("IfcProfileDef") and subelement.ProfileName:
named_profiles.add(subelement)
do_not_delete = file.by_type("IfcGeometricRepresentationContext")
do_not_delete = set(file.by_type("IfcGeometricRepresentationContext"))
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)
@@ -73,7 +73,7 @@ def remove_representation(
file,
representation,
also_consider=also_consider,
do_not_delete=set(do_not_delete),
do_not_delete=do_not_delete,
)
for texture in textures:
@@ -16,6 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
from collections import deque
import ifcopenshell
import ifcopenshell.ifcopenshell_wrapper as W
import ifcopenshell.api.geometry
@@ -302,7 +303,7 @@ class Usecase:
self.whitelisted_inverse_attributes = {
"IfcMaterial": ["HasExternalReferences", "HasProperties", "HasRepresentation"]
}
self.existing_contexts = self.file.by_type("IfcGeometricRepresentationContext")
self.existing_contexts = list(self.file.by_type("IfcGeometricRepresentationContext"))
element = self.add_element(self.settings["element"])
if element.HasRepresentation:
self.reuse_existing_contexts()
@@ -329,7 +330,7 @@ class Usecase:
"IfcProductDefinitionShape": ["HasShapeAspects"],
"IfcRepresentationMap": ["HasShapeAspects"],
}
self.existing_contexts = self.file.by_type("IfcGeometricRepresentationContext")
self.existing_contexts = list(self.file.by_type("IfcGeometricRepresentationContext"))
element = self.add_element(self.settings["element"])
self.reuse_existing_contexts()
return element
@@ -348,7 +349,7 @@ class Usecase:
"IfcProductDefinitionShape": ["HasShapeAspects"],
"IfcRepresentationMap": ["HasShapeAspects"],
}
self.existing_contexts = self.file.by_type("IfcGeometricRepresentationContext")
self.existing_contexts = list(self.file.by_type("IfcGeometricRepresentationContext"))
element = self.add_element(self.settings["element"])
self.reuse_existing_contexts()
@@ -390,9 +391,9 @@ class Usecase:
new = self.file_add(element)
self.added_elements[element.id()] = new
self.check_inverses(element)
subelement_queue = self.settings["library"].traverse(element, max_levels=1)[1:]
subelement_queue = deque(self.settings["library"].traverse(element, max_levels=1)[1:])
while subelement_queue:
subelement = subelement_queue.pop(0)
subelement = subelement_queue.popleft()
existing_element = self.get_existing_element(subelement)
if existing_element:
self.added_elements[subelement.id()] = existing_element
@@ -22,7 +22,7 @@ import ifcopenshell.util.element
import ifcopenshell.util.representation
from typing import Any, Callable, Optional, Union, Literal, overload
from collections.abc import Generator, Sequence
from collections import namedtuple
from collections import deque, namedtuple
MATERIAL_TYPE = Literal[
@@ -958,7 +958,7 @@ def get_elements_by_profile(profile: ifcopenshell.entity_instance) -> set[ifcope
:return: The elements using the profile.
"""
ifc_file = profile.file
queue = ifc_file.get_inverse(profile)
queue = list(ifc_file.get_inverse(profile))
processed: set[ifcopenshell.entity_instance] = set()
representations: set[ifcopenshell.entity_instance] = set()
while queue:
@@ -1661,14 +1661,14 @@ def remove_deep2(
subgraph = list(ifc_file.traverse(element, breadth_first=True))
subgraph.extend(also_consider)
subgraph_set = set(subgraph)
subelement_queue = [element]
subelement_queue = deque([element])
# Cache already processed entities to avoid traversing them multiple time.
# E.g. lots of IFCINDEXEDPOLYCURVES may reference the same IFCCARTESIANPOINTLIST2D.
processed_ids: set[int] = set()
while subelement_queue:
subelement = subelement_queue.pop(0)
subelement = subelement_queue.popleft()
subelement_id = subelement.id()
if (
subelement_id
@@ -1703,6 +1703,7 @@ def remove_deep2(
# We delete elements from subgraph in reverse order to allow batching to work
for subelement in filter(lambda e: e in to_delete, subgraph[::-1]):
to_delete.remove(subelement)
ifc_file.remove(subelement)
# ifc_file.unbatch()