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

    How to get animation tracks of Redshift material using python in Cinema 4D 2023

    Cinema 4D SDK
    python
    2
    3
    662
    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
      BeerTheKid9
      last edited by

      How to get animation tracks of Redshift material using python in Cinema 4D 2023? (Ultimately, I want to set keyframes for the material's Diffuse Color and animate it.)

      Here is what I have tried.

      I manually added keyframes to the color parameter of RS materials, such as RS Material, RS Standard, and RS C4D Shader, and executed the followin script to get the animation tracks.
      The script returns nothing but the name of materials and no tracks. (Of course, the animation information can be seen in the dope sheet.)

      for mat in doc.GetMaterials():
          print(f"material:{mat.GetName()}")
          for track in mat.GetCTracks():
              print(f"->track:{track.GetName()}")
      

      My environment is Windows 10, Cinema 4D 2023.1.3, Redshift 3.5.13.

      Thanks in advance.

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

        hi,

        this should not be different than any node inside c4d (including scene node).
        Tracks are stored inside a Baselist2D object created and linked to any node.
        You must get the path of the node and retrieve the object using GetBaseListForNode.

        Once you got the object, it will work as expected with GetCTracks for example. I included in the example below how to get directly the descID of a port and the corresponding track.

        from typing import Optional
        import c4d
        import maxon
        
        # for this example we are creating keys for the color and the intensity parameter of the BSDF node inside
        # a standard/physical material
        
        
        doc: c4d.documents.BaseDocument  # The active document
        op: Optional[c4d.BaseObject]  # The active object, None if unselected
        
        def main() -> None:
            # Get the active material
            mat = doc.GetActiveMaterial()
            if mat is None:
                raise ValueError("There is no selected BaseMaterial")
        
            # Retrieve the reference of the material as a node Material.
            nodeMaterial = mat.GetNodeMaterialReference()
            if nodeMaterial is None:
                raise ValueError("can't retrieve nodeMaterial reference")
        
            # Retrieve the current node space Id
            nodespaceId = c4d.GetActiveNodeSpaceId()
            # Get the nimbusref, this is useful to retrieve the DescID of a parameter.
            nimbusRef =  nodeMaterial.GetNimbusRef(nodespaceId)
        
        
            graph = nodeMaterial.GetGraph(nodespaceId)
            if graph is None:
                raise ValueError("can't retrieve the graph of this nimbus ref")
        
            root = graph.GetRoot()
        
            # Delegate function that will retrieve the tracks for a port.
            def PrintInfo(port):
                # Get the path of the node. We are looking for port that must have "color" somewhere in their path.
                portPath = port.GetPath()
                if "color" in portPath:
                    # Retrieve information of the True node this port is part of
                    # For each GraphNode (node and port) a BaseList2D is created.
                    parentNode = port.GetAncestor(maxon.NODE_KIND.NODE)
                    parentNodePath = parentNode.GetPath()
        
                    # Retrieve the descID corresponding to this port.
                    portDescID =  nimbusRef.GetDescID(portPath)          
                    # Retrieve the BaseList2D object corresponding to the True Node and NOT the port.
                    obj = nodeMaterial.GetBaseListForNode(nodespaceId, parentNodePath)
                    if obj is None:
                        return False
                    # As this parameter is a color, the parameter will have one track per sub channel.
                    # The last level of the descID must be added.
                    portDescID.PushId(c4d.DescLevel(c4d.COLORA_R))
                    # Find the right track with this DescID on the True Node Baselist2D object
                    track = obj.FindCTrack(portDescID)
                    print (track)
        
                return True
        
            nodesList = []
            root.GetChildren(nodesList, maxon.NODE_KIND.NODE)
            for node in nodesList:
                # Another way of printing all the track a node have. Retrieve the object corresponding to the node.
                # Once the right object is founded, track works the same as any regular c4d object.
                # nodePath = node.GetPath()
                # obj = nodeMaterial.GetBaseListForNode(nodespaceId, nodePath)
                # for track in obj.GetCTracks():
                #     print (track)
                node.GetInputs().GetChildren(PrintInfo, maxon.NODE_KIND.PORT_MASK)
        
        """
        def state():
            # Defines the state of the command in a menu. Similar to CommandData.GetState.
            return c4d.CMD_ENABLED
        """
        
        if __name__ == '__main__':
            main()
        

        Cheers,
        Manuel

        MAXON SDK Specialist

        MAXON Registered Developer

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

          Hi Manuel,

          Thank you very much.
          Your script works perfectly in my environment.

          Only one modification I made was
          if "color" in portPath:
          to
          if "color" in str(portPath):

          Thank you.

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