3
$\begingroup$

I just got a Kitbash 3d asset pack and I want to add it to the blender asset browser but the problem with this is that the asset browser does not support objects parented to empties. is their a way to convert these to collections?

enter image description here

$\endgroup$

3 Answers 3

4
$\begingroup$

I just solved the same problem. Please, try this code:

"""Convert EMPTY to COLLECTION for selected objects or whole the scene. Recursively."""

import bpy

class ConvertEmptyToCollectionOperator(bpy.types.Operator):
    bl_idname = "wm.empty_to_collection"
    bl_label = "Minimal Operator"

    def execute(self, context):
        if len(bpy.context.selected_objects):
            objects = bpy.context.selected_objects
        else:
            objects = get_scene_children()
        for o in objects:
            if len(o.users_collection):
                parent_collection = o.users_collection[0]
            else:
                parent_collection = bpy.context.scene.collection
            self.empties_to_collections(o, parent_collection)
        return {'FINISHED'}


    def empties_to_collections(self, o, parent_collection):
        children = get_objects_children(o)
        if hasattr(o, 'type') and o.type == 'EMPTY':
            # Create a new collection
            new_collection = bpy.data.collections.new(o.name)
            parent_collection.children.link(new_collection)

            # Move all children into the collection
            for ch in o.children_recursive:
                for old_collection in ch.users_collection:
                    old_collection.objects.unlink(ch)
                new_collection.objects.link(ch)

            bpy.data.objects.remove(o)
            for ch in children:
                self.empties_to_collections(ch, new_collection)
        else:
            for ch in children:
                self.my_execute(ch, parent_collection)


def get_objects_children(obj):
    obs = []
    if hasattr(obj, 'children'):
        obs.extend(obj.children)
    if hasattr(obj, 'objects'):
        obs.extend(obj.objects)
    return obs


def get_scene_children():
    """List of the 'Scene' collection's children."""
    children = []
    for o in bpy.data.objects:
        if hasattr(o, 'parent') and o.parent is None:
            children.append(o)
    return children

bpy.utils.register_class(ConvertEmptyToCollectionOperator)

# run operator.
bpy.ops.wm.empty_to_collection()

Result is:

enter image description here

enter image description here

$\endgroup$
1
  • $\begingroup$ Duuuuuudeeee. Nice. $\endgroup$
    – IvanP
    Commented Feb 8 at 13:21
0
$\begingroup$

You will have to do it the manual way for now:

In the layer view right click the empty and click select hierarchy. Press M > new collection > name collection > shift + a > collection instance > select named collection > place origin on the newly made instance > make a 3d asset from the instance.

Someone should make an add-on to automate this process...

$\endgroup$
2
  • $\begingroup$ Unfortunately this is what I was trying to avoid. $\endgroup$ Commented Apr 29, 2022 at 6:37
  • $\begingroup$ just write a python script. easy :) i see alkor has one already. $\endgroup$
    – Harry McKenzie
    Commented Jul 23, 2022 at 14:35
0
$\begingroup$

This script should find all empties in the scene, create a new collection for each empty with the same name as the empty, and then move the empty and its child objects to the new collection while keeping them parented.

To use the script, open Blender and go to the Scripting workspace. Create a new text file and paste the code into it. Then, click the "Run Script" button or press F5 to execute the script.

The script:

import bpy

# Find all empties in the scene
empties = [obj for obj in bpy.context.scene.objects if obj.type == 
'EMPTY']

# Create a collection for each empty and move the empty and its 
child objects to the collection
for empty in empties:
# Create a new collection with the same name as the empty
collection = bpy.data.collections.new(empty.name)
# Link the new collection to the scene
bpy.context.scene.collection.children.link(collection)

# Move the empty to the new collection
empty_collection = empty.users_collection[0]
empty_collection.objects.unlink(empty)
collection.objects.link(empty)

# Loop through all child objects of the empty
for obj in empty.children:
    # Move the object to the new collection
    obj_collection = obj.users_collection[0]
    obj_collection.objects.unlink(obj)
    collection.objects.link(obj)

# Select the original collection so that it's active
bpy.context.view_layer.active_layer_collection = 
bpy.context.view_layer.layer_collection
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .