Posts Tagged c4d

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
print(sys.path)

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

[
'/Applications/Autodesk/maya2012/Maya.app/Contents/MacOS',
'/Applications/Autodesk/maya2012',
'/Users/Carney/scripts/mayaScripts/scripts',

...

u'/Users/Carney/Library/Preferences/Autodesk/maya/2012-x64/prefs/scripts',
u'/Users/Carney/Library/Preferences/Autodesk/maya/2012-x64/scripts',
u'/Users/Carney/Library/Preferences/Autodesk/maya/scripts'
]

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 util.py and add the following text:

# util.py
# simple utility functions

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

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
sys.path.append('/Users/Carney/Desktop/scripts')

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 userSetup.py files it finds. If you put the userSetup.py 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 userSetup.py file into , and make sure it contains the following (after modifying the path to point to where you saved your util.py file):

import sys
sys.path.append('/Users/Carney/Desktop/scripts')

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 userSetup.py 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 python_init.py.

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 python_init.py file belongs in prefs/python. As an example, my python_init.py 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: , , ,

cinema 4d scripting, part 2

Three posts in three days! I don’t actually have as much time as It appears I do; the iPhone WordPress app is very useful.

I’m finally at a good place with my rigging library of COFFEE functions that now when I code out a set or rig steps, things are behaving as I expect. I’ve recreated the “Wipix Leg” in code (if you’re not familiar with it, it’s a method for making a stable IK solution without the 90 degree pole vector flip trick in used in Maya), and I’m now at a point where I have to do some rig redesigning. In other words, I’m no longer fighting the code misbehaving– now I’m back to working on conceptual stuff.

I do plan on releasing some of what I’ve learned either for free here or on a DVD at some point down the line, with my function library.

One thing I found out that really put a thorn in my side is that my constraint code was made useless by changes to the Constraint tag in R11. By cleaning up how the tag works, Maxon has rendered the tag completely useless when working from COFFEE. I’m not sure whether Py4D will be able to do what’s needed; I won’t be able to begin porting my rig to Python until the whole thing is finished. However, because you can get selected objects as arrays through Py4D (and not through COFFEE) maybe there will be better constraint code workarounds in my future.

Also nice to discover was that the Wipix Leg works just fine in Blender. Stable leg IK was the one thing for which I didn’t have a setup I liked in Blender, but that problem is now sorted. Still thinking I’ll be using Blender for my short film because of it’s speed of use. I can build that leg from scratch in Blender in twenty minutes; it takes significantly longer in both C4D and Maya.

Tags: , ,