Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Python Node with Hierarchy

    PYTHON Development
    0
    8
    941
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H
      Helper
      last edited by

      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

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        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().

        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          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.

          1 Reply Last reply Reply Quote 0
          • H
            Helper
            last edited by

            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.

            1 Reply Last reply Reply Quote 0
            • H
              Helper
              last edited by

              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/

              1 Reply Last reply Reply Quote 0
              • H
                Helper
                last edited by

                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.

                1 Reply Last reply Reply Quote 0
                • H
                  Helper
                  last edited by

                  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.

                  1 Reply Last reply Reply Quote 0
                  • H
                    Helper
                    last edited by

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

                    Thanks for all the answers. It is great!

                    Best Wishes!
                    Ching.

                    1 Reply Last reply Reply Quote 0
                    • First post
                      Last post