CH NEO-ZÜRICH AUSGABE
WETTER · KLAR 4°C
BLEND DES TAGES · 07/ROGUE
EST. 2027
DIE AEC CYBER MORGENZEITUNG

PAZ Kaffi

DESIGN · ABBRUCH · KOFFEIN · DEPESCHE
AUSGABE 1114 · 14 November 2026
SENDUNG 04:42 MEZ
2'400 BOGEN GEDRUCKT
LESEZEIT · 47 MIN
Räume einmal zeichnen, Rhino zählt: Ein SIA-416-Flächenverzeichnis in Python 3
Akademie
FRAME · 06:50
14-11-2026

Räume einmal zeichnen, Rhino zählt: Ein SIA-416-Flächenverzeichnis in Python 3

Zeichnen Sie Räume als geschlossene Kurven auf HNF-, NNF-, VF-, FF-Layern; 30 Zeilen RhinoScriptSyntax summieren NF und NGF in eine Swiss-Excel-ready CSV.

In einem Rhino-8-Modell ist ein Raum drei Dinge: eine geschlossene Kurve, ein Name und ein Layer. Das ist alles, was ein SIA-416-Flächenverzeichnis braucht, und Rhino misst die Kurve bereits exakt mit CurveArea. Zeichnen Sie die Räume einmal, und etwa 30 Zeilen Python 3 drucken die Tabelle. Bei einer 3,5-Zimmer-Testwohnung ergeben sich HNF 69,15 m2, VF 11,06 m2 und NGF 82,75 m2, geschrieben in eine CSV-Datei, die Swiss Excel in Spalten öffnet.

Jeder Wettbewerb, jede Baueingabe und jede Kostenschätzung fordert Flächen nach Kategorie. Viele Büros tippen diese Flächen immer noch in ein Tabellenkalkulationsprogramm, das beim ersten Wandversatz zu driften anfängt. Hier ist das Modell die Quelle und die Tabelle wird aus ihm ausgedruckt: Wand verschieben, neu ausführen, und die Zahlen folgen der Zeichnung. Eine ehrliche Bemerkung, bevor wir beginnen. Die Rhino-Hälfte unten wurde gegen die McNeel-Entwicklerdokumentation geschrieben und wurde nicht in Rhino ausgeführt. Die reine-Python-Hälfte wurde auf Python 3.10.11 ausgeführt, und ihre Ausgabe wird genau zitiert.

Das Werkzeug: rhinoscriptsyntax ist die Klartextschicht für Python, die McNeel in Rhino ausliefert und die aus dem Rhino-8-ScriptEditor läuft. Sie geht zurück auf RhinoPython, entwickelt bei McNeel von Steve Baer; Rhino 8 ergänzte dann natives CPython 3, das gleiche Python, das Wissenschaftler nutzen. Die stillen Helden sind die, die die Entwicklerreferenz geschrieben haben. Jeder Aufruf in diesem Lernprogramm ist auf einer Seite dokumentiert, Argumente und Rückgabewerte ausgeschrieben, und diese Seite ist das Grund, warum ein Anfänger an einem Nachmittag ein funktionierendes Skript schreiben kann. Das Skript nutzt zehn dieser Aufrufe.

←HEUTE: 2026: viele Schweizer Flächentabellen werden immer noch von Hand neben einem Modell eingegeben, das bereits jeden Quadratmeter kennt.
→3012: Von meiner Seite des Jahrhunderts waren die Pläne, die überdauerten, geschlossene Kurven plus eine einfache CSV – Dateien, die ein 25-Jähriger immer noch öffnen kann.
Fulcrum: Das Verzeichnis überlebt die Software nur, wenn es aus der Geometrie gedruckt wird, nicht neben ihr von Hand eingegeben.

Einrichtung:

# Rhino 8 · beliebige Dokumenteinheiten (mm oder m, das Skript konvertiert)
# 1 · Ebenen-Panel: erstellen Sie HNF, NNF, VF, FF
#     (Unterebenen wie "Geschoss 1::HNF" funktionieren auch)
# 2 · Öffnen Sie den Editor von der Befehlszeile aus:
_ScriptEditor
# 3 · Neue Python-Datei. Die erste Zeile muss lauten:
#! python 3
# 4 · Fügen Sie die beiden Blöcke unten in EINE Datei ein, speichern Sie sie unter
#     C:pazroom_schedule.py, dann führen Sie sie aus einer Symbolleiste aus:
_-ScriptEditor _R "C:pazroom_schedule.py"

