Hello @aimidi,
so, I did revisit your problem and CKey::GetValueLeft/Right
and CKey::GetTimeLeft/Right
do indeed not work with key presets. They will always return the non-adjusted values for the key, i.e., what equates to the preset CUSTOM
. It is a bit a matter of opinion if this could be considered a bug or not, since there are some indicators in our code that this has been implemented intentionally in this way for performance reasons.
If you want to retrieve the true tangents for a key, i.e., the tangents which take the presets into account, you must use CCurve::GetTangents
where the documentation already states that they do this.
Currently there is no warning in the docs that CKey::GetValueLeft/Right
and CKey::GetTimeLeft/Right
will behave in this way. I will reach out to the developers if we want to change this behavior. If we do not, we will update the documentation of CKey::GetValueLeft/Right
and CKey::GetTimeLeft/Right
in an upcoming release to reflect that this will always return the underlying custom tangents (which are sort of invisibly always there).
Below you will find a code example in C++ and the matching output which should be what you are after.
Sorry for the longwinded thread and cheers,
Ferdinand
The output:

The code:
// For https://plugincafe.maxon.net/topic/13344
#include "c4d.h"
#include "c4d_symbols.h"
static maxon::Result<void> pc13344(BaseDocument* doc)
{
iferr_scope;
BaseObject* op = doc->GetFirstObject();
if (op == nullptr) {
ApplicationOutput("Please insert at least one object into the scene.");
return maxon::OK;
}
CTrack* track = op->GetFirstCTrack();
if (track == nullptr) {
ApplicationOutput("The first object in the scene has no animation track.");
return maxon::OK;
}
CCurve* curve = track->GetCurve();
if (curve == nullptr) {
ApplicationOutput("The first object's animation track has no curve/keys.");
return maxon::OK;
}
for (int index = 0; index < curve->GetKeyCount(); index++)
{
CKey* key = curve->GetKey(index);
CKEYPRESET preset = key->GetKeyPreset();
maxon::Float keyTleftX = key->GetTimeLeft().Get(),
keyTleftY = key->GetValueLeft(),
keyTRightX = key->GetTimeRight().Get(),
keyTRightY = key->GetValueRight();
maxon::Float64 curveTleftX = 0., curveTleftY = 0., curveTRightX = 0., curveTRightY = 0.;
curve->GetTangents(index, &curveTleftX, &curveTRightX, &curveTleftY, &curveTRightY);
ApplicationOutput("index: @, mode: @, keyLeftTangent: (@, @), keyRightTangent: (@, @),
curveLeftTangent: (@, @), curveRightTangent: (@, @)",
index, preset,
keyTleftX, keyTleftY,
keyTRightX, keyTRightY,
curveTleftX, curveTleftY,
curveTRightX, curveTRightY);
}
return maxon::OK;
}