Check element for geometric clashes against other elements. :param model: The IFC model. :param element: The element to check. :param clearance: Minimum clearance distance; if provided, runs clearance check. :param tolerance: Intersection tolerance in meters (default 0.002). :pa
(
model: ifcopenshell.file,
element: ifcopenshell.entity_instance,
clearance: float | None = None,
tolerance: float = 0.002,
scope: str = "storey",
)
| 96 | |
| 97 | |
| 98 | def clash( |
| 99 | model: ifcopenshell.file, |
| 100 | element: ifcopenshell.entity_instance, |
| 101 | clearance: float | None = None, |
| 102 | tolerance: float = 0.002, |
| 103 | scope: str = "storey", |
| 104 | ) -> dict[str, Any]: |
| 105 | """Check element for geometric clashes against other elements. |
| 106 | |
| 107 | :param model: The IFC model. |
| 108 | :param element: The element to check. |
| 109 | :param clearance: Minimum clearance distance; if provided, runs clearance check. |
| 110 | :param tolerance: Intersection tolerance in meters (default 0.002). |
| 111 | :param scope: Which elements to check against: "storey" or "all". |
| 112 | :return: Dict with clash results suitable for JSON serialization. |
| 113 | """ |
| 114 | result: dict[str, Any] = {"element": _ref(element)} |
| 115 | |
| 116 | # Get scope elements |
| 117 | scope_elements, effective_scope = _get_scope_elements(model, element, scope) |
| 118 | result["scope"] = effective_scope |
| 119 | |
| 120 | if not scope_elements: |
| 121 | result["pass"] = True |
| 122 | result["checks"] = {"intersection": {"pass": True, "tolerance": tolerance, "clashes": []}} |
| 123 | if clearance is not None: |
| 124 | result["checks"]["clearance"] = {"pass": True, "clearance": clearance, "clashes": []} |
| 125 | return result |
| 126 | |
| 127 | # Build geometry tree for target element + scope elements |
| 128 | all_elements = scope_elements | {element} |
| 129 | geom_tree = _build_tree(model, all_elements) |
| 130 | |
| 131 | if geom_tree is None: |
| 132 | result["pass"] = None |
| 133 | result["error"] = f"No geometry for element #{element.id()}" |
| 134 | return result |
| 135 | |
| 136 | # Run intersection check |
| 137 | intersection_clashes = geom_tree.clash_intersection_many( |
| 138 | [element], list(scope_elements), tolerance=tolerance, check_all=True |
| 139 | ) |
| 140 | intersection_results = [_format_clash(c, geom_tree, model) for c in intersection_clashes] |
| 141 | checks: dict[str, Any] = { |
| 142 | "intersection": { |
| 143 | "pass": len(intersection_results) == 0, |
| 144 | "tolerance": tolerance, |
| 145 | "clashes": intersection_results, |
| 146 | } |
| 147 | } |
| 148 | |
| 149 | all_pass = len(intersection_results) == 0 |
| 150 | |
| 151 | # Run clearance check if requested |
| 152 | if clearance is not None: |
| 153 | clearance_clashes = geom_tree.clash_clearance_many( |
| 154 | [element], list(scope_elements), clearance=clearance, check_all=True |
| 155 | ) |