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:248
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:1475
Bool Store(BaseDocument *doc, CAPoseMorphTag *tag, CAMORPH_DATA_FLAGS flags)
void SetName(const String &name)
Definition: lib_ca.h:1670
Bool ExitEdit(BaseDocument *doc, Bool noapply)
CAMorph * AddMorph()
DescID GetMorphID(Int32 index) const
void UpdateMorphs(BaseDocument *doc=nullptr)
static CAPoseMorphTag * Alloc()
Definition: lib_ca.h:1683
Definition: lib_description.h:355
maxon::Vec3< maxon::Float64, 1 > Vector
Definition: ge_math.h:145
#define Ocube
Cube.
Definition: ge_prepass.h:1110
#define MAXON_SOURCE_LOCATION
Definition: memoryallocationbase.h:67
#define ConstDescID(...)
Definition: lib_description.h:594
@ PRIM_CUBE_LEN
Definition: ocube.h:6
const char * doc
Definition: pyerrors.h:226
Represents a level within a DescID.
Definition: lib_description.h:298
@ ID_CA_POSE_MODE
Definition: tcaposemorph.h:18
@ ID_CA_POSE_PARAM
Definition: tcaposemorph.h:30
@ ID_CA_POSE_MODE_ANIMATE
Definition: tcaposemorph.h:87

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:50
Bool IsInstanceOf(Int32 id) const
Definition: c4d_baselist.h:1437
String GetName()
Int32 GetMorphCount() const
const CAMorph * GetMorph(Int32 index) const
maxon::Int32 Int32
Definition: ge_sys_math.h:60
#define ApplicationOutput(formatString,...)
Definition: debugdiagnostics.h:210
#define Tposemorph
Pose morph.
Definition: ge_prepass.h:1442

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(const CAMorph *morph) const
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) const
Definition: c4d_gedata.h:83
Float GetFloat() const
Definition: c4d_gedata.h:468
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() const

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