How can we get the default port of a GraphNode?
-
Hi community,
I had read the new graphdescription manual, which is super useful, but something came in my mind, in the GraphDescription, we connect the "default" port to a GraphDescription.Type: "Output", how we can get the "default" port of a true node, if there are some functions I didn't know or something like get image node in NodeSpaceHelpersInterface that we can query the "default" port.
Cheers~
DunHou -
Hey @Dunhou,
Thank you for reaching out us. I am unsure about your question here. What is the "default" port of a true node for you?
I might have a hunch what you mean by that but I am not sure. Let us assume we have a Root type node with an input port called In, and a Data type node with an output port called Out. As a graph description we would write it like this:
{ "$type": "Root", "In": { "$type": "Data", } }
I.e., the fact that we connect in to out has become implicit. This is an intentional feature of graph descriptions, as in material graphs nodes often only have one output port. So, by default this information is compressed away and graph descriptions figure out which output port you mean. There is also a syntax for making this explicit which is needed when you have more than one output port. But it is not yet functional in
2024.3
, I will touch it together with variadic ports in the next week, so that I can hopefully squeeze it into the next 2024.X.0 release. But it might take another release, as the development doors for that release are already closing.// Same result as above but here we are more verbose about how we want to connect things. // This syntax is non-functional in Cinema 4D 2024.3. { "$type": "Root", // Here we make the connection explicit using the -> operator "In -> Out": { "$type": "Data", } }
So, the "default" output port a graph description is connecting to, is the singular output port on that node. I had to take that feature and its documentation out last minute and could have been more verbose about how that works. Once I fixed that feature and add back its documentation, it should become clearer for future readers how this works.
If that was not what you meant, could please reiterate what you mean by the 'default port of a graph node'?
Cheers,
Ferdinand -
Hi @ferdinand ,
Thanks for your quickly answer.
Compared to the new GraphDescription, I am more interested in exploring whether there is a method in the Maxon API to obtain the default output port, rather than use normal FindChild("specific id"). like the GetNodeSpaceData.Get(maxon.nodes.NODESPACE.IMAGENODEASSETID) can get the defult image node?
And thanks you explain for the GraphDescription as well.
Cheers
DunHou -
Hey @Dunhou,
I still do not really understand what you would consider to be a "default port". The Nodes API has the concept of a default value of a port with
GraphNode.GetDefaultValue
but there is no such thing as the default port of a node.Graph descriptions do this by getting all output ports of the node to connect to, and simply complain when there is not exactly one port or the user has not provided an explicit connection. There is no metadata in a
GraphNode
instance or theDataDescription
of a node template which would tell you which in- or output ports are "the important ones" (what you probably mean with 'default' here).When you want to emulate what graph descriptions do, simply get all output ports, make sure that there is exactly one child and pick that
# Get all (direct) output ports and make sure that there is exactly one. outputs: list[maxon.GraphNode] = myTrueNode.GetOutputs().GetChildren() if len(outputs) != 1: raise RuntimeError("Node has more than one output port.") # The selected port and its ID. port: maxon.GraphNode = outputs[0] pid: maxon.Id = port.GetId()
Cheers,
Ferdinand -
Hi @ferdinand ,
Sorry for bad description here, and here is and example to show what I try to do,this function works well, but just curious about if there is an official attribute like "maxon.node.default_output" that I am not aware of
Like the picture, the material had a OUT port named Output, and some color port accept same datatype. I want to get the very first port of the given type(like if we want to connect a image to the material, we can auto select a port), but I think it returns a list but not like the "UI" show us, Base Color > Specular Color > Transmission Color and etc. and you can see the out port of the node can be "outcolor/out/color" this is the attribute I ask .
A more specific situation isοΌif we drag a color correction node into a wire, it will auto-connect to node into the wire with an input port and an output port connected. I want to imitate this heavier.
Hope this will be clear.
Cheers~
DunHou# θ·εθηΉδΈη«―ε£ ==> ok def GetPort(self, shader: maxon.GraphNode, port_id :str = None) -> Union[maxon.GraphNode,bool]: """ Get a port from a Shader node.if port id is None,try to find out port. Args: shader (maxon.GraphNode): the host shader port_id (str, optional): the port id, fill none try to get the output port. Returns: Union[maxon.GraphNode,bool]: the port we get. """ if not shader: raise ValueError(f'Expected a maxon.GraphNode, got {type(shader)}') out_ids = ['outcolor','output','out'] if self.nodespaceId == RS_NODESPACE: if port_id == None: for out in out_ids: port_id = f"{self.GetAssetId(shader)}.{out}" port: maxon.GraphNode = shader.GetInputs().FindChild(port_id) if port.IsNullValue(): port = shader.GetOutputs().FindChild(port_id) if not port.IsNullValue(): return port else: port: maxon.GraphNode = shader.GetInputs().FindChild(port_id) if port.IsNullValue(): port = shader.GetOutputs().FindChild(port_id) return port
-
Hey @Dunhou,
ah okay, now I understand. These are called converter ports, you can find that port attribute in the resource editor.
But you cannot really access that information in Python since there we neither have there DataDescriptionDatabaseInterface with which we could access the
DataDescription
data of a node template, nor do we have the means to get a port description as we do in C++. The port descriptions are very fringe stuff, I doubt that we will ever port that (hehe, port ^^). What has been more than once a topic internally, isDataDescriptionDatabaseInterface
(not ported) andDataDescription
(already ported) which is somewhat the counterpart to the classic APIc4d.Description
in the maxon API world.But there is also a lot of other stuff to port, and in the end it is up to @m_adam what to port and what not. Descriptions are an important concept in the maxon API just as they were in the classic API. But I am not sure if this is a top level priority. I'll ask Maxime tomorrow what his take is
Cheers,
Ferdinand -
Hey @m_adam ,
Can we port this DataDescriptionDatabaseInterface in python in some up-coming versions? this would be handy for some converting progress, now if I want to convert data, I have to manually writhe to node id, it is worth an automatic solution and we already have this.
Cheers~
DunHou