Archive for category cinema4d

fun with python modules

New scripters I speak with don’t often know how to easily load code from external folders / modules in Python scripts. Today’s post will give you a few pointers in both Cinema 4D and Maya.

Setting Your Script Paths

Python’s import command should be no stranger to you if this topic interests you– it was probably the second thing most people learn in Python, after writing “Hello, World!” to the console. Import allows you to bring in code from libraries external to the source file in which you’re currently working. For example:

# commonly seen in Cinema 4D
import c4d
from c4d import *

# commonly seen in Maya
import maya
from maya import cmds as mc
import pymel.all as pm

These statements bring whatever module you specify into the current namespace, or bring in functions, classes, and variables. But where are the libraries that the import method references? Where do they live on disk?

The easiest way to find out is to list Python’s sys.path:

import sys

In my case, in Maya, it outputs the following:




Looking in the folders that are listed, you may find any number of Python source files and Python object files (*.pyc). sys.path is great because it’s just a regular Python list, which means it’s editable. You can append any number of paths that you like to it, and when import is called it will look through each and every path for the name specified.

Let’s try this in Cinema 4D. First, make a folder somewhere on your machine. I’m going to use /Users/Carney/Desktop/scripts for this example (I’m on a Mac.) In that folder, create a new file called and add the following text:

# simple utility functions

def ut_log(*args):
    msg =''
    for arg in args:
        msg += ' ' + str(arg)

Now back in Cinema 4D, open the Console and the Script Manager from the Scripts menu. In the Script Manager, paste the following and hit Execute, replacing the path with the folder you chose above:

import sys

import util
util.ut_log('Fun', 'Bunnies', 'are', 'fun.')

If all’s well, you should get a single sentence printed to the console output. If you made a mistake, you may get an error about not being able to import the util file. Check your path and try again.

With this setup, you can write scripts in your application that reference lengthy libraries of external code or other utility functions that you’ve created. At the moment I’m organizing code into single files with multiple functions for shorter utilities. Any function that’s more complex gets it’s own file and a class to contain it. This leads to funny lines like the following:

import module_generic
mod = module_generic.GenericModule()

But the organization and the ability to quickly update code without having to sift through a monolithic file inside the C4D Script Manager is worth the headache.

Automatically Adding Python Search Paths in Maya

The only thing to remember about this setup is that you have to make sure you add that folder you created to sys.path every time your application starts. In Maya this is a simple and well-known trick, but I had to do some digging to find out the same for Cinema 4D.

In both applications there’s a special Python file that gets loaded every time the Python VM restarts. In Maya, the file is called

Automatically Adding Search Paths in Maya

and it must live in one of three places:

  • ~/Library/Preferences/Autodesk/maya/2012-x64/prefs/scripts
  • ~/Library/Preferences/Autodesk/maya/2012-x64/scripts
  • ~/Library/Preferences/Autodesk/maya/scripts

You may notice that these are listed in the above printout of sys.path. When Maya starts it will execute files it finds. If you put the file in a folder that has the version of Maya specified (for example, in maya/2012-x64/scripts), then only that version will load the userSetup. If you place it in the general scripts folder — the last folder listed above — then it will be loaded by all Maya versions that support Python.

You can also use the MEL command internalVar -usd to find a folder that will work.

The userSetup file can execute any code you like when Maya loads, allowing you to have custom menus auto-created or to modify your sys.path variable so that you can access your code at any time. Try this: save a file into , and make sure it contains the following (after modifying the path to point to where you saved your file):

import sys

Now in Maya, open the script editor and copy, paste, and run the following:

import util
util.ut_log('Fun', 'Bunnies', 'are', 'funner.')

If all worked, you’ll see a line printed from your file letting you know that the custom setup succeeded on Maya startup, and you’ll see the proper output from this file.

Automatically Adding Python Search Paths in Cinema 4D

The way to do the above in Cinema 4D seems to be less well-known: you have to find the folder that is appropriate for your particular version of Cinema 4D and copy in a file called

The easiest way to find this folder is to go to the Scripts menu and choose User Scripts > Script Folder. This is the folder where scripts you’ve edited and saved through the Script Manager live. Now, go up one folder to Library, then go up again. This is the main folder for your version of Cinema 4D; it may have an oddly long name, but it contains your prefs and libraries. The file belongs in prefs/python. As an example, my folder is:

  • /Users/Carney/Library/MAXON/Cinema 4D R13/prefs/python/

Final Notes

This is just the start of organizing your code. If you want to know more, I recommend reading the official documentation on Python modules.

Tags: , , ,

playing in coffee

