Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python 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

    Placing an effector at specific Index in effector list

    Cinema 4D SDK
    python
    2
    5
    856
    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.
    • M
      Motion4D
      last edited by

      Hi, this is probably an easy question but I'm placing an effector into a cloner and I want to put it in the first position so the cloner reads it first. I see the InExcludeData has the InsertObject() command which always puts the effector in the last position and no option to place at a specific index. Is there a way to specify which index to place the effector?

      1 Reply Last reply Reply Quote 0
      • ferdinandF
        ferdinand
        last edited by ferdinand

        Hello @Motion4D,

        thank you for reaching out to us. Unfortunately, there is no method attached to InExcludeData in either the C++ or Python SDK which would allow this. The only way to achieve the desired result is to instantiate a new InExcludeData , for details see example below. It also seems noteworthy to point out that an InExcludeData does not come with a guarantee of execution, i.e., you cannot be sure that everything will consider the first index entry as the first thing in an InExcludeData. While a Cloner might currently behave this way, there is no guarantee that this won't change with a future revision.

        Cheers,
        Ferdinand

        The code example:

        """Example for inserting a node at an arbitrary index in an InExcludeData.
        
        As discussed in:
            plugincafe.maxon.net/topic/13388
        """
        
        import c4d
        
        def InsertNodeIntoInExclude(data, node, index, isActive=True):
            """Inserts a node at a certain index into an InExcludeData.
        
            Does return a copy of the passed data with the node inserted at the 
            specified index. The function assumes the argument to be in the same
            document as the BaseList2D referenced by data. 
        
            Args:
                data (c4d.InExcludeData): The data to insert into.
                node (c4d.BaseList2D): The node to insert.
                index (int): The index to insert at.
                isActive (bool, optional): If the node is active or not. Defaults to 
                 True.
            
            Returns:
                c4d.InExcludeData: A copy of data with node inserted at index.
            
            Raises:
                IndexError: When index is out of bounds.
            """
            dataCount = data.GetObjectCount()
            doc = node.GetDocument()
        
            if index > dataCount:
                raise IndexError(f"The index {index} is out of bounds.")
        
            result, i = c4d.InExcludeData(), 0
            while data.ObjectFromIndex(doc, i):
                if i == index:
                    result.InsertObject(node, int(isActive))
                
                item = data.ObjectFromIndex(doc, i)
                flags = data.GetFlags(i)
                result.InsertObject(item, flags)
                i += 1
            return result
        
        
        def main():
            """Insert an effector at an arbitrary index.
            """
            # Check if the first object is a cloner object, there is no type symbol
            # for the cloner object, so, we have to use the raw identifier.  
            cloner = doc.GetFirstObject()
            if not (isinstance(cloner, c4d.C4DAtom) and
                    cloner.CheckType(1018544)):
                raise TypeError("Expected a cloner as the first object in the scene.")
        
            # Check if the second object is an effector.
            effector = cloner.GetNext()
            if not (isinstance(effector, c4d.C4DAtom) and
                    effector.CheckType(c4d.Obaseeffector)):
                raise TypeError(
                    "Expected an effector as the second object in the scene.")
        
            # Get the InExcludeData of the cloner.
            inExData = cloner[c4d.ID_MG_MOTIONGENERATOR_EFFECTORLIST]
        
            # Insert an effector wrapped in an undo.
            doc.StartUndo()
            modifiedInExData = InsertNodeIntoInExclude(inExData, effector, 1)
            cloner[c4d.ID_MG_MOTIONGENERATOR_EFFECTORLIST] = modifiedInExData
            doc.AddUndo(c4d.UNDOTYPE_CHANGE, cloner)
            doc.EndUndo()
        
            # Update Cinema 4D.
            c4d.EventAdd()
        
        if __name__ == '__main__':
            main()
        

        MAXON SDK Specialist
        developers.maxon.net

        1 Reply Last reply Reply Quote 0
        • M
          Motion4D
          last edited by

          @ferdinand Perfect! that seemed to do the trick. I'm not entirely sure what's going on in that function but it works. I tried different index positions and it threw an error but it works for the zero index and that's all I really needed. Thanks for the help!

          AJ

          1 Reply Last reply Reply Quote 0
          • ferdinandF
            ferdinand
            last edited by

            Hello @Motion4D,

            I am sorry, there snuck in an else where should not have been one. I fixed the code, which now works as I would expect it to work (did not test very thoroughly though). I also added an argument for the initial state of the added node.

            Please note that we cannot deliver full solutions, but if you have specific questions, I am more than happy to help.

            Cheers,
            Ferdinand

            MAXON SDK Specialist
            developers.maxon.net

            ferdinandF 1 Reply Last reply Reply Quote 0
            • ferdinandF
              ferdinand @ferdinand
              last edited by

              Hello @Motion4D,

              without any further questions or replies, we will consider this topic as solved by Wednesday and flag it accordingly.

              Thank you for your understanding,
              Ferdinand

              MAXON SDK Specialist
              developers.maxon.net

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