BaseObject Manual

About

BaseObject is the base class of all scene objects of Cinema 4D. These objects can be polygon objects, splines, generators, deformers, effectors, cameras, lights or objects like the "Sky" or "Background" object.

BaseObject objects are an instance of Obase.

A BaseObject may be also a:

See also Flags.

Access

BaseObject objects are typically stored in and accessed from a BaseDocument:

  • BaseDocument::GetFirstObject(): Returns the first BaseObject of the scene.
  • BaseDocument::InsertObject(): Inserts a BaseObject into the scene.
  • BaseDocument::SearchObject(): Searches for a BaseObject with the given name.

See BaseDocument Objects and Selections.

// This example searches for an object named "Cube".
// If it cannot be found a new cube with that name will be created.
BaseObject* const object = doc->SearchObject("Cube"_s);
if (object != nullptr)
{
ApplicationOutput("found \"Cube\""_s);
return maxon::OK;
}
BaseObject* const cubeObject = BaseObject::Alloc(Ocube);
if (cubeObject == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
cubeObject->SetName("Cube"_s);
doc->InsertObject(cubeObject, nullptr, nullptr);
return OK
Definition: apibase.h:2740
#define Ocube
Cube.
Definition: ge_prepass.h:1118
#define MAXON_SOURCE_LOCATION
Definition: memoryallocationbase.h:69
#define ApplicationOutput(formatString,...)
Definition: debugdiagnostics.h:204
const char * doc
Definition: pyerrors.h:226

Allocation/Deallocation

BaseObject objects are created with the usual tools:

  • BaseObject::Alloc(): Creates a new BaseObject.
  • BaseObject::Free(): Deletes the given BaseObject.

The object IDs of many build-in object types are defined in Object Types.

// This example shows how to create a new "Cube" object and how to insert it into the document.
BaseDocument* const document = GetActiveDocument();
if (document == nullptr)
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
BaseObject* const cubeObject = BaseObject::Alloc(Ocube);
if (cubeObject == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
cubeObject->SetName("This is a new object"_s);
document->InsertObject(cubeObject, nullptr, nullptr);
BaseDocument * GetActiveDocument()
void EventAdd(EVENT eventflag=EVENT::NONE)

Primitive objects can also be created with these dedicated functions:

New objects are typically added to a BaseDocument that takes ownership:

  • BaseDocument::InsertObject(): Inserts a BaseObject into the scene.
  • GeListNode::InsertUnder(): Inserts the element under the given element.
  • InsertCreateObject(): This function takes care for modifiers to add the given object in the given BaseDocument at a certain place in the hierarchy.
// This example accesses the currently active object.
// If an object is found a new Sphere is created and inserted under the found object.
BaseObject* const parentObject = doc->GetActiveObject();
if (parentObject == nullptr)
return maxon::IllegalArgumentError(MAXON_SOURCE_LOCATION);
BaseObject* const newSphere = BaseObject::Alloc(Osphere);
if (newSphere == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
newSphere->InsertUnder(parentObject);
#define Osphere
Sphere.
Definition: ge_prepass.h:1119

Remove

A BaseObject can be removed from the host BaseDocument:

// The example removes the active object from the document.
BaseObject* object = doc->GetActiveObject();
if (object == nullptr)
return maxon::IllegalArgumentError(MAXON_SOURCE_LOCATION);
object->Remove();
BaseObject::Free(object);

Navigate

BaseObject elements are organized in a tree. The usual functions can be used to navigate in that tree:

  • BaseObject::GetNext(): Returns the next BaseObject in the list.
  • BaseObject::GetPred(): Returns the previous BaseObject in the list.
  • BaseObject::GetUp(): Returns the parent BaseObject.
  • BaseObject::GetDown(): Returns the first child BaseObject.
  • BaseObject::GetDownLast(): Returns the last child BaseObject.
  • BaseObject::SearchHierarchy(): Checks if the objects is child of the given BaseObject.

See also Navigation in Lists and Trees.

// This example function iterates through all objects
// of the object tree defined by the given BaseObject.
static void CheckObjects(BaseObject* obj)
{
while (obj != nullptr)
{
ApplicationOutput("Object Name: " + obj->GetName());
CheckObjects(obj->GetDown());
obj = obj->GetNext();
}
}
PyObject * obj
Definition: complexobject.h:60

Read-Only Properties

Bounding Box

The bounding box defines the dimensions of a BaseObject.

  • BaseObject::GetMp(): Returns the object's bounding box center in local space.
  • BaseObject::GetRad(): Returns the object's bounding box radius (x/y/z).
// This example creates a cube with the size of the bounding box.
const Vector bbCenter = object->GetMp();
const Vector bbRadius = object->GetRad();
BaseObject* const cube = BaseObject::Alloc(Ocube);
if (cube == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
cube->SetParameter(ConstDescID(DescLevel(PRIM_CUBE_LEN)), bbRadius * 2.0, DESCFLAGS_SET::NONE);
cube->SetParameter(ConstDescID(DescLevel(ID_BASEOBJECT_REL_POSITION)), bbCenter, DESCFLAGS_SET::NONE);
cube->InsertUnder(object);
NONE
Definition: asset_browser.h:1
#define ConstDescID(...)
Definition: lib_description.h:592
maxon::Vec3< maxon::Float64, 1 > Vector
Definition: ge_math.h:140
@ ID_BASEOBJECT_REL_POSITION
Definition: obase.h:15
@ PRIM_CUBE_LEN
Definition: ocube.h:6

Cache

Generator objects store virtual child objects in a cache. If a deformer is applied, the deformed child objects are found in the deform cache.

  • BaseObject::GetCache(): Returns the object from the previously built cache. The returned object may have child objects.
  • BaseObject::GetDeformCache(): Returns the previously built cache that has been deformed by an active deformer.
  • BaseObject::GetCacheParent(): If the BaseObject is in a cache this function will return the parent generator.
// This function can be used to recursively search the cache
// of a given BaseObject for polygon objects.
static void DoRecursion(BaseObject* op)
{
// Check the deform cache
BaseObject* tp = op->GetDeformCache();
if (tp)
{
DoRecursion(tp);
}
else
{
// check the cache
tp = op->GetCache();
if (tp)
{
DoRecursion(tp);
}
else
{
// check if generator
if (!op->GetBit(BIT_CONTROLOBJECT))
{
// check if polygon object
if (op->IsInstanceOf(Opolygon))
{
ApplicationOutput("Found polygon data"_s);
}
}
}
}
// loop through child objects
for (tp = op->GetDown(); tp; tp = tp->GetNext())
{
DoRecursion(tp);
}
}
#define BIT_CONTROLOBJECT
Internal bit set by generators.
Definition: ge_prepass.h:904
#define Opolygon
Polygon - PolygonObject.
Definition: ge_prepass.h:1041
PyObject * op
Definition: object.h:520

See also Generating.

Miscellaneous

Further functions are:

  • BaseObject::GetGUID(): Returns a unique ID for any object in a document. This unique ID is a checksum based on several object properties.
  • BaseObject::GetHighlightHandle(): Only needed if one draws handles in a plugin.
  • BaseObject::GetRealSpline(): Returns a real spline representation of a primitive spline object. See also Flags.
// This example casts the given BaseObject into SplineObject
// if it is a spline or if it is a spline generator.
SplineObject* spline = nullptr;
// check if the object is a "Spline" object
if (object->IsInstanceOf(Ospline))
spline = ToSpline(object);
// check if the object is a spline generator
else if (object->GetInfo() & OBJECT_ISSPLINE)
spline = object->GetRealSpline();
if (spline != nullptr)
ApplicationOutput("Spline Object: " + spline->GetName());
#define OBJECT_ISSPLINE
Spline object.
Definition: ge_prepass.h:951
#define Ospline
Spline - SplineObject.
Definition: ge_prepass.h:1042
MAXON_ATTRIBUTE_FORCE_INLINE const SplineObject * ToSpline(const T *op)
Casts a BaseObject* to a SplineObject*.
Definition: c4d_baseobject.h:2405
Definition: object.h:105

Properties

Parameters

The basic parameters IDs of a BaseObject are defined in obase.h. They can be changed using C4DAtom::SetParameter() and C4DAtom::GetParameter(). For several properties dedicated functions exist.

PSR

The placement of an object is defined by its position, scale and rotation (PSR). Freeze Transformations allow to define a default or reset value. In short, the absolute value is the frozen value plus the relative value.

Note
The "absolute" values are not the world space values.

These functions give access to the "absolute" values:

  • BaseObject::GetAbsPos(): Returns the absolute position.
  • BaseObject::SetAbsPos(): Sets the absolute position.
  • BaseObject::GetAbsScale(): Returns the absolute scale.
  • BaseObject::SetAbsScale(): Sets the absolute scale.
  • BaseObject::GetAbsRot(): Returns the absolute rotation.
  • BaseObject::SetAbsRot(): Sets the absolute rotation.

These functions give access to the "frozen" values:

  • BaseObject::GetFrozenPos(): Returns the frozen position.
  • BaseObject::SetFrozenPos(): Sets the frozen position.
  • BaseObject::GetFrozenScale(): Returns the frozen scale.
  • BaseObject::SetFrozenScale(): Sets the frozen scale.
  • BaseObject::GetFrozenRot(): Returns the frozen rotation.
  • BaseObject::SetFrozenRot(): Sets the frozen rotation.

These functions give access to the "relative" values:

  • BaseObject::GetRelPos(): Returns the relative position.
  • BaseObject::SetRelPos(): Sets the relative position.
  • BaseObject::GetRelScale(): Returns the relative scale.
  • BaseObject::SetRelScale(): Sets the relative scale.
  • BaseObject::GetRelRot(): Returns the relative rotation.
  • BaseObject::SetRelRot(): Sets the relative rotation.

These functions are used to access the local and global Matrix of an object:

  • BaseObject::GetMg(): Returns the world (global) matrix.
  • BaseObject::SetMg(): Sets the world (global) matrix.
  • BaseObject::GetMgn(): Returns the world (global) normalized matrix.
  • BaseObject::GetMl(): Returns the local matrix.
  • BaseObject::SetMl(): Sets the local matrix.
  • BaseObject::GetFrozenMln(): Returns the frozen and normalized matrix of the object.
  • BaseObject::GetRelMln(): Returns the relative and normalized matrix of the object.
  • BaseObject::GetRelMl(): Returns the relative matrix of the object.
  • BaseObject::SetRelMl(): Sets the relative matrix of the object.
  • BaseObject::GetMln(): Returns the local normalized matrix.
  • BaseObject::GetUpMg(): Returns the world (global) matrix of the parent object.
  • BaseObject::CopyMatrixTo(): Copies the object's matrix to the given BaseObject.
// This example reads the global matrix of the given object
// and applies it to the newly created BaseObject.
const Matrix mg = object->GetMg();
BaseObject* const cube = BaseObject::Alloc(Ocube);
if (cube == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
doc->InsertObject(cube, nullptr, nullptr);
cube->SetMg(mg);
maxon::Mat3< maxon::Vector64 > Matrix
Definition: ge_math.h:159

See also Vector Manual (Cinema API) and Matrix Manual (Cinema API).

Visibility

A BaseObject may or may not be visible in the editor and rendered output.

  • BaseObject::GetEditorMode(): Returns the editor mode of the object.
  • BaseObject::SetEditorMode(): Sets the editor mode of the object.
  • BaseObject::GetRenderMode(): Returns the render mode of the object.
  • BaseObject::SetRenderMode(): Sets the render mode of the object.

The modes are:

  • MODE_ON: The object is enabled regardless of the state of any parent object.
  • MODE_OFF: The object is disabled regardless of the state of any parent object.
  • MODE_UNDEF: The object is enabled by default, but the state of any parent object is used if it is enabled or disabled.
// This example synchronizes editor and render mode if the render mode is off.
const Int32 mode = object->GetRenderMode();
if (mode == MODE_OFF)
object->SetEditorMode(MODE_OFF);
const wchar_t * mode
Definition: fileutils.h:96
#define MODE_OFF
The object is disabled regardless of the state of any parent object.
Definition: c4d_baseobject.h:37
maxon::Int32 Int32
Definition: ge_sys_math.h:51
Note
CheckEditorVisibility() checks the editor mode effect and layer settings of the given object, see Utility.

Generator / Deformer enabled

If an object is a generator or deformer it can be enabled or disabled:

  • BaseObject::GetDeformMode(): Returns the enabled mode.
  • BaseObject::SetDeformMode(): Sets the enabled mode.
// This example checks if the given object is a SDS.
// If so it gets disabled.
// check if the object is a
// "Subdivision Surface"
if (object->IsInstanceOf(Osds))
{
object->SetDeformMode(false);
}
#define Osds
SDS (HyperNURBS) - SDSObject.
Definition: ge_prepass.h:1157

Tags

A BaseObject can host a variable number of tags. These tags add additional functionality and data to the object.

See also BaseTag and VariableTag Manual.

Warning
Since R17 the Take System can add and own tags. See Take System Overview.

Existing tags can be accessed with:

  • BaseObject::GetFirstTag(): Returns the first tag of the object.
  • BaseObject::GetTag(): Returns a tag of the given type if existing on the host object.
  • BaseObject::GetLastTag(): Returns the last tag of the host object.
  • BaseObject::GetTagDataR(): Returns a pointer to the read-only data of the VariableTag.
  • BaseObject::GetTagDataW(): Returns a pointer to the writeable data of the VariableTag.
  • BaseObject::GetTagDataCount(): Returns the number of elements stored in the VariableTag.
// This example loops through the tags of the given object.
BaseTag* tag = object->GetFirstTag();
while (tag != nullptr)
{
ApplicationOutput("Tag: " + tag->GetName());
tag = tag->GetNext();
}

New tags can be created:

  • BaseObject::MakeTag(): Creates a new BaseTag of the given type.
  • BaseObject::MakeVariableTag(): Creates a new VariableTag of the given type.
  • BaseObject::InsertTag(): Inserts the given BaseTag into the object's tag list.
  • BaseObject::SetPhong(): Creates a Phong tag.
// This example checks if the given object owns a "Protection" tag.
// If not, the "Protection" tag is created.
BaseTag* protectionTag = object->GetTag(Tprotection);
if (protectionTag == nullptr)
{
protectionTag = object->MakeTag(Tprotection);
if (protectionTag == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
}
#define Tprotection
Protection.
Definition: ge_prepass.h:1422

and

// This example adds a Phong tag to the given object.
object->SetPhong(true, true, DegToRad(60.0));
Float32 DegToRad(Float32 r)
Definition: apibasemath.h:256

Further tag related functionality:

  • BaseObject::KillTag(): Deletes a hosted tag of the given type.
  • BaseObject::CopyTagsTo(): Copies the tags of this object onto the given BaseObject.
  • BaseObject::GetVisibility(): Gets the visibility of the assigned Display tag.
// This example removes all "Annotation" tags from the given object.
// loop until no "Annotation" tag can be found anymore
while (object->GetTag(Tannotation))
{
object->KillTag(Tannotation);
}
#define Tannotation
Annotation.
Definition: ge_prepass.h:1426

Color

A BaseObject can have an assigned color and can be displayed in xray mode:

  • BaseObject::GetColorProperties(): Gets the object's color properties.
  • BaseObject::SetColorProperties(): Sets the object's color properties.

The settings are:

  • ObjectColorProperties::usecolor: The color mode. See obase.h for values.
  • ObjectColorProperties::color: The color.
  • ObjectColorProperties::xray: True if xray mode is enabled.
// This example reads the color settings of the given object.
ObjectColorProperties objColor;
object->GetColorProperties(&objColor);
ApplicationOutput("Color: " + String::VectorToString(objColor.color));
Note
To set the color of virtual objects in ObjectData::GetVirtualObjects() a generator must be registered with OBJECT_USECACHECOLOR, see Flags and Generating.

Modeling Axis

In certain modeling modes a modeling axis is presented as the result of the current selection.

  • BaseObject::GetModelingAxis(): Returns the modeling axis matrix.
  • BaseObject::SetModelingAxis(): Sets the modeling axis matrix.
// This example creates a new cube object using the modeling axis of the given object.
const Matrix mat = object->GetModelingAxis(doc);
BaseObject* const cube = BaseObject::Alloc(Ocube);
if (cube == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
cube->SetMg(mat);
doc->InsertObject(cube, nullptr, nullptr);
Note
The axis of a multiselection can be obtained from the document, see BaseDocument Axis and Plane.

Generating

A generator object creates virtual and cached BaseObject elements in its ObjectData::GetVirtualObjects() function. The following BaseObject member functions are only used in this context.

While creating the cache one should typically check if the cache is already build:

  • BaseObject::CheckCache(): Returns true if the cache is build and matches the requirements.
// This code checks if the cache or the object is dirty.
// If not, the existing cache is returned.
Bool dirty = op->CheckCache(hh) || op->IsDirty(DIRTYFLAGS::DATA);
if (!dirty)
return op->GetCache();
DATA
Data accessible via Get/SetParameter (including data stored in the BaseContainer and the DIRTYFLAGS::...
Definition: c4d_accessedobjects.h:6
maxon::Bool Bool
Definition: ge_sys_math.h:46

See also Cache.

Generators can use child objects as input objects (see flag OBJECT_INPUT). A generator can check if these child objects are dirty and it can hide them in the viewport. The most simple way is to handle the child objects manually:

  • BaseObject::IsDirty(): Returns true if the object has been changed since the last time the object was touched.
  • BaseObject::SetDirty(): Sets the dirty flags if any part of the object was changed.
  • BaseObject::Touch(): Marks objects to be used by a generator. Automatically resets dirty values for use with BaseObject::IsDirty().
  • BIT_CONTROLOBJECT: Input objects are marked by a generator with this bit using BaseObject::Touch(). This bit is also set for the generator object itself.
// This example checks if the child object is dirty and "touches" it so it will be hidden.
Bool dirty = false;
BaseObject* const childObject = op->GetDown();
if (childObject != nullptr)
{
dirty = childObject->IsDirty(DIRTYFLAGS::MATRIX | DIRTYFLAGS::DATA);
childObject->Touch();
}
MATRIX
The matrix will be accessed (including e.g. frozen matrix). This doesn't include the global matrix.
Definition: c4d_accessedobjects.h:3

To handle multiple child objects a dependence list can be used:

  • BaseObject::NewDependenceList(): Starts a new dependence list.
  • BaseObject::AddDependence(): Adds a child object to the dependence list.
  • BaseObject::CompareDependenceList(): Compares if anything in the dependence list has changed.
  • BaseObject::TouchDependenceList(): Marks all the objects in the dependence list to be replaced by the generator.
// This example adds only the cube child objects to the dependencies list.
op->NewDependenceList();
BaseObject* child = op->GetDown();
while (child != nullptr)
{
// check if the child object is a "Cube" object
if (child->GetType() == Ocube)
{
op->AddDependence(child);
}
child = child->GetNext();
}
if (!dirty)
dirty = !op->CompareDependenceList();
op->TouchDependenceList();

But the most simple way is to use one of these two functions: They will return polygon versions of the child objects and hide them:

  • BaseObject::GetHierarchyClone(): Generates a clone of the child objects of the parent generator.
  • BaseObject::GetAndCheckHierarchyClone(): Similar to GetHierarchyClone() but if the hierarchy is not dirty no new clone is created.
Note
In some special cases (eg, Matrix Object) these functions don't work as expected (eg, wrong dirtiness). In these cases, a custom cache handling is needed.
// This example gets a polygon clone of the first child object.
// If the child object is not dirty, the returned object is the cache.
Bool dirty = false;
BaseObject* const childObject = op->GetDown();
if (childObject != nullptr)
{
BaseObject* const clone = op->GetAndCheckHierarchyClone(hh, childObject, flags, &dirty, nullptr, false);
if (!dirty)
return clone;
// Fill the cache based on the polygon clone.
// ...
PyCompilerFlags * flags
Definition: ast.h:14
ASPOLY
Objects cloned as polygons. (Used by e.g. HyperNURBS.)
Definition: ge_prepass.h:2
HIERARCHYCLONEFLAGS
Definition: ge_prepass.h:3426

If a generator creates multiple child objects each object must be uniquely identifiable. If the flag OBJECT_UNIQUEENUMERATION is set each object can receive an unique IP number.

  • BaseObject::GetUniqueIP(): Returns the unique IP number.
  • BaseObject::SetUniqueIP(): Sets the unique IP number.
Note
The unique IP must not be zero.
// This example creates some cube objects with a unique IP.
Vector pos = Vector(0, 0, 0);
for (Int32 i = 1; i < 11; ++i)
{
BaseObject* const cube = BaseObject::Alloc(Ocube);
if (cube != nullptr)
{
cube->InsertUnder(parent);
cube->SetAbsPos(pos);
cube->SetUniqueIP(i);
pos.x += 250.0;
}
}
Py_ssize_t i
Definition: abstract.h:645
void Py_ssize_t * pos
Definition: dictobject.h:50

Isoparm lines can be used to display and accentuate certain lines in the viewport.

  • BaseObject::GetIsoparm(): Returns the isoparm LineObject.
  • BaseObject::SetIsoparm(): Sets the isoparm LineObject.
// This example creates a simple Line object and assigns it to the given polygon object.
LineObject* const lineObject = LineObject::Alloc(2, 1);
if (lineObject != nullptr)
{
Segment* const segments = lineObject->GetSegmentW();
Vector* const linePoints = lineObject->GetPointW();
// check pointers
if (segments && linePoints)
{
segments[0].cnt = 2;
linePoints[0] = Vector(0, 0, 0);
linePoints[1] = Vector(0, 1000, 0);
lineObject->Message(MSG_UPDATE);
polyObject->SetIsoparm(lineObject);
}
}
#define MSG_UPDATE
Must be sent if the bounding box has to be recalculated. (Otherwise use MSG_CHANGE....
Definition: c4d_baselist.h:372

Rotation Order

In Cinema 4D the rotation of an object is stored as a ::Vector. Each component of this vector corresponds to a rotation axis. The rotation result depends on the order in which the rotation is executed. For values see ::ROTATIONORDER.

  • BaseObject::GetRotationOrder(): Returns the object's rotation order.
  • BaseObject::SetRotationOrder(): Sets the object's rotation order.
// This example simply sets the default rotation order.
object->SetRotationOrder(ROTATIONORDER::DEFAULT);
DEFAULT
Default.
Definition: lib_ca.h:4
Note
Typically used with MatrixToHPB() and HPBToMatrix(). See Matrix Manual (Cinema API).

The rotation values of an animation can be optimized:

  • BaseObject::FindBestEulerAngle(): Modifies the rotation values of the given rotation track to find the best Euler angle.
// This example checks the rotation tracks of the given object.
// FindBestEulerAngle() will modify the existing keys to find the best angles.
obj->FindBestEulerAngle(ID_BASEOBJECT_REL_ROTATION, true, false);
// animate the object so it uses the new key values
doc->AnimateObject(obj, doc->GetTime(), ANIMATEFLAGS::NONE);
@ ID_BASEOBJECT_REL_ROTATION
Definition: obase.h:16

Quaternion Rotation Mode

The (animated) rotation values of an object can be interpolated using quaternions.

  • BaseObject::IsQuaternionRotationMode(): Returns true if the rotation is interpolated in quaternion mode.
  • BaseObject::SetQuaternionRotationMode(): Sets the object's interpolation mode.
// This example checks if the given object uses quaternion interpolation.
// If not quaternion interpolation is enabled.
// check if the object uses quaternion interpolation
if (obj->IsQuaternionRotationMode() == false)
{
// turn on quaternion interpolation.
// this will update the rotation animation tracks
obj->SetQuaternionRotationMode(true, false);
}

The use of quaternion interpolation can be forced with:

  • BaseObject::EvaluateSynchronizedRotation(): Evaluates all rotation tracks using quaternion interpolation.

Animation Tracks

These utility functions allow fast access to the animation tracks and curves of an animated ::Vector parameter. See Animation Overview.

  • BaseObject::GetVectorTracks(): Gets the animation tracks for each component of the given ::Vector parameter.
  • BaseObject::GetVectorCurves(): Gets the animation curves for each component of the given ::Vector parameter.
Note
This is typically used with synchronized tracks, see CTrack Synchronisation.
// This example accesses the subtracks of the object's position track.
const DescID positionTrack = ConstDescID(DescLevel(ID_BASEOBJECT_REL_POSITION, DTYPE_VECTOR, 0));
CTrack* trackX = nullptr;
CTrack* trackY = nullptr;
CTrack* trackZ = nullptr;
// access track for each vector component
if (obj->GetVectorTracks(positionTrack, trackX, trackY, trackZ))
{
if (trackX != nullptr)
ApplicationOutput("Track X: " + trackX->GetName());
if (trackY != nullptr)
ApplicationOutput("Track Y: " + trackY->GetName());
if (trackZ != nullptr)
ApplicationOutput("Track Z: " + trackZ->GetName());
}
@ DTYPE_VECTOR
Vector
Definition: lib_description.h:69

This function is used to handle keys on a ::Vector parameter:

  • BaseObject::SynchronizeVectorTrackKeys(): Synchronizes the keys on the components of the given ::Vector parameter.

Animate

An object can be animated using the host BaseDocument:

  • BaseDocument::AnimateObject(): Animates the given object at the given frame.
Note
This function only animates the object based on its keyframes but does not care about expressions or other objects.

See also BaseDocument Animate.

Convert

Generators create and own virtual child objects. To access these child object one can read the cache of the generator (see Cache). Another way is to apply the "Current State to Object" command to the given generator object.

// This example creates a torus object and converts it to a polygon object.
AutoAlloc<BaseDocument> tempDoc;
if (tempDoc == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
BaseObject* const object = BaseObject::Alloc(Otorus);
if (object == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
// insert it into the temp doc.
tempDoc->InsertObject(object, nullptr, nullptr);
// modify object
object->SetParameter(ConstDescID(DescLevel(PRIM_TORUS_INNERRAD)), 100.0, DESCFLAGS_SET::NONE);
ModelingCommandData mcd;
mcd.doc = tempDoc;
mcd.op = object;
// execute the "Current State to Object" modeling command
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
C4DAtom* atom = mcd.result->GetIndex(0);
BaseObject* const res = static_cast<BaseObject*>(atom);
// check if the result object is a polygon object
if (res && (res->GetType() == Opolygon))
{
doc->InsertObject(res, nullptr, nullptr);
}
PyObject * object
Definition: asdl.h:7
Py_UCS4 * res
Definition: unicodeobject.h:1113
#define atom
Definition: graminit.h:72
#define MCOMMAND_CURRENTSTATETOOBJECT
Current state to object (returns object): MDATA_CURRENTSTATETOOBJECT.
Definition: ge_prepass.h:1652
#define Otorus
Torus.
Definition: ge_prepass.h:1122
Bool SendModelingCommand(Int32 command, ModelingCommandData &data)
Executes a builtin modelling operation as for example extruding a polygon selection or selecting all ...
@ PRIM_TORUS_INNERRAD
Definition: otorus.h:7

Bits

A BaseObject can be hidden in the Object Manager or viewport using these bits:

// This example hides the given object in the Object Manager.
object->ChangeNBit(NBIT::OHIDE, NBITCONTROL::SET);
SET
Set.
Definition: c4d_baselist.h:1
OHIDE
Hide object/tag in Object Manager or material in Material Manager.
Definition: ge_prepass.h:83

Flags

The flags of a BaseObject can be accessed with GeListNode::GetInfo(). These flags inform about the type of object and its behavior.

Object type:

// This example casts the given BaseObject into SplineObject
// if it is a spline or if it is a spline generator.
SplineObject* spline = nullptr;
// check if the object is a "Spline" object
if (object->IsInstanceOf(Ospline))
spline = ToSpline(object);
// check if the object is a spline generator
else if (object->GetInfo() & OBJECT_ISSPLINE)
spline = object->GetRealSpline();
if (spline != nullptr)
ApplicationOutput("Spline Object: " + spline->GetName());

Generator related flags:

Other flags:

Utility

These utility functions can return the name of the object type or return the object type based on that name.

// This example prints the name of the object type of the given object.
const Int32 type = obj->GetType();
const String typeName = GetObjectName(type);
ApplicationOutput("Object Type: " + typeName);
String GetObjectName(Int32 type)
PyObject ** type
Definition: pycore_pyerrors.h:34

These functions can be used to check if the given BaseObject is visible in the Editor:

  • CheckEditorVisibility(): Checks the editor visibility by checking the BaseObject's layer, bits and hierarchical editor settings.
  • CheckDisplayFilter(): Checks if the given BaseObject is covered by the given display filter.
// This example checks if the given BaseObject is visible in the active editor view.
BaseDraw* const bd = doc->GetActiveBaseDraw();
if (bd == nullptr)
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
const DISPLAYFILTER filter = bd->GetDisplayFilter();
const Bool displayFilter = CheckDisplayFilter(object, filter);
// check editor visibility
const Bool editorVisibiliy = CheckEditorVisibility(object);
// check if the object is visible in the viewport
if (displayFilter && editorVisibiliy)
{
ApplicationOutput("The object is visible in the Editor"_s);
}
else
{
ApplicationOutput("The object is not visible in the Editor"_s);
}
DISPLAYFILTER
Definition: ge_prepass.h:4573
Bool CheckDisplayFilter(BaseObject *op, DISPLAYFILTER filter)
Bool CheckEditorVisibility(BaseObject *op)

Further Reading