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

    API for Adding a Port on a Group Node?

    Cinema 4D SDK
    2023 python
    2
    5
    713
    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,

      Is there an API way to add port on a group node, and consequently, rename them?
      So far the only examples I can find is modifying an existind node.

      I did try using AddPort method. But it gives me an error of
      ValueError: You can't add a port directly to node group@L8BzdBtMNh1sWN7TnpEXFD.

      Here's what I'm trying to do:

      2023-01-18_17-01-59.gif

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

        Hi,
        you have the function CreateInputPort that will help you to create that port.

        You could use this code #addedPort = groupRoot.GetInputs().AddPort("newID") The difference is that the port will be identified only with the ID you passe as the argument of AddPort. CreateInputPort will create for you a hash and will add it to the port's ID creating something like passedID@Hashxxxxxx

        There is no type as the port is just streaming the data. As you can still specify the data using the Resource editor, i will ask the dev if you can do it programmatically to force the type of the port.

        Here an example that will group the selected nodes in the selected material and add an input port to the group.

        import c4d
        import maxon
        
        
        def main():
            # Retrieve the selected BaseMaterial
            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("Cannot retrieve node material reference")
        
            # Retrieve the current node space Id
            nodespaceId = c4d.GetActiveNodeSpaceId()
        
            # Retrieve the Nimbus reference for a specific node space
            nimbusRef = mat.GetNimbusRef(nodespaceId)
            if nimbusRef is None:
                raise ValueError("Cannot retrieve the nimbus ref for that node space")
        
            # Retrieve the graph corresponding to that node space.
            graph = nimbusRef.GetGraph()
            if graph is None:
                raise ValueError("Cannot retrieve the graph of this nimbus ref")
        
            # Get the root of the GraphNode
            root = graph.GetRoot()
        
            # Retrieve all nodes, child of the root node
            nodes = []
            root.GetChildren(nodes, maxon.NODE_KIND.NODE)
        
            # Create a list of the selected ones.
            selectedNodes = []
            maxon.GraphModelHelper.GetSelectedNodes(graph, maxon.NODE_KIND.NODE, selectedNodes)
         
            # Group all the selected nodes in an empty node.
            groupRoot = maxon.GraphNode()
        
            # To modify a graph, modification must be done inside a transaction. After
            # modifications are done, the transaction must be committed.
            with graph.BeginTransaction() as transaction:
                groupRoot = graph.MoveToGroup(groupRoot, maxon.Id("idOfMyGroup"), selectedNodes)
                maxon.GraphModelHelper.CreateInputPort(groupRoot, "someid", "new port name")
                transaction.Commit()
        
            # Pushes an update event to Cinema 4D
            c4d.EventAdd()
        
        
        if __name__ == "__main__":
            main()
        

        Cheers,
        Manuel

        MAXON SDK Specialist

        MAXON Registered Developer

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

          @manuel

          Thanks for the illustration code. I'm trying to supplement it by connecting the group ports and node ports but I'm having problem doing so.

          See sample code with comments.

              value = selectedNodes[0] # assuming the selected node is a value node
          
              with graph.BeginTransaction() as transaction:
                  groupRoot = graph.MoveToGroup(groupRoot, maxon.Id("idOfMyGroup"), selectedNodes)
                  maxon.GraphModelHelper.CreateInputPort(groupRoot, "someid", "new port name")
                  
          
                 print (groupRoot.GetInputs().FindChild("someid") ) # returns null instead of a node object
                 print (groupRoot.GetOutputs().FindChild("someid") ) # returns null instead of a node object
                 
                 print (value.GetInputs().FindChild("in")) # returns an error of ValueError: Node with path type@KX8Pk7tsBJgq7AjxVnYQLZ doesn't exist any longer. Not sure why the path matters considering I'm already storing the actual node in a variable (i.e. value)
          

          Thanks for looking at my problem.

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

            The function CreateInputPort will return the new port. Its complete ID will be something like someid@BSMjOUqqO13ufL3qExOL5B where the part after the @ make it unique. If you use FindChild only using "someid" it will not find the port.

                with graph.BeginTransaction() as transaction:
                    groupRoot = graph.MoveToGroup(groupRoot, maxon.Id("idOfMyGroup"), selectedNodes)
                    newPort = maxon.GraphModelHelper.CreateInputPort(groupRoot, "someid", "new port name")
                    value = []
                    maxon.GraphModelHelper.FindNodesByAssetId(graph,"net.maxon.node.type", True, value)
                    valueNode = value[0]
                    inputNode = valueNode.GetInputs().FindChild("in")
                    print (inputNode, newPort)
                    newPort.Connect(inputNode)
                    transaction.Commit()
            

            Defining the ports' type added to the group is not possible. You need to use SetType that is not available.

            Cheers,
            Manuel

            MAXON SDK Specialist

            MAXON Registered Developer

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

              @manuel

              Thanks for the illustration. Works as expected.

              When you have this statement:

                      maxon.GraphModelHelper.FindNodesByAssetId(graph,"net.maxon.node.type", True, value)
                      valueNode = value[0]
                      inputNode = valueNode.GetInputs().FindChild("in")
              

              I'm guessing this part of my previous code is no longer working and so we need to reestablish the variable again.

              value = selectedNodes[0] 
              

              Anyhow, thanks again.
              Closing this thread now 🙂

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