Making nodes in C

How to set up your computer to make new Vuo nodes using the C programming language

Transcript

Hello. I’m Karl, one of the developers working on Vuo.

Today I’ll show you how to write and compile your own nodes for use in Vuo. In this tutorial I’ll cover setting up a development environment, compiling example node projects, and the basics of writing a custom node.

Setting up your workspace

To develop nodes for Vuo, you’ll need a few software packages and programs. Namely, Xcode, Xcode Command Line Tools, Qt Creator, Qt framework, and of course, the Vuo SDK.

Xcode

Xcode is available for download in the App Store, or by going to the Apple Developer website, developer.apple.com.

Once you’ve downloaded Xcode and installed it, make sure you’ve opened it at least once, and accepted the developer agreement.

Next install Xcode Command Line Tools. This sets your system up with things like header files for frameworks and various other utilities that are used when compiling Vuo nodes.

The easiest way to install Xcode Command Line Tools is through the Terminal, which I open here using Spotlight. In the Terminal, write xcode-select --install, then hit enter. This will open a new window and download Command Line Tools. Once the download is finished, you can verify that it has been correctly installed by typing in the Terminal: xcode-select -print-path, with a hyphen between “print” and “path”. This should print the the path to the location on your computer that Command Line is installed to.

Qt

To install Qt, go to Download Qt: Get Qt Online Installer and click the green “Download” button. Open the disk image and run the installer. On the second page of the installer, it’ll ask you to log in or sign up, but you can also click the “Skip” button in the bottom right corner. On the “Select Components” page, the defaults are fine.

Vuo SDK

Lastly, install the Vuo SDK. You can find it in the Releases section of the Vuo website. The Vuo SDK contains frameworks and utilities necessary for compiling your own nodes.

You can place the vuo-sdk folder anywhere you’d like. I put mine in a folder named Developer in the Home directory.

Compiling the Examples

OK, the next step is to compile one of the example nodes. This makes sure that your development environment is correctly configured, making troubleshooting easier down the road.

In the Vuo SDK folder there are two folders: example and framework. framework contains the files necessary to compile your own nodes, and the example folder provides some templates to work from. Open examples/node/stateless and double-click the example.stateless.pro file. Qt Creator should open, and you’ll be asked to configure the project. The “Desktop” configuration is good.

Troubleshooting

If you see a “No valid kits found” message, that means Qt Creator cannot find qmake. To remedy this, open the Preferences menu, select the “Build & Run” row, and select the “Qt Versions” tab. Hit “Add…”, and locate the qmake executable. If you left the install location to the default when installing Qt, it will be in the /Users/vuodev/Qt/5.4/clang_64/bin folder.
Now, select the “Kits” tab. Select “Manual / Desktop”, and find the “Qt version” field. In the dropdown, select the latest Qt version, then hit “OK” in the bottom right.

Click “Configure Project”. Qt should take a moment to parse the project, then show the .pro and source files in the file browser.

The next step is to turn off “Shadow build” in the build settings. On the left side of Qt Creator, open the Projects tab. Under “General”, uncheck “Shadow build”.

The project is now ready to compile! Click the hammer icon in the bottom left of Qt Creator, or use the shortcut ⌘ B. If Vuo is open when you compile, it will need to be relaunched before you can see the new nodes in Vuo. Once you’ve quit and re-launched Vuo, search for “Vuoize” in the node library. This is the node you just compiled!

If you see compile errors, check the transcript accompanying this video for troubleshooting tips.

Troubleshooting

  • If your project is failing to compile with a message like Error 127: ./../framework/vuo-compile: No such file or directory, that means Qt Creator cannot find the Vuo SDK. In the .pro file, make sure that the path for the VUO_FRAMEWORK_PATH variable is set correctly.
  • If the project compiles successfully, but you cannot find your nodes in Vuo:
    • The project may not be correctly copying the compiled .vuonode files to the user modules folder. Make sure that in the .pro file, the variable for VUO_USER_MODULES_PATH is the same path that the Vuo menu Tools > Open User Modules points to.
    • This may be a symptom of “Shadow build” being enabled. In Qt Creator, under the Projects > General tab, ensure that “Shadow build” is not checked.
    • If you still don’t see your nodes in Vuo, open Console.app, then re-launch Vuo. Vuo may log some messages to help you figure out the problem.

Node Basics

Now that your development environment is set up and compiling nodes successfully, you can start writing your own nodes.

To quote the documentation, “a node class is like a function or method. It takes some input, processes it, and produces some output.”

