Fix #130216: GPv3: Crash in render due to slotted Actions
The root cause of this bug can be traced to: - `ANIM_nla_mapping_get(ac, ale)` conditionally returns an `AnimData *adt`. - This can be `nullptr` in various cases, depending on the editor (in `ac`) and the type & source of data (in `ale`). - This `nullptr` has different meanings: 1. There is not enough information to return an `adt` (like `ac` or `ale` being `nullptr` themselves). 2. NLA time remapping should not be done. For example for NLA control F-Curves (like animated strip influence), or Grease Pencil (because that doesn't use the NLA). - The above-returned `adt` is passed to other functions. Some of them are aware of the "`nullptr` means no NLA time remapping" scenario, and gracefully handle it. Other code, however, just gets "an adt" from the caller and handles it as normal (and likely crashes on `nullptr`). Other cases start out as the first, but somewhere in the call stack shift over to the second. The approach taken in this PR to fix the bug is to (generally) stop signaling "do not use NLA time remapping" via `adt = nullptr`, and instead explicitly indicate/check whether remapping should be done. In most cases this means passing a `bAnimListElem *` instead of an `AnimData *`, because the former has the information needed to determine if time remapping should be done or not. However, in some cases there is no `bAnimListElem *` to pass, and instead other information determines whether remapping is needed. In those cases we add a `bool` parameter or field in the appropriate place so that calling code can explicitly indicate whether remapping should be done or not. To accomplish this a variety of functions have been added to help handle things correctly. Of particular note: - `AnimData *ANIM_nla_mapping_get(ac, ale)` (that conditionally returned an `adt`) has been removed entirely in favor of the new `bool ANIM_nla_mapping_allowed(ale)` function that simply returns whether nla remapping should be done or not. - `ANIM_nla_tweakedit_remap(ale, …)` has been added, which wraps `BKE_nla_tweakedit_remap(adt, …)` and only performs the remapping when `ANIM_nla_mapping_allowed()` indicates that it's allowed. - `ANIM_nla_mapping_apply_if_needed_fcurve(ale, …)` has been added, which is an alternative to `ANIM_nla_mapping_apply_fcurve(adt, …)` that also only performs the remapping when `ANIM_nla_mapping_allowed()` indicates that it's allowed. Note that even with this PR there are still a couple of places remaining that use `adt = nullptr` to indicate "don't remap", because they appear to be correct and would require larger changes to make explicit. In those cases comments have been added to explain the situation, with a reference to this PR. In the future we way want to take the time to change those as well. Also of minor note: this PR moves the definition of the type `slot_handle_t` from ANIM_action.hh to BKE_action.hh. This is due to `BKE_nla.hh` (which needs that definition) now being included directly and indirectly in a lot more places. Moving the definition to BKE_action.hh prevents all of those new places from gaining dependencies on the animrig module. Co-authored-by: Sybren A. Stüvel <sybren@blender.org> Pull Request: #130440
This commit is contained in:
parent
c17b546dac
commit
1dcd435a87
@ -15,6 +15,7 @@
|
||||
#include "DNA_action_types.h"
|
||||
#include "DNA_anim_types.h"
|
||||
|
||||
#include "BKE_action.hh"
|
||||
#include "BKE_anim_data.hh"
|
||||
|
||||
#include "BLI_math_vector.hh"
|
||||
@ -40,9 +41,6 @@ class Layer;
|
||||
class Strip;
|
||||
class Slot;
|
||||
|
||||
/* Use an alias for the Slot handle type to help disambiguate function parameters. */
|
||||
using slot_handle_t = decltype(::ActionSlot::handle);
|
||||
|
||||
/**
|
||||
* Container of animation data for one or more animated IDs.
|
||||
*
|
||||
|
@ -35,6 +35,25 @@ struct bPose;
|
||||
struct bPoseChannel;
|
||||
struct bPoseChannel_Runtime;
|
||||
|
||||
namespace blender::animrig {
|
||||
|
||||
/**
|
||||
* Action slot handle type.
|
||||
*
|
||||
* An identifier of slots within an action that is guaranteed to be unique
|
||||
* within that action and is guaranteed not to change for a slot.
|
||||
*
|
||||
* NOTE: keep this type in sync with `ActionSlot::handle` in the action DNA
|
||||
* types. We redefine it here rather than making a type alias to avoid bringing
|
||||
* in the entirety of DNA_action_types.h for everything that includes this
|
||||
* header.
|
||||
*
|
||||
* \see `ActionSlot::handle`
|
||||
*/
|
||||
using slot_handle_t = int32_t;
|
||||
|
||||
} // namespace blender::animrig
|
||||
|
||||
/* Action Lib Stuff ----------------- */
|
||||
|
||||
/* Allocate a new bAction with the given name */
|
||||
|
@ -13,13 +13,11 @@
|
||||
|
||||
#include "DNA_listBase.h"
|
||||
|
||||
#include "BKE_action.hh"
|
||||
#include "BKE_anim_data.hh"
|
||||
|
||||
#include "BLI_function_ref.hh"
|
||||
|
||||
/* For blender::animrig::slot_handle_t. */
|
||||
#include "ANIM_action.hh"
|
||||
|
||||
struct AnimData;
|
||||
struct ID;
|
||||
struct LibraryForeachIDData;
|
||||
@ -536,13 +534,18 @@ enum eNlaTime_ConvertModes {
|
||||
};
|
||||
|
||||
/**
|
||||
* Non clipped mapping for strip-time <-> global time:
|
||||
* `mode = eNlaTime_ConvertModes -> NLATIME_CONVERT_*`
|
||||
* Non clipped mapping for strip-time <-> global time.
|
||||
*
|
||||
* Public API method - perform this mapping using the given AnimData block
|
||||
* and perform any necessary sanity checks on the value
|
||||
* and perform any necessary sanity checks on the value.
|
||||
*
|
||||
* \note Do not call this with an `adt` obtained from an `bAnimListElem`.
|
||||
* Instead, use `ANIM_nla_tweakedit_remap()` for that. This is because not all
|
||||
* data that might be in an `bAnimListElem` should be nla remapped, and this
|
||||
* function cannot account for that, whereas `ANIM_nla_tweakedit_remap()` takes
|
||||
* the `bAnimListElem` directly and makes sure the right thing is done.
|
||||
*/
|
||||
float BKE_nla_tweakedit_remap(AnimData *adt, float cframe, short mode);
|
||||
float BKE_nla_tweakedit_remap(AnimData *adt, float cframe, eNlaTime_ConvertModes mode);
|
||||
|
||||
/* ----------------------------- */
|
||||
/* .blend file API */
|
||||
|
@ -781,7 +781,7 @@ float nlastrip_get_frame(NlaStrip *strip, float cframe, short mode)
|
||||
}
|
||||
}
|
||||
|
||||
float BKE_nla_tweakedit_remap(AnimData *adt, float cframe, short mode)
|
||||
float BKE_nla_tweakedit_remap(AnimData *adt, const float cframe, const eNlaTime_ConvertModes mode)
|
||||
{
|
||||
NlaStrip *strip;
|
||||
|
||||
|
@ -73,7 +73,6 @@
|
||||
* \{ */
|
||||
|
||||
static bool get_normalized_fcurve_bounds(FCurve *fcu,
|
||||
AnimData *anim_data,
|
||||
SpaceLink *space_link,
|
||||
Scene *scene,
|
||||
ID *id,
|
||||
@ -103,8 +102,6 @@ static bool get_normalized_fcurve_bounds(FCurve *fcu,
|
||||
r_bounds->ymin -= (min_height - height) / 2;
|
||||
r_bounds->ymax += (min_height - height) / 2;
|
||||
}
|
||||
r_bounds->xmin = BKE_nla_tweakedit_remap(anim_data, r_bounds->xmin, NLATIME_CONVERT_MAP);
|
||||
r_bounds->xmax = BKE_nla_tweakedit_remap(anim_data, r_bounds->xmax, NLATIME_CONVERT_MAP);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -188,9 +185,12 @@ static bool get_channel_bounds(bAnimContext *ac,
|
||||
|
||||
case ALE_FCURVE: {
|
||||
FCurve *fcu = (FCurve *)ale->key_data;
|
||||
AnimData *anim_data = ANIM_nla_mapping_get(ac, ale);
|
||||
found_bounds = get_normalized_fcurve_bounds(
|
||||
fcu, anim_data, ac->sl, ac->scene, ale->id, include_handles, range, r_bounds);
|
||||
fcu, ac->sl, ac->scene, ale->id, include_handles, range, r_bounds);
|
||||
if (found_bounds) {
|
||||
r_bounds->xmin = ANIM_nla_tweakedit_remap(ale, r_bounds->xmin, NLATIME_CONVERT_MAP);
|
||||
r_bounds->xmax = ANIM_nla_tweakedit_remap(ale, r_bounds->xmax, NLATIME_CONVERT_MAP);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ALE_NONE:
|
||||
@ -5091,10 +5091,10 @@ static int channels_bake_exec(bContext *C, wmOperator *op)
|
||||
if (!fcu->bezt) {
|
||||
continue;
|
||||
}
|
||||
AnimData *adt = ANIM_nla_mapping_get(&ac, ale);
|
||||
blender::int2 nla_mapped_range;
|
||||
nla_mapped_range[0] = int(BKE_nla_tweakedit_remap(adt, frame_range[0], NLATIME_CONVERT_UNMAP));
|
||||
nla_mapped_range[1] = int(BKE_nla_tweakedit_remap(adt, frame_range[1], NLATIME_CONVERT_UNMAP));
|
||||
blender::int2 nla_mapped_range = {
|
||||
int(ANIM_nla_tweakedit_remap(ale, frame_range[0], NLATIME_CONVERT_UNMAP)),
|
||||
int(ANIM_nla_tweakedit_remap(ale, frame_range[1], NLATIME_CONVERT_UNMAP)),
|
||||
};
|
||||
/* Save current state of modifier flags so they can be reapplied after baking. */
|
||||
blender::Vector<short> modifier_flags;
|
||||
if (!bake_modifiers) {
|
||||
@ -5499,14 +5499,8 @@ static rctf calculate_fcurve_bounds_and_unhide(SpaceLink *space_link,
|
||||
for (FCurve *fcurve : fcurves) {
|
||||
fcurve->flag |= (FCURVE_SELECTED | FCURVE_VISIBLE);
|
||||
rctf fcu_bounds;
|
||||
get_normalized_fcurve_bounds(fcurve,
|
||||
anim_data,
|
||||
space_link,
|
||||
scene,
|
||||
id,
|
||||
include_handles,
|
||||
mapped_frame_range,
|
||||
&fcu_bounds);
|
||||
get_normalized_fcurve_bounds(
|
||||
fcurve, space_link, scene, id, include_handles, mapped_frame_range, &fcu_bounds);
|
||||
|
||||
if (BLI_rctf_is_valid(&fcu_bounds)) {
|
||||
BLI_rctf_union(&bounds, &fcu_bounds);
|
||||
|
@ -207,44 +207,62 @@ void ANIM_draw_action_framerange(
|
||||
/* *************************************************** */
|
||||
/* NLA-MAPPING UTILITIES (required for drawing and also editing keyframes). */
|
||||
|
||||
AnimData *ANIM_nla_mapping_get(bAnimContext *ac, bAnimListElem *ale)
|
||||
bool ANIM_nla_mapping_allowed(const bAnimListElem *ale)
|
||||
{
|
||||
/* sanity checks */
|
||||
if (ac == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
/* Historically, there was another check in the code that this function replaced:
|
||||
* if (!ELEM(ac->datatype,
|
||||
* ANIMCONT_ACTION,
|
||||
* ANIMCONT_SHAPEKEY,
|
||||
* ANIMCONT_DOPESHEET,
|
||||
* ANIMCONT_FCURVES,
|
||||
* ANIMCONT_NLA,
|
||||
* ANIMCONT_CHANNEL,
|
||||
* ANIMCONT_TIMELINE))
|
||||
* {
|
||||
* ... prevent NLA-remapping ...
|
||||
* }
|
||||
*
|
||||
* I (Sybren) suspect that this was actually hiding some animation type check. When that code was
|
||||
* written, I think there was no GreasePencil data showing in the regular Dope Sheet editor.
|
||||
*/
|
||||
|
||||
/* abort if rendering - we may get some race condition issues... */
|
||||
if (G.is_rendering) {
|
||||
return nullptr;
|
||||
switch (ale->type) {
|
||||
case ANIMTYPE_NLACURVE:
|
||||
/* NLA Control Curves occur on NLA strips,
|
||||
* and shouldn't be subjected to this kind of mapping. */
|
||||
return false;
|
||||
case ANIMTYPE_FCURVE: {
|
||||
/* The F-Curve data of a driver should never get NLA-remapped. */
|
||||
FCurve *fcurve = static_cast<FCurve *>(ale->key_data);
|
||||
return !fcurve->driver;
|
||||
}
|
||||
case ANIMTYPE_DSGPENCIL:
|
||||
case ANIMTYPE_GPDATABLOCK:
|
||||
case ANIMTYPE_GPLAYER:
|
||||
case ANIMTYPE_GREASE_PENCIL_DATABLOCK:
|
||||
case ANIMTYPE_GREASE_PENCIL_LAYER_GROUP:
|
||||
case ANIMTYPE_GREASE_PENCIL_LAYER:
|
||||
/* Grease Pencil doesn't use the NLA, so don't bother remapping. */
|
||||
return false;
|
||||
case ANIMTYPE_MASKDATABLOCK:
|
||||
case ANIMTYPE_MASKLAYER:
|
||||
/* I (Sybren) don't _think_ masks can use the NLA. */
|
||||
return false;
|
||||
default:
|
||||
/* NLA time remapping is the default behaviour, and only should be
|
||||
* prohibited for the above types. */
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* apart from strictly keyframe-related contexts, this shouldn't even happen */
|
||||
/* XXX: nla and channel here may not be necessary... */
|
||||
if (!ELEM(ac->datatype,
|
||||
ANIMCONT_ACTION,
|
||||
ANIMCONT_SHAPEKEY,
|
||||
ANIMCONT_DOPESHEET,
|
||||
ANIMCONT_FCURVES,
|
||||
ANIMCONT_NLA,
|
||||
ANIMCONT_CHANNEL,
|
||||
ANIMCONT_TIMELINE))
|
||||
{
|
||||
return nullptr;
|
||||
float ANIM_nla_tweakedit_remap(bAnimListElem *ale,
|
||||
const float cframe,
|
||||
const eNlaTime_ConvertModes mode)
|
||||
{
|
||||
if (!ANIM_nla_mapping_allowed(ale)) {
|
||||
return cframe;
|
||||
}
|
||||
|
||||
/* handling depends on the type of animation-context we've got */
|
||||
if (!ale) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* NLA Control Curves occur on NLA strips,
|
||||
* and shouldn't be subjected to this kind of mapping. */
|
||||
if (ale->type == ANIMTYPE_NLACURVE) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return ale->adt;
|
||||
return BKE_nla_tweakedit_remap(ale->adt, cframe, mode);
|
||||
}
|
||||
|
||||
/* ------------------- */
|
||||
@ -314,6 +332,17 @@ void ANIM_nla_mapping_apply_fcurve(AnimData *adt, FCurve *fcu, bool restore, boo
|
||||
ANIM_fcurve_keyframes_loop(&ked, fcu, nullptr, map_cb, nullptr);
|
||||
}
|
||||
|
||||
void ANIM_nla_mapping_apply_if_needed_fcurve(bAnimListElem *ale,
|
||||
FCurve *fcu,
|
||||
const bool restore,
|
||||
const bool only_keys)
|
||||
{
|
||||
if (!ANIM_nla_mapping_allowed(ale)) {
|
||||
return;
|
||||
}
|
||||
ANIM_nla_mapping_apply_fcurve(ale->adt, fcu, restore, only_keys);
|
||||
}
|
||||
|
||||
/* *************************************************** */
|
||||
/* UNITS CONVERSION MAPPING (required for drawing and editing keyframes) */
|
||||
|
||||
|
@ -321,7 +321,7 @@ static void motionpath_calculate_update_range(MPathTarget *mpt,
|
||||
* we ignore all others (which can potentially make an update range unnecessary wide). */
|
||||
for (FCurve *fcu = static_cast<FCurve *>(fcurve_list->first); fcu != nullptr; fcu = fcu->next) {
|
||||
AnimKeylist *keylist = ED_keylist_create();
|
||||
fcurve_to_keylist(adt, fcu, keylist, 0, {-FLT_MAX, FLT_MAX});
|
||||
fcurve_to_keylist(adt, fcu, keylist, 0, {-FLT_MAX, FLT_MAX}, true);
|
||||
ED_keylist_prepare_for_direct_access(keylist);
|
||||
|
||||
int fcu_sfra = motionpath_get_prev_prev_keyframe(mpt, keylist, current_frame);
|
||||
@ -371,7 +371,7 @@ void animviz_motionpath_compute_range(Object *ob, Scene *scene)
|
||||
|
||||
AnimKeylist *keylist = ED_keylist_create();
|
||||
for (FCurve *fcu : blender::animrig::legacy::fcurves_for_assigned_action(ob->adt)) {
|
||||
fcurve_to_keylist(ob->adt, fcu, keylist, 0, {-FLT_MAX, FLT_MAX});
|
||||
fcurve_to_keylist(ob->adt, fcu, keylist, 0, {-FLT_MAX, FLT_MAX}, true);
|
||||
}
|
||||
|
||||
Range2f frame_range;
|
||||
|
@ -410,6 +410,11 @@ struct ChannelListElement {
|
||||
eSAction_Flag saction_flag;
|
||||
bool channel_locked;
|
||||
|
||||
/* Currently only used for F-Curve channels, because some should be nla
|
||||
* remapped but not others. All other channel types ignore this, as it's clear
|
||||
* from the type whether they should be nla remapped or not. */
|
||||
bool use_nla_remapping;
|
||||
|
||||
/* TODO: check which of these can be put into a `union`: */
|
||||
bAnimContext *ac;
|
||||
bDopeSheet *ads;
|
||||
@ -443,7 +448,8 @@ static void build_channel_keylist(ChannelListElement *elem, blender::float2 rang
|
||||
break;
|
||||
}
|
||||
case ChannelType::FCURVE: {
|
||||
fcurve_to_keylist(elem->adt, elem->fcu, elem->keylist, elem->saction_flag, range);
|
||||
fcurve_to_keylist(
|
||||
elem->adt, elem->fcu, elem->keylist, elem->saction_flag, range, elem->use_nla_remapping);
|
||||
break;
|
||||
}
|
||||
case ChannelType::ACTION_LAYERED: {
|
||||
@ -696,7 +702,7 @@ void ED_add_object_channel(ChannelDrawList *channel_list,
|
||||
}
|
||||
|
||||
void ED_add_fcurve_channel(ChannelDrawList *channel_list,
|
||||
AnimData *adt,
|
||||
bAnimListElem *ale,
|
||||
FCurve *fcu,
|
||||
float ypos,
|
||||
float yscale_fac,
|
||||
@ -704,36 +710,38 @@ void ED_add_fcurve_channel(ChannelDrawList *channel_list,
|
||||
{
|
||||
const bool locked = (fcu->flag & FCURVE_PROTECTED) ||
|
||||
((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) ||
|
||||
((adt && adt->action) &&
|
||||
(!ID_IS_EDITABLE(adt->action) || ID_IS_OVERRIDE_LIBRARY(adt->action)));
|
||||
((ale->adt && ale->adt->action) &&
|
||||
(!ID_IS_EDITABLE(ale->adt->action) ||
|
||||
ID_IS_OVERRIDE_LIBRARY(ale->adt->action)));
|
||||
|
||||
ChannelListElement *draw_elem = channel_list_add_element(
|
||||
channel_list, ChannelType::FCURVE, ypos, yscale_fac, eSAction_Flag(saction_flag));
|
||||
draw_elem->adt = adt;
|
||||
draw_elem->adt = ale->adt;
|
||||
draw_elem->fcu = fcu;
|
||||
draw_elem->channel_locked = locked;
|
||||
draw_elem->use_nla_remapping = ANIM_nla_mapping_allowed(ale);
|
||||
}
|
||||
|
||||
void ED_add_action_group_channel(ChannelDrawList *channel_list,
|
||||
AnimData *adt,
|
||||
bAnimListElem *ale,
|
||||
bActionGroup *agrp,
|
||||
float ypos,
|
||||
float yscale_fac,
|
||||
int saction_flag)
|
||||
{
|
||||
bool locked = (agrp->flag & AGRP_PROTECTED) ||
|
||||
((adt && adt->action) &&
|
||||
(!ID_IS_EDITABLE(adt->action) || ID_IS_OVERRIDE_LIBRARY(adt->action)));
|
||||
((ale->adt && ale->adt->action) &&
|
||||
(!ID_IS_EDITABLE(ale->adt->action) || ID_IS_OVERRIDE_LIBRARY(ale->adt->action)));
|
||||
|
||||
ChannelListElement *draw_elem = channel_list_add_element(
|
||||
channel_list, ChannelType::ACTION_GROUP, ypos, yscale_fac, eSAction_Flag(saction_flag));
|
||||
draw_elem->adt = adt;
|
||||
draw_elem->adt = ale->adt;
|
||||
draw_elem->agrp = agrp;
|
||||
draw_elem->channel_locked = locked;
|
||||
}
|
||||
|
||||
void ED_add_action_layered_channel(ChannelDrawList *channel_list,
|
||||
AnimData *adt,
|
||||
bAnimListElem *ale,
|
||||
bAction *action,
|
||||
const float ypos,
|
||||
const float yscale_fac,
|
||||
@ -747,13 +755,13 @@ void ED_add_action_layered_channel(ChannelDrawList *channel_list,
|
||||
|
||||
ChannelListElement *draw_elem = channel_list_add_element(
|
||||
channel_list, ChannelType::ACTION_LAYERED, ypos, yscale_fac, eSAction_Flag(saction_flag));
|
||||
draw_elem->adt = adt;
|
||||
draw_elem->adt = ale->adt;
|
||||
draw_elem->act = action;
|
||||
draw_elem->channel_locked = locked;
|
||||
}
|
||||
|
||||
void ED_add_action_slot_channel(ChannelDrawList *channel_list,
|
||||
AnimData *adt,
|
||||
bAnimListElem *ale,
|
||||
animrig::Action &action,
|
||||
animrig::Slot &slot,
|
||||
const float ypos,
|
||||
@ -765,14 +773,14 @@ void ED_add_action_slot_channel(ChannelDrawList *channel_list,
|
||||
|
||||
ChannelListElement *draw_elem = channel_list_add_element(
|
||||
channel_list, ChannelType::ACTION_SLOT, ypos, yscale_fac, eSAction_Flag(saction_flag));
|
||||
draw_elem->adt = adt;
|
||||
draw_elem->adt = ale->adt;
|
||||
draw_elem->act = &action;
|
||||
draw_elem->action_slot = &slot;
|
||||
draw_elem->channel_locked = locked;
|
||||
}
|
||||
|
||||
void ED_add_action_channel(ChannelDrawList *channel_list,
|
||||
AnimData *adt,
|
||||
bAnimListElem *ale,
|
||||
bAction *act,
|
||||
float ypos,
|
||||
float yscale_fac,
|
||||
@ -785,14 +793,14 @@ void ED_add_action_channel(ChannelDrawList *channel_list,
|
||||
|
||||
ChannelListElement *draw_elem = channel_list_add_element(
|
||||
channel_list, ChannelType::ACTION_LEGACY, ypos, yscale_fac, eSAction_Flag(saction_flag));
|
||||
draw_elem->adt = adt;
|
||||
draw_elem->adt = ale->adt;
|
||||
draw_elem->act = act;
|
||||
draw_elem->channel_locked = locked;
|
||||
}
|
||||
|
||||
void ED_add_grease_pencil_datablock_channel(ChannelDrawList *channel_list,
|
||||
bAnimContext *ac,
|
||||
AnimData *adt,
|
||||
bAnimListElem *ale,
|
||||
const GreasePencil *grease_pencil,
|
||||
const float ypos,
|
||||
const float yscale_fac,
|
||||
@ -805,8 +813,8 @@ void ED_add_grease_pencil_datablock_channel(ChannelDrawList *channel_list,
|
||||
eSAction_Flag(saction_flag));
|
||||
/* GreasePencil properties can be animated via an Action, so the GP-related
|
||||
* animation data is not limited to GP drawings. */
|
||||
draw_elem->adt = adt;
|
||||
draw_elem->act = adt ? adt->action : nullptr;
|
||||
draw_elem->adt = ale->adt;
|
||||
draw_elem->act = ale->adt ? ale->adt->action : nullptr;
|
||||
draw_elem->grease_pencil = grease_pencil;
|
||||
draw_elem->ac = ac;
|
||||
}
|
||||
|
@ -361,15 +361,11 @@ static short summary_keyframes_loop(KeyframeEditData *ked,
|
||||
float f1 = ked->f1;
|
||||
float f2 = ked->f2;
|
||||
|
||||
if (ked->iterflags & (KED_F1_NLA_UNMAP | KED_F2_NLA_UNMAP)) {
|
||||
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
|
||||
|
||||
if (ked->iterflags & KED_F1_NLA_UNMAP) {
|
||||
ked->f1 = BKE_nla_tweakedit_remap(adt, f1, NLATIME_CONVERT_UNMAP);
|
||||
}
|
||||
if (ked->iterflags & KED_F2_NLA_UNMAP) {
|
||||
ked->f2 = BKE_nla_tweakedit_remap(adt, f2, NLATIME_CONVERT_UNMAP);
|
||||
}
|
||||
if (ked->iterflags & KED_F1_NLA_UNMAP) {
|
||||
ked->f1 = ANIM_nla_tweakedit_remap(ale, f1, NLATIME_CONVERT_UNMAP);
|
||||
}
|
||||
if (ked->iterflags & KED_F2_NLA_UNMAP) {
|
||||
ked->f2 = ANIM_nla_tweakedit_remap(ale, f2, NLATIME_CONVERT_UNMAP);
|
||||
}
|
||||
|
||||
/* now operate on the channel as per normal */
|
||||
|
@ -1829,7 +1829,6 @@ eKeyPasteError paste_animedit_keys(bAnimContext *ac,
|
||||
* (group check is not that important).
|
||||
* - Most importantly, rna-paths should match (array indices are unimportant for now)
|
||||
*/
|
||||
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
|
||||
FCurve *fcu = (FCurve *)ale->data; /* destination F-Curve */
|
||||
tAnimCopybufItem *aci = nullptr;
|
||||
|
||||
@ -1855,14 +1854,12 @@ eKeyPasteError paste_animedit_keys(bAnimContext *ac,
|
||||
totmatch++;
|
||||
|
||||
offset[1] = paste_get_y_offset(ac, aci, ale, value_offset_mode);
|
||||
if (adt) {
|
||||
ANIM_nla_mapping_apply_fcurve(adt, static_cast<FCurve *>(ale->key_data), false, false);
|
||||
paste_animedit_keys_fcurve(fcu, aci, offset, merge_mode, flip);
|
||||
ANIM_nla_mapping_apply_fcurve(adt, static_cast<FCurve *>(ale->key_data), true, false);
|
||||
}
|
||||
else {
|
||||
paste_animedit_keys_fcurve(fcu, aci, offset, merge_mode, flip);
|
||||
}
|
||||
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(
|
||||
ale, static_cast<FCurve *>(ale->key_data), false, false);
|
||||
paste_animedit_keys_fcurve(fcu, aci, offset, merge_mode, flip);
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(
|
||||
ale, static_cast<FCurve *>(ale->key_data), true, false);
|
||||
}
|
||||
|
||||
ale->update |= ANIM_UPDATE_DEFAULT;
|
||||
|
@ -956,8 +956,12 @@ void summary_to_keylist(bAnimContext *ac,
|
||||
* there isn't really any benefit at all from including them. - Aligorith */
|
||||
switch (ale->datatype) {
|
||||
case ALE_FCURVE:
|
||||
fcurve_to_keylist(
|
||||
ale->adt, static_cast<FCurve *>(ale->data), keylist, saction_flag, range);
|
||||
fcurve_to_keylist(ale->adt,
|
||||
static_cast<FCurve *>(ale->data),
|
||||
keylist,
|
||||
saction_flag,
|
||||
range,
|
||||
ANIM_nla_mapping_allowed(ale));
|
||||
break;
|
||||
case ALE_MASKLAY:
|
||||
mask_to_keylist(ac->ads, static_cast<MaskLayer *>(ale->data), keylist);
|
||||
@ -1010,7 +1014,12 @@ void scene_to_keylist(bDopeSheet *ads,
|
||||
|
||||
/* Loop through each F-Curve, grabbing the keyframes. */
|
||||
LISTBASE_FOREACH (const bAnimListElem *, ale, &anim_data) {
|
||||
fcurve_to_keylist(ale->adt, static_cast<FCurve *>(ale->data), keylist, saction_flag, range);
|
||||
fcurve_to_keylist(ale->adt,
|
||||
static_cast<FCurve *>(ale->data),
|
||||
keylist,
|
||||
saction_flag,
|
||||
range,
|
||||
ANIM_nla_mapping_allowed(ale));
|
||||
}
|
||||
|
||||
ANIM_animdata_freelist(&anim_data);
|
||||
@ -1051,7 +1060,12 @@ void ob_to_keylist(bDopeSheet *ads,
|
||||
|
||||
/* Loop through each F-Curve, grabbing the keyframes. */
|
||||
LISTBASE_FOREACH (const bAnimListElem *, ale, &anim_data) {
|
||||
fcurve_to_keylist(ale->adt, static_cast<FCurve *>(ale->data), keylist, saction_flag, range);
|
||||
fcurve_to_keylist(ale->adt,
|
||||
static_cast<FCurve *>(ale->data),
|
||||
keylist,
|
||||
saction_flag,
|
||||
range,
|
||||
ANIM_nla_mapping_allowed(ale));
|
||||
}
|
||||
|
||||
ANIM_animdata_freelist(&anim_data);
|
||||
@ -1086,8 +1100,12 @@ void cachefile_to_keylist(bDopeSheet *ads,
|
||||
|
||||
/* Loop through each F-Curve, grabbing the keyframes. */
|
||||
LISTBASE_FOREACH (const bAnimListElem *, ale, &anim_data) {
|
||||
fcurve_to_keylist(
|
||||
ale->adt, static_cast<FCurve *>(ale->data), keylist, saction_flag, {-FLT_MAX, FLT_MAX});
|
||||
fcurve_to_keylist(ale->adt,
|
||||
static_cast<FCurve *>(ale->data),
|
||||
keylist,
|
||||
saction_flag,
|
||||
{-FLT_MAX, FLT_MAX},
|
||||
ANIM_nla_mapping_allowed(ale));
|
||||
}
|
||||
|
||||
ANIM_animdata_freelist(&anim_data);
|
||||
@ -1116,14 +1134,22 @@ void fcurve_to_keylist(AnimData *adt,
|
||||
FCurve *fcu,
|
||||
AnimKeylist *keylist,
|
||||
const int saction_flag,
|
||||
blender::float2 range)
|
||||
blender::float2 range,
|
||||
const bool use_nla_remapping)
|
||||
{
|
||||
/* This is not strictly necessary because `ANIM_nla_mapping_apply_fcurve()`
|
||||
* will just not do remapping if `adt` is null. Nevertheless, saying that you
|
||||
* want NLA remapping to be performed while not passing an `adt` (needed for
|
||||
* NLA remapping) almost certainly indicates a mistake somewhere. */
|
||||
BLI_assert_msg(!(use_nla_remapping && adt == nullptr),
|
||||
"Cannot perform NLA time remapping without an adt.");
|
||||
|
||||
if (!fcu || fcu->totvert == 0 || !fcu->bezt) {
|
||||
return;
|
||||
}
|
||||
ED_keylist_reset_last_accessed(keylist);
|
||||
|
||||
if (adt) {
|
||||
if (use_nla_remapping) {
|
||||
ANIM_nla_mapping_apply_fcurve(adt, fcu, false, false);
|
||||
}
|
||||
|
||||
@ -1183,7 +1209,7 @@ void fcurve_to_keylist(AnimData *adt,
|
||||
keylist, &fcu->bezt[index_bounds.min], (index_bounds.max + 1) - index_bounds.min);
|
||||
}
|
||||
|
||||
if (adt) {
|
||||
if (use_nla_remapping) {
|
||||
ANIM_nla_mapping_apply_fcurve(adt, fcu, true, false);
|
||||
}
|
||||
}
|
||||
@ -1204,7 +1230,7 @@ void action_group_to_keylist(AnimData *adt,
|
||||
if (fcu->grp != agrp) {
|
||||
break;
|
||||
}
|
||||
fcurve_to_keylist(adt, fcu, keylist, saction_flag, range);
|
||||
fcurve_to_keylist(adt, fcu, keylist, saction_flag, range, true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -1214,7 +1240,7 @@ void action_group_to_keylist(AnimData *adt,
|
||||
Span<FCurve *> fcurves = channel_bag.fcurves().slice(agrp->fcurve_range_start,
|
||||
agrp->fcurve_range_length);
|
||||
for (FCurve *fcurve : fcurves) {
|
||||
fcurve_to_keylist(adt, fcurve, keylist, saction_flag, range);
|
||||
fcurve_to_keylist(adt, fcurve, keylist, saction_flag, range, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1227,7 +1253,7 @@ void action_slot_to_keylist(AnimData *adt,
|
||||
{
|
||||
BLI_assert(GS(action.id.name) == ID_AC);
|
||||
for (FCurve *fcurve : fcurves_for_action_slot(action, slot_handle)) {
|
||||
fcurve_to_keylist(adt, fcurve, keylist, saction_flag, range);
|
||||
fcurve_to_keylist(adt, fcurve, keylist, saction_flag, range, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1246,7 +1272,7 @@ void action_to_keylist(AnimData *adt,
|
||||
/* TODO: move this into fcurves_for_action_slot(). */
|
||||
if (action.is_action_legacy()) {
|
||||
LISTBASE_FOREACH (FCurve *, fcu, &action.curves) {
|
||||
fcurve_to_keylist(adt, fcu, keylist, saction_flag, range);
|
||||
fcurve_to_keylist(adt, fcu, keylist, saction_flag, range, true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -1255,6 +1281,7 @@ void action_to_keylist(AnimData *adt,
|
||||
* Assumption: the animation is bound to adt->slot_handle. This assumption will break when we
|
||||
* have things like reference strips, where the strip can reference another slot handle.
|
||||
*/
|
||||
BLI_assert(adt);
|
||||
action_slot_to_keylist(adt, action, adt->slot_handle, keylist, saction_flag, range);
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ static AnimKeylist *create_test_keylist()
|
||||
build_fcurve(*fcurve);
|
||||
|
||||
AnimKeylist *keylist = ED_keylist_create();
|
||||
fcurve_to_keylist(nullptr, fcurve, keylist, 0, {-FLT_MAX, FLT_MAX});
|
||||
fcurve_to_keylist(nullptr, fcurve, keylist, 0, {-FLT_MAX, FLT_MAX}, false);
|
||||
BKE_fcurve_free(fcurve);
|
||||
|
||||
ED_keylist_prepare_for_direct_access(keylist);
|
||||
|
@ -990,8 +990,9 @@ static int pose_slide_invoke_common(bContext *C, wmOperator *op, const wmEvent *
|
||||
LISTBASE_FOREACH (tPChanFCurveLink *, pfl, &pso->pfLinks) {
|
||||
/* Do this for each F-Curve. */
|
||||
LISTBASE_FOREACH (LinkData *, ld, &pfl->fcurves) {
|
||||
AnimData *adt = pfl->ob->adt;
|
||||
FCurve *fcu = (FCurve *)ld->data;
|
||||
fcurve_to_keylist(pfl->ob->adt, fcu, pso->keylist, 0, {-FLT_MAX, FLT_MAX});
|
||||
fcurve_to_keylist(adt, fcu, pso->keylist, 0, {-FLT_MAX, FLT_MAX}, adt != nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1783,7 +1784,7 @@ static void get_keyed_frames_in_range(ListBase *pflinks,
|
||||
LISTBASE_FOREACH (tPChanFCurveLink *, pfl, pflinks) {
|
||||
LISTBASE_FOREACH (LinkData *, ld, &pfl->fcurves) {
|
||||
FCurve *fcu = (FCurve *)ld->data;
|
||||
fcurve_to_keylist(nullptr, fcu, keylist, 0, {start_frame, end_frame});
|
||||
fcurve_to_keylist(nullptr, fcu, keylist, 0, {start_frame, end_frame}, false);
|
||||
}
|
||||
}
|
||||
LISTBASE_FOREACH (ActKeyColumn *, column, ED_keylist_listbase(keylist)) {
|
||||
@ -1806,7 +1807,7 @@ static void get_selected_frames(ListBase *pflinks, ListBase /*FrameLink*/ *targe
|
||||
LISTBASE_FOREACH (tPChanFCurveLink *, pfl, pflinks) {
|
||||
LISTBASE_FOREACH (LinkData *, ld, &pfl->fcurves) {
|
||||
FCurve *fcu = (FCurve *)ld->data;
|
||||
fcurve_to_keylist(nullptr, fcu, keylist, 0, {-FLT_MAX, FLT_MAX});
|
||||
fcurve_to_keylist(nullptr, fcu, keylist, 0, {-FLT_MAX, FLT_MAX}, false);
|
||||
}
|
||||
}
|
||||
LISTBASE_FOREACH (ActKeyColumn *, column, ED_keylist_listbase(keylist)) {
|
||||
|
@ -8,6 +8,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BKE_nla.hh"
|
||||
|
||||
#include "BLI_sys_types.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
@ -963,19 +965,41 @@ void nla_action_get_color(AnimData *adt, bAction *act, float color[4]);
|
||||
/* `anim_draw.cc` */
|
||||
|
||||
/**
|
||||
* Obtain the AnimData block providing NLA-mapping for the given channel (if applicable).
|
||||
* Check whether NLA time remapping should be done on this bAnimListElem.
|
||||
*
|
||||
* TODO: do not supply return this if the animdata tells us that there is no mapping to perform.
|
||||
* \returns true by default, false only when this ale indicates an NLA control curve (like animated
|
||||
* influence) or a driver.
|
||||
*/
|
||||
AnimData *ANIM_nla_mapping_get(bAnimContext *ac, bAnimListElem *ale);
|
||||
bool ANIM_nla_mapping_allowed(const bAnimListElem *ale);
|
||||
|
||||
/**
|
||||
* Do NLA time remapping, but only if `ANIM_nla_mapping_allowed(ale)` returns `true`.
|
||||
*
|
||||
* \see #ANIM_nla_mapping_allowed
|
||||
* \see #BKE_nla_tweakedit_remap
|
||||
*/
|
||||
float ANIM_nla_tweakedit_remap(bAnimListElem *ale, float cframe, eNlaTime_ConvertModes mode);
|
||||
|
||||
/**
|
||||
* Apply/Unapply NLA mapping to all keyframes in the nominated F-Curve
|
||||
* \param restore: Whether to map points back to non-mapped time.
|
||||
* \param only_keys: Whether to only adjust the location of the center point of beztriples.
|
||||
*
|
||||
* TODO: this is only used by `fcurve_to_keylist()` at this point. Perhaps with
|
||||
* some refactoring we can make `fcurve_to_keylist()` use
|
||||
* `ANIM_nla_mapping_apply_if_needed_fcurve()` instead, and then we can get rid
|
||||
* of this.
|
||||
*/
|
||||
void ANIM_nla_mapping_apply_fcurve(AnimData *adt, FCurve *fcu, bool restore, bool only_keys);
|
||||
|
||||
/**
|
||||
* Same as above, but only if `ANIM_nla_mapping_allowed(ale)` returns `true`.
|
||||
*/
|
||||
void ANIM_nla_mapping_apply_if_needed_fcurve(bAnimListElem *ale,
|
||||
FCurve *fcu,
|
||||
bool restore,
|
||||
bool only_keys);
|
||||
|
||||
/* ..... */
|
||||
|
||||
/**
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include "DNA_curve_types.h"
|
||||
|
||||
#include "ED_anim_api.hh"
|
||||
#include "ED_keyframes_keylist.hh"
|
||||
|
||||
struct AnimData;
|
||||
@ -60,28 +61,28 @@ void draw_keyframe_shape(float x,
|
||||
/* Channel Drawing ------------------ */
|
||||
/* F-Curve */
|
||||
void ED_add_fcurve_channel(ChannelDrawList *draw_list,
|
||||
AnimData *adt,
|
||||
bAnimListElem *ale,
|
||||
FCurve *fcu,
|
||||
float ypos,
|
||||
float yscale_fac,
|
||||
int saction_flag);
|
||||
/* Action Group Summary */
|
||||
void ED_add_action_group_channel(ChannelDrawList *draw_list,
|
||||
AnimData *adt,
|
||||
bAnimListElem *ale,
|
||||
bActionGroup *agrp,
|
||||
float ypos,
|
||||
float yscale_fac,
|
||||
int saction_flag);
|
||||
/* Layered Action Summary.*/
|
||||
void ED_add_action_layered_channel(ChannelDrawList *channel_list,
|
||||
AnimData *adt,
|
||||
bAnimListElem *ale,
|
||||
bAction *action,
|
||||
const float ypos,
|
||||
const float yscale_fac,
|
||||
int saction_flag);
|
||||
/* Action Slot summary. */
|
||||
void ED_add_action_slot_channel(ChannelDrawList *channel_list,
|
||||
AnimData *adt,
|
||||
bAnimListElem *ale,
|
||||
blender::animrig::Action &action,
|
||||
blender::animrig::Slot &slot,
|
||||
float ypos,
|
||||
@ -89,7 +90,7 @@ void ED_add_action_slot_channel(ChannelDrawList *channel_list,
|
||||
int saction_flag);
|
||||
/* Legacy Action Summary */
|
||||
void ED_add_action_channel(ChannelDrawList *draw_list,
|
||||
AnimData *adt,
|
||||
bAnimListElem *ale,
|
||||
bAction *act,
|
||||
float ypos,
|
||||
float yscale_fac,
|
||||
@ -131,7 +132,7 @@ void ED_add_grease_pencil_layer_group_channel(ChannelDrawList *draw_list,
|
||||
/* Grease Pencil data channels */
|
||||
void ED_add_grease_pencil_datablock_channel(ChannelDrawList *draw_list,
|
||||
bAnimContext *ac,
|
||||
AnimData *adt,
|
||||
bAnimListElem *ale,
|
||||
const GreasePencil *grease_pencil,
|
||||
const float ypos,
|
||||
const float yscale_fac,
|
||||
|
@ -155,12 +155,22 @@ int64_t ED_keylist_array_len(const AnimKeylist *keylist);
|
||||
|
||||
/**
|
||||
* Add the keyframes of the F-Curve to the keylist.
|
||||
* \param adt: can be a nullptr.
|
||||
* \param range: adds keys in the given range to the keylist plus 1 extra on each side if
|
||||
* available.
|
||||
*
|
||||
* \param adt: the AnimData associated with the FCurve, if any. Must be
|
||||
* non-null if `use_nla_remapping` is true, because it's needed for that
|
||||
* remapping.
|
||||
* \param range: adds keys in the given range to the keylist plus 1 extra on
|
||||
* each side if available.
|
||||
* \param use_nla_remapping: whether to allow NLA remapping or not. `true` by
|
||||
* default, basically only `false` when this F-Curve is an NLA control curve
|
||||
* (like animated influence) or a driver.
|
||||
*/
|
||||
void fcurve_to_keylist(
|
||||
AnimData *adt, FCurve *fcu, AnimKeylist *keylist, int saction_flag, blender::float2 range);
|
||||
void fcurve_to_keylist(AnimData *adt,
|
||||
FCurve *fcu,
|
||||
AnimKeylist *keylist,
|
||||
int saction_flag,
|
||||
blender::float2 range,
|
||||
bool use_nla_remapping);
|
||||
/* Action Group */
|
||||
void action_group_to_keylist(AnimData *adt,
|
||||
bActionGroup *agrp,
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
#include "ED_keyframing.hh"
|
||||
|
||||
#include "ANIM_fcurve.hh"
|
||||
#include "ANIM_keyframing.hh"
|
||||
|
||||
#include "UI_interface.hh"
|
||||
|
@ -348,8 +348,6 @@ static void draw_keyframes(bAnimContext *ac,
|
||||
continue;
|
||||
}
|
||||
|
||||
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
|
||||
|
||||
/* Add channels to list to draw later. */
|
||||
switch (ale->datatype) {
|
||||
case ALE_ALL:
|
||||
@ -374,7 +372,7 @@ static void draw_keyframes(bAnimContext *ac,
|
||||
break;
|
||||
case ALE_ACTION_LAYERED:
|
||||
ED_add_action_layered_channel(draw_list,
|
||||
adt,
|
||||
ale,
|
||||
static_cast<bAction *>(ale->key_data),
|
||||
ycenter,
|
||||
scale_factor,
|
||||
@ -382,7 +380,7 @@ static void draw_keyframes(bAnimContext *ac,
|
||||
break;
|
||||
case ALE_ACTION_SLOT:
|
||||
ED_add_action_slot_channel(draw_list,
|
||||
adt,
|
||||
ale,
|
||||
static_cast<bAction *>(ale->key_data)->wrap(),
|
||||
*static_cast<animrig::Slot *>(ale->data),
|
||||
ycenter,
|
||||
@ -391,7 +389,7 @@ static void draw_keyframes(bAnimContext *ac,
|
||||
break;
|
||||
case ALE_ACT:
|
||||
ED_add_action_channel(draw_list,
|
||||
adt,
|
||||
ale,
|
||||
static_cast<bAction *>(ale->key_data),
|
||||
ycenter,
|
||||
scale_factor,
|
||||
@ -399,20 +397,21 @@ static void draw_keyframes(bAnimContext *ac,
|
||||
break;
|
||||
case ALE_GROUP:
|
||||
ED_add_action_group_channel(draw_list,
|
||||
adt,
|
||||
ale,
|
||||
static_cast<bActionGroup *>(ale->data),
|
||||
ycenter,
|
||||
scale_factor,
|
||||
action_flag);
|
||||
break;
|
||||
case ALE_FCURVE:
|
||||
case ALE_FCURVE: {
|
||||
ED_add_fcurve_channel(draw_list,
|
||||
adt,
|
||||
ale,
|
||||
static_cast<FCurve *>(ale->key_data),
|
||||
ycenter,
|
||||
scale_factor,
|
||||
action_flag);
|
||||
break;
|
||||
}
|
||||
case ALE_GREASE_PENCIL_CEL:
|
||||
ED_add_grease_pencil_cels_channel(draw_list,
|
||||
ads,
|
||||
@ -433,7 +432,7 @@ static void draw_keyframes(bAnimContext *ac,
|
||||
case ALE_GREASE_PENCIL_DATA:
|
||||
ED_add_grease_pencil_datablock_channel(draw_list,
|
||||
ac,
|
||||
ale->adt,
|
||||
ale,
|
||||
static_cast<const GreasePencil *>(ale->data),
|
||||
ycenter,
|
||||
scale_factor,
|
||||
|
@ -173,7 +173,6 @@ static bool get_keyframe_extents(bAnimContext *ac, float *min, float *max, const
|
||||
if (anim_data.first) {
|
||||
/* go through channels, finding max extents */
|
||||
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
|
||||
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
|
||||
if (ale->datatype == ALE_GPFRAME) {
|
||||
bGPDlayer *gpl = static_cast<bGPDlayer *>(ale->data);
|
||||
|
||||
@ -216,11 +215,8 @@ static bool get_keyframe_extents(bAnimContext *ac, float *min, float *max, const
|
||||
|
||||
/* get range and apply necessary scaling before processing */
|
||||
if (BKE_fcurve_calc_range(fcu, &tmin, &tmax, onlySel)) {
|
||||
|
||||
if (adt) {
|
||||
tmin = BKE_nla_tweakedit_remap(adt, tmin, NLATIME_CONVERT_MAP);
|
||||
tmax = BKE_nla_tweakedit_remap(adt, tmax, NLATIME_CONVERT_MAP);
|
||||
}
|
||||
tmin = ANIM_nla_tweakedit_remap(ale, tmin, NLATIME_CONVERT_MAP);
|
||||
tmax = ANIM_nla_tweakedit_remap(ale, tmax, NLATIME_CONVERT_MAP);
|
||||
|
||||
/* Try to set cur using these values,
|
||||
* if they're more extreme than previously set values. */
|
||||
@ -876,13 +872,9 @@ static void insert_fcurve_key(bAnimContext *ac,
|
||||
* mapping will need to be handled here. */
|
||||
assert_baklava_phase_1_invariants(action->wrap());
|
||||
|
||||
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
|
||||
|
||||
/* adjust current frame for NLA-scaling */
|
||||
float cfra = anim_eval_context.eval_time;
|
||||
if (adt) {
|
||||
cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
|
||||
}
|
||||
/* Adjust current frame for NLA-scaling. */
|
||||
const float cfra = ANIM_nla_tweakedit_remap(
|
||||
ale, anim_eval_context.eval_time, NLATIME_CONVERT_UNMAP);
|
||||
|
||||
const float curval = evaluate_fcurve(fcu, cfra);
|
||||
KeyframeSettings settings = get_keyframe_settings(true);
|
||||
@ -1858,16 +1850,10 @@ static int actkeys_framejump_exec(bContext *C, wmOperator * /*op*/)
|
||||
}
|
||||
|
||||
case ALE_FCURVE: {
|
||||
AnimData *adt = ANIM_nla_mapping_get(&ac, ale);
|
||||
FCurve *fcurve = static_cast<FCurve *>(ale->key_data);
|
||||
if (adt) {
|
||||
ANIM_nla_mapping_apply_fcurve(adt, fcurve, false, true);
|
||||
ANIM_fcurve_keyframes_loop(&ked, fcurve, nullptr, bezt_calc_average, nullptr);
|
||||
ANIM_nla_mapping_apply_fcurve(adt, fcurve, true, true);
|
||||
}
|
||||
else {
|
||||
ANIM_fcurve_keyframes_loop(&ked, fcurve, nullptr, bezt_calc_average, nullptr);
|
||||
}
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(ale, fcurve, false, true);
|
||||
ANIM_fcurve_keyframes_loop(&ked, fcurve, nullptr, bezt_calc_average, nullptr);
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(ale, fcurve, true, true);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1968,8 +1954,6 @@ static void snap_action_keys(bAnimContext *ac, short mode)
|
||||
|
||||
/* snap keyframes */
|
||||
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
|
||||
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
|
||||
|
||||
if (ale->type == ANIMTYPE_GPLAYER) {
|
||||
ED_gpencil_layer_snap_frames(static_cast<bGPDlayer *>(ale->data), ac->scene, mode);
|
||||
}
|
||||
@ -1987,19 +1971,13 @@ static void snap_action_keys(bAnimContext *ac, short mode)
|
||||
else if (ale->type == ANIMTYPE_MASKLAYER) {
|
||||
ED_masklayer_snap_frames(static_cast<MaskLayer *>(ale->data), ac->scene, mode);
|
||||
}
|
||||
else if (adt) {
|
||||
FCurve *fcurve = static_cast<FCurve *>(ale->key_data);
|
||||
ANIM_nla_mapping_apply_fcurve(adt, fcurve, false, false);
|
||||
ANIM_fcurve_keyframes_loop(&ked, fcurve, nullptr, edit_cb, BKE_fcurve_handles_recalc);
|
||||
BKE_fcurve_merge_duplicate_keys(
|
||||
fcurve, SELECT, false); /* only use handles in graph editor */
|
||||
ANIM_nla_mapping_apply_fcurve(adt, fcurve, true, false);
|
||||
}
|
||||
else {
|
||||
FCurve *fcurve = static_cast<FCurve *>(ale->key_data);
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(ale, fcurve, false, false);
|
||||
ANIM_fcurve_keyframes_loop(&ked, fcurve, nullptr, edit_cb, BKE_fcurve_handles_recalc);
|
||||
BKE_fcurve_merge_duplicate_keys(
|
||||
fcurve, SELECT, false); /* only use handles in graph editor */
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(ale, fcurve, true, false);
|
||||
}
|
||||
|
||||
ale->update |= ANIM_UPDATE_DEFAULT;
|
||||
@ -2112,8 +2090,6 @@ static void mirror_action_keys(bAnimContext *ac, short mode)
|
||||
|
||||
/* mirror keyframes */
|
||||
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
|
||||
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
|
||||
|
||||
if (ale->type == ANIMTYPE_GPLAYER) {
|
||||
ED_gpencil_layer_mirror_frames(static_cast<bGPDlayer *>(ale->data), ac->scene, mode);
|
||||
}
|
||||
@ -2131,15 +2107,11 @@ static void mirror_action_keys(bAnimContext *ac, short mode)
|
||||
else if (ale->type == ANIMTYPE_MASKLAYER) {
|
||||
/* TODO */
|
||||
}
|
||||
else if (adt) {
|
||||
FCurve *fcurve = static_cast<FCurve *>(ale->key_data);
|
||||
ANIM_nla_mapping_apply_fcurve(adt, fcurve, false, false);
|
||||
ANIM_fcurve_keyframes_loop(&ked, fcurve, nullptr, edit_cb, BKE_fcurve_handles_recalc);
|
||||
ANIM_nla_mapping_apply_fcurve(adt, fcurve, true, false);
|
||||
}
|
||||
else {
|
||||
ANIM_fcurve_keyframes_loop(
|
||||
&ked, static_cast<FCurve *>(ale->key_data), nullptr, edit_cb, BKE_fcurve_handles_recalc);
|
||||
FCurve *fcurve = static_cast<FCurve *>(ale->key_data);
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(ale, fcurve, false, false);
|
||||
ANIM_fcurve_keyframes_loop(&ked, fcurve, nullptr, edit_cb, BKE_fcurve_handles_recalc);
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(ale, fcurve, true, false);
|
||||
}
|
||||
|
||||
ale->update |= ANIM_UPDATE_DEFAULT;
|
||||
|
@ -92,8 +92,6 @@ static void actkeys_list_element_to_keylist(bAnimContext *ac,
|
||||
AnimKeylist *keylist,
|
||||
bAnimListElem *ale)
|
||||
{
|
||||
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
|
||||
|
||||
bDopeSheet *ads = nullptr;
|
||||
if (ELEM(ac->datatype, ANIMCONT_DOPESHEET, ANIMCONT_TIMELINE)) {
|
||||
ads = static_cast<bDopeSheet *>(ac->data);
|
||||
@ -115,7 +113,7 @@ static void actkeys_list_element_to_keylist(bAnimContext *ac,
|
||||
}
|
||||
case ALE_ACTION_LAYERED: {
|
||||
bAction *action = (bAction *)ale->key_data;
|
||||
action_to_keylist(adt, action, keylist, 0, range);
|
||||
action_to_keylist(ale->adt, action, keylist, 0, range);
|
||||
break;
|
||||
}
|
||||
case ALE_ACTION_SLOT: {
|
||||
@ -123,17 +121,17 @@ static void actkeys_list_element_to_keylist(bAnimContext *ac,
|
||||
animrig::Slot *slot = static_cast<animrig::Slot *>(ale->data);
|
||||
BLI_assert(action);
|
||||
BLI_assert(slot);
|
||||
action_slot_to_keylist(adt, *action, slot->handle, keylist, 0, range);
|
||||
action_slot_to_keylist(ale->adt, *action, slot->handle, keylist, 0, range);
|
||||
break;
|
||||
}
|
||||
case ALE_ACT: {
|
||||
bAction *act = (bAction *)ale->key_data;
|
||||
action_to_keylist(adt, act, keylist, 0, range);
|
||||
action_to_keylist(ale->adt, act, keylist, 0, range);
|
||||
break;
|
||||
}
|
||||
case ALE_FCURVE: {
|
||||
FCurve *fcu = (FCurve *)ale->key_data;
|
||||
fcurve_to_keylist(adt, fcu, keylist, 0, range);
|
||||
fcurve_to_keylist(ale->adt, fcu, keylist, 0, range, ANIM_nla_mapping_allowed(ale));
|
||||
break;
|
||||
}
|
||||
case ALE_NONE:
|
||||
@ -155,22 +153,22 @@ static void actkeys_list_element_to_keylist(bAnimContext *ac,
|
||||
else if (ale->type == ANIMTYPE_GROUP) {
|
||||
/* TODO: why don't we just give groups key_data too? */
|
||||
bActionGroup *agrp = (bActionGroup *)ale->data;
|
||||
action_group_to_keylist(adt, agrp, keylist, 0, range);
|
||||
action_group_to_keylist(ale->adt, agrp, keylist, 0, range);
|
||||
}
|
||||
else if (ale->type == ANIMTYPE_GREASE_PENCIL_LAYER) {
|
||||
/* TODO: why don't we just give grease pencil layers key_data too? */
|
||||
grease_pencil_cels_to_keylist(
|
||||
adt, static_cast<const GreasePencilLayer *>(ale->data), keylist, 0);
|
||||
ale->adt, static_cast<const GreasePencilLayer *>(ale->data), keylist, 0);
|
||||
}
|
||||
else if (ale->type == ANIMTYPE_GREASE_PENCIL_LAYER_GROUP) {
|
||||
/* TODO: why don't we just give grease pencil layers key_data too? */
|
||||
grease_pencil_layer_group_to_keylist(
|
||||
adt, static_cast<const GreasePencilLayerTreeGroup *>(ale->data), keylist, 0);
|
||||
ale->adt, static_cast<const GreasePencilLayerTreeGroup *>(ale->data), keylist, 0);
|
||||
}
|
||||
else if (ale->type == ANIMTYPE_GREASE_PENCIL_DATABLOCK) {
|
||||
/* TODO: why don't we just give grease pencil layers key_data too? */
|
||||
grease_pencil_data_block_to_keylist(
|
||||
adt, static_cast<const GreasePencil *>(ale->data), keylist, 0, false);
|
||||
ale->adt, static_cast<const GreasePencil *>(ale->data), keylist, 0, false);
|
||||
}
|
||||
else if (ale->type == ANIMTYPE_GPLAYER) {
|
||||
/* TODO: why don't we just give gplayers key_data too? */
|
||||
@ -200,8 +198,6 @@ static void actkeys_find_key_in_list_element(bAnimContext *ac,
|
||||
actkeys_list_element_to_keylist(ac, keylist, ale);
|
||||
ED_keylist_prepare_for_direct_access(keylist);
|
||||
|
||||
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
|
||||
|
||||
/* standard channel height (to allow for some slop) */
|
||||
float key_hsize = ANIM_UI_get_channel_height() * 0.8f;
|
||||
/* half-size (for either side), but rounded up to nearest int (for easier targeting) */
|
||||
@ -218,7 +214,7 @@ static void actkeys_find_key_in_list_element(bAnimContext *ac,
|
||||
* so that the frame will get selected by the selection functions without
|
||||
* requiring to map each frame once again...
|
||||
*/
|
||||
*r_selx = BKE_nla_tweakedit_remap(adt, ak->cfra, NLATIME_CONVERT_UNMAP);
|
||||
*r_selx = ANIM_nla_tweakedit_remap(ale, ak->cfra, NLATIME_CONVERT_UNMAP);
|
||||
*r_frame = ak->cfra;
|
||||
*r_found = true;
|
||||
*r_is_selected = (ak->sel & SELECT) != 0;
|
||||
@ -574,18 +570,16 @@ static void box_select_action(bAnimContext *ac,
|
||||
for (ale = static_cast<bAnimListElem *>(anim_data.first); ale;
|
||||
ale = ale->next, ymax -= channel_step)
|
||||
{
|
||||
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
|
||||
|
||||
/* get new vertical minimum extent of channel */
|
||||
float ymin = ymax - channel_step;
|
||||
|
||||
/* set horizontal range (if applicable) */
|
||||
if (ELEM(mode, ACTKEYS_BORDERSEL_FRAMERANGE, ACTKEYS_BORDERSEL_ALLKEYS)) {
|
||||
/* if channel is mapped in NLA, apply correction */
|
||||
if (adt) {
|
||||
if (ANIM_nla_mapping_allowed(ale)) {
|
||||
sel_data.ked.iterflags &= ~(KED_F1_NLA_UNMAP | KED_F2_NLA_UNMAP);
|
||||
sel_data.ked.f1 = BKE_nla_tweakedit_remap(adt, rectf.xmin, NLATIME_CONVERT_UNMAP);
|
||||
sel_data.ked.f2 = BKE_nla_tweakedit_remap(adt, rectf.xmax, NLATIME_CONVERT_UNMAP);
|
||||
sel_data.ked.f1 = ANIM_nla_tweakedit_remap(ale, rectf.xmin, NLATIME_CONVERT_UNMAP);
|
||||
sel_data.ked.f2 = ANIM_nla_tweakedit_remap(ale, rectf.xmax, NLATIME_CONVERT_UNMAP);
|
||||
}
|
||||
else {
|
||||
sel_data.ked.iterflags |= (KED_F1_NLA_UNMAP | KED_F2_NLA_UNMAP); /* for summary tracks */
|
||||
@ -871,8 +865,6 @@ static void region_select_action_keys(bAnimContext *ac,
|
||||
for (ale = static_cast<bAnimListElem *>(anim_data.first); ale;
|
||||
ale = ale->next, ymax -= channel_step)
|
||||
{
|
||||
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
|
||||
|
||||
/* get new vertical minimum extent of channel */
|
||||
const float ymin = ymax - channel_step;
|
||||
|
||||
@ -885,10 +877,10 @@ static void region_select_action_keys(bAnimContext *ac,
|
||||
* - Save result to the scaled_rect, which is all that these operators
|
||||
* will read from
|
||||
*/
|
||||
if (adt) {
|
||||
if (ANIM_nla_mapping_allowed(ale)) {
|
||||
sel_data.ked.iterflags &= ~(KED_F1_NLA_UNMAP | KED_F2_NLA_UNMAP);
|
||||
sel_data.ked.f1 = BKE_nla_tweakedit_remap(adt, rectf.xmin, NLATIME_CONVERT_UNMAP);
|
||||
sel_data.ked.f2 = BKE_nla_tweakedit_remap(adt, rectf.xmax, NLATIME_CONVERT_UNMAP);
|
||||
sel_data.ked.f1 = ANIM_nla_tweakedit_remap(ale, rectf.xmin, NLATIME_CONVERT_UNMAP);
|
||||
sel_data.ked.f2 = ANIM_nla_tweakedit_remap(ale, rectf.xmax, NLATIME_CONVERT_UNMAP);
|
||||
}
|
||||
else {
|
||||
sel_data.ked.iterflags |= (KED_F1_NLA_UNMAP | KED_F2_NLA_UNMAP); /* for summary tracks */
|
||||
@ -1122,16 +1114,10 @@ static void markers_selectkeys_between(bAnimContext *ac)
|
||||
break;
|
||||
|
||||
case ANIMTYPE_FCURVE: {
|
||||
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
|
||||
FCurve *fcurve = static_cast<FCurve *>(ale->key_data);
|
||||
if (adt) {
|
||||
ANIM_nla_mapping_apply_fcurve(adt, fcurve, false, true);
|
||||
ANIM_fcurve_keyframes_loop(&ked, fcurve, ok_cb, select_cb, nullptr);
|
||||
ANIM_nla_mapping_apply_fcurve(adt, fcurve, true, true);
|
||||
}
|
||||
else {
|
||||
ANIM_fcurve_keyframes_loop(&ked, fcurve, ok_cb, select_cb, nullptr);
|
||||
}
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(ale, fcurve, false, true);
|
||||
ANIM_fcurve_keyframes_loop(&ked, fcurve, ok_cb, select_cb, nullptr);
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(ale, fcurve, true, true);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1223,19 +1209,12 @@ static void columnselect_action_keys(bAnimContext *ac, short mode)
|
||||
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, eAnimCont_Types(ac->datatype));
|
||||
|
||||
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
|
||||
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
|
||||
|
||||
/* loop over cfraelems (stored in the KeyframeEditData->list)
|
||||
* - we need to do this here, as we can apply fewer NLA-mapping conversions
|
||||
*/
|
||||
LISTBASE_FOREACH (CfraElem *, ce, &ked.list) {
|
||||
/* set frame for validation callback to refer to */
|
||||
if (adt) {
|
||||
ked.f1 = BKE_nla_tweakedit_remap(adt, ce->cfra, NLATIME_CONVERT_UNMAP);
|
||||
}
|
||||
else {
|
||||
ked.f1 = ce->cfra;
|
||||
}
|
||||
ked.f1 = ANIM_nla_tweakedit_remap(ale, ce->cfra, NLATIME_CONVERT_UNMAP);
|
||||
|
||||
/* select elements with frame number matching cfraelem */
|
||||
if (ale->type == ANIMTYPE_GPLAYER) {
|
||||
@ -1580,16 +1559,10 @@ static void actkeys_select_leftright(bAnimContext *ac,
|
||||
break;
|
||||
|
||||
case ANIMTYPE_FCURVE: {
|
||||
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
|
||||
FCurve *fcurve = static_cast<FCurve *>(ale->key_data);
|
||||
if (adt) {
|
||||
ANIM_nla_mapping_apply_fcurve(adt, fcurve, false, true);
|
||||
ANIM_fcurve_keyframes_loop(&ked, fcurve, ok_cb, select_cb, nullptr);
|
||||
ANIM_nla_mapping_apply_fcurve(adt, fcurve, true, true);
|
||||
}
|
||||
else {
|
||||
ANIM_fcurve_keyframes_loop(&ked, fcurve, ok_cb, select_cb, nullptr);
|
||||
}
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(ale, fcurve, false, true);
|
||||
ANIM_fcurve_keyframes_loop(&ked, fcurve, ok_cb, select_cb, nullptr);
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(ale, fcurve, true, true);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1858,15 +1831,8 @@ static void actkeys_mselect_column(bAnimContext *ac, eEditKeyframes_Select selec
|
||||
ale->update |= ANIM_UPDATE_DEPS;
|
||||
}
|
||||
else {
|
||||
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
|
||||
|
||||
/* set frame for validation callback to refer to */
|
||||
if (adt) {
|
||||
ked.f1 = BKE_nla_tweakedit_remap(adt, selx, NLATIME_CONVERT_UNMAP);
|
||||
}
|
||||
else {
|
||||
ked.f1 = selx;
|
||||
}
|
||||
ked.f1 = ANIM_nla_tweakedit_remap(ale, selx, NLATIME_CONVERT_UNMAP);
|
||||
|
||||
ANIM_fcurve_keyframes_loop(
|
||||
&ked, static_cast<FCurve *>(ale->key_data), ok_cb, select_cb, nullptr);
|
||||
|
@ -80,11 +80,12 @@ static blender::IndexRange get_bounding_bezt_index_range(const FCurve *fcu,
|
||||
|
||||
/* TODO: draw a shaded poly showing the region of influence too!!! */
|
||||
/**
|
||||
* \param adt_nla_remap: Send nullptr if no NLA remapping necessary.
|
||||
* \param ale_nla_remap: the anim list element of the fcurve that this modifier
|
||||
* is on. This is used to do NLA time remapping, as appropriate.
|
||||
*/
|
||||
static void draw_fcurve_modifier_controls_envelope(FModifier *fcm,
|
||||
View2D *v2d,
|
||||
AnimData *adt_nla_remap)
|
||||
bAnimListElem *ale_nla_remap)
|
||||
{
|
||||
FMod_Envelope *env = (FMod_Envelope *)fcm->data;
|
||||
FCM_EnvelopeData *fed;
|
||||
@ -131,8 +132,8 @@ static void draw_fcurve_modifier_controls_envelope(FModifier *fcm,
|
||||
immBeginAtMost(GPU_PRIM_POINTS, env->totvert * 2);
|
||||
|
||||
for (i = 0, fed = env->data; i < env->totvert; i++, fed++) {
|
||||
const float env_scene_time = BKE_nla_tweakedit_remap(
|
||||
adt_nla_remap, fed->time, NLATIME_CONVERT_MAP);
|
||||
const float env_scene_time = ANIM_nla_tweakedit_remap(
|
||||
ale_nla_remap, fed->time, NLATIME_CONVERT_MAP);
|
||||
|
||||
/* only draw if visible
|
||||
* - min/max here are fixed, not relative
|
||||
@ -1143,10 +1144,9 @@ static void draw_fcurve(bAnimContext *ac, SpaceGraph *sipo, ARegion *region, bAn
|
||||
{
|
||||
FCurve *fcu = (FCurve *)ale->key_data;
|
||||
FModifier *fcm = find_active_fmodifier(&fcu->modifiers);
|
||||
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
|
||||
|
||||
/* map keyframes for drawing if scaled F-Curve */
|
||||
ANIM_nla_mapping_apply_fcurve(adt, static_cast<FCurve *>(ale->key_data), false, false);
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(ale, static_cast<FCurve *>(ale->key_data), false, false);
|
||||
|
||||
/* draw curve:
|
||||
* - curve line may be result of one or more destructive modifiers or just the raw data,
|
||||
@ -1213,20 +1213,23 @@ static void draw_fcurve(bAnimContext *ac, SpaceGraph *sipo, ARegion *region, bAn
|
||||
/* draw a curve affected by modifiers or only allowed to have integer values
|
||||
* by sampling it at various small-intervals over the visible region
|
||||
*/
|
||||
if (adt) {
|
||||
/* We have to do this mapping dance since the keyframes were remapped but the F-modifier
|
||||
* evaluations are not.
|
||||
*
|
||||
* So we undo the keyframe remapping and instead remap the evaluation time when drawing the
|
||||
* curve itself. Afterward, we go back and redo the keyframe remapping so the controls are
|
||||
* drawn properly. */
|
||||
ANIM_nla_mapping_apply_fcurve(adt, static_cast<FCurve *>(ale->key_data), true, false);
|
||||
draw_fcurve_curve(ac, ale->id, fcu, ®ion->v2d, shdr_pos, true, draw_extrapolation);
|
||||
ANIM_nla_mapping_apply_fcurve(adt, static_cast<FCurve *>(ale->key_data), false, false);
|
||||
}
|
||||
else {
|
||||
draw_fcurve_curve(ac, ale->id, fcu, ®ion->v2d, shdr_pos, false, draw_extrapolation);
|
||||
}
|
||||
/* We have to do this mapping dance since the keyframes were remapped but the F-modifier
|
||||
* evaluations are not.
|
||||
*
|
||||
* So we undo the keyframe remapping and instead remap the evaluation time when drawing
|
||||
* the curve itself. Afterward, we go back and redo the keyframe remapping so the controls
|
||||
* are drawn properly. */
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(
|
||||
ale, static_cast<FCurve *>(ale->key_data), true, false);
|
||||
draw_fcurve_curve(ac,
|
||||
ale->id,
|
||||
fcu,
|
||||
®ion->v2d,
|
||||
shdr_pos,
|
||||
ANIM_nla_mapping_allowed(ale),
|
||||
draw_extrapolation);
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(
|
||||
ale, static_cast<FCurve *>(ale->key_data), false, false);
|
||||
}
|
||||
else if (((fcu->bezt) || (fcu->fpt)) && (fcu->totvert)) {
|
||||
/* just draw curve based on defined data (i.e. no modifiers) */
|
||||
@ -1258,7 +1261,7 @@ static void draw_fcurve(bAnimContext *ac, SpaceGraph *sipo, ARegion *region, bAn
|
||||
if ((fcu->flag & FCURVE_ACTIVE) && (fcm)) {
|
||||
switch (fcm->type) {
|
||||
case FMODIFIER_TYPE_ENVELOPE: /* envelope */
|
||||
draw_fcurve_modifier_controls_envelope(fcm, ®ion->v2d, adt);
|
||||
draw_fcurve_modifier_controls_envelope(fcm, ®ion->v2d, ale);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1303,9 +1306,7 @@ static void draw_fcurve(bAnimContext *ac, SpaceGraph *sipo, ARegion *region, bAn
|
||||
}
|
||||
|
||||
/* undo mapping of keyframes for drawing if scaled F-Curve */
|
||||
if (adt) {
|
||||
ANIM_nla_mapping_apply_fcurve(adt, static_cast<FCurve *>(ale->key_data), true, false);
|
||||
}
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(ale, static_cast<FCurve *>(ale->key_data), true, false);
|
||||
}
|
||||
|
||||
/* Debugging -------------------------------- */
|
||||
|
@ -152,7 +152,6 @@ static void insert_graph_keys(bAnimContext *ac, eGraphKeys_InsertKey_Types mode)
|
||||
/* Insert keyframes. */
|
||||
if (mode & GRAPHKEYS_INSERTKEY_CURSOR) {
|
||||
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
|
||||
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
|
||||
FCurve *fcu = (FCurve *)ale->key_data;
|
||||
|
||||
short mapping_flag = ANIM_get_normalization_flags(ac->sl);
|
||||
@ -166,11 +165,8 @@ static void insert_graph_keys(bAnimContext *ac, eGraphKeys_InsertKey_Types mode)
|
||||
if ((sipo) && (sipo->mode == SIPO_MODE_DRIVERS)) {
|
||||
x = sipo->cursorTime;
|
||||
}
|
||||
else if (adt) {
|
||||
x = BKE_nla_tweakedit_remap(adt, float(scene->r.cfra), NLATIME_CONVERT_UNMAP);
|
||||
}
|
||||
else {
|
||||
x = float(scene->r.cfra);
|
||||
x = ANIM_nla_tweakedit_remap(ale, float(scene->r.cfra), NLATIME_CONVERT_UNMAP);
|
||||
}
|
||||
|
||||
/* Normalize units of cursor's value. */
|
||||
@ -223,15 +219,13 @@ static void insert_graph_keys(bAnimContext *ac, eGraphKeys_InsertKey_Types mode)
|
||||
}
|
||||
}
|
||||
else {
|
||||
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
|
||||
|
||||
/* Adjust current frame for NLA-mapping. */
|
||||
float cfra = float(scene->r.cfra);
|
||||
float cfra;
|
||||
if ((sipo) && (sipo->mode == SIPO_MODE_DRIVERS)) {
|
||||
cfra = sipo->cursorTime;
|
||||
}
|
||||
else if (adt) {
|
||||
cfra = BKE_nla_tweakedit_remap(adt, float(scene->r.cfra), NLATIME_CONVERT_UNMAP);
|
||||
else {
|
||||
cfra = ANIM_nla_tweakedit_remap(ale, float(scene->r.cfra), NLATIME_CONVERT_UNMAP);
|
||||
}
|
||||
|
||||
const float curval = evaluate_fcurve_only_curve(fcu, cfra);
|
||||
@ -302,9 +296,7 @@ static int graphkeys_click_insert_exec(bContext *C, wmOperator *op)
|
||||
using namespace blender::animrig;
|
||||
bAnimContext ac;
|
||||
bAnimListElem *ale;
|
||||
AnimData *adt;
|
||||
FCurve *fcu;
|
||||
float frame, val;
|
||||
|
||||
/* Get animation context. */
|
||||
if (ANIM_animdata_get_context(C, &ac) == 0) {
|
||||
@ -328,9 +320,6 @@ static int graphkeys_click_insert_exec(bContext *C, wmOperator *op)
|
||||
ListBase anim_data;
|
||||
ToolSettings *ts = ac.scene->toolsettings;
|
||||
|
||||
short mapping_flag = ANIM_get_normalization_flags(ac.sl);
|
||||
float scale, offset;
|
||||
|
||||
/* Preserve selection? */
|
||||
if (RNA_boolean_get(op->ptr, "extend") == false) {
|
||||
/* Deselect all keyframes first,
|
||||
@ -339,19 +328,23 @@ static int graphkeys_click_insert_exec(bContext *C, wmOperator *op)
|
||||
deselect_graph_keys(&ac, false, SELECT_SUBTRACT, false);
|
||||
}
|
||||
|
||||
/* Get frame and value from props. */
|
||||
frame = RNA_float_get(op->ptr, "frame");
|
||||
val = RNA_float_get(op->ptr, "value");
|
||||
|
||||
/* Apply inverse NLA-mapping to frame to get correct time in un-scaled action. */
|
||||
adt = ANIM_nla_mapping_get(&ac, ale);
|
||||
frame = BKE_nla_tweakedit_remap(adt, frame, NLATIME_CONVERT_UNMAP);
|
||||
/* Get frame and value from props.
|
||||
*
|
||||
* We apply inverse NLA-mapping to `frame` to get correct time in un-scaled
|
||||
* action. */
|
||||
const float frame = ANIM_nla_tweakedit_remap(
|
||||
ale, RNA_float_get(op->ptr, "frame"), NLATIME_CONVERT_UNMAP);
|
||||
float val = RNA_float_get(op->ptr, "value");
|
||||
|
||||
/* Apply inverse unit-mapping to value to get correct value for F-Curves. */
|
||||
scale = ANIM_unit_mapping_get_factor(
|
||||
ac.scene, ale->id, fcu, mapping_flag | ANIM_UNITCONV_RESTORE, &offset);
|
||||
{
|
||||
const short mapping_flag = ANIM_get_normalization_flags(ac.sl);
|
||||
float offset;
|
||||
const float scale = ANIM_unit_mapping_get_factor(
|
||||
ac.scene, ale->id, fcu, mapping_flag | ANIM_UNITCONV_RESTORE, &offset);
|
||||
|
||||
val = val * scale - offset;
|
||||
val = val * scale - offset;
|
||||
}
|
||||
|
||||
KeyframeSettings settings = get_keyframe_settings(true);
|
||||
settings.keyframe_type = eBezTriple_KeyframeType(ts->keyframe_type);
|
||||
@ -2139,7 +2132,6 @@ static KeyframeEditData sum_selected_keyframes(bAnimContext *ac)
|
||||
ac, &anim_data, eAnimFilter_Flags(filter), ac->data, eAnimCont_Types(ac->datatype));
|
||||
|
||||
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
|
||||
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
|
||||
short mapping_flag = ANIM_get_normalization_flags(ac->sl);
|
||||
KeyframeEditData current_ked;
|
||||
float offset;
|
||||
@ -2151,16 +2143,11 @@ static KeyframeEditData sum_selected_keyframes(bAnimContext *ac)
|
||||
|
||||
memset(¤t_ked, 0, sizeof(current_ked));
|
||||
|
||||
if (adt) {
|
||||
ANIM_nla_mapping_apply_fcurve(adt, static_cast<FCurve *>(ale->key_data), false, true);
|
||||
ANIM_fcurve_keyframes_loop(
|
||||
¤t_ked, static_cast<FCurve *>(ale->key_data), nullptr, bezt_calc_average, nullptr);
|
||||
ANIM_nla_mapping_apply_fcurve(adt, static_cast<FCurve *>(ale->key_data), true, true);
|
||||
}
|
||||
else {
|
||||
ANIM_fcurve_keyframes_loop(
|
||||
¤t_ked, static_cast<FCurve *>(ale->key_data), nullptr, bezt_calc_average, nullptr);
|
||||
}
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(
|
||||
ale, static_cast<FCurve *>(ale->key_data), false, true);
|
||||
ANIM_fcurve_keyframes_loop(
|
||||
¤t_ked, static_cast<FCurve *>(ale->key_data), nullptr, bezt_calc_average, nullptr);
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(ale, static_cast<FCurve *>(ale->key_data), true, true);
|
||||
|
||||
if (current_ked.i1 == 0) {
|
||||
continue;
|
||||
@ -2293,12 +2280,11 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op)
|
||||
if (!fcu->bezt) {
|
||||
continue;
|
||||
}
|
||||
AnimData *adt = ANIM_nla_mapping_get(&ac, ale);
|
||||
|
||||
float closest_fcu_frame;
|
||||
ANIM_nla_mapping_apply_fcurve(adt, fcu, false, true);
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(ale, fcu, false, true);
|
||||
const bool success = find_closest_frame(fcu, current_frame, next, &closest_fcu_frame);
|
||||
ANIM_nla_mapping_apply_fcurve(adt, fcu, true, true);
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(ale, fcu, true, true);
|
||||
|
||||
if (!success) {
|
||||
continue;
|
||||
@ -2467,8 +2453,6 @@ static void snap_graph_keys(bAnimContext *ac, short mode)
|
||||
/* Snap keyframes. */
|
||||
const bool use_handle = (sipo->flag & SIPO_NOHANDLES) == 0;
|
||||
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
|
||||
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
|
||||
|
||||
/* Normalize cursor value (for normalized F-Curves display). */
|
||||
if (mode == GRAPHKEYS_SNAP_VALUE) {
|
||||
short mapping_flag = ANIM_get_normalization_flags(ac->sl);
|
||||
@ -2480,20 +2464,14 @@ static void snap_graph_keys(bAnimContext *ac, short mode)
|
||||
}
|
||||
|
||||
/* Perform snapping. */
|
||||
if (adt) {
|
||||
ANIM_nla_mapping_apply_fcurve(adt, static_cast<FCurve *>(ale->key_data), false, false);
|
||||
ANIM_fcurve_keyframes_loop(
|
||||
&ked, static_cast<FCurve *>(ale->key_data), nullptr, edit_cb, BKE_fcurve_handles_recalc);
|
||||
BKE_fcurve_merge_duplicate_keys(
|
||||
static_cast<FCurve *>(ale->key_data), BEZT_FLAG_TEMP_TAG, use_handle);
|
||||
ANIM_nla_mapping_apply_fcurve(adt, static_cast<FCurve *>(ale->key_data), true, false);
|
||||
}
|
||||
else {
|
||||
ANIM_fcurve_keyframes_loop(
|
||||
&ked, static_cast<FCurve *>(ale->key_data), nullptr, edit_cb, BKE_fcurve_handles_recalc);
|
||||
BKE_fcurve_merge_duplicate_keys(
|
||||
static_cast<FCurve *>(ale->key_data), BEZT_FLAG_TEMP_TAG, use_handle);
|
||||
}
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(
|
||||
ale, static_cast<FCurve *>(ale->key_data), false, false);
|
||||
ANIM_fcurve_keyframes_loop(
|
||||
&ked, static_cast<FCurve *>(ale->key_data), nullptr, edit_cb, BKE_fcurve_handles_recalc);
|
||||
BKE_fcurve_merge_duplicate_keys(
|
||||
static_cast<FCurve *>(ale->key_data), BEZT_FLAG_TEMP_TAG, use_handle);
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(
|
||||
ale, static_cast<FCurve *>(ale->key_data), true, false);
|
||||
|
||||
ale->update |= ANIM_UPDATE_DEFAULT;
|
||||
}
|
||||
@ -2780,8 +2758,6 @@ static void mirror_graph_keys(bAnimContext *ac, short mode)
|
||||
|
||||
/* Mirror keyframes. */
|
||||
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
|
||||
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
|
||||
|
||||
/* Apply unit corrections. */
|
||||
if (mode == GRAPHKEYS_MIRROR_VALUE) {
|
||||
short mapping_flag = ANIM_get_normalization_flags(ac->sl);
|
||||
@ -2796,16 +2772,12 @@ static void mirror_graph_keys(bAnimContext *ac, short mode)
|
||||
}
|
||||
|
||||
/* Perform actual mirroring. */
|
||||
if (adt) {
|
||||
ANIM_nla_mapping_apply_fcurve(adt, static_cast<FCurve *>(ale->key_data), false, false);
|
||||
ANIM_fcurve_keyframes_loop(
|
||||
&ked, static_cast<FCurve *>(ale->key_data), nullptr, edit_cb, BKE_fcurve_handles_recalc);
|
||||
ANIM_nla_mapping_apply_fcurve(adt, static_cast<FCurve *>(ale->key_data), true, false);
|
||||
}
|
||||
else {
|
||||
ANIM_fcurve_keyframes_loop(
|
||||
&ked, static_cast<FCurve *>(ale->key_data), nullptr, edit_cb, BKE_fcurve_handles_recalc);
|
||||
}
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(
|
||||
ale, static_cast<FCurve *>(ale->key_data), false, false);
|
||||
ANIM_fcurve_keyframes_loop(
|
||||
&ked, static_cast<FCurve *>(ale->key_data), nullptr, edit_cb, BKE_fcurve_handles_recalc);
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(
|
||||
ale, static_cast<FCurve *>(ale->key_data), true, false);
|
||||
|
||||
ale->update |= ANIM_UPDATE_DEFAULT;
|
||||
}
|
||||
|
@ -185,15 +185,13 @@ static void get_nearest_fcurve_verts_list(bAnimContext *ac, const int mval[2], L
|
||||
|
||||
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
|
||||
FCurve *fcu = (FCurve *)ale->key_data;
|
||||
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
|
||||
float offset;
|
||||
float unit_scale = ANIM_unit_mapping_get_factor(
|
||||
ac->scene, ale->id, fcu, mapping_flag, &offset);
|
||||
|
||||
/* apply NLA mapping to all the keyframes */
|
||||
if (adt) {
|
||||
ANIM_nla_mapping_apply_fcurve(adt, static_cast<FCurve *>(ale->key_data), false, false);
|
||||
}
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(
|
||||
ale, static_cast<FCurve *>(ale->key_data), false, false);
|
||||
|
||||
if (fcu->bezt) {
|
||||
BezTriple *bezt1 = fcu->bezt, *prevbezt = nullptr;
|
||||
@ -251,9 +249,8 @@ static void get_nearest_fcurve_verts_list(bAnimContext *ac, const int mval[2], L
|
||||
}
|
||||
|
||||
/* un-apply NLA mapping from all the keyframes */
|
||||
if (adt) {
|
||||
ANIM_nla_mapping_apply_fcurve(adt, static_cast<FCurve *>(ale->key_data), true, false);
|
||||
}
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(
|
||||
ale, static_cast<FCurve *>(ale->key_data), true, false);
|
||||
}
|
||||
|
||||
/* free channels */
|
||||
@ -617,7 +614,6 @@ static bool box_select_graphkeys(bAnimContext *ac,
|
||||
|
||||
/* First loop over data, doing box select. try selecting keys only. */
|
||||
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
|
||||
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
|
||||
FCurve *fcu = (FCurve *)ale->key_data;
|
||||
float offset;
|
||||
const float unit_scale = ANIM_unit_mapping_get_factor(
|
||||
@ -626,10 +622,8 @@ static bool box_select_graphkeys(bAnimContext *ac,
|
||||
/* Apply NLA mapping to all the keyframes, since it's easier than trying to
|
||||
* guess when a callback might use something different.
|
||||
*/
|
||||
if (adt) {
|
||||
ANIM_nla_mapping_apply_fcurve(
|
||||
adt, static_cast<FCurve *>(ale->key_data), false, incl_handles == 0);
|
||||
}
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(
|
||||
ale, static_cast<FCurve *>(ale->key_data), false, incl_handles == 0);
|
||||
|
||||
scaled_rectf.xmin = rectf.xmin;
|
||||
scaled_rectf.xmax = rectf.xmax;
|
||||
@ -665,10 +659,8 @@ static bool box_select_graphkeys(bAnimContext *ac,
|
||||
}
|
||||
|
||||
/* Un-apply NLA mapping from all the keyframes. */
|
||||
if (adt) {
|
||||
ANIM_nla_mapping_apply_fcurve(
|
||||
adt, static_cast<FCurve *>(ale->key_data), true, incl_handles == 0);
|
||||
}
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(
|
||||
ale, static_cast<FCurve *>(ale->key_data), true, incl_handles == 0);
|
||||
}
|
||||
|
||||
/* Cleanup. */
|
||||
@ -706,7 +698,7 @@ static int rectf_curve_zone_y(const FCurve *fcu,
|
||||
static bool rectf_curve_intersection(const float offset,
|
||||
const float unit_scale,
|
||||
const rctf *rectf,
|
||||
AnimData *adt,
|
||||
bAnimListElem *ale,
|
||||
const FCurve *fcu)
|
||||
{
|
||||
/* 30 sampling points. This worked well in tests. */
|
||||
@ -714,8 +706,8 @@ static bool rectf_curve_intersection(const float offset,
|
||||
|
||||
/* Remap the range at which to evaluate the fcurves. This enables us to avoid remapping
|
||||
* the keys themselves. */
|
||||
const float mapped_max = BKE_nla_tweakedit_remap(adt, rectf->xmax, NLATIME_CONVERT_UNMAP);
|
||||
const float mapped_min = BKE_nla_tweakedit_remap(adt, rectf->xmin, NLATIME_CONVERT_UNMAP);
|
||||
const float mapped_max = ANIM_nla_tweakedit_remap(ale, rectf->xmax, NLATIME_CONVERT_UNMAP);
|
||||
const float mapped_min = ANIM_nla_tweakedit_remap(ale, rectf->xmin, NLATIME_CONVERT_UNMAP);
|
||||
const float eval_step = (mapped_max - mapped_min) / num_steps;
|
||||
|
||||
/* Sample points on the given fcurve in the interval defined by the
|
||||
@ -779,7 +771,6 @@ static void box_select_graphcurves(bAnimContext *ac,
|
||||
*/
|
||||
|
||||
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
|
||||
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
|
||||
FCurve *fcu = (FCurve *)ale->key_data;
|
||||
float offset;
|
||||
const float unit_scale = ANIM_unit_mapping_get_factor(
|
||||
@ -798,7 +789,7 @@ static void box_select_graphcurves(bAnimContext *ac,
|
||||
scaled_rectf.ymax = rectf.ymax / unit_scale - offset;
|
||||
|
||||
const KeyframeEditFunc select_cb = ANIM_editkeyframes_select(selectmode);
|
||||
if (rectf_curve_intersection(offset, unit_scale, &rectf, adt, fcu)) {
|
||||
if (rectf_curve_intersection(offset, unit_scale, &rectf, ale, fcu)) {
|
||||
if ((selectmode & SELECT_ADD) || (selectmode & SELECT_REPLACE)) {
|
||||
fcu->flag |= FCURVE_SELECTED;
|
||||
last_selected_curve = fcu;
|
||||
@ -1195,18 +1186,11 @@ static void markers_selectkeys_between(bAnimContext *ac)
|
||||
|
||||
/* select keys in-between */
|
||||
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
|
||||
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
|
||||
|
||||
if (adt) {
|
||||
ANIM_nla_mapping_apply_fcurve(adt, static_cast<FCurve *>(ale->key_data), false, true);
|
||||
ANIM_fcurve_keyframes_loop(
|
||||
&ked, static_cast<FCurve *>(ale->key_data), ok_cb, select_cb, nullptr);
|
||||
ANIM_nla_mapping_apply_fcurve(adt, static_cast<FCurve *>(ale->key_data), true, true);
|
||||
}
|
||||
else {
|
||||
ANIM_fcurve_keyframes_loop(
|
||||
&ked, static_cast<FCurve *>(ale->key_data), ok_cb, select_cb, nullptr);
|
||||
}
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(
|
||||
ale, static_cast<FCurve *>(ale->key_data), false, true);
|
||||
ANIM_fcurve_keyframes_loop(
|
||||
&ked, static_cast<FCurve *>(ale->key_data), ok_cb, select_cb, nullptr);
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(ale, static_cast<FCurve *>(ale->key_data), true, true);
|
||||
}
|
||||
|
||||
/* Cleanup */
|
||||
@ -1272,14 +1256,12 @@ static void columnselect_graph_keys(bAnimContext *ac, short mode)
|
||||
ac, &anim_data, eAnimFilter_Flags(filter), ac->data, eAnimCont_Types(ac->datatype));
|
||||
|
||||
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
|
||||
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
|
||||
|
||||
/* loop over cfraelems (stored in the KeyframeEditData->list)
|
||||
* - we need to do this here, as we can apply fewer NLA-mapping conversions
|
||||
*/
|
||||
LISTBASE_FOREACH (CfraElem *, ce, &ked.list) {
|
||||
/* set frame for validation callback to refer to */
|
||||
ked.f1 = BKE_nla_tweakedit_remap(adt, ce->cfra, NLATIME_CONVERT_UNMAP);
|
||||
ked.f1 = ANIM_nla_tweakedit_remap(ale, ce->cfra, NLATIME_CONVERT_UNMAP);
|
||||
|
||||
/* select elements with frame number matching cfraelem */
|
||||
ANIM_fcurve_keyframes_loop(
|
||||
@ -1578,18 +1560,11 @@ static void graphkeys_select_leftright(bAnimContext *ac,
|
||||
|
||||
/* select keys */
|
||||
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
|
||||
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
|
||||
|
||||
if (adt) {
|
||||
ANIM_nla_mapping_apply_fcurve(adt, static_cast<FCurve *>(ale->key_data), false, true);
|
||||
ANIM_fcurve_keyframes_loop(
|
||||
&ked, static_cast<FCurve *>(ale->key_data), ok_cb, select_cb, nullptr);
|
||||
ANIM_nla_mapping_apply_fcurve(adt, static_cast<FCurve *>(ale->key_data), true, true);
|
||||
}
|
||||
else {
|
||||
ANIM_fcurve_keyframes_loop(
|
||||
&ked, static_cast<FCurve *>(ale->key_data), ok_cb, select_cb, nullptr);
|
||||
}
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(
|
||||
ale, static_cast<FCurve *>(ale->key_data), false, true);
|
||||
ANIM_fcurve_keyframes_loop(
|
||||
&ked, static_cast<FCurve *>(ale->key_data), ok_cb, select_cb, nullptr);
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(ale, static_cast<FCurve *>(ale->key_data), true, true);
|
||||
}
|
||||
|
||||
/* Cleanup */
|
||||
@ -1938,15 +1913,8 @@ static int graphkeys_mselect_column(bAnimContext *ac,
|
||||
ac, &anim_data, eAnimFilter_Flags(filter), ac->data, eAnimCont_Types(ac->datatype));
|
||||
|
||||
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
|
||||
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
|
||||
|
||||
/* set frame for validation callback to refer to */
|
||||
if (adt) {
|
||||
ked.f1 = BKE_nla_tweakedit_remap(adt, selx, NLATIME_CONVERT_UNMAP);
|
||||
}
|
||||
else {
|
||||
ked.f1 = selx;
|
||||
}
|
||||
ked.f1 = ANIM_nla_tweakedit_remap(ale, selx, NLATIME_CONVERT_UNMAP);
|
||||
|
||||
/* select elements with frame number matching cfra */
|
||||
ANIM_fcurve_keyframes_loop(
|
||||
|
@ -82,7 +82,6 @@ void get_graph_keyframe_extents(bAnimContext *ac,
|
||||
|
||||
/* Go through channels, finding max extents. */
|
||||
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
|
||||
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
|
||||
FCurve *fcu = (FCurve *)ale->key_data;
|
||||
rctf bounds;
|
||||
float unitFac, offset;
|
||||
@ -92,10 +91,8 @@ void get_graph_keyframe_extents(bAnimContext *ac,
|
||||
short mapping_flag = ANIM_get_normalization_flags(ac->sl);
|
||||
|
||||
/* Apply NLA scaling. */
|
||||
if (adt) {
|
||||
bounds.xmin = BKE_nla_tweakedit_remap(adt, bounds.xmin, NLATIME_CONVERT_MAP);
|
||||
bounds.xmax = BKE_nla_tweakedit_remap(adt, bounds.xmax, NLATIME_CONVERT_MAP);
|
||||
}
|
||||
bounds.xmin = ANIM_nla_tweakedit_remap(ale, bounds.xmin, NLATIME_CONVERT_MAP);
|
||||
bounds.xmax = ANIM_nla_tweakedit_remap(ale, bounds.xmax, NLATIME_CONVERT_MAP);
|
||||
|
||||
/* Apply unit corrections. */
|
||||
unitFac = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag, &offset);
|
||||
@ -405,7 +402,6 @@ static void create_ghost_curves(bAnimContext *ac, int start, int end)
|
||||
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
|
||||
FCurve *fcu = (FCurve *)ale->key_data;
|
||||
FCurve *gcu = BKE_fcurve_create();
|
||||
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
|
||||
ChannelDriver *driver = fcu->driver;
|
||||
FPoint *fpt;
|
||||
float unitFac, offset;
|
||||
@ -427,7 +423,7 @@ static void create_ghost_curves(bAnimContext *ac, int start, int end)
|
||||
|
||||
/* Use the sampling callback at 1-frame intervals from start to end frames. */
|
||||
for (cfra = start; cfra <= end; cfra++, fpt++) {
|
||||
float cfrae = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
|
||||
const float cfrae = ANIM_nla_tweakedit_remap(ale, cfra, NLATIME_CONVERT_UNMAP);
|
||||
|
||||
fpt->vec[0] = cfrae;
|
||||
fpt->vec[1] = (fcurve_samplingcb_evalcurve(fcu, nullptr, cfrae) + offset) * unitFac;
|
||||
|
@ -383,7 +383,7 @@ static int count_masklayer_frames(MaskLayer *masklay, char side, float cfra, boo
|
||||
|
||||
/* This function assigns the information to transdata. */
|
||||
static void TimeToTransData(
|
||||
TransData *td, TransData2D *td2d, BezTriple *bezt, AnimData *adt, float ypos)
|
||||
TransData *td, TransData2D *td2d, BezTriple *bezt, bAnimListElem *ale, float ypos)
|
||||
{
|
||||
float *time = bezt->vec[1];
|
||||
|
||||
@ -404,17 +404,20 @@ static void TimeToTransData(
|
||||
copy_v3_v3(td->iloc, td->loc);
|
||||
td->val = time;
|
||||
td->ival = *(time);
|
||||
if (adt) {
|
||||
td->center[0] = BKE_nla_tweakedit_remap(adt, td->ival, NLATIME_CONVERT_MAP);
|
||||
}
|
||||
else {
|
||||
td->center[0] = td->ival;
|
||||
}
|
||||
td->center[0] = ANIM_nla_tweakedit_remap(ale, td->ival, NLATIME_CONVERT_MAP);
|
||||
td->center[1] = ypos;
|
||||
|
||||
/* Store the AnimData where this keyframe exists as a keyframe of the
|
||||
* active action as #td->extra. */
|
||||
td->extra = adt;
|
||||
* active action as #td->extra.
|
||||
*
|
||||
* We do this conditionally as a hacky way of indicating whether NLA remapping
|
||||
* should be done. This is left over from old code, most of which was changed
|
||||
* in #130440 to avoid using `adt == nullptr` as an indicator for that. This
|
||||
* was left that way because updating it cleanly was more involved than made
|
||||
* sense for the bug fix in #130440. */
|
||||
if (ANIM_nla_mapping_allowed(ale)) {
|
||||
td->extra = ale->adt;
|
||||
}
|
||||
|
||||
if (bezt->f2 & SELECT) {
|
||||
td->flag |= TD_SELECTED;
|
||||
@ -436,7 +439,7 @@ static void TimeToTransData(
|
||||
static TransData *ActionFCurveToTransData(TransData *td,
|
||||
TransData2D **td2dv,
|
||||
FCurve *fcu,
|
||||
AnimData *adt,
|
||||
bAnimListElem *ale,
|
||||
char side,
|
||||
float cfra,
|
||||
bool is_prop_edit,
|
||||
@ -456,7 +459,7 @@ static TransData *ActionFCurveToTransData(TransData *td,
|
||||
{ /* Note this MUST match #count_fcurve_keys(), so can't use #BEZT_ISSEL_ANY() macro. */
|
||||
/* Only add if on the right 'side' of the current frame. */
|
||||
if (FrameOnMouseSide(side, bezt->vec[1][0], cfra)) {
|
||||
TimeToTransData(td, td2d, bezt, adt, ypos);
|
||||
TimeToTransData(td, td2d, bezt, ale, ypos);
|
||||
|
||||
td++;
|
||||
td2d++;
|
||||
@ -662,7 +665,6 @@ static void createTransActionData(bContext *C, TransInfo *t)
|
||||
|
||||
int count = 0;
|
||||
int gpf_count = 0;
|
||||
float cfra;
|
||||
float ypos = 1.0f / ((ysize / xsize) * (xmask / ymask)) * BLI_rctf_cent_y(&t->region->v2d.cur);
|
||||
|
||||
/* Determine what type of data we are operating on. */
|
||||
@ -686,35 +688,29 @@ static void createTransActionData(bContext *C, TransInfo *t)
|
||||
|
||||
/* Loop 1: fully select F-Curve keys and count how many BezTriples are selected. */
|
||||
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
|
||||
AnimData *adt = ANIM_nla_mapping_get(&ac, ale);
|
||||
int adt_count = 0;
|
||||
int ale_count = 0;
|
||||
/* Convert current-frame to action-time (slightly less accurate, especially under
|
||||
* higher scaling ratios, but is faster than converting all points). */
|
||||
if (adt) {
|
||||
cfra = BKE_nla_tweakedit_remap(adt, float(scene->r.cfra), NLATIME_CONVERT_UNMAP);
|
||||
}
|
||||
else {
|
||||
cfra = float(scene->r.cfra);
|
||||
}
|
||||
const float cfra = ANIM_nla_tweakedit_remap(ale, float(scene->r.cfra), NLATIME_CONVERT_UNMAP);
|
||||
|
||||
switch (ale->type) {
|
||||
case ANIMTYPE_FCURVE:
|
||||
case ANIMTYPE_NLACURVE:
|
||||
adt_count = count_fcurve_keys(
|
||||
ale_count = count_fcurve_keys(
|
||||
static_cast<FCurve *>(ale->key_data), t->frame_side, cfra, is_prop_edit);
|
||||
break;
|
||||
case ANIMTYPE_GPLAYER:
|
||||
adt_count = count_gplayer_frames(
|
||||
ale_count = count_gplayer_frames(
|
||||
static_cast<bGPDlayer *>(ale->data), t->frame_side, cfra, is_prop_edit);
|
||||
break;
|
||||
case ANIMTYPE_GREASE_PENCIL_LAYER: {
|
||||
using namespace blender::bke::greasepencil;
|
||||
adt_count = count_grease_pencil_frames(
|
||||
ale_count = count_grease_pencil_frames(
|
||||
static_cast<Layer *>(ale->data), t->frame_side, cfra, is_prop_edit, use_duplicated);
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_MASKLAYER:
|
||||
adt_count = count_masklayer_frames(
|
||||
ale_count = count_masklayer_frames(
|
||||
static_cast<MaskLayer *>(ale->data), t->frame_side, cfra, is_prop_edit);
|
||||
break;
|
||||
case ANIMTYPE_NONE:
|
||||
@ -763,11 +759,11 @@ static void createTransActionData(bContext *C, TransInfo *t)
|
||||
break;
|
||||
}
|
||||
|
||||
if (adt_count > 0) {
|
||||
if (ale_count > 0) {
|
||||
if (ELEM(ale->type, ANIMTYPE_GPLAYER, ANIMTYPE_MASKLAYER)) {
|
||||
gpf_count += adt_count;
|
||||
gpf_count += ale_count;
|
||||
}
|
||||
count += adt_count;
|
||||
count += ale_count;
|
||||
ale->tag = true;
|
||||
}
|
||||
}
|
||||
@ -798,15 +794,7 @@ static void createTransActionData(bContext *C, TransInfo *t)
|
||||
continue;
|
||||
}
|
||||
|
||||
cfra = float(scene->r.cfra);
|
||||
|
||||
{
|
||||
AnimData *adt;
|
||||
adt = ANIM_nla_mapping_get(&ac, ale);
|
||||
if (adt) {
|
||||
cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
|
||||
}
|
||||
}
|
||||
const float cfra = ANIM_nla_tweakedit_remap(ale, float(scene->r.cfra), NLATIME_CONVERT_UNMAP);
|
||||
|
||||
if (ale->type == ANIMTYPE_GPLAYER) {
|
||||
bGPDlayer *gpl = (bGPDlayer *)ale->data;
|
||||
@ -836,10 +824,8 @@ static void createTransActionData(bContext *C, TransInfo *t)
|
||||
td2d += i;
|
||||
}
|
||||
else {
|
||||
AnimData *adt = ANIM_nla_mapping_get(&ac, ale);
|
||||
FCurve *fcu = (FCurve *)ale->key_data;
|
||||
|
||||
td = ActionFCurveToTransData(td, &td2d, fcu, adt, t->frame_side, cfra, is_prop_edit, ypos);
|
||||
td = ActionFCurveToTransData(td, &td2d, fcu, ale, t->frame_side, cfra, is_prop_edit, ypos);
|
||||
}
|
||||
}
|
||||
|
||||
@ -848,20 +834,13 @@ static void createTransActionData(bContext *C, TransInfo *t)
|
||||
td = tc->data;
|
||||
|
||||
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
|
||||
AnimData *adt;
|
||||
|
||||
/* F-Curve may not have any keyframes. */
|
||||
if (!ale->tag) {
|
||||
continue;
|
||||
}
|
||||
|
||||
adt = ANIM_nla_mapping_get(&ac, ale);
|
||||
if (adt) {
|
||||
cfra = BKE_nla_tweakedit_remap(adt, float(scene->r.cfra), NLATIME_CONVERT_UNMAP);
|
||||
}
|
||||
else {
|
||||
cfra = float(scene->r.cfra);
|
||||
}
|
||||
const float cfra = ANIM_nla_tweakedit_remap(
|
||||
ale, float(scene->r.cfra), NLATIME_CONVERT_UNMAP);
|
||||
|
||||
if (ale->type == ANIMTYPE_GPLAYER) {
|
||||
bGPDlayer *gpl = (bGPDlayer *)ale->data;
|
||||
@ -1214,20 +1193,13 @@ static void posttrans_action_clean(bAnimContext *ac, bAction *act)
|
||||
* - all keyframes are converted in/out of global time.
|
||||
*/
|
||||
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
|
||||
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
|
||||
|
||||
if (adt) {
|
||||
ANIM_nla_mapping_apply_fcurve(adt, static_cast<FCurve *>(ale->key_data), false, false);
|
||||
BKE_fcurve_merge_duplicate_keys(static_cast<FCurve *>(ale->key_data),
|
||||
SELECT,
|
||||
false); /* Only use handles in graph editor. */
|
||||
ANIM_nla_mapping_apply_fcurve(adt, static_cast<FCurve *>(ale->key_data), true, false);
|
||||
}
|
||||
else {
|
||||
BKE_fcurve_merge_duplicate_keys(static_cast<FCurve *>(ale->key_data),
|
||||
SELECT,
|
||||
false); /* Only use handles in graph editor. */
|
||||
}
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(
|
||||
ale, static_cast<FCurve *>(ale->key_data), false, false);
|
||||
BKE_fcurve_merge_duplicate_keys(static_cast<FCurve *>(ale->key_data),
|
||||
SELECT,
|
||||
false); /* Only use handles in graph editor. */
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(
|
||||
ale, static_cast<FCurve *>(ale->key_data), true, false);
|
||||
}
|
||||
|
||||
/* Free temp data. */
|
||||
@ -1265,7 +1237,6 @@ static void special_aftertrans_update__actedit(bContext *C, TransInfo *t)
|
||||
break;
|
||||
|
||||
case ALE_FCURVE: {
|
||||
AnimData *adt = ANIM_nla_mapping_get(&ac, ale);
|
||||
FCurve *fcu = (FCurve *)ale->key_data;
|
||||
|
||||
/* 3 cases here for curve cleanups:
|
||||
@ -1276,16 +1247,10 @@ static void special_aftertrans_update__actedit(bContext *C, TransInfo *t)
|
||||
* but we made duplicates, so get rid of these.
|
||||
*/
|
||||
if ((saction->flag & SACTION_NOTRANSKEYCULL) == 0 && ((canceled == 0) || (duplicate))) {
|
||||
if (adt) {
|
||||
ANIM_nla_mapping_apply_fcurve(adt, fcu, false, false);
|
||||
BKE_fcurve_merge_duplicate_keys(
|
||||
fcu, SELECT, false); /* Only use handles in graph editor. */
|
||||
ANIM_nla_mapping_apply_fcurve(adt, fcu, true, false);
|
||||
}
|
||||
else {
|
||||
BKE_fcurve_merge_duplicate_keys(
|
||||
fcu, SELECT, false); /* Only use handles in graph editor. */
|
||||
}
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(ale, fcu, false, false);
|
||||
BKE_fcurve_merge_duplicate_keys(
|
||||
fcu, SELECT, false); /* Only use handles in graph editor. */
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(ale, fcu, true, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ struct TransDataGraph {
|
||||
static void bezt_to_transdata(TransData *td,
|
||||
TransData2D *td2d,
|
||||
TransDataGraph *tdg,
|
||||
AnimData *adt,
|
||||
bAnimListElem *ale,
|
||||
BezTriple *bezt,
|
||||
int bi,
|
||||
bool selected,
|
||||
@ -67,14 +67,14 @@ static void bezt_to_transdata(TransData *td,
|
||||
* and then that mapping will be undone after transform is done.
|
||||
*/
|
||||
|
||||
if (adt) {
|
||||
td2d->loc[0] = BKE_nla_tweakedit_remap(adt, loc[0], NLATIME_CONVERT_MAP);
|
||||
if (ANIM_nla_mapping_allowed(ale)) {
|
||||
td2d->loc[0] = ANIM_nla_tweakedit_remap(ale, loc[0], NLATIME_CONVERT_MAP);
|
||||
td2d->loc[1] = (loc[1] + offset) * unit_scale;
|
||||
td2d->loc[2] = 0.0f;
|
||||
td2d->loc2d = loc;
|
||||
|
||||
td->loc = td2d->loc;
|
||||
td->center[0] = BKE_nla_tweakedit_remap(adt, cent[0], NLATIME_CONVERT_MAP);
|
||||
td->center[0] = ANIM_nla_tweakedit_remap(ale, cent[0], NLATIME_CONVERT_MAP);
|
||||
td->center[1] = (cent[1] + offset) * unit_scale;
|
||||
td->center[2] = 0.0f;
|
||||
|
||||
@ -109,8 +109,16 @@ static void bezt_to_transdata(TransData *td,
|
||||
td->ext = nullptr;
|
||||
td->val = nullptr;
|
||||
|
||||
/* Store AnimData info in td->extra, for applying mapping when flushing. */
|
||||
td->extra = adt;
|
||||
/* Store AnimData info in td->extra, for applying mapping when flushing.
|
||||
*
|
||||
* We do this conditionally as a hacky way of indicating whether NLA remapping
|
||||
* should be done. This is left over from old code, most of which was changed
|
||||
* in #130440 to avoid using `adt == nullptr` as an indicator for that. This
|
||||
* was left that way because updating it cleanly was more involved than made
|
||||
* sense for the bug fix in #130440. */
|
||||
if (ANIM_nla_mapping_allowed(ale)) {
|
||||
td->extra = ale->adt;
|
||||
}
|
||||
|
||||
if (selected) {
|
||||
td->flag |= TD_SELECTED;
|
||||
@ -281,7 +289,6 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
blender::Set<FCurve *> visited_fcurves;
|
||||
blender::Vector<bAnimListElem *> unique_fcu_anim_list_elements;
|
||||
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
|
||||
AnimData *adt = ANIM_nla_mapping_get(&ac, ale);
|
||||
FCurve *fcu = (FCurve *)ale->key_data;
|
||||
/* If 2 or more objects share the same action, multiple bAnimListElem might reference the same
|
||||
* FCurve. */
|
||||
@ -289,7 +296,6 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
continue;
|
||||
}
|
||||
unique_fcu_anim_list_elements.append(ale);
|
||||
float cfra;
|
||||
int curvecount = 0;
|
||||
bool selected = false;
|
||||
|
||||
@ -300,12 +306,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
|
||||
/* Convert current-frame to action-time (slightly less accurate, especially under
|
||||
* higher scaling ratios, but is faster than converting all points). */
|
||||
if (adt) {
|
||||
cfra = BKE_nla_tweakedit_remap(adt, float(scene->r.cfra), NLATIME_CONVERT_UNMAP);
|
||||
}
|
||||
else {
|
||||
cfra = float(scene->r.cfra);
|
||||
}
|
||||
const float cfra = ANIM_nla_tweakedit_remap(ale, float(scene->r.cfra), NLATIME_CONVERT_UNMAP);
|
||||
|
||||
for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
|
||||
/* Only include BezTriples whose 'keyframe'
|
||||
@ -396,11 +397,9 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
|
||||
/* Loop 2: build transdata arrays. */
|
||||
for (bAnimListElem *ale : unique_fcu_anim_list_elements) {
|
||||
AnimData *adt = ANIM_nla_mapping_get(&ac, ale);
|
||||
FCurve *fcu = (FCurve *)ale->key_data;
|
||||
bool intvals = (fcu->flag & FCURVE_INT_VALUES) != 0;
|
||||
float unit_scale, offset;
|
||||
float cfra;
|
||||
|
||||
/* F-Curve may not have any keyframes. */
|
||||
if (fcu->bezt == nullptr || (is_prop_edit && ale->tag == 0)) {
|
||||
@ -409,12 +408,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
|
||||
/* Convert current-frame to action-time (slightly less accurate, especially under
|
||||
* higher scaling ratios, but is faster than converting all points). */
|
||||
if (adt) {
|
||||
cfra = BKE_nla_tweakedit_remap(adt, float(scene->r.cfra), NLATIME_CONVERT_UNMAP);
|
||||
}
|
||||
else {
|
||||
cfra = float(scene->r.cfra);
|
||||
}
|
||||
const float cfra = ANIM_nla_tweakedit_remap(ale, float(scene->r.cfra), NLATIME_CONVERT_UNMAP);
|
||||
|
||||
unit_scale = ANIM_unit_mapping_get_factor(
|
||||
ac.scene, ale->id, static_cast<FCurve *>(ale->key_data), anim_map_flag, &offset);
|
||||
@ -440,7 +434,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
bezt_to_transdata(td++,
|
||||
td2d++,
|
||||
tdg++,
|
||||
adt,
|
||||
ale,
|
||||
bezt,
|
||||
0,
|
||||
is_sel,
|
||||
@ -454,7 +448,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
bezt_to_transdata(td++,
|
||||
td2d++,
|
||||
tdg++,
|
||||
adt,
|
||||
ale,
|
||||
bezt,
|
||||
1,
|
||||
is_sel,
|
||||
@ -468,7 +462,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
bezt_to_transdata(td++,
|
||||
td2d++,
|
||||
tdg++,
|
||||
adt,
|
||||
ale,
|
||||
bezt,
|
||||
2,
|
||||
is_sel,
|
||||
@ -493,7 +487,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
bezt_to_transdata(td++,
|
||||
td2d++,
|
||||
tdg++,
|
||||
adt,
|
||||
ale,
|
||||
bezt,
|
||||
0,
|
||||
sel_left,
|
||||
@ -513,7 +507,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
bezt_to_transdata(td++,
|
||||
td2d++,
|
||||
tdg++,
|
||||
adt,
|
||||
ale,
|
||||
bezt,
|
||||
2,
|
||||
sel_right,
|
||||
@ -548,7 +542,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
bezt_to_transdata(td++,
|
||||
td2d++,
|
||||
tdg++,
|
||||
adt,
|
||||
ale,
|
||||
bezt,
|
||||
1,
|
||||
sel_key,
|
||||
@ -588,10 +582,8 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
td = tc->data;
|
||||
|
||||
for (bAnimListElem *ale : unique_fcu_anim_list_elements) {
|
||||
AnimData *adt = ANIM_nla_mapping_get(&ac, ale);
|
||||
FCurve *fcu = (FCurve *)ale->key_data;
|
||||
TransData *td_start = td;
|
||||
float cfra;
|
||||
|
||||
/* F-Curve may not have any keyframes. */
|
||||
if (fcu->bezt == nullptr || (ale->tag == 0)) {
|
||||
@ -600,12 +592,8 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
|
||||
/* Convert current-frame to action-time (slightly less accurate, especially under
|
||||
* higher scaling ratios, but is faster than converting all points). */
|
||||
if (adt) {
|
||||
cfra = BKE_nla_tweakedit_remap(adt, float(scene->r.cfra), NLATIME_CONVERT_UNMAP);
|
||||
}
|
||||
else {
|
||||
cfra = float(scene->r.cfra);
|
||||
}
|
||||
const float cfra = ANIM_nla_tweakedit_remap(
|
||||
ale, float(scene->r.cfra), NLATIME_CONVERT_UNMAP);
|
||||
|
||||
for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
|
||||
/* Only include BezTriples whose 'keyframe' occurs on the
|
||||
@ -1010,7 +998,6 @@ static void special_aftertrans_update__graph(bContext *C, TransInfo *t)
|
||||
&ac, &anim_data, eAnimFilter_Flags(filter), ac.data, eAnimCont_Types(ac.datatype));
|
||||
|
||||
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
|
||||
AnimData *adt = ANIM_nla_mapping_get(&ac, ale);
|
||||
FCurve *fcu = (FCurve *)ale->key_data;
|
||||
|
||||
/* 3 cases here for curve cleanups:
|
||||
@ -1021,14 +1008,9 @@ static void special_aftertrans_update__graph(bContext *C, TransInfo *t)
|
||||
* but we made duplicates, so get rid of these.
|
||||
*/
|
||||
if ((sipo->flag & SIPO_NOTRANSKEYCULL) == 0 && ((canceled == 0) || (duplicate))) {
|
||||
if (adt) {
|
||||
ANIM_nla_mapping_apply_fcurve(adt, fcu, false, false);
|
||||
BKE_fcurve_merge_duplicate_keys(fcu, BEZT_FLAG_TEMP_TAG, use_handle);
|
||||
ANIM_nla_mapping_apply_fcurve(adt, fcu, true, false);
|
||||
}
|
||||
else {
|
||||
BKE_fcurve_merge_duplicate_keys(fcu, BEZT_FLAG_TEMP_TAG, use_handle);
|
||||
}
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(ale, fcu, false, false);
|
||||
BKE_fcurve_merge_duplicate_keys(fcu, BEZT_FLAG_TEMP_TAG, use_handle);
|
||||
ANIM_nla_mapping_apply_if_needed_fcurve(ale, fcu, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1184,6 +1184,8 @@ typedef struct ActionSlot {
|
||||
*
|
||||
* Only valid within the Action that owns this Slot.
|
||||
*
|
||||
* NOTE: keep this type in sync with `slot_handle_t` in BKE_action.hh.
|
||||
*
|
||||
* \see #blender::animrig::Action::slot_for_handle()
|
||||
*/
|
||||
int32_t handle;
|
||||
|
Loading…
Reference in New Issue
Block a user