Token System Manual


See the overview on Token System Overview.

Handling Tokens

Getting Tokens

Converting Tokens

// This example renders a BaseDocument and saves the resulting image using a filename handling tokens:
const Int32 width = 1280;
const Int32 height = 720;
// Prepare bitmap
if (bitmap == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
if (bitmap->Init(width, height) != IMAGERESULT::OK)
return maxon::UnknownError(MAXON_SOURCE_LOCATION);
// Define render settings
RenderData* const renderData = renderDocument->GetActiveRenderData();
if (renderData == nullptr)
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
BaseContainer renderSettings = renderData->GetData();
renderSettings.SetFloat(RDATA_XRES, width);
renderSettings.SetFloat(RDATA_YRES, height);
// Get filename
const Filename savePath = renderSettings.GetFilename(RDATA_PATH);
if (savePath.IsPopulated() == false)
return maxon::OK;
// Render the document
const RENDERRESULT res = RenderDocument(renderDocument, renderSettings, nullptr, nullptr, bitmap, RENDERFLAGS::NODOCUMENTCLONE, nullptr);
return maxon::UnknownError(MAXON_SOURCE_LOCATION);
// Save result
// Convert tokens
const RenderPathData rpd = RenderPathData(renderDocument, renderData, &renderSettings, nullptr, 1, String(), String(), NOTOK);
Filename finalFilename = FilenameConvertTokens(savePath, &rpd);
// Save
bitmap->Save(finalFilename, FILTER_PNG, nullptr, SAVEBIT::NONE);
RENDERRESULT RenderDocument(BaseDocument *doc, const BaseContainer &rdata, ProgressHook *prog, void *private_data, BaseBitmap *bmp, RENDERFLAGS renderflags, BaseThread *th, WriteProgressHook *wprog=nullptr, void *data=nullptr)
Definition: ge_autoptr.h:37
Definition: c4d_basecontainer.h:47
void SetFloat(Int32 id, Float r)
Definition: c4d_basecontainer.h:533
Filename GetFilename(Int32 id, const Filename &preset=Filename()) const
Definition: c4d_basecontainer.h:403
BaseContainer GetData()
Definition: c4d_baselist.h:2311
Manages file and path names.
Definition: c4d_file.h:94
void SetSuffix(const maxon::String &str)
Bool IsPopulated() const
Definition: c4d_basedocument.h:144
Definition: c4d_string.h:39
Py_UCS4 * res
Definition: unicodeobject.h:1113
Definition: drendersettings.h:68
Definition: drendersettings.h:154
Definition: drendersettings.h:155
#define NOTOK
Definition: ge_sys_math.h:267
maxon::Int32 Int32
Definition: ge_sys_math.h:60
return OK
Definition: apibase.h:2667
#define FILTER_PNG
Definition: ge_prepass.h:200
@ OK
Image loaded/created.
Set to avoid an automatic clone of the scene sent to RenderDocument().
Definition: ge_prepass.h:419
@ OK
Function was successful.
Definition: memoryallocationbase.h:67
Filename FilenameConvertTokens(const Filename &path, const RenderPathData *rpData)
unsigned long Py_ssize_t width
Definition: pycore_traceback.h:88
Data structure to collect render information in handling Tokens in render output path.
Definition: lib_token.h:86

Dissecting Tokens

There are a bunch of functions to dissect a path containing Tokens. In the following an exemplary path /myprojects/topnotchproject/$take/beautiful.tif is assumed.

  • StringExtractRoot() / FilenameExtractRoot(): Both return the "constant" part of a path. With the above path, these functions return /myprojects/topnotchproject/.
  • FilenameSlicePath(): This function is similar, but it also returns the part containing Tokens. With above path, it will return /myprojects/topnotchproject/ and $take/beautiful.tif.

Custom Tokens

  • RegisterToken(): Using RegisterToken() custom Tokens can be registered within Cinema 4D. Therefore RegisterToken() gets provided with all information needed by a TokenEntry (key, help and example) and a pointer to the TOKENHOOK function. The example below shows how the "$take" Token is implemented.
  • RegisterHiddenToken(): This function registers a hidden token that is not displayed in Render Settings.
  • RegisterPythonToken(): Registers a new Python token.
  • RegisterPythonHiddenToken(): Registers a new Python token that is not displayed in Render Settings.
When registering custom Tokens, it is recommended to use a prefix to avoid collision with already existing Tokens. For example, the plugin name could be used.
// The custom token callback
static String ExampleTakeTokenHook(void* data)
RenderPathData* const rDataPath = (RenderPathData*)data;
if (rDataPath == nullptr)
return String();
BaseTake* const take = rDataPath->_cTake;
if (take != nullptr)
return take->GetName();
return String();
static maxon::Result<void> RegisterExampleToken()
// NOTE: When registering a custom Token, use a prefix like for example "myplugin.take"
const Bool success = RegisterToken(
String("Current Take Name"),
if (success == false)
return maxon::UnknownError(MAXON_SOURCE_LOCATION);
return maxon::OK;
String GetName() const
Definition: c4d_baselist.h:2363
Definition: lib_takesystem.h:323
maxon::Bool Bool
Definition: ge_sys_math.h:55
Bool RegisterToken(const String &key, const String &help, const String &example, TOKENHOOK *hook)
BaseTake * _cTake
The BaseTake used for rendering.
Definition: lib_token.h:110