is this code optimizable?

I have a script where I search for an object, if found select it, select all children (recursivly by calling the code sample below) and then duplicate this selection.

Basically the script works fine, but the more objects I duplicate the longer it takes to search for the children objects as the code walks through all objects each time.


def mark_as_selected(the_object):
    for ob in bpy.data.objects: 
        if ob.parent == the_object:
            ob.sel = 1
            mark_as_selected(ob)

Anyone have an idea how to make this faster?

Prebuild children lists, it’ll be faster.


# pre building children dict

children = {}

for ob in bpy.data.objects:
    if ob.parent:
        if not ob.parent in children:
            children[ob.parent] = []
        
        children[ob.parent].append(ob)

def mark_as_selected(the_object):
    if the_object in children:
        for ob in children[the_object]:
            ob.sel = 1
            mark_as_selected(ob)

Martin

A fun challenge :slight_smile: And curious, that a list of children is not immediately available (even the official suggestion on http://wiki.blender.org/index.php/Resources/Python_scripts search all objects).
I believe a faster solution would be the following algorithm:


set worklist = all objects
set descendants = empty
while worklist is not empty
  set potentials = emptylist
  set o = next element in worklist
  while (o.parent != null and o.parent != the_object)
    add o to potentials
    o = o.parent
  if o.parent == the_object
    add potentials to descendants
  remove potentials from worklist
slect objects in descendants

The last step could be moved in, so that objects were selected when they were added to descendants, and one could start the whole thing by removing the parent chain of the_object from worklist.

hm…my indentations have vanished…should have used a code tag, I guess…

Fixed it for you.

It keeps the whitespace, they are just stripped by your browser. In those case, you can just go back, edit your post and add the code tags.

Martin

thanks for the ideas. i will incorporate the first code sample today and see how it goes. for the other i might need more time to code it (i am new to python) but i will definitely try it also.

this is a result of my script in case you want to see :slight_smile:
chris

http://img369.imageshack.us/img369/623/assemblyps1.th.jpg

@theeth: Hey, thanks :slight_smile:
@lightning2911: That looks cool :slight_smile: Depending on the usage pattern the code given by theeth may be better than mine (if you do these selelctions often, say). An even faster way might be to precompute descendants (as opposed to just immediate children).


def mark_as_selected(ob):
    ob.sel = 1
    [mark_as_selected(child) for child in bpy.data.objects if (child.parent == ob)]

List comprehensions can get you pretty massive speed-ups.

cheers,
RS