SOLVED PYTHON - FIND ANY ID PORT

Hello,
I'm new in python's world. I would like to know what peace of code I can wrhite to get any ID of nodes and nodes' ports.

I'm running C4D R21 under MAC OS.

In that case I'm trying to generate global and local matrice ports but it would be nice if I can use this to find any ports I need.
Here is a peace of code I've done, that generates some nodes and ports.

I've done some research but I'm a bit confused about how to do it.

import c4d

def main():

    # Create a null object and add an Xpresso tag to it.
    null = c4d.BaseList2D(c4d.Onull)
    null[c4d.ID_BASELIST_NAME] = "ESSAIM - DROTEK-NL"
    xpresso_tag = c4d.BaseList2D(c4d.Texpresso)
    null.InsertTag(xpresso_tag)

    # Crée la texture de référence Led
    c4d.CallCommand(202586)
    Ref_Led = doc.GetFirstMaterial()
    Ref_Led[c4d.MATERIAL_USE_COLOR] = False
    Ref_Led[c4d.MATERIAL_USE_REFLECTION] = False
    Ref_Led[c4d.MATERIAL_USE_LUMINANCE] = True
    Ref_Led[c4d.ID_BASELIST_NAME] = "REF_DROTEK-NL_LED"


    # Get the node master and the root noode of that graphview.
    master = xpresso_tag.GetNodeMaster()
    root = master.GetRoot()

    # Crée de nouveaux nodes dans l'éditeur python et ouvre les ports nécessaires
    Hierarchie_node = master.CreateNode(root, c4d.ID_OPERATOR_HIERARCHY, x=10, y=10)
    Hierarchie_node[c4d.GV_HIERARCHY_START_ID] = "DL"
    Hierarchie_node[c4d.GV_HIERARCHY_ITERATION_ID] = "P"

    Indice_objets = master.CreateNode(master.GetRoot(),400001152,None,100,10)
    ListeDeLiens_node = master.CreateNode(root, c4d.ID_OPERATOR_LINK,  x=250, y=10)
    Obj_Essaim = master.CreateNode(root, c4d.ID_OPERATOR_OBJECT,  x=600, y=10)
    Obj_Essaim.AddPort(c4d.GV_PORT_INPUT, c4d.GV_OBJECT_OPERATOR_OBJECT_IN, flag = c4d.GV_PORT_FLAG_IS_VISIBLE)

    Obj_cloner = master.CreateNode(root, c4d.ID_OPERATOR_OBJECT,  x=100, y=100)
    Obj_cloner.AddPort(c4d.GV_PORT_OUTPUT, c4d.GV_OBJECT_OPERATOR_OBJECT_OUT, flag = c4d.GV_PORT_FLAG_IS_VISIBLE)
    

    mo_donnee = master.CreateNode(master.GetRoot(),1019010,None,250,100)
    # Get all in ports of the math node and select the first one.
    mo_donnee_out = mo_donnee.GetOutPorts()
    mo_donnee_out = mo_donnee_out[0] if mo_donnee_out else None

    Obj_Ref_Led = master.CreateNode(root, c4d.ID_OPERATOR_OBJECT,  x=600, y=100)
    Obj_Ref_Led.AddPort(c4d.GV_PORT_INPUT, c4d.GV_OBJECT_OPERATOR_OBJECT_IN, flag = c4d.GV_PORT_FLAG_IS_VISIBLE)

    # Lie les ports entre eux


    """
    # Get all out ports of the constant node and select the first one.
    const_node_out = const_node.GetOutPorts()
    const_node_out = const_node_out[0] if const_node_out else None

    # Get all in ports of the math node and select the first one.
    math_node_in = math_node.GetInPorts()
    math_node_in = math_node_in[0] if math_node_in else None

    # Connect the constant node to the math node.
    if const_node_out and math_node_in:
        const_node_out.Connect(math_node_in)
    """

    # Add our object to the scene graph and let Cinema update.
    doc.InsertObject(null)
    c4d.EventAdd()
    
    """liaison des bons objets aux nodes créés."""
    
    # Définition des objets
    cloner = doc.SearchObject("DROTEK-NL") # Récupère l'objet selon son nom.
    Rerefence_LED = doc.SearchMaterial("REF_DROTEK-NL_LED") # Récupère le matériaux selon son nom.
    
    Obj_cloner[c4d.GV_OBJECT_OBJECT_ID] = cloner # Lie le cloner "DROTEK-NL au Node "cloner" crée précédement.
    Obj_Ref_Led[c4d.GV_OBJECT_OBJECT_ID] = Rerefence_LED
    

if __name__=='__main__':
    main()

Can you help me on that point ?
Thank you

Hi @Hugo-BATTISTELLA,

regarding your screenshot,

