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

    How to Use GetConnectionValue/s() or GetConnection()?

    Cinema 4D SDK
    2023 python
    3
    11
    1.8k
    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

      I already the following code.
      It does give me a True result which I guess it means there is a connection.
      But the receiver returns an empty list.

      CASE: A texture node (outColor Outport) is connected to the standard node (opacity Inport)

              result = []
              GraphModelHelper.GetSelectedNodes(graph, maxon.NODE_KIND.ALL_MASK, result)
              texture = result[1]
              standard = result[0]
      
              port = standard.GetInputs().FindChild("com.redshift3d.redshift4c4d.nodes.core.standardmaterial.opacity_color")
      
              receiver = []
              connection = port.GetConnectionValues(texture, receiver)
      
              print (connection) # Returns True
              print (receiver) # Returns an Empty List instead of the actual connection
      
      ferdinandF 1 Reply Last reply Reply Quote 0
      • B
        bentraje
        last edited by bentraje

        I also tried the GetValue method but it gives me none

        val = standard.GetValue(attr="com.redshift3d.redshift4c4d.nodes.core.standardmaterial.opacity_color")) # returns None instead of the texture node out color

        val = port.GetValue(attr="com.redshift3d.redshift4c4d.nodes.core.standardmaterial.opacity_color")) #returns None instead of the texture node out color
        `

        ferdinandF 1 Reply Last reply Reply Quote 0
        • ferdinandF
          ferdinand @bentraje
          last edited by

          Hello @bentraje,

          Thank you for reaching out to us. Your question has not been overlooked, but I did not get to it yet.

          Cheers,
          Ferdinand

          MAXON SDK Specialist
          developers.maxon.net

          1 Reply Last reply Reply Quote 1
          • ferdinandF
            ferdinand @bentraje
            last edited by ferdinand

            Hey @bentraje,

            Thank you for reaching out to us and please excuse the short delay. Your code likely does not work because the two entities for which you attempt to evaluate the connection with GraphNode.GetConnectionValues are what the Nodes API calls a True Node (texture) and a Port Node (port). Connections can however only exist between an out-port and an in-port.

            The methods GraphNode.GetConstantValue, .GetDefaultValue, .GetValue, and .GetValue are all not related to connections. In short, GetDefaultValue yields the value a port has when no wire is connected to it, while GetValue yields any node attribute. Attributes are a somewhat underlying concept of ports and many more things.

            I am not quite sure what you are trying to achieve when you say

            I'm trying to retrieve a data of the inport and outport connection between two nodes.

            First of all, there is a slight ambiguity in the connection finding part of your question because there can be more than one connection between two true nodes, and there can be more than one wire between two ports.

            • GraphModelHelper.IsConnected: Allows you to evaluate if a given true or port node is connected to a given port node in any shape or form.
            • GraphNode.GetConnections: Yields all connections that fan out from a port node. So, you must iterate over the ports of a true node to use it.
            • GraphNode.GetWires: Returns the wires that are spanned between two port nodes.
            • GraphModelHelper.GetAllPredecessors, .GetAllSuccessors, .GetDirectPredecessors, and .GetDirectSuccessors: The concept of sucessors and predecessors puts an abstraction on top of node connections and lets you retrieve the true nodes that are connected up- or downstream to a true node.

            What to do here, depends also a bit on what you would consider 'data' in your question. Do you want to get the metadata for a connection like the direction and the wire mode? Or do you want to get hold of the value which is transported with the connection from an out-port to an in-port?

            Cheers,
            Ferdinand

            MAXON SDK Specialist
            developers.maxon.net

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

              @ferdinand
              Thanks for the response.

              RE: Do you want to get the metadata .. or .. ?
              Can I have both? I never really thought as a trivial.
              I just want the data of two nodes. and the ports they are connected it.
              So I can recreate them later.

              For example, like in the above.
              Texture Node (OutColor OutPort) > Standard Node (Opacity InPort)
              Inherently there is 4 data there. 2 node with their 2 ports that is connected.

              RE: GraphNode.GetConnections

              I'm trying this but I'm not sure how to use it.

                      port = standard.GetInputs().FindChild("com.redshift3d.redshift4c4d.nodes.core.standardmaterial.opacity_color")
              
                      receiver = []
                      port.GetConnections(maxon.PORT_DIR.INPUT, conns=receiver, mask=maxon.Wires.value, mode=maxon.WIRE_MODE.ALL)
              

              It gives me an error of TypeError: unable to convert builtins.property to @net.maxon.graph.wires

              What I'm expecting for the GetConnectionsto spit is this one:
              Texture Node (OutColor OutPort) in whatever form because that is what it is connected to.

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

                For reference,

                Here it is a simple equivalent in Maya Python.

                # List all connections to BALL
                list = cmds.listConnections('BALL')
                
                # List only incoming connections from BALL.tx
                cmds.listConnections( 'standard_node.opacityColor', destination=False, source=True )
                # result textureNode.outColor
                

                I am not expecting it to be 1 to 1 of course but I'm not also expecting to this trivial and hard.
                I just really need the connection.

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

                  Here is also the corresponding documentation.

                  https://download.autodesk.com/us/maya/2009help/CommandsPython/listConnections.html

                  You can see it below how it is being used so there's no whatsoever confusion on its usage.

                  ferdinandF 1 Reply Last reply Reply Quote 0
                  • ferdinandF
                    ferdinand @bentraje
                    last edited by ferdinand

                    Hey @bentraje,

                    first of all, I understand your frustration, we just yesterday talked about the state of the Nodes API and are well aware of its hurdles for anything but super-experts. On the other hand, I must point out again, that fragments of code or error messages are pretty meaningless. As stated in the forum guidelines, you should post executable code.

                    With that being said, I can confirm that GraphNode.GetConnectionValues is behaving oddly. But that could be because Redshift really does not like laptop as a rendering device. Everything else works fine for me here but I still have no clue what you want to do effectively.

                    PS: The mistake in your GetConnections call lied in the incorrect mask value. The documentation for the method is a bit butchered, we will fix that. I would however always recommend using the VS Code bindings, as it would have told you this:

                    da78fb95-5281-413d-81be-3afc10bbf818-image.png

                    Cheers,
                    Ferdinand

                    Graph:
                    aac45e2b-1a88-49fe-9716-1cbc9d2cb816-image.png
                    Output:

                    maxon.GraphModelHelper.GetDirectPredecessors(endNode, maxon.NODE_KIND.NODE) = [standardmaterial@Hv6m0BuyCB4idfeZnssZYC]
                    maxon.GraphModelHelper.GetDirectPredecessors(endNode, maxon.NODE_KIND.OUTPORT) = [standardmaterial@Hv6m0BuyCB4idfeZnssZYC>com.redshift3d.redshift4c4d.nodes.core.standardmaterial.outcolor]
                    maxon.GraphModelHelper.GetAllPredecessors(endNode, maxon.NODE_KIND.NODE) = [standardmaterial@Hv6m0BuyCB4idfeZnssZYC, group@WVcBzy1WDR_kJrRviYwbmF, texturesampler@EddwvQ5ALJSnU5EcX99U$x, texturesampler@E1AoVUhQEBEn$4nuyz8irm, rsscalarramp@TEY3JetDLNkqz86IJahb_C, texturesampler@aKfJScQXKF0ugzuJyl27MG, texturesampler@F9gCNSUTGdMlqUsC69b$0A, bumpmap@HiKbvo1FLNCkb4DKLPKvjE, texturesampler@crysppSdAZvt5dCHd$$i1E]
                    
                     ----------------------------------------------------------------------------------------------------
                    
                    out-port: standardmaterial@Hv6m0BuyCB4idfeZnssZYC>com.redshift3d.redshift4c4d.nodes.core.standardmaterial.outcolor
                    wires: Wires - Value:16, Event:16, Dependency:16, Context:0, Hidden:0, Inhibit:0, Slink:0, Tlink:0
                    default: 0.0,0.0,0.0
                    in-port: output@TvFBXodvDtuu346T8ZukFG<com.redshift3d.redshift4c4d.node.output.surface
                    
                    out-port: group@WVcBzy1WDR_kJrRviYwbmF>outcolor@KbTuENK$GBdgV12yPDVlKA
                    wires: Wires - Value:16, Event:16, Dependency:16, Context:0, Hidden:0, Inhibit:0, Slink:0, Tlink:0
                    default: 0.21404114365577698,0.21404114365577698,0.21404114365577698
                    in-port: standardmaterial@Hv6m0BuyCB4idfeZnssZYC<com.redshift3d.redshift4c4d.nodes.core.standardmaterial.base_color
                    
                    out-port: texturesampler@EddwvQ5ALJSnU5EcX99U$x>com.redshift3d.redshift4c4d.nodes.core.texturesampler.outcolor
                    wires: Wires - Value:16, Event:16, Dependency:16, Context:0, Hidden:0, Inhibit:0, Slink:0, Tlink:0
                    default: 0.0,0.0,0.0,1.0
                    in-port: group@WVcBzy1WDR_kJrRviYwbmF<in@GrX6SuapEpQkoY6CBvFyAj
                    
                    out-port: texturesampler@E1AoVUhQEBEn$4nuyz8irm>com.redshift3d.redshift4c4d.nodes.core.texturesampler.outcolor
                    wires: Wires - Value:16, Event:16, Dependency:16, Context:0, Hidden:0, Inhibit:0, Slink:0, Tlink:0
                    default: 0.0,0.0,0.0,1.0
                    in-port: group@WVcBzy1WDR_kJrRviYwbmF<in@fd8$tVTfOhKtjHscJx8tPm
                    
                    out-port: rsscalarramp@TEY3JetDLNkqz86IJahb_C>com.redshift3d.redshift4c4d.nodes.core.rsscalarramp.out
                    wires: Wires - Value:16, Event:16, Dependency:16, Context:0, Hidden:0, Inhibit:0, Slink:0, Tlink:0
                    default: 0
                    in-port: standardmaterial@Hv6m0BuyCB4idfeZnssZYC<com.redshift3d.redshift4c4d.nodes.core.standardmaterial.refl_weight
                    
                    out-port: texturesampler@aKfJScQXKF0ugzuJyl27MG>com.redshift3d.redshift4c4d.nodes.core.texturesampler.outcolor
                    wires: Wires - Value:16, Event:16, Dependency:16, Context:0, Hidden:0, Inhibit:0, Slink:0, Tlink:0
                    default: 0.0,0.0,0.0,1.0
                    in-port: rsscalarramp@TEY3JetDLNkqz86IJahb_C<com.redshift3d.redshift4c4d.nodes.core.rsscalarramp.input
                    
                    out-port: texturesampler@F9gCNSUTGdMlqUsC69b$0A>com.redshift3d.redshift4c4d.nodes.core.texturesampler.outcolor
                    wires: Wires - Value:16, Event:16, Dependency:16, Context:0, Hidden:0, Inhibit:0, Slink:0, Tlink:0
                    default: 0.0,0.0,0.0,1.0
                    in-port: standardmaterial@Hv6m0BuyCB4idfeZnssZYC<com.redshift3d.redshift4c4d.nodes.core.standardmaterial.refl_roughness
                    
                    out-port: texturesampler@EddwvQ5ALJSnU5EcX99U$x>com.redshift3d.redshift4c4d.nodes.core.texturesampler.outcolor
                    wires: Wires - Value:16, Event:16, Dependency:16, Context:0, Hidden:0, Inhibit:0, Slink:0, Tlink:0
                    default: 0.0,0.0,0.0,1.0
                    in-port: standardmaterial@Hv6m0BuyCB4idfeZnssZYC<com.redshift3d.redshift4c4d.nodes.core.standardmaterial.sheen_color
                    
                    out-port: bumpmap@HiKbvo1FLNCkb4DKLPKvjE>com.redshift3d.redshift4c4d.nodes.core.bumpmap.out
                    wires: Wires - Value:16, Event:16, Dependency:16, Context:0, Hidden:0, Inhibit:0, Slink:0, Tlink:0
                    default: 0.0,0.0,0.0
                    in-port: standardmaterial@Hv6m0BuyCB4idfeZnssZYC<com.redshift3d.redshift4c4d.nodes.core.standardmaterial.bump_input
                    
                    out-port: texturesampler@crysppSdAZvt5dCHd$$i1E>com.redshift3d.redshift4c4d.nodes.core.texturesampler.outcolor
                    wires: Wires - Value:16, Event:16, Dependency:16, Context:0, Hidden:0, Inhibit:0, Slink:0, Tlink:0
                    default: 0.0,0.0,0.0,1.0
                    in-port: bumpmap@HiKbvo1FLNCkb4DKLPKvjE<com.redshift3d.redshift4c4d.nodes.core.bumpmap.input
                    

                    Code:

                    """Unwinds connection information in the active node space graph of the first material in the
                    active scene.
                    """
                    
                    import c4d
                    import maxon
                    
                    doc: c4d.documents.BaseDocument  # The active document
                    
                    def main() -> None:
                        """Unwinds connection information in the active node space graph of the first material in the
                        active scene.
                        """
                        # Attempt to get the node graph for the active node space for the first material in the document.
                        material: c4d.BaseMaterial = doc.GetFirstMaterial()
                        if not material:
                            return
                        
                        nodeMaterial: c4d.NodeMaterial = material.GetNodeMaterialReference()
                        currentSpace: maxon.Id = c4d.GetActiveNodeSpaceId()
                        graph: maxon.NodesGraphModelInterface = nodeMaterial.GetGraph(currentSpace)
                        if graph.IsNullValue():
                            return
                        
                        # Get the end node in the graph, so that we can unwind connection information.
                        endNode: maxon.GraphNode = graph.GetNode(nodeMaterial.GetMaterialNodePath(currentSpace))
                        if endNode.IsNullValue():
                            return
                        
                        # Get the direct true node predecessors of the end node, i.e., all true nodes that are connected
                        # directly to the end node.
                        print (f"{maxon.GraphModelHelper.GetDirectPredecessors(endNode, maxon.NODE_KIND.NODE) = }")
                        # Get the direct out-port node predecessors of the end node, i.e., all out-port nodes that are
                        # connected directly to the end node.
                        print (f"{maxon.GraphModelHelper.GetDirectPredecessors(endNode, maxon.NODE_KIND.OUTPORT) = }")
                    
                        # Get all true node predecessors of the end node, i.e., all true nodes that are connected
                        # directly or indirectly to the end node. In a well connected graph, i.e., a graph where every
                        # node does contribute to the end node, this will simply yield all true nodes.
                        print (f"{maxon.GraphModelHelper.GetAllPredecessors(endNode, maxon.NODE_KIND.NODE) = }")
                    
                        print ("\n", "-" * 100)
                    
                        def GetPredConnectionInfo(node: maxon.GraphNode) -> None:
                            """Prints predecessor connection information for #node in a recursive fashion.
                            """
                            # Bail when the passed node is not a true node.
                            if node.GetKind() != maxon.NODE_KIND.NODE:
                                return
                            
                            # For every input port in #node.
                            for inPort in node.GetInputs().GetChildren():
                                # Get the connected output ports and their wires.
                                for outPort, wires in inPort.GetConnections(
                                    maxon.PORT_DIR.INPUT, None, maxon.Wires.All(), maxon.WIRE_MODE.ALL):
                                    # Get the true node which owns #outPort, i.e., the other true node which is 
                                    # connected to the true node #node.
                                    otherNode: maxon.GraphNode = outPort.GetAncestor(maxon.NODE_KIND.NODE)
                                    defaultValue: any = outPort.GetDefaultValue()
                                    print (f"\nout-port: {outPort}")
                                    print (f"wires: {wires}")
                                    print (f"default: {defaultValue}")
                                    print (f"in-port: {inPort}")
                                    # Start the recursion with #otherNode.
                                    GetPredConnectionInfo(otherNode)
                    
                        GetPredConnectionInfo(endNode)
                    
                    if __name__ == '__main__':
                        main()
                    

                    MAXON SDK Specialist
                    developers.maxon.net

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

                      @ferdinand

                      Slr. Can confirm. This works.
                      This screenshot is all I need (i.e. how to use the GetConnections method).
                      Thanks

                      https://developers.maxon.net/forum/assets/uploads/files/1683785107297-da78fb95-5281-413d-81be-3afc10bbf818-image-resized.png

                      @

                      1 Reply Last reply Reply Quote 0
                      • indexofrefractionI
                        indexofrefraction @ferdinand
                        last edited by indexofrefraction

                        @ferdinand
                        first of all, I understand your frustration, we just yesterday talked about the state of the Nodes API and are well aware of its hurdles for anything but super-experts.

                        you can say that aloud!
                        the whole system is very hard to understand. the only thing i got is all we know about traditional materials and even shaders is for the bin. node support evolved over time and most node examples do not work for people still using older c4d versions. also there are misc 3rd-party renderers that use different kinds of nodes / node systems. Drag & drop of attributes to the console doesn't work anymore, as well. the days of easy scripting are gone.. 😵

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