diff --git a/src/bonsai/bonsai/bim/module/project/decorator.py b/src/bonsai/bonsai/bim/module/project/decorator.py index 54a4e7181c..a2788bce09 100644 --- a/src/bonsai/bonsai/bim/module/project/decorator.py +++ b/src/bonsai/bonsai/bim/module/project/decorator.py @@ -26,6 +26,7 @@ from bpy_extras import view3d_utils from mathutils import Vector from gpu_extras.batch import batch_for_shader from bpy.app.handlers import persistent +from typing import Union @persistent @@ -92,14 +93,19 @@ class ProjectDecorator: selected_edges = [] selected_tris = [] + props = context.scene.BIMProjectProperties try: - obj = context.scene.BIMProjectProperties.queried_obj + obj = props.queried_obj selected_vertices = obj["selected_vertices"] selected_edges = obj["selected_edges"] selected_tris = obj["selected_tris"] except: return + root_obj: Union[bpy.types.Object, None] = props.queried_obj_root + if root_obj and not (m := root_obj.matrix_world).is_identity: + selected_vertices = [m @ Vector(v) for v in selected_vertices] + if selected_edges: self.draw_batch("LINES", selected_vertices, selected_elements_color, selected_edges) self.draw_batch("TRIS", selected_vertices, transparent_color(selected_elements_color), selected_tris) @@ -313,7 +319,6 @@ class MeasureDecorator: self.shader = gpu.shader.from_builtin("UNIFORM_COLOR") gpu.state.point_size_set(6) - measure_data = context.scene.BIMPolylineProperties.measure_polyline for data in measure_data: polyline_data = data.polyline_point @@ -327,7 +332,6 @@ class MeasureDecorator: for i in range(len(polyline_points) - 1): polyline_edges.append([i, i + 1]) - # Draw polyline with selected points self.line_shader.uniform_float("lineWidth", 2.0) self.draw_batch("POINTS", polyline_points, decorator_color_special) diff --git a/src/bonsai/bonsai/bim/module/project/operator.py b/src/bonsai/bonsai/bim/module/project/operator.py index da7b472454..f391cdbdc8 100644 --- a/src/bonsai/bonsai/bim/module/project/operator.py +++ b/src/bonsai/bonsai/bim/module/project/operator.py @@ -1766,7 +1766,9 @@ class QueryLinkedElement(bpy.types.Operator): from bpy_extras.view3d_utils import region_2d_to_vector_3d, region_2d_to_origin_3d LinksData.linked_data = {} - bpy.context.scene.BIMProjectProperties.queried_obj = None + props = context.scene.BIMProjectProperties + props.queried_obj = None + props.quried_obj_root = None for area in bpy.context.screen.areas: if area.type == "PROPERTIES": @@ -1781,7 +1783,7 @@ class QueryLinkedElement(bpy.types.Operator): coord = (self.mouse_x, self.mouse_y) origin = region_2d_to_origin_3d(region, rv3d, coord) direction = region_2d_to_vector_3d(region, rv3d, coord) - hit, location, normal, face_index, obj, matrix = self.ray_cast(context, origin, direction) + hit, location, normal, face_index, obj, instance_matrix = self.ray_cast(context, origin, direction) if not hit: self.report({"INFO"}, "No object found.") return {"FINISHED"} @@ -1795,7 +1797,8 @@ class QueryLinkedElement(bpy.types.Operator): for i, guid_end_index in enumerate(obj["guid_ids"]): if face_index < guid_end_index: guid = obj["guids"][i] - bpy.context.scene.BIMProjectProperties.queried_obj = obj + props.queried_obj = obj + props.queried_obj_root = self.find_obj_root(obj, instance_matrix) selected_tris = [] selected_edges = [] @@ -1868,11 +1871,23 @@ class QueryLinkedElement(bpy.types.Operator): ProjectDecorator.install(bpy.context) return {"FINISHED"} - def ray_cast(self, context, origin, direction): + def ray_cast(self, context: bpy.types.Context, origin: Vector, direction: Vector): depsgraph = context.evaluated_depsgraph_get() result = context.scene.ray_cast(depsgraph, origin, direction) return result + def find_obj_root(self, obj: bpy.types.Object, matrix: Matrix) -> Union[bpy.types.Object, None]: + collections = set(obj.users_collection) + for o in bpy.data.objects: + if ( + o.type != "EMPTY" + or o.instance_type != "COLLECTION" + or o.instance_collection not in collections + or not np.allclose(matrix, o.matrix_world, atol=1e-4) + ): + continue + return o + def invoke(self, context, event): self.mouse_x = event.mouse_region_x self.mouse_y = event.mouse_region_y @@ -2388,4 +2403,3 @@ class MeasureTool(bpy.types.Operator, PolylineOperator): def invoke(self, context, event): super().invoke(context, event) return {"RUNNING_MODAL"} - diff --git a/src/bonsai/bonsai/bim/module/project/prop.py b/src/bonsai/bonsai/bim/module/project/prop.py index ae1412b8f2..0f9751df87 100644 --- a/src/bonsai/bonsai/bim/module/project/prop.py +++ b/src/bonsai/bonsai/bim/module/project/prop.py @@ -203,6 +203,7 @@ class BIMProjectProperties(PropertyGroup): library_file: EnumProperty(items=get_library_file, name="Library File", update=update_library_file) use_relative_project_path: BoolProperty(name="Use Relative Project Path", default=False) queried_obj: bpy.props.PointerProperty(type=bpy.types.Object) + queried_obj_root: bpy.props.PointerProperty(type=bpy.types.Object) clipping_planes: bpy.props.CollectionProperty(type=ObjProperty) clipping_planes_active: bpy.props.IntProperty(min=0, default=0, max=5)