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
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Character Defenition Tag - maxon.Id?

    Cinema 4D SDK
    2024 python
    2
    3
    517
    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.
    • jochemdkJ
      jochemdk
      last edited by

      Hi,

      Before release 2024, the Character Defenition Tag has always been a "Black Box" - at least for Python. I recently discovered that now there is/should be a way to get and set data. I tried to look in various .h-files, the C++ docs, Github etc. but I just can't find the corresponding maxon.InternedId to use.

      # small non-working example..
      import c4d, maxon
      
      
      def main() -> None:
          obj = op.GetObject() # from a pyTag..
          csTag = None
          for tag in obj.GetTags():
              if tag.GetType() == 1055068:
                  csTag = tag
                  # c4d.modules.character.MTCharacterDefinitionTag
                  break
              
          print (csTag.GetExposedBodyPartSettings(   > maxon.Id <   )) 
      

      So, the base question is: what's the maxonId?
      & the sub question: is there some python script to get the Ids?

      Thx in advance, Jochem

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

        Hey @jochemdk, thanks for asking this question, because while investigating it, I discovered that MtCharacterDefintionTag is buggy since the beginning in Python and you can't retrieve any MTCharacterBodyPart since the method MTCharacterDefinitionTag.GetRootBodyPart is badly implemented and will cause a crash.

        Moreover I also found out that GetExposedBodyPartSettings was also badly implemented so you can't pass a valid argument. Sadly you can't do anything about that. I will provide a fix for it in the next version.

        Just in case find bellow a script that will works once the two previous bugs will be fixed. This script iterates over all character definition parts and display their Id and also use the GetExposedBodyPartSettings to get the current weight a given body part is assigned to.

        import c4d
        import maxon
        
        doc: c4d.documents.BaseDocument  # The currently active document.
        op: c4d.BaseObject | None  # The primary selected object in `doc`. Can be `None`.
        
        # A Generator to iterate over all children of a given skeleton body part.
        # This function is recursive by default it won't be able to proceed skeleton whith an element nested in 1000 or more elements.
        def SketeletonIterator(root: c4d.modules.character.MTCharacterBodyPart, level=0):
            yield root, level
            for childIndex in range(root.GetChildCount()):
                child = c4d.modules.character.MTCharacterBodyPart = root.GetChild(childIndex)
                yield from SketeletonIterator(child, level+1)
        
        # Prints all IDs for all skeletons
        def PrintAllCharacterDefinitionId(characterSolverTag):
            # Get the associated Character definition tag
            characterDefinitionTag = characterSolverTag[c4d.CS_TARGET_CHARACTER]
            if not characterDefinitionTag:
                return
        
            # Get the Character definition(skeleton) Root stored within the Character Definition Tag
            # Aka the Root element visible in the tree from the Character Definition Tag's Manager window.
            # WARNING: This will will crash when root will be deallocated, there is no workaround a fix is going to be provided.
            root: c4d.modules.character.MTCharacterBodyPart = characterDefinitionTag.GetRootBodyPart()
        
            for child, level in SketeletonIterator(root):
                # Get all the settings of this child
                childParam: c4d.modules.character.MTBodyPartParameters = child.GetParameters()
        
                # Print the name and their id
                print(f"{' ' * level * 2}{childParam._name}, Id:{childParam._identifier}")
        
        
        def main() -> None:
            if not op:
                return
        
            # Retrieve the motion tag
            characterSolverTag = op.GetTag(c4d.Tcharmotiontransfer)
            if not characterSolverTag:
                return
        
            PrintAllCharacterDefinitionId(characterSolverTag)
            
            # Print the weight of the torso body part 
            bodyPartSetting = characterSolverTag.GetExposedBodyPartSettings("net.maxon.animation.retarget.defaulttemplate.torso")
            print(bodyPartSetting[c4d.CS_BPSS_IDENT_ID], bodyPartSetting[c4d.CS_BPSS_WEIGHT_ID])
        
        
        
        if __name__ == '__main__':
            main()
        

        Cheers,
        Maxime.

        MAXON SDK Specialist

        Development Blog, MAXON Registered Developer

        1 Reply Last reply Reply Quote 0
        • jochemdkJ
          jochemdk
          last edited by

          Thx Maxim, so I'll have to wait until the next version..

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