Cleanup: Comments in animrig
No functional changes. For all the recently moved keyframing code I did the following: * Remove comments that just repeat what the code is doing. * Move comments for public functions to their location in the header file. * Make sure comments are formatted properly with a capital letter at the start and a dot at the end. Pull Request: https://projects.blender.org/blender/blender/pulls/114448
This commit is contained in:
committed by
Christoph Lendenfeld
parent
d1e732a114
commit
cfb50a2e2e
@@ -17,7 +17,7 @@ struct bAction;
|
||||
namespace blender::animrig {
|
||||
|
||||
/**
|
||||
* Get (or add relevant data to be able to do so) F-Curve from the Active Action,
|
||||
* Get (or add relevant data to be able to do so) F-Curve from the given Action,
|
||||
* for the given Animation Data block. This assumes that all the destinations are valid.
|
||||
*/
|
||||
FCurve *ED_action_fcurve_ensure(Main *bmain,
|
||||
@@ -28,11 +28,14 @@ FCurve *ED_action_fcurve_ensure(Main *bmain,
|
||||
int array_index);
|
||||
|
||||
/**
|
||||
* Find the F-Curve from the Active Action,
|
||||
* for the given Animation Data block. This assumes that all the destinations are valid.
|
||||
* Find the F-Curve from the given Action. This assumes that all the destinations are valid.
|
||||
*/
|
||||
FCurve *ED_action_fcurve_find(bAction *act, const char rna_path[], int array_index);
|
||||
|
||||
/**
|
||||
* \note The caller needs to run #BKE_nla_tweakedit_remap to get NLA relative frame.
|
||||
* The caller should also check #BKE_fcurve_is_protected before keying.
|
||||
*/
|
||||
bool delete_keyframe_fcurve(AnimData *adt, FCurve *fcu, float cfra);
|
||||
|
||||
} // namespace blender::animrig
|
||||
|
||||
@@ -92,6 +92,16 @@ int delete_keyframe(Main *bmain,
|
||||
int array_index,
|
||||
float cfra);
|
||||
|
||||
/**
|
||||
* Main Keyframing API call:
|
||||
* Use this when validation of necessary animation data isn't necessary as it
|
||||
* already exists. It will clear the current buttons fcurve(s).
|
||||
*
|
||||
* The flag argument is used for special settings that alter the behavior of
|
||||
* the keyframe deletion. These include the quick refresh options.
|
||||
*
|
||||
* \return The number of f-curves removed.
|
||||
*/
|
||||
int clear_keyframe(Main *bmain,
|
||||
ReportList *reports,
|
||||
ID *id,
|
||||
@@ -128,6 +138,14 @@ bool autokeyframe_cfra_can_key(const Scene *scene, ID *id);
|
||||
|
||||
void autokeyframe_object(
|
||||
bContext *C, Scene *scene, ViewLayer *view_layer, Object *ob, eTfmMode tmode);
|
||||
/**
|
||||
* Auto-keyframing feature - for objects
|
||||
*
|
||||
* \param tmode: A transform mode.
|
||||
*
|
||||
* \note Context may not always be available,
|
||||
* so must check before using it as it's a luxury for a few cases.
|
||||
*/
|
||||
bool autokeyframe_object(bContext *C, Scene *scene, Object *ob, KeyingSet *ks);
|
||||
bool autokeyframe_pchan(bContext *C, Scene *scene, Object *ob, bPoseChannel *pchan, KeyingSet *ks);
|
||||
|
||||
|
||||
@@ -15,7 +15,20 @@ struct PropertyRNA;
|
||||
|
||||
namespace blender::animrig {
|
||||
|
||||
/**
|
||||
* This helper function determines if visual-keyframing should be used when
|
||||
* inserting keyframes for the given channel. As visual-keyframing only works
|
||||
* on Object and Pose-Channel blocks, this should only get called for those
|
||||
* block-types, when using "standard" keying but 'Visual Keying' option in Auto-Keying
|
||||
* settings is on.
|
||||
*/
|
||||
bool visualkey_can_use(PointerRNA *ptr, PropertyRNA *prop);
|
||||
|
||||
/**
|
||||
* This helper function extracts the value to use for visual-keyframing
|
||||
* In the event that it is not possible to perform visual keying, try to fall-back
|
||||
* to using the default method. Assumes that all data it has been passed is valid.
|
||||
*/
|
||||
Vector<float> visualkey_get_values(PointerRNA *ptr, PropertyRNA *prop);
|
||||
|
||||
} // namespace blender::animrig
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup animrig
|
||||
*/
|
||||
|
||||
#include "BLI_vector.hh"
|
||||
#include "RNA_access.hh"
|
||||
#include "RNA_define.hh"
|
||||
|
||||
@@ -20,7 +20,6 @@ namespace blender::animrig {
|
||||
|
||||
FCurve *ED_action_fcurve_find(bAction *act, const char rna_path[], const int array_index)
|
||||
{
|
||||
/* Sanity checks. */
|
||||
if (ELEM(nullptr, act, rna_path)) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -37,7 +36,6 @@ FCurve *ED_action_fcurve_ensure(Main *bmain,
|
||||
bActionGroup *agrp;
|
||||
FCurve *fcu;
|
||||
|
||||
/* Sanity checks. */
|
||||
if (ELEM(nullptr, act, rna_path)) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -49,25 +47,20 @@ FCurve *ED_action_fcurve_ensure(Main *bmain,
|
||||
fcu = BKE_fcurve_find(&act->curves, rna_path, array_index);
|
||||
|
||||
if (fcu == nullptr) {
|
||||
/* use default settings to make a F-Curve */
|
||||
fcu = BKE_fcurve_create();
|
||||
|
||||
fcu->flag = (FCURVE_VISIBLE | FCURVE_SELECTED);
|
||||
fcu->auto_smoothing = U.auto_smoothing_new;
|
||||
if (BLI_listbase_is_empty(&act->curves)) {
|
||||
fcu->flag |= FCURVE_ACTIVE; /* first one added active */
|
||||
fcu->flag |= FCURVE_ACTIVE;
|
||||
}
|
||||
|
||||
/* store path - make copy, and store that */
|
||||
fcu->rna_path = BLI_strdup(rna_path);
|
||||
fcu->array_index = array_index;
|
||||
|
||||
/* if a group name has been provided, try to add or find a group, then add F-Curve to it */
|
||||
if (group) {
|
||||
/* try to find group */
|
||||
agrp = BKE_action_group_find_name(act, group);
|
||||
|
||||
/* no matching groups, so add one */
|
||||
if (agrp == nullptr) {
|
||||
agrp = action_groups_add_new(act, group);
|
||||
|
||||
@@ -78,11 +71,9 @@ FCurve *ED_action_fcurve_ensure(Main *bmain,
|
||||
}
|
||||
}
|
||||
|
||||
/* add F-Curve to group */
|
||||
action_groups_add_channel(act, agrp, fcu);
|
||||
}
|
||||
else {
|
||||
/* just add F-Curve to end of Action's list */
|
||||
BLI_addtail(&act->curves, fcu);
|
||||
}
|
||||
|
||||
@@ -92,32 +83,25 @@ FCurve *ED_action_fcurve_ensure(Main *bmain,
|
||||
DEG_relations_tag_update(bmain);
|
||||
}
|
||||
|
||||
/* return the F-Curve */
|
||||
return fcu;
|
||||
}
|
||||
|
||||
/**
|
||||
* \note caller needs to run #BKE_nla_tweakedit_remap to get NLA relative frame.
|
||||
* caller should also check #BKE_fcurve_is_protected before keying.
|
||||
*/
|
||||
bool delete_keyframe_fcurve(AnimData *adt, FCurve *fcu, float cfra)
|
||||
{
|
||||
bool found;
|
||||
int i;
|
||||
|
||||
/* try to find index of beztriple to get rid of */
|
||||
i = BKE_fcurve_bezt_binarysearch_index(fcu->bezt, cfra, fcu->totvert, &found);
|
||||
if (found) {
|
||||
/* delete the key at the index (will sanity check + do recalc afterwards) */
|
||||
/* Delete the key at the index (will sanity check + do recalc afterwards). */
|
||||
BKE_fcurve_delete_key(fcu, i);
|
||||
BKE_fcurve_handles_recalc(fcu);
|
||||
|
||||
/* Only delete curve too if it won't be doing anything anymore */
|
||||
/* Empty curves get automatically deleted. */
|
||||
if (BKE_fcurve_is_empty(fcu)) {
|
||||
ANIM_fcurve_delete_from_animdata(nullptr, adt, fcu);
|
||||
}
|
||||
|
||||
/* return success */
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -75,7 +75,6 @@ static void make_new_fcurve_cyclic(const bAction *act, FCurve *fcu)
|
||||
fcu->bezt[1].vec[1][0] += period;
|
||||
fcu->bezt[1].vec[2][0] += period;
|
||||
|
||||
/* Add the cycles modifier. */
|
||||
if (!fcu->modifiers.first) {
|
||||
add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_CYCLES, fcu);
|
||||
}
|
||||
@@ -151,14 +150,13 @@ static Vector<float> get_keyframe_values(ReportList *reports,
|
||||
Vector<float> values;
|
||||
|
||||
if ((flag & INSERTKEY_MATRIX) && visualkey_can_use(&ptr, prop)) {
|
||||
/* visual-keying is only available for object and pchan datablocks, as
|
||||
/* Visual-keying is only available for object and pchan datablocks, as
|
||||
* it works by keyframing using a value extracted from the final matrix
|
||||
* instead of using the kt system to extract a value.
|
||||
*/
|
||||
values = visualkey_get_values(&ptr, prop);
|
||||
}
|
||||
else {
|
||||
/* read value from system */
|
||||
values = ANIM_setting_get_rna_values(&ptr, prop);
|
||||
}
|
||||
|
||||
@@ -226,7 +224,7 @@ static eFCU_Cycle_Type remap_cyclic_keyframe_location(FCurve *fcu, float *px, fl
|
||||
return type;
|
||||
}
|
||||
|
||||
/* return codes for new_key_needed */
|
||||
/* Return codes for new_key_needed. */
|
||||
enum {
|
||||
KEYNEEDED_DONTADD = 0,
|
||||
KEYNEEDED_JUSTADD,
|
||||
@@ -244,7 +242,6 @@ enum {
|
||||
*/
|
||||
static short new_key_needed(FCurve *fcu, float cFrame, float nValue)
|
||||
{
|
||||
/* safety checking */
|
||||
if (fcu == nullptr) {
|
||||
return KEYNEEDED_JUSTADD;
|
||||
}
|
||||
@@ -253,49 +250,46 @@ static short new_key_needed(FCurve *fcu, float cFrame, float nValue)
|
||||
return KEYNEEDED_JUSTADD;
|
||||
}
|
||||
|
||||
/* loop through checking if any are the same */
|
||||
/* Loop through checking if any are the same. */
|
||||
BezTriple *bezt = fcu->bezt;
|
||||
BezTriple *prev = nullptr;
|
||||
for (int i = 0; i < totCount; i++) {
|
||||
float prevPosi = 0.0f, prevVal = 0.0f;
|
||||
float beztPosi = 0.0f, beztVal = 0.0f;
|
||||
|
||||
/* get current time+value */
|
||||
beztPosi = bezt->vec[1][0];
|
||||
beztVal = bezt->vec[1][1];
|
||||
|
||||
if (prev) {
|
||||
/* there is a keyframe before the one currently being examined */
|
||||
|
||||
/* get previous time+value */
|
||||
/* There is a keyframe before the one currently being examined. */
|
||||
prevPosi = prev->vec[1][0];
|
||||
prevVal = prev->vec[1][1];
|
||||
|
||||
/* keyframe to be added at point where there are already two similar points? */
|
||||
/* Keyframe to be added at point where there are already two similar points? */
|
||||
if (IS_EQF(prevPosi, cFrame) && IS_EQF(beztPosi, cFrame) && IS_EQF(beztPosi, prevPosi)) {
|
||||
return KEYNEEDED_DONTADD;
|
||||
}
|
||||
|
||||
/* keyframe between prev+current points ? */
|
||||
/* Keyframe between prev+current points? */
|
||||
if ((prevPosi <= cFrame) && (cFrame <= beztPosi)) {
|
||||
/* is the value of keyframe to be added the same as keyframes on either side ? */
|
||||
/* Is the value of keyframe to be added the same as keyframes on either side? */
|
||||
if (IS_EQF(prevVal, nValue) && IS_EQF(beztVal, nValue) && IS_EQF(prevVal, beztVal)) {
|
||||
return KEYNEEDED_DONTADD;
|
||||
}
|
||||
|
||||
float realVal;
|
||||
|
||||
/* get real value of curve at that point */
|
||||
/* Get real value of curve at that point. */
|
||||
realVal = evaluate_fcurve(fcu, cFrame);
|
||||
|
||||
/* compare whether it's the same as proposed */
|
||||
/* Compare whether it's the same as proposed. */
|
||||
if (IS_EQF(realVal, nValue)) {
|
||||
return KEYNEEDED_DONTADD;
|
||||
}
|
||||
return KEYNEEDED_JUSTADD;
|
||||
}
|
||||
|
||||
/* new keyframe before prev beztriple? */
|
||||
/* New keyframe before prev beztriple? */
|
||||
if (cFrame < prevPosi) {
|
||||
/* A new keyframe will be added. However, whether the previous beztriple
|
||||
* stays around or not depends on whether the values of previous/current
|
||||
@@ -309,7 +303,7 @@ static short new_key_needed(FCurve *fcu, float cFrame, float nValue)
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* just add a keyframe if there's only one keyframe
|
||||
/* Just add a keyframe if there's only one keyframe
|
||||
* and the new one occurs before the existing one does.
|
||||
*/
|
||||
if ((cFrame < beztPosi) && (totCount == 1)) {
|
||||
@@ -317,7 +311,7 @@ static short new_key_needed(FCurve *fcu, float cFrame, float nValue)
|
||||
}
|
||||
}
|
||||
|
||||
/* continue. frame to do not yet passed (or other conditions not met) */
|
||||
/* Continue. Frame to do not yet passed (or other conditions not met) */
|
||||
if (i < (totCount - 1)) {
|
||||
prev = bezt;
|
||||
bezt++;
|
||||
@@ -359,11 +353,9 @@ static AnimationEvalContext nla_time_remap(const AnimationEvalContext *anim_eval
|
||||
NlaKeyframingContext **r_nla_context)
|
||||
{
|
||||
if (adt && adt->action == act) {
|
||||
/* Get NLA context for value remapping. */
|
||||
*r_nla_context = BKE_animsys_get_nla_keyframing_context(
|
||||
nla_cache, id_ptr, adt, anim_eval_context);
|
||||
|
||||
/* Apply NLA-mapping to frame. */
|
||||
const float remapped_frame = BKE_nla_tweakedit_remap(
|
||||
adt, anim_eval_context->eval_time, NLATIME_CONVERT_UNMAP);
|
||||
return BKE_animsys_eval_context_construct_at(anim_eval_context, remapped_frame);
|
||||
@@ -383,7 +375,6 @@ static bool insert_keyframe_value(ReportList *reports,
|
||||
eBezTriple_KeyframeType keytype,
|
||||
eInsertKeyFlags flag)
|
||||
{
|
||||
/* F-Curve not editable? */
|
||||
if (BKE_fcurve_is_keyframable(fcu) == 0) {
|
||||
BKE_reportf(
|
||||
reports,
|
||||
@@ -397,12 +388,11 @@ static bool insert_keyframe_value(ReportList *reports,
|
||||
|
||||
float cfra = anim_eval_context->eval_time;
|
||||
|
||||
/* adjust frame on which to add keyframe */
|
||||
/* Adjust frame on which to add keyframe, to make it easier to add corrective drivers. */
|
||||
if ((flag & INSERTKEY_DRIVER) && (fcu->driver)) {
|
||||
PathResolvedRNA anim_rna;
|
||||
|
||||
if (RNA_path_resolved_create(ptr, prop, fcu->array_index, &anim_rna)) {
|
||||
/* for making it easier to add corrective drivers... */
|
||||
cfra = evaluate_driver(&anim_rna, fcu->driver, fcu->driver, anim_eval_context);
|
||||
}
|
||||
else {
|
||||
@@ -410,30 +400,27 @@ static bool insert_keyframe_value(ReportList *reports,
|
||||
}
|
||||
}
|
||||
|
||||
/* adjust coordinates for cycle aware insertion */
|
||||
/* Adjust coordinates for cycle aware insertion. */
|
||||
if (flag & INSERTKEY_CYCLE_AWARE) {
|
||||
if (remap_cyclic_keyframe_location(fcu, &cfra, &curval) != FCU_CYCLE_PERFECT) {
|
||||
/* inhibit action from insert_vert_fcurve unless it's a perfect cycle */
|
||||
/* Inhibit action from insert_vert_fcurve unless it's a perfect cycle. */
|
||||
flag &= ~INSERTKEY_CYCLE_AWARE;
|
||||
}
|
||||
}
|
||||
|
||||
/* only insert keyframes where they are needed */
|
||||
if (flag & INSERTKEY_NEEDED) {
|
||||
/* check whether this curve really needs a new keyframe */
|
||||
static short insert_mode = new_key_needed(fcu, cfra, curval);
|
||||
|
||||
/* only return success if keyframe added */
|
||||
if (insert_mode == KEYNEEDED_DONTADD) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* insert new keyframe at current frame */
|
||||
if (insert_vert_fcurve(fcu, cfra, curval, keytype, flag) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* delete keyframe immediately before/after newly added */
|
||||
/* Based on the heuristics applied in new_key_needed(), the previous or next key needs to be
|
||||
* deleted. */
|
||||
switch (insert_mode) {
|
||||
case KEYNEEDED_DELPREV:
|
||||
BKE_fcurve_delete_key(fcu, fcu->totvert - 2);
|
||||
@@ -448,7 +435,6 @@ static bool insert_keyframe_value(ReportList *reports,
|
||||
return true;
|
||||
}
|
||||
|
||||
/* just insert keyframe */
|
||||
return insert_vert_fcurve(fcu, cfra, curval, keytype, flag) >= 0;
|
||||
}
|
||||
|
||||
@@ -462,24 +448,21 @@ bool insert_keyframe_direct(ReportList *reports,
|
||||
eInsertKeyFlags flag)
|
||||
{
|
||||
|
||||
/* no F-Curve to add keyframe to? */
|
||||
if (fcu == nullptr) {
|
||||
BKE_report(reports, RPT_ERROR, "No F-Curve to add keyframes to");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* if no property given yet, try to validate from F-Curve info */
|
||||
if ((ptr.owner_id == nullptr) && (ptr.data == nullptr)) {
|
||||
BKE_report(
|
||||
reports, RPT_ERROR, "No RNA pointer available to retrieve values for keyframing from");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (prop == nullptr) {
|
||||
PointerRNA tmp_ptr;
|
||||
|
||||
/* try to get property we should be affecting */
|
||||
if (RNA_path_resolve_property(&ptr, fcu->rna_path, &tmp_ptr, &prop) == false) {
|
||||
/* property not found... */
|
||||
const char *idname = (ptr.owner_id) ? ptr.owner_id->name : TIP_("<No ID pointer>");
|
||||
|
||||
BKE_reportf(reports,
|
||||
@@ -491,14 +474,13 @@ bool insert_keyframe_direct(ReportList *reports,
|
||||
return false;
|
||||
}
|
||||
|
||||
/* property found, so overwrite 'ptr' to make later code easier */
|
||||
/* Property found, so overwrite 'ptr' to make later code easier. */
|
||||
ptr = tmp_ptr;
|
||||
}
|
||||
|
||||
/* update F-Curve flags to ensure proper behavior for property type */
|
||||
/* Update F-Curve flags to ensure proper behavior for property type. */
|
||||
update_autoflags_fcurve_direct(fcu, prop);
|
||||
|
||||
/* Obtain the value to insert. */
|
||||
const int index = fcu->array_index;
|
||||
BLI_bitmap *successful_remaps = nullptr;
|
||||
Vector<float> values = get_keyframe_values(reports,
|
||||
@@ -528,7 +510,7 @@ bool insert_keyframe_direct(ReportList *reports,
|
||||
reports, &ptr, prop, fcu, anim_eval_context, current_value, keytype, flag);
|
||||
}
|
||||
|
||||
/** Find or create the #FCurve based on the given path, and insert the specified value into it. */
|
||||
/** Find or create the FCurve based on the given path, and insert the specified value into it. */
|
||||
static bool insert_keyframe_fcurve_value(Main *bmain,
|
||||
ReportList *reports,
|
||||
PointerRNA *ptr,
|
||||
@@ -542,7 +524,7 @@ static bool insert_keyframe_fcurve_value(Main *bmain,
|
||||
eBezTriple_KeyframeType keytype,
|
||||
eInsertKeyFlags flag)
|
||||
{
|
||||
/* make sure the F-Curve exists
|
||||
/* Make sure the F-Curve exists.
|
||||
* - if we're replacing keyframes only, DO NOT create new F-Curves if they do not exist yet
|
||||
* but still try to get the F-Curve if it exists...
|
||||
*/
|
||||
@@ -551,16 +533,16 @@ static bool insert_keyframe_fcurve_value(Main *bmain,
|
||||
ED_action_fcurve_ensure(bmain, act, group, ptr, rna_path, array_index) :
|
||||
ED_action_fcurve_find(act, rna_path, array_index);
|
||||
|
||||
/* we may not have a F-Curve when we're replacing only... */
|
||||
/* We may not have a F-Curve when we're replacing only. */
|
||||
if (!fcu) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool is_new_curve = (fcu->totvert == 0);
|
||||
|
||||
/* set color mode if the F-Curve is new (i.e. without any keyframes) */
|
||||
/* Set color mode if the F-Curve is new (i.e. without any keyframes). */
|
||||
if (is_new_curve && (flag & INSERTKEY_XYZ2RGB)) {
|
||||
/* for Loc/Rot/Scale and also Color F-Curves, the color of the F-Curve in the Graph Editor,
|
||||
/* For Loc/Rot/Scale and also Color F-Curves, the color of the F-Curve in the Graph Editor,
|
||||
* is determined by the array index for the F-Curve
|
||||
*/
|
||||
PropertySubType prop_subtype = RNA_property_subtype(prop);
|
||||
@@ -579,10 +561,9 @@ static bool insert_keyframe_fcurve_value(Main *bmain,
|
||||
make_new_fcurve_cyclic(act, fcu);
|
||||
}
|
||||
|
||||
/* update F-Curve flags to ensure proper behavior for property type */
|
||||
/* Update F-Curve flags to ensure proper behavior for property type. */
|
||||
update_autoflags_fcurve_direct(fcu, prop);
|
||||
|
||||
/* insert keyframe */
|
||||
const bool success = insert_keyframe_value(
|
||||
reports, ptr, prop, fcu, anim_eval_context, curval, keytype, flag);
|
||||
|
||||
@@ -605,7 +586,6 @@ int insert_keyframe(Main *bmain,
|
||||
eBezTriple_KeyframeType keytype,
|
||||
eInsertKeyFlags flag)
|
||||
{
|
||||
/* validate pointer first - exit if failure */
|
||||
if (id == nullptr) {
|
||||
BKE_reportf(reports, RPT_ERROR, "No ID block to insert keyframe in (path = %s)", rna_path);
|
||||
return 0;
|
||||
@@ -629,11 +609,9 @@ int insert_keyframe(Main *bmain,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if no action is provided, keyframe to the default one attached to this ID-block */
|
||||
/* If no action is provided, keyframe to the default one attached to this ID-block. */
|
||||
if (act == nullptr) {
|
||||
/* get action to add F-Curve+keyframe to */
|
||||
act = ED_id_action_ensure(bmain, id);
|
||||
|
||||
if (act == nullptr) {
|
||||
BKE_reportf(reports,
|
||||
RPT_ERROR,
|
||||
@@ -645,14 +623,13 @@ int insert_keyframe(Main *bmain,
|
||||
}
|
||||
}
|
||||
|
||||
/* apply NLA-mapping to frame to use (if applicable) */
|
||||
/* Apply NLA-mapping to frame to use (if applicable). */
|
||||
NlaKeyframingContext *nla_context = nullptr;
|
||||
ListBase nla_cache = {nullptr, nullptr};
|
||||
AnimData *adt = BKE_animdata_from_id(id);
|
||||
const AnimationEvalContext remapped_context = nla_time_remap(
|
||||
anim_eval_context, &id_ptr, adt, act, &nla_cache, &nla_context);
|
||||
|
||||
/* Obtain values to insert. */
|
||||
bool force_all;
|
||||
BLI_bitmap *successful_remaps = nullptr;
|
||||
Vector<float> values = get_keyframe_values(reports,
|
||||
@@ -813,13 +790,11 @@ int delete_keyframe(Main *bmain,
|
||||
{
|
||||
AnimData *adt = BKE_animdata_from_id(id);
|
||||
|
||||
/* sanity checks */
|
||||
if (ELEM(nullptr, id, adt)) {
|
||||
BKE_report(reports, RPT_ERROR, "No ID block and/or AnimData to delete keyframe from");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* validate pointer first - exit if failure */
|
||||
PointerRNA ptr;
|
||||
PropertyRNA *prop;
|
||||
PointerRNA id_ptr = RNA_id_pointer_create(id);
|
||||
@@ -833,18 +808,9 @@ int delete_keyframe(Main *bmain,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get F-Curve
|
||||
* NOTE: here is one of the places where we don't want new Action + F-Curve added!
|
||||
* so 'add' var must be 0
|
||||
*/
|
||||
if (act == nullptr) {
|
||||
/* if no action is provided, use the default one attached to this ID-block
|
||||
* - if it doesn't exist, then we're out of options...
|
||||
*/
|
||||
if (adt->action) {
|
||||
act = adt->action;
|
||||
|
||||
/* apply NLA-mapping to frame to use (if applicable) */
|
||||
cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
|
||||
}
|
||||
else {
|
||||
@@ -854,26 +820,25 @@ int delete_keyframe(Main *bmain,
|
||||
}
|
||||
|
||||
int array_index_max = array_index + 1;
|
||||
/* key entire array convenience method */
|
||||
|
||||
if (array_index == -1) {
|
||||
array_index = 0;
|
||||
array_index_max = RNA_property_array_length(&ptr, prop);
|
||||
|
||||
/* for single properties, increase max_index so that the property itself gets included,
|
||||
/* For single properties, increase max_index so that the property itself gets included,
|
||||
* but don't do this for standard arrays since that can cause corruption issues
|
||||
* (extra unused curves)
|
||||
* (extra unused curves).
|
||||
*/
|
||||
if (array_index_max == array_index) {
|
||||
array_index_max++;
|
||||
}
|
||||
}
|
||||
|
||||
/* will only loop once unless the array index was -1 */
|
||||
/* Will only loop once unless the array index was -1. */
|
||||
int key_count = 0;
|
||||
for (; array_index < array_index_max; array_index++) {
|
||||
FCurve *fcu = ED_action_fcurve_find(act, rna_path, array_index);
|
||||
|
||||
/* check if F-Curve exists and/or whether it can be edited */
|
||||
if (fcu == nullptr) {
|
||||
continue;
|
||||
}
|
||||
@@ -893,23 +858,13 @@ int delete_keyframe(Main *bmain,
|
||||
if (key_count) {
|
||||
deg_tag_after_keyframe_delete(bmain, id, adt);
|
||||
}
|
||||
/* return success/failure */
|
||||
|
||||
return key_count;
|
||||
}
|
||||
|
||||
/* ************************************************** */
|
||||
/* KEYFRAME CLEAR */
|
||||
|
||||
/**
|
||||
* Main Keyframing API call:
|
||||
* Use this when validation of necessary animation data isn't necessary as it
|
||||
* already exists. It will clear the current buttons fcurve(s).
|
||||
*
|
||||
* The flag argument is used for special settings that alter the behavior of
|
||||
* the keyframe deletion. These include the quick refresh options.
|
||||
*
|
||||
* \return The number of f-curves removed.
|
||||
*/
|
||||
int clear_keyframe(Main *bmain,
|
||||
ReportList *reports,
|
||||
ID *id,
|
||||
@@ -920,13 +875,11 @@ int clear_keyframe(Main *bmain,
|
||||
{
|
||||
AnimData *adt = BKE_animdata_from_id(id);
|
||||
|
||||
/* sanity checks */
|
||||
if (ELEM(nullptr, id, adt)) {
|
||||
BKE_report(reports, RPT_ERROR, "No ID block and/or AnimData to delete keyframe from");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* validate pointer first - exit if failure */
|
||||
PointerRNA ptr;
|
||||
PropertyRNA *prop;
|
||||
PointerRNA id_ptr = RNA_id_pointer_create(id);
|
||||
@@ -940,14 +893,7 @@ int clear_keyframe(Main *bmain,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get F-Curve
|
||||
* NOTE: here is one of the places where we don't want new Action + F-Curve added!
|
||||
* so 'add' var must be 0
|
||||
*/
|
||||
if (act == nullptr) {
|
||||
/* if no action is provided, use the default one attached to this ID-block
|
||||
* - if it doesn't exist, then we're out of options...
|
||||
*/
|
||||
if (adt->action) {
|
||||
act = adt->action;
|
||||
}
|
||||
@@ -957,15 +903,14 @@ int clear_keyframe(Main *bmain,
|
||||
}
|
||||
}
|
||||
|
||||
/* key entire array convenience method */
|
||||
int array_index_max = array_index + 1;
|
||||
if (array_index == -1) {
|
||||
array_index = 0;
|
||||
array_index_max = RNA_property_array_length(&ptr, prop);
|
||||
|
||||
/* for single properties, increase max_index so that the property itself gets included,
|
||||
/* For single properties, increase max_index so that the property itself gets included,
|
||||
* but don't do this for standard arrays since that can cause corruption issues
|
||||
* (extra unused curves)
|
||||
* (extra unused curves).
|
||||
*/
|
||||
if (array_index_max == array_index) {
|
||||
array_index_max++;
|
||||
@@ -973,11 +918,10 @@ int clear_keyframe(Main *bmain,
|
||||
}
|
||||
|
||||
int key_count = 0;
|
||||
/* will only loop once unless the array index was -1 */
|
||||
/* Will only loop once unless the array index was -1. */
|
||||
for (; array_index < array_index_max; array_index++) {
|
||||
FCurve *fcu = ED_action_fcurve_find(act, rna_path, array_index);
|
||||
|
||||
/* check if F-Curve exists and/or whether it can be edited */
|
||||
if (fcu == nullptr) {
|
||||
continue;
|
||||
}
|
||||
@@ -994,13 +938,12 @@ int clear_keyframe(Main *bmain,
|
||||
|
||||
ANIM_fcurve_delete_from_animdata(nullptr, adt, fcu);
|
||||
|
||||
/* return success */
|
||||
key_count++;
|
||||
}
|
||||
if (key_count) {
|
||||
deg_tag_after_keyframe_delete(bmain, id, adt);
|
||||
}
|
||||
/* return success/failure */
|
||||
|
||||
return key_count;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ bool is_autokey_flag(const Scene *scene, const eAutokey_Flag flag)
|
||||
|
||||
bool autokeyframe_cfra_can_key(const Scene *scene, ID *id)
|
||||
{
|
||||
/* only filter if auto-key mode requires this */
|
||||
/* Only filter if auto-key mode requires this. */
|
||||
if (!is_autokey_on(scene)) {
|
||||
return false;
|
||||
}
|
||||
@@ -78,18 +78,9 @@ bool autokeyframe_cfra_can_key(const Scene *scene, ID *id)
|
||||
*/
|
||||
scene->toolsettings->autokey_mode = AUTOKEY_MODE_NORMAL;
|
||||
|
||||
/* Can insert anytime we like... */
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto-keyframing feature - for objects
|
||||
*
|
||||
* \param tmode: A transform mode.
|
||||
*
|
||||
* \note Context may not always be available,
|
||||
* so must check before using it as it's a luxury for a few cases.
|
||||
*/
|
||||
void autokeyframe_object(
|
||||
bContext *C, Scene *scene, ViewLayer *view_layer, Object *ob, const eTfmMode tmode)
|
||||
{
|
||||
@@ -121,12 +112,13 @@ void autokeyframe_object(
|
||||
ANIM_apply_keyingset(
|
||||
C, &sources, active_ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
|
||||
}
|
||||
|
||||
else if (is_autokey_flag(scene, AUTOKEY_FLAG_INSERTAVAIL)) {
|
||||
/* Only key on available channels. */
|
||||
AnimData *adt = ob->adt;
|
||||
ToolSettings *ts = scene->toolsettings;
|
||||
Main *bmain = CTX_data_main(C);
|
||||
|
||||
/* only key on available channels */
|
||||
if (adt && adt->action) {
|
||||
LISTBASE_FOREACH (FCurve *, fcu, &adt->action->curves) {
|
||||
insert_keyframe(bmain,
|
||||
@@ -142,10 +134,11 @@ void autokeyframe_object(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (is_autokey_flag(scene, AUTOKEY_FLAG_INSERTNEEDED)) {
|
||||
bool do_loc = false, do_rot = false, do_scale = false;
|
||||
|
||||
/* filter the conditions when this happens (assume that curarea->spacetype==SPACE_VIE3D) */
|
||||
/* Filter the conditions when this happens (assume that curarea->spacetype==SPACE_VIE3D). */
|
||||
if (tmode == TFM_TRANSLATION) {
|
||||
do_loc = true;
|
||||
}
|
||||
@@ -180,7 +173,6 @@ void autokeyframe_object(
|
||||
}
|
||||
}
|
||||
|
||||
/* insert keyframes for the affected sets of channels using the builtin KeyingSets found */
|
||||
if (do_loc) {
|
||||
KeyingSet *ks = ANIM_builtin_keyingset_get_named(ANIM_KS_LOCATION_ID);
|
||||
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
|
||||
@@ -194,7 +186,8 @@ void autokeyframe_object(
|
||||
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
|
||||
}
|
||||
}
|
||||
/* insert keyframe in all (transform) channels */
|
||||
|
||||
/* Insert keyframe in all (transform) channels. */
|
||||
else {
|
||||
KeyingSet *ks = ANIM_builtin_keyingset_get_named(ANIM_KS_LOC_ROT_SCALE_ID);
|
||||
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
|
||||
@@ -203,7 +196,6 @@ void autokeyframe_object(
|
||||
|
||||
bool autokeyframe_object(bContext *C, Scene *scene, Object *ob, KeyingSet *ks)
|
||||
{
|
||||
/* auto keyframing */
|
||||
if (!autokeyframe_cfra_can_key(scene, &ob->id)) {
|
||||
return false;
|
||||
}
|
||||
@@ -255,8 +247,8 @@ bool autokeyframe_property(bContext *C,
|
||||
bool special;
|
||||
bool changed = false;
|
||||
|
||||
/* for entire array buttons we check the first component, it's not perfect
|
||||
* but works well enough in typical cases */
|
||||
/* For entire array buttons we check the first component, it's not perfect
|
||||
* but works well enough in typical cases. */
|
||||
const int rnaindex_check = (rnaindex == -1) ? 0 : rnaindex;
|
||||
FCurve *fcu = BKE_fcurve_find_by_rna_context_ui(
|
||||
C, ptr, prop, rnaindex_check, nullptr, &action, &driven, &special);
|
||||
@@ -268,7 +260,7 @@ bool autokeyframe_property(bContext *C,
|
||||
}
|
||||
|
||||
if (special) {
|
||||
/* NLA Strip property */
|
||||
/* NLA Strip property. */
|
||||
if (is_autokey_on(scene)) {
|
||||
ReportList *reports = CTX_wm_reports(C);
|
||||
ToolSettings *ts = scene->toolsettings;
|
||||
@@ -286,7 +278,7 @@ bool autokeyframe_property(bContext *C,
|
||||
}
|
||||
else if (driven) {
|
||||
/* Driver - Try to insert keyframe using the driver's input as the frame,
|
||||
* making it easier to set up corrective drivers
|
||||
* making it easier to set up corrective drivers.
|
||||
*/
|
||||
if (is_autokey_on(scene)) {
|
||||
ReportList *reports = CTX_wm_reports(C);
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
namespace blender::animrig {
|
||||
|
||||
/* internal status codes for visualkey_can_use */
|
||||
/* Internal status codes for visualkey_can_use. */
|
||||
enum {
|
||||
VISUALKEY_NONE = 0,
|
||||
VISUALKEY_LOC,
|
||||
@@ -39,42 +39,32 @@ enum {
|
||||
VISUALKEY_SCA,
|
||||
};
|
||||
|
||||
/**
|
||||
* This helper function determines if visual-keyframing should be used when
|
||||
* inserting keyframes for the given channel. As visual-keyframing only works
|
||||
* on Object and Pose-Channel blocks, this should only get called for those
|
||||
* block-types, when using "standard" keying but 'Visual Keying' option in Auto-Keying
|
||||
* settings is on.
|
||||
*/
|
||||
bool visualkey_can_use(PointerRNA *ptr, PropertyRNA *prop)
|
||||
{
|
||||
bConstraint *con = nullptr;
|
||||
bool has_rigidbody = false;
|
||||
bool has_parent = false;
|
||||
|
||||
/* validate data */
|
||||
if (ELEM(nullptr, ptr, ptr->data, prop)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* get first constraint and determine type of keyframe constraints to check for
|
||||
/* Get first constraint and determine type of keyframe constraints to check for
|
||||
* - constraints can be on either Objects or PoseChannels, so we only check if the
|
||||
* ptr->type is RNA_Object or RNA_PoseBone, which are the RNA wrapping-info for
|
||||
* those structs, allowing us to identify the owner of the data
|
||||
*/
|
||||
if (ptr->type == &RNA_Object) {
|
||||
/* Object */
|
||||
Object *ob = static_cast<Object *>(ptr->data);
|
||||
RigidBodyOb *rbo = ob->rigidbody_object;
|
||||
|
||||
con = static_cast<bConstraint *>(ob->constraints.first);
|
||||
has_parent = (ob->parent != nullptr);
|
||||
|
||||
/* active rigidbody objects only, as only those are affected by sim */
|
||||
/* Active rigidbody objects only, as only those are affected by sim. */
|
||||
has_rigidbody = ((rbo) && (rbo->type == RBO_TYPE_ACTIVE));
|
||||
}
|
||||
else if (ptr->type == &RNA_PoseBone) {
|
||||
/* Pose Channel */
|
||||
bPoseChannel *pchan = static_cast<bPoseChannel *>(ptr->data);
|
||||
|
||||
if (pchan->constflag & (PCHAN_HAS_IK | PCHAN_INFLUENCED_BY_IK)) {
|
||||
@@ -129,9 +119,9 @@ bool visualkey_can_use(PointerRNA *ptr, PropertyRNA *prop)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* some constraints may alter these transforms */
|
||||
/* Some constraints may alter these transforms. */
|
||||
switch (con->type) {
|
||||
/* multi-transform constraints */
|
||||
/* Multi-transform constraints. */
|
||||
case CONSTRAINT_TYPE_CHILDOF:
|
||||
case CONSTRAINT_TYPE_ARMATURE:
|
||||
return true;
|
||||
@@ -208,11 +198,6 @@ bool visualkey_can_use(PointerRNA *ptr, PropertyRNA *prop)
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This helper function extracts the value to use for visual-keyframing
|
||||
* In the event that it is not possible to perform visual keying, try to fall-back
|
||||
* to using the default method. Assumes that all data it has been passed is valid.
|
||||
*/
|
||||
Vector<float> visualkey_get_values(PointerRNA *ptr, PropertyRNA *prop)
|
||||
{
|
||||
Vector<float> values;
|
||||
@@ -220,7 +205,7 @@ Vector<float> visualkey_get_values(PointerRNA *ptr, PropertyRNA *prop)
|
||||
float tmat[4][4];
|
||||
int rotmode;
|
||||
|
||||
/* handle for Objects or PoseChannels only
|
||||
/* Handle for Objects or PoseChannels only
|
||||
* - only Location, Rotation or Scale keyframes are supported currently
|
||||
* - constraints can be on either Objects or PoseChannels, so we only check if the
|
||||
* ptr->type is RNA_Object or RNA_PoseBone, which are the RNA wrapping-info for
|
||||
@@ -246,7 +231,7 @@ Vector<float> visualkey_get_values(PointerRNA *ptr, PropertyRNA *prop)
|
||||
|
||||
/* Loc code is specific... */
|
||||
if (strstr(identifier, "location")) {
|
||||
/* only use for non-connected bones */
|
||||
/* Only use for non-connected bones. */
|
||||
if ((pchan->bone->parent == nullptr) || !(pchan->bone->flag & BONE_CONNECTED)) {
|
||||
values.extend({tmat[3], 3});
|
||||
return values;
|
||||
@@ -283,7 +268,7 @@ Vector<float> visualkey_get_values(PointerRNA *ptr, PropertyRNA *prop)
|
||||
return values;
|
||||
}
|
||||
|
||||
/* as the function hasn't returned yet, read value from system in the default way */
|
||||
/* As the function hasn't returned yet, read value from system in the default way. */
|
||||
return ANIM_setting_get_rna_values(ptr, prop);
|
||||
}
|
||||
} // namespace blender::animrig
|
||||
|
||||
Reference in New Issue
Block a user