2
$\begingroup$

How can I delete hierarchy of objects in code? When trying to delete the "parent_obj", it's written in the GUI tooltip:

bpy.ops.outliner.object_operation(type='DELETE_HIERARCHY')

I tried to select the "parent_obj" using this code:

context.scene.objects.active = bpy.data.objects['parent_obj']

But got this error:

File "~/blender-2.76-rc2-linux-glibc211-x86_64/2.76/scripts/modules/bpy/ops.py", line 189, in __call__
    ret = op_call(self.idname_py(), None, kw)
RuntimeError: Operator bpy.ops.outliner.object_operation.poll() failed, context is incorrect

Edit

Ok, I've found how to bypass this problem. Instead of using bpy.ops.outliner.object_operation(), I first select the objects hierarchy, and then used bpy.ops.object.delete():

bpy.data.objects[obj_name].select = True
for child in bpy.data.objects[obj_name].children:
    child.select = True
bpy.ops.object.delete()
$\endgroup$
  • 1
    $\begingroup$ Have you searched for "context is incorrect" on this site yet? $\endgroup$ – zeffii Jan 10 '16 at 13:31
3
$\begingroup$

Your own solution probably works fine in your case, but the general case where the hierarchy is a bit more nested (children of children) might still deserve a solution.

perhaps something recursive:

import bpy

def delete_hierarchy(obj):
    names = set([obj.name])

    # recursion
    def get_child_names(obj):
        for child in obj.children:
            names.add(child.name)
            if child.children:
                get_child_names(child)

    get_child_names(obj)

    print(names)
    objects = bpy.data.objects
    [setattr(objects[n], 'select', True) for n in names]

    bpy.ops.object.delete()

delete_hierarchy(bpy.context.active_object)

This function assumes no objects are currently selected, and accumulates the names of the hierarchy starting with the main object ( i used active_object, but you can pass any object reference there ). Then it selects all the found names, then runs the object_delete operator.

$\endgroup$
  • $\begingroup$ I found that bpy.ops.object.delete() doesn't delete a nested animation objects. I inserted keyframes to the parent objects, and they weren't been deleted. Any ideas? $\endgroup$ – Noam Peled Jan 11 '16 at 16:12
  • $\begingroup$ you want to remove all keyframes from each object in this hierarchy.? $\endgroup$ – zeffii Jan 11 '16 at 16:31
  • $\begingroup$ Yes. In my case, only the parent obj has keyframes. $\endgroup$ – Noam Peled Jan 11 '16 at 16:33
  • $\begingroup$ I dont have a file at hand with any complicated animation, perhaps share one on blend-exchange.giantcowfilms.com - can be a trivial one to show what you mean, before and after. $\endgroup$ – zeffii Jan 11 '16 at 16:34
  • 1
    $\begingroup$ If you've solved your own question. we encourage you to write your own answer and even accept it :) $\endgroup$ – zeffii Jan 11 '16 at 18:49
3
$\begingroup$

One should deseleted all the objects, select and remove the animation data from all the objects in the hierarchy, and call bpy.ops.object.delete():

def delete_hierarchy(parent_obj_name):
    bpy.ops.object.select_all(action='DESELECT')
    obj = bpy.data.objects[parent_obj_name]
    obj.animation_data_clear()
    names = set()
    # Go over all the objects in the hierarchy like @zeffi suggested:
    def get_child_names(obj):
        for child in obj.children:
            names.add(child.name)
            if child.children:
                get_child_names(child)

    get_child_names(obj)

    print(names)
    objects = bpy.data.objects
    [setattr(objects[n], 'select', True) for n in names]
    # Remove the animation from the all the child objects
    for child_name in names:
        bpy.data.objects[child_name].animation_data_clear()

    result = bpy.ops.object.delete()
    if result == {'FINISHED'}:
        print ("Successfully deleted object")
    else:
        print ("Could not delete object")
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.