Open Search
    Token System Manual

    About

    See the overview on Token System Overview.

    Handling Tokens

    Getting Tokens

    Converting Tokens

    • StringConvertTokens() / FilenameConvertTokens(): Using these conversion functions, a path containing Tokens can be converted into a complete file path. The Tokens will be evaluated and replaced by the actual data based on RenderPathData. There are two flavors, one taking String and the other taking Filename as an input parameter.
    • StringConvertTokensFilter() / FilenameConvertTokensFilter(): There may be situations, where one wants to evaluate only a subset of Tokens, while keeping others for later evaluation. That's what the *ConvertTokensFilter() functions are for.
    // 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
    AutoAlloc<BaseBitmap> 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->GetDataInstanceRef();
    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
    finalFilename.SetSuffix("png"_s);
    bitmap->Save(finalFilename, FILTER_PNG, nullptr, SAVEBIT::NONE);
    NONE
    Definition: asset_browser.h:1
    Py_UCS4 * res
    Definition: unicodeobject.h:1113
    OK
    User has selected a font.
    Definition: customgui_fontchooser.h:0
    @ RDATA_PATH
    Definition: drendersettings.h:66
    @ RDATA_XRES
    Definition: drendersettings.h:152
    @ RDATA_YRES
    Definition: drendersettings.h:153
    NODOCUMENTCLONE
    Set to avoid an automatic clone of the scene sent to RenderDocument().
    Definition: ge_prepass.h:2
    #define NOTOK
    Definition: ge_sys_math.h:258
    return OK
    Definition: apibase.h:2740
    #define FILTER_PNG
    PNG.
    Definition: ge_prepass.h:202
    RENDERRESULT
    Definition: ge_prepass.h:426
    #define MAXON_SOURCE_LOCATION
    Definition: memoryallocationbase.h:69
    Filename FilenameConvertTokens(const Filename &path, const RenderPathData *rpData)
    maxon::Int32 Int32
    Definition: ge_sys_math.h:51
    RENDERRESULT RenderDocument(BaseDocument *doc, const BaseContainer &rdata, ProgressHook *prog, void *private_data, BaseBitmap *bmp, RENDERFLAGS renderflags, BaseThread *th, WriteProgressHook *wprog=nullptr, void *data=nullptr)
    unsigned long Py_ssize_t width
    Definition: pycore_traceback.h:88

    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();
    const 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;
    }
    Bool RegisterToken(const String &key, const String &help, const String &example, TOKENHOOK *hook)
    maxon::Bool Bool
    Definition: ge_sys_math.h:46