diff --git a/src/blenderbim/blenderbim/bim/helper.py b/src/blenderbim/blenderbim/bim/helper.py index 5682f5ee37..48bc67a294 100644 --- a/src/blenderbim/blenderbim/bim/helper.py +++ b/src/blenderbim/blenderbim/bim/helper.py @@ -323,6 +323,7 @@ def draw_filter(layout, filter_groups, data, module): row = box.row(align=True) row.prop(ifc_filter, "pset", text="", icon="PROPERTIES") row.prop(ifc_filter, "name", text="") + row.prop(ifc_filter, "comparison", text="") row.prop(ifc_filter, "value", text="") elif ifc_filter.type == "classification": row = box.row(align=True) diff --git a/src/blenderbim/blenderbim/bim/prop.py b/src/blenderbim/blenderbim/bim/prop.py index c35aac8ea6..392bc330cb 100644 --- a/src/blenderbim/blenderbim/bim/prop.py +++ b/src/blenderbim/blenderbim/bim/prop.py @@ -481,7 +481,16 @@ class BIMFacet(PropertyGroup): pset: StringProperty(name="Pset") value: StringProperty(name="Value") type: StringProperty(name="Type") - comparison: StringProperty(name="Comparison") + comparison: EnumProperty( + items=[ + ("=", "equal to", ""), + ("!=", "not equal to", ""), + (">=", "greater than or equal to", ""), + ("<=", "lesser than or equal to", ""), + (">", "greater than", ""), + ("<", "less than", ""), + ], + ) class BIMFilterGroup(PropertyGroup): diff --git a/src/blenderbim/blenderbim/tool/search.py b/src/blenderbim/blenderbim/tool/search.py index 7918a428d4..0ae0f8991b 100644 --- a/src/blenderbim/blenderbim/tool/search.py +++ b/src/blenderbim/blenderbim/tool/search.py @@ -64,8 +64,9 @@ class Search(blenderbim.core.tool.Search): continue pset = cls.wrap_value(ifc_filter, ifc_filter.pset) name = cls.wrap_value(ifc_filter, ifc_filter.name) - comparison, value = cls.get_comparison_and_value(ifc_filter) - filter_group_query.append(f"{pset}.{name}{comparison}{value}") + comparison = ifc_filter.comparison + value = cls.wrap_value(ifc_filter, ifc_filter.value) + filter_group_query.append(f"{pset}.{name} {comparison} {value}") elif ifc_filter.type == "classification": comparison, value = cls.get_comparison_and_value(ifc_filter) filter_group_query.append(f"classification{comparison}{value}") @@ -141,7 +142,9 @@ class ImportFilterQueryTransformer(lark.Transformer): new2.name = arg["name"] if "pset" in arg: new2.pset = arg["pset"] - + if "comparison" in arg: + new2.comparison = arg["comparison"] +###################################################################### def facet(self, args): return args[0] @@ -166,7 +169,8 @@ class ImportFilterQueryTransformer(lark.Transformer): def property(self, args): pset, prop, comparison, value = args - return {"type": "property", "pset": pset, "name": prop, "value": f"{comparison}{value}"} + #return {"type": "property", "pset": pset, "name": prop, "value": f"{comparison}{value}"} + return {"type": "property", "pset": pset, "name": prop, "comparison" : comparison, "value": f"{value}"} def classification(self, args): comparison, value = args @@ -185,7 +189,19 @@ class ImportFilterQueryTransformer(lark.Transformer): return {"type": "query", "name": keys, "value": f"{comparison}{value}"} def comparison(self, args): - return "" if args[0].data == "equals" else "!=" + if args[0].data == "equals": + return "=" + elif args[0].data == "morethanequalto": + return ">=" + elif args[0].data == "lessthanequalto": + return "<=" + elif args[0].data == "morethan": + return ">" + elif args[0].data == "lessthan": + return "<" + else: + return "!=" + #return "" if args[0].data == "equals" else "!=" def keys(self, args): return self.value(args) diff --git a/src/ifcopenshell-python/ifcopenshell/util/selector.py b/src/ifcopenshell-python/ifcopenshell/util/selector.py index ec9ef7667c..73f6bcf4b2 100644 --- a/src/ifcopenshell-python/ifcopenshell/util/selector.py +++ b/src/ifcopenshell-python/ifcopenshell/util/selector.py @@ -61,9 +61,13 @@ filter_elements_grammar = lark.Lark( special: null | true | false - comparison: not? equals + comparison: not? equals | morethanequalto | lessthanequalto | morethan | lessthan not: "!" equals: "=" + morethanequalto: ">=" + lessthanequalto: "<=" + morethan: ">" + lessthan: "<" null: "NULL" true: "TRUE" false: "FALSE" @@ -553,7 +557,18 @@ class FacetTransformer(lark.Transformer): return tree def comparison(self, args): - return "=" if args[0].data == "equals" else "!=" + if args[0].data == "equals": + return "=" + elif args[0].data == "morethanequalto": + return ">=" + elif args[0].data == "lessthanequalto": + return "<=" + elif args[0].data == "morethan": + return ">" + elif args[0].data == "lessthan": + return "<" + else: + return "!=" def keys(self, args): return self.value(args) @@ -580,19 +595,35 @@ class FacetTransformer(lark.Transformer): return False def compare(self, element_value, comparison, value): - if isinstance(element_value, (list, tuple)): - return any(self.compare(ev, comparison, value) for ev in element_value) - elif isinstance(value, str): - if isinstance(element_value, int): - value = int(value) - elif isinstance(element_value, float): - value = float(value) - result = element_value == value - elif isinstance(value, re.Pattern): - result = bool(value.match(element_value)) if element_value is not None else False - elif value in (None, True, False): - result = element_value is value - return result if comparison == "=" else not result + if element_value: + if isinstance(element_value, (list, tuple)): + return any(self.compare(ev, comparison, value) for ev in element_value) + elif isinstance(value, re.Pattern): + result = bool(value.match(element_value)) if element_value is not None else False + elif isinstance(value, str): + if isinstance(element_value, int): + value = int(value) + elif isinstance(element_value, float): + value = float(value) + + if comparison == "=": + result = element_value == value + elif comparison == ">": + result = element_value > value + elif comparison == "<": + result = element_value < value + elif comparison == ">=": + result = element_value >= value + elif comparison == "<= ": + result = element_value <= value + else: + result = element_value != value + + elif value in (None, True, False): + result = element_value is value + else: + result = False + return result class Selector: