Refactor: move FCurve baking code to animrig #120984
|
@ -89,4 +89,31 @@ int insert_vert_fcurve(FCurve *fcu,
|
|||
const KeyframeSettings &settings,
|
||||
eInsertKeyFlags flag);
|
||||
|
||||
/**
|
||||
* \param sample_rate: indicates how many samples per frame should be generated.
|
||||
* \param r_samples: Is expected to be an array large enough to hold `sample_count`.
|
||||
*/
|
||||
void sample_fcurve_segment(
|
||||
|
||||
FCurve *fcu, float start_frame, float sample_rate, float *samples, int sample_count);
|
||||
|
||||
enum class BakeCurveRemove {
|
||||
REMOVE_NONE = 0,
|
||||
REMOVE_IN_RANGE = 1,
|
||||
REMOVE_OUT_RANGE = 2,
|
||||
REMOVE_ALL = 3,
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates keyframes in the given range at the given step interval.
|
||||
* \param range: start and end frame to bake. Is inclusive on both ends.
|
||||
* \param remove_existing: choice which keys to remove in relation to the given range.
|
||||
*/
|
||||
void bake_fcurve(FCurve *fcu, blender::int2 range, float step, BakeCurveRemove remove_existing);
|
||||
|
||||
/**
|
||||
* Fill the space between selected keyframes with keyframes on full frames.
|
||||
* E.g. With a key selected on frame 1 and 3 it will insert a key on frame 2.
|
||||
*/
|
||||
void bake_fcurve_segments(FCurve *fcu);
|
||||
|
||||
} // namespace blender::animrig
|
||||
|
|
|
@ -326,4 +326,195 @@ int insert_vert_fcurve(FCurve *fcu,
|
|||
return a;
|
||||
}
|
||||
|
||||
void sample_fcurve_segment(FCurve *fcu,
|
||||
const float start_frame,
|
||||
const float sample_rate,
|
||||
float *samples,
|
||||
const int sample_count)
|
||||
{
|
||||
for (int i = 0; i < sample_count; i++) {
|
||||
const float evaluation_time = start_frame + (float(i) / sample_rate);
|
||||
samples[i] = evaluate_fcurve(fcu, evaluation_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void remove_fcurve_key_range(FCurve *fcu,
|
||||
const int2 range,
|
||||
const BakeCurveRemove removal_mode)
|
||||
{
|
||||
switch (removal_mode) {
|
||||
|
||||
case BakeCurveRemove::REMOVE_ALL: {
|
||||
BKE_fcurve_delete_keys_all(fcu);
|
||||
break;
|
||||
}
|
||||
|
||||
case BakeCurveRemove::REMOVE_OUT_RANGE: {
|
||||
bool replace;
|
||||
|
||||
int before_index = BKE_fcurve_bezt_binarysearch_index(
|
||||
fcu->bezt, range[0], fcu->totvert, &replace);
|
||||
|
||||
if (before_index > 0) {
|
||||
BKE_fcurve_delete_keys(fcu, {0, uint(before_index)});
|
||||
}
|
||||
|
||||
int after_index = BKE_fcurve_bezt_binarysearch_index(
|
||||
fcu->bezt, range[1], fcu->totvert, &replace);
|
||||
/* #REMOVE_OUT_RANGE is treated as exclusive on both ends. */
|
||||
if (replace) {
|
||||
after_index++;
|
||||
}
|
||||
if (after_index < fcu->totvert) {
|
||||
BKE_fcurve_delete_keys(fcu, {uint(after_index), fcu->totvert});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case BakeCurveRemove::REMOVE_IN_RANGE: {
|
||||
bool replace;
|
||||
const int range_start_index = BKE_fcurve_bezt_binarysearch_index(
|
||||
fcu->bezt, range[0], fcu->totvert, &replace);
|
||||
int range_end_index = BKE_fcurve_bezt_binarysearch_index(
|
||||
fcu->bezt, range[1], fcu->totvert, &replace);
|
||||
if (replace) {
|
||||
range_end_index++;
|
||||
}
|
||||
|
||||
if (range_end_index > range_start_index) {
|
||||
BKE_fcurve_delete_keys(fcu, {uint(range_start_index), uint(range_end_index)});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void bake_fcurve(FCurve *fcu,
|
||||
const int2 range,
|
||||
const float step,
|
||||
const BakeCurveRemove remove_existing)
|
||||
{
|
||||
BLI_assert(step > 0);
|
||||
const int sample_count = (range[1] - range[0]) / step + 1;
|
||||
float *samples = static_cast<float *>(
|
||||
MEM_callocN(sample_count * sizeof(float), "Channel Bake Samples"));
|
||||
const float sample_rate = 1.0f / step;
|
||||
sample_fcurve_segment(fcu, range[0], sample_rate, samples, sample_count);
|
||||
|
||||
if (remove_existing != BakeCurveRemove::REMOVE_NONE) {
|
||||
remove_fcurve_key_range(fcu, range, remove_existing);
|
||||
}
|
||||
|
||||
BezTriple *baked_keys = static_cast<BezTriple *>(
|
||||
MEM_callocN(sample_count * sizeof(BezTriple), "beztriple"));
|
||||
|
||||
const KeyframeSettings settings = get_keyframe_settings(true);
|
||||
|
||||
for (int i = 0; i < sample_count; i++) {
|
||||
BezTriple *key = &baked_keys[i];
|
||||
float2 key_position = {range[0] + i * step, samples[i]};
|
||||
initialize_bezt(key, key_position, settings, eFCurve_Flags(fcu->flag));
|
||||
}
|
||||
|
||||
int merged_size;
|
||||
BezTriple *merged_bezt = BKE_bezier_array_merge(
|
||||
baked_keys, sample_count, fcu->bezt, fcu->totvert, &merged_size);
|
||||
|
||||
if (fcu->bezt != nullptr) {
|
||||
/* Can happen if we removed all keys beforehand. */
|
||||
MEM_freeN(fcu->bezt);
|
||||
}
|
||||
MEM_freeN(baked_keys);
|
||||
fcu->bezt = merged_bezt;
|
||||
fcu->totvert = merged_size;
|
||||
|
||||
MEM_freeN(samples);
|
||||
BKE_fcurve_handles_recalc(fcu);
|
||||
}
|
||||
|
||||
struct TempFrameValCache {
|
||||
float frame, val;
|
||||
};
|
||||
|
||||
void bake_fcurve_segments(FCurve *fcu)
|
||||
{
|
||||
BezTriple *bezt, *start = nullptr, *end = nullptr;
|
||||
TempFrameValCache *value_cache, *fp;
|
||||
int sfra, range;
|
||||
int i, n;
|
||||
|
||||
if (fcu->bezt == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
KeyframeSettings settings = get_keyframe_settings(true);
|
||||
settings.keyframe_type = BEZT_KEYTYPE_BREAKDOWN;
|
||||
|
||||
/* Find selected keyframes... once pair has been found, add keyframes. */
|
||||
for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
|
||||
/* check if selected, and which end this is */
|
||||
if (BEZT_ISSEL_ANY(bezt)) {
|
||||
if (start) {
|
||||
/* If next bezt is also selected, don't start sampling yet,
|
||||
* but instead wait for that one to reconsider, to avoid
|
||||
* changing the curve when sampling consecutive segments
|
||||
* (#53229)
|
||||
*/
|
||||
if (i < fcu->totvert - 1) {
|
||||
BezTriple *next = &fcu->bezt[i + 1];
|
||||
if (BEZT_ISSEL_ANY(next)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
end = bezt;
|
||||
|
||||
/* Cache values then add keyframes using these values, as adding
|
||||
* keyframes while sampling will affect the outcome...
|
||||
* - Only start sampling+adding from index=1, so that we don't overwrite original keyframe.
|
||||
*/
|
||||
range = int(ceil(end->vec[1][0] - start->vec[1][0]));
|
||||
sfra = int(floor(start->vec[1][0]));
|
||||
|
||||
if (range) {
|
||||
value_cache = static_cast<TempFrameValCache *>(
|
||||
MEM_callocN(sizeof(TempFrameValCache) * range, "IcuFrameValCache"));
|
||||
|
||||
/* Sample values. */
|
||||
for (n = 1, fp = value_cache; n < range && fp; n++, fp++) {
|
||||
fp->frame = float(sfra + n);
|
||||
fp->val = evaluate_fcurve(fcu, fp->frame);
|
||||
}
|
||||
|
||||
/* Add keyframes with these, tagging as 'breakdowns'. */
|
||||
for (n = 1, fp = value_cache; n < range && fp; n++, fp++) {
|
||||
blender::animrig::insert_vert_fcurve(
|
||||
fcu, {fp->frame, fp->val}, settings, eInsertKeyFlags(1));
|
||||
}
|
||||
|
||||
MEM_freeN(value_cache);
|
||||
|
||||
/* As we added keyframes, we need to compensate so that bezt is at the right place. */
|
||||
bezt = fcu->bezt + i + range - 1;
|
||||
i += (range - 1);
|
||||
}
|
||||
|
||||
/* The current selection island has ended, so start again from scratch. */
|
||||
start = nullptr;
|
||||
end = nullptr;
|
||||
}
|
||||
else {
|
||||
/* Just set start keyframe. */
|
||||
start = bezt;
|
||||
end = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BKE_fcurve_handles_recalc(fcu);
|
||||
}
|
||||
|
||||
} // namespace blender::animrig
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
#include "ED_select_utils.hh"
|
||||
|
||||
#include "ANIM_animdata.hh"
|
||||
#include "ANIM_fcurve.hh"
|
||||
|
||||
#include "WM_api.hh"
|
||||
#include "WM_types.hh"
|
||||
|
@ -4333,6 +4334,7 @@ static const EnumPropertyItem channel_bake_key_options[] = {
|
|||
|
||||
static int channels_bake_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
using namespace blender::animrig;
|
||||
bAnimContext ac;
|
||||
|
||||
/* Get editor data. */
|
||||
|
|
|
@ -1223,209 +1223,6 @@ void smooth_fcurve(FCurve *fcu)
|
|||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name FCurve Sample
|
||||
* \{ */
|
||||
|
||||
/* little cache for values... */
|
||||
struct TempFrameValCache {
|
||||
float frame, val;
|
||||
};
|
||||
|
||||
void sample_fcurve_segment(FCurve *fcu,
|
||||
const float start_frame,
|
||||
const float sample_rate,
|
||||
float *samples,
|
||||
const int sample_count)
|
||||
{
|
||||
for (int i = 0; i < sample_count; i++) {
|
||||
const float evaluation_time = start_frame + (float(i) / sample_rate);
|
||||
samples[i] = evaluate_fcurve(fcu, evaluation_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void remove_fcurve_key_range(FCurve *fcu,
|
||||
const blender::int2 range,
|
||||
const BakeCurveRemove removal_mode)
|
||||
{
|
||||
switch (removal_mode) {
|
||||
|
||||
case BakeCurveRemove::REMOVE_ALL: {
|
||||
BKE_fcurve_delete_keys_all(fcu);
|
||||
break;
|
||||
}
|
||||
|
||||
case BakeCurveRemove::REMOVE_OUT_RANGE: {
|
||||
bool replace;
|
||||
|
||||
int before_index = BKE_fcurve_bezt_binarysearch_index(
|
||||
fcu->bezt, range[0], fcu->totvert, &replace);
|
||||
|
||||
if (before_index > 0) {
|
||||
BKE_fcurve_delete_keys(fcu, {0, uint(before_index)});
|
||||
}
|
||||
|
||||
int after_index = BKE_fcurve_bezt_binarysearch_index(
|
||||
fcu->bezt, range[1], fcu->totvert, &replace);
|
||||
/* #REMOVE_OUT_RANGE is treated as exclusive on both ends. */
|
||||
if (replace) {
|
||||
after_index++;
|
||||
}
|
||||
if (after_index < fcu->totvert) {
|
||||
BKE_fcurve_delete_keys(fcu, {uint(after_index), fcu->totvert});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case BakeCurveRemove::REMOVE_IN_RANGE: {
|
||||
bool replace;
|
||||
const int range_start_index = BKE_fcurve_bezt_binarysearch_index(
|
||||
fcu->bezt, range[0], fcu->totvert, &replace);
|
||||
int range_end_index = BKE_fcurve_bezt_binarysearch_index(
|
||||
fcu->bezt, range[1], fcu->totvert, &replace);
|
||||
if (replace) {
|
||||
range_end_index++;
|
||||
}
|
||||
|
||||
if (range_end_index > range_start_index) {
|
||||
BKE_fcurve_delete_keys(fcu, {uint(range_start_index), uint(range_end_index)});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void bake_fcurve(FCurve *fcu,
|
||||
const blender::int2 range,
|
||||
const float step,
|
||||
const BakeCurveRemove remove_existing)
|
||||
{
|
||||
using namespace blender::animrig;
|
||||
BLI_assert(step > 0);
|
||||
const int sample_count = (range[1] - range[0]) / step + 1;
|
||||
float *samples = static_cast<float *>(
|
||||
MEM_callocN(sample_count * sizeof(float), "Channel Bake Samples"));
|
||||
const float sample_rate = 1.0f / step;
|
||||
sample_fcurve_segment(fcu, range[0], sample_rate, samples, sample_count);
|
||||
|
||||
if (remove_existing != BakeCurveRemove::REMOVE_NONE) {
|
||||
remove_fcurve_key_range(fcu, range, remove_existing);
|
||||
}
|
||||
|
||||
BezTriple *baked_keys = static_cast<BezTriple *>(
|
||||
MEM_callocN(sample_count * sizeof(BezTriple), "beztriple"));
|
||||
|
||||
const KeyframeSettings settings = get_keyframe_settings(true);
|
||||
|
||||
for (int i = 0; i < sample_count; i++) {
|
||||
BezTriple *key = &baked_keys[i];
|
||||
blender::float2 key_position = {range[0] + i * step, samples[i]};
|
||||
initialize_bezt(key, key_position, settings, eFCurve_Flags(fcu->flag));
|
||||
}
|
||||
|
||||
int merged_size;
|
||||
BezTriple *merged_bezt = BKE_bezier_array_merge(
|
||||
baked_keys, sample_count, fcu->bezt, fcu->totvert, &merged_size);
|
||||
|
||||
if (fcu->bezt != nullptr) {
|
||||
/* Can happen if we removed all keys beforehand. */
|
||||
MEM_freeN(fcu->bezt);
|
||||
}
|
||||
MEM_freeN(baked_keys);
|
||||
fcu->bezt = merged_bezt;
|
||||
fcu->totvert = merged_size;
|
||||
|
||||
MEM_freeN(samples);
|
||||
BKE_fcurve_handles_recalc(fcu);
|
||||
}
|
||||
|
||||
void bake_fcurve_segments(FCurve *fcu)
|
||||
{
|
||||
using namespace blender::animrig;
|
||||
BezTriple *bezt, *start = nullptr, *end = nullptr;
|
||||
TempFrameValCache *value_cache, *fp;
|
||||
int sfra, range;
|
||||
int i, n;
|
||||
|
||||
if (fcu->bezt == nullptr) { /* ignore baked */
|
||||
return;
|
||||
}
|
||||
|
||||
KeyframeSettings settings = get_keyframe_settings(true);
|
||||
settings.keyframe_type = BEZT_KEYTYPE_BREAKDOWN;
|
||||
|
||||
/* Find selected keyframes... once pair has been found, add keyframes. */
|
||||
for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
|
||||
/* check if selected, and which end this is */
|
||||
if (BEZT_ISSEL_ANY(bezt)) {
|
||||
if (start) {
|
||||
/* If next bezt is also selected, don't start sampling yet,
|
||||
* but instead wait for that one to reconsider, to avoid
|
||||
* changing the curve when sampling consecutive segments
|
||||
* (#53229)
|
||||
*/
|
||||
if (i < fcu->totvert - 1) {
|
||||
BezTriple *next = &fcu->bezt[i + 1];
|
||||
if (BEZT_ISSEL_ANY(next)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* set end */
|
||||
end = bezt;
|
||||
|
||||
/* cache values then add keyframes using these values, as adding
|
||||
* keyframes while sampling will affect the outcome...
|
||||
* - only start sampling+adding from index=1, so that we don't overwrite original keyframe
|
||||
*/
|
||||
range = int(ceil(end->vec[1][0] - start->vec[1][0]));
|
||||
sfra = int(floor(start->vec[1][0]));
|
||||
|
||||
if (range) {
|
||||
value_cache = static_cast<TempFrameValCache *>(
|
||||
MEM_callocN(sizeof(TempFrameValCache) * range, "IcuFrameValCache"));
|
||||
|
||||
/* sample values */
|
||||
for (n = 1, fp = value_cache; n < range && fp; n++, fp++) {
|
||||
fp->frame = float(sfra + n);
|
||||
fp->val = evaluate_fcurve(fcu, fp->frame);
|
||||
}
|
||||
|
||||
/* add keyframes with these, tagging as 'breakdowns' */
|
||||
for (n = 1, fp = value_cache; n < range && fp; n++, fp++) {
|
||||
blender::animrig::insert_vert_fcurve(
|
||||
fcu, {fp->frame, fp->val}, settings, eInsertKeyFlags(1));
|
||||
}
|
||||
|
||||
/* free temp cache */
|
||||
MEM_freeN(value_cache);
|
||||
|
||||
/* as we added keyframes, we need to compensate so that bezt is at the right place */
|
||||
bezt = fcu->bezt + i + range - 1;
|
||||
i += (range - 1);
|
||||
}
|
||||
|
||||
/* the current selection island has ended, so start again from scratch */
|
||||
start = nullptr;
|
||||
end = nullptr;
|
||||
}
|
||||
else {
|
||||
/* just set start keyframe */
|
||||
start = bezt;
|
||||
end = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* recalculate channel's handles? */
|
||||
BKE_fcurve_handles_recalc(fcu);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Copy/Paste Tools
|
||||
*
|
||||
|
|
|
@ -511,24 +511,6 @@ void blend_to_default_fcurve(PointerRNA *id_ptr, FCurve *fcu, float factor);
|
|||
* Use a weighted moving-means method to reduce intensity of fluctuations.
|
||||
*/
|
||||
void smooth_fcurve(FCurve *fcu);
|
||||
void bake_fcurve_segments(FCurve *fcu);
|
||||
/**
|
||||
* \param sample_rate: indicates how many samples per frame should be generated.
|
||||
*/
|
||||
void sample_fcurve_segment(
|
||||
FCurve *fcu, float start_frame, float sample_rate, float *r_samples, int sample_count);
|
||||
|
||||
enum class BakeCurveRemove {
|
||||
REMOVE_NONE = 0,
|
||||
REMOVE_IN_RANGE = 1,
|
||||
REMOVE_OUT_RANGE = 2,
|
||||
REMOVE_ALL = 3,
|
||||
};
|
||||
/** Creates keyframes in the given range at the given step interval.
|
||||
* \param range: start and end frame to bake. Is inclusive on both ends.
|
||||
* \param remove_existing: choice which keys to remove in relation to the given range.
|
||||
*/
|
||||
void bake_fcurve(FCurve *fcu, blender::int2 range, float step, BakeCurveRemove remove_existing);
|
||||
|
||||
/* ----------- */
|
||||
|
||||
|
|
|
@ -1300,7 +1300,7 @@ static void bake_action_keys(bAnimContext *ac)
|
|||
|
||||
/* Loop through filtered data and add keys between selected keyframes on every frame. */
|
||||
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
|
||||
bake_fcurve_segments((FCurve *)ale->key_data);
|
||||
blender::animrig::bake_fcurve_segments((FCurve *)ale->key_data);
|
||||
|
||||
ale->update |= ANIM_UPDATE_DEPS;
|
||||
}
|
||||
|
|
|
@ -1337,7 +1337,7 @@ static void bake_graph_keys(bAnimContext *ac)
|
|||
|
||||
/* Loop through filtered data and add keys between selected keyframes on every frame. */
|
||||
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
|
||||
bake_fcurve_segments((FCurve *)ale->key_data);
|
||||
blender::animrig::bake_fcurve_segments((FCurve *)ale->key_data);
|
||||
|
||||
ale->update |= ANIM_UPDATE_DEPS;
|
||||
}
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
#include "WM_api.hh"
|
||||
#include "WM_types.hh"
|
||||
|
||||
#include "ANIM_fcurve.hh"
|
||||
|
||||
#include "graph_intern.hh"
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@ -1836,7 +1838,8 @@ static void gaussian_smooth_allocate_operator_data(tGraphSliderOp *gso,
|
|||
(filter_width * 2 + 1);
|
||||
float *samples = static_cast<float *>(
|
||||
MEM_callocN(sizeof(float) * sample_count, "Smooth FCurve Op Samples"));
|
||||
sample_fcurve_segment(fcu, left_bezt.vec[1][0] - filter_width, 1, samples, sample_count);
|
||||
blender::animrig::sample_fcurve_segment(
|
||||
fcu, left_bezt.vec[1][0] - filter_width, 1, samples, sample_count);
|
||||
segment_link->samples = samples;
|
||||
BLI_addtail(&segment_links, segment_link);
|
||||
}
|
||||
|
@ -1938,7 +1941,8 @@ static void gaussian_smooth_graph_keys(bAnimContext *ac,
|
|||
(filter_width * 2 + 1);
|
||||
float *samples = static_cast<float *>(
|
||||
MEM_callocN(sizeof(float) * sample_count, "Smooth FCurve Op Samples"));
|
||||
sample_fcurve_segment(fcu, left_bezt.vec[1][0] - filter_width, 1, samples, sample_count);
|
||||
blender::animrig::sample_fcurve_segment(
|
||||
fcu, left_bezt.vec[1][0] - filter_width, 1, samples, sample_count);
|
||||
smooth_fcurve_segment(fcu, segment, samples, factor, filter_width, kernel);
|
||||
MEM_freeN(samples);
|
||||
}
|
||||
|
@ -2077,7 +2081,7 @@ static void btw_smooth_allocate_operator_data(tGraphSliderOp *gso,
|
|||
&right_bezt, &left_bezt, filter_order, samples_per_frame);
|
||||
float *samples = static_cast<float *>(
|
||||
MEM_callocN(sizeof(float) * sample_count, "Btw Smooth FCurve Op Samples"));
|
||||
sample_fcurve_segment(
|
||||
blender::animrig::sample_fcurve_segment(
|
||||
fcu, left_bezt.vec[1][0] - filter_order, samples_per_frame, samples, sample_count);
|
||||
segment_link->samples = samples;
|
||||
segment_link->sample_count = sample_count;
|
||||
|
@ -2206,7 +2210,7 @@ static void btw_smooth_graph_keys(bAnimContext *ac,
|
|||
&right_bezt, &left_bezt, filter_order, samples_per_frame);
|
||||
float *samples = static_cast<float *>(
|
||||
MEM_callocN(sizeof(float) * sample_count, "Smooth FCurve Op Samples"));
|
||||
sample_fcurve_segment(
|
||||
blender::animrig::sample_fcurve_segment(
|
||||
fcu, left_bezt.vec[1][0] - filter_order, samples_per_frame, samples, sample_count);
|
||||
butterworth_smooth_fcurve_segment(
|
||||
fcu, segment, samples, sample_count, factor, blend_in_out, samples_per_frame, bw_coeff);
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
|
||||
#include "DNA_anim_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "ED_keyframes_edit.hh"
|
||||
|
||||
#include "ANIM_fcurve.hh"
|
||||
|
||||
#include "rna_internal.hh" /* own include */
|
||||
|
||||
|
@ -72,6 +73,7 @@ static void rna_FCurve_bake(FCurve *fcu,
|
|||
float step,
|
||||
int remove_existing_as_int)
|
||||
{
|
||||
using namespace blender::animrig;
|
||||
if (start_frame >= end_frame) {
|
||||
BKE_reportf(reports,
|
||||
RPT_ERROR,
|
||||
|
@ -89,18 +91,22 @@ static void rna_FCurve_bake(FCurve *fcu,
|
|||
#else
|
||||
|
||||
static const EnumPropertyItem channel_bake_remove_options[] = {
|
||||
{int(BakeCurveRemove::REMOVE_NONE), "NONE", 0, "None", "Keep all keys"},
|
||||
{int(BakeCurveRemove::REMOVE_IN_RANGE),
|
||||
{int(blender::animrig::BakeCurveRemove::REMOVE_NONE), "NONE", 0, "None", "Keep all keys"},
|
||||
{int(blender::animrig::BakeCurveRemove::REMOVE_IN_RANGE),
|
||||
"IN_RANGE",
|
||||
0,
|
||||
"In Range",
|
||||
"Remove all keys within the defined range"},
|
||||
{int(BakeCurveRemove::REMOVE_OUT_RANGE),
|
||||
{int(blender::animrig::BakeCurveRemove::REMOVE_OUT_RANGE),
|
||||
"OUT_RANGE",
|
||||
0,
|
||||
"Outside Range",
|
||||
"Remove all keys outside the defined range"},
|
||||
{int(BakeCurveRemove::REMOVE_ALL), "ALL", 0, "All", "Remove all existing keys"},
|
||||
{int(blender::animrig::BakeCurveRemove::REMOVE_ALL),
|
||||
"ALL",
|
||||
0,
|
||||
"All",
|
||||
"Remove all existing keys"},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
|
@ -160,7 +166,7 @@ void RNA_api_fcurves(StructRNA *srna)
|
|||
RNA_def_enum(func,
|
||||
"remove",
|
||||
channel_bake_remove_options,
|
||||
int(BakeCurveRemove::REMOVE_IN_RANGE),
|
||||
int(blender::animrig::BakeCurveRemove::REMOVE_IN_RANGE),
|
||||
"Remove Options",
|
||||
"Choose which keys should be automatically removed by the bake");
|
||||
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_PYFUNC_OPTIONAL);
|
||||
|
|
Loading…
Reference in New Issue
r_samples
has another name (samples
) in the function definition. These should be consistent. I thinksamples
is actually better. If it were to be namedr_samples
, I'd expect it to receive a single float (as that would be the typical use for afloat *
return parameter).Probably also good to document that
samples
is expected to be an array that's large enough to holdsample_count
values.