32e2926e-d518-4b9f-ab43-297b8b4e55ff-image.png

"it does not work" is usually not a very good starting point to pin point for us what is going wrong, and so I also do struggle here a bit with what you do mean by that. Because when I run/inspect that passage on R21.207, it works as I would expect it to work. So I would have to ask you to please clarify what you do mean by "not working".

    # Addding a Motion Graphics Data node.
    mo_donnee = master.CreateNode(master.GetRoot(),1019010,None,250,100)
    mo_donnee_out = mo_donnee.GetOutPorts()
    mo_donnee_out = mo_donnee_out[0] if mo_donnee_out else None
    # The name of the first out port is: Count
    print (mo_donnee_out.GetName(mo_donnee))

Will print:

Count

Regarding the addition of ports, I see three .AddPort calls in your code and the resulting nodes will contain these ports in R21.207 as shown in your screenshot in the previous posting. So I am also confused about what you mean by "I still can't create ports on nodes" and would have to ask you to also clarify this. Our forum guide has also section on how to ask "good" questions, the "Structure of a Question: Detailed Description" section might be useful for you. You should line out what you do expect to happen and what happens instead.

So I cannot really say anything helpful for now, sorry,
Ferdinand

@zipit Thank you for quick answer !

That's weird 'cause a got this result on R21.207 : Capture d’écran 2021-01-05 à 15.34.39.png

Ports are created as expected...

But I just wonder how I can get the Global matrix and Local matrix ports ID... Still a mistery for me about how I can use any peace of code to get that

Hi @Hugo-BATTISTELLA,

my bad, it actually seems to work on R21.207, I did only test it on R21.116. So you are fine 🙂 I also removed my older post not to confuse anyone. About your problem of finding and connecting ports by their main id rather than their index, please have a look at the attached script example. The trick is basically here to iterate over all out/in ports in a node to find the one in question.

Cheers,
Ferdinand

import c4d

def main():

    # Create a null object and add an Xpresso tag to it.
    null = c4d.BaseList2D(c4d.Onull)
    null[c4d.ID_BASELIST_NAME] = "ESSAIM - DROTEK-NL"
    xpresso_tag = c4d.BaseList2D(c4d.Texpresso)
    null.InsertTag(xpresso_tag)

    # Crée la texture de référence Led
    c4d.CallCommand(202586)
    Ref_Led = doc.GetFirstMaterial()
    Ref_Led[c4d.MATERIAL_USE_COLOR] = False
    Ref_Led[c4d.MATERIAL_USE_REFLECTION] = False
    Ref_Led[c4d.MATERIAL_USE_LUMINANCE] = True
    Ref_Led[c4d.ID_BASELIST_NAME] = "REF_DROTEK-NL_LED"


    # Get the node master and the root noode of that graphview.
    master = xpresso_tag.GetNodeMaster()
    root = master.GetRoot()

    # Crée de nouveaux nodes dans l'éditeur python et ouvre les ports nécessaires
    Hierarchie_node = master.CreateNode(root, c4d.ID_OPERATOR_HIERARCHY, x=10, y=10)
    Hierarchie_node[c4d.GV_HIERARCHY_START_ID] = "DL"
    Hierarchie_node[c4d.GV_HIERARCHY_ITERATION_ID] = "P"

    Indice_objets = master.CreateNode(master.GetRoot(),400001152,None,100,10)
    ListeDeLiens_node = master.CreateNode(root, c4d.ID_OPERATOR_LINK,  x=250, y=10)
    Obj_Essaim = master.CreateNode(root, c4d.ID_OPERATOR_OBJECT,  x=600, y=10)
    Obj_Essaim.AddPort(c4d.GV_PORT_INPUT, c4d.GV_OBJECT_OPERATOR_OBJECT_IN, flag = c4d.GV_PORT_FLAG_IS_VISIBLE)

    Obj_cloner = master.CreateNode(root, c4d.ID_OPERATOR_OBJECT,  x=100, y=100)
    Obj_cloner.AddPort(c4d.GV_PORT_OUTPUT, c4d.GV_OBJECT_OPERATOR_OBJECT_OUT, flag = c4d.GV_PORT_FLAG_IS_VISIBLE)
    

    mo_donnee = master.CreateNode(master.GetRoot(),1019010,None,250,100)
    # Get all in ports of the math node and select the first one.
    mo_donnee_out = mo_donnee.GetOutPorts()
    mo_donnee_out = mo_donnee_out[0] if mo_donnee_out else None

    Obj_Ref_Led = master.CreateNode(root, c4d.ID_OPERATOR_OBJECT,  x=600, y=100)
    Obj_Ref_Led.AddPort(c4d.GV_PORT_INPUT, c4d.GV_OBJECT_OPERATOR_OBJECT_IN, flag = c4d.GV_PORT_FLAG_IS_VISIBLE)

    # Start of code added by Ferdinand ---------------------------------------

    # Ports have two ways to be indexed: By an index (0, 1, 2, ...)
    # which just enumerates all ports and is dependent on the order in which
    # they have been created. But also by a construct with is similar to
    # DescIDs - (main id, sub id, user id).
    # 
    # The identifier you have been using for creating the ports, e.g., 
    # c4d.GV_OBJECT_OPERATOR_OBJECT_OUT, is stored in the main id. There can
    # technically be more than one port with a given main ID on a node, but
    # we will ignore this for now. In Python we have to iterate over all ports
    # to get a port by its main id.
    
    # Get the output port of the node containing it. I created an alias for
    # your name so that things are a bit more readable.
    outputNode, outputPort = Obj_cloner, None
    # Get over all ports until we find one with the main id in question.
    for port in outputNode.GetOutPorts():
        if port.GetMainID() == c4d.GV_OBJECT_OPERATOR_OBJECT_OUT:
            outputPort = port
            break

    # The same for the input port of the other node.
    inputNode, inputPort = Obj_Ref_Led, None
    for port in inputNode.GetInPorts():
        if port.GetMainID() == c4d.GV_OBJECT_OPERATOR_OBJECT_IN:
            inputPort = port
            break

    # Try to connect both ports.
    if not (outputPort and inputPort and outputPort.Connect(inputPort)):
        msg = "Could not find ports or could not connect ports."
        raise RuntimeError(msg)

    # End of code added by Ferdinand -----------------------------------------

    # Add our object to the scene graph and let Cinema update.
    doc.InsertObject(null)
    c4d.EventAdd()
    
    """liaison des bons objets aux nodes créés."""
    
    # Définition des objets
    cloner = doc.SearchObject("DROTEK-NL") # Récupère l'objet selon son nom.
    Rerefence_LED = doc.SearchMaterial("REF_DROTEK-NL_LED") # Récupère le matériaux selon son nom.
    
    Obj_cloner[c4d.GV_OBJECT_OBJECT_ID] = cloner # Lie le cloner "DROTEK-NL au Node "cloner" crée précédement.
    Obj_Ref_Led[c4d.GV_OBJECT_OBJECT_ID] = Rerefence_LED
    

