Utility_Apps/Blender/addons/Deselect Non-Intersecting Objects with Camera/__init__.py

73 lines
2.3 KiB
Python

bl_info = {
"name": "Deselect Non-Intersecting Objects with Camera",
"author": "Ryan Schultz & GPT-5",
"version": (1, 0),
"blender": (4, 0, 0),
"location": "View3D > Select",
"description": "Deselects selected objects that do not intersect the camera plane",
"category": "Object",
}
import bpy
import mathutils
class OBJECT_OT_deselect_non_intersecting(bpy.types.Operator):
"""Deselect selected objects that do not intersect with the active camera plane"""
bl_idname = "object.deselect_non_intersecting"
bl_label = "Deselect Non-Intersecting with Camera"
bl_options = {'REGISTER', 'UNDO'}
def execute(self, context):
camera = context.scene.camera
if camera is None:
self.report({'WARNING'}, "No active camera found in the scene.")
return {'CANCELLED'}
cam_matrix = camera.matrix_world
cam_origin = cam_matrix.translation
cam_direction = cam_matrix.to_quaternion() @ mathutils.Vector((0.0, 0.0, -1.0))
plane_normal = cam_direction.normalized()
plane_point = cam_origin
def point_plane_distance(point):
return (point - plane_point).dot(plane_normal)
deselected = 0
for obj in context.selected_objects:
if obj == camera:
continue
bbox_world = [obj.matrix_world @ mathutils.Vector(corner) for corner in obj.bound_box]
distances = [point_plane_distance(p) for p in bbox_world]
min_d = min(distances)
max_d = max(distances)
intersects = (min_d <= 0.0 <= max_d) or (max_d <= 0.0 <= min_d)
if not intersects:
obj.select_set(False)
deselected += 1
self.report({'INFO'}, f"Deselected {deselected} object(s) not intersecting camera plane")
return {'FINISHED'}
def menu_func(self, context):
layout = self.layout
layout.separator()
layout.operator(OBJECT_OT_deselect_non_intersecting.bl_idname)
def register():
bpy.utils.register_class(OBJECT_OT_deselect_non_intersecting)
bpy.types.VIEW3D_MT_select_object.append(menu_func)
def unregister():
bpy.types.VIEW3D_MT_select_object.remove(menu_func)
bpy.utils.unregister_class(OBJECT_OT_deselect_non_intersecting)
if __name__ == "__main__":
register()