Fallback for queries if no elements filter is provided #5901

This commit is contained in:
Andrej730
2024-12-25 15:07:28 +05:00
parent e3aaf5defa
commit ff147a4c24
4 changed files with 34 additions and 9 deletions
@@ -87,9 +87,15 @@ The filters are chained and apply from left to right.
filter[, filter]*
There are nine types of filters to choose from. Some of these filters will add
new elements to your filter group, and some will filter previously added
elements in your filter group based on their criteria.
Below is the table of filters to choose from. Most of these filters will filter
previously added elements in your filter group based on their criteria.
There are two exceptions - if ``elements`` are not provided to ``filter_elements``
*Class* and *GlobalId* filters (without ``[!]``) will add new elements to the filter group ,
otherwise they'll also filter elements based on criteria.
If neither *Class* and *GlobalId* and ``elements`` are not provided then filter
will search through all IfcTypeProducts and IfcProducts in the IFC project.
.. csv-table::
:header: "Filter", "Type", "Usage", "Example"
@@ -771,6 +771,23 @@ class FacetTransformer(lark.Transformer):
results |= r
return results
def transform(self, tree: lark.ParseTree):
def has_elements_token(tree: lark.tree.ParseTree) -> bool:
for child in tree.iter_subtrees_topdown():
data = child.data
# Tokens that add elements to filter.
if data in ("entity", "instance"):
return True
return False
# Only elements tokens can add elements to the filter.
# Fallback to default elements if they are not provided.
if self.base_elements is None and not has_elements_token(tree):
self.elements.update(self.file.by_type("IfcProduct"))
self.elements.update(self.file.by_type("IfcTypeProduct"))
return super().transform(tree)
def facet_list(self, args):
if self.elements:
self.results.append(self.elements)
@@ -159,6 +159,14 @@ class TestFilterElements(test.bootstrap.IFC4):
assert subject.filter_elements(self.file, "IfcWall") == {element}
assert subject.filter_elements(self.file, "IfcElement, ! IfcWall") == {element2}
def test_select_without_elements_token(self):
element = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall")
element.Name = "Foo"
element2 = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall")
element2.Name = "Bar"
ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcSlab")
assert subject.filter_elements(self.file, "Name=Foo") == {element}
def test_selecting_by_attribute(self):
element = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall")
element.Name = "Foo"