Spaces:
Sleeping
Sleeping
AGENTS.md β Structure Compliance Check
Developer and AI agent reference for contributing to or extending this project.
Project Overview
This project checks BIM/IFC building models for structural and regulatory compliance. It has two interfaces:
- Gradio web app β
reinforcement_check/app.py - Standalone CLI tools β
tools/checker_*.py
Repository Structure
structure_compliance_check/
β
βββ reinforcement_check/ β Gradio web application (main app)
β βββ app.py β Entry point: run with `py reinforcement_check/app.py`
β βββ requirements.txt
β βββ src/
β βββ ifc_analyzer.py β IFCAnalyzer class (property extraction)
β βββ report_generator.py β ReportGenerator class (HTML/text output)
β
βββ tools/ β Standalone IFCore-compliant checker modules
β βββ checker_foundation.py β Art. 69, Art. 128, DB SE-AE (foundation)
β βββ checker_beams.py β EHE / DB SE (beam depth + width)
β βββ checker_columns.py β EHE (column min dimension)
β βββ checker_slabs.py β EHE / DB SE (slab thickness)
β βββ checker_walls.py β DB SE-F, EHE, CTE DB HE (walls)
β βββ checker_reinforcement.py β Reinforcement checks
β βββ checker_accessibility.py β DB SUA (doors, windows, corridors)
β
βββ data/ β Sample IFC files for testing
β
βββ beam_check/ β Legacy source (do not import from tools/)
βββ walls_check/ β Legacy source (do not import from tools/)
βββ reinforcement_check/src/ β Legacy source (do not import from tools/)
IFCore Contract
Every check function in tools/ must follow this contract:
Function signature
def check_<topic>(model: ifcopenshell.file, **kwargs) -> list[dict]:
...
- Accepts an
ifcopenshell.fileobject - Returns a
list[dict]β one dict per element checked
Required dict keys (9 fields)
{
"element_id": str | None, # GlobalId of the IFC element
"element_type": str, # e.g. "IfcFooting", "IfcWall"
"element_name": str, # Short display name
"element_name_long": str | None, # Long name with context/regulation
"check_status": str, # "pass" | "fail" | "warning" | "blocked" | "log"
"actual_value": str | None, # Measured value (e.g. "250 mm", "0.75 W/(mΒ²Β·K)")
"required_value": str | None, # Required value (e.g. "β₯ 300 mm")
"comment": str | None, # Human-readable explanation
"log": str | None, # Debug info (key=value pairs)
}
Status values
| Status | When to use |
|---|---|
pass |
Element meets the regulation |
fail |
Element does not meet the regulation |
warning |
Marginal / borderline case β review recommended |
blocked |
Required data not found in IFC model |
log |
Informational row (not a compliance result) |
Adding a New Checker
- Create
tools/checker_<topic>.py - Import only
ifcopenshelland stdlib β no imports from other project folders - Write private helpers prefixed with
_ - Write public
check_*functions following the IFCore contract above - Add a
__main__block for CLI use:
if __name__ == "__main__":
import sys
ifc_path = sys.argv[1] if len(sys.argv) > 1 else "data/01_Duplex_Apartment.ifc"
print("Loading:", ifc_path)
_model = ifcopenshell.open(ifc_path)
_ICON = {"pass": "PASS", "fail": "FAIL", "warning": "WARN", "blocked": "BLKD", "log": "LOG "}
for _fn in [check_my_function]:
print("\n" + "=" * 60)
print(" ", _fn.__name__)
print("=" * 60)
for _row in _fn(_model):
print(" ", "[" + _ICON.get(_row["check_status"], "?") + "]", _row["element_name"])
if _row["actual_value"]:
print(" actual :", _row["actual_value"])
if _row["required_value"]:
print(" required :", _row["required_value"])
print(" comment :", _row["comment"])
- Run from the project root:
py tools/checker_<topic>.py data/01_Duplex_Apartment.ifc
Dimension Extraction Priority
When extracting dimensions from IFC elements, use this fallback chain:
| Priority | Source | Example |
|---|---|---|
| 1 | Quantity sets | Qto_FootingBaseQuantities.Width |
| 2 | Extruded geometry | IfcExtrudedAreaSolid β IfcRectangleProfileDef |
| 3 | Property sets | PSet_Revit_Type_Dimensions.d, Pset_WallCommon.Width |
| 4 | Element name parsing | "Bearing Footing - 900 x 300" β width=900mm, depth=300mm |
| 5 | Material layers | Sum of IfcMaterialLayerSet thicknesses |
If all paths fail β return check_status: "blocked" with a comment listing what was searched.
Unit Handling
- Use
_get_length_scale(model)to readIfcUnitAssignmentand get a metre conversion factor - Multiply all geometry/quantity values by
scaleto convert to metres - Do not scale pressure/load values (kN/mΒ²) β these are unit-independent
Gradio App Integration
To add a new checker to the Gradio app (reinforcement_check/app.py):
- Import the checker at the top of
app.py:sys.path.insert(0, str(Path(__file__).parent.parent / "tools")) from checker_<topic> import check_<function> - Call it inside a tab's button handler
- Pass results to
_build_*_html()or add a new rendering function - Return an
gr.HTMLcomponent with the results
Regulations Reference
| Regulation | Topic | Requirement |
|---|---|---|
| Art. 69 (Met. Building Ord.) | Foundation slab thickness | β₯ 300 mm (150 mm concrete + 150 mm drainage) |
| Art. 128 (Met. Building Ord.) | Floor capacity | max floors = bearing capacity / floor load |
| DB SE-AE | Bearing beam section | β₯ 300 Γ 300 mm |
| EHE | Beam depth | β₯ 200 mm |
| EHE | Beam width | β₯ 150 mm |
| EHE | Column min side | β₯ 250 mm |
| EHE / DB SE | Slab thickness | 100 β 200 mm |
| DB SE-F / EHE | Wall thickness | β₯ 100 mm |
| CTE DB HE | Wall U-value | β€ 0.80 W/(mΒ²Β·K) |
| DB SUA | Door width | β₯ 800 mm |
Running the App
py reinforcement_check/app.py
Gradio auto-selects an available port. The browser opens automatically.
Running Individual Checkers
py tools/checker_foundation.py data/01_Duplex_Apartment.ifc
py tools/checker_beams.py data/01_Duplex_Apartment.ifc
py tools/checker_columns.py data/01_Duplex_Apartment.ifc
py tools/checker_slabs.py data/01_Duplex_Apartment.ifc
py tools/checker_walls.py data/01_Duplex_Apartment.ifc