mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-21 10:23:41 +00:00
Fallback for queries if no elements filter is provided #5901
This commit is contained in:
@@ -64,19 +64,16 @@ class Search(bonsai.core.tool.Search):
|
|||||||
query = []
|
query = []
|
||||||
for filter_group in filter_groups:
|
for filter_group in filter_groups:
|
||||||
filter_group_query = []
|
filter_group_query = []
|
||||||
has_instance_or_entity_filter = False
|
|
||||||
for ifc_filter in filter_group.filters:
|
for ifc_filter in filter_group.filters:
|
||||||
if not ifc_filter.value:
|
if not ifc_filter.value:
|
||||||
continue
|
continue
|
||||||
if ifc_filter.type == "instance":
|
if ifc_filter.type == "instance":
|
||||||
has_instance_or_entity_filter = True
|
|
||||||
if "bpy.data.texts" in ifc_filter.value:
|
if "bpy.data.texts" in ifc_filter.value:
|
||||||
data_name = ifc_filter.value.split("bpy.data.texts")[1][2:-2]
|
data_name = ifc_filter.value.split("bpy.data.texts")[1][2:-2]
|
||||||
filter_group_query.append(bpy.data.texts[data_name].as_string())
|
filter_group_query.append(bpy.data.texts[data_name].as_string())
|
||||||
else:
|
else:
|
||||||
filter_group_query.append(ifc_filter.value)
|
filter_group_query.append(ifc_filter.value)
|
||||||
elif ifc_filter.type == "entity":
|
elif ifc_filter.type == "entity":
|
||||||
has_instance_or_entity_filter = True
|
|
||||||
filter_group_query.append(ifc_filter.value)
|
filter_group_query.append(ifc_filter.value)
|
||||||
elif ifc_filter.type == "attribute":
|
elif ifc_filter.type == "attribute":
|
||||||
if not ifc_filter.name:
|
if not ifc_filter.name:
|
||||||
@@ -113,9 +110,6 @@ class Search(bonsai.core.tool.Search):
|
|||||||
keys = cls.wrap_value(ifc_filter, ifc_filter.name)
|
keys = cls.wrap_value(ifc_filter, ifc_filter.name)
|
||||||
comparison, value = cls.get_comparison_and_value(ifc_filter)
|
comparison, value = cls.get_comparison_and_value(ifc_filter)
|
||||||
filter_group_query.append(f"query:{keys}{comparison}{value}")
|
filter_group_query.append(f"query:{keys}{comparison}{value}")
|
||||||
if not has_instance_or_entity_filter:
|
|
||||||
filter_group_query.insert(0, "IfcProduct")
|
|
||||||
filter_group_query.insert(0, "IfcTypeProduct")
|
|
||||||
query.append(", ".join(filter_group_query))
|
query.append(", ".join(filter_group_query))
|
||||||
return " + ".join(query)
|
return " + ".join(query)
|
||||||
|
|
||||||
|
|||||||
@@ -87,9 +87,15 @@ The filters are chained and apply from left to right.
|
|||||||
|
|
||||||
filter[, filter]*
|
filter[, filter]*
|
||||||
|
|
||||||
There are nine types of filters to choose from. Some of these filters will add
|
Below is the table of filters to choose from. Most of these filters will filter
|
||||||
new elements to your filter group, and some will filter previously added
|
previously added elements in your filter group based on their criteria.
|
||||||
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::
|
.. csv-table::
|
||||||
:header: "Filter", "Type", "Usage", "Example"
|
:header: "Filter", "Type", "Usage", "Example"
|
||||||
|
|||||||
@@ -771,6 +771,23 @@ class FacetTransformer(lark.Transformer):
|
|||||||
results |= r
|
results |= r
|
||||||
return results
|
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):
|
def facet_list(self, args):
|
||||||
if self.elements:
|
if self.elements:
|
||||||
self.results.append(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, "IfcWall") == {element}
|
||||||
assert subject.filter_elements(self.file, "IfcElement, ! IfcWall") == {element2}
|
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):
|
def test_selecting_by_attribute(self):
|
||||||
element = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall")
|
element = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall")
|
||||||
element.Name = "Foo"
|
element.Name = "Foo"
|
||||||
|
|||||||
Reference in New Issue
Block a user