Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_fcurve.h8
-rw-r--r--source/blender/blenkernel/intern/fcurve.c103
-rw-r--r--source/blender/editors/animation/anim_channels_defines.c6
-rw-r--r--source/blender/editors/animation/keyframing.c50
-rw-r--r--source/blender/editors/animation/keyingsets.c5
-rw-r--r--source/blender/editors/include/ED_anim_api.h4
-rw-r--r--source/blender/editors/include/ED_keyframing.h7
-rw-r--r--source/blender/editors/interface/interface_anim.c3
-rw-r--r--source/blender/editors/interface/interface_ops.c51
-rw-r--r--source/blender/editors/interface/interface_templates.c16
-rw-r--r--source/blender/editors/space_action/action_edit.c3
-rw-r--r--source/blender/editors/space_graph/graph_draw.c2
-rw-r--r--source/blender/editors/space_graph/graph_edit.c43
-rw-r--r--source/blender/editors/space_graph/graph_utils.c69
-rw-r--r--source/blender/editors/transform/transform_conversions.c7
-rw-r--r--source/blender/python/intern/bpy_rna.c4
16 files changed, 254 insertions, 127 deletions
diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h
index 8dbfb4f2c73..46392c2c8ea 100644
--- a/source/blender/blenkernel/BKE_fcurve.h
+++ b/source/blender/blenkernel/BKE_fcurve.h
@@ -214,6 +214,14 @@ void calc_fcurve_range(struct FCurve *fcu, float *min, float *max);
/* get the bounding-box extents for F-Curve */
void calc_fcurve_bounds(struct FCurve *fcu, float *xmin, float *xmax, float *ymin, float *ymax);
+/* .............. */
+
+/* Are keyframes on F-Curve of any use (to final result, and to show in editors)? */
+short fcurve_are_keyframes_usable(struct FCurve *fcu);
+
+/* Can keyframes be added to F-Curve? */
+short fcurve_is_keyframable(struct FCurve *fcu);
+
/* -------- Curve Sanity -------- */
void calchandles_fcurve(struct FCurve *fcu);
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 75029af4b10..2f886d8ab43 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -163,7 +163,7 @@ void copy_fcurves (ListBase *dst, ListBase *src)
}
}
-/* --------------------- Finding -------------------------- */
+/* ----------------- Finding F-Curves -------------------------- */
/* high level function to get an fcurve from C without having the rna */
FCurve *id_data_find_fcurve(ID *id, void *data, StructRNA *type, char *prop_name, int index)
@@ -298,36 +298,36 @@ int list_find_data_fcurves (ListBase *dst, ListBase *src, const char *dataPrefix
return matches;
}
-FCurve *rna_get_fcurve(PointerRNA *ptr, PropertyRNA *prop, int rnaindex, bAction **action, int *driven)
+FCurve *rna_get_fcurve (PointerRNA *ptr, PropertyRNA *prop, int rnaindex, bAction **action, int *driven)
{
FCurve *fcu= NULL;
*driven= 0;
/* there must be some RNA-pointer + property combon */
- if(prop && ptr->id.data && RNA_property_animateable(ptr, prop)) {
+ if (prop && ptr->id.data && RNA_property_animateable(ptr, prop)) {
AnimData *adt= BKE_animdata_from_id(ptr->id.data);
char *path;
- if(adt) {
- if((adt->action && adt->action->curves.first) || (adt->drivers.first)) {
+ if (adt) {
+ if ((adt->action && adt->action->curves.first) || (adt->drivers.first)) {
/* XXX this function call can become a performance bottleneck */
path= RNA_path_from_ID_to_property(ptr, prop);
- if(path) {
+ if (path) {
/* animation takes priority over drivers */
- if(adt->action && adt->action->curves.first)
+ if (adt->action && adt->action->curves.first)
fcu= list_find_fcurve(&adt->action->curves, path, rnaindex);
/* if not animated, check if driven */
- if(!fcu && (adt->drivers.first)) {
+ if (!fcu && (adt->drivers.first)) {
fcu= list_find_fcurve(&adt->drivers, path, rnaindex);
- if(fcu)
+ if (fcu)
*driven= 1;
}
- if(fcu && action)
+ if (fcu && action)
*action= adt->action;
MEM_freeN(path);
@@ -339,6 +339,8 @@ FCurve *rna_get_fcurve(PointerRNA *ptr, PropertyRNA *prop, int rnaindex, bAction
return fcu;
}
+/* ----------------- Finding Keyframes/Extents -------------------------- */
+
/* threshold for binary-searching keyframes - threshold here should be good enough for now, but should become userpref */
#define BEZT_BINARYSEARCH_THRESH 0.01f /* was 0.00001, but giving errors */
@@ -520,6 +522,87 @@ void calc_fcurve_range (FCurve *fcu, float *start, float *end)
}
}
+/* ----------------- Status Checks -------------------------- */
+
+/* Are keyframes on F-Curve of any use?
+ * Usability of keyframes refers to whether they should be displayed,
+ * and also whether they will have any influence on the final result.
+ */
+short fcurve_are_keyframes_usable (FCurve *fcu)
+{
+ /* F-Curve must exist */
+ if (fcu == NULL)
+ return 0;
+
+ /* F-Curve must not have samples - samples are mutually exclusive of keyframes */
+ if (fcu->fpt)
+ return 0;
+
+ /* if it has modifiers, none of these should "drastically" alter the curve */
+ if (fcu->modifiers.first) {
+ FModifier *fcm;
+
+ /* check modifiers from last to first, as last will be more influential */
+ // TODO: optionally, only check modifier if it is the active one...
+ for (fcm = fcu->modifiers.last; fcm; fcm = fcm->prev) {
+ /* ignore if muted/disabled */
+ if (fcm->flag & (FMODIFIER_FLAG_DISABLED|FMODIFIER_FLAG_MUTED))
+ continue;
+
+ /* type checks */
+ switch (fcm->type) {
+ /* clearly harmless - do nothing */
+ case FMODIFIER_TYPE_CYCLES:
+ case FMODIFIER_TYPE_STEPPED:
+ case FMODIFIER_TYPE_NOISE:
+ break;
+
+ /* sometimes harmful - depending on whether they're "additive" or not */
+ case FMODIFIER_TYPE_GENERATOR:
+ {
+ FMod_Generator *data = (FMod_Generator *)fcm->data;
+
+ if ((data->flag & FCM_GENERATOR_ADDITIVE) == 0)
+ return 0;
+ }
+ break;
+ case FMODIFIER_TYPE_FN_GENERATOR:
+ {
+ FMod_FunctionGenerator *data = (FMod_FunctionGenerator *)fcm->data;
+
+ if ((data->flag & FCM_GENERATOR_ADDITIVE) == 0)
+ return 0;
+ }
+ break;
+
+ /* always harmful - cannot allow */
+ default:
+ return 0;
+ }
+ }
+ }
+
+ /* keyframes are usable */
+ return 1;
+}
+
+/* Can keyframes be added to F-Curve?
+ * Keyframes can only be added if they are already visible
+ */
+short fcurve_is_keyframable (FCurve *fcu)
+{
+ /* F-Curve's keyframes must be "usable" (i.e. visible + have an effect on final result) */
+ if (fcurve_are_keyframes_usable(fcu) == 0)
+ return 0;
+
+ /* F-Curve must currently be editable too */
+ if ( (fcu->flag & FCURVE_PROTECTED) || ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) )
+ return 0;
+
+ /* F-Curve is keyframable */
+ return 1;
+}
+
/* ***************************** Keyframe Column Tools ********************************* */
/* add a BezTriple to a column */
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c
index 9121d8cd66c..4d28bed0ffb 100644
--- a/source/blender/editors/animation/anim_channels_defines.c
+++ b/source/blender/editors/animation/anim_channels_defines.c
@@ -2917,6 +2917,7 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi
ID *id= (ID *)id_poin;
FCurve *fcu= (FCurve *)fcu_poin;
+ ReportList *reports = CTX_wm_reports(C);
Scene *scene= CTX_data_scene(C);
PointerRNA id_ptr, ptr;
PropertyRNA *prop;
@@ -2940,7 +2941,7 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi
flag |= INSERTKEY_REPLACE;
/* insert a keyframe for this F-Curve */
- done= insert_keyframe_direct(ptr, prop, fcu, cfra, flag);
+ done= insert_keyframe_direct(reports, ptr, prop, fcu, cfra, flag);
if (done)
WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN|NA_EDITED, NULL);
@@ -2954,6 +2955,7 @@ static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, voi
KeyBlock *kb= (KeyBlock *)kb_poin;
char *rna_path= key_get_curValue_rnaPath(key, kb);
+ ReportList *reports = CTX_wm_reports(C);
Scene *scene= CTX_data_scene(C);
PointerRNA id_ptr, ptr;
PropertyRNA *prop;
@@ -2982,7 +2984,7 @@ static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, voi
flag |= INSERTKEY_REPLACE;
/* insert a keyframe for this F-Curve */
- done= insert_keyframe_direct(ptr, prop, fcu, cfra, flag);
+ done= insert_keyframe_direct(reports, ptr, prop, fcu, cfra, flag);
if (done)
WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN|NA_EDITED, NULL);
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index 7f99a5e3b47..fd8487973c8 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -697,25 +697,26 @@ static float visualkey_get_value (PointerRNA *ptr, PropertyRNA *prop, int array_
* the keyframe insertion. These include the 'visual' keyframing modes, quick refresh,
* and extra keyframe filtering.
*/
-short insert_keyframe_direct (PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, float cfra, short flag)
+short insert_keyframe_direct (ReportList *reports, PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, float cfra, short flag)
{
float curval= 0.0f;
/* no F-Curve to add keyframe to? */
if (fcu == NULL) {
- printf("ERROR: no F-Curve to add keyframes to \n");
+ BKE_report(reports, RPT_ERROR, "No F-Curve to add keyframes to");
return 0;
}
/* F-Curve not editable? */
- if ( (fcu->flag & FCURVE_PROTECTED) || ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) ) {
- if (G.f & G_DEBUG)
- printf("WARNING: not inserting keyframe for locked F-Curve \n");
+ if (fcurve_is_keyframable(fcu) == 0) {
+ BKE_reportf(reports, RPT_ERROR,
+ "F-Curve with path = '%s' [%d] cannot be keyframed. Ensure that it is not locked or sampled. Also, try removing F-Modifiers.",
+ fcu->rna_path, fcu->array_index);
return 0;
}
/* if no property given yet, try to validate from F-Curve info */
if ((ptr.id.data == NULL) && (ptr.data==NULL)) {
- printf("ERROR: no RNA-pointer available to retrieve values for keyframing from\n");
+ BKE_report(reports, RPT_ERROR, "No RNA-pointer available to retrieve values for keyframing from");
return 0;
}
if (prop == NULL) {
@@ -726,7 +727,9 @@ short insert_keyframe_direct (PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, fl
/* property not found... */
char *idname= (ptr.id.data) ? ((ID *)ptr.id.data)->name : "<No ID-Pointer>";
- printf("Insert Key: Could not insert keyframe, as RNA Path is invalid for the given ID (ID = %s, Path = %s)\n", idname, fcu->rna_path);
+ BKE_reportf(reports, RPT_ERROR,
+ "Could not insert keyframe, as RNA Path is invalid for the given ID (ID = %s, Path = %s)",
+ idname, fcu->rna_path);
return 0;
}
else {
@@ -815,7 +818,7 @@ short insert_keyframe_direct (PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, fl
*
* index of -1 keys all array indices
*/
-short insert_keyframe (ID *id, bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short flag)
+short insert_keyframe (ReportList *reports, ID *id, bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short flag)
{
PointerRNA id_ptr, ptr;
PropertyRNA *prop = NULL;
@@ -825,13 +828,14 @@ short insert_keyframe (ID *id, bAction *act, const char group[], const char rna_
/* validate pointer first - exit if failure */
if (id == NULL) {
- printf("Insert Key: no ID-block to insert keyframe in (Path = %s) \n", rna_path);
+ BKE_reportf(reports, RPT_ERROR, "No ID-block to insert keyframe in (Path = %s)", rna_path);
return 0;
}
RNA_id_pointer_create(id, &id_ptr);
if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) {
- printf("Insert Key: Could not insert keyframe, as RNA Path is invalid for the given ID (ID = %s, Path = %s)\n",
+ BKE_reportf(reports, RPT_ERROR,
+ "Could not insert keyframe, as RNA Path is invalid for the given ID (ID = %s, Path = %s)",
(id)? id->name : "<Missing ID-Block>", rna_path);
return 0;
}
@@ -844,7 +848,9 @@ short insert_keyframe (ID *id, bAction *act, const char group[], const char rna_
act= verify_adt_action(id, 1);
if (act == NULL) {
- printf("Insert Key: Could not insert keyframe, as this type does not support animation data (ID = %s, Path = %s)\n", id->name, rna_path);
+ BKE_reportf(reports, RPT_ERROR,
+ "Could not insert keyframe, as this type does not support animation data (ID = %s, Path = %s)",
+ id->name, rna_path);
return 0;
}
@@ -900,7 +906,7 @@ short insert_keyframe (ID *id, bAction *act, const char group[], const char rna_
}
/* insert keyframe */
- ret += insert_keyframe_direct(ptr, prop, fcu, cfra, flag);
+ ret += insert_keyframe_direct(reports, ptr, prop, fcu, cfra, flag);
}
}
@@ -917,7 +923,7 @@ short insert_keyframe (ID *id, bAction *act, const char group[], const char rna_
* The flag argument is used for special settings that alter the behaviour of
* the keyframe deletion. These include the quick refresh options.
*/
-short delete_keyframe (ID *id, bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short UNUSED(flag))
+short delete_keyframe (ReportList *reports, ID *id, bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short UNUSED(flag))
{
AnimData *adt= BKE_animdata_from_id(id);
PointerRNA id_ptr, ptr;
@@ -927,14 +933,14 @@ short delete_keyframe (ID *id, bAction *act, const char group[], const char rna_
/* sanity checks */
if ELEM(NULL, id, adt) {
- printf("ERROR: no ID-block and/or AnimData to delete keyframe from \n");
+ BKE_report(reports, RPT_ERROR, "No ID-Block and/Or AnimData to delete keyframe from");
return 0;
}
/* validate pointer first - exit if failure */
RNA_id_pointer_create(id, &id_ptr);
if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) {
- printf("Delete Key: Could not delete keyframe, as RNA Path is invalid for the given ID (ID = %s, Path = %s)\n", id->name, rna_path);
+ BKE_reportf(reports, RPT_ERROR, "Could not delete keyframe, as RNA Path is invalid for the given ID (ID = %s, Path = %s)", id->name, rna_path);
return 0;
}
@@ -953,7 +959,7 @@ short delete_keyframe (ID *id, bAction *act, const char group[], const char rna_
cfra= BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
}
else {
- printf("ERROR: no Action to delete keyframes from for ID = %s \n", id->name);
+ BKE_reportf(reports, RPT_ERROR, "No Action to delete keyframes from for ID = %s \n", id->name);
return 0;
}
}
@@ -997,7 +1003,7 @@ short delete_keyframe (ID *id, bAction *act, const char group[], const char rna_
if ( (fcu->flag & FCURVE_PROTECTED) || ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) ) {
if (G.f & G_DEBUG)
- printf("WARNING: not inserting keyframe for locked F-Curve \n");
+ printf("WARNING: not deleting keyframe for locked F-Curve \n");
continue;
}
@@ -1308,7 +1314,7 @@ static int delete_key_v3d_exec (bContext *C, wmOperator *op)
for (fcu= act->curves.first; fcu; fcu= fcn) {
fcn= fcu->next;
- success+= delete_keyframe(id, NULL, NULL, fcu->rna_path, fcu->array_index, cfra, 0);
+ success+= delete_keyframe(op->reports, id, NULL, NULL, fcu->rna_path, fcu->array_index, cfra, 0);
}
}
@@ -1378,7 +1384,7 @@ static int insert_key_button_exec (bContext *C, wmOperator *op)
length= 1;
for (a=0; a<length; a++)
- success+= insert_keyframe(ptr.id.data, NULL, NULL, path, index+a, cfra, flag);
+ success+= insert_keyframe(op->reports, ptr.id.data, NULL, NULL, path, index+a, cfra, flag);
MEM_freeN(path);
}
@@ -1387,7 +1393,7 @@ static int insert_key_button_exec (bContext *C, wmOperator *op)
NlaStrip *strip= (NlaStrip *)ptr.data;
FCurve *fcu= list_find_fcurve(&strip->fcurves, RNA_property_identifier(prop), flag);
- success+= insert_keyframe_direct(ptr, prop, fcu, cfra, 0);
+ success+= insert_keyframe_direct(op->reports, ptr, prop, fcu, cfra, 0);
}
else {
if (G.f & G_DEBUG)
@@ -1456,14 +1462,14 @@ static int delete_key_button_exec (bContext *C, wmOperator *op)
if (all) {
length= RNA_property_array_length(&ptr, prop);
- if(length) index= 0;
+ if (length) index= 0;
else length= 1;
}
else
length= 1;
for (a=0; a<length; a++)
- success+= delete_keyframe(ptr.id.data, NULL, NULL, path, index+a, cfra, 0);
+ success+= delete_keyframe(op->reports, ptr.id.data, NULL, NULL, path, index+a, cfra, 0);
MEM_freeN(path);
}
diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c
index 643ba96f7fe..5d96c015caa 100644
--- a/source/blender/editors/animation/keyingsets.c
+++ b/source/blender/editors/animation/keyingsets.c
@@ -818,6 +818,7 @@ void ANIM_relative_keyingset_add_source (ListBase *dsources, ID *id, StructRNA *
int ANIM_apply_keyingset (bContext *C, ListBase *dsources, bAction *act, KeyingSet *ks, short mode, float cfra)
{
Scene *scene= CTX_data_scene(C);
+ ReportList *reports = CTX_wm_reports(C);
KS_Path *ksp;
int kflag=0, success= 0;
char *groupname= NULL;
@@ -913,9 +914,9 @@ int ANIM_apply_keyingset (bContext *C, ListBase *dsources, bAction *act, KeyingS
for (; i < arraylen; i++) {
/* action to take depends on mode */
if (mode == MODIFYKEY_MODE_INSERT)
- success += insert_keyframe(ksp->id, act, groupname, ksp->rna_path, i, cfra, kflag2);
+ success += insert_keyframe(reports, ksp->id, act, groupname, ksp->rna_path, i, cfra, kflag2);
else if (mode == MODIFYKEY_MODE_DELETE)
- success += delete_keyframe(ksp->id, act, groupname, ksp->rna_path, i, cfra, kflag2);
+ success += delete_keyframe(reports, ksp->id, act, groupname, ksp->rna_path, i, cfra, kflag2);
}
/* set recalc-flags */
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index 40478ddcbc2..ce2d6044e1a 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -35,6 +35,7 @@ struct AnimData;
struct bContext;
struct wmKeyConfig;
+struct ReportList;
struct ScrArea;
struct ARegion;
struct View2D;
@@ -73,7 +74,8 @@ typedef struct bAnimContext {
struct Scene *scene; /* active scene */
struct Object *obact; /* active object */
ListBase *markers; /* active set of markers */
- ListBase *reports; /* pointer to current reports list */ // XXX not yet used
+
+ struct ReportList *reports; /* pointer to current reports list */
} bAnimContext;
/* Main Data container types */
diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h
index d2f30939fbb..ff4ec92562f 100644
--- a/source/blender/editors/include/ED_keyframing.h
+++ b/source/blender/editors/include/ED_keyframing.h
@@ -47,6 +47,7 @@ struct bConstraint;
struct bContext;
struct wmOperatorType;
+struct ReportList;
struct PointerRNA;
struct PropertyRNA;
@@ -93,7 +94,7 @@ int insert_vert_fcurve(struct FCurve *fcu, float x, float y, short flag);
* Use this to insert a keyframe using the current value being keyframed, in the
* nominated F-Curve (no creation of animation data performed). Returns success.
*/
-short insert_keyframe_direct(struct PointerRNA ptr, struct PropertyRNA *prop, struct FCurve *fcu, float cfra, short flag);
+short insert_keyframe_direct(struct ReportList *reports, struct PointerRNA ptr, struct PropertyRNA *prop, struct FCurve *fcu, float cfra, short flag);
/* -------- */
@@ -101,12 +102,12 @@ short insert_keyframe_direct(struct PointerRNA ptr, struct PropertyRNA *prop, st
* Use this to create any necessary animation data, and then insert a keyframe
* using the current value being keyframed, in the relevant place. Returns success.
*/
-short insert_keyframe(struct ID *id, struct bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short flag);
+short insert_keyframe(struct ReportList *reports, struct ID *id, struct bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short flag);
/* Main Keyframing API call:
* Use this to delete keyframe on current frame for relevant channel. Will perform checks just in case.
*/
-short delete_keyframe(struct ID *id, struct bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short flag);
+short delete_keyframe(struct ReportList *reports, struct ID *id, struct bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short flag);
/* ************ Keying Sets ********************** */
diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c
index 2a30a36ffe0..4021e4208dc 100644
--- a/source/blender/editors/interface/interface_anim.c
+++ b/source/blender/editors/interface/interface_anim.c
@@ -105,10 +105,11 @@ void ui_but_anim_autokey(bContext *C, uiBut *but, Scene *scene, float cfra)
// TODO: this should probably respect the keyingset only option for anim
if(autokeyframe_cfra_can_key(scene, id)) {
+ ReportList *reports = CTX_wm_reports(C);
short flag = ANIM_get_keyframing_flags(scene, 1);
fcu->flag &= ~FCURVE_SELECTED;
- insert_keyframe(id, action, ((fcu->grp)?(fcu->grp->name):(NULL)), fcu->rna_path, fcu->array_index, cfra, flag);
+ insert_keyframe(reports, id, action, ((fcu->grp)?(fcu->grp->name):(NULL)), fcu->rna_path, fcu->array_index, cfra, flag);
WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_EDITED, NULL);
}
}
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 10458a763e6..b4a6f9e77a3 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -34,11 +34,15 @@
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
+#include "DNA_text_types.h" /* for UI_OT_reports_to_text */
#include "BLI_blenlib.h"
#include "BLI_math_color.h"
#include "BKE_context.h"
+#include "BKE_global.h"
+#include "BKE_text.h" /* for UI_OT_reports_to_text */
+#include "BKE_report.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -402,7 +406,51 @@ void UI_OT_copy_to_selected_button(wmOperatorType *ot)
/* properties */
RNA_def_boolean(ot->srna, "all", 1, "All", "Reset to default values all elements of the array.");
}
-
+
+/* Reports to Textblock Operator ------------------------ */
+
+/* FIXME: this is just a temporary operator so that we can see all the reports somewhere
+ * when there are too many to display...
+ */
+
+static int reports_to_text_poll(bContext *C)
+{
+ return CTX_wm_reports(C) != NULL;
+}
+
+static int reports_to_text_exec(bContext *C, wmOperator *op)
+{
+ ReportList *reports = CTX_wm_reports(C);
+ Text *txt;
+ char *str;
+
+ /* create new text-block to write to */
+ txt = add_empty_text("Recent Reports");
+
+ /* convert entire list to a display string, and add this to the text-block
+ * - if commandline debug option enabled, show debug reports too
+ * - otherwise, up to info (which is what users normally see)
+ */
+ str = BKE_reports_string(reports, (G.f & G_DEBUG)? RPT_DEBUG : RPT_INFO);
+
+ write_text(txt, str);
+ MEM_freeN(str);
+
+ return OPERATOR_FINISHED;
+}
+
+void UI_OT_reports_to_textblock(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Reports to Text Block";
+ ot->idname= "UI_OT_reports_to_textblock";
+ ot->description= "Write the reports ";
+
+ /* callbacks */
+ ot->poll= reports_to_text_poll;
+ ot->exec= reports_to_text_exec;
+}
+
/* ********************************************************* */
/* Registration */
@@ -413,5 +461,6 @@ void UI_buttons_operatortypes(void)
WM_operatortype_append(UI_OT_copy_data_path_button);
WM_operatortype_append(UI_OT_reset_default_button);
WM_operatortype_append(UI_OT_copy_to_selected_button);
+ WM_operatortype_append(UI_OT_reports_to_textblock); // XXX: temp?
}
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index a5964d595dd..8237e175794 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -2331,6 +2331,7 @@ void uiTemplateReportsBanner(uiLayout *layout, bContext *C)
uiBut *but;
uiStyle *style= U.uistyles.first;
int width;
+ int icon=0;
/* if the report display has timed out, don't show */
if (!reports->reporttimer) return;
@@ -2364,13 +2365,20 @@ void uiTemplateReportsBanner(uiLayout *layout, bContext *C)
/* icon and report message on top */
if(report->type & RPT_ERROR_ALL)
- uiDefIconBut(block, LABEL, 0, ICON_ERROR, 2, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "");
+ icon = ICON_ERROR;
else if(report->type & RPT_WARNING_ALL)
- uiDefIconBut(block, LABEL, 0, ICON_ERROR, 2, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "");
+ icon = ICON_ERROR;
else if(report->type & RPT_INFO_ALL)
- uiDefIconBut(block, LABEL, 0, ICON_INFO, 2, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "");
+ icon = ICON_INFO;
+
+ /* XXX: temporary operator to dump all reports to a text block, but only if more than 1 report
+ * to be shown instead of icon when appropriate...
+ */
+ if (reports->list.first != reports->list.last)
+ uiDefIconButO(block, BUT, "UI_OT_reports_to_textblock", WM_OP_INVOKE_REGION_WIN, icon, 2, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Click to see rest of reports in textblock: 'Recent Reports'");
+ else
+ uiDefIconBut(block, LABEL, 0, icon, 2, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "");
uiDefBut(block, LABEL, 0, report->message, UI_UNIT_X+10, 0, UI_UNIT_X+width, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "");
-
}
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index 32bb02ddcda..4d35b5ca4ff 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -410,6 +410,7 @@ static void insert_action_keys(bAnimContext *ac, short mode)
bAnimListElem *ale;
int filter;
+ ReportList *reports = ac->reports;
Scene *scene= ac->scene;
float cfra= (float)CFRA;
short flag = 0;
@@ -437,7 +438,7 @@ static void insert_action_keys(bAnimContext *ac, short mode)
/* if there's an id */
if (ale->id)
- insert_keyframe(ale->id, NULL, ((fcu->grp)?(fcu->grp->name):(NULL)), fcu->rna_path, fcu->array_index, cfra, flag);
+ insert_keyframe(reports, ale->id, NULL, ((fcu->grp)?(fcu->grp->name):(NULL)), fcu->rna_path, fcu->array_index, cfra, flag);
else
insert_vert_fcurve(fcu, cfra, fcu->curval, 0);
}
diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c
index 01a8ba4797c..1f92f32cc88 100644
--- a/source/blender/editors/space_graph/graph_draw.c
+++ b/source/blender/editors/space_graph/graph_draw.c
@@ -899,7 +899,7 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGri
* - if the option to only show controls if the F-Curve is selected is enabled, we must obey this
*/
if (!(sipo->flag & SIPO_SELCUVERTSONLY) || (fcu->flag & FCURVE_SELECTED)) {
- if (fcurve_needs_draw_fmodifier_controls(fcu, fcm)) {
+ if (fcurve_are_keyframes_usable(fcu) == 0) {
/* only draw controls if this is the active modifier */
if ((fcu->flag & FCURVE_ACTIVE) && (fcm)) {
switch (fcm->type) {
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index e1d1e4194d5..35307a78e65 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -406,6 +406,7 @@ static void insert_graph_keys(bAnimContext *ac, short mode)
bAnimListElem *ale;
int filter;
+ ReportList *reports = ac->reports;
Scene *scene= ac->scene;
float cfra= (float)CFRA;
short flag = 0;
@@ -432,7 +433,7 @@ static void insert_graph_keys(bAnimContext *ac, short mode)
/* if there's an id */
if (ale->id)
- insert_keyframe(ale->id, NULL, ((fcu->grp)?(fcu->grp->name):(NULL)), fcu->rna_path, fcu->array_index, cfra, flag);
+ insert_keyframe(reports, ale->id, NULL, ((fcu->grp)?(fcu->grp->name):(NULL)), fcu->rna_path, fcu->array_index, cfra, flag);
else
insert_vert_fcurve(fcu, cfra, fcu->curval, 0);
}
@@ -507,19 +508,33 @@ static int graphkeys_click_insert_exec (bContext *C, wmOperator *op)
}
fcu = ale->data;
- /* 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);
-
- /* apply inverse unit-mapping to value to get correct value for F-Curves */
- val *= ANIM_unit_mapping_get_factor(ac.scene, ale->id, fcu, 1);
-
- /* insert keyframe on the specified frame + value */
- insert_vert_fcurve(fcu, frame, val, 0);
+ /* when there are F-Modifiers on the curve, only allow adding
+ * keyframes if these will be visible after doing so...
+ */
+ if (fcurve_is_keyframable(fcu)) {
+ /* 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);
+
+ /* apply inverse unit-mapping to value to get correct value for F-Curves */
+ val *= ANIM_unit_mapping_get_factor(ac.scene, ale->id, fcu, 1);
+
+ /* insert keyframe on the specified frame + value */
+ insert_vert_fcurve(fcu, frame, val, 0);
+ }
+ else {
+ /* warn about why this can't happen */
+ if (fcu->fpt)
+ BKE_report(op->reports, RPT_ERROR, "Keyframes cannot be added to sampled F-Curves");
+ else if (fcu->flag & FCURVE_PROTECTED)
+ BKE_report(op->reports, RPT_ERROR, "Active F-Curve is not editable");
+ else
+ BKE_report(op->reports, RPT_ERROR, "Remove F-Modifiers from F-Curve to add keyframes");
+ }
/* free temp data */
MEM_freeN(ale);
diff --git a/source/blender/editors/space_graph/graph_utils.c b/source/blender/editors/space_graph/graph_utils.c
index 927149a268d..417d92782cc 100644
--- a/source/blender/editors/space_graph/graph_utils.c
+++ b/source/blender/editors/space_graph/graph_utils.c
@@ -87,57 +87,6 @@ bAnimListElem *get_active_fcurve_channel (bAnimContext *ac)
/* ************************************************************** */
/* Operator Polling Callbacks */
-/* check if any FModifiers to draw controls for - fcm is 'active' modifier
- * used for the polling callbacks + also for drawing
- */
-// TODO: restructure these tests
-// TODO: maybe for now, just allow editing always for now...
-short fcurve_needs_draw_fmodifier_controls (FCurve *fcu, FModifier *fcm)
-{
- /* don't draw if there aren't any modifiers at all */
- if (fcu->modifiers.first == NULL)
- return 0;
-
- /* if only one modifier
- * - don't draw if it is muted or disabled
- * - set it as the active one if no active one is present
- */
- if (fcu->modifiers.first == fcu->modifiers.last) {
- fcm= fcu->modifiers.first;
- if (fcm->flag & (FMODIFIER_FLAG_DISABLED|FMODIFIER_FLAG_MUTED))
- return 0;
- }
-
- /* if there's an active modifier - don't draw if it doesn't drastically
- * alter the curve...
- */
- if (fcm) {
- switch (fcm->type) {
- /* clearly harmless */
- case FMODIFIER_TYPE_CYCLES:
- return 0;
- case FMODIFIER_TYPE_STEPPED:
- return 0;
-
- /* borderline... */
- case FMODIFIER_TYPE_NOISE:
- return 0;
- }
- }
-
- /* if only active modifier - don't draw if it is muted or disabled */
- if (fcm) {
- if (fcm->flag & (FMODIFIER_FLAG_DISABLED|FMODIFIER_FLAG_MUTED))
- return 0;
- }
-
- /* if we're still here, this means that there are modifiers with controls to be drawn */
- // FIXME: what happens if all the modifiers were muted/disabled
- return 1;
-}
-
-/* ------------------- */
-
/* Check if there are any visible keyframes (for selection tools) */
int graphop_visible_keyframes_poll (bContext *C)
{
@@ -167,7 +116,6 @@ int graphop_visible_keyframes_poll (bContext *C)
for (ale = anim_data.first; ale; ale= ale->next) {
FCurve *fcu= (FCurve *)ale->data;
- FModifier *fcm;
/* visible curves for selection must fulfull the following criteria:
* - it has bezier keyframes
@@ -176,10 +124,10 @@ int graphop_visible_keyframes_poll (bContext *C)
*/
if (fcu->bezt == NULL)
continue;
- fcm= find_active_fmodifier(&fcu->modifiers);
-
- found= (fcurve_needs_draw_fmodifier_controls(fcu, fcm) == 0);
- if (found) break;
+ if (fcurve_are_keyframes_usable(fcu)) {
+ found = 1;
+ break;
+ }
}
/* cleanup and return findings */
@@ -216,7 +164,6 @@ int graphop_editable_keyframes_poll (bContext *C)
for (ale = anim_data.first; ale; ale= ale->next) {
FCurve *fcu= (FCurve *)ale->data;
- FModifier *fcm;
/* editable curves must fulfull the following criteria:
* - it has bezier keyframes
@@ -226,10 +173,10 @@ int graphop_editable_keyframes_poll (bContext *C)
*/
if (fcu->bezt == NULL)
continue;
- fcm= find_active_fmodifier(&fcu->modifiers);
-
- found= (fcurve_needs_draw_fmodifier_controls(fcu, fcm) == 0);
- if (found) break;
+ if (fcurve_is_keyframable(fcu)) {
+ found = 1;
+ break;
+ }
}
/* cleanup and return findings */
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 54b724d69f7..e1cda354872 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -68,6 +68,7 @@
#include "BKE_pointcache.h"
#include "BKE_bmesh.h"
#include "BKE_scene.h"
+#include "BKE_report.h"
#include "ED_anim_api.h"
@@ -4546,6 +4547,7 @@ void autokeyframe_ob_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *ob,
// TODO: this should probably be done per channel instead...
if (autokeyframe_cfra_can_key(scene, id)) {
+ ReportList *reports = CTX_wm_reports(C);
KeyingSet *active_ks = ANIM_scene_get_active_keyingset(scene);
ListBase dsources = {NULL, NULL};
float cfra= (float)CFRA; // xxx this will do for now
@@ -4570,7 +4572,7 @@ void autokeyframe_ob_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *ob,
if (adt && adt->action) {
for (fcu= adt->action->curves.first; fcu; fcu= fcu->next) {
fcu->flag &= ~FCURVE_SELECTED;
- insert_keyframe(id, adt->action, ((fcu->grp)?(fcu->grp->name):(NULL)), fcu->rna_path, fcu->array_index, cfra, flag);
+ insert_keyframe(reports, id, adt->action, ((fcu->grp)?(fcu->grp->name):(NULL)), fcu->rna_path, fcu->array_index, cfra, flag);
}
}
}
@@ -4645,6 +4647,7 @@ void autokeyframe_pose_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *o
// TODO: this should probably be done per channel instead...
if (autokeyframe_cfra_can_key(scene, id)) {
+ ReportList *reports = CTX_wm_reports(C);
KeyingSet *active_ks = ANIM_scene_get_active_keyingset(scene);
float cfra= (float)CFRA;
short flag= 0;
@@ -4686,7 +4689,7 @@ void autokeyframe_pose_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *o
* NOTE: this will do constraints too, but those are ok to do here too?
*/
if (pchanName && strcmp(pchanName, pchan->name) == 0)
- insert_keyframe(id, act, ((fcu->grp)?(fcu->grp->name):(NULL)), fcu->rna_path, fcu->array_index, cfra, flag);
+ insert_keyframe(reports, id, act, ((fcu->grp)?(fcu->grp->name):(NULL)), fcu->rna_path, fcu->array_index, cfra, flag);
if (pchanName) MEM_freeN(pchanName);
}
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index 2bffd7f6b88..8daad50f5d0 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -2122,7 +2122,7 @@ static PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *arg
if(pyrna_struct_keyframe_parse(&self->ptr, args, kw, "s|ifs:bpy_struct.keyframe_insert()", "bpy_struct.keyframe_insert()", &path_full, &index, &cfra, &group_name) == -1)
return NULL;
- result= PyBool_FromLong(insert_keyframe((ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0));
+ result= PyBool_FromLong(insert_keyframe(/*ReportList*/NULL, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0));
MEM_freeN(path_full);
return result;
@@ -2156,7 +2156,7 @@ static PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *arg
if(pyrna_struct_keyframe_parse(&self->ptr, args, kw, "s|ifs:bpy_struct.keyframe_delete()", "bpy_struct.keyframe_insert()", &path_full, &index, &cfra, &group_name) == -1)
return NULL;
- result= PyBool_FromLong(delete_keyframe((ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0));
+ result= PyBool_FromLong(delete_keyframe(/*ReportList*/NULL, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0));
MEM_freeN(path_full);
return result;