2011-02-23 10:52:22 +00:00
|
|
|
/*
|
2009-07-02 04:47:36 +00:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
2018-06-01 18:19:39 +02:00
|
|
|
* of the License, or (at your option) any later version.
|
2009-07-02 04:47:36 +00:00
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
2010-02-12 13:34:04 +00:00
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2009-07-02 04:47:36 +00:00
|
|
|
*
|
|
|
|
* The Original Code is Copyright (C) 2009 Blender Foundation.
|
|
|
|
* All rights reserved.
|
|
|
|
*/
|
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
* \ingroup edanimation
|
2011-02-27 20:29:51 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
/* User-Interface Stuff for F-Modifiers:
|
2018-06-01 18:19:39 +02:00
|
|
|
* This file defines the (C-Coded) templates + editing callbacks needed
|
2009-07-02 04:47:36 +00:00
|
|
|
* by the interface stuff or F-Modifiers, as used by F-Curves in the Graph Editor,
|
|
|
|
* and NLA-Strips in the NLA Editor.
|
2010-03-18 13:04:46 +00:00
|
|
|
*
|
|
|
|
* Copy/Paste Buffer for F-Modifiers:
|
2018-06-01 18:19:39 +02:00
|
|
|
* For now, this is also defined in this file so that it can be shared between the
|
2009-07-02 04:47:36 +00:00
|
|
|
*/
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "DNA_anim_types.h"
|
|
|
|
#include "DNA_scene_types.h"
|
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
2015-08-16 17:32:01 +10:00
|
|
|
#include "BLT_translation.h"
|
2012-03-03 21:42:21 +00:00
|
|
|
|
More F-Modifier Tweaks:
This commit started out aiming to make the "Stepped" F-Modifier (committed last night) even more useful, but ended up fixing a few other finer-points of how F-Modifiers work.
Firstly, the new stuff:
I've addded options to the Stepped F-Modifier to not affect frames before and/or after specified values, and renamed the 'start offset' to 'offset' for clarity.
The main objective of this is to allow Stepped F-Modifiers to only affect certain time ranges, so that by layering/using multiple instances of the F-Modifier, it can be possible to have multiple stepping-sizes.
This allows for effects like:
http://www.pasteall.org/blend/2230
or in words, it provides a convenient mechanism for animators to specify whether sections of the animation is shown "on twos", "fours", or even "forty-second-ths plus a smidgen", as can be easily done with 2D.
Assorted changes to support this:
* Properly fixed up how F-Modifiers that work with time, evaluate the time to evaluate the curve at. Now layered time effects like this should be possible in a much nicer way.
* Added proper value range validation/clamping to many properties. There are still a lot more that need checking, but at least more properties now do "the right thing".
2010-03-19 03:38:14 +00:00
|
|
|
#include "BLI_blenlib.h"
|
2011-01-07 18:36:47 +00:00
|
|
|
#include "BLI_utildefines.h"
|
More F-Modifier Tweaks:
This commit started out aiming to make the "Stepped" F-Modifier (committed last night) even more useful, but ended up fixing a few other finer-points of how F-Modifiers work.
Firstly, the new stuff:
I've addded options to the Stepped F-Modifier to not affect frames before and/or after specified values, and renamed the 'start offset' to 'offset' for clarity.
The main objective of this is to allow Stepped F-Modifiers to only affect certain time ranges, so that by layering/using multiple instances of the F-Modifier, it can be possible to have multiple stepping-sizes.
This allows for effects like:
http://www.pasteall.org/blend/2230
or in words, it provides a convenient mechanism for animators to specify whether sections of the animation is shown "on twos", "fours", or even "forty-second-ths plus a smidgen", as can be easily done with 2D.
Assorted changes to support this:
* Properly fixed up how F-Modifiers that work with time, evaluate the time to evaluate the curve at. Now layered time effects like this should be possible in a much nicer way.
* Added proper value range validation/clamping to many properties. There are still a lot more that need checking, but at least more properties now do "the right thing".
2010-03-19 03:38:14 +00:00
|
|
|
|
2019-01-10 15:56:02 +01:00
|
|
|
#include "BKE_animsys.h"
|
2009-07-02 04:47:36 +00:00
|
|
|
#include "BKE_context.h"
|
|
|
|
#include "BKE_fcurve.h"
|
|
|
|
|
|
|
|
#include "WM_api.h"
|
|
|
|
#include "WM_types.h"
|
|
|
|
|
|
|
|
#include "RNA_access.h"
|
|
|
|
|
|
|
|
#include "UI_interface.h"
|
|
|
|
#include "UI_resources.h"
|
|
|
|
|
2011-02-14 17:55:27 +00:00
|
|
|
#include "ED_anim_api.h"
|
2018-04-02 15:02:08 +02:00
|
|
|
#include "ED_undo.h"
|
2011-02-14 17:55:27 +00:00
|
|
|
|
2019-01-10 15:56:02 +01:00
|
|
|
#include "DEG_depsgraph.h"
|
|
|
|
|
2010-03-18 13:04:46 +00:00
|
|
|
/* ********************************************** */
|
|
|
|
/* UI STUFF */
|
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
// XXX! --------------------------------
|
|
|
|
/* temporary definition for limits of float number buttons (FLT_MAX tends to infinity with old system) */
|
2012-05-08 11:48:19 +00:00
|
|
|
#define UI_FLT_MAX 10000.0f
|
2009-07-02 04:47:36 +00:00
|
|
|
|
2012-05-08 11:48:19 +00:00
|
|
|
#define B_REDR 1
|
|
|
|
#define B_FMODIFIER_REDRAW 20
|
2009-07-02 04:47:36 +00:00
|
|
|
|
|
|
|
/* callback to verify modifier data */
|
2012-05-08 11:48:19 +00:00
|
|
|
static void validate_fmodifier_cb(bContext *UNUSED(C), void *fcm_v, void *UNUSED(arg))
|
2009-07-02 04:47:36 +00:00
|
|
|
{
|
2012-05-08 11:48:19 +00:00
|
|
|
FModifier *fcm = (FModifier *)fcm_v;
|
2015-03-30 21:17:07 +11:00
|
|
|
const FModifierTypeInfo *fmi = fmodifier_get_typeinfo(fcm);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
/* call the verify callback on the modifier if applicable */
|
|
|
|
if (fmi && fmi->verify_data)
|
|
|
|
fmi->verify_data(fcm);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* callback to remove the given modifier */
|
2019-01-10 15:56:02 +01:00
|
|
|
typedef struct FModifierDeleteContext {
|
|
|
|
ID *fcurve_owner_id;
|
|
|
|
ListBase *modifiers;
|
|
|
|
} FModifierDeleteContext;
|
|
|
|
static void delete_fmodifier_cb(bContext *C, void *ctx_v, void *fcm_v)
|
2009-07-02 04:47:36 +00:00
|
|
|
{
|
2019-01-10 15:56:02 +01:00
|
|
|
FModifierDeleteContext *ctx = (FModifierDeleteContext *)ctx_v;
|
|
|
|
ListBase *modifiers = ctx->modifiers;
|
2012-05-08 11:48:19 +00:00
|
|
|
FModifier *fcm = (FModifier *)fcm_v;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 05:25:14 +00:00
|
|
|
/* remove the given F-Modifier from the active modifier-stack */
|
|
|
|
remove_fmodifier(modifiers, fcm);
|
2011-04-06 01:13:01 +00:00
|
|
|
|
|
|
|
ED_undo_push(C, "Delete F-Curve Modifier");
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-11-29 05:56:39 +00:00
|
|
|
/* send notifiers */
|
2018-06-04 09:31:30 +02:00
|
|
|
// XXX for now, this is the only way to get updates in all the right places... but would be nice to have a special one in this case
|
2012-05-08 11:48:19 +00:00
|
|
|
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
|
2019-03-13 15:38:45 +01:00
|
|
|
DEG_id_tag_update(ctx->fcurve_owner_id, ID_RECALC_ANIMATION);
|
2009-07-02 04:47:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------- */
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
/* draw settings for generator modifier */
|
2019-01-10 16:21:40 +01:00
|
|
|
static void draw_modifier__generator(uiLayout *layout, ID *fcurve_owner_id, FModifier *fcm, short width)
|
2009-07-02 04:47:36 +00:00
|
|
|
{
|
2012-05-08 11:48:19 +00:00
|
|
|
FMod_Generator *data = (FMod_Generator *)fcm->data;
|
2011-09-25 15:37:06 +00:00
|
|
|
uiLayout /* *col, */ /* UNUSED */ *row;
|
2009-07-02 23:27:11 +00:00
|
|
|
uiBlock *block;
|
2009-07-02 04:47:36 +00:00
|
|
|
uiBut *but;
|
2009-07-02 23:27:11 +00:00
|
|
|
PointerRNA ptr;
|
2013-06-27 11:29:53 +00:00
|
|
|
short bwidth = width - 1.5 * UI_UNIT_X; /* max button width */
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 23:27:11 +00:00
|
|
|
/* init the RNA-pointer */
|
2019-01-10 16:21:40 +01:00
|
|
|
RNA_pointer_create(fcurve_owner_id, &RNA_FModifierFunctionGenerator, fcm, &ptr);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
/* basic settings (backdrop + mode selector + some padding) */
|
2014-04-01 11:34:00 +11:00
|
|
|
/* col = uiLayoutColumn(layout, true); */ /* UNUSED */
|
2012-05-08 11:48:19 +00:00
|
|
|
block = uiLayoutGetBlock(layout);
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_align_begin(block);
|
|
|
|
but = uiDefButR(block, UI_BTYPE_MENU, B_FMODIFIER_REDRAW, NULL, 0, 0, bwidth, UI_UNIT_Y, &ptr, "mode", -1, 0, 0, -1, -1, NULL);
|
|
|
|
UI_but_func_set(but, validate_fmodifier_cb, fcm, NULL);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
uiDefButR(block, UI_BTYPE_TOGGLE, B_FMODIFIER_REDRAW, NULL, 0, 0, bwidth, UI_UNIT_Y, &ptr, "use_additive", -1, 0, 0, -1, -1, NULL);
|
|
|
|
UI_block_align_end(block);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
/* now add settings for individual modes */
|
|
|
|
switch (data->mode) {
|
|
|
|
case FCM_GENERATOR_POLYNOMIAL: /* polynomial expression */
|
|
|
|
{
|
2015-01-20 14:25:39 +11:00
|
|
|
const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
|
2009-07-02 04:47:36 +00:00
|
|
|
float *cp = NULL;
|
|
|
|
char xval[32];
|
|
|
|
unsigned int i;
|
2012-10-19 08:49:49 +00:00
|
|
|
int maxXWidth;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
/* draw polynomial order selector */
|
2014-04-01 11:34:00 +11:00
|
|
|
row = uiLayoutRow(layout, false);
|
2012-05-08 11:48:19 +00:00
|
|
|
block = uiLayoutGetBlock(row);
|
2014-11-09 21:20:40 +01:00
|
|
|
but = uiDefButI(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, IFACE_("Poly Order:"), 0.5f * UI_UNIT_X, 0, bwidth, UI_UNIT_Y,
|
2012-05-08 11:48:19 +00:00
|
|
|
&data->poly_order, 1, 100, 0, 0,
|
|
|
|
TIP_("'Order' of the Polynomial (for a polynomial with n terms, 'order' is n-1)"));
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_but_func_set(but, validate_fmodifier_cb, fcm, NULL);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
|
|
|
|
2012-10-19 08:49:49 +00:00
|
|
|
/* calculate maximum width of label for "x^n" labels */
|
|
|
|
if (data->arraysize > 2) {
|
|
|
|
BLI_snprintf(xval, sizeof(xval), "x^%u", data->arraysize);
|
2015-01-20 14:25:39 +11:00
|
|
|
/* XXX: UI_fontstyle_string_width is not accurate */
|
|
|
|
maxXWidth = UI_fontstyle_string_width(fstyle, xval) + 0.5 * UI_UNIT_X;
|
2012-10-19 08:49:49 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* basic size (just "x") */
|
2015-01-20 14:25:39 +11:00
|
|
|
maxXWidth = UI_fontstyle_string_width(fstyle, "x") + 0.5 * UI_UNIT_X;
|
2012-10-19 08:49:49 +00:00
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
/* draw controls for each coefficient and a + sign at end of row */
|
2014-04-01 11:34:00 +11:00
|
|
|
row = uiLayoutRow(layout, true);
|
2012-05-08 11:48:19 +00:00
|
|
|
block = uiLayoutGetBlock(row);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2012-05-08 11:48:19 +00:00
|
|
|
cp = data->coefficients;
|
|
|
|
for (i = 0; (i < data->arraysize) && (cp); i++, cp++) {
|
2012-10-19 08:49:49 +00:00
|
|
|
/* To align with first line... */
|
2012-03-03 21:42:21 +00:00
|
|
|
if (i)
|
2014-11-09 21:20:40 +01:00
|
|
|
uiDefBut(block, UI_BTYPE_LABEL, 1, " ", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
|
2012-03-03 21:42:21 +00:00
|
|
|
else
|
2014-11-09 21:20:40 +01:00
|
|
|
uiDefBut(block, UI_BTYPE_LABEL, 1, "y =", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
/* coefficient */
|
2014-11-09 21:20:40 +01:00
|
|
|
uiDefButF(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, "", 0, 0, bwidth / 2, UI_UNIT_Y, cp, -UI_FLT_MAX, UI_FLT_MAX,
|
2012-03-03 21:42:21 +00:00
|
|
|
10, 3, TIP_("Coefficient for polynomial"));
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
/* 'x' param (and '+' if necessary) */
|
2012-03-03 21:42:21 +00:00
|
|
|
if (i == 0)
|
2012-10-19 08:49:49 +00:00
|
|
|
BLI_strncpy(xval, "", sizeof(xval));
|
2012-03-03 21:42:21 +00:00
|
|
|
else if (i == 1)
|
2012-10-19 08:49:49 +00:00
|
|
|
BLI_strncpy(xval, "x", sizeof(xval));
|
2012-03-03 21:42:21 +00:00
|
|
|
else
|
2012-10-19 08:49:49 +00:00
|
|
|
BLI_snprintf(xval, sizeof(xval), "x^%u", i);
|
2014-11-09 21:20:40 +01:00
|
|
|
uiDefBut(block, UI_BTYPE_LABEL, 1, xval, 0, 0, maxXWidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, TIP_("Power of x"));
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2012-05-08 11:48:19 +00:00
|
|
|
if ( (i != (data->arraysize - 1)) || ((i == 0) && data->arraysize == 2) ) {
|
2014-11-09 21:20:40 +01:00
|
|
|
uiDefBut(block, UI_BTYPE_LABEL, 1, "+", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 23:27:11 +00:00
|
|
|
/* next coefficient on a new row */
|
2014-04-01 11:34:00 +11:00
|
|
|
row = uiLayoutRow(layout, true);
|
2012-05-08 11:48:19 +00:00
|
|
|
block = uiLayoutGetBlock(row);
|
2009-07-02 23:27:11 +00:00
|
|
|
}
|
2012-03-03 21:42:21 +00:00
|
|
|
else {
|
2012-10-19 08:49:49 +00:00
|
|
|
/* For alignment in UI! */
|
2014-11-09 21:20:40 +01:00
|
|
|
uiDefBut(block, UI_BTYPE_LABEL, 1, " ", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
|
2012-03-03 21:42:21 +00:00
|
|
|
}
|
2009-07-02 04:47:36 +00:00
|
|
|
}
|
|
|
|
break;
|
2012-03-03 21:42:21 +00:00
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2012-03-01 12:20:18 +00:00
|
|
|
case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* Factorized polynomial expression */
|
2009-07-02 04:47:36 +00:00
|
|
|
{
|
|
|
|
float *cp = NULL;
|
|
|
|
unsigned int i;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
/* draw polynomial order selector */
|
2014-04-01 11:34:00 +11:00
|
|
|
row = uiLayoutRow(layout, false);
|
2012-05-08 11:48:19 +00:00
|
|
|
block = uiLayoutGetBlock(row);
|
2014-11-09 21:20:40 +01:00
|
|
|
but = uiDefButI(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, IFACE_("Poly Order:"), 0, 0, width - 1.5 * UI_UNIT_X, UI_UNIT_Y,
|
2012-05-08 11:48:19 +00:00
|
|
|
&data->poly_order, 1, 100, 0, 0,
|
|
|
|
TIP_("'Order' of the Polynomial (for a polynomial with n terms, 'order' is n-1)"));
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_but_func_set(but, validate_fmodifier_cb, fcm, NULL);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
/* draw controls for each pair of coefficients */
|
2014-04-01 11:34:00 +11:00
|
|
|
row = uiLayoutRow(layout, true);
|
2012-05-08 11:48:19 +00:00
|
|
|
block = uiLayoutGetBlock(row);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2012-05-08 11:48:19 +00:00
|
|
|
cp = data->coefficients;
|
|
|
|
for (i = 0; (i < data->poly_order) && (cp); i++, cp += 2) {
|
2012-03-04 02:43:15 +00:00
|
|
|
/* To align with first line */
|
2012-03-03 21:42:21 +00:00
|
|
|
if (i)
|
2014-11-09 21:20:40 +01:00
|
|
|
uiDefBut(block, UI_BTYPE_LABEL, 1, " ", 0, 0, 2.5 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
|
2012-03-03 21:42:21 +00:00
|
|
|
else
|
2014-11-09 21:20:40 +01:00
|
|
|
uiDefBut(block, UI_BTYPE_LABEL, 1, "y =", 0, 0, 2.5 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
|
2009-07-02 04:47:36 +00:00
|
|
|
/* opening bracket */
|
2014-11-09 21:20:40 +01:00
|
|
|
uiDefBut(block, UI_BTYPE_LABEL, 1, "(", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
/* coefficients */
|
2014-11-09 21:20:40 +01:00
|
|
|
uiDefButF(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, "", 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y, cp, -UI_FLT_MAX, UI_FLT_MAX,
|
2012-03-03 21:42:21 +00:00
|
|
|
10, 3, TIP_("Coefficient of x"));
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
uiDefBut(block, UI_BTYPE_LABEL, 1, "x +", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
uiDefButF(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, "", 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y, cp + 1, -UI_FLT_MAX, UI_FLT_MAX,
|
2012-03-03 21:42:21 +00:00
|
|
|
10, 3, TIP_("Second coefficient"));
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2012-12-21 05:03:47 +00:00
|
|
|
/* closing bracket and multiplication sign */
|
2012-05-08 11:48:19 +00:00
|
|
|
if ( (i != (data->poly_order - 1)) || ((i == 0) && data->poly_order == 2) ) {
|
2014-11-09 21:20:40 +01:00
|
|
|
uiDefBut(block, UI_BTYPE_LABEL, 1, ") \xc3\x97", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2012-08-17 14:43:20 +00:00
|
|
|
/* set up new row for the next pair of coefficients */
|
2014-04-01 11:34:00 +11:00
|
|
|
row = uiLayoutRow(layout, true);
|
2012-05-08 11:48:19 +00:00
|
|
|
block = uiLayoutGetBlock(row);
|
2009-07-02 23:27:11 +00:00
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
else
|
2014-11-09 21:20:40 +01:00
|
|
|
uiDefBut(block, UI_BTYPE_LABEL, 1, ") ", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
|
2009-07-02 04:47:36 +00:00
|
|
|
}
|
2013-07-19 15:23:42 +00:00
|
|
|
break;
|
2009-07-02 04:47:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------- */
|
|
|
|
|
2009-11-22 12:10:45 +00:00
|
|
|
/* draw settings for generator modifier */
|
2019-01-10 16:21:40 +01:00
|
|
|
static void draw_modifier__fn_generator(uiLayout *layout, ID *fcurve_owner_id, FModifier *fcm, short UNUSED(width))
|
2009-07-02 04:47:36 +00:00
|
|
|
{
|
2009-07-03 01:10:46 +00:00
|
|
|
uiLayout *col;
|
2009-07-02 12:41:03 +00:00
|
|
|
PointerRNA ptr;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 12:41:03 +00:00
|
|
|
/* init the RNA-pointer */
|
2019-01-10 16:21:40 +01:00
|
|
|
RNA_pointer_create(fcurve_owner_id, &RNA_FModifierFunctionGenerator, fcm, &ptr);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 12:41:03 +00:00
|
|
|
/* add the settings */
|
2014-04-01 11:34:00 +11:00
|
|
|
col = uiLayoutColumn(layout, true);
|
2012-05-08 11:48:19 +00:00
|
|
|
uiItemR(col, &ptr, "function_type", 0, "", ICON_NONE);
|
|
|
|
uiItemR(col, &ptr, "use_additive", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
|
|
|
|
|
2014-04-01 11:34:00 +11:00
|
|
|
col = uiLayoutColumn(layout, false); // no grouping for now
|
2012-05-08 11:48:19 +00:00
|
|
|
uiItemR(col, &ptr, "amplitude", 0, NULL, ICON_NONE);
|
|
|
|
uiItemR(col, &ptr, "phase_multiplier", 0, NULL, ICON_NONE);
|
|
|
|
uiItemR(col, &ptr, "phase_offset", 0, NULL, ICON_NONE);
|
|
|
|
uiItemR(col, &ptr, "value_offset", 0, NULL, ICON_NONE);
|
2009-07-02 04:47:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------- */
|
|
|
|
|
|
|
|
/* draw settings for cycles modifier */
|
2019-01-10 16:21:40 +01:00
|
|
|
static void draw_modifier__cycles(uiLayout *layout, ID *fcurve_owner_id, FModifier *fcm, short UNUSED(width))
|
2009-07-02 04:47:36 +00:00
|
|
|
{
|
2009-07-02 12:41:03 +00:00
|
|
|
uiLayout *split, *col;
|
|
|
|
PointerRNA ptr;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 12:41:03 +00:00
|
|
|
/* init the RNA-pointer */
|
2019-01-10 16:21:40 +01:00
|
|
|
RNA_pointer_create(fcurve_owner_id, &RNA_FModifierCycles, fcm, &ptr);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
|
|
|
/* split into 2 columns
|
2009-07-02 12:41:03 +00:00
|
|
|
* NOTE: the mode comboboxes shouldn't get labels, otherwise there isn't enough room
|
|
|
|
*/
|
2014-04-01 11:34:00 +11:00
|
|
|
split = uiLayoutSplit(layout, 0.5f, false);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 12:41:03 +00:00
|
|
|
/* before range */
|
2014-04-01 11:34:00 +11:00
|
|
|
col = uiLayoutColumn(split, true);
|
2012-05-08 11:48:19 +00:00
|
|
|
uiItemL(col, IFACE_("Before:"), ICON_NONE);
|
|
|
|
uiItemR(col, &ptr, "mode_before", 0, "", ICON_NONE);
|
|
|
|
uiItemR(col, &ptr, "cycles_before", 0, NULL, ICON_NONE);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 12:41:03 +00:00
|
|
|
/* after range */
|
2014-04-01 11:34:00 +11:00
|
|
|
col = uiLayoutColumn(split, true);
|
2012-05-08 11:48:19 +00:00
|
|
|
uiItemL(col, IFACE_("After:"), ICON_NONE);
|
|
|
|
uiItemR(col, &ptr, "mode_after", 0, "", ICON_NONE);
|
|
|
|
uiItemR(col, &ptr, "cycles_after", 0, NULL, ICON_NONE);
|
2009-07-02 04:47:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------- */
|
|
|
|
|
|
|
|
/* draw settings for noise modifier */
|
2019-01-10 16:21:40 +01:00
|
|
|
static void draw_modifier__noise(uiLayout *layout, ID *fcurve_owner_id, FModifier *fcm, short UNUSED(width))
|
2009-07-02 04:47:36 +00:00
|
|
|
{
|
2009-07-02 12:41:03 +00:00
|
|
|
uiLayout *split, *col;
|
|
|
|
PointerRNA ptr;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 12:41:03 +00:00
|
|
|
/* init the RNA-pointer */
|
2019-01-10 16:21:40 +01:00
|
|
|
RNA_pointer_create(fcurve_owner_id, &RNA_FModifierNoise, fcm, &ptr);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-03 01:10:46 +00:00
|
|
|
/* blending mode */
|
2011-02-27 18:03:19 +00:00
|
|
|
uiItemR(layout, &ptr, "blend_type", 0, NULL, ICON_NONE);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 12:41:03 +00:00
|
|
|
/* split into 2 columns */
|
2014-04-01 11:34:00 +11:00
|
|
|
split = uiLayoutSplit(layout, 0.5f, false);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 12:41:03 +00:00
|
|
|
/* col 1 */
|
2014-04-01 11:34:00 +11:00
|
|
|
col = uiLayoutColumn(split, false);
|
2012-05-08 11:48:19 +00:00
|
|
|
uiItemR(col, &ptr, "scale", 0, NULL, ICON_NONE);
|
|
|
|
uiItemR(col, &ptr, "strength", 0, NULL, ICON_NONE);
|
2014-02-10 15:23:01 +13:00
|
|
|
uiItemR(col, &ptr, "offset", 0, NULL, ICON_NONE);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 12:41:03 +00:00
|
|
|
/* col 2 */
|
2014-04-01 11:34:00 +11:00
|
|
|
col = uiLayoutColumn(split, false);
|
2012-05-08 11:48:19 +00:00
|
|
|
uiItemR(col, &ptr, "phase", 0, NULL, ICON_NONE);
|
|
|
|
uiItemR(col, &ptr, "depth", 0, NULL, ICON_NONE);
|
2009-07-02 04:47:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* callback to add new envelope data point */
|
2012-05-08 11:48:19 +00:00
|
|
|
static void fmod_envelope_addpoint_cb(bContext *C, void *fcm_dv, void *UNUSED(arg))
|
2009-07-02 04:47:36 +00:00
|
|
|
{
|
2012-05-08 11:48:19 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
FMod_Envelope *env = (FMod_Envelope *)fcm_dv;
|
2009-07-02 04:47:36 +00:00
|
|
|
FCM_EnvelopeData *fedn;
|
|
|
|
FCM_EnvelopeData fed;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
/* init template data */
|
2012-05-08 11:48:19 +00:00
|
|
|
fed.min = -1.0f;
|
|
|
|
fed.max = 1.0f;
|
|
|
|
fed.time = (float)scene->r.cfra; // XXX make this int for ease of use?
|
|
|
|
fed.f1 = fed.f2 = 0;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
/* check that no data exists for the current frame... */
|
|
|
|
if (env->data) {
|
2013-03-17 19:13:04 +00:00
|
|
|
bool exists;
|
2013-01-31 08:19:11 +00:00
|
|
|
int i = BKE_fcm_envelope_find_index(env->data, (float)(scene->r.cfra), env->totvert, &exists);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2019-01-15 23:24:20 +11:00
|
|
|
/* binarysearch_...() will set exists by default to 0,
|
|
|
|
* so if it is non-zero, that means that the point exists already */
|
|
|
|
if (exists) {
|
2009-07-02 04:47:36 +00:00
|
|
|
return;
|
2019-01-15 23:24:20 +11:00
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
/* add new */
|
2012-05-08 11:48:19 +00:00
|
|
|
fedn = MEM_callocN((env->totvert + 1) * sizeof(FCM_EnvelopeData), "FCM_EnvelopeData");
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
/* add the points that should occur before the point to be pasted */
|
|
|
|
if (i > 0)
|
2012-05-08 11:48:19 +00:00
|
|
|
memcpy(fedn, env->data, i * sizeof(FCM_EnvelopeData));
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
/* add point to paste at index i */
|
2012-05-08 11:48:19 +00:00
|
|
|
*(fedn + i) = fed;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
/* add the points that occur after the point to be pasted */
|
2018-06-04 09:31:30 +02:00
|
|
|
if (i < env->totvert)
|
2012-05-08 11:48:19 +00:00
|
|
|
memcpy(fedn + i + 1, env->data + i, (env->totvert - i) * sizeof(FCM_EnvelopeData));
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
/* replace (+ free) old with new */
|
|
|
|
MEM_freeN(env->data);
|
2012-05-08 11:48:19 +00:00
|
|
|
env->data = fedn;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
env->totvert++;
|
|
|
|
}
|
|
|
|
else {
|
2012-05-08 11:48:19 +00:00
|
|
|
env->data = MEM_callocN(sizeof(FCM_EnvelopeData), "FCM_EnvelopeData");
|
|
|
|
*(env->data) = fed;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2012-05-08 11:48:19 +00:00
|
|
|
env->totvert = 1;
|
2009-07-02 04:47:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* callback to remove envelope data point */
|
|
|
|
// TODO: should we have a separate file for things like this?
|
2012-05-08 11:48:19 +00:00
|
|
|
static void fmod_envelope_deletepoint_cb(bContext *UNUSED(C), void *fcm_dv, void *ind_v)
|
2009-07-02 04:47:36 +00:00
|
|
|
{
|
2012-05-08 11:48:19 +00:00
|
|
|
FMod_Envelope *env = (FMod_Envelope *)fcm_dv;
|
2009-07-02 04:47:36 +00:00
|
|
|
FCM_EnvelopeData *fedn;
|
2018-09-19 12:05:58 +10:00
|
|
|
int index = POINTER_AS_INT(ind_v);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
/* check that no data exists for the current frame... */
|
|
|
|
if (env->totvert > 1) {
|
|
|
|
/* allocate a new smaller array */
|
2012-05-08 11:48:19 +00:00
|
|
|
fedn = MEM_callocN(sizeof(FCM_EnvelopeData) * (env->totvert - 1), "FCM_EnvelopeData");
|
2011-03-24 09:59:02 +00:00
|
|
|
|
2012-05-08 11:48:19 +00:00
|
|
|
memcpy(fedn, env->data, sizeof(FCM_EnvelopeData) * (index));
|
|
|
|
memcpy(fedn + index, env->data + (index + 1), sizeof(FCM_EnvelopeData) * ((env->totvert - index) - 1));
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
/* free old array, and set the new */
|
|
|
|
MEM_freeN(env->data);
|
2012-05-08 11:48:19 +00:00
|
|
|
env->data = fedn;
|
2009-07-02 04:47:36 +00:00
|
|
|
env->totvert--;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* just free array, since the only vert was deleted */
|
2011-03-24 09:59:02 +00:00
|
|
|
if (env->data) {
|
2009-07-02 04:47:36 +00:00
|
|
|
MEM_freeN(env->data);
|
2012-05-08 11:48:19 +00:00
|
|
|
env->data = NULL;
|
2011-03-24 09:59:02 +00:00
|
|
|
}
|
2012-05-08 11:48:19 +00:00
|
|
|
env->totvert = 0;
|
2009-07-02 04:47:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* draw settings for envelope modifier */
|
2019-01-10 16:21:40 +01:00
|
|
|
static void draw_modifier__envelope(uiLayout *layout, ID *fcurve_owner_id, FModifier *fcm, short UNUSED(width))
|
2009-07-02 04:47:36 +00:00
|
|
|
{
|
2012-05-08 11:48:19 +00:00
|
|
|
FMod_Envelope *env = (FMod_Envelope *)fcm->data;
|
2009-07-02 04:47:36 +00:00
|
|
|
FCM_EnvelopeData *fed;
|
2009-07-02 23:27:11 +00:00
|
|
|
uiLayout *col, *row;
|
|
|
|
uiBlock *block;
|
2009-07-02 04:47:36 +00:00
|
|
|
uiBut *but;
|
2009-07-02 23:27:11 +00:00
|
|
|
PointerRNA ptr;
|
2009-07-02 04:47:36 +00:00
|
|
|
int i;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 23:27:11 +00:00
|
|
|
/* init the RNA-pointer */
|
2019-01-10 16:21:40 +01:00
|
|
|
RNA_pointer_create(fcurve_owner_id, &RNA_FModifierEnvelope, fcm, &ptr);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 23:27:11 +00:00
|
|
|
/* general settings */
|
2014-04-01 11:34:00 +11:00
|
|
|
col = uiLayoutColumn(layout, true);
|
2012-05-08 11:48:19 +00:00
|
|
|
uiItemL(col, IFACE_("Envelope:"), ICON_NONE);
|
|
|
|
uiItemR(col, &ptr, "reference_value", 0, NULL, ICON_NONE);
|
|
|
|
|
2014-04-01 11:34:00 +11:00
|
|
|
row = uiLayoutRow(col, true);
|
2012-05-08 11:48:19 +00:00
|
|
|
uiItemR(row, &ptr, "default_min", 0, IFACE_("Min"), ICON_NONE);
|
|
|
|
uiItemR(row, &ptr, "default_max", 0, IFACE_("Max"), ICON_NONE);
|
2012-07-06 23:56:59 +00:00
|
|
|
|
2009-07-02 23:27:11 +00:00
|
|
|
/* control points header */
|
2012-07-06 23:56:59 +00:00
|
|
|
/* TODO: move this control-point control stuff to using the new special widgets for lists
|
|
|
|
* the current way is far too cramped */
|
2014-04-01 11:34:00 +11:00
|
|
|
row = uiLayoutRow(layout, false);
|
2012-05-08 11:48:19 +00:00
|
|
|
block = uiLayoutGetBlock(row);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
uiDefBut(block, UI_BTYPE_LABEL, 1, IFACE_("Control Points:"), 0, 0, 7.5 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
but = uiDefBut(block, UI_BTYPE_BUT, B_FMODIFIER_REDRAW, IFACE_("Add Point"), 0, 0, 7.5 * UI_UNIT_X, UI_UNIT_Y,
|
2012-05-08 11:48:19 +00:00
|
|
|
NULL, 0, 0, 0, 0, TIP_("Add a new control-point to the envelope on the current frame"));
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_but_func_set(but, fmod_envelope_addpoint_cb, env, NULL);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 23:27:11 +00:00
|
|
|
/* control points list */
|
2012-05-08 11:48:19 +00:00
|
|
|
for (i = 0, fed = env->data; i < env->totvert; i++, fed++) {
|
2009-07-02 23:27:11 +00:00
|
|
|
/* get a new row to operate on */
|
2014-04-01 11:34:00 +11:00
|
|
|
row = uiLayoutRow(layout, true);
|
2012-05-08 11:48:19 +00:00
|
|
|
block = uiLayoutGetBlock(row);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_align_begin(block);
|
|
|
|
but = uiDefButF(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, IFACE_("Fra:"), 0, 0, 4.5 * UI_UNIT_X, UI_UNIT_Y,
|
2012-05-08 11:48:19 +00:00
|
|
|
&fed->time, -MAXFRAMEF, MAXFRAMEF, 10, 1, TIP_("Frame that envelope point occurs"));
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_but_func_set(but, validate_fmodifier_cb, fcm, NULL);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
uiDefButF(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, IFACE_("Min:"), 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y,
|
2012-05-08 11:48:19 +00:00
|
|
|
&fed->min, -UI_FLT_MAX, UI_FLT_MAX, 10, 2, TIP_("Minimum bound of envelope at this point"));
|
2014-11-09 21:20:40 +01:00
|
|
|
uiDefButF(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, IFACE_("Max:"), 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y,
|
2012-05-08 11:48:19 +00:00
|
|
|
&fed->max, -UI_FLT_MAX, UI_FLT_MAX, 10, 2, TIP_("Maximum bound of envelope at this point"));
|
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
but = uiDefIconBut(block, UI_BTYPE_BUT, B_FMODIFIER_REDRAW, ICON_X, 0, 0, 0.9 * UI_UNIT_X, UI_UNIT_Y,
|
2012-05-08 11:48:19 +00:00
|
|
|
NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Delete envelope control point"));
|
2018-09-19 12:05:58 +10:00
|
|
|
UI_but_func_set(but, fmod_envelope_deletepoint_cb, env, POINTER_FROM_INT(i));
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_align_begin(block);
|
2009-07-02 04:47:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------- */
|
|
|
|
|
|
|
|
/* draw settings for limits modifier */
|
2019-01-10 16:21:40 +01:00
|
|
|
static void draw_modifier__limits(uiLayout *layout, ID *fcurve_owner_id, FModifier *fcm, short UNUSED(width))
|
2009-07-02 04:47:36 +00:00
|
|
|
{
|
2011-09-25 15:37:06 +00:00
|
|
|
uiLayout *split, *col /* , *row */ /* UNUSED */;
|
2009-07-02 12:41:03 +00:00
|
|
|
PointerRNA ptr;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 12:41:03 +00:00
|
|
|
/* init the RNA-pointer */
|
2019-01-10 16:21:40 +01:00
|
|
|
RNA_pointer_create(fcurve_owner_id, &RNA_FModifierLimits, fcm, &ptr);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 12:41:03 +00:00
|
|
|
/* row 1: minimum */
|
|
|
|
{
|
2014-04-01 11:34:00 +11:00
|
|
|
/* row = uiLayoutRow(layout, false); */ /* UNUSED */
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 12:41:03 +00:00
|
|
|
/* split into 2 columns */
|
2014-04-01 11:34:00 +11:00
|
|
|
split = uiLayoutSplit(layout, 0.5f, false);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 12:41:03 +00:00
|
|
|
/* x-minimum */
|
2014-04-01 11:34:00 +11:00
|
|
|
col = uiLayoutColumn(split, true);
|
2012-05-08 11:48:19 +00:00
|
|
|
uiItemR(col, &ptr, "use_min_x", 0, NULL, ICON_NONE);
|
|
|
|
uiItemR(col, &ptr, "min_x", 0, NULL, ICON_NONE);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 12:41:03 +00:00
|
|
|
/* y-minimum*/
|
2014-04-01 11:34:00 +11:00
|
|
|
col = uiLayoutColumn(split, true);
|
2012-05-08 11:48:19 +00:00
|
|
|
uiItemR(col, &ptr, "use_min_y", 0, NULL, ICON_NONE);
|
|
|
|
uiItemR(col, &ptr, "min_y", 0, NULL, ICON_NONE);
|
2009-07-02 12:41:03 +00:00
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
More F-Modifier Tweaks:
This commit started out aiming to make the "Stepped" F-Modifier (committed last night) even more useful, but ended up fixing a few other finer-points of how F-Modifiers work.
Firstly, the new stuff:
I've addded options to the Stepped F-Modifier to not affect frames before and/or after specified values, and renamed the 'start offset' to 'offset' for clarity.
The main objective of this is to allow Stepped F-Modifiers to only affect certain time ranges, so that by layering/using multiple instances of the F-Modifier, it can be possible to have multiple stepping-sizes.
This allows for effects like:
http://www.pasteall.org/blend/2230
or in words, it provides a convenient mechanism for animators to specify whether sections of the animation is shown "on twos", "fours", or even "forty-second-ths plus a smidgen", as can be easily done with 2D.
Assorted changes to support this:
* Properly fixed up how F-Modifiers that work with time, evaluate the time to evaluate the curve at. Now layered time effects like this should be possible in a much nicer way.
* Added proper value range validation/clamping to many properties. There are still a lot more that need checking, but at least more properties now do "the right thing".
2010-03-19 03:38:14 +00:00
|
|
|
/* row 2: maximum */
|
2009-07-02 12:41:03 +00:00
|
|
|
{
|
2014-04-01 11:34:00 +11:00
|
|
|
/* row = uiLayoutRow(layout, false); */ /* UNUSED */
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 12:41:03 +00:00
|
|
|
/* split into 2 columns */
|
2014-04-01 11:34:00 +11:00
|
|
|
split = uiLayoutSplit(layout, 0.5f, false);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 12:41:03 +00:00
|
|
|
/* x-minimum */
|
2014-04-01 11:34:00 +11:00
|
|
|
col = uiLayoutColumn(split, true);
|
2012-05-08 11:48:19 +00:00
|
|
|
uiItemR(col, &ptr, "use_max_x", 0, NULL, ICON_NONE);
|
|
|
|
uiItemR(col, &ptr, "max_x", 0, NULL, ICON_NONE);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 12:41:03 +00:00
|
|
|
/* y-minimum*/
|
2014-04-01 11:34:00 +11:00
|
|
|
col = uiLayoutColumn(split, true);
|
2012-05-08 11:48:19 +00:00
|
|
|
uiItemR(col, &ptr, "use_max_y", 0, NULL, ICON_NONE);
|
|
|
|
uiItemR(col, &ptr, "max_y", 0, NULL, ICON_NONE);
|
2009-07-02 12:41:03 +00:00
|
|
|
}
|
2009-07-02 04:47:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------- */
|
|
|
|
|
2010-03-18 13:04:46 +00:00
|
|
|
/* draw settings for stepped interpolation modifier */
|
2019-01-10 16:21:40 +01:00
|
|
|
static void draw_modifier__stepped(uiLayout *layout, ID *fcurve_owner_id, FModifier *fcm, short UNUSED(width))
|
2010-03-18 13:04:46 +00:00
|
|
|
{
|
2011-11-23 19:05:52 +00:00
|
|
|
uiLayout *col, *sub;
|
2010-03-18 13:04:46 +00:00
|
|
|
PointerRNA ptr;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2010-03-18 13:04:46 +00:00
|
|
|
/* init the RNA-pointer */
|
2019-01-10 16:21:40 +01:00
|
|
|
RNA_pointer_create(fcurve_owner_id, &RNA_FModifierStepped, fcm, &ptr);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
More F-Modifier Tweaks:
This commit started out aiming to make the "Stepped" F-Modifier (committed last night) even more useful, but ended up fixing a few other finer-points of how F-Modifiers work.
Firstly, the new stuff:
I've addded options to the Stepped F-Modifier to not affect frames before and/or after specified values, and renamed the 'start offset' to 'offset' for clarity.
The main objective of this is to allow Stepped F-Modifiers to only affect certain time ranges, so that by layering/using multiple instances of the F-Modifier, it can be possible to have multiple stepping-sizes.
This allows for effects like:
http://www.pasteall.org/blend/2230
or in words, it provides a convenient mechanism for animators to specify whether sections of the animation is shown "on twos", "fours", or even "forty-second-ths plus a smidgen", as can be easily done with 2D.
Assorted changes to support this:
* Properly fixed up how F-Modifiers that work with time, evaluate the time to evaluate the curve at. Now layered time effects like this should be possible in a much nicer way.
* Added proper value range validation/clamping to many properties. There are still a lot more that need checking, but at least more properties now do "the right thing".
2010-03-19 03:38:14 +00:00
|
|
|
/* block 1: "stepping" settings */
|
2014-04-01 11:34:00 +11:00
|
|
|
col = uiLayoutColumn(layout, false);
|
2012-05-08 11:48:19 +00:00
|
|
|
uiItemR(col, &ptr, "frame_step", 0, NULL, ICON_NONE);
|
|
|
|
uiItemR(col, &ptr, "frame_offset", 0, NULL, ICON_NONE);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
More F-Modifier Tweaks:
This commit started out aiming to make the "Stepped" F-Modifier (committed last night) even more useful, but ended up fixing a few other finer-points of how F-Modifiers work.
Firstly, the new stuff:
I've addded options to the Stepped F-Modifier to not affect frames before and/or after specified values, and renamed the 'start offset' to 'offset' for clarity.
The main objective of this is to allow Stepped F-Modifiers to only affect certain time ranges, so that by layering/using multiple instances of the F-Modifier, it can be possible to have multiple stepping-sizes.
This allows for effects like:
http://www.pasteall.org/blend/2230
or in words, it provides a convenient mechanism for animators to specify whether sections of the animation is shown "on twos", "fours", or even "forty-second-ths plus a smidgen", as can be easily done with 2D.
Assorted changes to support this:
* Properly fixed up how F-Modifiers that work with time, evaluate the time to evaluate the curve at. Now layered time effects like this should be possible in a much nicer way.
* Added proper value range validation/clamping to many properties. There are still a lot more that need checking, but at least more properties now do "the right thing".
2010-03-19 03:38:14 +00:00
|
|
|
/* block 2: start range settings */
|
2014-04-01 11:34:00 +11:00
|
|
|
col = uiLayoutColumn(layout, true);
|
2012-05-08 11:48:19 +00:00
|
|
|
uiItemR(col, &ptr, "use_frame_start", 0, NULL, ICON_NONE);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2014-04-01 11:34:00 +11:00
|
|
|
sub = uiLayoutColumn(col, true);
|
2012-05-08 11:48:19 +00:00
|
|
|
uiLayoutSetActive(sub, RNA_boolean_get(&ptr, "use_frame_start"));
|
|
|
|
uiItemR(sub, &ptr, "frame_start", 0, NULL, ICON_NONE);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
More F-Modifier Tweaks:
This commit started out aiming to make the "Stepped" F-Modifier (committed last night) even more useful, but ended up fixing a few other finer-points of how F-Modifiers work.
Firstly, the new stuff:
I've addded options to the Stepped F-Modifier to not affect frames before and/or after specified values, and renamed the 'start offset' to 'offset' for clarity.
The main objective of this is to allow Stepped F-Modifiers to only affect certain time ranges, so that by layering/using multiple instances of the F-Modifier, it can be possible to have multiple stepping-sizes.
This allows for effects like:
http://www.pasteall.org/blend/2230
or in words, it provides a convenient mechanism for animators to specify whether sections of the animation is shown "on twos", "fours", or even "forty-second-ths plus a smidgen", as can be easily done with 2D.
Assorted changes to support this:
* Properly fixed up how F-Modifiers that work with time, evaluate the time to evaluate the curve at. Now layered time effects like this should be possible in a much nicer way.
* Added proper value range validation/clamping to many properties. There are still a lot more that need checking, but at least more properties now do "the right thing".
2010-03-19 03:38:14 +00:00
|
|
|
/* block 3: end range settings */
|
2014-04-01 11:34:00 +11:00
|
|
|
col = uiLayoutColumn(layout, true);
|
2012-05-08 11:48:19 +00:00
|
|
|
uiItemR(col, &ptr, "use_frame_end", 0, NULL, ICON_NONE);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2014-04-01 11:34:00 +11:00
|
|
|
sub = uiLayoutColumn(col, true);
|
2012-05-08 11:48:19 +00:00
|
|
|
uiLayoutSetActive(sub, RNA_boolean_get(&ptr, "use_frame_end"));
|
|
|
|
uiItemR(sub, &ptr, "frame_end", 0, NULL, ICON_NONE);
|
2010-03-18 13:04:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------- */
|
2009-07-02 12:41:03 +00:00
|
|
|
|
2019-01-10 16:21:40 +01:00
|
|
|
void ANIM_uiTemplate_fmodifier_draw(uiLayout *layout, ID *fcurve_owner_id,
|
2019-01-10 15:56:02 +01:00
|
|
|
ListBase *modifiers, FModifier *fcm)
|
2009-07-02 04:47:36 +00:00
|
|
|
{
|
2015-03-30 21:17:07 +11:00
|
|
|
const FModifierTypeInfo *fmi = fmodifier_get_typeinfo(fcm);
|
2011-11-23 19:05:52 +00:00
|
|
|
uiLayout *box, *row, *sub, *col;
|
2009-07-02 12:41:03 +00:00
|
|
|
uiBlock *block;
|
2009-07-02 04:47:36 +00:00
|
|
|
uiBut *but;
|
2012-05-08 11:48:19 +00:00
|
|
|
short width = 314;
|
2009-11-25 08:28:57 +00:00
|
|
|
PointerRNA ptr;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-11-25 08:28:57 +00:00
|
|
|
/* init the RNA-pointer */
|
2019-01-10 16:21:40 +01:00
|
|
|
RNA_pointer_create(fcurve_owner_id, &RNA_FModifier, fcm, &ptr);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
/* draw header */
|
|
|
|
{
|
2009-07-02 12:41:03 +00:00
|
|
|
/* get layout-row + UI-block for this */
|
2012-05-08 11:48:19 +00:00
|
|
|
box = uiLayoutBox(layout);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2014-04-01 11:34:00 +11:00
|
|
|
row = uiLayoutRow(box, false);
|
2012-05-08 11:48:19 +00:00
|
|
|
block = uiLayoutGetBlock(row); // err...
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 12:41:03 +00:00
|
|
|
/* left-align -------------------------------------------- */
|
2014-04-01 11:34:00 +11:00
|
|
|
sub = uiLayoutRow(row, true);
|
2011-11-23 19:05:52 +00:00
|
|
|
uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_emboss_set(block, UI_EMBOSS_NONE);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
/* expand */
|
2011-11-23 19:05:52 +00:00
|
|
|
uiItemR(sub, &ptr, "show_expanded", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
/* checkbox for 'active' status (for now) */
|
2011-11-23 19:05:52 +00:00
|
|
|
uiItemR(sub, &ptr, "active", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
/* name */
|
|
|
|
if (fmi)
|
2013-02-24 15:40:28 +00:00
|
|
|
uiItemL(sub, IFACE_(fmi->name), ICON_NONE);
|
2009-07-02 04:47:36 +00:00
|
|
|
else
|
2013-02-24 15:40:28 +00:00
|
|
|
uiItemL(sub, IFACE_("<Unknown Modifier>"), ICON_NONE);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 12:41:03 +00:00
|
|
|
/* right-align ------------------------------------------- */
|
2014-04-01 11:34:00 +11:00
|
|
|
sub = uiLayoutRow(row, true);
|
2011-11-23 19:05:52 +00:00
|
|
|
uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_RIGHT);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
/* 'mute' button */
|
2011-11-23 19:05:52 +00:00
|
|
|
uiItemR(sub, &ptr, "mute", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_emboss_set(block, UI_EMBOSS_NONE);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
/* delete button */
|
2014-11-09 21:20:40 +01:00
|
|
|
but = uiDefIconBut(block, UI_BTYPE_BUT, B_REDR, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y,
|
2012-05-08 11:48:19 +00:00
|
|
|
NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Delete F-Curve Modifier"));
|
2019-01-10 15:56:02 +01:00
|
|
|
FModifierDeleteContext *ctx = MEM_mallocN(sizeof(FModifierDeleteContext), "fmodifier ctx");
|
|
|
|
ctx->fcurve_owner_id = fcurve_owner_id;
|
|
|
|
ctx->modifiers = modifiers;
|
|
|
|
UI_but_funcN_set(but, delete_fmodifier_cb, ctx, fcm);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_block_emboss_set(block, UI_EMBOSS);
|
2009-07-02 04:47:36 +00:00
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
/* when modifier is expanded, draw settings */
|
|
|
|
if (fcm->flag & FMODIFIER_FLAG_EXPANDED) {
|
2009-07-02 12:41:03 +00:00
|
|
|
/* set up the flexible-box layout which acts as the backdrop for the modifier settings */
|
2012-05-08 11:48:19 +00:00
|
|
|
box = uiLayoutBox(layout);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
/* draw settings for individual modifiers */
|
|
|
|
switch (fcm->type) {
|
|
|
|
case FMODIFIER_TYPE_GENERATOR: /* Generator */
|
2019-01-10 16:21:40 +01:00
|
|
|
draw_modifier__generator(box, fcurve_owner_id, fcm, width);
|
2009-07-02 04:47:36 +00:00
|
|
|
break;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
case FMODIFIER_TYPE_FN_GENERATOR: /* Built-In Function Generator */
|
2019-01-10 16:21:40 +01:00
|
|
|
draw_modifier__fn_generator(box, fcurve_owner_id, fcm, width);
|
2009-07-02 04:47:36 +00:00
|
|
|
break;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
case FMODIFIER_TYPE_CYCLES: /* Cycles */
|
2019-01-10 16:21:40 +01:00
|
|
|
draw_modifier__cycles(box, fcurve_owner_id, fcm, width);
|
2009-07-02 04:47:36 +00:00
|
|
|
break;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
case FMODIFIER_TYPE_ENVELOPE: /* Envelope */
|
2019-01-10 16:21:40 +01:00
|
|
|
draw_modifier__envelope(box, fcurve_owner_id, fcm, width);
|
2009-07-02 04:47:36 +00:00
|
|
|
break;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
case FMODIFIER_TYPE_LIMITS: /* Limits */
|
2019-01-10 16:21:40 +01:00
|
|
|
draw_modifier__limits(box, fcurve_owner_id, fcm, width);
|
2009-07-02 04:47:36 +00:00
|
|
|
break;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
case FMODIFIER_TYPE_NOISE: /* Noise */
|
2019-01-10 16:21:40 +01:00
|
|
|
draw_modifier__noise(box, fcurve_owner_id, fcm, width);
|
2009-07-02 04:47:36 +00:00
|
|
|
break;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2010-03-18 13:04:46 +00:00
|
|
|
case FMODIFIER_TYPE_STEPPED: /* Stepped */
|
2019-01-10 16:21:40 +01:00
|
|
|
draw_modifier__stepped(box, fcurve_owner_id, fcm, width);
|
2010-03-18 13:04:46 +00:00
|
|
|
break;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-07-02 04:47:36 +00:00
|
|
|
default: /* unknown type */
|
|
|
|
break;
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2011-06-03 13:34:02 +00:00
|
|
|
/* one last panel below this: FModifier range */
|
|
|
|
// TODO: experiment with placement of this
|
|
|
|
{
|
|
|
|
box = uiLayoutBox(layout);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2011-06-04 06:22:01 +00:00
|
|
|
/* restricted range ----------------------------------------------------- */
|
2014-04-01 11:34:00 +11:00
|
|
|
col = uiLayoutColumn(box, true);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2011-06-03 13:34:02 +00:00
|
|
|
/* top row: use restricted range */
|
2014-04-01 11:34:00 +11:00
|
|
|
row = uiLayoutRow(col, true);
|
2011-06-03 13:34:02 +00:00
|
|
|
uiItemR(row, &ptr, "use_restricted_range", 0, NULL, ICON_NONE);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2011-06-03 13:34:02 +00:00
|
|
|
if (fcm->flag & FMODIFIER_FLAG_RANGERESTRICT) {
|
|
|
|
/* second row: settings */
|
2014-04-01 11:34:00 +11:00
|
|
|
row = uiLayoutRow(col, true);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2012-03-03 21:42:21 +00:00
|
|
|
uiItemR(row, &ptr, "frame_start", 0, IFACE_("Start"), ICON_NONE);
|
|
|
|
uiItemR(row, &ptr, "frame_end", 0, IFACE_("End"), ICON_NONE);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2011-06-04 06:22:01 +00:00
|
|
|
/* third row: blending influence */
|
2014-04-01 11:34:00 +11:00
|
|
|
row = uiLayoutRow(col, true);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2012-03-03 21:42:21 +00:00
|
|
|
uiItemR(row, &ptr, "blend_in", 0, IFACE_("In"), ICON_NONE);
|
|
|
|
uiItemR(row, &ptr, "blend_out", 0, IFACE_("Out"), ICON_NONE);
|
2011-06-04 06:22:01 +00:00
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2011-06-04 06:22:01 +00:00
|
|
|
/* influence -------------------------------------------------------------- */
|
2014-04-01 11:34:00 +11:00
|
|
|
col = uiLayoutColumn(box, true);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2011-06-04 06:22:01 +00:00
|
|
|
/* top row: use influence */
|
|
|
|
uiItemR(col, &ptr, "use_influence", 0, NULL, ICON_NONE);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2011-06-04 06:22:01 +00:00
|
|
|
if (fcm->flag & FMODIFIER_FLAG_USEINFLUENCE) {
|
|
|
|
/* second row: influence value */
|
|
|
|
uiItemR(col, &ptr, "influence", 0, NULL, ICON_NONE);
|
2011-06-03 13:34:02 +00:00
|
|
|
}
|
|
|
|
}
|
2009-07-02 04:47:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ********************************************** */
|
2010-03-18 13:04:46 +00:00
|
|
|
/* COPY/PASTE BUFFER STUFF */
|
|
|
|
|
|
|
|
/* Copy/Paste Buffer itself (list of FModifier 's) */
|
|
|
|
static ListBase fmodifier_copypaste_buf = {NULL, NULL};
|
|
|
|
|
|
|
|
/* ---------- */
|
|
|
|
|
|
|
|
/* free the copy/paste buffer */
|
2016-04-03 01:18:23 +13:00
|
|
|
void ANIM_fmodifiers_copybuf_free(void)
|
2010-03-18 13:04:46 +00:00
|
|
|
{
|
|
|
|
/* just free the whole buffer */
|
|
|
|
free_fmodifiers(&fmodifier_copypaste_buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* copy the given F-Modifiers to the buffer, returning whether anything was copied or not
|
2016-04-03 01:18:23 +13:00
|
|
|
* assuming that the buffer has been cleared already with ANIM_fmodifiers_copybuf_free()
|
2018-11-14 12:53:15 +11:00
|
|
|
* - active: only copy the active modifier
|
2010-03-18 13:04:46 +00:00
|
|
|
*/
|
2014-04-11 11:25:41 +10:00
|
|
|
bool ANIM_fmodifiers_copy_to_buf(ListBase *modifiers, bool active)
|
2010-03-18 13:04:46 +00:00
|
|
|
{
|
2014-04-11 11:25:41 +10:00
|
|
|
bool ok = true;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2010-03-18 13:04:46 +00:00
|
|
|
/* sanity checks */
|
2012-03-25 22:35:18 +00:00
|
|
|
if (ELEM(NULL, modifiers, modifiers->first))
|
2010-03-18 13:04:46 +00:00
|
|
|
return 0;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2010-03-18 13:04:46 +00:00
|
|
|
/* copy the whole list, or just the active one? */
|
|
|
|
if (active) {
|
|
|
|
FModifier *fcm = find_active_fmodifier(modifiers);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2010-03-18 13:04:46 +00:00
|
|
|
if (fcm) {
|
|
|
|
FModifier *fcmN = copy_fmodifier(fcm);
|
|
|
|
BLI_addtail(&fmodifier_copypaste_buf, fcmN);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ok = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
copy_fmodifiers(&fmodifier_copypaste_buf, modifiers);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2010-03-18 13:04:46 +00:00
|
|
|
/* did we succeed? */
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
2018-06-04 09:31:30 +02:00
|
|
|
/* 'Paste' the F-Modifier(s) from the buffer to the specified list
|
2018-11-14 12:53:15 +11:00
|
|
|
* - replace: free all the existing modifiers to leave only the pasted ones
|
2010-03-18 13:04:46 +00:00
|
|
|
*/
|
2017-10-17 19:39:10 +03:00
|
|
|
bool ANIM_fmodifiers_paste_from_buf(ListBase *modifiers, bool replace, FCurve *curve)
|
2010-03-18 13:04:46 +00:00
|
|
|
{
|
|
|
|
FModifier *fcm;
|
2014-04-11 11:25:41 +10:00
|
|
|
bool ok = false;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2010-03-18 13:04:46 +00:00
|
|
|
/* sanity checks */
|
|
|
|
if (modifiers == NULL)
|
|
|
|
return 0;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2017-10-17 19:39:10 +03:00
|
|
|
bool was_cyclic = curve && BKE_fcurve_is_cyclic(curve);
|
|
|
|
|
2010-03-18 13:04:46 +00:00
|
|
|
/* if replacing the list, free the existing modifiers */
|
|
|
|
if (replace)
|
|
|
|
free_fmodifiers(modifiers);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2010-03-18 13:04:46 +00:00
|
|
|
/* now copy over all the modifiers in the buffer to the end of the list */
|
2012-05-08 11:48:19 +00:00
|
|
|
for (fcm = fmodifier_copypaste_buf.first; fcm; fcm = fcm->next) {
|
2010-03-18 13:04:46 +00:00
|
|
|
/* make a copy of it */
|
|
|
|
FModifier *fcmN = copy_fmodifier(fcm);
|
2017-10-17 19:39:10 +03:00
|
|
|
|
|
|
|
fcmN->curve = curve;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2010-03-18 13:04:46 +00:00
|
|
|
/* make sure the new one isn't active, otherwise the list may get several actives */
|
|
|
|
fcmN->flag &= ~FMODIFIER_FLAG_ACTIVE;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2010-03-18 13:04:46 +00:00
|
|
|
/* now add it to the end of the list */
|
|
|
|
BLI_addtail(modifiers, fcmN);
|
|
|
|
ok = 1;
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2017-10-17 19:39:10 +03:00
|
|
|
/* adding or removing the Cycles modifier requires an update to handles */
|
|
|
|
if (curve && BKE_fcurve_is_cyclic(curve) != was_cyclic)
|
|
|
|
calchandles_fcurve(curve);
|
|
|
|
|
2010-03-18 13:04:46 +00:00
|
|
|
/* did we succeed? */
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ********************************************** */
|