130 lines
6.1 KiB
Markdown
130 lines
6.1 KiB
Markdown
# Speckle-Grasshopper to IFC 4.3 Exporter
|
|
|
|
A [Speckle Automate](https://automate.speckle.dev/) function that converts Speckle models into IFC 4.3 files using [ifcopenshell](https://ifcopenshell.org/). Built for Grasshopper + Rhino workflows, but compatible with any application that produces Speckle objects matching the expected property structure.
|
|
|
|
## What It Does
|
|
|
|
The exporter receives a Speckle model version, walks its nested collection tree, and produces a standards-compliant IFC 4.3 file. Each Speckle object becomes an IFC element with:
|
|
|
|
- Correct IFC entity classification read from `_properties.Attributes.type`
|
|
- Tessellated geometry (IfcPolygonalFaceSet)
|
|
- Material colours from Speckle render materials
|
|
- All property sets cloned from `_properties.Property Sets`
|
|
- All quantity sets cloned from `_properties.Quantities`
|
|
- IFC type objects created from `_properties.Element Type Attributes`
|
|
- Building storeys derived from `_properties.Building Storey`
|
|
- Spatial structure (IfcProject > IfcSite > IfcBuilding > IfcBuildingStorey)
|
|
|
|
## Object Structure
|
|
|
|
The exporter expects Speckle objects with the following `_properties` layout:
|
|
|
|
```
|
|
_properties
|
|
├── Attributes → IFC element attributes (type, GlobalId, Name, Tag, etc.)
|
|
├── Property Sets → dict of {pset_name: {prop_name: value}}
|
|
├── Quantities → dict of {qto_name: {qty_name: {name, units, value}}}
|
|
├── Building Storey → string, used for storey assignment
|
|
├── Element Type Attributes → type class, Name, GlobalId (creates IfcTypeObject)
|
|
└── Element Type Property Sets → property sets written on the IfcTypeObject
|
|
```
|
|
|
|
The nested collection tree is expected as: `Root Collection > Collection > ... > Object`
|
|
|
|
## Pipeline Overview
|
|
|
|
```
|
|
Speckle Model
|
|
│
|
|
▼
|
|
1. Receive version (specklepy)
|
|
│
|
|
▼
|
|
2. Build definition map (for instance geometry reuse)
|
|
│
|
|
▼
|
|
3. Create IFC scaffold (Project → Site → Building)
|
|
│
|
|
▼
|
|
4. Traverse collection tree
|
|
│ For each leaf element:
|
|
│ ├── Classify → IFC entity class (from _properties.Attributes.type)
|
|
│ ├── Convert geometry → IfcPolygonalFaceSet
|
|
│ ├── Create IFC element + placement
|
|
│ ├── Clone all properties & quantities
|
|
│ ├── Assign to Building Storey (from _properties.Building Storey)
|
|
│ └── Assign IFC type object (from Element Type Attributes)
|
|
│
|
|
▼
|
|
5. Flush spatial containment & type relationships
|
|
│
|
|
▼
|
|
6. Write .ifc file
|
|
```
|
|
|
|
## Module Structure
|
|
|
|
| File | Purpose |
|
|
|------|---------|
|
|
| `main.py` | Entry point, orchestrates the full pipeline |
|
|
| `utils/traversal.py` | Walks the Speckle collection tree (Root > Collection* > Object) |
|
|
| `utils/mapper.py` | Reads IFC entity class from `_properties.Attributes.type` |
|
|
| `utils/geometry.py` | Converts Speckle meshes to IfcPolygonalFaceSet geometry |
|
|
| `utils/instances.py` | Handles InstanceProxy objects with shared geometry (IfcMappedItem) |
|
|
| `utils/properties.py` | Clones all properties, quantities, and attributes into IFC entities |
|
|
| `utils/type_manager.py` | Creates and caches IfcTypeObjects from Element Type Attributes |
|
|
| `utils/materials.py` | Maps Speckle render materials to IfcSurfaceStyle colours |
|
|
| `utils/writer.py` | Creates the IFC file scaffold and manages storey creation |
|
|
| `utils/receiver.py` | Standalone Speckle model receiver utility |
|
|
|
|
## Classification
|
|
|
|
IFC entity classification is read directly from `_properties.Attributes.type` on each object. For example, an object with `Attributes.type = "IfcWall"` becomes an `IfcWall` element. If the field is missing, the object falls back to `IfcBuildingElementProxy`.
|
|
|
|
For instance proxy objects without their own type, the exporter looks up the definition object's `Attributes.type`.
|
|
|
|
## Property Handling
|
|
|
|
All properties are cloned generically — no source-application-specific logic:
|
|
|
|
| Source | IFC Target |
|
|
|--------|------------|
|
|
| `_properties.Attributes` | Element attributes: GlobalId, Name, Tag, ObjectType, Description, PredefinedType |
|
|
| `_properties.Property Sets.*` | IfcPropertySet per sub-dict (e.g. `Pset_WallCommon` → IfcPropertySet with IfcPropertySingleValue entries) |
|
|
| `_properties.Quantities.*` | IfcElementQuantity per sub-dict, with automatic unit detection (mm → IfcQuantityLength, m² → IfcQuantityArea, m³ → IfcQuantityVolume) |
|
|
| `_properties.Element Type Attributes` | Shared IfcTypeObject (e.g. IfcWallType), cached by GlobalId |
|
|
| `_properties.Element Type Property Sets` | Property sets on the IfcTypeObject |
|
|
|
|
Property values are auto-typed: `bool` → IfcBoolean, `int` → IfcInteger, `float` → IfcReal, `str` → IfcLabel, `list` → comma-joined IfcLabel.
|
|
|
|
## Geometry Handling
|
|
|
|
### Direct Meshes (Path B1)
|
|
|
|
Objects with `displayValue` containing Mesh objects are converted directly:
|
|
|
|
1. Extract vertices and faces from each mesh in `displayValue`
|
|
2. Scale vertices to millimetres based on the mesh's unit declaration
|
|
3. Deduplicate vertices via snap grid (0.01mm tolerance) to avoid IFC GEM111 errors
|
|
4. Build `IfcPolygonalFaceSet` with `IfcCartesianPointList3D` + `IfcIndexedPolygonalFace`
|
|
5. Compute bounding box origin for `IfcLocalPlacement`, offset vertices relative to it
|
|
|
|
### Instance Objects (Path A / B2)
|
|
|
|
Speckle `InstanceProxy` objects reference shared definition geometry via `definitionId`. Geometry is built once as an `IfcRepresentationMap`, then each instance references it via `IfcMappedItem` + `IfcCartesianTransformationOperator3DnonUniform`. This avoids duplicating vertex data across hundreds of identical elements.
|
|
|
|
## Function Inputs
|
|
|
|
| Input | Description |
|
|
|---|---|
|
|
| `file_name` | Output IFC filename (timestamp is appended automatically) |
|
|
| `IFC_PROJECT_NAME` | Name for the IfcProject entity |
|
|
| `IFC_SITE_NAME` | Name for the IfcSite entity |
|
|
| `IFC_BUILDING_NAME` | Name for the IfcBuilding entity |
|
|
|
|
## Resources
|
|
|
|
- [Speckle Developer Docs](https://speckle.guide/dev/python.html)
|
|
- [ifcopenshell Documentation](https://ifcopenshell.org/)
|
|
- [IFC 4.3 Schema](https://standards.buildingsmart.org/IFC/RELEASE/IFC4x3/HTML/)
|