I’m slowly coming out of the fog of Maya, now that I’m done with using it for Animation Mentor, and I’ve been trying to get back into Cinema 4D. I just wanted to post this short COFFEE script snippet. This looks through all the animation curves on an object and spits out information on them.

var op = doc->GetActiveObject();
var curTime = doc->GetTime();

println("\nKey dump for ", op->GetName(), ":\n");

var t = op->GetFirstCTrack();
if (t == NULL)

var i = 0;
var j = 0;
var k;
var c;

while (t != NULL) {
	c = t->GetCurve();
	println("\tTrack ", i, ": ", t->GetName(), " -- ",
	c->GetKeyCount(), " keys.");

	for (j = 0; j < c->GetKeyCount(); j++) {
		k = c->GetKey(j);
		var bt = k->GetTime();
		println("\t\t", j, ": v", k->GetValue(), ", t:", bt->GetFrame(30));

	t = t->GetNext();

println("Number of tracks: ", i);

The sad part is this: you can’t add new keys to curves in COFFEE; you can only read what’s there. (EPIC FAIL, Maxon.) At least now I know how to get keys and how the BaseTime class works.

Weak References

Last year while I was working at Red Rover, I heard the term “weak reference” in reference to a technique for referencing objects in 3DS Max. The Max TD used them for a variety of things. I didn’t quite understand what he was talking about at the time, since the last version of Max I used was 2.5 and I never did rigging or coding for it then.

More recently I’ve come to the same technique on my own both in Maya and in Cinema 4D, and was reminded of the name for it by that same TD over beers a few weeks back.

Essentially, weak references are variables on objects that contain a pointer to an object, and not a reference to it’s name. In Maya, for example, you may see rigging scripts written by TDs referencing specific objects by name or saving names of objects as they’re created and using those names to connect attributes or add constraints. In a clean scene this works fine, as long as the rigger is meticulous in their naming scheme and runs different stages of the rigging script in proper order.

But what happens when Maya namespaces become involved? As soon as you reference in an asset, every object that makes up that asset gets a namespace prefixed onto it’s name. If you’ve written scripts that require specific names, they break. If your layout files aren’t perfect and the namespace is different between two or more shots (as Maya is wont to append a number, regardless of what you specify), useful tools like character GUIs and the like break and you’re left doing namespace surgery in a text editor.

Weak references sidestep all this by giving you a permanent connection to an object regardless of name changes or namespace prefixes.

A good example is how I’m currently handling cameras in scenes. A decision was made early on, on the current project at work, to name cameras in layout files by the name of the shot / sequence. Normally this isnt a problem, but we’re using a renderer that’s not linked into Maya directly and therefore needs a command line batch exporter written. If all the cameras are named differently, and the camera’s animation has to be baked and exported as well, how do you go about picking the right object?

Using weak references, the problem becomes trivial. You create them as follows:

addAttr -ln "cameraObj" -at "message";

You’ve probably seen attribute connections of type message into IK handles and other things. The message attribute carries no data– that is, it never changes and causes no DAG recalculations. (This is doubly useful because you can connect the message attributes of two objects to message-typed user attributes in a cycle without causing a cycle error– more on that later.) However, the attribute can be used to get the name of the connected object like so:

listConnections object.messageAttribute;

It will return an array of strings. If you rename an object, you can get the object’s current name through the above command.

So where do you store these attributes? For the moment I’m using a trick I saw on the Siggraph ’08 talk by Blue Sky on procedural rigging: I create non-executing script nodes and store connections on them. In the camera example above, every scene has a master script node. On that node are a few attributes, including its “type” and a .message connection to the render camera. It’s them trivial to find the camera’s name:

string $sel[] = `ls -type "script"`;
for ($s in $sel) {
	if (`attributeQuery -node $s -ex "snCamera"`) {
		// this should be the one you need
		// normally I search for the type, but this is an example
		string $conn[] = `listConnections ($s + ".snCamera")`;
		// if it's only one connection incoming, then you're done.
		print("Camera is named " + ($conn[0]) + "\n");

This technique can be extended to include all kinds of objects. It can also be very helpful for scripts like character GUIs that need to know what characters are present in a scene, and be able to change the positions of all those controls.

One final note on this for now: In Cinema 4D, every object and tag in a scene can be named the same. Searches for objects or tags by name are often fruitless because of this; if two objects or tags have the same name there’s really no easy way to tell which is which in a COFFEE script. What you can do, however, is create a user data variable that is of the Link type. This allows you to drag and drop an object into that variable’s edit field, and provides a permanent pointer to that object regardless of name. This is very useful in rigging; for example, you can always tell which joints in a leg are control joints, and which are bind joints, by creating links. You can also expose the links in XPresso and use the pointers as if you’d dragged an object onto the XPresso node window.