Open Search

    About

    The CAPoseMorphTag class represents a pose morph tag. Such a tag stores multiple morphs that can be applied to the host object (and it's child objects) to modify and animate it. The class is defined in the lib_ca.h header file.

    CAPoseMorphTag objects are an instance of Tposemorph.

    // This example creates a cube with a CAPoseMorphTag.
    // A base morph and an additional morph are added to the tag.
    // create cube
    if (cube == nullptr)
    return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
    doc->InsertObject(cube, nullptr, nullptr);
    // create morph tag
    CAPoseMorphTag* const poseMorphTag = CAPoseMorphTag::Alloc();
    if (poseMorphTag == nullptr)
    return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
    cube->InsertTag(poseMorphTag);
    poseMorphTag->InitMorphs();
    // configure tag
    // edit morphs
    poseMorphTag->ExitEdit(doc, true);
    // add base morph
    CAMorph* const baseMorph = poseMorphTag->AddMorph();
    if (baseMorph == nullptr)
    return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
    baseMorph->Store(doc, poseMorphTag, CAMORPH_DATA_FLAGS::ASTAG);
    // modify cube
    // add morph
    CAMorph* const morph = poseMorphTag->AddMorph();
    if (morph == nullptr)
    return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
    // store current state in morph
    morph->SetName("Scaled Size");
    morph->Store(doc, poseMorphTag, CAMORPH_DATA_FLAGS::ASTAG);
    poseMorphTag->UpdateMorphs();
    // switch to "Animate" mode
    // set strength
    const DescID sliderID = poseMorphTag->GetMorphID(1);
    poseMorphTag->SetParameter(sliderID, 0.5, DESCFLAGS_SET::NONE);
    Definition: c4d_baseobject.h:225
    static BaseObject * Alloc(Int32 type)
    void InsertTag(BaseTag *tp, BaseTag *pred=nullptr)
    Bool SetParameter(const DescID &id, const GeData &t_data, DESCFLAGS_SET flags)
    Definition: lib_ca.h:1429
    Bool Store(BaseDocument *doc, CAPoseMorphTag *tag, CAMORPH_DATA_FLAGS flags)
    void SetName(const String &name)
    Definition: lib_ca.h:1618
    Bool ExitEdit(BaseDocument *doc, Bool noapply)
    CAMorph * AddMorph()
    DescID GetMorphID(Int32 index)
    void UpdateMorphs(BaseDocument *doc=nullptr)
    static CAPoseMorphTag * Alloc()
    Definition: lib_ca.h:1631
    Definition: lib_description.h:330
    maxon::Vec3< maxon::Float64, 1 > Vector
    Definition: ge_math.h:145
    #define Ocube
    Cube.
    Definition: ge_prepass.h:1102
    #define MAXON_SOURCE_LOCATION
    Definition: memoryallocationbase.h:67
    @ PRIM_CUBE_LEN
    Definition: ocube.h:6
    const char * doc
    Definition: pyerrors.h:226
    @ ID_CA_POSE_MODE
    Definition: tcaposemorph.h:18
    @ ID_CA_POSE_PARAM
    Definition: tcaposemorph.h:30
    @ ID_CA_POSE_MODE_ANIMATE
    Definition: tcaposemorph.h:86

    Access

    A CAPoseMorphTag tag can be accessed like any other tag, see BaseTag and VariableTag Manual.

    // This example accesses the selected pose morph tag and
    // prints the names of all it's morphs.
    // get tag
    BaseTag* const tag = doc->GetActiveTag();
    if (tag == nullptr || !tag->IsInstanceOf(Tposemorph))
    return maxon::IllegalArgumentError(MAXON_SOURCE_LOCATION);
    CAPoseMorphTag* const poseMorphTag = static_cast<CAPoseMorphTag*>(tag);
    // loop through all morphs
    const Int32 morphCount = poseMorphTag->GetMorphCount();
    for (Int32 i = 0; i < morphCount; ++i)
    {
    CAMorph* const morph = poseMorphTag->GetMorph(i);
    if (morph != nullptr)
    {
    // print morph name
    ApplicationOutput("Morph: " + morph->GetName());
    }
    }
    Py_ssize_t i
    Definition: abstract.h:645
    Definition: c4d_basetag.h:48
    Bool IsInstanceOf(Int32 id) const
    Definition: c4d_baselist.h:1436
    String GetName()
    Int32 GetMorphCount()
    CAMorph * GetMorph(Int32 index)
    maxon::Int32 Int32
    Definition: ge_sys_math.h:60
    #define ApplicationOutput(formatString,...)
    Definition: debugdiagnostics.h:210
    #define Tposemorph
    Pose morph.
    Definition: ge_prepass.h:1433

    Allocation/Deallocation

    CAPoseMorphTag instances are created with the usual tools, see Entity Creation and Destruction Manual (Classic).

    // This example creates a new CAPoseMorphTag
    // and adds it to the given polygon object.
    CAPoseMorphTag* const poseMorphTag = CAPoseMorphTag::Alloc();
    if (poseMorphTag == nullptr)
    return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
    polyObject->InsertTag(poseMorphTag);

    After creation, the tag must be initialized.

    Properties

    The parameters of CAPoseMorphTag can be edited with C4DAtom::SetParameter() and C4DAtom::GetParameter(). The parameter IDs are defined in tcaposemorph.h.

    Note
    Several settings of the active morph must be set on the morph tag using C4DAtom::SetParameter().
    // This example enables "Points", adds a new morph and
    // switches to "Animate" mode.
    // mix points
    // add new morph
    CAMorph* const morph = poseMorphTag->AddMorph();
    if (morph == nullptr)
    return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
    morph->SetName("New Morph");
    // set morph as the active morph
    const Int32 index = poseMorphTag->GetMorphIndex(morph);
    poseMorphTag->SetActiveMorphIndex(index);
    // update
    poseMorphTag->UpdateMorphs(doc);
    // enable "Post Deformers" for the active morph
    // switch to animate mode
    void SetActiveMorphIndex(Int32 index)
    Int32 GetMorphIndex(CAMorph *morph)
    Py_ssize_t * index
    Definition: abstract.h:374
    @ ID_CA_POSE_POINTS
    Definition: tcaposemorph.h:34
    @ ID_CA_POSE_MIXING_DEFORMED
    Definition: tcaposemorph.h:42

    Morphs

    Any change to the morph data must be encompassed by the following functions:

    The stored morphs are accessed with:

    See also CAMorph Manual.

    // This example lists the names and strengths
    // of all morphs in the given tag.
    const Int32 morphCount = poseMorphTag->GetMorphCount();
    for (Int32 i = 0; i < morphCount; ++i)
    {
    CAMorph* const morph = poseMorphTag->GetMorph(i);
    if (morph == nullptr)
    return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
    // print morph name
    ApplicationOutput("Morph: " + morph->GetName());
    // ignore base morph
    if (i != 0)
    {
    // print current strength of the morph
    const DescID id = poseMorphTag->GetMorphID(i);
    GeData data;
    poseMorphTag->GetParameter(id, data, DESCFLAGS_GET::NONE);
    const Float strength = data.GetFloat();
    ApplicationOutput("Strength: " + String::FloatToString(strength));
    }
    }
    Bool GetParameter(const DescID &id, GeData &t_data, DESCFLAGS_GET flags)
    Definition: c4d_gedata.h:83
    Float GetFloat() const
    Definition: c4d_gedata.h:439
    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
    // This example deletes the currently selected morph.
    poseMorphTag->ExitEdit(doc, true);
    // delete active morph
    const Int32 activeIndex = poseMorphTag->GetActiveMorphIndex();
    poseMorphTag->RemoveMorph(activeIndex);
    poseMorphTag->UpdateMorphs();
    void RemoveMorph(Int32 index)
    Int32 GetActiveMorphIndex()

    PSD

    Several Pose Space Deformation related settings can be edited with these functions:

    See also CAReferencePSD Manual.

    // This example changes the PSD display settings on the given pose morph tag.
    CAPoseMorphTag* const poseMorphTag = static_cast<CAPoseMorphTag*>(tag);
    if (poseMorphTag)
    {
    // enable color
    poseMorphTag->SetPSDFeedbackColorEnabled(true);
    // set color to red
    poseMorphTag->SetPSDFeedbackColor(Vector(1.0, 0.0, 0.0));
    }
    Bool SetPSDFeedbackColorEnabled(Bool active)
    Bool SetPSDFeedbackColor(const Vector &color)

    Mode

    A CAPoseMorphTag can either be in "edit" or "animate" mode:

    Note
    To change the mode use C4DAtom::SetParameter() with DescID ID_CA_POSE_MODE.

    Further Reading