Adding new Node¶
This page documents the essentials to make your own node for sverchok. We make several assumptions about your Python knowledge - an affinity for Python is a prerequisite. If you suck at Python, you will have a bad time trying to write nodes for sverchok (– a hard truth).
Tip
If you don’t know Python my advice to you is to read first all the shorter nodes, and take notes about parts you don’t understand. As you read more, the notes you took on previous nodes will be about techniques that re-occur in other nodes. Once you notice some repetition of the techniques you can class them, and start to associate the code with a procedure. Humans learn by extracting patterns from the chaos, but you have to see enough new material to let your brain do the pattern matching.
Also do any of the free python courses, and quit and move on from easy ones to harder ones.
To create a node:¶
Creation of new node can be split into next steps.
Make a scripted node to test the idea.
Show your node to us in an issue or create branch or fork of master in github. If it is a huge complex job we can make you collaborator.
Create a file with the node code according this page in appropriate folder
..sverchok/nodes/whatever_existing_category/your_file.py
Add node’s
bl_idname
tosverchok/index.md
file in an appropriate category.Make a pull request.
This page will describe from which pats the code of a new node should consist using simple example of a node. The whole code of the node can be downloaded from the link below.
Note
This documentation describe node structure which is used in most nodes in Sverchok. However there are other experimental approaches too. In the future more advanced approach may be born because current approach has certain disadvantages.
License¶
Use next strings in the top of the node file:
# This file is part of project Sverchok. It's copyrighted by the contributors
# recorded in the version control history of the file, available from
# its original location https://github.com/nortikin/sverchok/commit/master
#
# SPDX-License-Identifier: GPL3
# License-Filename: LICENSE
Imports¶
import bpy
from mathutils import Vector
from bpy.props import FloatProperty
from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import updateNode
You need to import
bpy
because we use always usebpy.types.Node
and often usebpy.props
The Sverchok imports are needed for the availability of common Sverchok functions.
The
updateNode
is the function we add to a property to trigger updates when a slider is adjusted.SverchCustomTreeNode
’s definition can be found in node_tree.py, it adds apoll
and several utility functions to the node class.
You are free to import any other useful module in that section.
Node Class¶
class SvScaleVectorNode(SverchCustomTreeNode, bpy.types.Node):
"""
Triggers: vector multiple scale
Tooltip: This node multiply vector and some value
Merely for illustration of node creation workflow
"""
bl_idname = 'SvScaleVectorNode' # should be add to `sverchok/index.md` file
bl_label = 'Name shown in menu'
bl_icon = 'GREASEPENCIL'
- Class name
A small (but significant) implementation detail of Sverchok is that name of the Node class should be identical to the
bl_idname
of the node class. This simplified a few things for development. This class name should start with a prefixSv
and contain only alphanumeric characters. Something likeSvMyFirstNode
would be fine. If you want to automatically make the node available upon startup then this classname must be added to theindex.md
file in the correct category.- Docstring
Triggers: This should be very short (two or three words, not much more) to be used in Ctrl-Space search menu.
Tooltip: Longer description to be present as a tooltip in UI.
More detailed description with technical information or historical notes goes after empty line. This is not shown anywhere in the UI.
- bl_idname
This is the unique identifier for a node type, like a post code for a home.
- bl_label
This is the name as it will appear in menus and on the node’s header when it’s first added to a node tree. Keep this short.
- bl_icon
This is used to display a node icon in the shift+A menu. There’s also a
sv_icon
implemented for custom icons (but for a different topic)
value: FloatProperty(name="My value", default=2, update=updateNode)
def draw_buttons(self, context, layout):
layout.prop(self, "value")
- Properties
Each node can have properties which can be displayed in the its UI and used in its code. Read more about properties.
- def draw_buttons
This is where we add any custom UI (sliders/buttons/enumerators), this is like the
draw
function of a panel. This function can be called many times a second so avoid doing intense computation inside it. This function is for nothing other than drawing the current state of the node, it isn’t for updating node properties. More information in the Blender documentation.
def sv_init(self, context):
self.inputs.new('SvVerticesSocket', "Vertices")
self.outputs.new('SvVerticesSocket', "Vertices")
- def sv_init
This function is used to setup the initial state of a node. This is where you add the default sockets and their properties. This is where we tell a socket to appear as a slider. To better get an idea of what it’s used for do a search for this function in the Sverchok repository.
def process(self):
# read input value
input_vertices = self.inputs["Vertices"].sv_get(default=[])
# vectorization code
output_vertices = []
for in_vert_list in input_vertices: # object level
out_vert_list = []
for v in in_vert_list: # value level
# perform the node function
out_vert_list.append((Vector(v) * self.value)[:])
output_vertices.append(out_vert_list)
# wright output value
self.outputs["Vertices"].sv_set(output_vertices)
- def process
This function is called whenever the node is told to update. It’s where we get the content of the input sockets, and set the output of the output sockets. This function is sometimes big..and sometimes merely a few lines - you should look at existing nodes to get a feel for what to put in there.
First line of the process method read data from the input socket with name Vertices. If the socket is not connected the input data will be an empty list. Expecting format of vertices is next:
[[[x, y, z], <- object 1, vector 1 [x, y, z]], <- object 1, vector 2 [[x, y, z], <- object 2, vector 1 [x, y, z]]] <- object 2, vector 2
To understand the Sverchok data structure read this tutorial.
Next step is unroll the vertices data structure, perform operation on single vertices and wrap the result back. Last string assign the result to output socket.
Register node class¶
def register():
bpy.utils.register_class(SvScaleVectorNode)
def unregister():
bpy.utils.unregister_class(SvScaleVectorNode)
All node classes should be registered so Blender could be able to use them.
register
function is called when the add-on is enabled,
unregister
when you hit f8 (or execute script.reload in Python
console editor) or disable Sverchok.
Warning
Fixing existing nodes is not the same as create new ones. Existing node can be used in some layouts and new changes should not break them. It’s possible to add new logic to an existing node but don’t do next:
Change
bl_idname
of a nodeRemove or rename sockets (use labels for socket renaming)
Adding new socket in between existing sockets. We prefer that you add sockets behind the last existing socket for either
self.inputs
orself.outputs
. This is the rule only if access to sockets is made by their indexes.There are other reserved property names see the bpy.types.Node baseclass in Blender docs and Sverchok’s custom node mixin class. (this is true and when new node is created)