I'm developing an add-on that uses a custom node tree. I want to be able to set a link between nodes as being valid or not:
NodeLink
has the property is_valid
which controls also how it's drawn (as pictured above). I want to use this value, but something keeps changing it to True
any time the node tree updates.
Node
's have the insert_link(link)
method which you can override. It seems to be the first thing called when a new link is made. This would be an ideal time to validate the link and set the property.
After insert_link(link)
returns, the NodeTree.update()
method is called on the parent NodeTree
which you can also override. What ever value you assigned to NodeLink.is_valid
is still the same at this point.
I don't think any other functions are called inside the custom tree after that? But once the UI updates the NodeLink.is_valid
value has returned to being True
regardless of what it was set to.
The same thing happens if you change the value from the python console. It will draw in the red color and be False
if you check the value. But as soon as any new link or update is made to the tree, it goes back to being True
again.
Something else must be determining if a link is valid each time it updates? But I cannot find anything in the documentation that says what this is or how to interact with it??? But, it seems like this should be something that can be done given there is a built-in value for it and the UI checks that value when drawing it...
So how do you validate links in a custom node tree?
# First function called in custom tree when a link is made
def Node.insert_link(link):
# Validate the link
link.is_valid = False
# Called after insert_link is finished
def NodeTree.update():
# Link valid value is still set from above
link.is_valid
False
# After update link valid value has been set to True
link.is_valid
True
I'm currently working around it with a custom bool property, which essentially just duplicates the existing property. Which works fine for preventing problems with invalid connections, but the state of the link isn't displayed in the UI.
I suppose an acceptable solution would be a way of making the link draw in red using my custom property. It just seems really silly when the property already exists and does the thing I want, but something keeps on changing it on me.
ntree_validate_links(bNodeTree *ntree)
in the C code is the thing that causes it to change and is called as essentially the last thing when updating a node tree. It does three things, first is sets the flag to valid, second it checks for a cyclic link and will set the flag to invalid if found. Lastly it checks for ntree->typeinfo->validate_link
which I'm assuming is a function pointer and calls that to set the flag.
I'm not seeing anything in the RNA node stuff to interact with it though.
insert_link
you would usenode_tree.requested_links.add()
to mark links you would like to add which you can then actually add to the node tree inupdate
. Assuming that you're usingself.links.new()
in update that would be a different link object than ininsert_link()
. That is the idea that I've got from a quick glance over existing code, e.g. github.com/LuxCoreRender/BlendLuxCore/blob/refactor/… $\endgroup$is_valid
, the choice of the user shouldn't be ignored. If I'm not mistaken you should be able to follow the described approach and setis_valid
on the link created from therequested_link
inupdate
. I'll look into it if I got a bit of time this weekend. $\endgroup$is_valid
will still get reset on future updates, but I will try it out and see if that's the case. $\endgroup$