How to make a custom NodeSocket class display as multi-input?

Hello. I am working on a custom nodes addon, and I have a node socket definition:

class MultiSocket(NodeSocket):
    '''Multi Socket Example'''
    bl_idname = 'MultiSocket'
    bl_label = "Multi Socket"
    color = (1,1,1,1)
    def __init__(self):
        self.link_limit=4095 # the max
    def draw_color(self, context, node):
        return self.color
    def draw(self, context, layout, node, text):
        layout.label(text=text)

Setting self.link_limit higher than 0 sets self.is_multi_input to True, and it will even accept up to the maximum number of connections… but it doesn’t change the appearance of the socket. Is this a bug?

I spent some time messing with the Join Geometry node to see what it is like… and it’s confusing. It doesn’t seem to have any special properties, and its link_limit is 1, even though you can just keep on adding links to it forever.

I would like to use the multi-input node feature for my addon, and I can do it without the nicer UI, but I would like to make it look pretty. Any help would be appreciated. Thanks!

For now you can’t…
is_multi_input is defined as read only, so you cannot change it from Python.

I don’t know why this choice and maybe someone could explain it why this was defined as readonly.

But to change this behaviour, it’s just a matter of not removing its PROP_EDITABLE flag (by removing RNA_def_property_clear_flag(prop, PROP_EDITABLE); from the rna_nodetree.c (line 11022).

PS: In fact, I don’t really understand the reason of this property at all… is_multi_input should be allways true whenever link_limits<>1.

Yes, this is correct. But it doesn’t change how it displays :confounded:
As for the reason: It is helpful to be able to know whether the socket is multi-input or not when writing functions to parse the node tree. I assume that’s all it is intended for, to inform the user if the node will potentially ruin his code that assumes each node only has one link for each input socket.

Having a flag operation (&& SOCK_MULTI_INPUT) or a compare operation (link_limits != 1) wouldn’t result in a very different byte code. Parsing the nodetree would just be done for updating the nodetree and not the Editor draw calls, and it would be required anytime your engine has to deal with a node with multiple inputs.

Anyway, I commited a patch for this. Perhaps there are some other changes that would be require, like removing the flag for all other sockets that aren’t supposed to have multiple inputs. :confused:

1 Like

Oh, I meant in addon code – every Python addon that deals with nodes has freedom to implement node-parsing in whatever way they see fit, so more info is better.
Could you post a link to the patch so I can try it out? Thanks.

sure: âš™ D16011 Make is_multi_input editable for custom nodes
is nothing more than what i wrote in the first post… :slight_smile:

1 Like

socket_still_ugly
Unfortunately it doesn’t seem to affect the socket display. I don’t think is_multi_input was a problem before, either, since it seemed to be setting itself automatically based on the value of link_limit. Well, thank you either way :smiley:
:thinking: I wonder if any of the devs of Geometry Nodes are around? It seems that the Join Geometry node has some kind of hardcoded special treatment?

You still need to change it to true in your code…
in your socket code add this:

  def __init__(self):
    self.is_multi_input=True
    self.link_limits = 0

I’m afraid it won’t display properly no matter how is_multi_input is set. It is set correctly automatically, but even if I set it manually using the patch, it doesn’t fix the display. I think there is a bug. Maybe I should open a bug report, since I can’t find any other settings to try. I’m starting to think it’s just hardcoded for the Join Geometry Node, now.

It’s working here based on the template…

1 Like

Then I must have found a bug!? :exploding_head:
I will try to copy this exactly… thank you for your time @Secrop . Did it ever look OK before the patch when you tried the same thing? The is_multi_input line will do nothing in un-patched Blender, since it is read-only, so the same code should work. I am curious about what that will look like.

Without the patch, Blender would complain that the property is readonly.
It is set to True in the nodes code, but it’s not available from python unless you get your hand dirty with ctypes.

IT WORKS
OK, I am an idiot. Before you authored the patch, I was trying to do this:

is_multi_input:bpy.props.BoolProperty(default=True)

and I was shadowing the class property… lol. Sorry about that. I forgot that I had tried that so I had left it in my test code.

OK. Now I am very confused. In unpatched Blender, is_multi_input will evaluate to True if the node has link_limit>0, but it will not display properly at all. In fact, it will only display properly if is_multi_input is set explicitly using your patch. Link_limit doesn’t seem to do anything if is_multi_input is set True using the patch.

I might need to patch Blender for my addon at some point, anyway, so it’s OK that this relies on a patch…

Anyhow, THANK YOU @Secrop :confetti_ball: :tada: :piñata: :partying_face: for the help. It looks good now :slight_smile:

That’s because the draw calls are using the SOCK_MULTI_INPUT flag… not the link_limit value. :slight_smile:
Glad it helped.

1 Like