Open Search
    Python

    About

    The Python module allows to execute Python source code. This can be standard Python as well as the classes included in the "c4d" and "maxon" module.

    The module's API is defined in the python.framework as well as lib_py.h.

    Classes and Functions

    Example Code

    // This example function executes the given Python code.
    #include "maxon/vm.h"
    #include "maxon/cpython.h"
    #include "c4d_general.h"
    #include "lib_py.h"
    //----------------------------------------------------------------------------------------
    // Executes the given Python code.
    // @param[in] sourceCode The source code to execute.
    // @param[in] doc The BaseDocument to set "doc" and "op". If no BaseDocument is set, "doc" and "op" will not be defined.
    // @return OK on success.
    //----------------------------------------------------------------------------------------
    static maxon::Result<void> ExecutePythonScript(maxon::String& sourceCode, BaseDocument* doc)
    {
    // check code
    if (sourceCode.IsEmpty())
    return maxon::IllegalArgumentError(MAXON_SOURCE_LOCATION);
    const maxon::VirtualMachineRef& vm = MAXON_CPYTHON3VM();
    const maxon::VirtualMachineScopeRef scope = vm.CreateScope() iferr_return;
    // init script
    iferr (scope.Init("Python Script"_s, sourceCode, maxon::ERRORHANDLING::PRINT, nullptr))
    {
    const String errorMessage = "Error on Init()"_s;
    return maxon::UnknownError(MAXON_SOURCE_LOCATION, errorMessage);
    }
    // only set "doc" and "op" if a BaseDocument is set.
    // another option would be to set both "doc" and "op" to None
    if (doc != nullptr)
    {
    // set "doc" and "op" variables
    auto python = maxon::Cast<maxon::py::CPythonLibraryRef>(vm.GetLibraryRef());
    maxon::py::CPythonGil gil(python);
    // the new Python API from python.framework is compatible with the legacy Python API from lib_py.h.
    // here we temporarily create an old PythonLibrary instance because it can create a PyObject
    // from a BaseDocument and BaseObject
    PythonLibrary pyLib;
    auto* pyObjectDoc = pyLib.ReturnGeListNode(doc, false);
    if (pyObjectDoc == nullptr)
    return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
    auto* pyDoc = reinterpret_cast<maxon::py::NativePyObject*>(pyObjectDoc);
    scope.Add("doc"_s, maxon::Data(pyDoc)) iferr_return;
    python.CPy_Decref(pyDoc);
    BaseObject* op = doc->GetActiveObject();
    auto* pyObjectOp = op ? pyLib.ReturnGeListNode(op, false) : pyLib.ReturnPyNone();
    if (pyObjectOp == nullptr)
    return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
    auto* pyOp = reinterpret_cast<maxon::py::NativePyObject*>(pyObjectOp);
    scope.Add("op"_s, maxon::Data(pyOp)) iferr_return;
    python.CPy_Decref(pyOp);
    }
    // set __name__ = __main__
    scope.Add("__name__"_s, maxon::Data("__main__"_s)) iferr_return;
    // stop all current threads which are potentially modifying the current document,
    // since the active script might modify the currently active document
    // executes the script and returns when it got executed.
    // info: if the script causes an unexpected infinite loop, Execute() does not return
    // and there is no way to stop from the outside.
    iferr (scope.Execute())
    {
    const String errorMessage = "Error on Execute()"_s;
    return maxon::UnknownError(MAXON_SOURCE_LOCATION, errorMessage);
    }
    return maxon::OK;
    }
    Definition: datatypebase.h:1235
    Definition: string.h:1287
    Bool IsEmpty() const
    Definition: string.h:1492
    return OK
    Definition: apibase.h:2771
    #define MAXON_SOURCE_LOCATION
    Definition: memoryallocationbase.h:69
    #define iferr(...)
    Definition: errorbase.h:388
    void StopAllThreads()
    @ PRINT
    Any thrown exception will be handled internally.
    const char * doc
    Definition: pyerrors.h:226
    #define iferr_scope
    Definition: resultbase.h:1396
    #define iferr_return
    Definition: resultbase.h:1531
    PyObject * op
    Definition: object.h:520
    Definition: cpython.h:2920
    Definition: cpython_raw.h:244
    #define MAXON_CPYTHON3VM()
    Definition: vm.h:471