Nach McNeel’s Anleitung zu erweiterten ScriptEditor-Makros ist der Sprachbezeichner “erforderlich, damit der Befehl bestimmen kann, welche Sprache zum Ausführen des Skripts verwendet werden soll”; die gültigen sind #! python 3, #! python 2 und // #! csharp.

Erste Schritte:

  1. Erstellen Sie die vier Layer. Der Layer ist die Klassifizierung: Das Skript liest die Kategorie, es rät nie eine.
  2. Zeichnen Sie jeden Raum als geschlossene Kurve auf seinem Layer. Polylinien, Bögen und Splines funktionieren alle, weil CurveArea jede geschlossene ebene Kurve misst. Geben Sie den Raumnamen unter Eigenschaften → Name ein, beispielsweise “Zimmer 1”.
  3. Führen Sie das Skript aus, wählen Sie die Raumkurven, drücken Sie die Eingabetaste. Jeder Raum erhält einen Textpunkt mit seinem Namen und seiner Fläche; die Befehlszeile zeigt an, wie viele Räume markiert wurden und wie viele Kurven rot gefärbt sind.
  4. Öffnen Sie room_schedule.csv aus Ihrem Ausgangsverzeichnis in Excel. Semikolons bedeuten, dass die Daten in Spalten landen, nicht in einer Zeile.

Ein Wort zu den Kategorien. Nach dem Ginesta-Glossar, das SIA 416 zitiert, ist Nettogeschossfläche (NGF) “der Teil der gesamten Geschossfläche” “zwischen den Perimeterwänden und den inneren Konstruktionselementen”, und sie unterteilt sich in Nutzfläche (NF), Verkehrsfläche (VF) und Funktionsfläche (FF). NNF ist der Teil der NF “ergänzend zum Hauptnutzraum” (HNF). FF umfasst Räume “für technische Wartung und Gebäudeinfrastruktur”: Schächte, Installationsräume, Heizräume. Also NF = HNF + NNF, und NGF = NF + VF + FF. Wir lesen die Norm durch dieses Glossar, nicht das SIA-Dokument selbst, daher überprüfen Sie die SIA-416-Zuweisung Ihres eigenen Projekts vor einer Einreichung.

Der Code, erläutert:

# schedule_core.py - die reine Python-Hälfte (kein Rhino erforderlich)
import csv, io

ORDER = ["HNF", "NNF", "VF", "FF"]          # SIA 416 Kategorien, ein Layer pro Kategorie

def shoelace(pts):
    """Fläche eines geschlossenen Polygons aus seinen Eckpunkten (x, y). Test-Helfer; in Rhino macht CurveArea das."""
    s = 0.0
    for (x1, y1), (x2, y2) in zip(pts, pts[1:] + pts[:1]):
        s += x1 * y2 - x2 * y1
    return abs(s) / 2.0

def schedule(rows):
    """rows: Liste von (Raumname, Kategorie, Fläche in m2). Gibt CSV-Text zurück und druckt eine Zusammenfassung."""
    rows = sorted(rows, key=lambda r: (ORDER.index(r[1]) if r[1] in ORDER else 99, r[0]))
    totals = {}
    for name, cat, a in rows:
        totals[cat] = totals.get(cat, 0.0) + a
    nf = totals.get("HNF", 0) + totals.get("NNF", 0)
    ngf = sum(totals.values())
    buf = io.StringIO()
    w = csv.writer(buf, delimiter=";")        # Semikolon: Swiss Excel öffnet es in Spalten
    w.writerow(["Raum", "Kategorie", "Flaeche m2"])
    for name, cat, a in rows:
        w.writerow([name, cat, f"{a:.2f}"])
    for cat in ORDER:
        if cat in totals:
            print(f"{cat:>4} {totals[cat]:8.2f} m2  {100 * totals[cat] / ngf:5.1f} % of NGF")
    print(f"  NF {nf:8.2f} m2  (HNF + NNF)")
    print(f" NGF {ngf:8.2f} m2  (NF + VF + FF, every drawn room)")
    return buf.getvalue()
#! python 3
# room_schedule.py - Rhino 8 ScriptEditor (Python 3)
# Wählen Sie geschlossene Raumkurven auf Layern HNF / NNF / VF / FF (SIA 416 Kategorien), benennen Sie jede Kurve
# unter Eigenschaften (z. B. "Zimmer 1"). Das Skript markiert jeden Raum mit seiner Fläche und schreibt eine CSV.
import os
import rhinoscriptsyntax as rs
from schedule_core import schedule      # in Rhino: fügen Sie die schedule()-Funktion und ORDER über dieser Zeile ein

