Jump to content

thunderdoc

Little help about recursive hierarchy

Recommended Posts

Hi,

I'm struggling a bit with recursive hierarchy iteration, I don't fully understand how it work but at least I can make it work in the entire object manager.

 

But now I'd like to iterate thought all the child objects of the selected object only, like this:

8TEvFpv.png

 

 

Here's my code:

objchildren = [] #list of selected objs

def recur_iter(obj):
    while obj:
        objchildren.append(obj)
        recur_iter(obj.GetDown())
        obj = obj.GetNext()

        
def main():
    recur_iter(doc.GetActiveObject())

 

Currently, this is selecting every object under the object I've selected, it's not stopping in the Sphere.3.

I also tried changing obj = obj.GetNext() to GetPredGetDown, and even removing this line (which causes C4D to crash, lol)

 

So, anyone cal help me to understand the theory behind a simple recursive hierarchy iteration code ? I watched and read all the tutorials in the web, but I can't understand yet :/

Share this post


Link to post
Share on other sites

import c4d


def main():
    obj = doc.GetActiveObject()
    parent = obj
    if obj:
        children = []
        while obj:
            obj = walker(parent, obj)
            if obj:
                children.append(obj)

    	print children


def walker(parent, obj):
        if not obj: return
        elif obj.GetDown():
            return obj.GetDown()
        while obj.GetUp() and not obj.GetNext() and obj != parent:
            obj = obj.GetUp()
        return obj.GetNext()


if __name__=='__main__':
    main()

 

Share this post


Link to post
Share on other sites

you can append the parent if you want it in the list :)

just add
children.append(parent)

before the "while obj:" line

Share this post


Link to post
Share on other sites
  • Topic Author
  • Hi @kalugin, thanks for your help!

     

    Interesting the new def  you're wrote, with that you can control very specifically when the iteration should stop.

     

    But it's still returning the rest of the objects, I tried reading very carefully to try to understand what is giving wrong results, but I couldn't :-/

    ZdI2oQq.png

     

    Thanks again!

     

     

     

     

    Share this post


    Link to post
    Share on other sites

    oops :) My bad, a stupid mistake

    import c4d
    
    
    def main():
        obj = doc.GetActiveObject()
        parent = obj
        if obj:
            children = []
            while obj:
                obj = walker(parent, obj)
                if obj:
                    children.append(obj)
    
            print children
    
    
    def walker(parent, obj):
            if not obj: return
            elif obj.GetDown():
                return obj.GetDown()
            while obj.GetUp() and not obj.GetNext() and obj.GetUp() != parent:
                obj = obj.GetUp()
            return obj.GetNext()
    
    
    if __name__=='__main__':
        main()

     

    Share this post


    Link to post
    Share on other sites

    it was in this line 

    while obj.GetUp() and not obj.GetNext() and obj.GetUp() != parent:

     

    I changed it to obj.GetUp() != parent

    so it doesn't go outside the selected object hierarchy

     

    • Awesome 1

    Share this post


    Link to post
    Share on other sites
  • Topic Author
  • Worked perfectly now @kalugin ! :signthankspin:

    Now I'm going to read it a thousand times to understand what's happening in each line, I don't just want the code, I wan't to learn it xD

     

    Share this post


    Link to post
    Share on other sites

    i guess this could help a bit 

    import c4d
    
    
    def main():
        obj = doc.GetActiveObject() # gets the current active object
        parent = obj # stores the active object in a 'parent' variable, so it always stays the same
        if obj: # if there is a object selected
            children = [] # create an empty list to store children
            while obj: # while there is a object (the "walker" function will return None at some point and that will exit the while loop)
                obj = walker(parent, obj) # set the obj to the result of the walker function
                if obj: # if obj is not None
                    children.append(obj) # append that object to the children list
    
            print children # print the list
    
    
    def walker(parent, obj):
            if not obj: return # if obj is None, the function returns None and breaks the while loop
            elif obj.GetDown(): # if there is a child of obj
                return obj.GetDown() # the walker function returns that child
            while obj.GetUp() and not obj.GetNext() and obj.GetUp() != parent: # if there is a parent of the obj and there isn't another object after the obj and the parent object is not the same object stored in "parent"
                obj = obj.GetUp() # it set's the current obj to that parent
            return obj.GetNext() # and return the object that's after that parent, not under, after :)
    
    
    if __name__=='__main__':
        main()

     

    • Awesome 1

    Share this post


    Link to post
    Share on other sites

    Create an account or sign in to comment

    You need to be a member in order to leave a comment

    Create an account

    Sign up for a new account in our community. It's easy!

    Register a new account

    Sign in

    Already have an account? Sign in here.

    Sign In Now

    • Recently Browsing   0 members

      No registered users viewing this page.

    ×