* Keyframing operators now use the reports system for displaying all its error messages. - The benefit of this is that users no longer need to check the console for error messages if keyframing fails. - Unfortunately, reports are not currently viewable in any space/view in Blender, so... * Added a temporary operator (UI_OT_reports_to_textblock), which can be accessed in the UI from the button which appears in place of the icon when more than one report exists. This dumps the current list of reports to a textblock "Recent Reports", from which they can be viewed. This isn't really nice, but at least we now have a way to view these again, which makes debugging some things a pain. * Bugfix #24606 - when trying to add keyframes to F-Curves with F-Modifiers already which alter the curve significantly enough that the keyframes will have no effect, there are now warnings which aim to alleviate any confusion.
246 lines
6.8 KiB
C
246 lines
6.8 KiB
C
/**
|
|
* $Id$
|
|
*
|
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
|
*
|
|
* 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
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* 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,
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* The Original Code is Copyright (C) 2009 Blender Foundation.
|
|
* All rights reserved.
|
|
*
|
|
*
|
|
* Contributor(s): Blender Foundation, Joshua Leung
|
|
*
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <math.h>
|
|
#include <float.h>
|
|
|
|
#include "DNA_anim_types.h"
|
|
#include "DNA_space_types.h"
|
|
#include "DNA_screen_types.h"
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
#include "BLI_math.h"
|
|
#include "BLI_blenlib.h"
|
|
#include "BLI_editVert.h"
|
|
#include "BLI_rand.h"
|
|
|
|
#include "BKE_context.h"
|
|
#include "BKE_fcurve.h"
|
|
|
|
|
|
#include "WM_api.h"
|
|
|
|
|
|
#include "ED_anim_api.h"
|
|
|
|
|
|
#include "graph_intern.h" // own include
|
|
|
|
/* ************************************************************** */
|
|
/* Active F-Curve */
|
|
|
|
/* Find 'active' F-Curve. It must be editable, since that's the purpose of these buttons (subject to change).
|
|
* We return the 'wrapper' since it contains valuable context info (about hierarchy), which will need to be freed
|
|
* when the caller is done with it.
|
|
*/
|
|
bAnimListElem *get_active_fcurve_channel (bAnimContext *ac)
|
|
{
|
|
ListBase anim_data = {NULL, NULL};
|
|
int filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_ACTIVE | ANIMFILTER_CURVESONLY);
|
|
int items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
|
|
|
/* We take the first F-Curve only, since some other ones may have had 'active' flag set
|
|
* if they were from linked data.
|
|
*/
|
|
if (items) {
|
|
bAnimListElem *ale= (bAnimListElem *)anim_data.first;
|
|
|
|
/* remove first item from list, then free the rest of the list and return the stored one */
|
|
BLI_remlink(&anim_data, ale);
|
|
BLI_freelistN(&anim_data);
|
|
|
|
return ale;
|
|
}
|
|
|
|
/* no active F-Curve */
|
|
return NULL;
|
|
}
|
|
|
|
/* ************************************************************** */
|
|
/* Operator Polling Callbacks */
|
|
|
|
/* Check if there are any visible keyframes (for selection tools) */
|
|
int graphop_visible_keyframes_poll (bContext *C)
|
|
{
|
|
bAnimContext ac;
|
|
bAnimListElem *ale;
|
|
ListBase anim_data = {NULL, NULL};
|
|
ScrArea *sa= CTX_wm_area(C);
|
|
int filter, items;
|
|
short found = 0;
|
|
|
|
/* firstly, check if in Graph Editor */
|
|
// TODO: also check for region?
|
|
if ((sa == NULL) || (sa->spacetype != SPACE_IPO))
|
|
return 0;
|
|
|
|
/* try to init Anim-Context stuff ourselves and check */
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
return 0;
|
|
|
|
/* loop over the visible (selection doesn't matter) F-Curves, and see if they're suitable
|
|
* stopping on the first successful match
|
|
*/
|
|
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY);
|
|
items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
|
|
if (items == 0)
|
|
return 0;
|
|
|
|
for (ale = anim_data.first; ale; ale= ale->next) {
|
|
FCurve *fcu= (FCurve *)ale->data;
|
|
|
|
/* visible curves for selection must fulfull the following criteria:
|
|
* - it has bezier keyframes
|
|
* - F-Curve modifiers do not interfere with the result too much
|
|
* (i.e. the modifier-control drawing check returns false)
|
|
*/
|
|
if (fcu->bezt == NULL)
|
|
continue;
|
|
if (fcurve_are_keyframes_usable(fcu)) {
|
|
found = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* cleanup and return findings */
|
|
BLI_freelistN(&anim_data);
|
|
return found;
|
|
}
|
|
|
|
/* Check if there are any visible + editable keyframes (for editing tools) */
|
|
int graphop_editable_keyframes_poll (bContext *C)
|
|
{
|
|
bAnimContext ac;
|
|
bAnimListElem *ale;
|
|
ListBase anim_data = {NULL, NULL};
|
|
ScrArea *sa= CTX_wm_area(C);
|
|
int filter, items;
|
|
short found = 0;
|
|
|
|
/* firstly, check if in Graph Editor */
|
|
// TODO: also check for region?
|
|
if ((sa == NULL) || (sa->spacetype != SPACE_IPO))
|
|
return 0;
|
|
|
|
/* try to init Anim-Context stuff ourselves and check */
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
return 0;
|
|
|
|
/* loop over the editable F-Curves, and see if they're suitable
|
|
* stopping on the first successful match
|
|
*/
|
|
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
|
|
items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
|
|
if (items == 0)
|
|
return 0;
|
|
|
|
for (ale = anim_data.first; ale; ale= ale->next) {
|
|
FCurve *fcu= (FCurve *)ale->data;
|
|
|
|
/* editable curves must fulfull the following criteria:
|
|
* - it has bezier keyframes
|
|
* - it must not be protected from editing (this is already checked for with the foredit flag
|
|
* - F-Curve modifiers do not interfere with the result too much
|
|
* (i.e. the modifier-control drawing check returns false)
|
|
*/
|
|
if (fcu->bezt == NULL)
|
|
continue;
|
|
if (fcurve_is_keyframable(fcu)) {
|
|
found = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* cleanup and return findings */
|
|
BLI_freelistN(&anim_data);
|
|
return found;
|
|
}
|
|
|
|
/* has active F-Curve that's editable */
|
|
int graphop_active_fcurve_poll (bContext *C)
|
|
{
|
|
bAnimContext ac;
|
|
bAnimListElem *ale;
|
|
ScrArea *sa= CTX_wm_area(C);
|
|
short has_fcurve= 0;
|
|
|
|
/* firstly, check if in Graph Editor */
|
|
// TODO: also check for region?
|
|
if ((sa == NULL) || (sa->spacetype != SPACE_IPO))
|
|
return 0;
|
|
|
|
/* try to init Anim-Context stuff ourselves and check */
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
return 0;
|
|
|
|
/* try to get the Active F-Curve */
|
|
ale= get_active_fcurve_channel(&ac);
|
|
if (ale == NULL)
|
|
return 0;
|
|
|
|
/* free temp data... */
|
|
has_fcurve= ((ale->data) && (ale->type == ANIMTYPE_FCURVE));
|
|
MEM_freeN(ale);
|
|
|
|
/* return success */
|
|
return has_fcurve;
|
|
}
|
|
|
|
/* has selected F-Curve that's editable */
|
|
int graphop_selected_fcurve_poll (bContext *C)
|
|
{
|
|
bAnimContext ac;
|
|
ListBase anim_data = {NULL, NULL};
|
|
ScrArea *sa= CTX_wm_area(C);
|
|
int filter, items;
|
|
|
|
/* firstly, check if in Graph Editor */
|
|
// TODO: also check for region?
|
|
if ((sa == NULL) || (sa->spacetype != SPACE_IPO))
|
|
return 0;
|
|
|
|
/* try to init Anim-Context stuff ourselves and check */
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
return 0;
|
|
|
|
/* get the editable + selected F-Curves, and as long as we got some, we can return */
|
|
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
|
|
items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
|
|
if (items == 0)
|
|
return 0;
|
|
|
|
/* cleanup and return findings */
|
|
BLI_freelistN(&anim_data);
|
|
return 1;
|
|
}
|
|
|
|
/* ************************************************************** */
|