API Transition

About

Cinema 4D R20 introduced significant changes of the C++ API. The new MAXON API was introduced, which is fundamentally different that the previous, classic, API. The classic API is still available in the cinema.framework, but several components of the classic API have been replaced with new MAXON API components.

Any plugin that was written for an earlier SDK (R19 or older) must be adapted and re-compiled to work with Cinema 4D R20.

Warning
In future releases more and more parts of the classic API will be replaced with new MAXON API components.

Project Files

Since Cinema 4D R20 the SDK does no longer contain any project files. The project files for frameworks, plugins and solutions must be created using the project Tool. See Project Tool.

Code Adaptations

Code Style

The source processor is part of the tool chain to build a plugin (see Source Processor). This source processor checks the source code and creates automatically additional code. The processor also checks the code style according to the level that is set in the project's projectdefinition.txt file (see Project Tool).

String Resources

The naming scheme of string resource folders was changed. The resource folder that was named "strings_us" is now named "strings_en-US". See Plugin Resources.

Namespaces

The complete MAXON API is defined in the maxon namespace. In contrast, the classic API is defined in the global namespace. To avoid collisions and ambiguity it might be necessary to use fully qualified names.

// This example uses explicit namespaces to use new and classic components.
// creating a maxon::String
maxon::String helloWorld { "Hello World" };
// creating a classic String
::String fooBar { "FooBar" };
Definition: c4d_string.h:41
Definition: string.h:1237

Includes

Wherever possible unneeded includes and umbrella includes were removed. It might be necessary to add additional includes to include specific header files explicitly.

Global Resources

The global resources instances has been renamed to g_resource.

// This example loads the plugin's resources when
// C4DPL_INIT_SYS is sent to PluginMessage().
{
// don't start plugin without resource
if (g_resource.Init() == false)
return false;
return true;
}
GeResource g_resource
Global resources for Cinema 4D.
Bool Init()
#define C4DPL_INIT_SYS
Initialize system.
Definition: c4d_plugin.h:28

Enumerations

Simple enumerations were reformatted as enumeration classes. Since "0" is not a valid enumeration value name it has been replaced with "NONE".

The macro ENUM_END_FLAGS() has been removed. If you have a custom enumeration you have to use MAXON_ENUM_LIST() or MAXON_ENUM_FLAGS().

// This example uses the enumeration value DESCFLAGS_GET::NONE to use GetParameter().
// In previous versions of Cinema 4D this was DESCFLAGS_GET_0.
GeData data;
// access the parameter
if (cubeObject->GetParameter(ConstDescID(DescLevel(PRIM_CUBE_LEN)), data, DESCFLAGS_GET::NONE) == false)
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
// get the value
const Vector size = data.GetVector();
DiagnosticOutput("Cube Size: @", size);
Definition: c4d_gedata.h:83
const Vector & GetVector() const
Definition: c4d_gedata.h:486
Py_ssize_t size
Definition: bytesobject.h:86
#define DiagnosticOutput(formatString,...)
Definition: debugdiagnostics.h:170
#define MAXON_SOURCE_LOCATION
Definition: memoryallocationbase.h:67
#define ConstDescID(...)
Definition: lib_description.h:594
@ PRIM_CUBE_LEN
Definition: ocube.h:6
Represents a level within a DescID.
Definition: lib_description.h:298

Using new Data Types

The MAXON API introduces new data types and replaces or extends classic data types:

  • The new maxon::String class is the base class of the classic String class. To declare a string literal as a maxon::String one can use the "_s" qualifier. The classic API has been refactured to use maxon::String wherever possible. See String Manual.
  • New maxon::Vector and maxon::Matrix classes replace their classic counter parts. The Matrix class has a slightly different internal structure. See Matrices.
  • More explicit data types are available and used. E.g. explicit color types like maxon::ColorA() are used instead of vector types.
// This example creates a sphere object and uses "_s"
// to declare a maxon::String to define the name.
if (sphere == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
// set the name of the new sphere using a maxon::String
sphere->SetName("New Sphere"_s);
doc->InsertObject(sphere, nullptr, nullptr);
void SetName(const maxon::String &name, Bool setDirty=true)
Definition: c4d_baselist.h:2550
Definition: c4d_baseobject.h:248
static BaseObject * Alloc(Int32 type)
#define Osphere
Sphere.
Definition: ge_prepass.h:1120
const char * doc
Definition: pyerrors.h:226

Error System

The MAXON API error system allows functions to return an explicit error state. Several functions of the classic API have been replaced with new functions that do return such an error state e.g. NewObj() or maxon::BaseArray::Append(). It is needed to handle this error state. See Error Handling.

The error system also allows to re-write functions so they return error states. This is extremely helpful to find the source of any error and to write stable code.

// This example shows how errors returned with "iferr_return" can be handled.
// catch any error
{
// print error to console
err.DiagOutput();
// debug stop
err.DbgStop();
};
// create and fill array
intValues.Append(100) iferr_return;
intValues.Append(200) iferr_return;
// allocate memory
// access memory
buffer[0] = 0;
const char ** buffer
Definition: abstract.h:327
Definition: basearray.h:415
MAXON_ATTRIBUTE_FORCE_INLINE ResultRef< T > Append(ARG &&x)
Appends a new element at the end of the array and constructs it using the forwarded value.
Definition: basearray.h:628
Definition: baseref.h:62
#define NewMemClear(T, cnt)
Definition: defaultallocator.h:204
char Char
signed 8 bit character
Definition: apibase.h:198
#define iferr_scope_handler
Definition: resultbase.h:1407
#define iferr_return
Definition: resultbase.h:1524

Terminology

Several functions have been renamed to follow a consistent terminology. Functions like "Content()" that check if a given instance has any content have been renamed to "IsPopulated()" and "IsEmpty()".

// This example uses IsPopulated() and IsEmpty() to check the string.
// create string
const maxon::String someText { "some text" };
// check if populated
if (someText.IsPopulated())
DiagnosticOutput("String is not empty");
// check if empty
if (someText.IsEmpty())
DiagnosticOutput("String is empty");

New Logger System

Cinema 4D R20 introduced a new, complex and adaptable logger system. The standard console is just one of many available loggers now. One can write messages to the standard console using ApplicationOutput() instead of GePrint(). See LoggerInterface Manual.

// This example prints the given message to both the IDE console and the application console window.
// define message
const maxon::String someMessage { "some message" };
// print the message to the console
DiagnosticOutput(someMessage);
// print the message to the application console window
ApplicationOutput(someMessage);
#define ApplicationOutput(formatString,...)
Definition: debugdiagnostics.h:204

Further Reading