mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-17 14:02:27 +00:00
Fix #4786. Speed up parent filter.
This commit is contained in:
@@ -102,6 +102,7 @@ elements in your filter group based on their criteria.
|
|||||||
"Material", "Filter", "``material{{=}}{{value}}``", "``material=Foo`` specifies the criteria that elements must have a IfcMaterial assigned directly or indirectly (such as within a layer set). That IfcMaterial must have either a ``Name`` or ``Category`` attribute with a value of ``Foo``."
|
"Material", "Filter", "``material{{=}}{{value}}``", "``material=Foo`` specifies the criteria that elements must have a IfcMaterial assigned directly or indirectly (such as within a layer set). That IfcMaterial must have either a ``Name`` or ``Category`` attribute with a value of ``Foo``."
|
||||||
"Classification", "Filter", "``classification{{=}}{{value}}``", "``classification=Foo`` specifies the criteria that elements must have an IfcClassificationReference with an ``Identification`` attribute with a value of ``Foo``."
|
"Classification", "Filter", "``classification{{=}}{{value}}``", "``classification=Foo`` specifies the criteria that elements must have an IfcClassificationReference with an ``Identification`` attribute with a value of ``Foo``."
|
||||||
"Location", "Filter", "``location{{=}}{{value}}``", "``location=Foo`` specifies the criteria that elements must be contained directly or indirectly in a spatial element with a ``Name`` attribute with a value of ``Foo``."
|
"Location", "Filter", "``location{{=}}{{value}}``", "``location=Foo`` specifies the criteria that elements must be contained directly or indirectly in a spatial element with a ``Name`` attribute with a value of ``Foo``."
|
||||||
|
"Parent", "Filter", "``parent{{=}}{{value}}``", "``parent=Foo`` specifies the criteria that elements must be a direct or indirect child in the spatial hierarchy to an element with a ``Name`` attribute with a value of ``Foo``."
|
||||||
"Query", "Filter", "``query:{{keys}}{{=}}{{value}}``", "``query:types.count=0`` specifies the criteria that elements must have zero type occurrences. The query keys corresponds to the syntax used in the `Getting element values`_ section"
|
"Query", "Filter", "``query:{{keys}}{{=}}{{value}}``", "``query:types.count=0`` specifies the criteria that elements must have zero type occurrences. The query keys corresponds to the syntax used in the `Getting element values`_ section"
|
||||||
|
|
||||||
When you specify a filter with a ``{{=}}`` check, you can choose from one of
|
When you specify a filter with a ``{{=}}`` check, you can choose from one of
|
||||||
@@ -183,6 +184,7 @@ Valid keys are:
|
|||||||
"``storey``", "Gets the first IfcBuildingStorey spatial element that an element is contained in."
|
"``storey``", "Gets the first IfcBuildingStorey spatial element that an element is contained in."
|
||||||
"``building``", "Gets the first IfcBuilding spatial element that an element is contained in."
|
"``building``", "Gets the first IfcBuilding spatial element that an element is contained in."
|
||||||
"``site``", "Gets the first IccSite spatial element that an element is contained in."
|
"``site``", "Gets the first IccSite spatial element that an element is contained in."
|
||||||
|
"``parent``", "Gets the parent element in the spatial hierarchy."
|
||||||
"``material`` or ``mat``", "Gets the assigned material, which may be a material set."
|
"``material`` or ``mat``", "Gets the assigned material, which may be a material set."
|
||||||
"``item`` or ``i``", "If the previous key returns a material set, gets the relevant material set items"
|
"``item`` or ``i``", "If the previous key returns a material set, gets the relevant material set items"
|
||||||
"``materials`` or ``mats``", "Gets a list of IfcMaterials assigned directly or indirectly (such as via a material set) to the element"
|
"``materials`` or ``mats``", "Gets a list of IfcMaterials assigned directly or indirectly (such as via a material set) to the element"
|
||||||
|
|||||||
@@ -687,21 +687,45 @@ class FacetTransformer(lark.Transformer):
|
|||||||
def parent(self, args):
|
def parent(self, args):
|
||||||
comparison, value = args
|
comparison, value = args
|
||||||
|
|
||||||
def filter_function(element):
|
parents = set()
|
||||||
parents = []
|
for rel in self.file.by_type("IfcRelAggregates"):
|
||||||
result = False
|
parent = rel.RelatingObject
|
||||||
if parent := ifcopenshell.util.element.get_parent(element):
|
if parent and self.compare(parent.Name, comparison, value):
|
||||||
parents.append(parent)
|
parents.add(parent)
|
||||||
while parents:
|
|
||||||
parent = parents.pop()
|
|
||||||
if self.compare(parent.Name, comparison, value):
|
|
||||||
result = True
|
|
||||||
break
|
|
||||||
if grandparent := ifcopenshell.util.element.get_parent(parent):
|
|
||||||
parents.append(grandparent)
|
|
||||||
return result if comparison == "=" else not result
|
|
||||||
|
|
||||||
self.elements = set(filter(filter_function, self.elements))
|
for rel in self.file.by_type("IfcRelContainedInSpatialStructure"):
|
||||||
|
parent = rel.RelatingStructure
|
||||||
|
if parent and self.compare(parent.Name, comparison, value):
|
||||||
|
parents.add(parent)
|
||||||
|
|
||||||
|
for rel in self.file.by_type("IfcRelNests"):
|
||||||
|
parent = rel.RelatingObject
|
||||||
|
if parent and self.compare(parent.Name, comparison, value):
|
||||||
|
parents.add(parent)
|
||||||
|
|
||||||
|
for rel in self.file.by_type("IfcRelVoidsElement"):
|
||||||
|
parent = rel.RelatingBuildingElement
|
||||||
|
if parent and self.compare(parent.Name, comparison, value):
|
||||||
|
parents.add(parent)
|
||||||
|
|
||||||
|
for rel in self.file.by_type("IfcRelVoidsElement"):
|
||||||
|
parent = rel.RelatingBuildingElement
|
||||||
|
if parent and self.compare(parent.Name, comparison, value):
|
||||||
|
parents.add(parent)
|
||||||
|
|
||||||
|
for rel in self.file.by_type("IfcRelFillsElement"):
|
||||||
|
parent = rel.RelatingOpeningElement
|
||||||
|
if parent and self.compare(parent.Name, comparison, value):
|
||||||
|
parents.add(parent)
|
||||||
|
|
||||||
|
children = set()
|
||||||
|
for parent in parents:
|
||||||
|
children |= set(ifcopenshell.util.element.get_decomposition(parent))
|
||||||
|
|
||||||
|
if comparison == "=":
|
||||||
|
self.elements = self.elements & children
|
||||||
|
else:
|
||||||
|
self.elements -= children
|
||||||
|
|
||||||
def query(self, args):
|
def query(self, args):
|
||||||
keys, comparison, value = args
|
keys, comparison, value = args
|
||||||
|
|||||||
Reference in New Issue
Block a user