if __name__=='__main__':
    main()

@zipit Thank you !

Your answer is quite clear !
I try to use this as soon as possible and let you know about the result

@zipit Hello back !
I tried to use the code your wrote and actualy, linking ports is working but creating ports by iterating into them and pick them by order's number doesn't seems to work.

I had that kind of thing in the code I've sent (line 39, 40). But it doesn't work. I should have the first output of the "Mograph data" node (called "Données").

Capture d’écran 2021-01-07 à 22.53.29.png

Can you explain my mistake ?

About your code I still can't create ports on nodes... I tried to create all out and in ports of the nodes but nothing appened. I've commented your lines where you link the ports to focus on ports creation... Can you help me with this please ?

import c4d

def main():

    # Create a null object and add an Xpresso tag to it.
    null = c4d.BaseList2D(c4d.Onull)
    null[c4d.ID_BASELIST_NAME] = "ESSAIM - DROTEK-NL"
    xpresso_tag = c4d.BaseList2D(c4d.Texpresso)
    null.InsertTag(xpresso_tag)

    # Crée la texture de référence Led
    c4d.CallCommand(202586)
    Ref_Led = doc.GetFirstMaterial()
    Ref_Led[c4d.MATERIAL_USE_COLOR] = False
    Ref_Led[c4d.MATERIAL_USE_REFLECTION] = False
    Ref_Led[c4d.MATERIAL_USE_LUMINANCE] = True
    Ref_Led[c4d.ID_BASELIST_NAME] = "REF_DROTEK-NL_LED"


    # Get the node master and the root noode of that graphview.
    master = xpresso_tag.GetNodeMaster()
    root = master.GetRoot()

    # Crée de nouveaux nodes dans l'éditeur python et ouvre les ports nécessaires
    Hierarchie_node = master.CreateNode(root, c4d.ID_OPERATOR_HIERARCHY, x=0, y=10)
    Hierarchie_node[c4d.GV_HIERARCHY_START_ID] = "DL"
    Hierarchie_node[c4d.GV_HIERARCHY_ITERATION_ID] = "P"

    Indice_objets = master.CreateNode(master.GetRoot(),400001152,None,150,10)
    ListeDeLiens_node = master.CreateNode(root, c4d.ID_OPERATOR_LINK,  x=300, y=10)
    Obj_Essaim = master.CreateNode(root, c4d.ID_OPERATOR_OBJECT,  x=600, y=10)
    Obj_Essaim.AddPort(c4d.GV_PORT_INPUT, c4d.GV_OBJECT_OPERATOR_OBJECT_IN, flag = c4d.GV_PORT_FLAG_IS_VISIBLE)

    Obj_cloner = master.CreateNode(root, c4d.ID_OPERATOR_OBJECT,  x=100, y=100)
    Obj_cloner.AddPort(c4d.GV_PORT_OUTPUT, c4d.GV_OBJECT_OPERATOR_OBJECT_OUT, flag = c4d.GV_PORT_FLAG_IS_VISIBLE)
    

    mo_donnee = master.CreateNode(master.GetRoot(),1019010,None,250,100)
    # Get all in ports of the math node and select the first one.
    mo_donnee_out = mo_donnee.GetOutPorts()
    mo_donnee_out = mo_donnee_out[0] if mo_donnee_out else None

    Obj_Ref_Led = master.CreateNode(root, c4d.ID_OPERATOR_OBJECT,  x=600, y=100)
    Obj_Ref_Led.AddPort(c4d.GV_PORT_INPUT, c4d.GV_OBJECT_OPERATOR_OBJECT_IN, flag = c4d.GV_PORT_FLAG_IS_VISIBLE)

    # Start of code added by Ferdinand ---------------------------------------

    # Ports have two ways to be indexed: By an index (0, 1, 2, ...)
    # which just enumerates all ports and is dependent on the order in which
    # they have been created. But also by a construct with is similar to
    # DescIDs - (main id, sub id, user id).
    # 
    # The identifier you have been using for creating the ports, e.g., 
    # c4d.GV_OBJECT_OPERATOR_OBJECT_OUT, is stored in the main id. There can
    # technically be more than one port with a given main ID on a node, but
    # we will ignore this for now. In Python we have to iterate over all ports
    # to get a port by its main id.
    
    # Get the output port of the node containing it. I created an alias for
    # your name so that things are a bit more readable.
    outputNode, outputPort = Obj_cloner, None
    # Get over all ports until we find one with the main id in question.
    for port in outputNode.GetOutPorts():
            outputPort = port
            break

    # The same for the input port of the other node.
    outputNode, outputPort = Obj_Ref_Led, None
    for port in outputNode.GetOutPorts():
            outputPort = port
            break

    #Try to connect both ports.
   # if not (outputPort and inputPort and outputPort.Connect(inputPort)):
   #    msg = "Could not find ports or could not connect ports."
    #    raise RuntimeError(msg)

    # End of code added by Ferdinand ----------------------------------------

    # Add our object to the scene graph and let Cinema update.
    doc.InsertObject(null)
    c4d.EventAdd()
    
    #liaison des bons objets aux nodes créés
    
    # Définition des objets
    cloner = doc.SearchObject("DROTEK-NL") # Récupère l'objet selon son nom.
    Rerefence_LED = doc.SearchMaterial("REF_DROTEK-NL_LED") # Récupère le matériaux selon son nom.
    
    Obj_cloner[c4d.GV_OBJECT_OBJECT_ID] = cloner # Lie le cloner "DROTEK-NL au Node "cloner" crée précédement.
    Obj_Ref_Led[c4d.GV_OBJECT_OBJECT_ID] = Rerefence_LED
    

