Claude
Skills
Sign in
Back

bim-consistency-checker

Included with Lifetime
$97 forever

Check BIM model consistency: naming conventions, parameter completeness, spatial relationships, and data integrity across model elements.

General

What this skill does

# BIM Consistency Checker for Construction

## Overview

Validate BIM model consistency including naming conventions, parameter completeness, spatial relationships, classification compliance, and cross-reference integrity.

## Business Case

BIM consistency checking ensures:
- **Data Quality**: Complete and accurate model data
- **Interoperability**: Models work across platforms
- **Coordination**: Consistent information for all trades
- **Deliverable Compliance**: Meet BIM execution plan requirements

## Technical Implementation

```python
from dataclasses import dataclass, field
from typing import List, Dict, Any, Optional, Set
from enum import Enum
import re

class CheckSeverity(Enum):
    ERROR = "error"
    WARNING = "warning"
    INFO = "info"

class CheckCategory(Enum):
    NAMING = "naming"
    PARAMETERS = "parameters"
    SPATIAL = "spatial"
    CLASSIFICATION = "classification"
    GEOMETRY = "geometry"
    RELATIONSHIPS = "relationships"

@dataclass
class ConsistencyIssue:
    element_id: str
    element_name: str
    category: CheckCategory
    severity: CheckSeverity
    rule: str
    message: str
    suggestion: str = ""

@dataclass
class ConsistencyReport:
    model_name: str
    total_elements: int
    elements_checked: int
    issues: List[ConsistencyIssue]
    issues_by_category: Dict[str, int]
    issues_by_severity: Dict[str, int]
    pass_rate: float

@dataclass
class NamingConvention:
    element_type: str
    pattern: str
    description: str
    examples: List[str]

class BIMConsistencyChecker:
    """Check BIM model consistency and data quality."""

    # Default naming conventions
    DEFAULT_NAMING_RULES = [
        NamingConvention(
            element_type='Level',
            pattern=r'^(L|Level)\s*\d{1,2}$|^(B|Basement)\s*\d?$|^(R|Roof)$',
            description='Levels should follow L01, Level 1, B1, Roof pattern',
            examples=['L01', 'Level 1', 'B1', 'Roof']
        ),
        NamingConvention(
            element_type='Grid',
            pattern=r'^[A-Z]$|^\d{1,2}$|^[A-Z]\.\d$',
            description='Grids should be single letters (A-Z) or numbers',
            examples=['A', '1', 'A.1']
        ),
        NamingConvention(
            element_type='Room',
            pattern=r'^\d{3,4}[A-Z]?\s*-?\s*.+',
            description='Rooms should have number and name (101 - Office)',
            examples=['101 - Office', '201A Conference']
        ),
        NamingConvention(
            element_type='Wall',
            pattern=r'^(INT|EXT|CW|CMU|GYP)[-_].+',
            description='Walls should have type prefix',
            examples=['INT-GYP-1HR', 'EXT-CMU-8IN']
        ),
        NamingConvention(
            element_type='Door',
            pattern=r'^[A-Z]?\d{2,3}[A-Z]?$',
            description='Doors should follow type numbering',
            examples=['101', 'A101', '101A']
        ),
    ]

    # Required parameters by element type
    REQUIRED_PARAMETERS = {
        'Wall': ['Fire Rating', 'Function', 'Structural'],
        'Door': ['Fire Rating', 'Width', 'Height', 'Frame Material'],
        'Room': ['Name', 'Number', 'Area', 'Department'],
        'Window': ['Width', 'Height', 'Glass Type'],
        'Floor': ['Structural', 'Fire Rating'],
        'Ceiling': ['Height', 'Type'],
        'Column': ['Structural Material', 'Shape'],
        'Beam': ['Structural Material', 'Size'],
    }

    def __init__(self):
        self.naming_rules: List[NamingConvention] = list(self.DEFAULT_NAMING_RULES)
        self.required_params: Dict[str, List[str]] = dict(self.REQUIRED_PARAMETERS)
        self.issues: List[ConsistencyIssue] = []

    def add_naming_rule(self, rule: NamingConvention):
        """Add custom naming convention rule."""
        self.naming_rules.append(rule)

    def set_required_parameters(self, element_type: str, parameters: List[str]):
        """Set required parameters for an element type."""
        self.required_params[element_type] = parameters

    def check_model(self, elements: List[Dict]) -> ConsistencyReport:
        """Run all consistency checks on model elements."""
        self.issues = []

        for element in elements:
            self._check_naming(element)
            self._check_parameters(element)
            self._check_spatial(element)
            self._check_classification(element)
            self._check_geometry(element)

        # Cross-element checks
        self._check_relationships(elements)
        self._check_duplicates(elements)

        # Calculate statistics
        issues_by_category = {}
        issues_by_severity = {}

        for issue in self.issues:
            cat = issue.category.value
            sev = issue.severity.value
            issues_by_category[cat] = issues_by_category.get(cat, 0) + 1
            issues_by_severity[sev] = issues_by_severity.get(sev, 0) + 1

        elements_with_issues = len(set(i.element_id for i in self.issues))
        pass_rate = (len(elements) - elements_with_issues) / len(elements) * 100 if elements else 100

        return ConsistencyReport(
            model_name='Model',
            total_elements=len(elements),
            elements_checked=len(elements),
            issues=self.issues,
            issues_by_category=issues_by_category,
            issues_by_severity=issues_by_severity,
            pass_rate=pass_rate
        )

    def _check_naming(self, element: Dict):
        """Check element naming conventions."""
        element_type = element.get('type', '')
        name = element.get('name', '')
        element_id = element.get('id', '')

        if not name:
            self.issues.append(ConsistencyIssue(
                element_id=element_id,
                element_name='(no name)',
                category=CheckCategory.NAMING,
                severity=CheckSeverity.ERROR,
                rule='Name Required',
                message='Element has no name',
                suggestion='Assign a descriptive name following conventions'
            ))
            return

        # Check against naming rules
        for rule in self.naming_rules:
            if rule.element_type.lower() in element_type.lower():
                if not re.match(rule.pattern, name, re.IGNORECASE):
                    self.issues.append(ConsistencyIssue(
                        element_id=element_id,
                        element_name=name,
                        category=CheckCategory.NAMING,
                        severity=CheckSeverity.WARNING,
                        rule=f'{rule.element_type} Naming',
                        message=f'Name "{name}" does not follow convention',
                        suggestion=f'{rule.description}. Examples: {", ".join(rule.examples)}'
                    ))

        # Check for special characters
        if re.search(r'[<>:"/\\|?*]', name):
            self.issues.append(ConsistencyIssue(
                element_id=element_id,
                element_name=name,
                category=CheckCategory.NAMING,
                severity=CheckSeverity.ERROR,
                rule='Invalid Characters',
                message='Name contains invalid characters',
                suggestion='Remove special characters: < > : " / \\ | ? *'
            ))

    def _check_parameters(self, element: Dict):
        """Check parameter completeness."""
        element_type = element.get('type', '')
        element_id = element.get('id', '')
        name = element.get('name', '')
        params = element.get('parameters', {})

        # Check required parameters
        required = self.required_params.get(element_type, [])
        for param in required:
            if param not in params or params[param] in [None, '', 'None']:
                self.issues.append(ConsistencyIssue(
                    element_id=element_id,
                    element_name=name,
                    category=CheckCategory.PARAMETERS,
                    severity=CheckSeverity.WARNING,
                    rule='Required 

Related in General