From 6f9d54c2af3e6f627c5286f81bbf9532d9eb4d92 Mon Sep 17 00:00:00 2001 From: Bruno Postle Date: Sun, 29 Mar 2026 15:30:29 +0100 Subject: [PATCH] ifcquery, ifcedit: update docs for --format ids and foreach subcommand Add --format ids to the ifcquery.rst format description and a new "Scripting with ifcedit" section showing composition examples. Add the foreach subcommand to ifcedit.rst with usage examples. --- src/ifcopenshell-python/docs/ifcedit.rst | 12 ++++++++++ src/ifcopenshell-python/docs/ifcquery.rst | 29 ++++++++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/ifcopenshell-python/docs/ifcedit.rst b/src/ifcopenshell-python/docs/ifcedit.rst index df7c083d1b..d5db9b7c82 100644 --- a/src/ifcopenshell-python/docs/ifcedit.rst +++ b/src/ifcopenshell-python/docs/ifcedit.rst @@ -10,6 +10,7 @@ you to write a Python script. It supports four subcommands: - **list** — list all API modules, or all functions within a module - **docs** — show full documentation for a function (parameters, types, descriptions) - **run** — execute a mutation against an IFC file +- **foreach** — apply an API function to each element in a JSON array read from stdin - **quantify** — run quantity take-off using ifc5d rules; requires the IfcOpenShell C++ geometry bindings Installation @@ -53,6 +54,17 @@ Dry-run to validate without modifying the file:: $ ifcedit run model.ifc root.remove_product --dry-run --product 42 +Apply an API function to each element in a JSON array from stdin (``{field}`` +placeholders are substituted from each item; model is opened and saved once):: + + $ ifcquery model.ifc select 'IfcWindow' | ifcedit foreach model.ifc root.remove_product --product {id} + $ ifcquery model.ifc select 'IfcDoor' | ifcedit foreach model.ifc attribute.edit_attributes \ + --product {id} --attributes '{"Name": "Door"}' + +Write to a separate output file instead of overwriting:: + + $ ifcquery model.ifc select 'IfcWall' | ifcedit foreach model.ifc root.remove_product -o output.ifc --product {id} + Quantity take-off (writes ``IfcElementQuantity`` psets back to the file; requires C++ geometry bindings):: $ ifcedit quantify list diff --git a/src/ifcopenshell-python/docs/ifcquery.rst b/src/ifcopenshell-python/docs/ifcquery.rst index 1c7a797bbf..8735b63da2 100644 --- a/src/ifcopenshell-python/docs/ifcquery.rst +++ b/src/ifcopenshell-python/docs/ifcquery.rst @@ -24,7 +24,11 @@ Subcommands: - **plot** — generate a drawing (SVG or PNG) using ``ifcopenshell.draw``; PNG output requires ``cairosvg`` - **render** — off-screen 3D render to a PNG image; requires ``pyvista`` and the IfcOpenShell C++ geometry bindings -All subcommands accept ``--format json|text`` to control output (default: ``json``). +All subcommands accept ``--format json|text|ids`` to control output (default: ``json``): + +- ``json`` — structured JSON, suitable for piping to ``jq`` or ``ifcedit foreach`` +- ``text`` — indented human-readable output +- ``ids`` — comma-separated step IDs extracted from list results, suitable for piping directly into ``ifcedit run`` parameters Installation ------------ @@ -68,6 +72,29 @@ Usage $ ifcquery model.ifc plot -o floorplan.svg --out-format svg --view floorplan $ ifcquery model.ifc plot -o floorplan.png --view floorplan $ ifcquery model.ifc render -o model.png + $ ifcquery model.ifc --format ids select 'IfcWall' + +Scripting with ifcedit +---------------------- + +``ifcquery`` and ``ifcedit`` are designed to compose. Use ``--format ids`` to +pass query results directly into ``ifcedit run`` parameters, or pipe JSON into +``ifcedit foreach`` to apply an operation to every matching element:: + + # Aggregate — pass all IDs as a list parameter + $ ifcedit run model.ifc spatial.unassign_container \ + --products "$(ifcquery model.ifc --format ids select 'IfcWall')" + + # Fan-out — one operation per element, model opened and saved once + $ ifcquery model.ifc select 'IfcWindow' | ifcedit foreach model.ifc root.remove_product --product {id} + + # Render an element highlighted against everything related to it + $ ifcquery model.ifc render -o relations.png \ + --element "$(ifcquery model.ifc --format ids relations 42)" + + # Render a clash — subject and clashing elements highlighted together + $ ifcquery model.ifc render -o clash.png \ + --element "$(ifcquery model.ifc --format ids clash 42)" .. seealso::