Select the Children of a Selected Object. Then, Store it in a List



  • Hi,

    I have a joint chain of shoulder_jnt > elbow_jnt > wrist_jnt
    I want it to store it in a list. Here is the code so far:

    def GetObjects(obj):
          objList = [obj]
          for kid in obj.GetChildren():        
              GetObjects(kid)
              objList += kid
          return objList # should return the parent/selected obejct and all its chidlren
    
    test = doc.SearchObject("shoulder_jnt")          
    ikJointChain = GetObjects(test)
    

    It gives me an error of

    Traceback (most recent call last):
      File "scriptmanager", line 9, in <module>
      File "scriptmanager", line 4, in GetObjects
      File "scriptmanager", line 5, in GetObjects
    TypeError: 'c4d.modules.character.CAJointObject' object is not iterable
    

    The code is modified from this post:
    http://www.plugincafe.com/forum/forum_posts.asp?TID=7774

    There is also another code in that post, but I can't really understand it.
    So I chose the most simpler one.

    Thank you for looking at the problem.



  • SearchObject() returns a single BaseObject.
    You might want to create a dedicated function that walks through your document and returns a list with all the filtered objects.

    Unfortunately, there's no function that I know of, that automatically does what you want.

    To iterate hierarchies, see this blogpost (this is about the code in the thread you linked).
    Those are helper functions, you should always use them, when it comes to hierarchies.



  • Your two lines

    GetObjects(kid)
    objList += kid
    

    make no sense. The first one calls the recursion but then throws the result away as it is not stored anywhere (objList is a local variable for the function, not a global, and does not exist beyond the context of the current method execution). The second tries to extend a list by a single object instead of another list (the operator += works like extend, not like append) and fails because it cannot iterate through a single object. (Even if you had used the append method or listified kid it would still fail logically because you have already added the kid in the recursion call and then threw it all away.)

    What you need to do is extend the local objList by the result list of the recursion call:

    objList += GetObjects(kid)
    

    or in context,

    import c4d
    from c4d import gui
    
    def GetObjects(obj):
          objList = [obj]
          for kid in obj.GetChildren(): 
              objList += GetObjects(kid)
          return objList # should return the parent/selected obejct and all its chidlren
    
    def main():
        test = doc.SearchObject("shoulder_jnt")          
        ikJointChain = GetObjects(test)
        print ikJointChain
    
    if __name__=='__main__':
        main()
    


  • @mp5gosu

    Thanks for the response and for the link regarding recursive and nonrecusive distinction, but I think the recursive version is shorter to write

    @Cairyn

    Thanks for the revised script. Works as expected. To be honest, I really do not know Python in C4D per se. I'm just winging it. Hahaha.
    So, thanks for the explanation!


Log in to reply