152 lines
5.2 KiB
Markdown
152 lines
5.2 KiB
Markdown
# Native IFC Merging with ifcmerge
|
|
|
|
How [ifcmerge](https://github.com/brunopostle/ifcmerge) relates to the ifc-commit
|
|
pipeline, and when to use it instead of (or alongside) `ifcpatch MergeProjects`.
|
|
|
|
---
|
|
|
|
## What is ifcmerge?
|
|
|
|
ifcmerge is a **three-way merge tool for IFC/STEP files**, written by Bruno
|
|
Postle (GPLv3, 2022). It brings software-development-style branching workflows
|
|
to BIM files stored in git.
|
|
|
|
Basic usage:
|
|
|
|
```bash
|
|
ifcmerge base.ifc local_fork.ifc remote_fork.ifc merged.ifc
|
|
```
|
|
|
|
It can be registered as a git mergetool:
|
|
|
|
```bash
|
|
git config --global mergetool.ifcmerge.cmd \
|
|
'ifcmerge $BASE $LOCAL $REMOTE $MERGED'
|
|
git config --global mergetool.ifcmerge.trustExitCode true
|
|
```
|
|
|
|
Then on a merge conflict:
|
|
|
|
```bash
|
|
git merge feature-branch
|
|
git mergetool --tool=ifcmerge
|
|
```
|
|
|
|
---
|
|
|
|
## How it works
|
|
|
|
IFC files are encoded in the STEP Physical File (SPF) format. Each entity has a
|
|
numeric id (`#514`, `#819`, …). ifcmerge uses these ids as stable keys — not
|
|
line numbers — to track changes between versions.
|
|
|
|
Given three versions of the **same model**:
|
|
|
|
1. **Analysis** — identifies which entity ids were added, deleted, or modified
|
|
in each branch relative to the common ancestor.
|
|
2. **ID renumbering** — newly-added entities from one branch are renumbered to
|
|
avoid collisions with the other branch.
|
|
3. **Attribute-level merge** — if branch A changed `Name` and branch B changed
|
|
`Representation` on the same entity, both changes are applied. No conflict.
|
|
4. **List merging** — list-valued attributes (e.g. `IfcRelContainedInSpatialStructure.RelatedElements`)
|
|
support independent additions and deletions from each branch.
|
|
5. **Conflict detection** — if an entity is **deleted in one branch but modified
|
|
in the other**, ifcmerge refuses and exits non-zero. Manual resolution required.
|
|
|
|
---
|
|
|
|
## ifcmerge vs `MergeProjects`
|
|
|
|
These tools solve **different problems**:
|
|
|
|
| Aspect | ifcmerge | ifcpatch `MergeProjects` |
|
|
|--------|----------|--------------------------|
|
|
| Purpose | Reconcile two divergent edits of the **same** model | Combine two **independent** models |
|
|
| Common ancestor | Required | Not applicable |
|
|
| Conflict detection | Yes — delete/modify conflicts | None |
|
|
| ID handling | Renumbers only new entities | Renumbers all entities from one side |
|
|
| Attribute merging | Attribute-by-attribute within same entity | No concept of same-entity merging |
|
|
| Git integration | Designed as a git mergetool | No relation to version control |
|
|
| Use case | Concurrent editing by multiple contributors | Federation / composing discipline models |
|
|
|
|
**In short:**
|
|
- Use `MergeProjects` (via `ifccommit insert` or `ifccommit replace`) to **compose**
|
|
models — e.g. merging an extracted and modified space back into the original.
|
|
- Use `ifcmerge` to **reconcile** concurrent edits — e.g. two contributors
|
|
independently edited the same model on separate branches.
|
|
|
|
---
|
|
|
|
## Relevance for ifc-commit
|
|
|
|
The ifc-commit pipeline operates as:
|
|
|
|
```
|
|
extract → modify → replace
|
|
```
|
|
|
|
This is a **sequential** workflow: one person extracts a space, modifies it,
|
|
and merges it back. ifcmerge adds value when the workflow becomes **concurrent**:
|
|
|
|
```
|
|
┌── contributor A: moves furniture ──┐
|
|
base ┤ ├→ ifcmerge → merged.ifc
|
|
└── contributor B: renames spaces ──┘
|
|
```
|
|
|
|
A git-based BIM workflow combining both tools:
|
|
|
|
```bash
|
|
# Both contributors branch from the same model
|
|
git checkout -b feature/move-table
|
|
# A edits duplex.ifc (moves table)
|
|
git commit -m "move coffee table in A102"
|
|
|
|
git checkout main
|
|
git checkout -b feature/rename-spaces
|
|
# B edits duplex.ifc (renames spaces)
|
|
git commit -m "rename spaces to long names"
|
|
|
|
# Merge B's changes into A's branch
|
|
git checkout feature/move-table
|
|
git merge feature/rename-spaces
|
|
# conflict on duplex.ifc → resolve with ifcmerge
|
|
git mergetool --tool=ifcmerge
|
|
git commit -m "merge: move table + rename spaces"
|
|
```
|
|
|
|
---
|
|
|
|
## Installation
|
|
|
|
ifcmerge is **not a Python package** — it cannot be installed with `uv add`.
|
|
|
|
| Platform | Method |
|
|
|----------|--------|
|
|
| Linux / macOS | Clone repo, put the `ifcmerge` Perl script on `$PATH` |
|
|
| Windows | Download pre-built `ifcmerge.exe` from the GitHub releases page |
|
|
| Rust port | Experimental binary available in the 2025-01-26 release |
|
|
|
|
---
|
|
|
|
## Limitations
|
|
|
|
- **Native IFC required** — only works if the editing application writes IFC
|
|
with stable entity ids. Applications that regenerate all ids on export
|
|
(Revit, ArchiCAD in export mode) are incompatible.
|
|
- **Delete/modify conflicts** — cannot auto-resolve; user must abort the merge
|
|
and resolve manually.
|
|
- **No parametric logic** — IFC captures geometry, not design intent. Two
|
|
branches that drive geometry from incompatible parameter sets may produce
|
|
geometrically inconsistent results.
|
|
- **Experimental Rust port** — the Perl implementation is the stable one.
|
|
- **Large file handling** — git forges cap LFS file sizes; large projects
|
|
(> 1 GB) need a self-hosted instance.
|
|
|
|
---
|
|
|
|
## References
|
|
|
|
- [ifcmerge GitHub](https://github.com/brunopostle/ifcmerge)
|
|
- [Porto OpenBIM Hackathon 2026](http://porto.gitaec.org)
|
|
- [Git-based IFC example by Bruno Postle](https://gitaec.org/brunopostle/creative-freedom)
|