BaseLink Manual

About

A BaseLink handles a reference to a C4DAtom (C4DAtomGoal) element. This class should always be used instead of storing a pointer to the element itself. A link is typically resolved by providing the BaseDocument that hosts the linked entity.

Note
When one copies entities an AliasTrans object can be used to determine how the links of these entities are handled.
To change all BaseLink objects pointing to an entity BaseList2D::TransferGoal() can be used.

Access

A BaseLink is typically stored in a BaseContainer or GeData container. Several functions are available to access either the BaseLink object itself or the linked entity.

To retrieve BaseLink objects stored in a BaseContainer use:

To modify BaseLink objects stored in a BaseContainer use:

See also BaseContainer Manual.

To retrieve BaseLink objects stored in a GeData object (GeData type is DA_ALIASLINK) use:

To modify BaseLink objects stored in a GeData object (GeData type is DA_ALIASLINK) use:

See also GeData Manual.

// This example reads the object link of the given Instance Object.
GeData data;
// read "Reference Object" parameter
if (!instanceObject->GetParameter(DescID(INSTANCEOBJECT_LINK), data, DESCFLAGS_GET::NONE))
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
BaseList2D* const linkedEntity = data.GetLink(doc);
// check if a BaseList2D element is linked and if it is a BaseObject
if (linkedEntity != nullptr && linkedEntity->IsInstanceOf(Obase))
{
const BaseObject* const linkedObject = static_cast<BaseObject*>(linkedEntity);
ApplicationOutput("Linked Object: " + linkedObject->GetName());
}
Definition: c4d_baselist.h:2188
String GetName() const
Definition: c4d_baselist.h:2361
Definition: c4d_baseobject.h:225
Bool IsInstanceOf(Int32 id) const
Definition: c4d_baselist.h:1416
Definition: lib_description.h:330
Definition: c4d_gedata.h:83
BaseList2D * GetLink(const BaseDocument *doc, Int32 instanceof=0) const
#define Obase
Base object - BaseObject.
Definition: ge_prepass.h:1072
#define MAXON_SOURCE_LOCATION
Definition: memoryallocationbase.h:67
#define ApplicationOutput(formatString,...)
Definition: debugdiagnostics.h:210
@ INSTANCEOBJECT_LINK
Definition: oinstance.h:6
const char * doc
Definition: pyerrors.h:226

Allocation/Deallocation

BaseLink objects can be created with the usual functions:

// This example sets the "Reference Object" parameter of the given Instance Object.
if (link == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
link->SetLink(someOtherObject);
GeData data;
data.SetBaseLink(link);
instanceObject->SetParameter(DescID(INSTANCEOBJECT_LINK), data, DESCFLAGS_SET::NONE);
Definition: ge_autoptr.h:37
void SetBaseLink(const BaseLink &v)
Definition: c4d_gedata.h:651

Copy

BaseLink objects can be cloned or copied:

Properties

A BaseLink object stores a reference to an entity. This reference can be handled with these function:

// This example adds a shader to the material and links it in the color channel.
if (link == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
if (shader == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
link->SetLink(shader);
// the material takes ownership
mat->InsertShader(shader);
// set parameter
Definition: c4d_basechannel.h:36
static BaseShader * Alloc(Int32 type)
#define Xbrick
Brick.
Definition: ge_prepass.h:1293
@ MATERIAL_COLOR_SHADER
Definition: mmaterial.h:272

The stored reference is typically resolved using the BaseDocument that contains the referenced entity. If the linked entity is not part of a BaseDocument the BaseLink can be forced to be resolved:

// This example shows how to use BaseLink::ForceGetLink() to access the linked object
// when it is no longer part of a document.
// insert "cube" into the document
tempDoc->InsertObject(cube, nullptr, nullptr);
if (link == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
// store link
link->SetLink(cube);
BaseObject* const resultA = static_cast<BaseObject*>(link->GetLink(tempDoc));
if (resultA != nullptr)
ApplicationOutput("Could access the linked object.");
// removes the cube from the document
cube->Remove();
BaseObject* const resultB = static_cast<BaseObject*>(link->GetLink(tempDoc));
if (resultB == nullptr)
ApplicationOutput("Could not access the linked object.");
BaseObject* const resultC = static_cast<BaseObject*>(link->ForceGetLink());
if (resultC != nullptr)
ApplicationOutput("Could access the linked object.");

Disc I/O

BaseLink objects can be stored in a HyperFile using:

Note
This is typically used in NodeData::Read() and NodeData::Write().

BaseLinkArray

A BaseLinkArray can be used to handle multiple BaseLink objects.

Add And Remove

References to entities can easily be added to and removed from the array using:

// This example stores links to all standard materials.
BaseMaterial* material = doc->GetFirstMaterial();
while (material != nullptr)
{
// check if the material is a Cinema 4D standard material
if (material->IsInstanceOf(Mmaterial))
links.Append(material);
material = material->GetNext();
}
Definition: c4d_basematerial.h:28
BaseMaterial * GetNext(void)
Definition: c4d_basematerial.h:60
#define Mmaterial
Standard material.
Definition: ge_prepass.h:990

Access

References to entities and other relevant data can easily be retrieved from the array using:

// This example loops through the elements of the given BaseLinkArray.
const Int count = linkArray.GetCount();
for (Int i = 0; i < count; ++i)
{
C4DAtomGoal* const goal = linkArray.GetIndex((Int32)i, doc);
if (goal == nullptr)
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
// check if the referenced element is a BaseObject
if (goal->IsInstanceOf(Obase))
{
const BaseObject* const obj = static_cast<BaseObject*>(goal);
ApplicationOutput(obj->GetName());
}
}
Py_ssize_t i
Definition: abstract.h:645
Py_ssize_t count
Definition: abstract.h:640
Dummy class for C4DAtom objects that can be pointed to by BaseLink objects.
Definition: c4d_baselist.h:1619
PyObject * obj
Definition: complexobject.h:60
maxon::Int32 Int32
Definition: ge_sys_math.h:60
maxon::Int Int
Definition: ge_sys_math.h:64

Convert

The BaseLinkArray can be converted into and built from an AtomArray.

// This example stores the current object selection in a BaseLinkArray.
if (objects == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
doc->GetActiveObjects(objects, GETACTIVEOBJECTFLAGS::NONE);
BaseLinkArray linkArray;
linkArray.FromAtomArray(objects);

Further Reading