Vuo nodes are written in C, with a little bit of JSON to provide information to Vuo. At its most basic, a node must contain at least these things:

  • A metadata entry, which is a JSON string with keys for node title, keywords, and the node version.
  • A nodeEvent() function, which receives and sends data.

There are two broad categories of nodes: stateless and stateful. A stateless node contains inputs and outputs, and modifies data, but does not store any information. A stateful node also has inputs, outputs, and modifies data, but can remember information between events. For example, the Count Within Range node stores an internal variable with the current count, making it a stateful node.

Your First Node: “Make Color Image”

The easiest way to get started writing a custom node is to simply duplicate one of the existing example projects. Select the stateless folder, then hit ⌘ D to duplicate it. Rename the duplicate folder tutorial.

I’ll be recreating an existing node, Make Color Image. This node accepts a color, width, and height, and outputs an image flood-filled with that color, with the dimensions specified. This will introduce some of the different types that Vuo uses, as well as explain how to use the Vuo API documentation.

In the tutorial folder, rename the folder and project files tutorial.image.pro and tutorial.image.color.c. Open Qt, configure project and turn off shadow build.

At this point you’ll notice the Project pane isn’t displaying the node source files. That’s because the project file is still pointing to the vuoize node file. Open the .pro file, and change the line under NODE_SOURCES to tutorial.image.color.c.

Once the project loads the source file, open it and swap out test.vuoize for the tutorial.color name. Make sure you get the comments and metadata title.

In the description I’m a little brief. However, when you’re writing your own nodes, make sure your descriptions are complete, as it’ll be the main source of documentation for your node in the editor.

In the nodeEvent function, modify VuoInputData. VuoInputData and VuoOutputData equate to input and output ports, respectively, in Vuo. For this node, 2 integers and a color are the inputs, and an image is the output. It’s important to only use Vuo-defined types in these ports. So int wouldn’t work; you’ll need to use VuoInteger instead. For a float type, you can use VuoReal. You can find a full list of defined types on the API reference page.

The new nodeEvent function should have 3 VuoInputData entries: 1 for width and 1 for height (both of the VuoInteger type), and 1 VuoInputData entry of the type VuoColor for the image color. There should also be a single VuoOutputData entry of the type VuoImage, which is the output image.

In the body of the nodeEvent method, remove the current contents, then add the following line: *outputImage = VuoImage_makeColorImage(color, width, height);. VuoImage_makeColorImage() accepts a color, width, and height as parameters, and returns a VuoImage, which I assign to the value of outputImage. outputImage is a pointer to data, so I dereference it with an asterisk to assign it a value. I found VuoImage_makeColorImage() by checking the API reference and looking at the documentation for VuoImage. As a rule, constructors of Vuo types will always contain the word make. Constructors are used to create new instances of Vuo types.

Once you’ve filled the body of the nodeEvent function, you’re ready to compile. Like last time, either click the hammer icon or use the ⌘ B shortcut. Open Vuo and search for tutorial.image in the Node Library.

Details

  • When you compile a node, a few things happen. First, the C files are compiled to bitcode, and packaged in .vuonode archives. Then, the build script copies those .vuonode files into the “User Modules” folder, thus allowing Vuo to access them.
  • You can search the node library by namespace. So typing “tutorial.” will show only nodes in the tutorial namespace.

If you don’t see your node, check the accompanying text tutorial for troubleshooting tips.

Summary

Well done! You have successfully made it through the hard part. At this point, you have a development environment primed for building nodes, and all the knowledge necessary for exploring your own node ideas.

If you run into troubles through this tutorial that aren’t covered by the video or the companion text guide, stop by the Vuo Q&A board. And be sure to check out api.vuo.org for further reading.

Node Source

#include "node.h"

VuoModuleMetadata({
					 "title" : "Make Color Image",
					 "description" : "Creates an image of a solid color.",
					 "keywords" : [ ],
					 "version" : "1.0.0",
					 "dependencies" : [ ],
					 "node": {
						 "isInterface" : false
					 }
				 });

void nodeEvent
(
		VuoInputData(VuoColor) color,		// The color the output image will be
		VuoInputData(VuoInteger) width,		// The output image width.
		VuoInputData(VuoInteger) height,	// The output image height.
		VuoOutputData(VuoImage) outputImage
)
{
	// outputImage is a pointer to the output data, so dereference with `*` to assign value.
	*outputImage = VuoImage_makeColorImage(color, (unsigned int) width, (unsigned int) height);
}