The C.O.F.F.E.E. SDK Primer

Per-Anders Cinema 4D, Tutorials

To start off with make sure you either have downloaded the latest COFFEE SDK from www.plugincafe.com or you’re browsing the online version (which is actually more recent than the downloadable version).

The COFFEE SDK is where you will find explanations for how to use all the commands and functions built into COFFEE. Lets take a look at one now, The first page of the COFFEE SDK is the “Reference” page, here commands are sorted into groups that are relevant to each other, for instance Object types, Plugins Types, Math functions, and Base Classes.

So how do you use this? Well it helps to remember what you’ve already been taught about functions and classes from the tutorials at www.plugincafe.com, remember a function is a command that can be called at any time from any part of the COFFEE program once it has been defined, COFFEE has many already defined functions, like “println();” or “cos()”, these functions can be called directly like this

println(cos(90));

(always remember to end your lines in COFFEE with a semicolon “;” this is the most common mistake, the semicolon tells COFFEE that it’s reached the end of a line, if it’s not there then it will read the next line as part of the previous line of code and invariably that will throw up a “Syntax Error” this is simply put a grammatical mistake as far as any programming language is concerned).

This line of code will print out in the Console (Window->Console) the cosine of 90 which should be 0. That line of code just called two inbuilt functions of COFFEE.
A function always “returns” a value, meaning it gives you a value back when you call it, this is useful because you can store the value it returns in a “variable”, variables in COFFEE must always be declared before you use them, declaring a variable is rather like introducing someone at a party, people need to know the newcomers name first so they can converse with them, COFFEE needs to know the variables name first (and maybe a little bit about them) before it can converse with that variable, this is how you tell COFFEE your variables name:

var fred;

So you’ve just introduced fred to COFFEE, an important point should be made here, and that is COFFEE makes a differentiation between upper and lower case letters, it’s very important both with variables and functions to make sure that you use the correct case, therefore fred is not the same as Fred or FRED to COFFEE, if you introduce fred, but then try to use FRED, COFFEE will not know what you’re talking about and will throw out an error.

Sometimes you want to tell COFFEE a little bit more about your variable when you introduce (declare) them, in these instances you can tell COFFEE that your variable contains such and such a value, or does such and such a job (in party speak).

var fred=10;

or

var fred=new(array,10);

or even

var fred=Vector(0,0,0);

In the first example we told COFFEE that the variable “fred” is numeric and contains the value 10, it might just as easily of contained the value “Rocket Scientist” ( var fred=”Rocket Scientist”; ) or anything else really.

In the second example, we didn’t tell COFFEE what “fred” contained, just what fred was, we told COFFEE that fred is an “array” and that this array contains ten elements, we didn’t say what those elements contain, each element of an array can contain it’s own information, for instance we could write

fred[0]=”Age”;
fred[1]=”Date of birth”;

