Refactor: pose_utils.cc

No functional changes expected.

This PR refactors the code by:
* passing things by reference if they cannot be a `nullptr`
* Managing indentation by returning early or continuing.
* Cleaning up comments
* Indicating ListBase element types in the declaration

This is in service of #126125 for which the `get_item_transform_flags`
needs to be passed a slot handle as well.

Pull Request: https://projects.blender.org/blender/blender/pulls/126291
This commit is contained in:
Christoph Lendenfeld
2024-08-15 09:47:14 +02:00
committed by Christoph Lendenfeld
parent 00be586a82
commit 0f5dd1c55c
2 changed files with 139 additions and 152 deletions

View File

@@ -165,10 +165,13 @@ struct tPChanFCurveLink {
/** Returns a valid pose armature for this object, else returns NULL. */
Object *poseAnim_object_get(Object *ob_);
/** Get sets of F-Curves providing transforms for the bones in the Pose. */
void poseAnim_mapping_get(bContext *C, ListBase *pfLinks);
/**
* Build up a list of tPChanFCurveLink. First only selected, and if that yields no result, all
* visible.
*/
void poseAnim_mapping_get(bContext *C, ListBase /* tPChanFCurveLink */ *pfLinks);
/** Free F-Curve <-> PoseChannel links. */
void poseAnim_mapping_free(ListBase *pfLinks);
void poseAnim_mapping_free(ListBase /* tPChanFCurveLink */ *pfLinks);
/**
* Helper for apply() / reset() - refresh the data.

View File

@@ -54,147 +54,120 @@
/**
* Types of transforms applied to the given item:
* - these are the return flags for #BKE_action_get_item_transform_flags()
* - these are the return flags for get_item_transform_flags()
*/
typedef enum eAction_TransformFlags {
/* location */
ACT_TRANS_LOC = (1 << 0),
/* rotation */
ACT_TRANS_ROT = (1 << 1),
/* scaling */
ACT_TRANS_SCALE = (1 << 2),
/* bbone shape - for all the parameters, provided one is set */
/* BBone shape - for all the parameters, provided one is set. */
ACT_TRANS_BBONE = (1 << 3),
/* strictly not a transform, but custom properties are also
* quite often used in modern rigs
*/
ACT_TRANS_PROP = (1 << 4),
/* all flags */
ACT_TRANS_ONLY = (ACT_TRANS_LOC | ACT_TRANS_ROT | ACT_TRANS_SCALE),
ACT_TRANS_ALL = (ACT_TRANS_ONLY | ACT_TRANS_PROP),
} eAction_TransformFlags;
static eAction_TransformFlags get_item_transform_flags(bAction *act,
Object *ob,
bPoseChannel *pchan,
ListBase *curves)
static eAction_TransformFlags get_item_transform_flags(bAction &act,
Object &ob,
bPoseChannel &pchan,
ListBase &curves)
{
PointerRNA ptr;
short flags = 0;
/* build PointerRNA from provided data to obtain the paths to use */
if (pchan) {
ptr = RNA_pointer_create((ID *)ob, &RNA_PoseBone, pchan);
}
else if (ob) {
ptr = RNA_id_pointer_create((ID *)ob);
}
else {
return eAction_TransformFlags(0);
}
/* Build PointerRNA from provided data to obtain the paths to use. */
PointerRNA ptr = RNA_pointer_create((ID *)&ob, &RNA_PoseBone, &pchan);
/* get the basic path to the properties of interest */
/* Get the basic path to the properties of interest. */
const std::optional<std::string> basePath = RNA_path_from_ID_to_struct(&ptr);
if (!basePath) {
return eAction_TransformFlags(0);
}
/* search F-Curves for the given properties
/* Search F-Curves for the given properties
* - we cannot use the groups, since they may not be grouped in that way...
*/
LISTBASE_FOREACH (FCurve *, fcu, &act->curves) {
LISTBASE_FOREACH (FCurve *, fcu, &act.curves) {
const char *bPtr = nullptr, *pPtr = nullptr;
/* If enough flags have been found,
* we can stop checking unless we're also getting the curves. */
if ((flags == ACT_TRANS_ALL) && (curves == nullptr)) {
if ((flags == ACT_TRANS_ALL)) {
break;
}
/* just in case... */
if (fcu->rna_path == nullptr) {
continue;
}
/* step 1: check for matching base path */
/* Step 1: check for matching base path */
bPtr = strstr(fcu->rna_path, basePath->c_str());
if (bPtr) {
/* we must add len(basePath) bytes to the match so that we are at the end of the
* base path so that we don't get false positives with these strings in the names
*/
bPtr += strlen(basePath->c_str());
if (!bPtr) {
continue;
}
/* step 2: check for some property with transforms
* - to speed things up, only check for the ones not yet found
* unless we're getting the curves too
* - if we're getting the curves, the BLI_genericNodeN() creates a LinkData
* node wrapping the F-Curve, which then gets added to the list
* - once a match has been found, the curve cannot possibly be any other one
*/
if ((curves) || (flags & ACT_TRANS_LOC) == 0) {
pPtr = strstr(bPtr, "location");
if (pPtr) {
flags |= ACT_TRANS_LOC;
/* We must add len(basePath) bytes to the match so that we are at the end of the
* base path so that we don't get false positives with these strings in the names
*/
bPtr += strlen(basePath->c_str());
if (curves) {
BLI_addtail(curves, BLI_genericNodeN(fcu));
}
continue;
}
/* Step 2: check for some property with transforms
* - to speed things up, only check for the ones not yet found
* unless we're getting the curves too
* - if we're getting the curves, the BLI_genericNodeN() creates a LinkData
* node wrapping the F-Curve, which then gets added to the list
* - once a match has been found, the curve cannot possibly be any other one
*/
if ((flags & ACT_TRANS_LOC) == 0) {
pPtr = strstr(bPtr, "location");
if (pPtr) {
flags |= ACT_TRANS_LOC;
BLI_addtail(&curves, BLI_genericNodeN(fcu));
continue;
}
}
if ((curves) || (flags & ACT_TRANS_SCALE) == 0) {
pPtr = strstr(bPtr, "scale");
if (pPtr) {
flags |= ACT_TRANS_SCALE;
if ((flags & ACT_TRANS_SCALE) == 0) {
pPtr = strstr(bPtr, "scale");
if (pPtr) {
flags |= ACT_TRANS_SCALE;
if (curves) {
BLI_addtail(curves, BLI_genericNodeN(fcu));
}
continue;
}
BLI_addtail(&curves, BLI_genericNodeN(fcu));
continue;
}
}
if ((curves) || (flags & ACT_TRANS_ROT) == 0) {
pPtr = strstr(bPtr, "rotation");
if (pPtr) {
flags |= ACT_TRANS_ROT;
if ((flags & ACT_TRANS_ROT) == 0) {
pPtr = strstr(bPtr, "rotation");
if (pPtr) {
flags |= ACT_TRANS_ROT;
if (curves) {
BLI_addtail(curves, BLI_genericNodeN(fcu));
}
continue;
}
BLI_addtail(&curves, BLI_genericNodeN(fcu));
continue;
}
}
if ((curves) || (flags & ACT_TRANS_BBONE) == 0) {
/* bbone shape properties */
pPtr = strstr(bPtr, "bbone_");
if (pPtr) {
flags |= ACT_TRANS_BBONE;
if ((flags & ACT_TRANS_BBONE) == 0) {
pPtr = strstr(bPtr, "bbone_");
if (pPtr) {
flags |= ACT_TRANS_BBONE;
if (curves) {
BLI_addtail(curves, BLI_genericNodeN(fcu));
}
continue;
}
BLI_addtail(&curves, BLI_genericNodeN(fcu));
continue;
}
}
if ((curves) || (flags & ACT_TRANS_PROP) == 0) {
/* custom properties only */
pPtr = strstr(bPtr, "[\"");
if (pPtr) {
flags |= ACT_TRANS_PROP;
if ((flags & ACT_TRANS_PROP) == 0) {
/* Custom properties only. */
pPtr = strstr(bPtr, "[\"");
if (pPtr) {
flags |= ACT_TRANS_PROP;
if (curves) {
BLI_addtail(curves, BLI_genericNodeN(fcu));
}
continue;
}
BLI_addtail(&curves, BLI_genericNodeN(fcu));
continue;
}
}
}
@@ -204,72 +177,70 @@ static eAction_TransformFlags get_item_transform_flags(bAction *act,
}
/* helper for poseAnim_mapping_get() -> get the relevant F-Curves per PoseChannel */
static void fcurves_to_pchan_links_get(ListBase *pfLinks,
Object *ob,
bAction *act,
bPoseChannel *pchan)
static void fcurves_to_pchan_links_get(ListBase &pfLinks,
Object &ob,
bAction &act,
bPoseChannel &pchan)
{
ListBase curves = {nullptr, nullptr};
const eAction_TransformFlags transFlags = get_item_transform_flags(act, ob, pchan, &curves);
const eAction_TransformFlags transFlags = get_item_transform_flags(act, ob, pchan, curves);
pchan->flag &= ~(POSE_LOC | POSE_ROT | POSE_SIZE | POSE_BBONE_SHAPE);
pchan.flag &= ~(POSE_LOC | POSE_ROT | POSE_SIZE | POSE_BBONE_SHAPE);
/* check if any transforms found... */
if (transFlags) {
/* make new linkage data */
tPChanFCurveLink *pfl = static_cast<tPChanFCurveLink *>(
MEM_callocN(sizeof(tPChanFCurveLink), "tPChanFCurveLink"));
if (!transFlags) {
return;
}
pfl->ob = ob;
pfl->fcurves = curves;
pfl->pchan = pchan;
tPChanFCurveLink *pfl = static_cast<tPChanFCurveLink *>(
MEM_callocN(sizeof(tPChanFCurveLink), "tPChanFCurveLink"));
/* get the RNA path to this pchan - this needs to be freed! */
PointerRNA ptr = RNA_pointer_create((ID *)ob, &RNA_PoseBone, pchan);
pfl->pchan_path = BLI_strdup(RNA_path_from_ID_to_struct(&ptr).value_or("").c_str());
pfl->ob = &ob;
pfl->fcurves = curves;
pfl->pchan = &pchan;
/* add linkage data to operator data */
BLI_addtail(pfLinks, pfl);
/* Get the RNA path to this pchan - this needs to be freed! */
PointerRNA ptr = RNA_pointer_create((ID *)&ob, &RNA_PoseBone, &pchan);
pfl->pchan_path = BLI_strdup(RNA_path_from_ID_to_struct(&ptr).value_or("").c_str());
/* set pchan's transform flags */
if (transFlags & ACT_TRANS_LOC) {
pchan->flag |= POSE_LOC;
}
if (transFlags & ACT_TRANS_ROT) {
pchan->flag |= POSE_ROT;
}
if (transFlags & ACT_TRANS_SCALE) {
pchan->flag |= POSE_SIZE;
}
if (transFlags & ACT_TRANS_BBONE) {
pchan->flag |= POSE_BBONE_SHAPE;
}
BLI_addtail(&pfLinks, pfl);
/* store current transforms */
copy_v3_v3(pfl->oldloc, pchan->loc);
copy_v3_v3(pfl->oldrot, pchan->eul);
copy_v3_v3(pfl->oldscale, pchan->size);
copy_qt_qt(pfl->oldquat, pchan->quat);
copy_v3_v3(pfl->oldaxis, pchan->rotAxis);
pfl->oldangle = pchan->rotAngle;
/* Set pchan's transform flags. */
if (transFlags & ACT_TRANS_LOC) {
pchan.flag |= POSE_LOC;
}
if (transFlags & ACT_TRANS_ROT) {
pchan.flag |= POSE_ROT;
}
if (transFlags & ACT_TRANS_SCALE) {
pchan.flag |= POSE_SIZE;
}
if (transFlags & ACT_TRANS_BBONE) {
pchan.flag |= POSE_BBONE_SHAPE;
}
/* store current bbone values */
pfl->roll1 = pchan->roll1;
pfl->roll2 = pchan->roll2;
pfl->curve_in_x = pchan->curve_in_x;
pfl->curve_in_z = pchan->curve_in_z;
pfl->curve_out_x = pchan->curve_out_x;
pfl->curve_out_z = pchan->curve_out_z;
pfl->ease1 = pchan->ease1;
pfl->ease2 = pchan->ease2;
copy_v3_v3(pfl->oldloc, pchan.loc);
copy_v3_v3(pfl->oldrot, pchan.eul);
copy_v3_v3(pfl->oldscale, pchan.size);
copy_qt_qt(pfl->oldquat, pchan.quat);
copy_v3_v3(pfl->oldaxis, pchan.rotAxis);
pfl->oldangle = pchan.rotAngle;
copy_v3_v3(pfl->scale_in, pchan->scale_in);
copy_v3_v3(pfl->scale_out, pchan->scale_out);
/* Store current bbone values. */
pfl->roll1 = pchan.roll1;
pfl->roll2 = pchan.roll2;
pfl->curve_in_x = pchan.curve_in_x;
pfl->curve_in_z = pchan.curve_in_z;
pfl->curve_out_x = pchan.curve_out_x;
pfl->curve_out_z = pchan.curve_out_z;
pfl->ease1 = pchan.ease1;
pfl->ease2 = pchan.ease2;
/* make copy of custom properties */
if (pchan->prop && (transFlags & ACT_TRANS_PROP)) {
pfl->oldprops = IDP_CopyProperty(pchan->prop);
}
copy_v3_v3(pfl->scale_in, pchan.scale_in);
copy_v3_v3(pfl->scale_out, pchan.scale_out);
/* Make copy of custom properties. */
if (pchan.prop && (transFlags & ACT_TRANS_PROP)) {
pfl->oldprops = IDP_CopyProperty(pchan.prop);
}
}
@@ -284,7 +255,8 @@ Object *poseAnim_object_get(Object *ob_)
void poseAnim_mapping_get(bContext *C, ListBase *pfLinks)
{
/* for each Pose-Channel which gets affected, get the F-Curves for that channel
BLI_assert(pfLinks != nullptr);
/* For each Pose-Channel which gets affected, get the F-Curves for that channel
* and set the relevant transform flags...
*/
Object *prev_ob, *ob_pose_armature;
@@ -292,6 +264,7 @@ void poseAnim_mapping_get(bContext *C, ListBase *pfLinks)
prev_ob = nullptr;
ob_pose_armature = nullptr;
CTX_DATA_BEGIN_WITH_ID (C, bPoseChannel *, pchan, selected_pose_bones, Object *, ob) {
BLI_assert(pchan != nullptr);
if (ob != prev_ob) {
prev_ob = ob;
ob_pose_armature = poseAnim_object_get(ob);
@@ -300,18 +273,24 @@ void poseAnim_mapping_get(bContext *C, ListBase *pfLinks)
if (ob_pose_armature == nullptr) {
continue;
}
if (!ob_pose_armature->adt || !ob_pose_armature->adt->action) {
/* No action means no FCurves. */
continue;
}
fcurves_to_pchan_links_get(pfLinks, ob_pose_armature, ob_pose_armature->adt->action, pchan);
fcurves_to_pchan_links_get(
*pfLinks, *ob_pose_armature, *ob_pose_armature->adt->action, *pchan);
}
CTX_DATA_END;
/* if no PoseChannels were found, try a second pass, doing visible ones instead
* i.e. if nothing selected, do whole pose
/* If no PoseChannels were found, try a second pass, doing visible ones instead.
* i.e. if nothing selected, do whole pose.
*/
if (BLI_listbase_is_empty(pfLinks)) {
prev_ob = nullptr;
ob_pose_armature = nullptr;
CTX_DATA_BEGIN_WITH_ID (C, bPoseChannel *, pchan, visible_pose_bones, Object *, ob) {
BLI_assert(pchan != nullptr);
if (ob != prev_ob) {
prev_ob = ob;
ob_pose_armature = poseAnim_object_get(ob);
@@ -320,8 +299,13 @@ void poseAnim_mapping_get(bContext *C, ListBase *pfLinks)
if (ob_pose_armature == nullptr) {
continue;
}
if (!ob_pose_armature->adt || !ob_pose_armature->adt->action) {
/* No action means no FCurves. */
continue;
}
fcurves_to_pchan_links_get(pfLinks, ob_pose_armature, ob_pose_armature->adt->action, pchan);
fcurves_to_pchan_links_get(
*pfLinks, *ob_pose_armature, *ob_pose_armature->adt->action, *pchan);
}
CTX_DATA_END;
}