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

    How to add Strengths of each Pose I set in Pose Morph as Ports into Xpresso?

    Cinema 4D SDK
    7
    9
    1.8k
    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.
    • P
      PATPAT
      last edited by

      I'm on a character rigging and I try to sort hand poses into Xpresso.
      075406bd-4a4c-4b22-a1e0-6ca08f71655a-image.png

      I didn't find out a DESC of each Pose, then I can't get each Pose Strength as a port in Xpresso by script which means I got to drag them in, it's a disaster.XD
      https://developers.maxon.net/docs/py/2023_2/classic_resource/tag/tcaposemorph.html?highlight=pose morph
      c56328dd-35db-4f8a-992b-4675bda41841-image.png

      Is there any to way to do it?

      1 Reply Last reply Reply Quote 0
      • X
        x_nerve
        last edited by x_nerve

        Hi:

        @PATPAT
        First of all, the point movement algorithm of attitude deformation label is not complicated.

        I've seen in some tutorials that you can add some data to a port with unconventional operations, but I forgot . So, I use Python nodes.

        The data control label object weight value for the input port, so you need to add a user data of type link to the Python node.

        Python is a dynamic language, and data types cannot be determined before compilation. There is no conditional right or wrong judgment in my code, so please add them by yourself.

        import c4d
        
        def main():
        
            obj = op[c4d.ID_USERDATA,1]
        
            Tags = obj.GetTags()
            
            Pose = [tag for tag in Tags if tag.GetRealType() == 1024237]
        
            #[4000,1101] is the ID of the strength value.  
         
            Pose[0][4000,1101] = Input1
        
            global Output1
            Output1 = Pose[0][4000,1101]
        

        17.jpg

        1 Reply Last reply Reply Quote 1
        • P
          PATPAT
          last edited by

          Oh dear, it's a fascinating method and it works well! Thank you, x_nerve!

          1 Reply Last reply Reply Quote 0
          • ManuelM
            Manuel
            last edited by Manuel

            Hi,

            The "problem" here is to retrieve the right ID of each morph.
            on the morph tag, the Data for each slider start at c4d.ID_CA_POSE_ANIMATE_OFFSET (1000). Each morph has a maximum of c4d.ID_CA_POSE_ANIMATE_CNT (100) parameters. The Strength parameter is the second one. (1).

            So, the Strength of the first morph slider have the ID 1101, the second 1201.... 1301 etc
            All those data are stored in the subcontainer c4d.ID_CA_POSE_ANIMATE_DATA (4000)
            You can retrieve the number of morphs with GetMorphCount.

            After that you can manipulate xpresso, we have a couple of examples about that on ou github repository.

            You can build the descID with those information. You can have a look at this thread to understand a bit more how to use descID

            import c4d
            from c4d import gui
            # Welcome to the world of Python
            
            # Main function
            def main():
                morphTag = op.GetFirstTag()
                if morphTag is None:
                    raise RuntimeError("Failed to retrieve the morpht tag.")
                xpressoTag = morphTag.GetNext()
                
                if xpressoTag is None:
                    raise RuntimeError("Failed to retrieve the xpressoTag.")
                
                morphCount = morphTag.GetMorphCount()
                
                 # Retrieves the node master
                gvNodeMaster = xpressoTag.GetNodeMaster()
                if gvNodeMaster is None:
                    raise RuntimeError("Failed to retrieve the Node Master.")
            
                # Retrieves the Root node (the Main XGroup) that holds all others nodes
                gvRoot = gvNodeMaster.GetRoot()
                if gvRoot is None:
                    raise RuntimeError("Failed to retrieve the Root Node.")
            
                # Creates a constant node in the GvRoot
                objectNode = gvNodeMaster.CreateNode(gvRoot, c4d.ID_OPERATOR_OBJECT, x=100, y=100)
                if objectNode is None:
                    raise RuntimeError("Failed to create the const Node.")
                
                objectNode[c4d.GV_OBJECT_OBJECT_ID] = morphTag
                
                for i in range(0, morphCount):
                    offsetID = c4d.ID_CA_POSE_ANIMATE_OFFSET + c4d.ID_CA_POSE_ANIMATE_CNT * i + 1
                    morphDescId =  c4d.DescID(c4d.DescLevel(c4d.ID_CA_POSE_ANIMATE_DATA, c4d.DTYPE_SUBCONTAINER, 0), c4d.DescLevel(offsetID, c4d.DTYPE_REAL, 0))
                    objectNode.AddPort(c4d.GV_PORT_INPUT, morphDescId, c4d.GV_PORT_FLAG_IS_VISIBLE, True)
                    
                
                
                c4d.EventAdd()
            
            # Execute main()
            if __name__=='__main__':
                main()
            

            @x_nerve your answer isn't clear. I don't fully understand the purpose here.

            Cheers,
            Manuel

            MAXON SDK Specialist

            MAXON Registered Developer

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

              Hello @PATPAT,

              without any further questions or replies, we will consider this thread as solved by Monday the 20th and flag it accordingly.

              Thank you for your understanding,
              Ferdinand

              MAXON SDK Specialist
              developers.maxon.net

              1 Reply Last reply Reply Quote 0
              • B
                bentraje
                last edited by

                Hi @Manuel

                Can this be adopted to the latest version of Cinema4D?
                I tried the script on R21 and it works as expected. But when I tried it on later versions, it gives me an error of:
                AttributeError: 'c4d.BaseTag' object has no attribute 'GetNodeMaster'. Did you mean: 'GetNodeData'?

                If I do a refactor to GetNodeData, it gives me an error of RuntimeError: Failed to retrieve the Node Master.

                Also, why does the Xpresso API is changing? I thought this feature is already deprecated and supposed to be kept for legacy with the scene nodes eventually replacing it.

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

                  GetNodeMaster is an attribute of XPressoTag so my guess is that you are calling the function on another tag as hinted by the error (c4d.BaseTag) and not on a xpresso tag.

                  The API did not change in this regard. So if you still have issue please open a new topic and post clear reproduction step with your code.

                  Cheers,
                  Maxime

                  MAXON SDK Specialist

                  Development Blog, MAXON Registered Developer

                  1 Reply Last reply Reply Quote 1
                  • B
                    blkmsk
                    last edited by blkmsk

                    Hi @bentraje I just came across this thread and quickly tested the above script in 2024. It still works as expected.
                    Without any further knowledge I would assume that A) you dont have a xpresso tag on your object or B) its not the the second tag on your object.

                    image.png

                    1 Reply Last reply Reply Quote 1
                    • B
                      bentraje
                      last edited by

                      @m_adam @blkmsk
                      Gotcha. It works now. My bad. The ordering of the tag was essential based on the context of the script.
                      I overlooked it.

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