This commit is contained in:
Andrej730
2024-03-21 11:20:57 +05:00
parent bae58e517a
commit 489e92da4e
3 changed files with 19 additions and 8 deletions
+11 -7
View File
@@ -5,15 +5,17 @@ import blenderbim.core.tool
import blenderbim.tool as tool import blenderbim.tool as tool
import ifcopenshell.util.selector import ifcopenshell.util.selector
from ifcopenshell.util.selector import Selector from ifcopenshell.util.selector import Selector
from blenderbim.bim.prop import BIMFacet
from typing import Union, Literal
class Search(blenderbim.core.tool.Search): class Search(blenderbim.core.tool.Search):
@classmethod @classmethod
def get_group_query(cls, group): def get_group_query(cls, group: ifcopenshell.entity_instance) -> str:
return json.loads(group.Description)["query"] return json.loads(group.Description)["query"]
@classmethod @classmethod
def get_filter_groups(cls, module): def get_filter_groups(cls, module: str) -> bpy.types.bpy_prop_collection:
if module == "search": if module == "search":
return bpy.context.scene.BIMSearchProperties.filter_groups return bpy.context.scene.BIMSearchProperties.filter_groups
elif module == "csv": elif module == "csv":
@@ -24,13 +26,13 @@ class Search(blenderbim.core.tool.Search):
return bpy.context.active_object.data.BIMCameraProperties.exclude_filter_groups return bpy.context.active_object.data.BIMCameraProperties.exclude_filter_groups
@classmethod @classmethod
def import_filter_query(cls, query, filter_groups): def import_filter_query(cls, query: str, filter_groups: bpy.types.bpy_prop_collection) -> None:
filter_groups.clear() filter_groups.clear()
transformer = ImportFilterQueryTransformer(filter_groups) transformer = ImportFilterQueryTransformer(filter_groups)
transformer.transform(ifcopenshell.util.selector.filter_elements_grammar.parse(query)) transformer.transform(ifcopenshell.util.selector.filter_elements_grammar.parse(query))
@classmethod @classmethod
def export_filter_query(cls, filter_groups): def export_filter_query(cls, filter_groups: bpy.types.bpy_prop_collection) -> str:
query = [] query = []
for filter_group in filter_groups: for filter_group in filter_groups:
filter_group_query = [] filter_group_query = []
@@ -87,13 +89,15 @@ class Search(blenderbim.core.tool.Search):
return " + ".join(query) return " + ".join(query)
@classmethod @classmethod
def get_comparison_and_value(cls, ifc_filter): def get_comparison_and_value(
cls, ifc_filter: BIMFacet
) -> Union[tuple[Literal["!="], str], tuple[Literal["="], str]]:
if ifc_filter.value.startswith("!="): if ifc_filter.value.startswith("!="):
return ("!=", cls.wrap_value(ifc_filter, ifc_filter.value[2:].strip())) return ("!=", cls.wrap_value(ifc_filter, ifc_filter.value[2:].strip()))
return ("=", cls.wrap_value(ifc_filter, ifc_filter.value.strip())) return ("=", cls.wrap_value(ifc_filter, ifc_filter.value.strip()))
@classmethod @classmethod
def wrap_value(cls, ifc_filter, value): def wrap_value(cls, ifc_filter: BIMFacet, value: str) -> str:
if value.startswith("/") and value.endswith("/"): if value.startswith("/") and value.endswith("/"):
return value return value
elif value in ("NULL", "TRUE", "FALSE"): elif value in ("NULL", "TRUE", "FALSE"):
@@ -101,7 +105,7 @@ class Search(blenderbim.core.tool.Search):
return '"' + value.replace('"', '\\"') + '"' return '"' + value.replace('"', '\\"') + '"'
@classmethod @classmethod
def from_selector_query(cls, query): def from_selector_query(cls, query: str) -> list[ifcopenshell.entity_instance]:
"""Returns a list of products from a selector query""" """Returns a list of products from a selector query"""
return Selector().parse(tool.Ifc.get(), query) return Selector().parse(tool.Ifc.get(), query)
@@ -711,7 +711,9 @@ class FacetTransformer(lark.Transformer):
class Selector: class Selector:
@classmethod @classmethod
def parse(cls, ifc_file, query, elements=None): def parse(
cls, ifc_file: ifcopenshell.file, query: str, elements: Optional[list[ifcopenshell.entity_instance]] = None
) -> list[ifcopenshell.entity_instance]:
cls.file = ifc_file cls.file = ifc_file
cls.elements = elements cls.elements = elements
l = lark.Lark( l = lark.Lark(
@@ -21,6 +21,7 @@ import test.bootstrap
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.util.selector as subject import ifcopenshell.util.selector as subject
import ifcopenshell.util.placement import ifcopenshell.util.placement
import ifcopenshell.util.pset
import numpy as np import numpy as np
@@ -293,6 +294,10 @@ class TestSetElementValue(test.bootstrap.IFC4):
class TestSelector(test.bootstrap.IFC4): class TestSelector(test.bootstrap.IFC4):
def test_selecting_from_specified_elements(self):
elements = [ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") for _ in range(2)]
assert subject.Selector.parse(self.file, ".IfcWall", elements[:1]) == [elements[0]]
def test_selecting_by_class(self): def test_selecting_by_class(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcSlab") ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcSlab")