vflow2 Documentation

IFC Analysis Tools ← Back to App

Heizlast Quality Check

Purpose

Real-world IFC models have sharp edges — models with "OKFF" vs. "OKRD" storey duplication, thin shaft walls sitting inside room AABBs, and openings tied to the wrong storey. These don't always make the extractor crash; they silently skew the heating load. The quality check runs a battery of structural tests over the heizlast envelope and surfaces anything suspicious so the user can decide whether it's a modelling quirk to accept or a bug to chase.

Clean-fixture Qualitätscheck panel

Where it lives

File Purpose
tools/_heizlast_quality.py Check definitions + the run_all_checks(ifc_path) entry point
app.py :: /heizlast_quality/<filename> GET endpoint (200 if cache is fresh, 202 + heizlast job otherwise)
templates/viewer.html (Heizlast view) "Qualitätscheck" button + expandable report panel
tests/test_heizlast_quality_{unit,e2e,ui}.py 10 unit + 5 e2e + 2 Playwright

Checks

Each issue has a check_id, level (error / warn / info), title, description, count, up to 10 samples, and a fix_hint.

Check Level What it catches Fix hint
zero_wall_rooms error Heated rooms with zero wall surfaces (balconies / terraces filtered by PredefinedType=EXTERNAL or name patterns) Room AABB doesn't touch any wall face — check placement and Z-offset
self_adjacency error Wall where adj_space_gid == owner_space_gid — a shaft/partition that slipped past the self-overlap filter in _compute_wall_sub_ranges Non-axis-aligned wall geometry; refine _face_bounding_segments
slab_double_count error Same (slab, room, surface_type) triple emitted twice Shrink slab Z-tolerance or guard against floor+ceiling matches on the same thin slab
missing_wall_openings error Opening declared via FillsVoids but absent from the envelope Opening position falls outside wall sub-ranges — verify local-frame transform
wall_area_divergence warn ΣWallArea diverges >50% from Qto_SpaceBaseQuantities.GrossWallArea Relax Z-tolerance when rooms and walls sit on different storey layers (OKFF vs. OKRD)
opening_storey_mismatch info Door/window's own storey differs from its parent wall's storey Data quirk; UI filters should inherit parent-wall storey for openings
zero_volume_rooms error IfcSpace with no volume + no surfaces Re-export with geometry + Qto; or exclude via usage_type
orphan_adjacencies warn Wall's adj_space_gid points to a room not in the envelope Force recompute (?force=1); check space GlobalId stability

Cache version bump

The extraction-cache format got a schema_version = 2 bump on 2026-04-23 (self-adjacency fix). Existing <stem>.heizlast.json / <stem>.room_network.json files with schema_version = 1 are detected as stale on the next load and regenerate automatically. User-entered surface_overrides survive — they're keyed on stable surface_id strings and the cache-load path preserves them across the version bump.

If a model's bundle was never regenerated after the fix, the quality check may surface a non-zero self_adjacency count on first open. Hitting "Neu berechnen" once clears it.

API shape

GET /heizlast_quality/<filename>?project=<name>

Running checks from Python

from tools._heizlast_quality import run_all_checks
report = run_all_checks("uploads/my-project/versions/v1/arch.ifc",
                        use_cache=True)  # use_cache=False forces re-extract
for issue in report["issues"]:
    if issue["count"]:
        print(f"[{issue['level']}] {issue['check_id']} = {issue['count']}")

Extending

New check function signature:

def check_something(envelope: dict, model) -> QualityIssue:
    ...

Register it in run_all_checks. Return count = 0 + level = "info" for the clean-bill case (so totals_by_level stays accurate).