Python Node with Hierarchy



  • On 14/03/2017 at 19:51, xxxxxxxx wrote:

    Hi,all.

    As we know,there is a xpresso node called "Hierarchy",which can iterate the objects in the same hierarchy.but can't in the  hierarchy with more complex. so I want to use python node to create a hierarchy which can iterate a whole objects of the hierarchy.How can I do?

    For example, I want to disable each object under the Xpresso object.what can I do?(as the screenshot below)

    I try some code,but not work:

      
      
    import c4d  
    def main() :  
      global obj  
      objs = link.GetChildren()  
        
      for child in objs:  
          obj = child  
      
    

    any help would be very appreciated!

    Best wishes!
    Ching



  • On 15/03/2017 at 05:48, xxxxxxxx wrote:

    Hi,

    that's not going to work that way. An iterator node in Xpresso works differently and you can't imitated something like that via a Python Script node. An iterator gets executed several times per evaluation of the Xpresso setup (the Python Script node only once) and thus triggers re-execution of connected nodes.

    Another problem you are facing is, that you can not return a list of objects. So in your code example, the Python script gets executed, it iterates through the for-loop, assigning the variable "obj" successively with different child objects and then in the end the variable "obj" gets assigned to the output, which then is the last child in the hierarchy.

    By the way, GetChildren() does only return the next level of children (that's what the docs mean by "no grandchild"), which is something the Hierarchy node delivers in its default setup. If you want all the children of a more complex hierarchy, you'd need something like the functionality of GetActiveObjects() with GETACTIVEOBJECTFLAGS_CHILDREN flag, but that of cause can not be used in an Xpresso Python node. So you will have to walk the hierarchy yourself.

    My suggestion would be to build the following:

    Have a Python Script node with a link input (the input ("parentObj" in below code) is connected to your parent object) and an output port of type "In-Exclusion" ("InExData" in below code). This output port gets connected to an ObjectList Iterator node with an "Iteration List" input. The "Instance" output port of this ObjectList iterator will deliver the objects you want.

    In the Python Script node use the following code:

    import c4d
      
    def AddHierarchyToInEx(obj, inex) :
        if obj is None:
            return
        while obj is not None:
            inex.InsertObject(obj, 1)
            AddHierarchyToInEx(obj.GetDown(), inex)
            obj = obj.GetNext()
      
    def main() :
        global InExData
        InExData = c4d.InExcludeData()
        if parentObj is None:
            return InExData
        AddHierarchyToInEx(parentObj.GetDown(), InExData)
        return InExData
    

    Have fun.

    Edit: Changed code after below discussion. Before InExData was passed as a list to AddHierarchyToInEx().



  • On 15/03/2017 at 20:51, xxxxxxxx wrote:

    Hi,Andreas.

    Thank you for your answer,your code is woriking perfectly.In your code,I still have some code that I don't understand ,for example,what's meaning of the "inex[0]" and "[InExDate]"? As far as I know,the "inex[0] represents the first element in the list of inex,Whether  can I use "index" and "InExDate" Instead of "inex[0]" and "[InExDate]" or not?   or there is other purpose. Would you mind explain, Thank you in advanced!

    Best wishes!
    Ching.



  • On 16/03/2017 at 01:08, xxxxxxxx wrote:

    Hi,

    to be honest, that might be a Python "gap" on my end. I'm a C/C++ guy and thus are used to passing parameters by reference. By passing InExData as a list [InExData] and then access the first member of that list inex[0] inside a function, I make sure I pass the reference of InExData, so any modification done inside the function actually influences the original InExData passed into the funtion. This may or may not be needed, I never bothered to look this up or tried to find out what's the Python way to go here. So, if anybody in our community wants to enlighten me, please go do so. Would be much appreciated.



  • On 16/03/2017 at 01:44, xxxxxxxx wrote:

    If I remember correctly what I have read. All mutable pass variable by reference(cf like a pointer in C++, so it's like that when a variable is into a list/dict and all others)
    While in all no mutable variable are passed by value (it simply make a copy of the variable)

    More indepth answerd
    http://stackoverflow.com/questions/986006/how-do-i-pass-a-variable-by-reference
    and in french (I post it cause it's a very nice ressource for python in french so it might be usefull for some people)
    http://sametmax.com/valeurs-et-references-en-python/



  • On 16/03/2017 at 02:46, xxxxxxxx wrote:

    Thanks, gr4ph0s, for breaking my ignorance and laziness. Nice link, topic solved (I guess, both links are nice, but unfortunately I have another language gap and that won't be solved as easily. Ask my French colleague Yannick, he's trying his best, but I'm a hard nut to crack).

    So, WeiChing, to sum it up, my "list workaround" is indeed redundant, it works fine without. I changed the code above accordingly.



  • On 16/03/2017 at 04:23, xxxxxxxx wrote:

    Thanks for the link to the page in French. It's an interesting tutorial with nice explanations.



  • On 16/03/2017 at 07:54, xxxxxxxx wrote:

    Thanks for all the answers. It is great!

    Best Wishes!
    Ching.


Log in to reply