if __name__=='__main__':
    main()

Hi @Hugo-BATTISTELLA,

regarding your screenshot,

32e2926e-d518-4b9f-ab43-297b8b4e55ff-image.png

"it does not work" is usually not a very good starting point to pin point for us what is going wrong, and so I also do struggle here a bit with what you do mean by that. Because when I run/inspect that passage on R21.207, it works as I would expect it to work. So I would have to ask you to please clarify what you do mean by "not working".

    # Addding a Motion Graphics Data node.
    mo_donnee = master.CreateNode(master.GetRoot(),1019010,None,250,100)
    mo_donnee_out = mo_donnee.GetOutPorts()
    mo_donnee_out = mo_donnee_out[0] if mo_donnee_out else None
    # The name of the first out port is: Count
    print (mo_donnee_out.GetName(mo_donnee))

Will print:

Count

Regarding the addition of ports, I see three .AddPort calls in your code and the resulting nodes will contain these ports in R21.207 as shown in your screenshot in the previous posting. So I am also confused about what you mean by "I still can't create ports on nodes" and would have to ask you to also clarify this. Our forum guide has also section on how to ask "good" questions, the "Structure of a Question: Detailed Description" section might be useful for you. You should line out what you do expect to happen and what happens instead.

So I cannot really say anything helpful for now, sorry,
Ferdinand

Hi @Hugo-BATTISTELLA ,

without further questions or feedback, we will consider this thread as solved by Monday and flag it accordingly.

Cheers,
Ferdinand