mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-11 10:06:47 +00:00
black ifcopenshell-python
This commit is contained in:
@@ -3,65 +3,67 @@ import ifcopenshell.util.element
|
||||
import lark
|
||||
|
||||
cobie_type_assets = [
|
||||
'IfcDoorStyle',
|
||||
'IfcBuildingElementProxyType',
|
||||
'IfcChimneyType',
|
||||
'IfcCoveringType',
|
||||
'IfcDoorType',
|
||||
'IfcFootingType',
|
||||
'IfcPileType',
|
||||
'IfcRoofType',
|
||||
'IfcShadingDeviceType',
|
||||
'IfcWindowType',
|
||||
'IfcDistributionControlElementType',
|
||||
'IfcDistributionChamberElementType',
|
||||
'IfcEnergyConversionDeviceType',
|
||||
'IfcFlowControllerType',
|
||||
'IfcFlowMovingDeviceType',
|
||||
'IfcFlowStorageDeviceType',
|
||||
'IfcFlowTerminalType',
|
||||
'IfcFlowTreatmentDeviceType',
|
||||
'IfcElementAssemblyType',
|
||||
'IfcBuildingElementPartType',
|
||||
'IfcDiscreteAccessoryType',
|
||||
'IfcMechanicalFastenerType',
|
||||
'IfcReinforcingElementType',
|
||||
'IfcVibrationIsolatorType',
|
||||
'IfcFurnishingElementType',
|
||||
'IfcGeographicElementType',
|
||||
'IfcTransportElementType',
|
||||
'IfcSpatialZoneType',
|
||||
'IfcWindowStyle',
|
||||
"IfcDoorStyle",
|
||||
"IfcBuildingElementProxyType",
|
||||
"IfcChimneyType",
|
||||
"IfcCoveringType",
|
||||
"IfcDoorType",
|
||||
"IfcFootingType",
|
||||
"IfcPileType",
|
||||
"IfcRoofType",
|
||||
"IfcShadingDeviceType",
|
||||
"IfcWindowType",
|
||||
"IfcDistributionControlElementType",
|
||||
"IfcDistributionChamberElementType",
|
||||
"IfcEnergyConversionDeviceType",
|
||||
"IfcFlowControllerType",
|
||||
"IfcFlowMovingDeviceType",
|
||||
"IfcFlowStorageDeviceType",
|
||||
"IfcFlowTerminalType",
|
||||
"IfcFlowTreatmentDeviceType",
|
||||
"IfcElementAssemblyType",
|
||||
"IfcBuildingElementPartType",
|
||||
"IfcDiscreteAccessoryType",
|
||||
"IfcMechanicalFastenerType",
|
||||
"IfcReinforcingElementType",
|
||||
"IfcVibrationIsolatorType",
|
||||
"IfcFurnishingElementType",
|
||||
"IfcGeographicElementType",
|
||||
"IfcTransportElementType",
|
||||
"IfcSpatialZoneType",
|
||||
"IfcWindowStyle",
|
||||
]
|
||||
cobie_component_assets = [
|
||||
'IfcBuildingElementProxy',
|
||||
'IfcChimney',
|
||||
'IfcCovering',
|
||||
'IfcDoor',
|
||||
'IfcShadingDevice',
|
||||
'IfcWindow',
|
||||
'IfcDistributionControlElement',
|
||||
'IfcDistributionChamberElement',
|
||||
'IfcEnergyConversionDevice',
|
||||
'IfcFlowController',
|
||||
'IfcFlowMovingDevice',
|
||||
'IfcFlowStorageDevice',
|
||||
'IfcFlowTerminal',
|
||||
'IfcFlowTreatmentDevice',
|
||||
'IfcDiscreteAccessory',
|
||||
'IfcTendon',
|
||||
'IfcTendonAnchor',
|
||||
'IfcVibrationIsolator',
|
||||
'IfcFurnishingElement',
|
||||
'IfcGeographicElement',
|
||||
'IfcTransportElement',
|
||||
"IfcBuildingElementProxy",
|
||||
"IfcChimney",
|
||||
"IfcCovering",
|
||||
"IfcDoor",
|
||||
"IfcShadingDevice",
|
||||
"IfcWindow",
|
||||
"IfcDistributionControlElement",
|
||||
"IfcDistributionChamberElement",
|
||||
"IfcEnergyConversionDevice",
|
||||
"IfcFlowController",
|
||||
"IfcFlowMovingDevice",
|
||||
"IfcFlowStorageDevice",
|
||||
"IfcFlowTerminal",
|
||||
"IfcFlowTreatmentDevice",
|
||||
"IfcDiscreteAccessory",
|
||||
"IfcTendon",
|
||||
"IfcTendonAnchor",
|
||||
"IfcVibrationIsolator",
|
||||
"IfcFurnishingElement",
|
||||
"IfcGeographicElement",
|
||||
"IfcTransportElement",
|
||||
]
|
||||
|
||||
class Selector():
|
||||
|
||||
class Selector:
|
||||
def parse(self, ifc_file, query):
|
||||
self.file = ifc_file
|
||||
|
||||
l = lark.Lark('''start: query (lfunction query)*
|
||||
l = lark.Lark(
|
||||
"""start: query (lfunction query)*
|
||||
query: selector | group
|
||||
group: "(" query (lfunction query)* ")"
|
||||
selector: (inverse_relationship)? guid_selector | (inverse_relationship)? class_selector
|
||||
@@ -111,7 +113,8 @@ class Selector():
|
||||
NEWLINE: (CR? LF)+
|
||||
|
||||
%ignore WS // Disregard spaces in text
|
||||
''')
|
||||
"""
|
||||
)
|
||||
|
||||
start = l.parse(query)
|
||||
return self.get_group(start)
|
||||
@@ -119,24 +122,24 @@ class Selector():
|
||||
def get_group(self, group):
|
||||
lfunction = None
|
||||
for child in group.children:
|
||||
if child.data == 'query':
|
||||
if child.data == "query":
|
||||
new_results = self.get_query(child)
|
||||
if not lfunction:
|
||||
results = new_results
|
||||
elif lfunction == 'or':
|
||||
elif lfunction == "or":
|
||||
results.extend(new_results)
|
||||
elif lfunction == 'and':
|
||||
elif lfunction == "and":
|
||||
results = list(set(results).intersection(new_results))
|
||||
results = list(set(results))
|
||||
elif child.data == 'lfunction':
|
||||
elif child.data == "lfunction":
|
||||
lfunction = child.children[0].data
|
||||
return results
|
||||
|
||||
def get_query(self, query):
|
||||
for child in query.children:
|
||||
if child.data == 'selector':
|
||||
if child.data == "selector":
|
||||
return self.get_selector(child)
|
||||
elif child.data == 'group':
|
||||
elif child.data == "group":
|
||||
return self.get_group(child)
|
||||
|
||||
def get_selector(self, selector):
|
||||
@@ -147,9 +150,9 @@ class Selector():
|
||||
inverse_relationship = selector.children[0]
|
||||
class_or_guid_selector = selector.children[1]
|
||||
|
||||
if class_or_guid_selector.data == 'class_selector':
|
||||
if class_or_guid_selector.data == "class_selector":
|
||||
results = self.get_class_selector(class_or_guid_selector)
|
||||
elif class_or_guid_selector.data == 'guid_selector':
|
||||
elif class_or_guid_selector.data == "guid_selector":
|
||||
results = self.get_guid_selector(class_or_guid_selector)
|
||||
|
||||
if not inverse_relationship:
|
||||
@@ -159,26 +162,25 @@ class Selector():
|
||||
def parse_inverse_relationship(self, elements, inverse_relationship):
|
||||
results = []
|
||||
for element in elements:
|
||||
if inverse_relationship == 'types':
|
||||
if hasattr(element, 'Types') and element.Types:
|
||||
if inverse_relationship == "types":
|
||||
if hasattr(element, "Types") and element.Types:
|
||||
results.extend(element.Types[0].RelatedObjects)
|
||||
elif hasattr(element, 'ObjectTypeOf') and element.ObjectTypeOf:
|
||||
elif hasattr(element, "ObjectTypeOf") and element.ObjectTypeOf:
|
||||
results.extend(element.ObjectTypeOf[0].RelatedObjects)
|
||||
elif inverse_relationship == 'contains_elements' \
|
||||
and hasattr(element, 'ContainsElements'):
|
||||
elif inverse_relationship == "contains_elements" and hasattr(element, "ContainsElements"):
|
||||
for relationship in element.ContainsElements:
|
||||
results.extend(relationship.RelatedElements)
|
||||
return results
|
||||
|
||||
def get_class_selector(self, class_selector):
|
||||
if class_selector.children[0] == 'COBie':
|
||||
if class_selector.children[0] == "COBie":
|
||||
elements = []
|
||||
for ifc_class in cobie_component_assets:
|
||||
try:
|
||||
elements += self.file.by_type(ifc_class)
|
||||
except:
|
||||
pass
|
||||
elif class_selector.children[0] == 'COBieType':
|
||||
elif class_selector.children[0] == "COBieType":
|
||||
elements = []
|
||||
for ifc_class in cobie_type_assets:
|
||||
try:
|
||||
@@ -187,8 +189,7 @@ class Selector():
|
||||
pass
|
||||
else:
|
||||
elements = self.file.by_type(class_selector.children[0])
|
||||
if len(class_selector.children) > 1 \
|
||||
and class_selector.children[1].data == 'filter':
|
||||
if len(class_selector.children) > 1 and class_selector.children[1].data == "filter":
|
||||
return self.filter_elements(elements, class_selector.children[1])
|
||||
return elements
|
||||
|
||||
@@ -196,7 +197,7 @@ class Selector():
|
||||
results = []
|
||||
key = filter_rule.children[0].children[0]
|
||||
if not isinstance(key, str):
|
||||
key = key.children[0] + '.' + key.children[1]
|
||||
key = key.children[0] + "." + key.children[1]
|
||||
comparison = value = None
|
||||
if len(filter_rule.children) > 1:
|
||||
comparison = filter_rule.children[1].children[0].data
|
||||
@@ -205,42 +206,40 @@ class Selector():
|
||||
element_value = self.get_element_value(element, key)
|
||||
if not element_value:
|
||||
continue
|
||||
if not comparison \
|
||||
or self.filter_element(element, element_value, comparison, value):
|
||||
if not comparison or self.filter_element(element, element_value, comparison, value):
|
||||
results.append(element)
|
||||
return results
|
||||
|
||||
def get_element_value(self, element, key):
|
||||
if '.' in key \
|
||||
and key.split('.')[0] == 'type':
|
||||
if "." in key and key.split(".")[0] == "type":
|
||||
try:
|
||||
element = ifcopenshell.util.element.get_type(element)
|
||||
if not element:
|
||||
return None
|
||||
except:
|
||||
return
|
||||
key = '.'.join(key.split('.')[1:])
|
||||
key = ".".join(key.split(".")[1:])
|
||||
info = element.get_info()
|
||||
if key in info:
|
||||
return info[key]
|
||||
elif '.' in key:
|
||||
pset_name, prop = key.split('.')
|
||||
elif "." in key:
|
||||
pset_name, prop = key.split(".")
|
||||
psets = ifcopenshell.util.element.get_psets(element)
|
||||
if pset_name in psets and prop in psets[pset_name]:
|
||||
return psets[pset_name][prop]
|
||||
|
||||
def filter_element(self, element, element_value, comparison, value):
|
||||
if comparison == 'equal':
|
||||
if comparison == "equal":
|
||||
return str(element_value) == value
|
||||
elif comparison == 'contains':
|
||||
elif comparison == "contains":
|
||||
return value in str(element_value)
|
||||
elif comparison == 'morethan':
|
||||
elif comparison == "morethan":
|
||||
return element_value > float(value)
|
||||
elif comparison == 'lessthan':
|
||||
elif comparison == "lessthan":
|
||||
return element_value < float(value)
|
||||
elif comparison == 'morethanequalto':
|
||||
elif comparison == "morethanequalto":
|
||||
return element_value >= float(value)
|
||||
elif comparison == 'lessthanequalto':
|
||||
elif comparison == "lessthanequalto":
|
||||
return element_value <= float(value)
|
||||
return False
|
||||
|
||||
|
||||
Reference in New Issue
Block a user