Open Search
    CAMorphNode Manual

    About

    A CAMorphNode object stores the actual morph data for a corresponding BaseList2D object. It is stored in a CAPoseMorphTag, see CAPoseMorphTag Manual. The class is defined in the lib_ca.h header file.

    Access

    A CAMorphNode object is obtained from the host CAMorph. See CAMorph Manual.

    // This example accesses the morph data of the
    // first morph of the given CAPoseMorphTag.
    poseMorphTag->ExitEdit(doc, false);
    // get active morph
    const Int32 activeIndex = poseMorphTag->GetActiveMorphIndex();
    CAMorph* const morph = poseMorphTag->GetMorph(activeIndex);
    if (morph == nullptr)
    return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
    CAMorphNode* const mnode = morph->GetFirst();
    if (mnode == nullptr)
    return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
    // expand data to access it
    morph->SetMode(doc, poseMorphTag, expandFlags, CAMORPH_MODE::ABS);
    // check stored data
    {
    // access point data
    const Int32 pointCount = mnode->GetPointCount();
    for (Int32 i = 0; i < pointCount; ++i)
    {
    const Vector point = mnode->GetPoint(i);
    }
    }
    // collapse data
    morph->SetMode(doc, poseMorphTag, collapseFlags, CAMORPH_MODE::AUTO);
    poseMorphTag->UpdateMorphs();
    Py_ssize_t i
    Definition: abstract.h:645
    Definition: lib_ca.h:1429
    Bool SetMode(BaseDocument *doc, CAPoseMorphTag *tag, CAMORPH_MODE_FLAGS flags, CAMORPH_MODE mode)
    CAMorphNode * GetFirst()
    Definition: lib_ca.h:1071
    Int32 GetPointCount()
    CAMORPH_DATA_FLAGS GetInfo()
    Vector GetPoint(Int32 index)
    static String VectorToString(const Vector32 &v, Int32 nnk=-1)
    Definition: c4d_string.h:571
    maxon::Int32 Int32
    Definition: ge_sys_math.h:60
    @ POINTS
    Points morphing.
    CAMORPH_MODE_FLAGS
    Definition: lib_ca.h:850
    @ ALL
    Expand or collapse all data.
    @ COLLAPSE
    Collapse data. Needs to be passed to collapse the expanded data, for instance after data access.
    @ EXPAND
    Expand data. Needs to be passed before accessing any data.
    @ ABS
    Absolute morph data.
    @ AUTO
    Auto mode. Used to collapse the data automatically into their correct mode.
    #define MAXON_SOURCE_LOCATION
    Definition: memoryallocationbase.h:67
    #define ApplicationOutput(formatString,...)
    Definition: debugdiagnostics.h:210
    const char * doc
    Definition: pyerrors.h:226

    Navigation

    A CAMorphNode stores the data of the corresponding BaseList2D object. In "Hierarchy" mode of the host CAPoseMorphTag a CAMorph stores multiple CAMorphNode objects for all corresponding objects in the object tree.

    // This example function iterates over the CAMorphNode tree of the
    // given morph and prints the names of the referenced objects.
    static void CheckMorphNode(CAMorphNode* mnode, CAPoseMorphTag* tag, CAMorph* morph, BaseDocument* doc)
    {
    // loop through all nodes on this level
    while (mnode != nullptr)
    {
    // get linked object
    BaseList2D* const link = mnode->GetLink(tag, morph, doc);
    if (link != nullptr)
    {
    // print name
    ApplicationOutput("Linked Object: " + link->GetName());
    }
    // check child nodes
    CheckMorphNode(mnode->GetDown(), tag, morph, doc);
    // get next node
    mnode = mnode->GetNext();
    }
    }
    Definition: c4d_basedocument.h:498
    Definition: c4d_baselist.h:2208
    String GetName() const
    Definition: c4d_baselist.h:2381
    CAMorphNode * GetNext()
    CAMorphNode * GetDown()
    BaseList2D * GetLink(CAPoseMorphTag *tag, CAMorph *morph, BaseDocument *doc)
    Definition: lib_ca.h:1618

    Data

    Info

    A CAMorphNode stores morph data of a corresponding BaseList2D object.

    PSR

    A CAMorphNode object can store PSR data:

    // This example reads the position data stored in the given morph.
    // check stored data
    {
    // access data
    const Vector position = mnode->GetP();
    // print data
    ApplicationOutput("Position: " + String::VectorToString(position));
    }
    Vector GetP()
    @ P
    Position morphing.

    Points

    A CAMorphNode object can store point data:

    // This example accesses the point data stored in the given morph.
    // The point data is changed and written back into the morph.
    // check stored data
    {
    Random random;
    // loop through points
    const Int32 pointCount = mnode->GetPointCount();
    for (Int32 i = 0; i < pointCount; ++i)
    {
    // get point
    Vector point = mnode->GetPoint(i);
    // random offset
    point.x += random.Get01() * 10.0;
    point.y += random.Get01() * 10.0;
    point.z += random.Get01() * 10.0;
    // set point
    mnode->SetPoint(i, point);
    }
    }
    void SetPoint(Int32 index, const Vector &pnt)
    Definition: c4d_tools.h:812
    Float Get01()
    T y
    Definition: vec.h:40
    T x
    Definition: vec.h:39
    T z
    Definition: vec.h:41

    For point mode additional Pose Space Deformation data is stored:

    See CAReferencePSD Manual.

    // This example accesses the PSD data of the given point morph.
    // expand data to access it
    morph->SetMode(doc, poseMorphTag, expandFlags, CAMORPH_MODE::ABS);
    // check stored data
    {
    // get PSD data
    CAReferencePSD* const psd = mnode->GetPSDReference();
    if (psd)
    {
    // loop through all controllers
    const Int32 controllerCount = psd->GetExternalControllerCount();
    for (Int32 controllerIndex = 0; controllerIndex < controllerCount; ++controllerIndex)
    {
    BaseObject* const controller = psd->GetExternalController(controllerIndex);
    if (controller == nullptr)
    return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
    ApplicationOutput("Controller: " + controller->GetName());
    }
    }
    }
    // collapse data
    morph->SetMode(doc, poseMorphTag, collapseFlags, CAMORPH_MODE::AUTO);
    Definition: c4d_baseobject.h:225
    CAReferencePSD * GetPSDReference()
    Definition: lib_ca.h:924
    Int32 GetExternalControllerCount() const
    BaseObject * GetExternalController(Int32 controllerIndex)

    Tangents

    A CAMorphNode object can store tangent data for spline points:

    Note
    For each spline point two tangent vectors are stored.
    // This example reads the stored tangent data from the given morph.
    // check stored data
    {
    // loop through tangents
    const Int32 tangentCount = mnode->GetTangentCount();
    for (Int32 i = 0; i < tangentCount; ++i)
    {
    // get data
    const Vector tangent = mnode->GetTangent(i);
    // print data
    ApplicationOutput("Tangent: " + String::VectorToString(tangent));
    }
    }
    Vector GetTangent(Int32 index)
    Int32 GetTangentCount()
    @ TANGENTS
    Tangents morphing.

    Vertex Map

    A CAMorphNode object can store vertex map data for all vertex map tags of the host object.

    // This example loops through all data stored for all vertex map tags.
    // check stored data
    {
    const Int32 vertexMapCount = mnode->GetVertexMapTagCount();
    // loop through tags
    for (Int32 tagIndex = 0; tagIndex < vertexMapCount; ++tagIndex)
    {
    ApplicationOutput("Tag Index " + String::IntToString(tagIndex));
    // loop through vertice
    const Int32 vertexCount = mnode->GetVertexMapCount(tagIndex);
    for (Int32 vertexIndex = 0; vertexIndex < vertexCount; ++vertexIndex)
    {
    const Float weight = mnode->GetVertexMap(tagIndex, vertexIndex);
    }
    }
    }
    Float GetVertexMap(Int32 tindex, Int32 index)
    Int32 GetVertexMapTagCount()
    Int32 GetVertexMapCount(Int32 tindex)
    static String IntToString(Int32 v)
    Definition: c4d_string.h:495
    static String FloatToString(Float32 v, Int32 vvk=-1, Int32 nnk=-3)
    Definition: c4d_string.h:529
    maxon::Float Float
    Definition: ge_sys_math.h:66
    @ VERTEXMAPS
    Vertex map morphing.

    Parameters

    A CAMorphNode object can store data for various object parameters.

    UV Sets

    A CAMorphNode object can store UVW data for all UVW tags of the host object. See also UVWTag Manual.

    // This example loops through all data stored for all UVW tags.
    // expand data to access it
    morph->SetMode(doc, poseMorphTag, expandFlags, CAMORPH_MODE::ABS);
    // check stored data
    {
    // loop through data for all uvw tags
    const Int32 uvTagCount = mnode->GetUVTagCount();
    for (Int32 tagIndex = 0; tagIndex < uvTagCount; ++tagIndex)
    {
    ApplicationOutput("UVW Tag #" + String::IntToString(tagIndex));
    // loop through data for each polygon
    const Int32 uvCount = mnode->GetUVCount(tagIndex);
    for (Int32 uvIndex = 0; uvIndex < uvCount; ++uvIndex)
    {
    ApplicationOutput("Polygon #" + String::IntToString(uvIndex));
    UVWStruct uvw;
    mnode->GetUV(tagIndex, uvIndex, uvw);
    }
    }
    }
    // collapse data
    morph->SetMode(doc, poseMorphTag, collapseFlags, CAMORPH_MODE::AUTO);
    void GetUV(Int32 tindex, Int32 index, UVWStruct &uv)
    Int32 GetUVTagCount()
    Int32 GetUVCount(Int32 tindex)
    @ UV
    UV coordinate morphing.
    Definition: operatingsystem.h:473
    Vector c
    The UVW coordinate for the third point.
    Definition: operatingsystem.h:512
    Vector b
    The UVW coordinate for the second point.
    Definition: operatingsystem.h:511
    Vector a
    The UVW coordinate for the first point.
    Definition: operatingsystem.h:510
    Vector d
    The UVW coordinate for the fourth point.
    Definition: operatingsystem.h:513

    Weight Maps

    A CAMorphNode object can store weight data for all weight tags of the host object. See also CAWeightTag Manual.

    // This example loops through all data stored for all weigth tags.
    // expand data to access it
    morph->SetMode(doc, poseMorphTag, expandFlags, CAMORPH_MODE::ABS);
    // check stored data
    {
    // loop through data for all weight tags
    const Int32 weightTagCount = mnode->GetWeightMapTagCount();
    for (Int32 tagIndex = 0; tagIndex < weightTagCount; ++tagIndex)
    {
    ApplicationOutput("Weight Tag #" + String::IntToString(tagIndex));
    // loop through data for all joints
    const Int32 jointCount = mnode->GetWeightMapJointCount(tagIndex);
    for (Int32 jointIndex = 0; jointIndex < jointCount; ++jointIndex)
    {
    ApplicationOutput("Joint #" + String::IntToString(jointIndex));
    const Int32 weightCount = mnode->GetWeightMapCount(tagIndex, jointIndex);
    for (Int32 weightIndex = 0; weightIndex < weightCount; ++weightIndex)
    {
    const Float weight = mnode->GetWeightMap(tagIndex, jointIndex, weightIndex);
    }
    }
    }
    }
    // collapse data
    morph->SetMode(doc, poseMorphTag, collapseFlags, CAMORPH_MODE::AUTO);
    Int32 GetWeightMapCount(Int32 tindex, Int32 jindex)
    Int32 GetWeightMapJointCount(Int32 tindex)
    Int32 GetWeightMapTagCount()
    Float GetWeightMap(Int32 tindex, Int32 jindex, Int32 index)
    @ WEIGHTMAPS
    Joint weights morphing.

    Further Reading