ids = rs.GetObjects("Wählen Sie geschlossene Raumkurven", filter=4, preselect=True)   # 4 = curves
if ids:
    k = rs.UnitScale(4) ** 2             # Modelleinheiten -> Meter, quadriert für Flächen
    rows, skipped = [], []
    for cid in ids:
        props = rs.CurveArea(cid) if rs.IsCurveClosed(cid) and rs.IsCurvePlanar(cid) else None
        if not props:                    # offen, nicht planar oder selbstschneidend: markieren, nicht raten
            skipped.append(cid)
            rs.ObjectColor(cid, (255, 0, 0))
            continue
        area = props[0] * k
        cat = rs.ObjectLayer(cid).split("::")[-1].upper()   # "Geschoss 1::HNF" -> "HNF"
        name = rs.ObjectName(cid) or "Raum ?"
        rows.append((name, cat, area))
        rs.AddTextDot(f"{name} {area:.1f} m2", rs.CurveAreaCentroid(cid)[0])
    text = schedule(rows)
    path = os.path.join(os.path.expanduser("~"), "room_schedule.csv")
    with open(path, "w", encoding="utf-8-sig", newline="") as f:   # BOM, damit Excel Umlaute liest
        f.write(text)
    print(f"{len(rows)} Räume markiert, {len(skipped)} Kurven rot. CSV: {path}")

Core, Zeilen 1–4 — die Norm-Begriffe als Liste: ORDER ist eine Liste, eine geordnete Reihe von Werten. Sie legt fest, in welcher Reihenfolge die Tabelle gedruckt wird. Die from schedule_core import-Zeile funktioniert nur, wenn die Datei auf dem Modulsuchpfad des ScriptEditors liegt, daher ist der sichere Weg der im Kommentar: Fügen Sie ORDER und schedule() über den Rhino-Teil ein, in einer Datei.

Core, Zeilen 6–11 — the shoelace, ein Test-Helfer: eine Funktion ist ein benannter, wiederverwendbarer Block. Dieser läuft durch die Ecken eines Polygons und summiert Kreuzprodukte, die klassische Formel für Polygonfläche. In Rhino macht CurveArea den Job, Bögen und Splines eingeschlossen; der Helfer existiert, damit Sie die Tabellenlogik auf einem Laptop ohne Rhino testen können.

Core, Zeilen 13–31 — sortieren, summieren, schreiben: der Sortierschlüssel ordnet bekannte Kategorien nach ORDER und alles Unbekannte auf Position 99, dann sortiert nach Name. Eine Schleife (Code, der einmal pro Element läuft) addiert jede Fläche in ein Wörterbuch von Summen. Der CSV-Schreiber nutzt ein Semikolon als Trennzeichen, weil Swiss Excel es so erwartet. Mit der 3,5-Zimmer-Testwohnung, in mm gezeichnet, war die gedruckte Zusammenfassung genau:

 HNF    69.15 m2   83.6 % of NGF
 NNF     2.24 m2    2.7 % of NGF
  VF    11.06 m2   13.4 % of NGF
  FF     0.30 m2    0.4 % of NGF
  NF    71.39 m2  (HNF + NNF)
 NGF    82.75 m2  (NF + VF + FF, every drawn room)

Die CSV-Zeilen enthalten Wohnen/Essen;HNF;29.76. Prüfen Sie per Hand: 6,2 × 4,8 = 29,76 m2. Die Wohnung ist ein Beispiel, kein Projekt, und Bad und Küche unter HNF einzuordnen war die Entscheidung des Editors, nicht der Norm.

Rhino, Zeilen 9–11 — Auswahl und Skalierung: GetObjects mit Filter 4 akzeptiert nur Kurven. McNeel’s API-Referenz besagt, dass UnitScale(to_system) die aktuellen Dokumenteinheiten nutzt, wenn from_system weggelassen wird; Code 4 bedeutet Meter, und das Beispiel der Docs ist rs.UnitScale(3, 4) # 100.0. Der Anfängerfehler: ** 2 vergessen. Ein Längenfaktor auf eine Fläche angewendet lässt eine mm-Datei 1.000 Mal zu gross werden. Quadriert, geben eine mm-Datei und eine m-Datei die gleiche Tabelle.

Rhino, Zeilen 12–18 — messen oder ablehnen: nach der gleichen Referenz gibt CurveArea “Fläche geschlossener ebener Kurven” zurück, als Liste, wo [0] die Fläche und [1] die absolute Fehlergrenze ist. Das Skript fragt nur, nachdem IsCurveClosed und IsCurvePlanar bestanden sind. Alles, was es nicht messen kann, landet in skipped und wird rot gefärbt. Ob das Rot sichtbar ist, wenn die Farbe der Kurve auf “Nach Layer” eingestellt ist, wurde nicht geprüft, daher verlassen Sie sich auf die skipped-Anzahl auf der Befehlszeile.

Rhino, Zeilen 19–28 — lesen, markieren, schreiben: der Layer-Pfad wird bei :: geteilt und gross geschrieben, daher zählt ein kleingeschriebenes “hnf” immer noch. Eine unbenannte Kurve wird zu “Raum ?”. CurveAreaCentroid gibt ein Tupel (ein festes Paar) von Punkt und Vektor zurück; [0], der Schwerpunkt, ist dort, wo der Punkt geht. utf-8-sig fügt eine BOM hinzu, einen kurzen Marker, der Excel mitteilt, Umlaute korrekt zu lesen. Bei einem Trockenlauf gegen ein Stub-rs-Modul, mit einer offenen “Balkon”-Kurve und einem unbenannten Raum auf Layer “hnf”, druckte es “3 Räume markiert, 1 Kurven rot.” und die Punkte lasen “Wohnen/Essen 29,8 m2”, “Korridor 11,1 m2”, “Raum ? 2,2 m2”. Das Skript verfolgat seine Punkte nicht, daher löschen Sie die alten vor einem Neulauf. Sonst bekommen Sie zwei Labels pro Raum, eine sehr Schweizer Form von Gründlichkeit.

Der Trade-Off, klar ausgesprochen: dieses Verzeichnis ist nur so ehrlich wie die Layer. Ein Raum auf dem falschen Layer wird in die falsche Kategorie summiert, ohne Beschwerde. Es misst nur Nettogeschossfläche; Wände werden nicht gezeichnet, daher gibt es hier kein GF.

Atelier: Für ein kleines Zürich oder Berner Atelier ist der Schritt vom Kontrollieren einer Tabellenkalkulation zum Kontrollieren einer Zeichnung, wo das Auge des Drafters bereits ist. Der Montag-Schritt: fügen Sie die vier Layer HNF, NNF, VF und FF zur Office-Rhino-Vorlage hinzu und einigen Sie sich darauf, dass jeder Raum eine benannte geschlossene Kurve auf genau einem davon ist.

Hack: Prüfen Sie den L-förmigen Korridor selbst, bevor Sie dem Skript trauen. Vorhersagen Sie zunächst: 1,4 × 2,6 + 5,3 × 1,4 sollte 11,06 m2 geben. Dann füttern Sie seine sechs Ecken in Metern in den Test-Helfer:

from schedule_core import shoelace
korridor = [(0, 0), (5.3, 0), (5.3, 1.4), (1.4, 1.4), (1.4, 4.0), (0, 4.0)]
print(round(shoelace(korridor), 2))   # expect 11.06

Dann ändern Sie 5,3 in 6,0 und sagen Sie die Antwort voraus, bevor Sie sie ausführen: 1,4 × 2,6 + 6,0 × 1,4 = 12,04.

Nächste Schritte: fügen Sie eine Geschoss-Spalte vom übergeordneten Layer-Namen hinzu, verschieben Sie dann die gleiche Logik in eine Grasshopper-Python-3-Komponente, damit die Tabelle live aktualisiert wird – der Weg, den PAZ Academy in seinen Rhino- und Grasshopper-Kursen lehrt. PAZ hat diesen Boden von der IFC-Seite aus gehen, in a Python door schedule in 30 lines. Gleiche Idee, andere Datei: das Modell kennt es, also lassen Sie das Skript fragen.

Lernquellen:

Öffnen Sie Ihr aktuelles Projekt, ordnen Sie die Räume eines Geschosses den vier Layern zu, und drucken Sie sein Verzeichnis vor Freitag aus.

GEMELDET AUS
MIT-UNTERZEICHNER
PAZ Academy
VERTRAUEN
HIGH
NACHDRUCKE
© PAZ - PARAMETRIC ACADEMY ZURICH · ALLE RECHTE VORBEHALTEN

PAZ Kaffi · interdisziplinäre Redaktionsarbeit, geleitet von der PAZ Academy

⚑ FEHLER MELDEN · KORREKTUR EINSENDEN
◂ ZURÜCK ZUR TITELSEITE · PAZ KAFFI

© 2026 PAZ Academy.