[Bf-committers] Node API

Lukas Tönne lukas.toenne at googlemail.com
Thu Dec 29 11:09:03 CET 2011


We have been talking about creating a usable node API, to allow
external engines and plugins make use of the node editor. I have been
working on a basic implementation of dynamically registered node types
for the particle nodes system. This can be used as a basis for further
work, by stripping away the new particles (should be easy and
painless). Particle nodes need more work to be ready for trunk, but
the general node API can go in as a separate project.

Let me try to break down the whole idea into a set of goals and
implementation notes:

* Node types, tree types and socket types should be registered
_dynamically_, i.e. they are registered/unregistered by subsystems
and/or plugins at runtime.

   We have a good example for this with python-defined menu and panel
types for the UI. These use a C typeinfo struct, which contains all
static information, in particular function pointers for dynamic
dispatch ("virtual" functions). These types can be registered from
python scripts, providing a simple way to extend the UI.
   Node types can use the same RNA framework to allow node type
definition from Python. However, all existing node subsystems use C or
C++ language, so it would be nice to have an actual API for these too.
   The Cycles render engine already uses C++ node class definitions,
generated from the internal RNA information, to convert node data from
the editor into the internal shader graph. At this point, however, the
node types are still all defined as part of the blender core code,
instead of being generated as part of the Cycles external system. It
would be good to have a way of registering node implementations from
C/C++ the way we can do in bpy.

* Nodes need a way to store custom data

   Beside the input parameters that are stored along node sockets,
some nodes need a couple of additional variables. Sometimes these are
pointers to scene data, sometimes constant settings, sometimes complex
data for curves or mapping. This data is stored in the bNode->storage
pointer and requires explicit code in readfile/writefile for correct
   For dynamic node types there needs to be a way of storing such
custom data without having to modify core C code. In the case of
simple button values the ID property system would be sufficient as it
is now. Nodes can store custom variables like objects or armature
bones this way. But ID properties do not work for pointers and for
complex data structs, like curves or color ramps. With links to shared
data comes the need to do proper user counting and unlinking. Storing
complex structs would require to either break them down into primitive
(float/int/char) parts and store with existing data types, or to
implement a general allocation/freeing mechanism as well as an API for
reading/writing blend files.

* Node typeinfo needs to be extended for subsystems

   Each node system (shader, compositor, textures, particles, ...) has
its own way of converting an editor node into a usable internal
component. When node types are registered in a truly dynamic way,
these subsystems also shouldn't have any static node type definitions.
In turn, this means they need to extend the core API, so that
user-defined node types can actually define their own execution code.
For Cycles shader nodes this code could be written in C/C++ or as
OpenCL/CUDA kernel code. Compositor nodes can use C++ or OpenCL as
well. The details are up to the respective project maintainers.

For overview, here's a list of things that imo should be in the node API:
- subsystem/tree type (not necessarily the same!): what kind of node is this
- basic info: type identifier, ui name & description, icon, node
category ("class"/submenu)
- input/output socket templates
- custom data (see above), including RNA subclass definition
- drawing code for custom data on the node or side bar details panel
- update functions for various changes:
  * node settings (buttons or custom data) have changed
  * node has been linked/unlinked
  * shared internal data changed (e.g. node group tree, render layers, texture)
- error reports interface, for debugging purposes (including "syntax"
errors from invalid links)
- preview output
- muting details: which inputs are passed on unchanged (optional, has
default implementation)

Let me know what you think.

More information about the Bf-committers mailing list