| name | bonsai-impl-clash |
| description | Use when performing clash detection, interference checking, or spatial coordination in BIM models using Bonsai and IfcClash. Prevents the common mistake of running clash detection without proper element group filters (testing everything against everything). Covers clash set definition, element filtering, smart grouping of results, and BCF integration for issue tracking. Keywords: clash detection, IfcClash, interference, collision, spatial coordination, clash set, element filter, BCF integration, clash report, find collisions, elements overlap, pipes through walls.
|
| license | MIT |
| compatibility | Designed for Claude Code. Requires Blender with Bonsai addon. |
| metadata | {"author":"OpenAEC-Foundation","version":"1.0"} |
Bonsai Clash Detection Implementation
Version: Bonsai v0.8.x | IfcClash (from IfcOpenShell v0.8.x) | Blender 4.2.0+ | Python 3.11
Module path: bonsai.bim.module.clash — NEVER blenderbim.bim.module.clash
Engine: IfcClash — frontend for FCL (Flexible Collision Library)
Critical Warnings
- ALWAYS save IFC files to disk BEFORE running clash detection. IfcClash reads files from disk, NOT from Blender's in-memory model.
- ALWAYS define BOTH Group A and Group B in every clash set, even for intra-model checks (e.g., structural vs. MEP in the same file).
- ALWAYS use
filter_groups to limit clash scope. Unfiltered detection on large models produces excessive runtime and noise.
- ALWAYS use
bim.smart_clash_group for result sets exceeding 50 clashes. Manual review of hundreds of individual clashes is impractical.
- NEVER expect real-time clash checking. Clash detection is a batch operation — there is NO live monitoring.
- NEVER use
collision mode with allow_touching=True for detecting hard overlaps — this generates false positives where elements share surfaces. Use intersection mode instead.
- ALWAYS specify an output path (
.bcf or .json) before executing clash detection.
- ALWAYS use
bonsai.* imports. NEVER use blenderbim.* — renamed in 2024 (v0.8.0+).
Decision Tree: Clash Detection Mode Selection
What type of geometric conflict are you detecting?
│
├── Physical overlap (pipe through wall, duct through beam)?
│ └── Use mode = "intersection"
│ └── tolerance = 0.001 (1mm) for architectural
│ └── tolerance = 0.0001 (0.1mm) for mechanical
│
├── Surface contact (elements touching)?
│ └── Use mode = "collision"
│ └── allow_touching = False (default) for strict contact detection
│ └── allow_touching = True ONLY when surface sharing is acceptable
│
└── Proximity clearance (maintenance access, fire safety)?
└── Use mode = "clearance"
└── clearance = required_distance_in_meters
└── Example: clearance = 0.3 for 300mm maintenance gap
Decision Tree: Output Format Selection
What will you do with clash results?
│
├── Share with external stakeholders (Navisworks, Solibri, BIMcollab)?
│ └── Export as .bcf
│ └── Each clash becomes a BCF topic with viewpoint
│ └── Set should_create_clash_snapshots = True for visual context
│
├── Programmatic analysis or custom reporting?
│ └── Export as .json
│ └── Contains coordinates, GlobalIds, distances
│ └── Parseable by any JSON library
│
└── Internal review within Bonsai?
└── Export as .json
└── Load with bim.select_ifc_clash_results
└── Navigate clashes in 3D viewport
Essential Patterns
Pattern 1: Define a Clash Set
import bpy
props = bpy.context.scene.BIMClashProperties
bpy.ops.bim.add_clash_set()
clash_set = props.clash_sets[props.active_clash_set_index]
clash_set.mode = "intersection"
clash_set.tolerance = 0.002
bpy.ops.bim.add_clash_source(group="a")
clash_set.a[0].name = "/path/to/structural.ifc"
clash_set.a[0].mode = "i"
bpy.ops.bim.add_clash_source(group="b")
clash_set.b[0].name = "/path/to/mep.ifc"
clash_set.b[0].mode = "i"
Pattern 2: Run Clash Detection
import bpy
props = bpy.context.scene.BIMClashProperties
props.export_path = "/path/to/results.json"
bpy.ops.bim.execute_ifc_clash()
props.should_create_clash_snapshots = True
props.export_path = "/path/to/results.bcf"
bpy.ops.bim.execute_ifc_clash()
Pattern 3: Review Clash Results
import bpy
props = bpy.context.scene.BIMClashProperties
props.clash_results_path = "/path/to/results.json"
bpy.ops.bim.select_ifc_clash_results()
bpy.ops.bim.select_clash(index=0)
clash_set = props.clash_sets[props.active_clash_set_index]
for i, clash in enumerate(clash_set.clashes):
print(f"Clash {i}: {clash.a_name} vs {clash.b_name}")
print(f" A GlobalId: {clash.a_global_id}")
print(f" B GlobalId: {clash.b_global_id}")
print(f" Type: {clash.clash_type}")
bpy.ops.bim.hide_clash()
Pattern 4: Use IfcClash Standalone (Without Bonsai)
import ifcclash
import json
import logging
settings = ifcclash.ClashSettings()
settings.output = "/path/to/results.json"
settings.logger = logging.getLogger("IfcClash")
settings.logger.setLevel(logging.INFO)
clash_sets = [
{
"name": "Structural vs MEP",
"a": [{"file": "/path/to/structural.ifc", "mode": "i", "selector": "IfcBeam"}],
"b": [{"file": "/path/to/mep.ifc", "mode": "i", "selector": "IfcFlowSegment"}],
"tolerance": 0.001,
"mode": "intersection",
}
]
clasher = ifcclash.Clasher(settings)
clasher.clash_sets = clash_sets
clasher.clash()
clasher.export()
Common Operations
Filter Configuration
Element filters control which elements participate in clash detection. Each ClashSource has a mode and optional filter_groups:
| Filter Mode | Value | Behavior |
|---|
| All Elements | "a" | Include every element from the IFC file |
| Include | "i" | Include ONLY elements matching the selector/filter |
| Exclude | "e" | Include all elements EXCEPT those matching the selector/filter |
Standalone IfcClash selector syntax uses IFC class names as filters:
{
"file": "/path/to/model.ifc",
"mode": "i",
"selector": "IfcWall"
}
Bonsai UI filter groups use BIMFilterGroup collections on ClashSource.filter_groups for more granular control (filter by class, property, attribute).
Smart Grouping
Smart grouping clusters spatially proximate clashes using the OPTICS algorithm to reduce noise and identify systemic patterns:
import bpy
props = bpy.context.scene.BIMClashProperties
props.smart_clash_grouping_max_distance = 3
bpy.ops.bim.smart_clash_group()
bpy.ops.bim.load_smart_groups_for_active_clash_set()
bpy.ops.bim.select_smart_group(group_index=0)
for group in props.smart_clash_groups:
print(f"Group {group.number}: {len(group.global_ids)} elements")
BCF Integration
Clash results integrate directly with BCF (BIM Collaboration Format) for issue tracking:
import bpy
props = bpy.context.scene.BIMClashProperties
props.export_path = "/path/to/clashes.bcf"
props.should_create_clash_snapshots = True
bpy.ops.bim.execute_ifc_clash()
bpy.ops.bim.load_bcf_project(filepath="/path/to/clashes.bcf")
Export and Import Clash Set Configurations
import bpy
bpy.ops.bim.export_clash_sets()
bpy.ops.bim.import_clash_sets()
Clash Visualization in 3D Viewport
The ClashDecorator renders clash points as a viewport overlay:
- Two colored points at P1 and P2 (clash contact endpoints)
- Connecting line between P1 and P2 (when points differ)
- Text label at midpoint with clash identification
- Colors configurable via addon preferences (selected/unselected/special)
- Uses GPU shaders (
UNIFORM_COLOR, POLYLINE_UNIFORM_COLOR)
props = bpy.context.scene.BIMClashProperties
print(f"P1: {tuple(props.p1)}")
print(f"P2: {tuple(props.p2)}")
print(f"Label: {props.active_clash_text}")
Workflow: Complete Clash Detection Pipeline
1. Prepare Models
├── Save all IFC files to disk
└── Verify file paths are absolute
2. Define Clash Sets
├── bpy.ops.bim.add_clash_set()
├── Configure mode (intersection/collision/clearance)
├── Set tolerance/clearance values
├── Add Group A sources with filters
└── Add Group B sources with filters
3. Execute Detection
├── Set export_path (.json or .bcf)
├── Set should_create_clash_snapshots (for BCF)
└── bpy.ops.bim.execute_ifc_clash()
4. Review Results
├── Load results: bpy.ops.bim.select_ifc_clash_results()
├── Navigate: bpy.ops.bim.select_clash(index=N)
└── Hide overlay: bpy.ops.bim.hide_clash()
5. Group and Analyze
├── bpy.ops.bim.smart_clash_group()
├── bpy.ops.bim.load_smart_groups_for_active_clash_set()
└── bpy.ops.bim.select_smart_group(group_index=N)
6. Report (optional)
├── BCF export for external collaboration
└── JSON export for programmatic analysis
Operator Quick Reference
| Operator | bl_idname | Purpose |
|---|
| AddClashSet | bim.add_clash_set | Create new clash set |
| RemoveClashSet | bim.remove_clash_set | Delete clash set by index |
| AddClashSource | bim.add_clash_source | Add IFC source to group (a/b) |
| RemoveClashSource | bim.remove_clash_source | Remove source from group |
| SelectClashSource | bim.select_clash_source | File picker for IFC source |
| ExecuteIfcClash | bim.execute_ifc_clash | Run clash detection engine |
| SelectIfcClashResults | bim.select_ifc_clash_results | Load clash results from JSON |
| SelectClash | bim.select_clash | Navigate to individual clash |
| HideClash | bim.hide_clash | Remove clash visualization |
| SmartClashGroup | bim.smart_clash_group | Group clashes by proximity |
| LoadSmartGroupsForActiveClashSet | bim.load_smart_groups_for_active_clash_set | Load saved smart groups |
| SelectSmartGroup | bim.select_smart_group | Select elements in smart group |
| ExportClashSets | bim.export_clash_sets | Export configuration to JSON |
| ImportClashSets | bim.import_clash_sets | Import configuration from JSON |
| SelectClashResults | bim.select_clash_results | Set clash results file path |
| SelectSmartGroupedClashesPath | bim.select_smart_grouped_clashes_path | Set smart groups file path |
Property Reference
BIMClashProperties (on bpy.context.scene)
| Property | Type | Default | Description |
|---|
clash_sets | Collection[ClashSet] | — | All defined clash sets |
active_clash_set_index | Int | 0 | Currently selected clash set |
active_clash_index | Int | 0 | Currently selected clash |
export_path | String | "" | Output path for .bcf or .json |
clash_results_path | String | "" | Path to loaded results file |
should_create_clash_snapshots | Bool | False | Generate BCF viewpoint snapshots |
smart_clash_groups | Collection[SmartClashGroup] | — | Grouped clash results |
active_smart_group_index | Int | 0 | Currently selected smart group |
smart_clash_grouping_max_distance | Int | 3 | Max clustering distance (meters) |
p1 | FloatVector | (0,0,0) | First clash contact point |
p2 | FloatVector | (0,0,0) | Second clash contact point |
active_clash_text | String | "" | Label text for active clash |
Dependencies
- bonsai-core-architecture — Three-layer architecture, IfcStore, operator pattern
- bonsai-syntax-elements — IFC element access via tool.Ifc, entity↔object mapping
Reference Links
Sources