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

    Setting Morph Mixing to Relative But still Remains Absolute

    Cinema 4D SDK
    r21 python
    2
    5
    698
    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.
    • B
      bentraje
      last edited by

      Hi,

      I am creating a morph tag and setting the mixing to a relative but the problem is it remains absolute.
      You can see an illustration of the problem here:
      https://www.dropbox.com/s/22e33ii8yvr14sw/c4d164_python_relative_morph_tag.jpg?dl=0

      You can see the working code below:

      import c4d
      from c4d import gui
      
      # Main function
      def main():
          obj_list = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_SELECTIONORDER)
          
          morph_tag = obj_list[-1].MakeTag(c4d.Tposemorph)
          morph_tag[c4d.ID_CA_POSE_POINTS] = 1
          
          # Create the Base Pose
          c4d.CallButton(morph_tag, c4d.ID_CA_POSE_ADDMORPH)
          
          
          for obj in obj_list[:-1]:
              morph = morph_tag.AddMorph()
              morph.SetName(obj.GetName())
              
              count = morph_tag.GetMorphCount() 
              morph_tag.SetActiveMorphIndex(count-1)
              morph.SetMode(doc, morph_tag, c4d.CAMORPH_MODE_FLAGS_ALL, c4d.CAMORPH_MODE_REL)
              #morph_tag[c4d.ID_CA_POSE_MIXING] = c4d.ID_CA_POSE_MIXING_REL
              morph_tag[c4d.ID_CA_POSE_TARGET] =  obj
              morph_tag.UpdateMorphs()      
            
          c4d.EventAdd()
      
      # Execute main()
      if __name__=='__main__':
          main()
      
      1 Reply Last reply Reply Quote 0
      • M
        m_adam
        last edited by m_adam

        Hi @bentraje The python doc should be improved in this regard.
        If you look at the C++ doc you will see that SetMode is not the correct way to go to convert internal data, but SetParameter.
        SetMode only defines how the tag should read the internal data stored.

        Additionally, you may found the C++ CAMorph Manual interesting.

        Cheers,
        Maxime.

        MAXON SDK Specialist

        Development Blog, MAXON Registered Developer

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

          @m_adam

          Thanks for the response. I tried this code:
          morph_tag.SetParameter(c4d.ID_CA_POSE_MIXING, c4d.ID_CA_POSE_MIXING_REL, c4d.DESCFLAGS_SET_NONE)

          It doesn't error out but it has the same effect as above. The mixing is set to "Relative" but the icon still shows "A".

          Are there any additional settings I should look out for?

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

            The A seems to be present until there is a target.
            So using the next code fix the things, by storing the data first absolutely then converts them to relative.

            import c4d
            
            
            # Main function
            def main():
                obj_list = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_SELECTIONORDER)
                
                morph_tag = obj_list[-1].MakeTag(c4d.Tposemorph)
                morph_tag[c4d.ID_CA_POSE_POINTS] = True
                
                morph_tag.ExitEdit(doc, True)
                
                # Adds the default base morph and store the data
                morph = morph_tag.AddMorph()
                morph.Store(doc, morph_tag, c4d.CAMORPH_DATA_FLAGS_POINTS)
                morph.Apply(doc, morph_tag, c4d.CAMORPH_DATA_FLAGS_POINTS)
                
                for obj in obj_list[:-1]:
                    morph = morph_tag.AddMorph()
                    morph.SetName(obj.GetName())
                    
                    count = morph_tag.GetMorphCount() 
                    morph_tag.SetActiveMorphIndex(count-1)
                    
                    # Set Data to Absolute and link to our obj
                    morph_tag[c4d.ID_CA_POSE_MIXING] = c4d.ID_CA_POSE_MIXING_ABS
                    morph_tag[c4d.ID_CA_POSE_TARGET] = obj
                    
                    # Store the point data in the morph node
                    morph.Store(doc, morph_tag, c4d.CAMORPH_DATA_FLAGS_POINTS)
                    morph.Apply(doc, morph_tag, c4d.CAMORPH_DATA_FLAGS_POINTS)
                    
                    # Set data to Relative and remove the link
                    morph_tag[c4d.ID_CA_POSE_MIXING] = c4d.ID_CA_POSE_MIXING_REL
                    morph_tag[c4d.ID_CA_POSE_TARGET] = None
                    
                    morph_tag.UpdateMorphs()
                    
                # Set to Animat
                morph_tag[c4d.ID_CA_POSE_MODE] = c4d.ID_CA_POSE_MODE_ANIMATE
                c4d.EventAdd()
            
            # Execute main()
            if __name__=='__main__':
                main()
            

            Cheers,
            Maxime.

            MAXON SDK Specialist

            Development Blog, MAXON Registered Developer

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

              @m_adam

              RE: The A seems to be present until there is a target.
              Thanks for the clarification. That make sense.
              Your code works as expected.

              This is just a trivial question.
              In the documentation for the CAPoseMorphTag.ExitEdit it says:
              Must be called before doing anything to a morph tag.

              Shouldn't it be named EnderEdit? Since we are editing the morph tag or calling the ExitEdit after actually editing the morph tag?

              Again trivial but just seeking some clarification.

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