ifc-commit/docs/ifc-extract.md
2026-03-25 10:36:30 +01:00

133 lines
3.7 KiB
Markdown

# IFC Extraction — Research Notes
How to extract parts from an IFC file, for use in the ifc-commit pipeline.
---
## 1. Core Tools
### IfcOpenShell (Python)
The main toolkit. Install via pip:
```bash
pip install ifcopenshell
```
Open a file and select elements by type:
```python
import ifcopenshell
model = ifcopenshell.open("model.ifc")
# All products (geometric elements)
products = model.by_type("IfcProduct")
# Specific type
walls = model.by_type("IfcWall")
# Inspect attributes
for wall in walls:
print(wall.get_info())
```
---
## 2. Extract to a New IFC File
### `ifcpatch` — `ExtractElements` recipe
The cleanest high-level API for extracting a subset of elements into a new file:
```python
import ifcopenshell
import ifcpatch
model = ifcopenshell.open("input.ifc")
result = ifcpatch.execute({
"input": "input.ifc",
"file": model,
"recipe": "ExtractElements",
"arguments": ["IfcWall"] # or "IfcWall, IfcSlab" for multiple types
})
ifcpatch.write(result, "walls-only.ifc")
```
Key parameters:
| Parameter | Default | Description |
|-----------|---------|-------------|
| `query` | `"IfcWall"` | IFC type(s) to extract, comma-separated |
| `assume_asset_uniqueness_by_name` | `True` | Deduplicate materials/profiles by name |
The recipe preserves spatial hierarchy (`add_spatial_structures`) and handles assets (materials, styles, profiles) via `append_asset`.
### `ifcopenshell.file.add()` — Low-level copy
Copies an entity and all its dependencies recursively into another file:
```python
import ifcopenshell
source = ifcopenshell.open("source.ifc")
target = ifcopenshell.file(schema=source.schema)
for wall in source.by_type("IfcWall"):
target.add(wall) # recursive deep copy
target.write("extracted.ifc")
```
Note: produces a valid-ish file but may need cleanup (missing spatial structure, duplicate references).
---
## 3. Extract by GlobalId (CLI)
Using `IfcConvert` to filter by specific element IDs and export to another format:
```bash
IfcConvert model.ifc out.glb \
--include attribute GlobalId 1yETHMphv6LwABqR4Pbs5g \
--include attribute GlobalId 2xETHMphv6LwABqR0Pbs5g
```
---
## 4. Spatial Decomposition
To get all sub-elements of a spatial element (building, storey, space…):
```python
from ifcopenshell.util.element import get_decomposition
storey = model.by_type("IfcBuildingStorey")[0]
elements = get_decomposition(storey)
# → all elements contained in that storey, their parts, openings, fills
```
---
## 5. Relevance for ifc-commit
| Operation | Tool | Notes |
|-----------|------|-------|
| Extract by type | `ifcpatch ExtractElements` | cleanest API |
| Extract by ID | `IfcConvert --include` | CLI, good for scripting |
| Deep copy to new file | `ifcopenshell.file.add()` | low-level, needs post-processing |
| Traverse spatial tree | `get_decomposition()` | useful for bus routing logic |
Next step: **insert** extracted parts into a target IFC file → see `ifc-insert.md`.
---
## Sources
- [IfcOpenShell — parse IFC files with Python](https://thinkmoult.com/using-ifcopenshell-parse-ifc-files-python.html)
- [ifcpatch ExtractElements recipe](https://docs.ifcopenshell.org/autoapi/ifcpatch/recipes/ExtractElements/index.html)
- [IfcOpenShell code examples — OSArch Wiki](https://wiki.osarch.org/index.php?title=IfcOpenShell_code_examples)
- [Splitting an IFC file into parts — SourceForge discussion](https://sourceforge.net/p/ifcopenshell/discussion/1782718/thread/1290d16904/)
- [Extracting entities from IFC — SourceForge discussion](https://sourceforge.net/p/ifcopenshell/discussion/1782717/thread/72b5297e51/)
- [IfcOpenShell code examples](https://docs.ifcopenshell.org/ifcopenshell-python/code_examples.html)