1
$\begingroup$

I'm trying to write an Unreal addon to translate Geometry Nodes to Unreal's Geometry Scripting.

I need to know the order of multi-input sockets, like "join".

I tried:

elif (node.bl_idname == 'GeometryNodeJoinGeometry' and input.type == 'GEOMETRY'):
     for link in input.links:
        output_file.write(f"{link.from_node.name}\n")

But this yields the links in the order they were created, not the order (top to bottom) they are used.

Example, say I plug something (A) in to "Geometry" of join node, then I plug (B) into the same place, but above it. The join node will add A to B (not B to A). (This is important for indexing later) The links display A first... I need a way to display the order used, AKA B -> A.

$\endgroup$

1 Answer 1

1
$\begingroup$

I did not find a way to access the input indices with the API of a multi input. Which makes sense somehow... if one inspects some geometry nodes, multi inputs will always work correctly with unordered inputs (Check for example the Mesh Boolean modes and how the inputs vary).

However, its possible. You can make a Node Group (right-click on node and Make Group). Blender will relink now all the in/outputs and they will show the order! In the screenshot i tried to replicate your problem. I added a cube, a sphere and a cone (in that order) to a Join Geometry node, but i placed the sphere noodle above the cube and the cone noodle above the sphere, thus we have

  • creation order: cube, sphere, cone
  • but index order: cone, sphere, cube

enter image description here

I verified with a little hacky script that the index order can indeed be retrieved (please adapt the script to your needs).

import bpy


test = bpy.data.objects['Test']

nodes = test.modifiers['GeometryNodes'].node_group.nodes

for node in nodes:
    if node.bl_idname == 'GeometryNodeJoinGeometry':
        
        # shows the inputs order when they were created (not how they _are_ ordered)
        for input in node.inputs:
            for i, link in enumerate(input.links):
                print('join input link', i, link.from_node.name)

        node.select = True
        
        # make group in correct context
        # source: https://blender.stackexchange.com/questions/196219/what-is-a-python-command-to-create-a-node-group-or-shader-node-tree-from-the-nod
        try:
            initial_area_type = bpy.context.area.type
            bpy.context.area.type = 'NODE_EDITOR'
            bpy.context.area.ui_type = 'GeometryNodeTree'
            bpy.ops.wm.redraw_timer(type='DRAW_WIN', iterations=1)
            
            bpy.ops.node.group_make()
            bpy.ops.node.group_edit(exit=True)
            
            # note: to do the opposite
            #bpy.ops.node.group_ungroup()
            
        except Exception as e:
            print(e)
        finally:
            bpy.context.area.type = initial_area_type
    
        # quick hack to get the created node group
        group = [ n for n in nodes if n.select ][0]

        # shows the inputs how they are ordered
        for i, input in enumerate(group.inputs):
            for link in input.links:
                print('group input link:', i, link.from_node.name)

which prints:

join input link: 0 Cube
join input link: 1 UV Sphere
join input link: 2 Cone
group input link: 0 Cone
group input link: 1 UV Sphere
group input link: 2 Cube

Now you have the indices mapped through the link references.

A warning: i dont know if you are allowed to change the geometry nodes setup by making groups, but if you are, you should already be fine. If not and you need to ungroup the nodes again after index retrieval to restore the original layout, be aware that Blender changes the index order of the input noodles! This is because it seems to create a new node within the group (throwing away the one which became a group) and relinks everything. But on ungrouping, the creation order is taken again, not the indexed order of the group node. In that case, you would have to go an extra mile and remember all in/outputs of that node to restore it how it was originally.

$\endgroup$
2
  • $\begingroup$ "Undo" leaves everything back in the correct order. You know the python command for "Undo"? $\endgroup$
    – Mike
    Commented Jul 12, 2023 at 1:24
  • 1
    $\begingroup$ Ah yes, good idea. blender.stackexchange.com/questions/110987/… $\endgroup$
    – taiyo
    Commented Jul 12, 2023 at 5:30

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .