How to Use GetConnectionValue/s() or GetConnection()?
-
Hi,
I'm trying to retrieve a data of the inport and outport connection between two nodes.
For example:
Texture Node (OutColor OutPort) > Standard Node (Opacity InPort)
I tried the
GetPredessor
andGetSuccesor
but it only spits the nodes. And if it spits connection, it only spits one sided connection but not both.Again, I want the actual connection data.
So I'm trying the
GetConnectionValues()
andGetConnection()
But I'm confused how to implement it.
In the documention, it says:
GraphNode.GetConnectionValues(target, receiver)
target – The other end of the connection.
What is a target?
The forum also doesn't give any relevant result to the aforementioned methods.
Is it possible to have a sample working illustration code on the methods?Regards,
Ben -
I already the following code.
It does give me aTrue
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
-
I also tried the
GetValue
method but it gives me noneval = 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
` -
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 -
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, whileGetValue
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 -
@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
GetConnections
to spit is this one:
Texture Node (OutColor OutPort)
in whatever form because that is what it is connected to. -
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. -
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.
-
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 incorrectmask
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:Cheers,
FerdinandGraph:
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()
-
Slr. Can confirm. This works.
This screenshot is all I need (i.e. how to use the GetConnections method).
Thanks@
-
@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..