Blender  V3.3
graph_utils.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2009 Blender Foundation. All rights reserved. */
3 
8 #include <float.h>
9 #include <math.h>
10 #include <stdio.h>
11 #include <string.h>
12 
13 #include "DNA_anim_types.h"
14 #include "DNA_screen_types.h"
15 #include "DNA_space_types.h"
16 
17 #include "MEM_guardedalloc.h"
18 
19 #include "BLI_blenlib.h"
20 
21 #include "BKE_context.h"
22 #include "BKE_fcurve.h"
23 #include "BKE_screen.h"
24 
25 #include "ED_anim_api.h"
26 #include "ED_screen.h"
27 #include "UI_interface.h"
28 
29 #include "RNA_access.h"
30 #include "RNA_prototypes.h"
31 
32 #include "graph_intern.h" /* own include */
33 
34 /* -------------------------------------------------------------------- */
39 {
40  SpaceGraph *sipo = (SpaceGraph *)area->spacedata.first;
41 
42  /* Set mode */
43  sipo->mode = SIPO_MODE_DRIVERS;
44 
45  /* Show Properties Region (or else the settings can't be edited) */
47  if (region_props) {
48  UI_panel_category_active_set(region_props, "Drivers");
49 
50  region_props->flag &= ~RGN_FLAG_HIDDEN;
51  /* XXX: Adjust width of this too? */
52 
54  }
55  else {
56  printf("%s: Couldn't find properties region for Drivers Editor - %p\n", __func__, area);
57  }
58 
59  /* Adjust framing in graph region */
60  /* TODO: Have a way of not resetting this every time?
61  * (e.g. So that switching back and forth between editors doesn't keep jumping?)
62  */
64  if (region_main) {
65  /* XXX: Ideally we recenter based on the range instead... */
66  region_main->v2d.tot.xmin = -2.0f;
67  region_main->v2d.tot.ymin = -2.0f;
68  region_main->v2d.tot.xmax = 2.0f;
69  region_main->v2d.tot.ymax = 2.0f;
70 
71  region_main->v2d.cur = region_main->v2d.tot;
72  }
73 }
74 
77 /* -------------------------------------------------------------------- */
82 {
83  ListBase anim_data = {NULL, NULL};
86  size_t items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
87 
88  /* We take the first F-Curve only, since some other ones may have had 'active' flag set
89  * if they were from linked data.
90  */
91  if (items) {
92  bAnimListElem *ale = (bAnimListElem *)anim_data.first;
93 
94  /* remove first item from list, then free the rest of the list and return the stored one */
95  BLI_remlink(&anim_data, ale);
96  ANIM_animdata_freelist(&anim_data);
97 
98  return ale;
99  }
100 
101  /* no active F-Curve */
102  return NULL;
103 }
104 
107 /* -------------------------------------------------------------------- */
112 {
113  bAnimContext ac;
114  bAnimListElem *ale;
115  ListBase anim_data = {NULL, NULL};
117  size_t items;
118  int filter;
119  bool found = false;
120 
121  /* firstly, check if in Graph Editor */
122  /* TODO: also check for region? */
123  if ((area == NULL) || (area->spacetype != SPACE_GRAPH)) {
124  return found;
125  }
126 
127  /* try to init Anim-Context stuff ourselves and check */
128  if (ANIM_animdata_get_context(C, &ac) == 0) {
129  return found;
130  }
131 
132  /* loop over the visible (selection doesn't matter) F-Curves, and see if they're suitable
133  * stopping on the first successful match
134  */
136  items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
137  if (items == 0) {
138  return found;
139  }
140 
141  for (ale = anim_data.first; ale; ale = ale->next) {
142  FCurve *fcu = (FCurve *)ale->data;
143 
144  /* visible curves for selection must fulfill the following criteria:
145  * - it has bezier keyframes
146  * - F-Curve modifiers do not interfere with the result too much
147  * (i.e. the modifier-control drawing check returns false)
148  */
149  if (fcu->bezt == NULL) {
150  continue;
151  }
153  found = true;
154  break;
155  }
156  }
157 
158  /* cleanup and return findings */
159  ANIM_animdata_freelist(&anim_data);
160  return found;
161 }
162 
164 {
165  bAnimContext ac;
166  bAnimListElem *ale;
167  ListBase anim_data = {NULL, NULL};
169  size_t items;
170  int filter;
171  bool found = false;
172 
173  /* firstly, check if in Graph Editor or Dopesheet */
174  /* TODO: also check for region? */
175  if (area == NULL || !ELEM(area->spacetype, SPACE_GRAPH, SPACE_ACTION)) {
176  return found;
177  }
178 
179  /* try to init Anim-Context stuff ourselves and check */
180  if (ANIM_animdata_get_context(C, &ac) == 0) {
181  return found;
182  }
183 
184  /* loop over the editable F-Curves, and see if they're suitable
185  * stopping on the first successful match
186  */
189  items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
190  if (items == 0) {
191  CTX_wm_operator_poll_msg_set(C, "There is no animation data to operate on");
192  return found;
193  }
194 
195  for (ale = anim_data.first; ale; ale = ale->next) {
196  FCurve *fcu = (FCurve *)ale->data;
197 
198  /* editable curves must fulfill the following criteria:
199  * - it has bezier keyframes
200  * - it must not be protected from editing (this is already checked for with the edit flag
201  * - F-Curve modifiers do not interfere with the result too much
202  * (i.e. the modifier-control drawing check returns false)
203  */
204  if (fcu->bezt == NULL && fcu->fpt != NULL) {
205  /* This is a baked curve, it is never editable. */
206  continue;
207  }
208  if (BKE_fcurve_is_keyframable(fcu)) {
209  found = true;
210  break;
211  }
212  }
213 
214  /* cleanup and return findings */
215  ANIM_animdata_freelist(&anim_data);
216  return found;
217 }
218 
220 {
221  bAnimContext ac;
222  bAnimListElem *ale;
224  bool has_fcurve = false;
225 
226  /* firstly, check if in Graph Editor */
227  /* TODO: also check for region? */
228  if ((area == NULL) || (area->spacetype != SPACE_GRAPH)) {
229  return has_fcurve;
230  }
231 
232  /* try to init Anim-Context stuff ourselves and check */
233  if (ANIM_animdata_get_context(C, &ac) == 0) {
234  return has_fcurve;
235  }
236 
237  /* try to get the Active F-Curve */
238  ale = get_active_fcurve_channel(&ac);
239  if (ale == NULL) {
240  return has_fcurve;
241  }
242 
243  /* Do we have a suitable F-Curves?
244  * - For most cases, NLA Control Curves are sufficiently similar to NLA
245  * curves to serve this role too. Under the hood, they are F-Curves too.
246  * The only problems which will arise here are if these need to be
247  * in an Action too (but drivers would then also be affected!)
248  */
249  has_fcurve = ((ale->data) && ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE));
250  if (has_fcurve) {
251  FCurve *fcu = (FCurve *)ale->data;
252  has_fcurve = (fcu->flag & FCURVE_VISIBLE) != 0;
253  }
254 
255  /* free temp data... */
256  MEM_freeN(ale);
257 
258  /* return success */
259  return has_fcurve;
260 }
261 
263 {
264  PointerRNA ptr = CTX_data_pointer_get_type(C, "active_editable_fcurve", &RNA_FCurve);
265 
266  return ptr.data != NULL;
267 }
268 
270 {
271  bAnimContext ac;
272  ListBase anim_data = {NULL, NULL};
274  size_t items;
275  int filter;
276 
277  /* firstly, check if in Graph Editor */
278  /* TODO: also check for region? */
279  if ((area == NULL) || (area->spacetype != SPACE_GRAPH)) {
280  return false;
281  }
282 
283  /* try to init Anim-Context stuff ourselves and check */
284  if (ANIM_animdata_get_context(C, &ac) == 0) {
285  return false;
286  }
287 
288  /* Get the editable + selected F-Curves, and as long as we got some, we can return.
289  * NOTE: curve-visible flag isn't included,
290  * otherwise selecting a curve via list to edit is too cumbersome. */
293  items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
294  if (items == 0) {
295  return false;
296  }
297 
298  /* cleanup and return findings */
299  ANIM_animdata_freelist(&anim_data);
300  return true;
301 }
302 
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:738
PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type)
Definition: context.c:473
void CTX_wm_operator_poll_msg_set(struct bContext *C, const char *msg)
Definition: context.c:1042
bool BKE_fcurve_are_keyframes_usable(struct FCurve *fcu)
Definition: fcurve.c:903
bool BKE_fcurve_is_keyframable(struct FCurve *fcu)
Definition: fcurve.c:968
struct ARegion * BKE_area_find_region_type(const struct ScrArea *area, int type)
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:100
#define ELEM(...)
@ FCURVE_VISIBLE
@ RGN_FLAG_HIDDEN
@ RGN_TYPE_UI
@ RGN_TYPE_WINDOW
@ SPACE_ACTION
@ SPACE_GRAPH
@ SIPO_MODE_DRIVERS
@ ANIMTYPE_NLACURVE
Definition: ED_anim_api.h:202
@ ANIMTYPE_FCURVE
Definition: ED_anim_api.h:199
@ ANIMFILTER_ACTIVE
Definition: ED_anim_api.h:303
@ ANIMFILTER_FOREDIT
Definition: ED_anim_api.h:312
@ ANIMFILTER_DATA_VISIBLE
Definition: ED_anim_api.h:292
@ ANIMFILTER_CURVE_VISIBLE
Definition: ED_anim_api.h:297
@ ANIMFILTER_FCURVESONLY
Definition: ED_anim_api.h:328
@ ANIMFILTER_SEL
Definition: ED_anim_api.h:308
void ED_region_visibility_change_update(struct bContext *C, struct ScrArea *area, struct ARegion *region)
Definition: area.c:2086
Read Guarded memory(de)allocation.
#define C
Definition: RandGen.cpp:25
void UI_panel_category_active_set(struct ARegion *region, const char *idname)
void ANIM_animdata_freelist(ListBase *anim_data)
Definition: anim_deps.c:397
bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
Definition: anim_filter.c:379
size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, eAnimFilter_Flags filter_mode, void *data, eAnimCont_Types datatype)
Definition: anim_filter.c:3447
bool graphop_visible_keyframes_poll(bContext *C)
Definition: graph_utils.c:111
bool graphop_active_editable_fcurve_ctx_poll(bContext *C)
Definition: graph_utils.c:262
bAnimListElem * get_active_fcurve_channel(bAnimContext *ac)
Definition: graph_utils.c:81
bool graphop_editable_keyframes_poll(bContext *C)
Definition: graph_utils.c:163
bool graphop_active_fcurve_poll(bContext *C)
Definition: graph_utils.c:219
bool graphop_selected_fcurve_poll(bContext *C)
Definition: graph_utils.c:269
void ED_drivers_editor_init(bContext *C, ScrArea *area)
Definition: graph_utils.c:38
DO_INLINE void filter(lfVector *V, fmatrix3x3 *S)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
static void area(int d1, int d2, int e1, int e2, float weights[2])
FPoint * fpt
BezTriple * bezt
short flag
void * first
Definition: DNA_listBase.h:31
void * data
Definition: RNA_types.h:38
short datatype
Definition: ED_anim_api.h:62
void * data
Definition: ED_anim_api.h:60
struct bAnimListElem * next
Definition: ED_anim_api.h:127
float xmax
Definition: DNA_vec_types.h:69
float xmin
Definition: DNA_vec_types.h:69
float ymax
Definition: DNA_vec_types.h:70
float ymin
Definition: DNA_vec_types.h:70
PointerRNA * ptr
Definition: wm_files.c:3480