The Essence Of Animation Nodes

Scripts

Prerequisites:

The following is a list of all prerequisites in order to make the most out of the following tutorial.

In this tutorial, I am going to introduce you to script nodes in Animation Nodes and Blender Python API.

You don’t have to know python in order to understand this tutorial, however, it is recommended that you know the basics like I do.

Script Node

Animation Nodes contains a lot of nodes, some nodes process data like Math nodes and some others communicates with blender like Object Transform Output which tells blender objects are located. More sophisticated node trees can be created using those fundamental nodes that AN provides.

However, you may encounter a situation where you need a feature(node) that is not in Animation Nodes already and you can’t create it using provided nodes (Such situations is usually when you try to communicate with blender), you have couple of options:

Example 6.1

Example1

Demonstration

Just like any subprogram, script node has inputs and outputs which are defined on the same node. When I add an input, a variable is created with its value, so in this example, it is like we wrote this script:


x= 1
y= 2

Consequently, input names follow the same rules as Python, that is, the name should start with a letter or an underscore, it can’t start with numbers or you will get a fatal error. You can’t name it like python operators, for instance, it can’t be named if or while.

The script node will then return the values of the variable result which I defined as x+y, so the script basically add two numbers and return the result.

Python API

There exist a python API (Application Programming Interface) that lets you communicate with blender, it can be found here. To be able to understand the API, lets open the console and see what the bpy module contains. Using auto complete, blender lists possible choices. bpy includes:


bpy.
	app
	context
	data
	ops
	path
	props
	types
	utils

When it comes to Animation Nodes, we are only interested in data and may be context for some limited cases:

Having chosen data, lets see what it contains:


py.data.
	actions
	armatures
	brushes
	cameras
	curves
	fonts
	grease_pencil
	groups
	images
	objects
	...

As you may see, we have all the data types, but we are mostly interested in objects as it include all the data of our objects, objects lists all objects in the blend file, you can choose or sample an object by its name or index as follows:


bpy.data.objects[0]
bpy.data.objects['Cube']

Both of them sample the first object which is named “Cube”. The object includes:


bpy.data.objects['Cube'].
	color
	active_material
	constraints
	dimensions
	location
	matrix_world
	...

And if I want to sample the color of the object and store it in a variable, I could just write the following code:


color = bpy.data.objects['Cube'].color
#Since "color" include RGBA channels:
color[0]   #Red value
color[1]   #Green value
color[2]   #Blue value
color[3]   #Alpha value

You probably get it by now, to access some data, we carefully follow its location in the data section of the API.

Example 6.2

Example2

Demonstration

Scripts node are not always needed, if your script can be written inline, then use the expression node directly.

Note!

Notice that the output of the node is not actually a color data type, so I disabled auto type correction and output it as if it was a color after the output was converted to a color. This is a bad practice, but it works sometimes.

Example 6.3a

Example3a


Image = bpy.data.images["AN_Image"]
Image.pixels = Pixels

Demonstration

In this example, I am writing pixel info to an image. Blender accepts the pixel info as a list of floats with the pattern RGBARGBARGBA…. it means the first float is the red value if the first pixel, second is green for the first pixel, third is blue for the first pixel, fourth is the alpha for the first pixel, fifth is the red value for second pixel, and so on. So, the node expects a float list with length $W \times H \times 4$ where $W,H$ are the width and height of the image respectively.

I generated a list of floats that goes from zero to one with 40000 float because my image is $100 \times 100$. This will produce some kind of vertical-horizontal gradient, but lets do something more useful.

Note!

Notice that we didn't have to import the bpy, that's because it is imported already along with some other modules.

Example 6.3b

Example3b Example3b


Image = bpy.data.images["AN_Image"]
Image.generated_width = Width
Image.generated_height = Height
Image.pixels = Pixels

Demonstration

In this example, I made it possible to change the width and height of the image. I also created a loop that compute a spherical gradient, which is created as follows:

Challenge!

Can you get the pixel info from another image, edit those info somehow and then write pixels back to an image?

LEAVE A COMMENT

Procedural Bookshelf In Animation Nodes
Procedural Bookshelf In Animation Nodes
Charts In Animation Nodes: Pie Charts
Charts In Animation Nodes: Pie Charts
Blender Objects In Animation Nodes
Blender Objects In Animation Nodes