BaseTake Manual

About

A BaseTake object represents a take of the Take System. It stores BaseOverride objects that define how a specific entity is changed in the given take.

Access

BaseTake objects are returned from the BaseDocument via the TakeData object.

// This example accesses the main take of the
// given BaseDocument.
// get take data
TakeData* const takeData = doc->GetTakeData();
if (takeData == nullptr)
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
// get the main take
BaseTake* const mainTake = takeData->GetMainTake();
if (mainTake == nullptr)
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);

Allocation/Deallocation

A BaseTake is created and deleted using the TakeData object:

// This example creates a new take and makes it the first child of the main take
// get the main take
BaseTake* const mainTake = takeData->GetMainTake();
if (mainTake == nullptr)
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
// create new take
BaseTake* const newTake = takeData->AddTake("this is a new take", nullptr, nullptr);
if (newTake == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
takeData->InsertTake(newTake, mainTake, INSERT_UNDER);
Note
Always use TakeData::AddTake() to clone a take.

Navigation

Like many other entities takes are organized in a BaseList2D tree. One can use the typical functions to navigate that tree.

// This example loops through all takes that are direct child takes of the main take.
// get main take
const BaseTake* const mainTake = takeData->GetMainTake();
// get first child
const BaseTake* take = mainTake->GetDown();
// loop through
while (take != nullptr)
{
ApplicationOutput("Take Name: " + take->GetName());
// get next take in the row
take = take->GetNext();
}

Marked

Takes can be marked in the Take Manager. This allows to render just a subset of all takes. The API allows to manage this marked state:

// This example loops through the takes and inverts the checked state.
BaseTake* take = mainTake->GetDown();
while (take != nullptr)
{
// get checked
const Bool marked = take->IsChecked();
// set inverted
take->SetChecked(!marked);
take = take->GetNext();
}

Utility

Overrides

BaseOverride

A BaseOverride defines the parameter changes for a specific object in a BaseTake. BaseOverrides are managed using methods of BaseTake:

// This example searches for an existing override for the active object in the given take.
BaseObject* const object = doc->GetActiveObject();
if (object == nullptr)
return maxon::IllegalArgumentError(MAXON_SOURCE_LOCATION);
BaseOverride* const baseOverride = take->FindOverride(takeData, object);
if (baseOverride != nullptr)
{
ApplicationOutput("Found BaseOverride");
}

Overrides can also be created automatically:

// This example creates a new take and overrides for the currently selected object.
BaseObject* const activeObject = doc->GetActiveObject();
if (activeObject == nullptr)
return maxon::IllegalArgumentError(MAXON_SOURCE_LOCATION);
BaseTake* const newTake = takeData->AddTake("this is a new take", nullptr, nullptr);
if (newTake == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
BaseOverride* const activeObjectOverride = newTake->OverrideNode(takeData, activeObject, false);
if (activeObjectOverride == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);

BaseTake::AutoTake() is especially useful to create the proper overrides when "Auto Take" is enabled. Just an unaltered clone of the changed object or the reference object from the undo stack is required:

// This example edits the given sphere object.
// If auto take is enabled, the current take is used.
// undo object as reference
// alternatively, on could access the undo cache with BaseDocument::GetUndoPtr() if applicable
BaseObject* undoObject = static_cast<BaseObject*>(sphereObject->GetClone(COPYFLAGS::NONE, nullptr));
if (undoObject == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
// edit the object
sphereObject->SetParameter(DescID { PRIM_SPHERE_RAD }, GeData(100.0), DESCFLAGS_SET::NONE);
// check for autotake
TakeData* const takeData = doc->GetTakeData();
// check if auto take mode is enabled
if (takeData && takeData->GetTakeMode() == TAKE_MODE::AUTO)
{
BaseTake* const currentTake = takeData->GetCurrentTake();
// check if the given take is not the main take
if (currentTake && !currentTake->IsMain())
{
currentTake->AutoTake(takeData, sphereObject, undoObject);
}
}
// free the clone
BaseObject::Free(undoObject);

BaseOverrideGroup

Override groups act like virtual null objects. They allow to add certain tags to a selection of objects.

// This example adds a new take and creates a new override group for all selected objects.
// If a material with the name "Green" exists a texture tag referencing that material
// is added to the override group.
AutoAlloc<AtomArray> selectedObjects;
if (selectedObjects == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
if (selectedObjects->GetCount() == 0)
return maxon::OK;
// new take
BaseTake* const take = takeData->AddTake("Green Objects", nullptr, nullptr);
if (take == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
// create override group
BaseOverrideGroup* const group = take->AddOverrideGroup();
if (group == nullptr)
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
group->SetName("Green Material"_s);
// if the material was found a texture tag should be added
BaseMaterial* const mat = doc->SearchMaterial("Green"_s);
if (mat != nullptr)
group->AddTag(takeData, Ttexture, mat);
// loop through all selected objects
for (Int32 i = 0; i < selectedObjects->GetCount(); ++i)
{
BaseList2D* const element = static_cast<BaseList2D*>(selectedObjects->GetIndex(i));
group->AddToGroup(takeData, element);
}

Camera

Takes also manage the camera currently in use. These functions allow to set and get the camera used for a certain take:

  • BaseTake::GetCamera(): Returns the camera used by this take which could also be the default camera or nullptr if the parent take's camera should be used.
  • BaseTake::GetEffectiveCamera(): Returns the camera that is effectively used by the given take.
  • BaseTake::SetCamera(): Sets the camera used for this take. nullptr means the parent take's settings should apply.
// This example creates a new take for each currently selected camera object.
// get the currently selected objects
AutoAlloc<AtomArray> selectedObjects;
if (selectedObjects == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
// loop through all selected objects
for (Int32 i = 0; i < selectedObjects->GetCount(); ++i)
{
C4DAtom* const element = selectedObjects->GetIndex(i);
if (element == nullptr)
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
// check if the object is a camera object
if (element->GetType() == Ocamera)
{
CameraObject* const camera = static_cast<CameraObject*>(element);
// create a take for this camera object
const String takeName { "Take for camera " + camera->GetName() };
BaseTake* const cameraTake = takeData->AddTake(takeName, nullptr, nullptr);
if (cameraTake == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
// set this camera object as this take's camera
cameraTake->SetCamera(takeData, camera);
}
}

Render Settings

Takes also manage render settings. As with the camera, it is possible to assign specific render settings to each take.

// This example gets the first RenderData and loops through all RenderData objects in that list.
// This won't loop through all RenderData elements since it ignores
// the child objects of these elements.
RenderData* renderData = doc->GetFirstRenderData();
while (renderData != nullptr)
{
// create new take
const String renderDataName = renderData->GetName();
const String takeName = "Take for RenderData " + renderDataName;
BaseTake* const renderDataTake = takeData->AddTake(takeName, nullptr, nullptr);
if (renderDataTake == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
// set this RenderData as this take's RenderData
renderDataTake->SetRenderData(takeData, renderData);
// get next element in the list
renderData = renderData->GetNext();
}

Userdata

A BaseTake can host userdata that can help to identify the take along the production pipeline. This userdata is managed using the default BaseList2D methods:

// This example adds a new Boolean userdata parameter to the given BaseTake.
// accesses the userdata of the given take
if (desc == nullptr)
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
// defines a new Boolean parameter
bc.SetString(DESC_NAME, "Enable"_s);
// creates the new userdata parameter
const DescID userData = desc->Alloc(bc);
// sets the value
const GeData data { true };
take->SetParameter(userData, data, DESCFLAGS_SET::NONE);

See also DynamicDescription Manual.

Utility

// This example resets the current take if it is not the main take
BaseTake* const take = takeData->GetCurrentTake();
if (take == nullptr)
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
if (!take->IsMain())
take->Reset();

Further Reading

DTYPE_BOOL
@ DTYPE_BOOL
GV Bool. ID_GV_DATA_TYPE_BOOL.
Definition: lib_description.h:75
C4DAtom::GetDynamicDescription
DynamicDescription * GetDynamicDescription()
BaseTake::AddOverrideGroup
BaseOverrideGroup * AddOverrideGroup()
BaseTake::IsChecked
Bool IsChecked()
GetCustomDataTypeDefault
BaseContainer GetCustomDataTypeDefault(Int32 type)
BaseList2D
Definition: c4d_baselist.h:2174
TAKE_MODE::AUTO
@ AUTO
Auto override: the system overrides any edited parameter (similar to Auto Key).
BaseOverrideGroup
Definition: lib_takesystem.h:180
BaseDocument::GetFirstRenderData
RenderData * GetFirstRenderData(void)
BaseTake::Reset
void Reset()
CameraObject
Definition: c4d_baseobject.h:1253
BaseObject
Definition: c4d_baseobject.h:224
TakeData::InsertTake
void InsertTake(BaseTake *takeToMove, BaseTake *destTake, Int32 insertMode)
DescID
Definition: lib_description.h:328
BaseTake
Definition: lib_takesystem.h:319
BaseDocument::SearchMaterial
BaseMaterial * SearchMaterial(const maxon::String &str)
BaseOverrideGroup::AddToGroup
void AddToGroup(TakeData *takeData, BaseList2D *node)
BaseContainer::SetString
void SetString(Int32 id, const maxon::String &s)
Definition: c4d_basecontainer.h:569
BaseTake::SetRenderData
void SetRenderData(TakeData *takeData, RenderData *rData)
BaseOverride
Definition: lib_takesystem.h:78
BaseTake::IsMain
Bool IsMain()
maxon::OK
return OK
Definition: apibase.h:2620
TakeData::AddTake
BaseTake * AddTake(const String &name, BaseTake *parent, BaseTake *cloneFrom)
GETACTIVEOBJECTFLAGS::NONE
@ NONE
None.
TakeData::GetMainTake
BaseTake * GetMainTake()
BaseOverrideGroup::AddTag
BaseTag * AddTag(TakeData *takeData, Int32 type, BaseMaterial *mat)
AtomArray::GetCount
Int32 GetCount() const
Definition: c4d_baselist.h:1649
MAXON_SOURCE_LOCATION
#define MAXON_SOURCE_LOCATION
Definition: memoryallocationbase.h:67
Ocamera
#define Ocamera
Camera - CameraObject.
Definition: ge_prepass.h:1010
DESCFLAGS_SET::NONE
@ NONE
None.
RenderData::GetNext
RenderData * GetNext(void)
Definition: c4d_basedocument.h:174
TakeData
Definition: lib_takesystem.h:573
BaseTake::GetNext
BaseTake * GetNext() const
Definition: lib_takesystem.h:338
BaseTake::SetCamera
void SetCamera(TakeData *takeData, BaseObject *camera)
String
Definition: c4d_string.h:38
C4DAtom::SetParameter
Bool SetParameter(const DescID &id, const GeData &t_data, DESCFLAGS_SET flags)
TakeData::GetCurrentTake
BaseTake * GetCurrentTake()
INSERT_UNDER
#define INSERT_UNDER
Insert under.
Definition: customgui_listview.h:591
BaseDocument::GetTakeData
TakeData * GetTakeData()
BaseDocument::GetActiveObjects
void GetActiveObjects(AtomArray &selection, GETACTIVEOBJECTFLAGS flags) const
GeData
Definition: c4d_gedata.h:82
C4DAtom
Definition: c4d_baselist.h:1361
BaseList2D::SetName
void SetName(const maxon::String &name)
Definition: c4d_baselist.h:2354
Int32
maxon::Int32 Int32
Definition: ge_sys_math.h:60
ApplicationOutput
#define ApplicationOutput(formatString,...)
Definition: debugdiagnostics.h:210
Ttexture
#define Ttexture
Texture - TextureTag.
Definition: ge_prepass.h:1270
BaseTake::OverrideNode
BaseOverride * OverrideNode(TakeData *takeData, BaseList2D *node, Bool deleteAnim)
BaseTake::SetChecked
void SetChecked(Bool status)
AutoAlloc
Definition: ge_autoptr.h:36
BaseObject::Free
static void Free(BaseObject *&bl)
DESC_NAME
@ DESC_NAME
String Name for standalone use.
Definition: lib_description.h:91
RenderData
Definition: c4d_basedocument.h:142
Bool
maxon::Bool Bool
Definition: ge_sys_math.h:55
BaseDocument::GetActiveObject
BaseObject * GetActiveObject(void)
BaseList2D::GetName
String GetName() const
Definition: c4d_baselist.h:2348
PRIM_SPHERE_RAD
@ PRIM_SPHERE_RAD
Definition: osphere.h:6
BaseTake::FindOverride
BaseOverride * FindOverride(TakeData *takeData, BaseList2D *node)
C4DAtom::GetType
Int32 GetType() const
Definition: c4d_baselist.h:1378
BaseMaterial
Definition: c4d_basematerial.h:27
DynamicDescription
Definition: lib_description.h:734
BaseTake::GetDown
BaseTake * GetDown() const
Definition: lib_takesystem.h:356
TakeData::GetTakeMode
TAKE_MODE GetTakeMode()
DynamicDescription::Alloc
DescID Alloc(const BaseContainer &datadescription)
BaseTake::AutoTake
void AutoTake(TakeData *takeData, BaseList2D *node, BaseList2D *undo)
COPYFLAGS::NONE
@ NONE
None.
BaseContainer
Definition: c4d_basecontainer.h:46
AtomArray::GetIndex
C4DAtom * GetIndex(Int32 idx) const
Definition: c4d_baselist.h:1664