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

    Adding a Morph Deformer Causes Pose Morph Tag to Stop Working

    Cinema 4D SDK
    python
    2
    6
    1.1k
    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.
    • kangddanK
      kangddan
      last edited by

      Hello all, I've noticed that my Pose Morph tag stops working after I add a Morph Deformer. It seems that I can't replicate the manual process of adding the Morph Deformer. What might I be doing wrong?bandicam 2024-05-01 20-57-06-001 00_00_00-00_00_30.gif
      The main function of the code is to copy the selected object, then add a pose morph, and set the target to the selected object. The reason for adding the Morph Deformer is that I can offset issues with priority lag. However, in the code, once I add the Morph Deformer, the Pose Morph stops working 😞

      import c4d
      
      def copyObj(obj):
          _copyObj = obj.GetClone(); doc.AddUndo(c4d.UNDOTYPE_NEW, _copyObj)
          _copyObj.SetName('{}_copy'.format(obj.GetName()))
          _copyObj[c4d.ID_BASEOBJECT_VISIBILITY_EDITOR] = 2
          _copyObj[c4d.ID_BASEOBJECT_VISIBILITY_RENDER] = 2
          doc.InsertObject(_copyObj); _copyObj.InsertAfter(obj)
          
          for tag in _copyObj.GetTags():
              if isinstance(tag, c4d.modules.character.CAWeightTag):
                  tag.Remove()
      
          for child in _copyObj.GetChildren():
              if child.CheckType(c4d.Oskin):
                  child.Remove()    
          return _copyObj
      
      def addPoseMorph(target, obj):
          pmTag = obj.MakeTag(1024237)
          priorityData = c4d.PriorityData()
          priorityData.SetPriorityValue(c4d.PRIORITYVALUE_MODE, c4d.CYCLE_INITIAL)
          pmTag[c4d.ID_CA_POSE_BASE_PRI] = priorityData
          
          pmTag[c4d.ID_CA_POSE_POINTS] = 1
          baseMorph = pmTag.AddMorph()   # id0
          targetMorph = pmTag.AddMorph() # id1
          pmTag.UpdateMorphs()
          
          targetMorph.SetName('target') 
          pmTag.SetActiveMorphIndex(1)
          pmTag[c4d.ID_CA_POSE_TARGET] = target 
          pmTag[c4d.ID_CA_POSE_MODE] = 1
          return pmTag
      
      def addMorphDeformer(obj, tag):
          morph = c4d.BaseObject(1019768)
          morph.InsertUnder(obj)
          morph[c4d.ID_CA_MORPH_DEFORMER_OBJECT_TAG] = tag
          morph[c4d.ID_CA_MORPH_DEFORMER_OBJECT_APPLY_BASEPOSE] = True
          
      def create():
          sel = doc.GetSelection()
          if not sel: return
          doc.StartUndo()
          for o in sel:
              doc.AddUndo(c4d.UNDOTYPE_CHANGE, o)
              o[c4d.ID_BASEOBJECT_VISIBILITY_EDITOR] = 1
              o[c4d.ID_BASEOBJECT_VISIBILITY_RENDER] = 1
              
              cObj = copyObj(o)
              pmTag = addPoseMorph(o, cObj)
              addMorphDeformer(cObj, pmTag)
              
          doc.EndUndo()
          c4d.EventAdd()
      if __name__ == '__main__':
          create()
      
      1 Reply Last reply Reply Quote 0
      • kangddanK
        kangddan
        last edited by

        test file

        test.c4d

        1 Reply Last reply Reply Quote 0
        • kangddanK
          kangddan
          last edited by

          Hello everyone, I seem to have found a solution. You just need to go to the Falloff option in Morph and add a default parameter

           data = c4d.FieldList()
          morph[c4d.FIELDS] = data
          

          This way, the PoseMorph tag becomes effective. I still don't understand why this is necessary, as I can't find any python related content about the Morph deformer:(

          i_mazlovI 1 Reply Last reply Reply Quote 0
          • i_mazlovI
            i_mazlov @kangddan
            last edited by i_mazlov

            Hi @kangddan,

            Thanks for providing such a good reference for reproducing the issue!

            Looks like you're missing the initialization and finalizing phases of creating the morph tag, hence you end up with invalid (or not updated) one. Executing the following functions in the correct order seems to fix your issue. Please have a look at InitMorphs(), UpdateMorphs() and ExitEdit().

            Please find the corrected addPoseMorph() function below.

            Regarding the falloff option, I assume it implicitly calls UpdateMorphs() function, which updates the morph tag, hence you have it in working state.

            Cheers,
            Ilia

            PS There's no need to insert object to document first, if you later insert it after another object that's already in document, or in other words the doc.InsertObject(_copyObj) call is redundant.

            The corrected addPoseMorph function code snippet:

            def addPoseMorph(target, obj):
                pmTag = obj.MakeTag(1024237)
                pmTag[c4d.ID_CA_POSE_POINTS] = 1
            
                pmTag.InitMorphs()
            
                priorityData = c4d.PriorityData()
                priorityData.SetPriorityValue(c4d.PRIORITYVALUE_MODE, c4d.CYCLE_INITIAL)
                pmTag[c4d.ID_CA_POSE_BASE_PRI] = priorityData
                
                baseMorph = pmTag.AddMorph()   # id0
                targetMorph = pmTag.AddMorph() # id1
                
                targetMorph.SetName('target') 
                pmTag.SetActiveMorphIndex(1)
                pmTag[c4d.ID_CA_POSE_TARGET] = target 
                
                pmTag.ExitEdit(doc, False) # switch to "Animate Mode"
                pmTag.UpdateMorphs()
            
                return pmTag
            

            MAXON SDK Specialist
            developers.maxon.net

            kangddanK 1 Reply Last reply Reply Quote 1
            • kangddanK
              kangddan @i_mazlov
              last edited by

              This post is deleted!
              1 Reply Last reply Reply Quote 0
              • kangddanK
                kangddan
                last edited by

                Thank u @i_mazlov
                I appreciate you pointing me in the right direction. I will try to understand the workings behind the posemorph tag! 😊

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