[Bf-committers] Python Access to some properties of nodes

Lukas Tönne lukas.toenne at gmail.com
Sat Dec 22 15:31:21 CET 2012


I think this should be treated as a design issue and not worry too
much about performance. You'd need some really creepy workflow or bad
scripting to generate more than a few hundred nodes and links max. So
for operators and other functions which are executed once, the only
relevant issue is to avoid bad algorithms: Nested "for socket, for
link" loops are essentially O(n^2), which is fine for these purposes.
Which way you order them doesn't really matter.

Adding more nested loops should be avoided though, if that was really
needed you could rather add nodes/sockets/links in a dictionary to
allow O(1) lookups.

On Sat, Dec 22, 2012 at 11:39 AM, Bartek Skorupa (priv)
<bartekskorupa at bartekskorupa.com> wrote:
> Thank you very much Lukas.
> Access to NodeSocket.links may be very helpful and if I had this earlier, I'd probably design my code in: http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Nodes/Nodes_Efficiency_Tools a bit differently.
> I am especially talking about the operator: NODE_OT_switches_to_outputs.
>
> However now after your explanation I begun to wonder if it's not just "hiding" the process from the coder.
> Let me explain:
> In my code I wanted to do some operation depending on links connected to outputs that I specified. So in fact I am referring to NodeSocket.links.
> Because I didn't have direct access to it, I knew that I have to iterate through all of the links.
> Iterating through all links for all of the outputs seemed not right for me, because I assumed that list of links will in most cases be longer than list of my "selected" outputs.
> Therefore I wrapped loops the other way, i.e have just one loop "for links" and analyze all my sockets inside this loop.
>
> # code A
> for link:
>     for socket:
> "do the magic"
>
>
> instead of
>
> # code B
> for socket:
>     for link
> "do the magic"
>
> This was more difficult in my case, but doable. If I had the access to NodeSocket.links, I'd probably not think about it and would simply do:
>
> # code C
> for socket:
>    for socket.links
> "do the magic"
>
> Easy, but isn't it so that accessing NodeSocket.links does iteration through ALL links anyway under the hood?
>
> The question is:
> >From performance point of view: doesn't code B require exactly the same amount of computing as code C?
> Or maybe because NodeSocket.links is shorter than all links - it's faster.
> Does it even matter? Maybe I try to fix the issue that doesn't exist?
>
>
>
> Bartek Skorupa
>
> www.bartekskorupa.com
>
> On 22 gru 2012, at 08:21, Lukas Tönne <lukas.toenne at gmail.com> wrote:
>
>> IMHO storing the links in a separate list like we do now is one of the
>> more well-designed code parts ;)
>>
>> It may be slightly inconvenient if you want to get a list of links for
>> a specific socket, but it has several advantages over storing lists of
>> links in each socket or node:
>>
>> * If each socket stores its own link list that means a lot more
>> overhead for all those lists. Now we have exactly 1 list.
>> * You only ever need a single loop. If each socket has a list of
>> links, to walk over all links in a node tree (e.g. for drawing or the
>> cut operator) you need to walk over all nodes and then all sockets and
>> then all links ...
>> * Storing a link in sockets is ambiguous, you could store the link
>> either in the output or input socket. If you store it on one side only
>> you have to loop over everything again to find links of the other
>> side. If you store it in both you have to keep them in sync, which is
>> error prone and leads to redundant data.
>> * In terms of time complexity having to filter the list of all links
>> vs. a reduced list of socket links does not make much difference, both
>> are essentially O(N+M), where N is number of nodes, M is number of
>> links. In general though the node DNA should not be judged by
>> performance criteria too much, if you need to access the node
>> structure millions of times (e.g. in rendering) you should create an
>> optimized structure with arrays instead of linked lists and can store
>> links in whatever way is needed for fast access. All modern node
>> systems in Blender (cycles, compositor) do this.
>>
>> Bottom line: the single links list is the best all-round solution for
>> the purpose of storing data in .blend files and user manipulation.
>>
>> On Sat, Dec 22, 2012 at 2:49 AM, Dan Eicher <dan at trollwerks.org> wrote:
>>> On Fri, Dec 21, 2012 at 4:52 AM, Lukas Tönne <lukas.toenne at gmail.com> wrote:
>>>
>>>> # List of connected (Node, NodeSocket) pairs for 'socket':
>>>> input_sockets = [(link.from_node, link.from_socket) for link in
>>>> socket.id_data.links if link.to_socket == socket]
>>>> output_sockets = [(link.to_node, link.to_socket) for link in
>>>> socket.id_data.links if link.from_socket == socket]
>>>>
>>>
>>> Somewhat off topic...
>>>
>>> Looking at this code I'm starting to think that maybe it was a mistake to
>>> expose Node.links instead of having it as a property on the sockets
>>> themselves, it would make the code a lot clearer and it isn't like you can
>>> really do anything with the links independent of the sockets they're
>>> assigned to.
>>>
>>> It may even be better to totally abstract away the NodeLinks too, maybe
>>> socket.links just return a list of (Node, NodeSocket) tuples -- have to
>>> think on this a bit more though since it would probably require
>>> sub-classing NodeSocket into NodeInputSocket, NodeOutputSocket so you'd
>>> know if the returned node/socket pair was an input or output for the node.
>>>
>>> Would also clean up node.links.new(add?) a bunch.
>>>
>>> Dan
>>> _______________________________________________
>>> Bf-committers mailing list
>>> Bf-committers at blender.org
>>> http://lists.blender.org/mailman/listinfo/bf-committers
>> _______________________________________________
>> Bf-committers mailing list
>> Bf-committers at blender.org
>> http://lists.blender.org/mailman/listinfo/bf-committers
>
> _______________________________________________
> Bf-committers mailing list
> Bf-committers at blender.org
> http://lists.blender.org/mailman/listinfo/bf-committers


More information about the Bf-committers mailing list