AI system for BIM model analysis
BIM (Building Information Modeling) stores not only the building's geometry but also metadata: materials, suppliers, schedules, and costs. An IFC file for a large facility contains tens of thousands of elements. Manual analysis of such a volume is a bottleneck in construction projects. AI-based BIM analysis automates clash detection, code compliance monitoring, and report generation.
Parsing and analyzing IFC files
import ifcopenshell
import ifcopenshell.geom
import numpy as np
from typing import Optional
import json
class BIMAnalyzer:
def __init__(self, ifc_path: str):
self.model = ifcopenshell.open(ifc_path)
self.settings = ifcopenshell.geom.settings()
self.settings.set(self.settings.USE_WORLD_COORDS, True)
def get_elements_by_type(self, ifc_type: str) -> list:
"""Получить все элементы определённого типа"""
return self.model.by_type(ifc_type)
def check_structural_clearances(self,
min_clearance_mm: float = 300) -> list[dict]:
"""
Проверка зазоров между инженерными системами.
Типичная clash detection задача: трубы проходят сквозь балки.
"""
pipes = self.model.by_type('IfcPipeSegment')
beams = self.model.by_type('IfcBeam')
columns = self.model.by_type('IfcColumn')
structural = beams + columns
clashes = []
for pipe in pipes:
try:
pipe_shape = ifcopenshell.geom.create_shape(
self.settings, pipe
)
pipe_bbox = self._get_bbox(pipe_shape)
except Exception:
continue
for struct_el in structural:
try:
struct_shape = ifcopenshell.geom.create_shape(
self.settings, struct_el
)
struct_bbox = self._get_bbox(struct_shape)
except Exception:
continue
# Проверка пересечения bounding boxes с отступом
if self._bboxes_overlap(pipe_bbox, struct_bbox,
margin=min_clearance_mm):
clashes.append({
'element_1': {
'guid': pipe.GlobalId,
'type': 'IfcPipeSegment',
'name': pipe.Name
},
'element_2': {
'guid': struct_el.GlobalId,
'type': struct_el.is_a(),
'name': struct_el.Name
},
'clash_type': 'clearance_violation',
'min_clearance_mm': min_clearance_mm
})
return clashes
def analyze_quantities(self) -> dict:
"""Автоматический подсчёт объёмов и площадей"""
quantities = {}
for wall in self.model.by_type('IfcWall'):
area = self._get_quantity(wall, 'NetSideArea')
if area:
quantities.setdefault('walls_area_m2', 0)
quantities['walls_area_m2'] += area
for slab in self.model.by_type('IfcSlab'):
area = self._get_quantity(slab, 'NetArea')
if area:
quantities.setdefault('slabs_area_m2', 0)
quantities['slabs_area_m2'] += area
return quantities
def check_fire_safety_compliance(self) -> list[dict]:
"""Проверка требований пожарной безопасности"""
issues = []
# Проверка расстояния между эвакуационными выходами
exits = [d for d in self.model.by_type('IfcDoor')
if self._is_emergency_exit(d)]
if len(exits) < 2:
issues.append({
'type': 'insufficient_emergency_exits',
'severity': 'critical',
'description': f'Найдено {len(exits)} аварийных выходов, требуется минимум 2'
})
# Проверка наличия систем пожаротушения
sprinklers = self.model.by_type('IfcFireSuppressionTerminal')
if not sprinklers:
issues.append({
'type': 'no_sprinkler_system',
'severity': 'critical',
'description': 'Система пожаротушения не найдена в BIM'
})
return issues
AI-based element classification and markup automation
Sometimes BIM models arrive with incomplete element classifications. An NLP model automatically determines the type based on the element's name and attributes:
from transformers import pipeline
class BIMElementClassifier:
def __init__(self):
self.classifier = pipeline(
'zero-shot-classification',
model='facebook/bart-large-mnli',
device=0
)
self.categories = [
'structural_beam', 'structural_column', 'wall',
'floor_slab', 'roof', 'pipe', 'duct', 'electrical_conduit',
'window', 'door', 'stair', 'elevator'
]
def classify_element(self, element_name: str,
element_description: str = '') -> dict:
text = f"{element_name}. {element_description}"
result = self.classifier(text, self.categories)
return {
'predicted_class': result['labels'][0],
'confidence': result['scores'][0]
}
Visualization and reports
BIM analysis is useless without a user-friendly report for engineers:
import plotly.graph_objects as go
class BIMReportGenerator:
def generate_clash_report(self, clashes: list[dict],
output_path: str):
# Группировка по типам столкновений
by_type = {}
for clash in clashes:
t = clash['clash_type']
by_type.setdefault(t, 0)
by_type[t] += 1
fig = go.Figure(data=[go.Bar(
x=list(by_type.keys()),
y=list(by_type.values())
)])
fig.update_layout(title='Количество конфликтов по типам')
fig.write_html(output_path)
Case: Residential complex, 30,000 m²
IFC model of the residential complex: 85,000 elements, 3 buildings, 18 floors each. Manual clash detection check: 2 BIM coordinators, 4 business days.
After automation:
- Model processing: 18 minutes
- 347 clashes found (pipe-beam, duct-column)
- Of these, critical (physical intersection): 23
- All confirmed by an engineer - 0 false positives
| Project type | Term |
|---|---|
| Clash detection pipeline | 3-5 weeks |
| Full BIM QC (clash + standards + quantities) | 6–10 weeks |
| AI classification + reports + Autodesk integration | 10–16 weeks |







