# BIM/IFC models for QTO

<div class="paragraph" id="bkmrk-below-is-a-concise%2C-">Below is a concise, **Python-first** recipe that shows exactly how to plug an **IFC model** (provided with the QRF) into your **Quantity-Take-Off (QTO)** pipeline. It follows the **external-mode** pattern described in the BIM literature: the IFC file is **only a data source**; all logic runs in Python.</div>---

### 1. Install the core IFC library

```bash
pip install ifcopenshell pandas openpyxl
```

<div data-v-e8248998="" id="bkmrk--1"></div>### 2. Load the IFC file and list every structural element

```python
import ifcopenshell, ifcopenshell.util.element as util
from pathlib import Path

model = ifcopenshell.open(Path("rfx_structural.ifc"))

# Example: grab every IfcBeam, IfcColumn, IfcMember, etc.
elements = (model.by_type("IfcBeam") +
            model.by_type("IfcColumn") +
            model.by_type("IfcMember"))
```

<div data-v-e8248998="" id="bkmrk--2"></div>### 3. Extract the quantities you need

```python
rows = []
for e in elements:
    # 1. Identity
    name   = e.Name or e.GlobalId
    ifc_ent= e.is_a()

    # 2. Geometry quantities (IfcElementQuantity)
    qs = util.get_psets(e).get("Pset_ElementQuantity", {})
    length_m = float(qs.get("Length", 0))
    weight_kg= float(qs.get("Weight", 0))     # if the modeller exported it
    area_m2  = float(qs.get("SurfaceArea", 0))

    # 3. Material grade (IfcMaterial)
    mat = util.get_material(e)
    grade = mat.Name if mat else "Unknown"

    rows.append({
        "Item"      : name,
        "Type"      : ifc_ent,
        "Material"  : grade,
        "Length_m"  : length_m,
        "Weight_kg" : weight_kg,
        "Area_m2"   : area_m2
    })
```

<div data-v-e8248998="" id="bkmrk--3"></div>### 4. Build a Pandas DataFrame → instant QTO table

```python
import pandas as pd

df = pd.DataFrame(rows)
# Aggregate identical sections
qto = (df
       .groupby(["Type", "Material"], as_index=False)
       .agg({"Length_m":"sum",
             "Weight_kg":"sum",
             "Area_m2":"sum"}))
```

<div data-v-e8248998="" id="bkmrk--4"></div>### 5. Export to Excel (ready for BOQ merge)

```python
qto.to_excel("IFC_QTO.xlsx", index=False)
```

<div data-v-e8248998="" id="bkmrk--5"></div>### 6. Optional: validate IFC quality first

<div class="paragraph" id="bkmrk-use-bimvision-or-sol">Use **BIMvision** or **Solibri Anywhere** (free viewers) to visually inspect the model and confirm that all **Pset\_ElementQuantity** properties are populated.</div>### 7. Handling federated models (multiple IFC files)

<div class="paragraph" id="bkmrk-if-the-qrf-supplies-">If the QRF supplies **several partial IFC files**, merge them once:</div>- <div class="paragraph">**BIMvision → IFC Merge plugin** (permanent merge), or</div>
- <div class="paragraph">**IfcOpenShell** (memory merge) if you want to stay in Python.</div>

### 8. When IFC lacks quantities

<div class="paragraph" id="bkmrk-if-the-ifc-only-has-">If the IFC only has geometry, compute **volume/length/area** yourself:</div>```python
import ifcopenshell.geom as geom
settings = geom.settings()
shape = geom.create_shape(settings, e)
volume = shape.geometry.volume
```

<div data-v-e8248998="" id="bkmrk--6"></div>### 9. Keep the workflow **MVD-compliant**

<div class="paragraph" id="bkmrk-the-nbims-qto-guide-">The NBIMS QTO guide recommends exporting with the **CDB-2010 MVD** view (or later). Ask the designer to tick that option in Revit/ArchiCAD so that **Pset\_ElementQuantity** and **IfcMaterial** are automatically embedded.</div>### Summary of the integration pattern

<div class="table markdown-table" data-v-0909cf3c="" data-v-3a4aba44="" id="bkmrk-step-tool-%2F-library-"><div class="table-container" data-v-0909cf3c=""><table data-v-0909cf3c=""><thead data-v-0909cf3c=""><tr data-v-0909cf3c=""><th align="left" data-v-0909cf3c="">Step</th><th align="left" data-v-0909cf3c="">Tool / Library</th><th align="left" class="" data-v-0909cf3c="">Purpose</th></tr></thead><tbody data-v-0909cf3c=""><tr data-v-0909cf3c=""><td align="left" class="" data-v-0909cf3c="">IFC ingestion</td><td align="left" class="" data-v-0909cf3c="">`IfcOpenShell`</td><td align="left" class="" data-v-0909cf3c="">Parse geometry &amp; properties</td></tr><tr data-v-0909cf3c=""><td align="left" class="" data-v-0909cf3c="">Quantity extraction</td><td align="left" class="" data-v-0909cf3c="">`IfcElementQuantity` or auto-calc</td><td align="left" class="" data-v-0909cf3c="">Length, area, volume, weight</td></tr><tr data-v-0909cf3c=""><td align="left" class="" data-v-0909cf3c="">Data shaping</td><td align="left" class="" data-v-0909cf3c="">`Pandas`</td><td align="left" class="" data-v-0909cf3c="">Group, sum, clean</td></tr><tr data-v-0909cf3c=""><td align="left" class="" data-v-0909cf3c="">Output</td><td align="left" class="" data-v-0909cf3c="">`openpyxl`</td><td align="left" class="" data-v-0909cf3c="">Excel BOQ ready for pricing</td></tr><tr data-v-0909cf3c=""><td align="left" class="" data-v-0909cf3c="">Visual QC</td><td align="left" class="" data-v-0909cf3c="">BIMvision / Solibri</td><td align="left" class="" data-v-0909cf3c="">Confirm model quality</td></tr></tbody></table>

</div></div><div class="paragraph" id="bkmrk-this-external-mode-a">This external-mode approach keeps your Python stack lightweight, avoids STAAD-Pro geometry duplication, and produces **code-compliant QTO tables** in minutes</div>