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
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    How can we get the default port of a GraphNode?

    Cinema 4D SDK
    windows python 2024
    2
    7
    1.4k
    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.
    • DunhouD
      Dunhou
      last edited by Dunhou

      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.

      cdb5394c-341e-4176-9a41-0fd3be97cc36-image.png

      Cheers~
      DunHou

      https://boghma.com
      https://github.com/DunHouGo

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

        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

        MAXON SDK Specialist
        developers.maxon.net

        DunhouD 1 Reply Last reply Reply Quote 0
        • DunhouD
          Dunhou @ferdinand
          last edited by

          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

          https://boghma.com
          https://github.com/DunHouGo

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

            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 the DataDescription 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

            MAXON SDK Specialist
            developers.maxon.net

            DunhouD 1 Reply Last reply Reply Quote 0
            • DunhouD
              Dunhou @ferdinand
              last edited by

              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

              c63dcde2-c984-4c4b-8e53-5b951b5c24d0-image.png

                  # 获取节点上端口 ==> 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
              

              https://boghma.com
              https://github.com/DunHouGo

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

                Hey @Dunhou,

                ah okay, now I understand. These are called converter ports, you can find that port attribute in the resource editor.
                9d6b1974-f66a-45e0-a6a2-e646247d3139-image.png

                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, is DataDescriptionDatabaseInterface (not ported) and DataDescription (already ported) which is somewhat the counterpart to the classic API c4d.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

                MAXON SDK Specialist
                developers.maxon.net

                1 Reply Last reply Reply Quote 1
                • DunhouD
                  Dunhou
                  last edited by

                  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

                  https://boghma.com
                  https://github.com/DunHouGo

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