Token System Manual

About

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);
if (res != RENDERRESULT::OK)
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
finalFilename.SetSuffix("png"_s);
bitmap->Save(finalFilename, FILTER_PNG, nullptr, SAVEBIT::NONE);

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.
Note
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("example.take"),
String("Current Take Name"),
String("MyTake"),
ExampleTakeTokenHook);
if (success == false)
return maxon::UnknownError(MAXON_SOURCE_LOCATION);
return maxon::OK;
}