etc etc, till we fill the array up (but don’t go beyond the “extents” of the array, in our example this is 10.

In the third example we showed COFFEE three things about fred, firstly his name “fred” then what type of information fred contains “Vector” and finally the values of that information. This is in fact the same as the first example, only here we’re showing that different data types can be used, in this case the data type “Vector” which contains three values, x,y and z. This sort of data type is known as a “Struct” and in order to access it’s elements you have to use the “dot” syntax, which means you write:

myvariable.element=whatever;

or

whatevervariable=myvariable.element;

In the case of the vector it’s three elements are x,y and z, (all lower case) so to access them individually we write:

fred.x=10;

or

my_y_direction=fred.y;

The last thing to talk about when dealing with variables is what’s known as “scope”, in COFFEE you’ll soon realize that lots of code is surrounded by curly brackets like there { }, when you see this that code is called a “Block”, you can use curly brackets anywhere you want to break up your code into meaningful chunks, but usually they’re there for a specific purpose, for instance many commands in COFFEE work on the next line down, for instance any function declarations like “main(doc, op)” also commands like “if”, “for” and “while” all of these commands are known as “flow” commands, they control the flow of what gets executed, and as has been said they all work by if a certain condition is met, then executing the line of code immediately beneath them.

This has one obvious problem though, you’re never going to get everything you want to happen onto one line of code, and even if you could it would probably be so long that you’d never be able to work out what was going on when and where. This is where the curly brackets come in, they essentially tell COFFEE that everything inside of the curly brackets is in fact one line (or really one block) of code, and therefore if they come after a “flow” command, everything inside of that block will be executed when the flow command is used. More or less everything has to be inside of a block of code in COFFEE, at least all commands have to be there, though you can declared variables only (you can’t assign them any value or type) outside of any block. This is the reason that COFFEE always needs a “main” function to work, as “main” is the first function Cinema calls when the COFFEE tag or plugin is executed.

So what does this have to do with this fabled “scope”, well when a variable is “declared” inside of any block of code surrounded by the curly brackets it can only be used inside of that block of code (and any blocks that are inside of that block of code). Outside of that block, the variable has no value. This means that the following code would throw an error out:

main (doc,op) {
var newguest=TRUE;
if (newguest==TRUE)
{
var fred;
fred=”Frederic”;
}
println{fred};
}

It’s common practice to tab in blocks to make it easier to see where a block begins and ends, however we can’t do that here in HTML land, but when coding this might help you to give yourself a clear idea about what’s going on with your code.

Why doesn’t this work? Because “fred” has been declared inside of the sub block of code for the “if” statement. if you were to do either of the following, then everything would be fine:

main (doc,op) {
var newguest=TRUE;
var fred;
if (newguest==TRUE)
{
fred=”Frederic”;
}
println{fred};
}

or

main (doc,op) {
var newguest=TRUE;
if (newguest==TRUE)
{
var fred;
fred=”Frederic”;
{
println{fred};
}
}
}

The code within the curly brackets represents the “scope” and any variable declared within those curly brackets is limited to the scope of those brackets.
So now we’ve covered variables, variables scope, calling values from a “struct” and using “functions” we see how to call a class, Classes are a way to define a “Type” of variable, or in programming speak “object”.

In COFFEE all the objects are a class in themselves but to make things even more confusing each Object also belong to a “parent” class, usually one of the “Base Classes”, we will examine how the SDK shows these later

How do we use a class? Well first of all we need an object that’s of that class to access, we can do this a number of ways, first we can simply make a new object of that class like so:

var myobject=new(PointObject);

Here we just made a new point’s object ready to put into our scene, COFFEE won’t actually add it till we tell it to as after all we might like to set a few parameters first (like adding points), later on we’ll see how to actually add an object to a scene.

Sometimes we can extract an object of the class that we want from another object of a different class, we do this by calling the classes internal functions, here’s how for instance we get the first object in a scene by using the class BaseDocument. (which is the class the current document comes from);

var doc=GetActiveDocument(); //this function doesn’t need a class and it tells COFFEE that doc contains the current document
var activeobject=doc->GetFirstObject();

Here we made a variable “doc” which we told COFFEE was of the type “BaseDocument” simply by filling it with a BaseDocument object by using the command “GetActiveDocument()”, we then called the function “GetFirstObject” from the base class “BaseDocument” which the object variable”doc” now belongs to. Take a moment to get your head around that, and we can look through the SDK to see how the SDK shows and explains this.

From the reference page go to “BaseDocument” from the “Base Classes” list, lets look at the layout of the page, at the top we have the name of the class/command/function/struct, in this case “BaseDocument”, in the box underneath that it tells you miscellaneous information about it, like what language it’s for (C++ or COFFEE), as well as what kind of COFFEE command it is, i.e. Class, Function etc, in this case it’s a “Class” which means that to make a new object of this class we go:

var mydoc=new(BaseDocument);

If it were another class then we would use

var myobject=new(Insert class name here);

What if we want to get an object of this type that already exists rather than making a new one, well that’s when we use a function of either the parent class or in certain cases when there is no real parent class accessible through COFFEE there are direct commands, such as for this class “BaseDocument” the way to get the current document is to use the “GetActiveDocument” function., remember we know how to use functions, it’s

myvar=function(function parameters);

therefore if you looked at the GetActiveDocument function in the SDK you would see that it needs no parameters, so the brackets will be empty and it’s called by:

currentdoc=GetActiveDocument();

this puts the active document into the variable currentdoc.

So carrying on looking at the SDK page for “BaseDocument” we can see that underneath the first box is an area headed by “Definition”, at first this just looks like a load of code itself (and in essence it is, it’s the declaration of the class in this case), but lets take a moment to examine what it shows and all will become clear.
the first line is as follows

class BaseDocument : BaseList2D

This line has three parts, first part is the declaration “Class” this tells you (and COFFEE) that this is a class type, the next word is going to be the name of the object class, in this case “BaseDocument”, we already know how to use this. The end part of the line is “BaseList2D” this tells us that the class if of the type “BaseList2D”, which means that BaseList2D (in this case) is the parent class, the parent class of any object class generally has function commands for choosing or selecting objects of the type that you’re currently looking at. Which means in turn that if you’re looking at a class (of object) then there will be functions in there for selecting children or related objects to that one, and indeed this is the case.

Looking down a couple of lines we come to the first line of meaningful text:

[BaseObject] GetFirstObject();

This is a function of the class. lets look at the line before we discuss how to use it. the left most bit of text in the square brackets “[BaseObject]” tells you what kind of information this function will return to you. In this case it will return a “BaseObject”, if you were observant before you will have noticed that on the reference page in the same block of “Base Classes” as “BaseDocument” there was a class called “BaseObject”, this means that calling this function would return an object belonging to that class type, which you could then use functions from within that class with.

The next bit of text “GetFirstObject” is the actual function, if you click on it, it will give you a similar page to the one we’re looking at, only it’s giving a description of “GetFirstObject”. We can look at this page later on, but be sure to notice that where it’s got the title “GetFirstObject” it’s written as “BaseObject :: GetFirstObject”, this tells you that not only is this a function, but it’s a function of the class “BaseDocument”, which in turn means that it’s meaningless to COFFEE if it’s not called in relation to a BaseDocument type object.

Back to the line of code above, the last bit of the brackets which with some lines of code contain the function parameters that are needed to call the function, for instance looking a little further down the list of functions we come to:

[bool] SetActiveObject ([BaseObject] op);

In this case the function returns a “bool” value, over time you will learn what is a COFFEE class, and what is a COFFEE struct, and what is just a COFFEE type, a bool is a “type< it’s got two values “TRUE” or “FALSE”, “TRUE” and “FALSE” are what’s known as Constants, that is they’re variables that are set by COFFEE and can’t be changed, PI is also a constant, most of COFFEE’s constants are in upper case letters, and they hold a specific value, for instance FALSE in coffee is equal to 0, while TRUE is equal to 1. Why should this command return anything at all when it’s there to change or “set” a parameter? Because you may want to check if it’s actually done it’s job, it will return TRUE if it’s successful, and FALSE if not.

After that we come tot the function parameters in the brackets “[BaseObject] op”, what this tells us is that in order to call this function we need to put in the brackets a variable containing, or a direct reference to an object of the class “BaseObject”, when you look down the list and see some function have some function parameters that are in square brackets that aren’t italic, that means those parameters are optional, apart from in those cases though you need to have the parameter of the type in the italic square brackets there.

So now how do we use a function of a class? We call it by using the arrow sign, which is a combination of the minus “-” and the greater than “>” to form an arrow “->”, what do we do with this arrow? It’s similar to the “dot” syntax of structs, we have an object of the class type we are looking at and we want to access it’s functions (whereas with a struct we wanted to access it’s elements). So the syntax is something like:

objectofclasstype->functionofclass(function parameters);

So to call the function “GetFirstObject” we first of all have to get an object of the type “BaseDocument”, but that’s easy enough because if you noticed the function “main” in any COFFEE tag already contains a variable “doc” which is in fact that current document object, and a document is an object of the class “BaseDocument”, so we’re already sorted for that, therefore the only line of code we need to invoke “GetFirstObject” is:

var myfirstobject=doc->GetFirstObject();

It’s worth knowing that you can make a line of these calls going into each other quite easily, what is meant by this, well take a look at the following code which is used to get the first object in a scene’s position:

var myfirstobject=doc->GetFirstObject(); //makes “myfirstobject” into an object of the class type”BaseObject”, containing the first object in the scene.
var position=myfirstobject->GetPos(); //makes “position” into a vector containing the position of the object “myfirstobject” which is of course the first object in the scene

That’s two lines, and maybe after that you’re never going to use “myfirstobject” again in your COFFEE code, so repeated class function calls allow you to do the following instead:

var position=doc->GetFirstObject()->GetPos(); //makes position a vector and puts the first objects position into that vector.

In essence the last function made (the rightmost one) determines what is returned, this can be very useful for cleaning up and making your code concise, but still readable.
Sometimes in the SDK you will see a class function whose parameters contain the words “FLAGS”, in this case click on the class function to see the page showing that functions description and in the Description box you should see a list of valid flags that you can use. For instance if you scroll down the BaseObject’s page of functions you will see a function called “CopyTo” click on that and in there you will see that it can take the following as valid flags:

CL_NO_BITS
CL_ONLY_VISIBLETAGS
CL_NO_TRACKS
CL_NO_HIERARCHY

And there’s a brief description of what each tag means, this means that with this function it would be called by something like:

doc->CopyTo(myobject,CL_NO_BITS);

or if you didn’t want to use any of the flags you could also use FALSE which would look like:

doc->CopyTo(myobject,FALSE);

You may have noticed that we didn’t put a variable=doc->CopyTo(myobject,FALSE);, this is because we don’t need to get the return value from the function if we don’t want to, the function will still be called, though in many cases it’s pointless calling the function unless we do get a return value (like “GetFirstObject” for instance).

Carrying on looking down the SDK page you will see that underneath “Definition” there is “Description”, here is held often a very brief description of what the command is meant to do or return, sometimes beneath that you will find Explanation, which where a more in depth description is given of the commands usage, and beneath there you might sometimes find either Examples, in a few cases there will be a piece of example code showing how this function works, and/or an area showing Inheriting Classes, these are the children or related classes to the current class or function.

Example

So now we have a slightly better idea about how to use the SDK, lets make a practical example, here we will make a COFFEE tag that checks to see if the object that the tag is on has a child, if not then it will add a new polygon object as a child of our object.

First step is to check to see if there is a child. Knowing that any object that we can put a COFFEE tag on is going to have the parent class BaseObject, we can see from the SDK page that a BaseObject’s parent class is in fact BaseList4D, we know that the BaseList classes are there to traverse the scene structure, going through the objects, so therefore if we look here we can see that here (rather than in BaseObject) is the function we need GetDown(). Remember if you can’t find the function you need in your objects class, look in the parents classes and the related classes

Looking at GetDown() as a function you can see that it returns a bool if it’s successful, this means we can use it to actually test if there is a child of our object hence to start off with our code should look something like:

main(doc,op)
{
if (op->GetDown()) return FALSE;
}

The if statement checks to see if what’s in the brackets is true, therefore if we can get op’s (the object that the tag is on) child, then the if statement is true, and we will return a value of FALSE because we don’t want to add an object when a child is already there, which jumps out of the main function and hence stops the code.

So now we’ve tested if there’s a child or not (we need to do this otherwise our tag would just keep adding children to our object ed-infinitum, and we would probably end up crashing cinema, or at least slowing it down considerably) it’s now time to make a new object of the sort that we want to put underneath our current object.

So once more looking at the SDK page for BaseObject you can see that there are a lot of inheriting classes (or child classes), each of these classes describes a specific object, we are going to add a PolygonObject which is actually a child of the PointObject, so click on PointObject, then on it’s inheriting class PolygonObject to see it’s page. So the first thing to do is to make a new instance of this class.

main(doc,op)
{
if (op->GetDown()) return FALSE;

var childop=new(PolygonObject);

}

Well we made the new object, but as yet we’ve not added it to our scene, now we know how to use the SDK we can search through and see how to do this by using functions of the SDK, but right here i’m only going to show you how to now add our new PolygonObject to the scene.

remembering that the BaseList classes are where the scene ordering goes on, lets look once again at BaseList4D. In here you will see that there is a command that allows us to place a new object as a child of our current object, the command is “InsertUnder”, all we have to do then is add one line of code that uses the InsertUnder() function that’s within our new PolygonObject, we can see in the SDK what function parameters need to be passed, all it needs is a parent object, which we have in the form of op so here goes:

main(doc,op)
{
if (op->GetDown()) return FALSE;
var childop=new(PolygonObject);

childop->InsertUnder(op);

}

There, simple eh?

Remember with the COFFEE SDK or even the C++ SDK many times things will not appear to be totally clear at first, don’t be afraid to ask at the Plugin Cafe forums, or do a search as more often than not he question you’re wanting to ask has already been asked and answered before (remember to search the archived forum first as that’s a much bigger resource at the moment than the current forum).

Good luck and happy programming.