1
$\begingroup$

I have a script that runs ok as long as there is only one parent (Empty object) selected since I need to select the whole hierarchy, but if I have many parents (Empties) I'm unable to do the same, it always work for the first parent (Empty object) leaving the others untouched. Is there a way to acomplish it?

This is not the prettiest code ever but it works until that point I'm facing. This is how the hierarchy looks after running this piece of code, but as you can see, after that I would need to perform a Clear Parent and keep Transform and this is what I cannot accomplish.

enter image description here

import bpy

collectionFound = False

for myCol in bpy.data.collections:
    #print(myCol.name)
    if myCol.name == "FBX REVIT Scene":
        collectionFound = True
        #print ("Collection found in scene")
        break
    
# Creates a new collection                
if collectionFound == False:
    myCol = bpy.data.collections.new("FBX REVIT Scene")
    bpy.context.scene.collection.children.link(myCol) 

# Set the new collection as active
def recurLayerCollection(layerColl, collName):
    found = None
    if (layerColl.name == collName):
        return layerColl
    for layer in layerColl.children:
        found = recurLayerCollection(layer, collName)
        if found:
            return found

layer_collection = bpy.context.view_layer.layer_collection
layerColl = recurLayerCollection(layer_collection, 'FBX REVIT Scene')
bpy.context.view_layer.active_layer_collection = layerColl


# Selects whole hierarchy
myObj = bpy.context.view_layer.objects.active 
bpy.ops.object.select_grouped(type='CHILDREN_RECURSIVE')
myObj.select_set(True)


# Move selected objects to another collection
# List of object references
objs = bpy.context.selected_objects

# Set target collection to a known collection 
coll_target = bpy.context.scene.collection.children.get("FBX REVIT Scene")

# If target found and object list not empty
if coll_target and objs:

    # Loop through all objects
    for ob in objs:
        # Loop through all collections the obj is linked to
        for coll in ob.users_collection:
            # Unlink the object
            coll.objects.unlink(ob)

        # Link each object to the target collection
        coll_target.objects.link(ob)



bpy.ops.object.select_all(action="DESELECT")

structures = [
    {
        'name': 'CURTAINS',
        'items': [
            "Curtain Wall Mullions[!A-Z]*",
            "Curtain Wall Mullions",
            "Curtain Panels[!A-Z]*", 
            "Curtain Panels", 
        ],
    },
]
for structure in structures:

    selection_pattern = bpy.ops.object.select_pattern
    
    for item in structure['items']:
        selection_pattern(pattern = item)

    # Pattern Selection which search only inside a custom Collection 
    all_in_list = bpy.context.selected_objects.copy()
    collection = bpy.data.collections['FBX REVIT Scene']

    bpy.ops.object.select_all(action="DESELECT")
    for object in collection.objects:
        if object.type == 'EMPTY':
            if object in all_in_list:
                object.select_set(True)
$\endgroup$

1 Answer 1

1
$\begingroup$

I found the solution so others can benefit from this as well. After the las line just add:

for obj in selected:
    bpy.context.view_layer.objects.active = obj
    bpy.ops.object.select_grouped(extend=True, type='CHILDREN_RECURSIVE')
    bpy.ops.object.parent_clear(type='CLEAR_KEEP_TRANSFORM')
$\endgroup$

You must log in to answer this question.

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