Open Search
    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:

    • BaseContainer::GetLink(): Returns the BaseList2D referenced in the BaseLink stored at the given ID.
    • BaseContainer::GetObjectLink(): Returns the BaseObject referenced in the BaseLink stored at the given ID.
    • BaseContainer::GetMaterialLink(): Returns the BaseMaterial referenced in the BaseLink stored at the given ID.
    • BaseContainer::GetBaseLink(): Returns the BaseLink stored at the given ID.

    To modify BaseLink objects stored in a BaseContainer use:

    • BaseContainer::SetLink(): Stores a BaseLink object referencing to the given C4DAtomGoal at the given ID.

    See also BaseContainer Manual.

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

    • GeData::GetBaseLink(): Returns the BaseLink object.
    • GeData::GetLink(): Returns the BaseList2D object referenced by the stored BaseLink object.
    • GeData::GetLinkAtom(): Returns the C4DAtomGoal object referenced by the stored BaseLink object.

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

    • GeData::SetBaseLink(): Stores the BaseLink object.
    • GeData::SetBaseList2D(): Stores a BaseLink object referencing to the given BaseList2D object.

    See also GeData Manual.

    // This example reads the object link of the given Instance Object.
    GeData data;
    // read "Reference Object" parameter
    if (!instanceObject->GetParameter(ConstDescID(DescLevel(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());
    }
    NONE
    Definition: asset_browser.h:1
    #define Obase
    Base object - BaseObject.
    Definition: ge_prepass.h:1090
    #define MAXON_SOURCE_LOCATION
    Definition: memoryallocationbase.h:69
    #define ApplicationOutput(formatString,...)
    Definition: debugdiagnostics.h:204
    #define ConstDescID(...)
    Definition: lib_description.h:596
    @ INSTANCEOBJECT_LINK
    Definition: oinstance.h:6
    const char * doc
    Definition: pyerrors.h:226

    Allocation/Deallocation

    BaseLink objects can be created with the usual functions:

    • BaseLink::Alloc(): Creates a new BaseLink object.
    • BaseLink::Free(): Destroys the given BaseLink object.
    // This example sets the "Reference Object" parameter of the given Instance Object.
    AutoAlloc<BaseLink> link;
    if (link == nullptr)
    return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
    link->SetLink(someOtherObject);
    GeData data;
    data.SetBaseLink(link);
    instanceObject->SetParameter(ConstDescID(DescLevel(INSTANCEOBJECT_LINK)), data, DESCFLAGS_SET::NONE);

    Copy

    BaseLink objects can be cloned or copied:

    • BaseLink::GetClone(): Returns a copy of the BaseLink object.
    • BaseLink::CopyTo(): Copies the BaseLink object into the given object.

    Properties

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

    • BaseLink::GetLink(): Evaluates the link and returns a pointer to the linked entity.
    • BaseLink::GetLinkAtom(): Evaluates the link and returns a pointer to the linked C4DAtomGoal.
    • BaseLink::SetLink(): Sets the link to point to the given C4DAtomGoal.
    • BaseLink::IsCacheLink(): Returns true if the referenced object is inside the cache of another object.
    // This example adds a shader to the material and links it in the color channel.
    AutoAlloc<BaseLink> link;
    if (link == nullptr)
    return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
    BaseShader* const shader = BaseShader::Alloc(Xbrick);
    if (shader == nullptr)
    return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
    link->SetLink(shader);
    // the material takes ownership
    mat->InsertShader(shader);
    // set parameter
    mat->SetParameter(ConstDescID(DescLevel(MATERIAL_COLOR_SHADER)), GeData(link), DESCFLAGS_SET::NONE);
    #define Xbrick
    Brick.
    Definition: ge_prepass.h:1333
    @ MATERIAL_COLOR_SHADER
    Definition: mmaterial.h:294

    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:

    • BaseLink::ForceGetLink(): Returns the stored link independent of a document.
    • BaseLink::ForceGetLinkAtom(): Returns the stored C4DAtomGoal independent of a document.
    // 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);
    AutoAlloc<BaseLink> link;
    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:

    • BaseLink::Read(): Reads the BaseLink from the given HyperFile.
    • BaseLink::Write(): Writes the BaseLink into the given HyperFile.
    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:

    • BaseLinkArray::Append(): Appends the given C4DAtomGoal to the array.
    • BaseLinkArray::Remove(): Removes the link at the given index from the array.
    // This example stores links to all standard materials.
    BaseLinkArray links;
    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();
    }
    #define Mmaterial
    Standard material.
    Definition: ge_prepass.h:1008

    Access

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

    • BaseLinkArray::GetRealCount(): Returns the number of valid base links in the array.
    • BaseLinkArray::Find(): Returns the index of the link to the given C4DAtomGoal.
    • BaseLinkArray::GetIndexLink(): Returns the link stored at the given index.
    • BaseLinkArray::GetIndex(): Returns the C4DAtomGoal referenced in the link stored at the given index.
    • BaseLinkArray::GetIndexBl(): Returns the BaseList2D referenced in the link stored at the given index.
    // 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
    PyObject * obj
    Definition: complexobject.h:60
    maxon::Int32 Int32
    Definition: ge_sys_math.h:51
    maxon::Int Int
    Definition: ge_sys_math.h:55

    Convert

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

    • BaseLinkArray::GetAtomArray(): Sets the atom array with entities referenced in the stored links.
    • BaseLinkArray::FromAtomArray(): Constructs the array from the given AtomArray.
    // This example stores the current object selection in a BaseLinkArray.
    AutoAlloc<AtomArray> objects;
    if (objects == nullptr)
    return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
    doc->GetActiveObjects(objects, GETACTIVEOBJECTFLAGS::NONE);
    BaseLinkArray linkArray;
    linkArray.FromAtomArray(objects);

    Further Reading