mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
this one fixes https://github.com/IfcOpenShell/IfcOpenShell/issues/7304
This commit is contained in:
+25
-9
@@ -92,24 +92,40 @@ def quantify(ifc_file: ifcopenshell.file, elements: set[ifcopenshell.entity_inst
|
||||
|
||||
for calculator, queries in rules["calculators"].items():
|
||||
calculator = calculators[calculator]
|
||||
if not set(m.lower() for m in queries.keys()) - lower_case_entity_names(ifc_file.schema_identifier):
|
||||
# all defined queries are actually simple entity names: instead of looping over all
|
||||
# calculators we loop over the entity types so that we don't have to repeatedly query
|
||||
# the model, especially when the set of elements is small.
|
||||
# Cache schema entity names once per file
|
||||
schema_entity_names = lower_case_entity_names(ifc_file.schema_identifier)
|
||||
|
||||
# Fast path: all queries are simple entity names
|
||||
if not set(m.lower() for m in queries.keys()) - schema_entity_names:
|
||||
casenorm = {k.lower(): k for k in queries.keys()}
|
||||
pred = lambda inst: inst.is_a().lower()
|
||||
for ty, elements in itertools.groupby(sorted(elements, key=pred), key=pred):
|
||||
|
||||
for ty, group in itertools.groupby(sorted(elements, key=pred), key=pred):
|
||||
group_elements = list(group)
|
||||
# check entity type and its supertypes for matching QTO rules
|
||||
for sty in entity_supertypes(ifc_file.schema_identifier, ty):
|
||||
if qtos := queries.get(casenorm.get(sty)):
|
||||
calculator.calculate(ifc_file, list(elements), qtos, results)
|
||||
calculator.calculate(ifc_file, group_elements, qtos, results)
|
||||
|
||||
# Fallback: per-query evaluation
|
||||
for query, qtos in queries.items():
|
||||
if query.lower() in lower_case_entity_names(ifc_file.schema_identifier):
|
||||
# by_type is faster than selector parsing
|
||||
filtered_elements = ifc_file.by_type(query)
|
||||
# Simple entity name: use by_type but restrict to incoming elements
|
||||
if query.lower() in schema_entity_names:
|
||||
by_type_all = ifc_file.by_type(query)
|
||||
# ensure we don't expand beyond provided elements subset
|
||||
if isinstance(elements, set):
|
||||
filtered_elements = [e for e in by_type_all if e in elements]
|
||||
else:
|
||||
elements_set = set(elements)
|
||||
filtered_elements = [e for e in by_type_all if e in elements_set]
|
||||
else:
|
||||
filtered_elements = ifcopenshell.util.selector.filter_elements(ifc_file, query, elements)
|
||||
|
||||
if filtered_elements:
|
||||
calculator.calculate(ifc_file, filtered_elements, qtos, results)
|
||||
|
||||
|
||||
|
||||
return results
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user