File size: 6,933 Bytes
51982d6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# 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

```python
def check_<topic>(model: ifcopenshell.file, **kwargs) -> list[dict]:
    ...
```

- Accepts an `ifcopenshell.file` object
- Returns a `list[dict]` β€” one dict per element checked

### Required dict keys (9 fields)

```python
{
    "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

1. Create `tools/checker_<topic>.py`
2. Import only `ifcopenshell` and stdlib β€” **no imports from other project folders**
3. Write private helpers prefixed with `_`
4. Write public `check_*` functions following the IFCore contract above
5. Add a `__main__` block for CLI use:

```python
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"])
```

6. Run from the project root:

```bash
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 read `IfcUnitAssignment` and get a metre conversion factor
- Multiply all geometry/quantity values by `scale` to 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`):

1. Import the checker at the top of `app.py`:
   ```python
   sys.path.insert(0, str(Path(__file__).parent.parent / "tools"))
   from checker_<topic> import check_<function>
   ```
2. Call it inside a tab's button handler
3. Pass results to `_build_*_html()` or add a new rendering function
4. Return an `gr.HTML` component 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

```bash
py reinforcement_check/app.py
```

Gradio auto-selects an available port. The browser opens automatically.

## Running Individual Checkers

```bash
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
```