Tools for Cycles PyNodes

The Addon serves mainly as a support for creating and mantaining scripted nodes. I’m making some nodes too, to show how the support works.
There is a minimal operator that converts a nodegroup into a python node. There isn’t any button for this operator and it’s only accessible through the search menu ( with the nodegroup selected, press [SPACEBAR] and search for ‘Convert Selected NodeGroup to PyNode’). The only options for now, are giving names to the bl_name, and the bl_label.

The converter’s purpose is to simplify the creation of python nodes, specially to define the reconstruction of the nodegroup in python, with all nodes, inputs, outputs and links. It will convert most of the nodegroups without any problem, but it’s not optimized and is up to the user to edit the generated code. There are also some things to consider prior to convert a nodegroup:

  • remove all nodes that’s not being used. (not important but makes less code and more readability)
  • remove all Frames, and any Reroute that isn’t strictly necessary.(same as above)
  • the converter isn’t recursive, so no nodegroups inside nodegroups (if it’s a common function, maybe convert it to a node, else just ungroup it on your nodegroup)
  • give good names to the most important nodes, so you can identify them when editing the code.

It doesn’t store the properties of the following nodes: SkyTexture, ImageTexture, EnviromentTexture, Mapping, Attribute, and perhaps one or two more. These properties are supposed to be controlled by the python node, and it’s up to the node to create an interface to control the node inside the nodegroup.
For example, if you need an Image texture inside the nodegroup, you can only expose the filepath by having a StringProperty to store the Path, a function to update the inside node whenever the string changes, and a layout.template_image() or similar in the draw_buttons() to give an interface to the path property. The Converter won’t do this, because it’s up to the creator to decide wich interface to have, if any.

If you want or you’re having troubles, send me the nodegroup you want to convert, and i’ll try to find some time to do the conversion.

duplicated post

My problem stems from the fact that I don’t really understand any of that at its root level. What’s the difference between a scripted node, a python node, and the nodes we use to built shader trees? I don’t even know if there is a difference to be honest.

Are you talking here about the addon or the nodes built with the addon?

That’s a very kind offer. Thank you. I’d hate for either of us to go to any trouble if the end product isn’t what I was assuming it would be. And since I’m still unsure if I know what your addon does, if I outline what I had in mind, maybe you can tell me whether or not if it’s even possible.

I have several PBR shader trees I’ve built, amalgams of techniques from tutorials by Blender Guru, CynicatPro, the CG Cookie guys, and a few others. At least one of my PBR shader trees has a group within a group. In fact, I think one of them is three groups deep.

What I assumed your addon could do is convert these shader trees into self-contained entities that I could make available from the Add menu in any future project without having to append them, sort of turn them into addons in their own right.

And after reading this:

it sounds like it will.

But after reading this:

I get the idea I need to have a solid understanding of Python before I can use it to its full potential.

I’m also starting to get the idea that node-tree conversion is more or less a by-product of your addon and I’m left wondering what its higher calling is (so to speak). :slight_smile:

Builtin nodes are hardcoded in Blender. They can do whatever you code on them, and you write them to use the Kernel.
Nodegroups and PythonNodes just use the SVM. The mechanisms inside a python node, is very similar to the nodegroup, but you have more control of it’s functionality and interface, through python.

Are you talking here about the addon or the nodes built with the addon?

Just for the converter operator. As soon you finish to convert your node will automatically appear in the add menu, at the ‘Custom Nodes’ category (and this can be changed in the script with the draw_menu function).

That’s a very kind offer. Thank you. I’d hate for either of us to go to any trouble if the end product isn’t what I was assuming it would be. And since I’m still unsure if I know what your addon does, if I outline what I had in mind, maybe you can tell me whether or not if it’s even possible.

If the Nodegroup is possible, the scripted node is also possible. A python node works the same as a nodegroup. The only difference, is that when you create an instance of a nodegroup, Blender uses a class that wraps the nodegroup and automatically draws the interface and deals with socket updates, etc. With python nodes you define this class on your own. The converter will just do more or less the same as the original wrapper, but you can edit the resulting file.

What I assumed your addon could do is convert these shader trees into self-contained entities that I could make available from the Add menu in any future project without having to append them, sort of turn them into addons in their own right.

The resulting nodes, will be available through the interface (the add menu) just like any ordinary node, but they are not stored in the Blender file until you use them. You won’t need to append anything, but you’ll need to have the addon, because the nodes created by the converter don’t have any register functions (the addon does that).

I get the idea I need to have a solid understanding of Python before I can use it to its full potential.

There’s no need of a solid knowledge of python. The converted node, will work Ok most of the times. Only if you have some of those nodes I talked on my previous post, you’ll need to add the properties by hand.
This can be done quite easilly, by finding the addNode(‘nodetype’, {‘name’:‘nodename’, etc}), and add the properties to that dictionary.
A more illustrative example. If you have a Mapping node and you want to set the default rotation, you need to change the addNode call to look like this: addNode(‘ShaderNodeMapping’, {‘name’:‘MyMapping’, ‘rotation’:Euler((0.0,0.0,1.0), ‘XYZ’)}).
For changing it at runtime, you can use value_set(self.nodes[‘MyMapping’].rotation, Euler((0.0,0.0,1.0), ‘XYZ’)).

I’m also starting to get the idea that node-tree conversion is more or less a by-product of your addon and I’m left wondering what its higher calling is (so to speak). :slight_smile:

You can script nodes by hand, without any use of this addon. It will be very boring to do it, you’ll need to write the node, by adding all nodes inside, adding all sockets, adding all links, setting all default_values, all nodes operations and properties, etc. Then you need to write the functions to create and register new panels and menus to expose the node in the interface by digging the guts out of the nodeitems_utils module… This addon just makes things a much easier.

Just another node added to the collection! :smiley:

Loop node

All you need to have is a nodegroup in your material, with an input with the name ‘iterator’, and for passing values from one step to the other, the nodegroup has to have an input and an output with the same name.

Here’s an example
Nodegroup to be used as a step in the loop:


And the node in usage with the respective result (here simple voronoi clouds)


it needs some improvements to deal with linked sockets (changing the nodegroup will remove all previous links to the node).

This beyond awesome! What are the drawbacks and limitations of using this? VRam usage basically or is there a limit of materials?

I don’t know the limitations, most of my tests worked, thought I haven’t pushed too far (the loop node worked ok for up to 60 iterations, which is pretty unusual and unnecessary)… Of course, very complex nodes will be a bit slower than if they were coded in the kernel, and some good design is required to make them fast.
I don’t know Vram usage also, as I don’t use GPU and there are not so many testers around, but the SVM is the one responsible for this.

Ok I’ll just have to test it in a real life scenario. But if everything else fails one can always bake these procedurals to a texture.

Hi Secrop - Is there anything I need to do to make the loop node activate (it’s not green as in your screenshot).

I have re-created your two node setups exactly - and selected the correct nodegroup in the loop node dropdown - however all I get is a white box - i’m not seeing the iterated voronoi texture.


It should work as soon as you choose the nodegroup… (the node’s color on the screenshot was just highlight it, as it uses by default the theme color)

Here’s an example file:
http://pasteall.org/blend/index.php?id=46536

Hmm weird. Your file does work - until I change something (like number of iterations) - then it just goes back to white as above - and never comes back, even if I change the number of iterations back to 8.

ok… it’s a bug. can you send me every steps to reproduce the failure? or the output on the console? and also your version number. :slight_smile:

Version 2.78c

  • Open file
  • Put 3d view into “rendered” mode
  • Cube renderes with iterated voronoi texture
  • Go to node editor
  • Change number of iterations on the loopnode (to 7 or 9 - doesnt matter)
  • Cube turns white

Console output when I change the number of iterations

Traceback (most recent call last):
File “C:\Users\Lee\AppData\Roaming\Blender Foundation\Blender\2.78\scripts\addons\ShaderNodesExtra-master\Nodes\ShaderNodeLoop.py”, line 72, in update_it
self.nodetree_setup()
File “C:\Users\Lee\AppData\Roaming\Blender Foundation\Blender\2.78\scripts\addons\ShaderNodesExtra-master\Nodes\ShaderNodeLoop.py”, line 49, in nodetree_setup
previousnode=self.node_tree.nodes[‘Group Input’]
KeyError: ‘bpy_prop_collection[key]: key “Group Input” not found’
File “C:\Users\Lee\AppData\Roaming\Blender Foundation\Blender\2.78\scripts\addons\ShaderNodesExtra-master\Nodes\ShaderNodeLoop.py”, line 71, in update_it

ohhh… uploaded the wrong file. It’s now fixed. :o
I also limited the iterations to 63 max (which is probably already too big). This way I force good use.

Thanks - seems to be working now. I’ll have to have a good play with this and see if I can figure it out.

Just a quick question - I have been playing with this node and am getting to grips with it, but should it work with shader outputs?

I was trying to create an iterative dispersion glass and I can get the colour of the glass to change with each increase in iteration - but the shader outputs don’t seem to want to add together with each iteration - so I basically go from red glass, to green glass, to blue, - rather than ending up with a dispersive white glass as you would if you created and added the 3 primary coloured nodes manually.

Am I correct in thinking that the output from the group should automatically feed in as the input to the group during the next iteration - or am I misinterpreting it?

This is a screenshot of what I was going for:


That’s pretty much the way it works (by either bypassing the initial variable to the next iterations, or deliver a changed value), but there’s one thing you missed: the names of the outputs must be the same to the names of the inputs. Any unique name, input or output, will only appear in the node interface. (and if you have more sockets with the same name, only the first will be connected).

In your case, you can either change the ‘BSDF’ name to ‘Shader’, or vice versa.

Brilliant - it works…and it’s marginally faster than adding three separate shaders (2500 samples takes 2:27 looping, or 2:37 adding three shaders)

It looks like looping a single shader has a performance advantage over adding three separate ones - around 6-7% by my reckoning.

The images are very slightly different using the two methods…but not by much.


:smiley: glad to ear!

really don’t know why it’s faster… :o

Maybe each shader you add has a performance overhead - whereas reusing the same one avoids that. All I know is - it’s faster - which with dispersion glass is no bad thing.

Nice work :smiley:

edit: I tweaked the settings and re-rendered to give a more realistic look with a more accurate IOR. Performance gain wasn’t as high this time ~0.5-1% - but still slightly faster using the loop node.