diff --git a/src/bonsai/bonsai/bim/module/clash/operator.py b/src/bonsai/bonsai/bim/module/clash/operator.py index ae5f622bbd..8062b348e9 100644 --- a/src/bonsai/bonsai/bim/module/clash/operator.py +++ b/src/bonsai/bonsai/bim/module/clash/operator.py @@ -428,10 +428,10 @@ class SelectClash(bpy.types.Operator): tool.Spatial.select_products(products, unhide=True) ClashDecorator.install(bpy.context) - target = Vector(clash["p1"]) + target = tool.Clash.convert_clash_point_to_blender(clash["p1"]) tool.Clash.look_at(target, target + Vector((5, 5, 5))) - self.props.p1 = clash["p1"] - self.props.p2 = clash["p2"] + self.props.p1 = target + self.props.p2 = tool.Clash.convert_clash_point_to_blender(clash["p2"]) self.props.active_clash_text = clash["type"].title() + " " + str(round(clash["distance"] * 1000)) + "mm" return {"FINISHED"} diff --git a/src/bonsai/bonsai/tool/clash.py b/src/bonsai/bonsai/tool/clash.py index fb64e82b49..f8a6f71bc8 100644 --- a/src/bonsai/bonsai/tool/clash.py +++ b/src/bonsai/bonsai/tool/clash.py @@ -22,6 +22,9 @@ import json from typing import TYPE_CHECKING, Literal, Union import bpy +import ifcopenshell.util.geolocation +import ifcopenshell.util.unit +import numpy as np from ifcclash import ifcclash from ifcclash.ifcclash import ClashSource from mathutils import Vector @@ -129,6 +132,25 @@ class Clash(bonsai.core.tool.Clash): with open(fn) as f: ClashStore.clash_sets = json.load(f) + @classmethod + def convert_clash_point_to_blender(cls, point: Union[list[float], tuple[float, float, float]]) -> Vector: + """Convert a raw ifcclash point into Bonsai's displayed viewport coordinates.""" + props = tool.Georeference.get_georeference_props() + if not props.has_blender_offset: + return Vector(point) + unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) + matrix = np.eye(4) + matrix[:3, 3] = point + matrix = ifcopenshell.util.geolocation.global2local( + matrix, + float(props.blender_offset_x) * unit_scale, + float(props.blender_offset_y) * unit_scale, + float(props.blender_offset_z) * unit_scale, + float(props.blender_x_axis_abscissa), + float(props.blender_x_axis_ordinate), + ) + return Vector(matrix[:3, 3]) + @classmethod def look_at(cls, target: Vector, location: Vector) -> None: camera_location = location