Check a BIM or IFC model before quantities or fabrication are taken from it: missing and duplicated elements, unclassified objects, broken geometry, wrong units and levels, with a tool-neutral severity checklist and a pass or fail report a detailer can act on. Use when receiving, auditing, or issuing an IFC model, before a quantity takeoff, a coordination gate, or fabrication, or when a model health check is asked for.
name: "bim_model_quality_checks" description: "Check a BIM or IFC model before quantities or fabrication are taken from it: missing and duplicated elements, unclassified objects, broken geometry, wrong units and levels, with a tool-neutral severity checklist and a pass or fail report a detailer can act on. Use when receiving, auditing, or issuing an IFC model, before a quantity takeoff, a coordination gate, or fabrication, or when a model health check is asked for."
Purpose
Decide, with evidence, whether an IFC model is safe to take quantities from, coordinate against, or fabricate from. The method is tool neutral. It works with a text pre-screen, the buildingSMART Validation Service, an IDS check, and any geometry checker, and it does not depend on one vendor model health feature.
A model that opens in a viewer has only proved it parsed. The defects that get a delivery rejected, or a takeoff wrong, are usually invisible on screen: duplicated GlobalIds, elements with no storey, proxies nobody classified, empty property sets, a length unit nobody agreed, and solids that count in a schedule but build nothing. This skill checks those first.
Workflow
1. Freeze the context before checking anything
- Record the file name, file size, date received, source team, revision or suitability code, IFC schema from FILE_SCHEMA, and the agreed model view. A check run against the wrong revision is wasted work.
- Record the purpose of this gate in one line: coordination, quantity takeoff, or fabrication. Severity depends on purpose. A missing fire rating blocks a compliance gate, a zero volume solid blocks fabrication, neither blocks an early massing review.
- Record the agreed units, level naming, classification system, and tolerance for duplicate and clash tests, taken from the project information requirements or the BIM Execution Plan. If no agreement exists, state that in the report and check against the defaults in
references/check-catalog.md.
- Keep the checked file unchanged. Work on a copy for any script or conversion step.
2. Run the pre-screen script
- Run the bundled text pre-screen first. It needs only Python 3, no IFC library:
bash
python3 scripts/check_ifc.py model.ifc
python3 scripts/check_ifc.py model.ifc --json --fail-on major > prescreen.json
- The script reports duplicate GlobalIds, a missing IfcUnitAssignment or missing LENGTHUNIT, IfcBuildingElementProxy count, PredefinedType NOTDEFINED count, physical elements with no IfcRelContainedInSpatialStructure entry, duplicated storey elevations, and physical elements whose Representation is null.
- Treat the script as a pre-screen, not a validator. It parses STEP text, it does not enforce EXPRESS schema rules and it does not build geometry. Say so in the report when you cite it.
- If the file is IFCZIP or IFCXML, unzip or convert a copy first, or skip the script and note why.
3. Check file conformance
- Submit the file to the buildingSMART Validation Service, or run an equivalent local check, and keep the result with the report. That service checks four things: STEP syntax, the referenced IFC schema, normative IFC rules, and bSDD compliance for classification and property references. Industry practice findings there are warnings, not errors.
- Know the limit of that service: it does not check project, national, or organisation specific rules. A conformance pass does not mean the model meets this project requirements. That is what step 6 is for. The hosted service also has a file size limit, 250 MB at the time of writing, so large files need a local route.
- Classify any schema or normative rule failure as a blocker. The receiving tool may import the file anyway and silently drop the broken parts.
4. Check identity, counts, and duplicates
- Confirm every physical element has a unique GlobalId. Duplicates are blockers: they corrupt federation, reimport, and BCF issue links, which are keyed by GlobalId.
- Count elements by IFC class and compare to the previous revision and to the count after import into the receiving tool. Explain any jump. Common causes are a duplicated link, a floor copied twice, or an export that included a linked model.
- Hunt exact duplicates in the geometry checker: same class, same placement, same bounding box size within the agreed tolerance. Two copies in the same place will both be counted. That is a counting defect, so keep it out of the clash report and list it on its own.
- Treat near duplicates with care. Same class with heavy overlap can be correct modelling, for example a column inside a wall build up. Mark those for a visual review, do not auto fail them.
- Flag elements with no representation. They appear in schedules, add to counts, and clash with nothing.
5. Check spatial structure, units, and levels
- Walk the spatial chain: IfcProject to site to building to storey. Every physical element in scope should be contained once, through IfcRelContainedInSpatialStructure, in the storey or space where it belongs. Uncontained elements are missed by level based takeoff and by most filters.
- Check storeys: elevations present, unique, and in order, names matching the agreed level naming. A duplicated elevation usually means a copied level or a split level modelled twice.
- Read project units from IfcProject.UnitsInContext and its IfcUnitAssignment. Each unit type must appear once in that assignment, which is formal rule WR01 in the IFC schema. Record the length, area, and volume units in the report header. If the length unit differs from the project agreement, stop: quantities from this file are a blocker level risk, because every number scales from that unit.
- Check placement distance from the project origin and, where required, IfcMapConversion and the target coordinate system. A model placed far from origin loses precision and lands in the wrong place on federation.
- Remember the inheritance rule when reading quantities: a quantity with no unit of its own uses the project unit assignment. Never guess a unit from the size of a number.
6. Check classification and properties, with IDS when there is one
- Check the IFC class against the real object. Use the closest matching class first, then a real PredefinedType. NOTDEFINED is a finding. USERDEFINED only passes with an ObjectType that says what the thing is.
- Count IfcBuildingElementProxy. Each proxy needs a written reason or a correct class before takeoff, because filters, cost codes, and fabrication rules key off class.
- Check classification references where the project requires them, through IfcRelAssociatesClassification to an IfcClassificationReference code, against the agreed system and edition.
- If the project has an IDS file, run it and attach the per specification result. IDS 1.0, a buildingSMART standard approved in June 2024, states requirements for entity, attribute, classification, property, material, and partOf in a form a checker can test. IDS does not define geometry detail, so an IDS pass does not clear geometry.
- If there is no IDS, build a short property checklist from the written requirements for the classes in scope: required property sets present and filled, correct value types, no empty strings or placeholder text counted as delivered. Note in the report that this part was checked manually.
- Check the properties the next step depends on, not every property in the file. For takeoff that is usually material, type, and the quantity set. For compliance it is usually fire rating, IsExternal, and load bearing, where those are required.
7. Check geometry with a kernel, not by eye
- Tessellate or open the model in a real geometry tool: IfcOpenShell, Solibri, Navisworks, BIMcollab Zoom, or the receiving fabrication tool. List elements that fail to build, build with zero volume where a solid is expected, or have a bounding box that is zero thickness or far larger than the building.
- With IfcOpenShell the pattern is:
python
import ifcopenshell
import ifcopenshell.geom
model = ifcopenshell.open("model.ifc")
settings = ifcopenshell.geom.settings()
tree = ifcopenshell.geom.tree()
tree.add_model(model)
for el in model.by_type("IfcElement"):
if not el.Representation:
print("NO_REP", el.GlobalId, el.is_a(), el.Name)
- Check openings against fillers: a door or window should fill a host opening, and the host should carry the matching void. A missing void makes the host quantity wrong and the fabrication cut missing.
- Run clash tests only between the agreed discipline pairs, with the agreed hard clash and clearance tolerances, and keep the result separate from the duplicate list and the quality findings.
8. Apply the quantities gate
- Do not release quantities until three numbers agree or the difference is explained in writing: the element count by class in the IFC file, the quantity totals read from the model, and the count and totals after import into the takeoff or fabrication tool.
- Spot check five elements by hand: measure the geometry, recompute length, area, or volume, and compare with the stored IfcElementQuantity value. Stored quantities can go stale after an edit.
- For fabrication, add the fabrication inputs to the gate: materials and grades, profile or type names, and assembly marks present and unique. Passing geometry alone does not clear a model for fabrication.
9. Score, decide, and report
- Assign every finding a severity:
- Blocker: the file will mislead takeoff, fabrication, or federation. Examples: duplicate GlobalId, no length unit or a length unit that breaks the agreement, a schema failure, an element in fabrication scope that builds no solid.
- Major: the finding will cause rework or a wrong count if it is not fixed. Examples: uncontained elements, proxies in takeoff scope, NOTDEFINED types, missing required properties, a door with no host void.
- Minor: worth fixing, does not change a count or a build decision. Examples: a duplicated storey elevation with a clear cause, naming drift outside the takeoff scope.
- Info: an observation, a churn note between revisions, a performance note about file size.
- Apply the verdict rule: any blocker means FAIL, do not use the model for the stated purpose. Majors with no blocker means PASS WITH ACTIONS, usable only for the purposes the majors do not touch, and the report must say which those are. No blockers and no majors means PASS.
- Write the report in the Output Contract format. Every finding names the check, the severity, the count, and the GlobalIds or STEP ids a detailer can use to find the elements. Export coordination findings as BCF where the team works that way, so each issue carries its viewpoint and element links back into the authoring tool.
- Re-run the same checks on the corrected file and compare counts. Close a finding only when the re-run shows it gone, not when someone says it was fixed.
Output Contract
Deliver a report with these parts, in this order:
- Header: file name, revision, schema, model view, checker and date, purpose of the gate, project length, area, and volume units, element count, and storey list.
- Verdict: PASS, PASS WITH ACTIONS, or FAIL, in the first lines, with the blocker and major counts next to it.
- Findings table or list: one row per check that failed, with severity, check name, count, a plain description of the risk, and the affected GlobalIds (first 20, with the full list in a CSV or JSON attachment when there are more).
- Counts comparison: elements by class for this revision, the previous revision, and the receiving tool after import, with differences explained.
- Quantities gate result: the three way reconciliation and the five element spot check, with numbers.
- Attachments: the pre-screen JSON when the script was run, the Validation Service result, the IDS result when an IDS exists, and a BCF file when findings were exported for coordination.
Worked example, shortened from a real pre-screen run on a test file with planted defects:
text
File: bad.ifc
Schema: IFC4
Purpose: quantity takeoff
Units: length NOT FOUND, area SQUARE_METRE, volume NOT FOUND
Verdict: FAIL (2 blockers, 4 majors, 1 minor)
- [blocker] duplicate_globalid: GlobalId 0vY$2X3$P5u8fQgAaaaaaa is used by
2 entities. Duplicates corrupt federation and BCF issue links.
- [blocker] units: IfcUnitAssignment exists but no LENGTHUNIT was found.
Quantities cannot be trusted until the author re-exports with units.
- [major] classification: 1 element exported as IfcBuildingElementProxy.
- [major] spatial_containment: 3 of 3 physical elements appear in no
IfcRelContainedInSpatialStructure. Level based takeoff will miss them.
- [major] geometry: 3 physical elements have no representation.
- [minor] levels: duplicate storey elevation 0.0 on L1 and L2.
Action: return to author. Do not take quantities from this file.
Operating Rules
- Never take quantities or fabrication data from a model with an open blocker, and never soften a blocker to get a gate to pass. Change the verdict only after a re-run on a corrected file.
- Never invent a unit, a level, a classification code, a tolerance, or a required property. Take each one from the file, the IDS, or the project requirements, and name the source in the report.
- Never report a check as done when the tool did not run. If there was no IDS, no geometry kernel, or no Validation Service run, the report says that plainly and marks that area unchecked.
- Keep duplicates, clashes, and quality findings in separate lists. They have different owners and different fixes, and mixing them hides the counting risk.
- Report elements by GlobalId, not by screen position or row number. GlobalId is the only identifier that survives the trip into the authoring tool, the checker, and a BCF issue.
- Do not fix the model silently during a check. Report the findings to the author, unless the task explicitly includes repairing the file. A checker who edits loses the audit trail that ISO 19650 style review depends on.
- Compare against the previous revision every time. A single snapshot cannot show GlobalId churn, count jumps, or a level that moved.
- Keep bulky detail out of the verdict. Full element lists, kernel logs, and IDS detail belong in attachments. The body of the report stays short enough for a detailer to act on in one reading.
References
- Full check catalog with severity defaults:
references/check-catalog.md
- Pre-screen script:
scripts/check_ifc.py
- buildingSMART Validation Service: https://technical.buildingsmart.org/services/validation-service/
- buildingSMART IDS standard: https://www.buildingsmart.org/standards/bsi-standards/information-delivery-specification-ids/page/2/
- buildingSMART BCF standard: https://www.buildingsmart.org/standards/bsi-standards/bim-collaboration-format/
- IfcOpenShell documentation: https://docs.ifcopenshell.org/autoapi/ifcopenshell/index.html
No ratings yet — be the first to rate it.