見出し画像

[Blender][script]コレクションの内容を新規エンプティの子供にしてまとめる

アウトライナで選択中のコレクション内に含まれるオブジェクトをひとつの新規エンプティの子供にしてまとめます。

アウトライナーのコレクションを右クリックして出るメニューから実行

fbxでエクスポートする時にオブジェクトをまとめるのに使うと便利です。
但しコレクション1個ずつ実行する必要があります。

※注意※実行後にすぐundo/redoをするとBlenderが落ちます。何か別の事(選択するとか選択を解除するとか)をするとundo/redoしても落ちません。どうしても治らないのでこれで妥協しました。

import bpy

def parent_objects_to_empty_preserve_hierarchy():
    # 選択中のコレクションを取得
    selected_collection = bpy.context.view_layer.active_layer_collection.collection
    
    if not selected_collection:
        print("コレクションが選択されていません")
        return
    
    # 新しいエンプティを作成してシーンに追加
    bpy.ops.object.empty_add(type='PLAIN_AXES')
    empty_object = bpy.context.object
    empty_object.name = f"{selected_collection.name}_group"
    
    # コレクション内のすべてのオブジェクトを処理
    for obj in selected_collection.objects:
        # ルートオブジェクト(親を持たないオブジェクト)を新しいエンプティの子にする
        if obj.parent is None and obj != empty_object:  # エンプティ自身は親にしない
            obj.parent = empty_object
    
    print(f"コレクション '{selected_collection.name}' 内のオブジェクトを '{empty_object.name}' にまとめ、階層構造を保持しました。")


class OBJECT_OT_parent_objects_to_empty_preserve_hierarchy(bpy.types.Operator):
    bl_idname = "object.parent_objects_to_empty_preserve_hierarchy"
    bl_label = "コレクションの内容をエンプティにまとめる"
    
    def execute(self, context):
        parent_objects_to_empty_preserve_hierarchy()
        return {'FINISHED'}

def menu_func(self, context):
    # コレクションの右クリックメニューに追加
    self.layout.operator(OBJECT_OT_parent_objects_to_empty_preserve_hierarchy.bl_idname)

def register():
    bpy.utils.register_class(OBJECT_OT_parent_objects_to_empty_preserve_hierarchy)
    bpy.types.OUTLINER_MT_collection.append(menu_func)

def unregister():
    bpy.utils.unregister_class(OBJECT_OT_parent_objects_to_empty_preserve_hierarchy)
    bpy.types.OUTLINER_MT_collection.remove(menu_func)

if __name__ == "__main__":
    register()

いいなと思ったら応援しよう!