IFC Write-Back (Export-Review)
Beim Export eines Reviews stempelt vflow2 unsere Heizlast- und Auslegungsentscheidungen als IFC-Property Sets (Psets) in eine abgeleitete IFC-Datei. Diese Datei kann dem Architekten zugeschickt und von dessen Tool (Solibri, Archicad, BIMcollab, Revit u.a.) gelesen werden.
Welche Felder pro Fläche tatsächlich in die IFC wandern, entscheidet der
Bearbeiter im Export-Panel (#export-Hash). Dort ist pro
IFC-Element-Typ gruppiert eine Baumansicht aller Werte, mit per-Zeile,
per-Gruppe und globalen Toggles. Der Bulk-Button Nur Overrides setzt
automatisch Haken bei Flächen, deren U-Quelle override oder iso13370
ist. Der Stamp & save-Button ruft genau den gleichen Writeback auf, den
dieses Dokument beschreibt.

In der Heizlast-Tabelle selbst lebt nur noch ein einzelner Status-Dot in der Spalte → IFC (grün = mindestens ein Feld markiert, grau = nichts). Ein Klick auf den Dot navigiert zum Export-Panel. Die alten vier per-Feld-Checkboxen pro Zeile wurden entfernt — die Entscheidung gehört in die Preview, nicht in die Tabelle.
Die obere Band der Heizlast-Seite zeigt zusammengefasst, wie viele Flächen schreibbar markiert sind und wie viele Parent-Wände einen einheitlichen U-Wert tragen:

Geschriebene Psets
Pro IfcSpace (nur beheizte Räume mit ΦHL > 0)
Pset_SpaceThermalLoad — buildingSMART-Standard:
| Property | IFC-Typ | Quelle |
|---|---|---|
TotalSensibleLoad |
IfcPowerMeasure (W) |
heizlast.results_by_room[gid].phi_HL_w |
Dies ist der wichtigste Wert für Empfänger-Tools, die den Standard lesen.
VflowPset_HeatingDesign — vendor-prefixed, enthält unsere vollständige
Entscheidungsakte:
| Property | IFC-Typ | Bedeutung |
|---|---|---|
PhiHL_W |
IfcPowerMeasure |
Heizlast gesamt |
PhiTrans_W |
IfcPowerMeasure |
Transmissions-Anteil |
PhiVent_W |
IfcPowerMeasure |
Ventilations-Anteil |
PhiReheat_W |
IfcPowerMeasure |
Wiederaufheizzuschlag |
ThetaInt_C |
IfcThermodynamicTemperatureMeasure |
Auslegungs-Raumtemperatur |
VolumeUsed_m3 |
IfcVolumeMeasure |
effektives Raumvolumen |
SizingCandidate_Type |
IfcLabel |
"radiator" / "ufh" / "none" |
SizingCandidate_Label |
IfcLabel |
Beschriftung des aktiven Kandidaten |
SizingCandidate_Delivered_W |
IfcPowerMeasure |
Φgeliefert |
SizingCandidate_Coverage_Pct |
IfcReal |
Deckungsgrad in % |
SizingCandidate_Params_Json |
IfcText |
Kandidat-Parameter als JSON |
StableRoomKey |
IfcLabel |
vfk_<8hex> — siehe unten |
VflowVersionId |
IfcLabel |
z.B. "v2" |
VflowTimestamp |
IfcLabel |
ISO-8601 UTC |
VflowPset_HeatingSurfaces — lossless per-Raum Oberflächenrecord, nur
dann geschrieben, wenn mindestens eine Fläche im Raum für Writeback markiert
ist (→ IFC-Häkchen in der Heizlast-UI):
| Property | IFC-Typ | Bedeutung |
|---|---|---|
Surfaces_Json |
IfcText |
JSON-Array der markierten Flächen |
Jeder Array-Eintrag hat die Form:
{
"surface_id": "<wall_gid>__face_max__<owner8>__<cm>",
"source_element_gid": "<IfcWall/Slab/Door/Window GlobalId>",
"source_element_type": "IfcWall",
"surface_type": "wall",
"u_source": "override",
"fields": {
"u_value": { "vflow": 0.18, "ifc": 0.35 },
"area_m2": { "vflow": 12.3, "ifc": null },
"adjacency": { "vflow": "to_unheated", "ifc": null },
"fk": { "vflow": 0.5, "ifc": null }
}
}
Nur Felder mit write_to_ifc.<field> == True erscheinen in fields. ifc ist
der Extraktions-Basiswert aus der Quell-IFC (für u_value aus
Pset_*Common.ThermalTransmittance, für geometrisch abgeleitete Felder
null). Die surface_id bleibt über Revisionen stabil, solange die Geometrie
sich nicht drastisch verschiebt — siehe StableRoomKey unten und die
Anchoring-Logik in _version_fingerprints.py.
Parent-Element Pset (konservativer Standard-Writeback)
Zusätzlich stampft der Exporter Pset_*Common.ThermalTransmittance auf das
übergeordnete Bauteil (IfcWall / IfcSlab / IfcDoor / IfcWindow) —
nur dann, wenn jede Teil-Fläche dieses Bauteils write_to_ifc.u_value
== True hat und alle effektiven U-Werte innerhalb von 1e-4 W/m²K
übereinstimmen. Teilabdeckung oder Disagreement → übersprungen mit Warnung
(parent_elements_u_conflict_skipped in ExportStats). Der lossless
VflowPset_HeatingSurfaces-Blob trägt die Werte in jedem Fall weiter — die
Daten gehen nie verloren.
Warum konservativ: eine Wand kann über ihre Länge mehrere Teil-Flächen mit
unterschiedlichen U-Werten haben (z. B. eine Korridor-Wand, die drei Räume
bedient). Den Standardweg-Pset in so einem Fall zu stampfen würde die anderen
Teilflächen fehl-bewerten. Wenn das Empfänger-Tool keinen
VflowPset_HeatingSurfaces-Leser hat, bleibt der Original-U-Wert auf der
Wand stehen — was sauberer ist als eine falsche Vereinfachung.
ExportStats-Zähler (im export_stats der Review-Version)
| Feld | Bedeutung |
|---|---|
spaces_written |
Anzahl beheizter IfcSpace mit Pset-Stempel |
spaces_with_surface_writeback |
Räume mit mindestens einer markierten Fläche |
surfaces_written |
Summe aller markierten Flächen über alle Räume |
parent_elements_u_written |
IfcWall/Slab/Door/Window mit gestempeltem ThermalTransmittance |
parent_elements_u_conflict_skipped |
übersprungene Parents (Disagreement / Teilabdeckung) |
Pro IfcProject (file-level)
VflowPset_ReviewMeta:
| Property | Bedeutung |
|---|---|
VersionId |
z.B. "v1" — die Architekten-Version, aus der exportiert wurde. ParentVersionId entfällt in v3, weil Exports keine Versionen mehr sind. |
GeneratedBy |
vflow2/<git-sha> |
TotalBuildingLoad_W |
Summe aller ΦHL |
RoomsWithLoad_Count |
Anzahl beheizter Räume |
SurfaceOverrides_Count |
Anzahl gesetzter Oberflächen-Overrides |
Disclaimer |
Rückschreib-Disclaimer (unten) |
StableRoomKey: Matching-Anker für Revisionen
Revit regeneriert GlobalId beim Re-Export relativ aggressiv (10–30 % Churn
pro Iteration ist plausibel). Und wenn eine Revit-Room gelöscht + neu
angelegt wurde, ändert sich auch die GlobalId.
Als Rettungsanker schreibt jeder Review StableRoomKey = vfk_<8hex> als
Pset-Property auf jeden beheizten Raum. Beim Upload einer Revision versucht
die Migrations-Pipeline zuerst, anhand dieses Keys zu matchen. Wenn das
Empfänger-Tool das Pset beim Round-Trip erhält (Solibri / Archicad /
BIMcollab zuverlässig; Revit variiert nach Export-Einstellung), haben wir
eine 100 %-Match-Rate.
Falls weder StableRoomKey noch GlobalId überleben (Revit-Delete-Recreate-Fall),
greift die Fingerprint-basierte Zuordnung (Name + Nummer + Storey + BBox-
Center) mit Konfidenzbuckets von 40–95 %. Siehe
10_version_compare.md und Plan §2 für Details.
Safety
- Atomic Save —
.ifc.tmpschreiben, dannos.replace. - Pre-save Round-Trip — jede geschriebene Property wird sofort via
ifcopenshell.util.element.get_psets()zurückgelesen und gegen das Soll verglichen. Drift bricht den Export ab; keine Teil-Schreibvorgänge. - Strict Validation (Ultraplan #7) — nach dem Save läuft
ifcopenshell.validate(). Fehler auf von uns geschriebenen Entitäten (tracked intouched_ids) brechen den Export ab. Fehler auf vor-existierenden Entitäten werden inpre_existing_validation_errorsgesammelt und im Export-Panel-Ergebnisblock oberhalb des Download-Links angezeigt — wir blockieren den Export nicht, aber nichts ist silent. - Missing GlobalId — Räume ohne GID werden geloggt und übersprungen,
gezählt in
spaces_skipped_no_gid.
Nicht in MVP
IfcSpaceHeater-Geometrie — nicht erzeugt; Pset-Daten aufIfcSpacesind aktuell ausreichend für Architekten-Tools.IfcSystem/IfcRelAssignsToControl— analog nicht modelliert.- Heizkörper-Plazierung — keine Platzierungsberechnung.
- Email-Automation — Versand an den Architekten erfolgt manuell.
Mandatory-Disclaimer
Rückschreiben in IFC: Pset-basierte Daten (Pset_SpaceThermalLoad + VflowPset_HeatingDesign). Die tatsächliche Interpretation durch den Architekten hängt vom Empfänger-Tool ab.
Der Disclaimer lebt zusätzlich im VflowPset_ReviewMeta.Disclaimer, also
auch in der IFC-Datei selbst.