[Blender][スクリプト]選択中のツリー内に含まれる全てのオブジェクトを選択

子を選択に似ていますが、このスクリプトならツリー内のどこを選択していてもツリー全体を選択してくれます。

import bpy

# 選択中のオブジェクトを取得
selected_obj = bpy.context.selected_objects

# 選択中のオブジェクトが存在するか確認
if selected_obj:
    # 選択中の最初のオブジェクトを取得
    obj = selected_obj[0]
    
    # 親を再帰的に辿り、ルートの親を見つける
    root_obj = obj
    while root_obj.parent:
        root_obj = root_obj.parent
    
    # ルートの親オブジェクトから子を再帰的に選択
    def select_hierarchy(obj):
        obj.select_set(True)
        for child in obj.children:
            select_hierarchy(child)

    # 選択をクリアし、ルートの親オブジェクトの階層を選択
    bpy.ops.object.select_all(action='DESELECT')
    select_hierarchy(root_obj)

    # ルートの親オブジェクトも選択
    root_obj.select_set(True)

# 3Dビューにフォーカスを戻す
bpy.context.view_layer.objects.active = selected_obj[0] if selected_obj else None


アドオン化したもの

bl_info = {
    "name": "ag_Select_Full_Hierarchy",
    "blender": (4, 1, 0),
    "category": "Object",
}

import bpy

class OBJECT_OT_select_full_hierarchy(bpy.types.Operator):
    """Select all objects in the full hierarchy of the selected object"""
    bl_idname = "object.select_full_hierarchy"
    bl_label = "Select Full Hierarchy"
    bl_options = {'REGISTER', 'UNDO'}

    def execute(self, context):
        # 選択中のオブジェクトを取得
        selected_obj = context.selected_objects

        # 選択中のオブジェクトが存在するか確認
        if selected_obj:
            # 選択中の最初のオブジェクトを取得
            obj = selected_obj[0]
            
            # 親を再帰的に辿り、ルートの親を見つける
            root_obj = obj
            while root_obj.parent:
                root_obj = root_obj.parent
            
            # ルートの親オブジェクトから子を再帰的に選択
            def select_hierarchy(obj):
                obj.select_set(True)
                for child in obj.children:
                    select_hierarchy(child)

            # 選択をクリアし、ルートの親オブジェクトの階層を選択
            bpy.ops.object.select_all(action='DESELECT')
            select_hierarchy(root_obj)

            # ルートの親オブジェクトも選択
            root_obj.select_set(True)

            # 3Dビューにフォーカスを戻す
            context.view_layer.objects.active = selected_obj[0] if selected_obj else None
        
        return {'FINISHED'}


def menu_func(self, context):
    self.layout.operator(OBJECT_OT_select_full_hierarchy.bl_idname)


def register():
    bpy.utils.register_class(OBJECT_OT_select_full_hierarchy)
    bpy.types.VIEW3D_MT_select_object.append(menu_func)


def unregister():
    bpy.utils.unregister_class(OBJECT_OT_select_full_hierarchy)
    bpy.types.VIEW3D_MT_select_object.remove(menu_func)


if __name__ == "__main__":
    register()



この記事が気に入ったらサポートをしてみませんか?