160 lines
4.1 KiB
Markdown
160 lines
4.1 KiB
Markdown
# `ifcopenshell.file`
|
|
|
|
An `ifcopenshell.file` is the in-memory representation of a parsed IFC file.
|
|
It is the central object in every ifcbus operation — all reading, querying,
|
|
modifying, and writing go through it.
|
|
|
|
---
|
|
|
|
## Opening a file
|
|
|
|
```python
|
|
import ifcopenshell
|
|
|
|
model = ifcopenshell.open("input.ifc")
|
|
# model is an ifcopenshell.file object
|
|
```
|
|
|
|
`ifcopenshell.open()` parses the STEP-encoded `.ifc` file and loads all
|
|
entities into memory. The result is a live, mutable object graph.
|
|
|
|
---
|
|
|
|
## What it contains
|
|
|
|
An IFC file is a flat list of **entity instances**, each identified by a
|
|
sequential integer id (`#1`, `#2`, …). Entities reference each other by id,
|
|
forming a directed graph.
|
|
|
|
```
|
|
#1 = IfcOrganization(...)
|
|
#2 = IfcApplication(#1, ...)
|
|
#33 = IfcOwnerHistory(#32, #2, ...)
|
|
#514 = IfcSpace('0BTBFw6f90Nfh9rP1dlXrr', #33, 'A101', ...)
|
|
```
|
|
|
|
The `ifcopenshell.file` object holds:
|
|
- **All entity instances** (the flat list above)
|
|
- **Schema** — e.g. `IFC2X3`, `IFC4`
|
|
- **Header** — file metadata (author, application, description, timestamp)
|
|
|
|
---
|
|
|
|
## Key methods
|
|
|
|
### Querying
|
|
|
|
```python
|
|
# By entity id (integer)
|
|
el = model.by_id(514)
|
|
|
|
# By GlobalId (GUID string)
|
|
el = model.by_guid("0BTBFw6f90Nfh9rP1dlXrr")
|
|
|
|
# All instances of a type (includes subtypes)
|
|
walls = model.by_type("IfcWall") # returns list
|
|
spaces = model.by_type("IfcSpace")
|
|
|
|
# Iterate over every entity in the file
|
|
for entity in model:
|
|
print(entity.id(), entity.is_a())
|
|
```
|
|
|
|
### Relationships
|
|
|
|
```python
|
|
# All entities that reference this element (inverse links)
|
|
refs = model.get_inverse(el) # returns set of entity instances
|
|
|
|
# All entities reachable from this element (deep graph traversal)
|
|
graph = model.traverse(el) # returns list, breadth-first
|
|
```
|
|
|
|
### Modifying
|
|
|
|
```python
|
|
# Create a new entity
|
|
org = model.create_entity("IfcOrganization", Name="ACME")
|
|
|
|
# Remove an entity and clean up its relationships
|
|
model.remove(el)
|
|
|
|
# Higher-level removal (cleans containment, placements, etc.)
|
|
import ifcopenshell.api
|
|
ifcopenshell.api.run("root.remove_product", model, product=el)
|
|
```
|
|
|
|
### Writing
|
|
|
|
```python
|
|
# Write back to a file
|
|
model.write("output.ifc")
|
|
|
|
# Or via ifcpatch (used when the result comes from a recipe)
|
|
import ifcpatch
|
|
ifcpatch.write(result, "output.ifc")
|
|
```
|
|
|
|
---
|
|
|
|
## Schema and header
|
|
|
|
```python
|
|
print(model.schema) # "IFC2X3" or "IFC4"
|
|
print(model.header.file_description) # ViewDefinition, ...
|
|
print(model.header.file_name.name) # original filename
|
|
```
|
|
|
|
---
|
|
|
|
## Entity instances
|
|
|
|
Each element returned by the methods above is an **entity instance**
|
|
(`ifcopenshell.entity_instance`). Its attributes are accessed as properties:
|
|
|
|
```python
|
|
wall = model.by_type("IfcWall")[0]
|
|
|
|
wall.GlobalId # GUID string
|
|
wall.Name # element name
|
|
wall.is_a() # "IfcWall" — runtime type string
|
|
wall.id() # integer entity id (file-local, unstable across extractions)
|
|
wall.get_info() # dict of all attribute name → value
|
|
```
|
|
|
|
Entity ids are **not stable** — the same physical element will have a different
|
|
id after extraction or merging. Always use `GlobalId` or `Name` to identify
|
|
elements across files.
|
|
|
|
---
|
|
|
|
## Relationship to ifcpatch
|
|
|
|
`ifcpatch.execute()` takes an `ifcopenshell.file` as input and returns a new
|
|
one as output. The input is never modified in place. `ifcpatch.write()` is a
|
|
thin wrapper around `model.write()` with some post-processing.
|
|
|
|
```python
|
|
result = ifcpatch.execute({
|
|
"input": "input.ifc",
|
|
"file": model, # ← ifcopenshell.file
|
|
"recipe": "ExtractElements",
|
|
"arguments": ["IfcWall"],
|
|
})
|
|
# result is a new ifcopenshell.file
|
|
ifcpatch.write(result, "output.ifc")
|
|
```
|
|
|
|
---
|
|
|
|
## Memory model
|
|
|
|
The entire file is loaded into memory as a C++ object graph (via a Python
|
|
binding). This means:
|
|
|
|
- Operations are fast (no re-parsing on each query).
|
|
- Large files consume significant RAM.
|
|
- The object is **not thread-safe** — do not share across threads.
|
|
- Passing the object to `MergeProjects` as a file path string (instead of the
|
|
object itself) triggers a segfault in the current version — always pass the
|
|
live object.
|