133 lines
3.7 KiB
Markdown
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)
|