Layer Manual

About

Layers are used to organize a Cinema 4D scene. A layer is represented by a LayerObject, its settings are stored in a LayerData object.

// This example creates new layers with distinct colors.
GeListHead* const root = doc->GetLayerObjectRoot();
if (root == nullptr)
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
// create 10 layers with variations
for (Int32 i = 0; i < 20; ++i)
{
LayerObject* const newLayer = LayerObject::Alloc();
if (newLayer == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
// new color
const Vector hsv { Float(i) * 0.05, 1.0, 1.0 };
const Vector rgb = HSVToRGB(hsv);
// define layerData
LayerData layerData;
layerData.color = rgb;
layerData.solo = false;
// set layer settings
newLayer->SetLayerData(doc, layerData);
newLayer->SetName("Layer " + String::IntToString(i));
// insert layer
root->InsertLast(newLayer);
}

LayerObject

A LayerObject represents a layer of a Cinema 4D scene. It is used to assign an element to this layer and to edit the layer.

LayerObject objects are an instance of Olayer.

Access

The LayerObject assigned to an element can be accessed and set with these BaseList2D functions:

Layers are organized in a tree. The root element of that tree is stored in the BaseDocument:

// This example gets the layer root object to access the first layer.
GeListHead* const layers = doc->GetLayerObjectRoot();
if (layers == nullptr)
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
LayerObject* const layer = static_cast<LayerObject*>(layers->GetFirst());
if (layer != nullptr)
ApplicationOutput("First Layer: " + layer->GetName());
Note
To check if a given LayerObject is currently selected in the Layer Manager, read the bit BIT_ACTIVE.

Allocation/Deallocation

LayerObject objects are created with the usual tools:

// This example creates a new layer and assigns it to the "object" entity.
GeListHead* const root = doc->GetLayerObjectRoot();
if (root == nullptr)
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
LayerObject* const newLayer = LayerObject::Alloc();
if (newLayer == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
newLayer->SetName("This is a new layer"_s);
root->InsertLast(newLayer);
// assign
object->SetLayerObject(newLayer);

Navigation

LayerObject objects are based on GeListNode and are organized in a tree. This tree can be navigated with:

// This example checks if the given object is has a layer.
// If so, the topmost parent of that layer is assigned instead.
BaseObject* const object = doc->GetActiveObject();
if (object == nullptr)
return maxon::IllegalArgumentError(MAXON_SOURCE_LOCATION);
LayerObject* const layer = object->GetLayerObject(doc);
if (layer != nullptr)
{
LayerObject* parentLayer = layer;
// search for topmost layer
while (parentLayer->GetUp())
{
parentLayer = parentLayer->GetUp();
}
// assign parent layer
object->SetLayerObject(parentLayer);
}
Note
If a layer is folded in the Layer Manager is controlled with the bit BIT_OFOLD.

LayerData

A LayerData object represents the settings of a layer.

Access

The applied layer settings of an element are accessed with these BaseList2D functions:

These functions can be used on the given element or on a LayerObject object.

// This example get the object's LayerData and prints the color to the console.
const LayerData* const layerData = object->GetLayerData(doc, true);
if (layerData != nullptr)
{
}

Properties

These are the properties of a layer stored in a LayerData object. These properties define how a layer changes the behavior of an element that is assigned to that layer:

// This example creates a new, locked layer and assigns all active objects.
// create layer
GeListHead* const root = doc->GetLayerObjectRoot();
if (root == nullptr)
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
LayerObject* const newLayer = LayerObject::Alloc();
if (newLayer == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
// setup layer and add it to the layer list
LayerData layerData;
layerData.locked = true;
layerData.solo = false;
newLayer->SetLayerData(doc, layerData);
newLayer->SetName("Locked"_s);
root->InsertLast(newLayer);
// get object selection
if (objects == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
// check every objects
for (Int32 i = 0; i < objects->GetCount(); ++i)
{
BaseObject* const object = static_cast<BaseObject*>(objects->GetIndex(i));
if (object == nullptr)
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
object->SetLayerObject(newLayer);
}
Note
When one edits the solo bit it is also necessary to change the NBIT::SOLO_LAYER of the BaseDocument with GeListNode::ChangeNBit() either using NBITCONTROL::SET or NBITCONTROL:: CLEAR.

Utility

  • IsObjectEnabled(): Checks if the given object should be visible in the viewport, including checking the layers.

Further Reading

LayerData::locked
Bool locked
Not selectable and no modification possible, grayed out in Object Manager.
Definition: c4d_basedocument.h:349
BaseList2D::SetLayerObject
Bool SetLayerObject(LayerObject *layer)
LayerObject
Definition: c4d_basedocument.h:245
LayerData::color
Vector color
Layer color.
Definition: c4d_basedocument.h:355
LayerData::solo
Bool solo
Definition: c4d_basedocument.h:344
LayerObject::Alloc
static LayerObject * Alloc(void)
BaseObject
Definition: c4d_baseobject.h:224
Float
maxon::Float Float
Definition: ge_sys_math.h:66
BaseList2D::SetLayerData
Bool SetLayerData(BaseDocument *doc, const LayerData &data)
GeListHead::GetFirst
GeListNode * GetFirst()
Definition: c4d_baselist.h:2053
GETACTIVEOBJECTFLAGS::NONE
@ NONE
None.
AtomArray::GetCount
Int32 GetCount() const
Definition: c4d_baselist.h:1635
MAXON_SOURCE_LOCATION
#define MAXON_SOURCE_LOCATION
Definition: memoryallocationbase.h:66
HSVToRGB
Vector HSVToRGB(const Vector &col)
BaseDocument::GetLayerObjectRoot
GeListHead * GetLayerObjectRoot(void)
String::IntToString
static String IntToString(Int32 v)
Definition: c4d_string.h:495
LayerData
Definition: c4d_basedocument.h:311
BaseList2D::GetLayerObject
LayerObject * GetLayerObject(BaseDocument *doc)
maxon::Vec3< maxon::Float64, 1 >
BaseDocument::GetActiveObjects
void GetActiveObjects(AtomArray &selection, GETACTIVEOBJECTFLAGS flags) const
BaseList2D::SetName
void SetName(const maxon::String &name)
Definition: c4d_baselist.h:2340
Int32
maxon::Int32 Int32
Definition: ge_sys_math.h:60
ApplicationOutput
#define ApplicationOutput(formatString,...)
Definition: debugdiagnostics.h:207
LayerObject::GetUp
LayerObject * GetUp(void)
Definition: c4d_basedocument.h:289
GeListHead::InsertLast
void InsertLast(GeListNode *bn)
Definition: c4d_baselist.h:2081
AutoAlloc
Definition: ge_autoptr.h:36
BaseDocument::GetActiveObject
BaseObject * GetActiveObject(void)
BaseList2D::GetName
String GetName() const
Definition: c4d_baselist.h:2334
String::VectorToString
static String VectorToString(const Vector32 &v, Int32 nnk=-1)
Definition: c4d_string.h:571
GeListHead
Definition: c4d_baselist.h:1996
AtomArray::GetIndex
C4DAtom * GetIndex(Int32 idx) const
Definition: c4d_baselist.h:1650