10
$\begingroup$

I'm developing a custom NodeTree using the PyNodes API (on Blender 2.70) for scientific analysis and am having trouble choosing the best way to transfer data between nodes via sockets.

Right now I can think of two options, neither of which seem satisfactory:

  • Accessing input socket links from the node itself on each update, for which purpose I'd have to create a dummy "input socket" with no associated properties which seems a little hacky (although I've seen similar dummy input sockets used in blendgraph)
  • Traversing the NodeTree links list, copying input socket data to their respective output sockets and updating nodes sequentially

Is there a specific method for transferring data between sockets that the API is intended for? I haven't managed to find any definitive examples so far.

$\endgroup$

3 Answers 3

8
$\begingroup$

The way I have found to get input values is

if self.inputs['inY'].is_linked and self.inputs['inY'].links[0].is_valid:
    iny = self.inputs['inY'].links[0].from_socket.default_value
else:
    iny = self.inputs['inY'].default_value

Add calculations in the middle here then pass on output values -

self.outputs['result'].default_value = res

The key point being read inputs from a connecting node socket default value and write to our output default value for other nodes to read.

You don't need dummy sockets to store values, sockets are for connecting other nodes to pass on values. You can use property definitions to add properties to your nodes. These can be shown on your node in it's draw() without having input connections available.

If your concern is that updates don't just happen, then you've found that pynodes don't just automatically update yet. The solution is manual updates, sverchok adds a panel with update buttons and has a 'Bake' button on some nodes to do the updating, it also implements a caching system. Another consideration is to register a function as a handler for frame changes so that animations aren't an issue.

def handler_node_update(scene):
    for n in node_tree.nodes:
        n.update()

bpy.app.handlers.frame_change_post.append(handler_node_update)

There is also a nodes internal_links property to consider, it's for "Internal input-to-output connections for muting". It is a collection of NodeLinks and I guess we use something like -

self.internal_links[0].from_node = self
self.internal_links[0].from_socket = self.input['inY']
self.internal_links[0].to_node = self
self.internal_links[0].to_socket = self.outputs['result']

I have got this far from this pynodes tutorial and looking through some of the sverchok source (luxblend is another project using pynodes) with this blender wiki page about the only other helpful source of info so far.

$\endgroup$
2
  • $\begingroup$ there is no way for custom pynodes to get evaluated in cycles ? $\endgroup$
    – Chebhou
    May 10, 2015 at 10:07
  • $\begingroup$ No not yet(I haven't checked for a while), they were implemented to be used as a complete custom nodetree, support for integrating them with any built-in nodes has not been implemented. You can add nodes that can be added in cycles materials but they don't get updated properly. $\endgroup$
    – sambler
    May 10, 2015 at 10:19
3
$\begingroup$

as developer of sverchok recommend from beginning to separate UI and data - make data tree operated as combination of definitions respecting node tree. we made this mistake and now have to separate ui from data it is hard

$\endgroup$
3
  • 1
    $\begingroup$ I know old thread but... Could you explain this a bit more? $\endgroup$ May 24, 2016 at 17:40
  • $\begingroup$ Just started writing PyNodes and remembered your comment. Do you still believe this was better than storing data in the nodes? $\endgroup$
    – VSB
    Nov 25, 2018 at 3:41
  • $\begingroup$ Yes, separate data and ui. just build data tree. Thank to Linus Yng, he implemented node tree exploiting mechanism for Sv $\endgroup$
    – nikitron
    Feb 13, 2019 at 7:46
3
$\begingroup$

My Solution is so far (doing something with the inputs and push them to the output/next Node and update):

    def update(self):
    # Eingänge aufsummieren
    self.wertab=0.0
    for i in self.inputs:
        self.wertab=self.wertab+i.default_value

   if self.outputs[0].is_linked:
       for l in self.outputs[0].links:
            l.to_socket.default_value=self.wertab
            l.to_node.update()
$\endgroup$

You must log in to answer this question.

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