ifcedit: include IfcSpace in default QTO element scope

IfcSpace is not a subtype of IfcElement, so quantify.run_quantify()'s
default selector silently skipped all spaces, reporting
elements_quantified: 0 with no error or warning.

Generated with the assistance of an AI coding tool.

(cherry picked from commit ab15750747)
This commit is contained in:
Bruno Postle
2026-07-12 23:16:12 +01:00
committed by Dion Moult
parent 8d9f027f3e
commit aef141505b
6 changed files with 24 additions and 5 deletions
+1 -1
View File
@@ -258,7 +258,7 @@ ifcedit quantify run model.ifc IFC4QtoBaseQuantities -o model_qto.ifc
Options:
- `--selector <query>` -- ifcopenshell selector to restrict elements (default: all `IfcElement`)
- `--selector <query>` -- ifcopenshell selector to restrict elements (default: all `IfcElement` and `IfcSpace`)
- `-o, --output <path>` -- write to a different file instead of overwriting the input
Note: `quantify run` writes geometry-based measurements and requires the
+3 -1
View File
@@ -244,7 +244,9 @@ def main():
qrun_parser = quantify_sub.add_parser("run", help="Run QTO on an IFC file")
qrun_parser.add_argument("ifc_file", help="Path to the IFC file")
qrun_parser.add_argument("rule_name", help="QTO rule name (e.g. IFC4QtoBaseQuantities)")
qrun_parser.add_argument("--selector", help="ifcopenshell selector to restrict elements (default: all IfcElement)")
qrun_parser.add_argument(
"--selector", help="ifcopenshell selector to restrict elements (default: all IfcElement and IfcSpace)"
)
qrun_parser.add_argument("-o", "--output", help="Output file path (default: overwrite input)")
args, extra = parser.parse_known_args()
+1 -1
View File
@@ -30,7 +30,7 @@ def run_quantify(model: ifcopenshell.file, rule: str, selector: str | None = Non
if selector:
elements = set(ifcopenshell.util.selector.filter_elements(model, selector))
else:
elements = set(model.by_type("IfcElement"))
elements = set(model.by_type("IfcElement")) | set(model.by_type("IfcSpace"))
results = quantify(model, elements, rule_sets[rule])
edit_qtos(model, results)
+17
View File
@@ -85,3 +85,20 @@ class TestRunQuantify:
def test_empty_selector_runs_on_all(self, quantify_model):
result = run_quantify(quantify_model, "IFC4QtoBaseQuantities", selector=None)
assert result["ok"] is True
def test_default_selector_includes_spaces(self, quantify_model, monkeypatch):
"""IfcSpace is not a subtype of IfcElement, so the default scope must add it explicitly."""
import ifc5d.qto
seen_elements = {}
def fake_quantify(ifc_file, elements, rules):
seen_elements["elements"] = elements
return {}
monkeypatch.setattr(ifc5d.qto, "quantify", fake_quantify)
space = ifcopenshell.api.root.create_entity(quantify_model, ifc_class="IfcSpace", name="TestSpace")
run_quantify(quantify_model, "IFC4QtoBaseQuantities")
assert space in seen_elements["elements"]
+1 -1
View File
@@ -255,7 +255,7 @@ ifc_quantify(rule="IFC4QtoBaseQuantities", selector="IfcWall")
Available rules: `IFC4QtoBaseQuantities`, `IFC4X3QtoBaseQuantities`.
`selector` is an optional ifcopenshell selector to restrict which elements
are quantified (default: all `IfcElement`).
are quantified (default: all `IfcElement` and `IfcSpace`).
Returns `{"ok": true, "rule": "...", "elements_quantified": 42}`.
+1 -1
View File
@@ -703,7 +703,7 @@ class IfcSession:
"rule": {"type": "string", "description": "QTO rule name, e.g. IFC4QtoBaseQuantities"},
"selector": {
"type": "string",
"description": "ifcopenshell selector to restrict elements (default: all IfcElement)",
"description": "ifcopenshell selector to restrict elements (default: all IfcElement and IfcSpace)",
},
},
"required": ["rule"],