Fix #35640, part 2. Check id.lib in poll functions for operators which do critical...
[blender.git] / source / blender / editors / gpencil / editaction_gpencil.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2008, Blender Foundation
19  * This is a new part of Blender
20  *
21  * Contributor(s): Joshua Leung
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 /** \file blender/editors/gpencil/editaction_gpencil.c
27  *  \ingroup edgpencil
28  */
29
30  
31 #include <stdio.h>
32 #include <string.h>
33 #include <stdlib.h>
34 #include <stddef.h>
35 #include <math.h>
36
37 #include "MEM_guardedalloc.h"
38
39 #include "BLI_blenlib.h"
40 #include "BLI_math.h"
41 #include "BLI_utildefines.h"
42
43 #include "DNA_gpencil_types.h"
44 #include "DNA_scene_types.h"
45
46 #include "BKE_fcurve.h"
47 #include "BKE_gpencil.h"
48
49 #include "ED_anim_api.h"
50 #include "ED_gpencil.h"
51 #include "ED_keyframes_edit.h"
52 #include "ED_markers.h"
53
54 #include "gpencil_intern.h"
55
56 /* ***************************************** */
57 /* NOTE ABOUT THIS FILE:
58  *  This file contains code for editing Grease Pencil data in the Action Editor
59  *  as a 'keyframes', so that a user can adjust the timing of Grease Pencil drawings.
60  *  Therefore, this file mostly contains functions for selecting Grease-Pencil frames.
61  */
62 /* ***************************************** */
63 /* Generics - Loopers */
64
65 /* Loops over the gp-frames for a gp-layer, and applies the given callback */
66 short ED_gplayer_frames_looper(bGPDlayer *gpl, Scene *scene, short (*gpf_cb)(bGPDframe *, Scene *))
67 {
68         bGPDframe *gpf;
69         
70         /* error checker */
71         if (gpl == NULL)
72                 return 0;
73         
74         /* do loop */
75         for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
76                 /* execute callback */
77                 if (gpf_cb(gpf, scene))
78                         return 1;
79         }
80                 
81         /* nothing to return */
82         return 0;
83 }
84
85 /* ****************************************** */
86 /* Data Conversion Tools */
87
88 /* make a listing all the gp-frames in a layer as cfraelems */
89 void ED_gplayer_make_cfra_list(bGPDlayer *gpl, ListBase *elems, short onlysel)
90 {
91         bGPDframe *gpf;
92         CfraElem *ce;
93         
94         /* error checking */
95         if (ELEM(NULL, gpl, elems))
96                 return;
97         
98         /* loop through gp-frames, adding */
99         for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
100                 if ((onlysel == 0) || (gpf->flag & GP_FRAME_SELECT)) {
101                         ce = MEM_callocN(sizeof(CfraElem), "CfraElem");
102                         
103                         ce->cfra = (float)gpf->framenum;
104                         ce->sel = (gpf->flag & GP_FRAME_SELECT) ? 1 : 0;
105                         
106                         BLI_addtail(elems, ce);
107                 }
108         }
109 }
110
111 /* ***************************************** */
112 /* Selection Tools */
113
114 /* check if one of the frames in this layer is selected */
115 short ED_gplayer_frame_select_check(bGPDlayer *gpl)
116 {
117         bGPDframe *gpf;
118         
119         /* error checking */
120         if (gpl == NULL) 
121                 return 0;
122         
123         /* stop at the first one found */
124         for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
125                 if (gpf->flag & GP_FRAME_SELECT)
126                         return 1;
127         }
128         
129         /* not found */
130         return 0;
131 }
132
133 /* helper function - select gp-frame based on SELECT_* mode */
134 static void gpframe_select(bGPDframe *gpf, short select_mode)
135 {
136         if (gpf == NULL)
137                 return;
138         
139         switch (select_mode) {
140                 case SELECT_ADD:
141                         gpf->flag |= GP_FRAME_SELECT;
142                         break;
143                 case SELECT_SUBTRACT:
144                         gpf->flag &= ~GP_FRAME_SELECT;
145                         break;
146                 case SELECT_INVERT:
147                         gpf->flag ^= GP_FRAME_SELECT;
148                         break;
149         }
150 }
151
152 /* set all/none/invert select (like above, but with SELECT_* modes) */
153 void ED_gpencil_select_frames(bGPDlayer *gpl, short select_mode)
154 {
155         bGPDframe *gpf;
156         
157         /* error checking */
158         if (gpl == NULL) 
159                 return;
160                 
161         /* handle according to mode */
162         for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
163                 gpframe_select(gpf, select_mode);
164         }
165 }
166
167 /* set all/none/invert select */
168 void ED_gplayer_frame_select_set(bGPDlayer *gpl, short mode)
169 {
170         /* error checking */
171         if (gpl == NULL) 
172                 return;
173         
174         /* now call the standard function */
175         ED_gpencil_select_frames(gpl, mode);
176 }
177
178 /* select the frame in this layer that occurs on this frame (there should only be one at most) */
179 void ED_gpencil_select_frame(bGPDlayer *gpl, int selx, short select_mode)
180 {
181         bGPDframe *gpf;
182         
183         if (gpl == NULL) 
184                 return;
185
186         gpf = BKE_gpencil_layer_find_frame(gpl, selx);
187
188         if (gpf) {
189                 gpframe_select(gpf, select_mode);
190         }
191 }
192
193 /* select the frames in this layer that occur within the bounds specified */
194 void ED_gplayer_frames_select_border(bGPDlayer *gpl, float min, float max, short select_mode)
195 {
196         bGPDframe *gpf;
197         
198         if (gpl == NULL)
199                 return;
200         
201         /* only select those frames which are in bounds */
202         for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
203                 if (IN_RANGE(gpf->framenum, min, max))
204                         gpframe_select(gpf, select_mode);
205         }
206 }
207
208 /* ***************************************** */
209 /* Frame Editing Tools */
210
211 /* Delete selected frames */
212 void ED_gplayer_frames_delete(bGPDlayer *gpl)
213 {
214         bGPDframe *gpf, *gpfn;
215         
216         /* error checking */
217         if (gpl == NULL)
218                 return;
219                 
220         /* check for frames to delete */
221         for (gpf = gpl->frames.first; gpf; gpf = gpfn) {
222                 gpfn = gpf->next;
223                 
224                 if (gpf->flag & GP_FRAME_SELECT)
225                         gpencil_layer_delframe(gpl, gpf);
226         }
227 }
228
229 /* Duplicate selected frames from given gp-layer */
230 void ED_gplayer_frames_duplicate(bGPDlayer *gpl)
231 {
232         bGPDframe *gpf, *gpfn;
233         
234         /* error checking */
235         if (gpl == NULL)
236                 return;
237         
238         /* duplicate selected frames  */
239         for (gpf = gpl->frames.first; gpf; gpf = gpfn) {
240                 gpfn = gpf->next;
241                 
242                 /* duplicate this frame */
243                 if (gpf->flag & GP_FRAME_SELECT) {
244                         bGPDframe *gpfd; 
245                         
246                         /* duplicate frame, and deselect self */
247                         gpfd = gpencil_frame_duplicate(gpf);
248                         gpf->flag &= ~GP_FRAME_SELECT;
249                         
250                         BLI_insertlinkafter(&gpl->frames, gpf, gpfd);
251                 }
252         }
253 }
254
255 #if 0 // XXX disabled until grease pencil code stabilises again
256 /* -------------------------------------- */
257 /* Copy and Paste Tools */
258 /* - The copy/paste buffer currently stores a set of GP_Layers, with temporary
259  *      GP_Frames with the necessary strokes
260  * - Unless there is only one element in the buffer, names are also tested to check for compatibility.
261  * - All pasted frames are offset by the same amount. This is calculated as the difference in the times of
262  *      the current frame and the 'first keyframe' (i.e. the earliest one in all channels).
263  * - The earliest frame is calculated per copy operation.
264  */
265  
266 /* globals for copy/paste data (like for other copy/paste buffers) */
267 ListBase gpcopybuf = {NULL, NULL};
268 static int gpcopy_firstframe = 999999999;
269
270 /* This function frees any MEM_calloc'ed copy/paste buffer data */
271 void free_gpcopybuf()
272 {
273         free_gpencil_layers(&gpcopybuf); 
274         
275         gpcopybuf.first = gpcopybuf.last = NULL;
276         gpcopy_firstframe = 999999999;
277 }
278
279 /* This function adds data to the copy/paste buffer, freeing existing data first
280  * Only the selected GP-layers get their selected keyframes copied.
281  */
282 void copy_gpdata()
283 {
284         ListBase act_data = {NULL, NULL};
285         bActListElem *ale;
286         int filter;
287         void *data;
288         short datatype;
289         
290         /* clear buffer first */
291         free_gpcopybuf();
292         
293         /* get data */
294         data = get_action_context(&datatype);
295         if (data == NULL) return;
296         if (datatype != ACTCONT_GPENCIL) return;
297         
298         /* filter data */
299         filter = (ACTFILTER_VISIBLE | ACTFILTER_SEL);
300         actdata_filter(&act_data, filter, data, datatype);
301         
302         /* assume that each of these is an ipo-block */
303         for (ale = act_data.first; ale; ale = ale->next) {
304                 bGPDlayer *gpls, *gpln;
305                 bGPDframe *gpf, *gpfn;
306                 
307                 /* get new layer to put into buffer */
308                 gpls = (bGPDlayer *)ale->data;
309                 gpln = MEM_callocN(sizeof(bGPDlayer), "GPCopyPasteLayer");
310                 
311                 gpln->frames.first = gpln->frames.last = NULL;
312                 BLI_strncpy(gpln->info, gpls->info, sizeof(gpln->info));
313                 
314                 BLI_addtail(&gpcopybuf, gpln);
315                 
316                 /* loop over frames, and copy only selected frames */
317                 for (gpf = gpls->frames.first; gpf; gpf = gpf->next) {
318                         /* if frame is selected, make duplicate it and its strokes */
319                         if (gpf->flag & GP_FRAME_SELECT) {
320                                 /* add frame to buffer */
321                                 gpfn = gpencil_frame_duplicate(gpf);
322                                 BLI_addtail(&gpln->frames, gpfn);
323                                 
324                                 /* check if this is the earliest frame encountered so far */
325                                 if (gpf->framenum < gpcopy_firstframe)
326                                         gpcopy_firstframe = gpf->framenum;
327                         }
328                 }
329         }
330         
331         /* check if anything ended up in the buffer */
332         if (ELEM(NULL, gpcopybuf.first, gpcopybuf.last))
333                 error("Nothing copied to buffer");
334         
335         /* free temp memory */
336         BLI_freelistN(&act_data);
337 }
338
339 void paste_gpdata(Scene *scene)
340 {
341         ListBase act_data = {NULL, NULL};
342         bActListElem *ale;
343         int filter;
344         void *data;
345         short datatype;
346         
347         const int offset = (CFRA - gpcopy_firstframe);
348         short no_name = 0;
349         
350         /* check if buffer is empty */
351         if (ELEM(NULL, gpcopybuf.first, gpcopybuf.last)) {
352                 error("No data in buffer to paste");
353                 return;
354         }
355         /* check if single channel in buffer (disregard names if so)  */
356         if (gpcopybuf.first == gpcopybuf.last)
357                 no_name = 1;
358         
359         /* get data */
360         data = get_action_context(&datatype);
361         if (data == NULL) return;
362         if (datatype != ACTCONT_GPENCIL) return;
363         
364         /* filter data */
365         filter = (ACTFILTER_VISIBLE | ACTFILTER_SEL | ACTFILTER_FOREDIT);
366         actdata_filter(&act_data, filter, data, datatype);
367         
368         /* from selected channels */
369         for (ale = act_data.first; ale; ale = ale->next) {
370                 bGPDlayer *gpld = (bGPDlayer *)ale->data;
371                 bGPDlayer *gpls = NULL;
372                 bGPDframe *gpfs, *gpf;
373                 
374                 /* find suitable layer from buffer to use to paste from */
375                 for (gpls = gpcopybuf.first; gpls; gpls = gpls->next) {
376                         /* check if layer name matches */
377                         if ((no_name) || (strcmp(gpls->info, gpld->info) == 0))
378                                 break;
379                 }
380                 
381                 /* this situation might occur! */
382                 if (gpls == NULL)
383                         continue;
384                 
385                 /* add frames from buffer */
386                 for (gpfs = gpls->frames.first; gpfs; gpfs = gpfs->next) {
387                         /* temporarily apply offset to buffer-frame while copying */
388                         gpfs->framenum += offset;
389                         
390                         /* get frame to copy data into (if no frame returned, then just ignore) */
391                         gpf = gpencil_layer_getframe(gpld, gpfs->framenum, 1);
392                         if (gpf) {
393                                 bGPDstroke *gps, *gpsn;
394                                 ScrArea *sa;
395                                 
396                                 /* get area that gp-data comes from */
397                                 //sa = gpencil_data_findowner((bGPdata *)ale->owner);
398                                 sa = NULL;
399                                 
400                                 /* this should be the right frame... as it may be a pre-existing frame, 
401                                  * must make sure that only compatible stroke types get copied over 
402                                  *      - we cannot just add a duplicate frame, as that would cause errors
403                                  *      - need to check for compatible types to minimize memory usage (copying 'junk' over)
404                                  */
405                                 for (gps = gpfs->strokes.first; gps; gps = gps->next) {
406                                         short stroke_ok;
407                                         
408                                         /* if there's an area, check that it supports this type of stroke */
409                                         if (sa) {
410                                                 stroke_ok = 0;
411                                                 
412                                                 /* check if spacetype supports this type of stroke
413                                                  *      - NOTE: must sync this with gp_paint_initstroke() in gpencil.c
414                                                  */
415                                                 switch (sa->spacetype) {
416                                                         case SPACE_VIEW3D: /* 3D-View: either screen-aligned or 3d-space */
417                                                                 if ((gps->flag == 0) || (gps->flag & GP_STROKE_3DSPACE))
418                                                                         stroke_ok = 1;
419                                                                 break;
420                                                                 
421                                                         case SPACE_NODE: /* Nodes Editor: either screen-aligned or view-aligned */
422                                                         case SPACE_IMAGE: /* Image Editor: either screen-aligned or view\image-aligned */
423                                                         case SPACE_CLIP: /* Image Editor: either screen-aligned or view\image-aligned */
424                                                                 if ((gps->flag == 0) || (gps->flag & GP_STROKE_2DSPACE))
425                                                                         stroke_ok = 1;
426                                                                 break;
427                                                                 
428                                                         case SPACE_SEQ: /* Sequence Editor: either screen-aligned or view-aligned */
429                                                                 if ((gps->flag == 0) || (gps->flag & GP_STROKE_2DIMAGE))
430                                                                         stroke_ok = 1;
431                                                                 break;
432                                                 }
433                                         }
434                                         else
435                                                 stroke_ok = 1;
436                                         
437                                         /* if stroke is ok, we make a copy of this stroke and add to frame */
438                                         if (stroke_ok) {
439                                                 /* make a copy of stroke, then of its points array */
440                                                 gpsn = MEM_dupallocN(gps);
441                                                 gpsn->points = MEM_dupallocN(gps->points);
442                                                 
443                                                 /* append stroke to frame */
444                                                 BLI_addtail(&gpf->strokes, gpsn);
445                                         }
446                                 }
447                                 
448                                 /* if no strokes (i.e. new frame) added, free gpf */
449                                 if (gpf->strokes.first == NULL)
450                                         gpencil_layer_delframe(gpld, gpf);
451                         }
452                         
453                         /* unapply offset from buffer-frame */
454                         gpfs->framenum -= offset;
455                 }
456         }
457         
458         /* free temp memory */
459         BLI_freelistN(&act_data);
460         
461         /* undo and redraw stuff */
462         BIF_undo_push("Paste Grease Pencil Frames");
463 }
464 #endif /* XXX disabled until Grease Pencil code stabilises again... */
465
466 /* -------------------------------------- */
467 /* Snap Tools */
468
469 static short snap_gpf_nearest(bGPDframe *gpf, Scene *UNUSED(scene))
470 {
471         if (gpf->flag & GP_FRAME_SELECT)
472                 gpf->framenum = (int)(floor(gpf->framenum + 0.5));
473         return 0;
474 }
475
476 static short snap_gpf_nearestsec(bGPDframe *gpf, Scene *scene)
477 {
478         float secf = (float)FPS;
479         if (gpf->flag & GP_FRAME_SELECT)
480                 gpf->framenum = (int)(floorf(gpf->framenum / secf + 0.5f) * secf);
481         return 0;
482 }
483
484 static short snap_gpf_cframe(bGPDframe *gpf, Scene *scene)
485 {
486         if (gpf->flag & GP_FRAME_SELECT)
487                 gpf->framenum = (int)CFRA;
488         return 0;
489 }
490
491 static short snap_gpf_nearmarker(bGPDframe *gpf, Scene *scene)
492 {
493         if (gpf->flag & GP_FRAME_SELECT)
494                 gpf->framenum = (int)ED_markers_find_nearest_marker_time(&scene->markers, (float)gpf->framenum);
495         return 0;
496 }
497
498 /* snap selected frames to ... */
499 void ED_gplayer_snap_frames(bGPDlayer *gpl, Scene *scene, short mode)
500 {
501         switch (mode) {
502                 case SNAP_KEYS_NEARFRAME: /* snap to nearest frame */
503                         ED_gplayer_frames_looper(gpl, scene, snap_gpf_nearest);
504                         break;
505                 case SNAP_KEYS_CURFRAME: /* snap to current frame */
506                         ED_gplayer_frames_looper(gpl, scene, snap_gpf_cframe);
507                         break;
508                 case SNAP_KEYS_NEARMARKER: /* snap to nearest marker */
509                         ED_gplayer_frames_looper(gpl, scene, snap_gpf_nearmarker);
510                         break;
511                 case SNAP_KEYS_NEARSEC: /* snap to nearest second */
512                         ED_gplayer_frames_looper(gpl, scene, snap_gpf_nearestsec);
513                         break;
514                 default: /* just in case */
515                         break;
516         }
517 }
518
519 #if 0 /* XXX disabled until grease pencil code stabilises again */
520 /* -------------------------------------- */
521 /* Mirror Tools */
522
523 static short mirror_gpf_cframe(bGPDframe *gpf, Scene *scene)
524 {
525         int diff;
526         
527         if (gpf->flag & GP_FRAME_SELECT) {
528                 diff = CFRA - gpf->framenum;
529                 gpf->framenum = CFRA;
530         }
531         
532         return 0;
533 }
534
535 static short mirror_gpf_yaxis(bGPDframe *gpf, Scene *scene)
536 {
537         int diff;
538         
539         if (gpf->flag & GP_FRAME_SELECT) {
540                 diff = -gpf->framenum;
541                 gpf->framenum = diff;
542         }
543         
544         return 0;
545 }
546
547 static short mirror_gpf_xaxis(bGPDframe *gpf, Scene *scene)
548 {
549         int diff;
550         
551         if (gpf->flag & GP_FRAME_SELECT) {
552                 diff = -gpf->framenum;
553                 gpf->framenum = diff;
554         }
555         
556         return 0;
557 }
558
559 static short mirror_gpf_marker(bGPDframe *gpf, Scene *scene)
560 {
561         static TimeMarker *marker;
562         static short initialized = 0;
563         int diff;
564         
565         /* In order for this mirror function to work without
566          * any extra arguments being added, we use the case
567          * of bezt==NULL to denote that we should find the 
568          * marker to mirror over. The static pointer is safe
569          * to use this way, as it will be set to null after 
570          * each cycle in which this is called.
571          */
572         
573         if (gpf) {
574                 /* mirroring time */
575                 if ((gpf->flag & GP_FRAME_SELECT) && (marker)) {
576                         diff = (marker->frame - gpf->framenum);
577                         gpf->framenum = (marker->frame + diff);
578                 }
579         }
580         else {
581                 /* initialization time */
582                 if (initialized) {
583                         /* reset everything for safety */
584                         marker = NULL;
585                         initialized = 0;
586                 }
587                 else {
588                         /* try to find a marker */
589                         marker = ED_markers_get_first_selected(&scene->markers);
590                         if (marker) {
591                                 initialized = 1;
592                         }
593                 }
594         }
595         
596         return 0;
597 }
598
599
600 /* mirror selected gp-frames on... */
601 void mirror_gplayer_frames(bGPDlayer *gpl, Scene *scene, short mode)
602 {
603         switch (mode) {
604                 case 1: /* mirror over current frame */
605                         ED_gplayer_frames_looper(gpl, scene, mirror_gpf_cframe);
606                         break;
607                 case 2: /* mirror over frame 0 */
608                         ED_gplayer_frames_looper(gpl, scene, mirror_gpf_yaxis);
609                         break;
610                 case 3: /* mirror over value 0 */
611                         ED_gplayer_frames_looper(gpl, scene, mirror_gpf_xaxis);
612                         break;
613                 case 4: /* mirror over marker */
614                         mirror_gpf_marker(NULL, NULL);
615                         ED_gplayer_frames_looper(gpl, scene, mirror_gpf_marker);
616                         mirror_gpf_marker(NULL, NULL);
617                         break;
618                 default: /* just in case */
619                         ED_gplayer_frames_looper(gpl, scene, mirror_gpf_yaxis);
620                         break;
621         }
622 }
623
624 /* ***************************************** */
625 #endif // XXX disabled until Grease Pencil code stabilises again...