Fix [#36831] Grease Pencil dont create a drawing in current frame less than 1
[blender.git] / source / blender / blenkernel / intern / 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/blenkernel/intern/gpencil.c
27  *  \ingroup bke
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_utildefines.h"
41
42 #include "BLF_translation.h"
43
44 #include "DNA_gpencil_types.h"
45 #include "DNA_userdef_types.h"
46
47 #include "BKE_global.h"
48 #include "BKE_gpencil.h"
49 #include "BKE_library.h"
50 #include "BKE_main.h"
51
52
53
54 /* ************************************************** */
55 /* GENERAL STUFF */
56
57 /* --------- Memory Management ------------ */
58
59 /* Free strokes belonging to a gp-frame */
60 void free_gpencil_strokes(bGPDframe *gpf)
61 {
62         bGPDstroke *gps, *gpsn;
63         
64         /* error checking */
65         if (gpf == NULL) return;
66         
67         /* free strokes */
68         for (gps = gpf->strokes.first; gps; gps = gpsn) {
69                 gpsn = gps->next;
70                 
71                 /* free stroke memory arrays, then stroke itself */
72                 if (gps->points) MEM_freeN(gps->points);
73                 BLI_freelinkN(&gpf->strokes, gps);
74         }
75 }
76
77 /* Free all of a gp-layer's frames */
78 void free_gpencil_frames(bGPDlayer *gpl)
79 {
80         bGPDframe *gpf, *gpfn;
81         
82         /* error checking */
83         if (gpl == NULL) return;
84         
85         /* free frames */
86         for (gpf = gpl->frames.first; gpf; gpf = gpfn) {
87                 gpfn = gpf->next;
88                 
89                 /* free strokes and their associated memory */
90                 free_gpencil_strokes(gpf);
91                 BLI_freelinkN(&gpl->frames, gpf);
92         }
93         gpl->actframe = NULL;
94 }
95
96 /* Free all of the gp-layers for a viewport (list should be &gpd->layers or so) */
97 void free_gpencil_layers(ListBase *list)
98 {
99         bGPDlayer *gpl, *gpln;
100         
101         /* error checking */
102         if (list == NULL) return;
103         
104         /* delete layers */
105         for (gpl = list->first; gpl; gpl = gpln) {
106                 gpln = gpl->next;
107                 
108                 /* free layers and their data */
109                 free_gpencil_frames(gpl);
110                 BLI_freelinkN(list, gpl);
111         }
112 }
113
114 /* Free all of GPencil datablock's related data, but not the block itself */
115 void BKE_gpencil_free(bGPdata *gpd)
116 {
117         /* free layers */
118         free_gpencil_layers(&gpd->layers);
119 }
120
121 /* -------- Container Creation ---------- */
122
123 /* add a new gp-frame to the given layer */
124 bGPDframe *gpencil_frame_addnew(bGPDlayer *gpl, int cframe)
125 {
126         bGPDframe *gpf, *gf;
127         short state = 0;
128         
129         /* error checking (neg frame only if they are not allowed in Blender!) */
130         if ((gpl == NULL) || ((U.flag & USER_NONEGFRAMES) && (cframe <= 0)))
131                 return NULL;
132                 
133         /* allocate memory for this frame */
134         gpf = MEM_callocN(sizeof(bGPDframe), "bGPDframe");
135         gpf->framenum = cframe;
136         
137         /* find appropriate place to add frame */
138         if (gpl->frames.first) {
139                 for (gf = gpl->frames.first; gf; gf = gf->next) {
140                         /* check if frame matches one that is supposed to be added */
141                         if (gf->framenum == cframe) {
142                                 state = -1;
143                                 break;
144                         }
145                         
146                         /* if current frame has already exceeded the frame to add, add before */
147                         if (gf->framenum > cframe) {
148                                 BLI_insertlinkbefore(&gpl->frames, gf, gpf);
149                                 state = 1;
150                                 break;
151                         }
152                 }
153         }
154         
155         /* check whether frame was added successfully */
156         if (state == -1) {
157                 MEM_freeN(gpf);
158                 printf("Error: frame (%d) existed already for this layer\n", cframe);
159         }
160         else if (state == 0) {
161                 /* add to end then! */
162                 BLI_addtail(&gpl->frames, gpf);
163         }
164         
165         /* return frame */
166         return gpf;
167 }
168
169 /* add a new gp-layer and make it the active layer */
170 bGPDlayer *gpencil_layer_addnew(bGPdata *gpd, const char *name, int setactive)
171 {
172         bGPDlayer *gpl;
173         
174         /* check that list is ok */
175         if (gpd == NULL)
176                 return NULL;
177                 
178         /* allocate memory for frame and add to end of list */
179         gpl = MEM_callocN(sizeof(bGPDlayer), "bGPDlayer");
180         
181         /* add to datablock */
182         BLI_addtail(&gpd->layers, gpl);
183         
184         /* set basic settings */
185         gpl->color[3] = 0.9f;
186         gpl->thickness = 3;
187         
188         /* auto-name */
189         BLI_strncpy(gpl->info, name, sizeof(gpl->info));
190         BLI_uniquename(&gpd->layers, gpl, DATA_("GP_Layer"), '.', offsetof(bGPDlayer, info), sizeof(gpl->info));
191         
192         /* make this one the active one */
193         if (setactive)
194                 gpencil_layer_setactive(gpd, gpl);
195         
196         /* return layer */
197         return gpl;
198 }
199
200 /* add a new gp-datablock */
201 bGPdata *gpencil_data_addnew(const char name[])
202 {
203         bGPdata *gpd;
204         
205         /* allocate memory for a new block */
206         gpd = BKE_libblock_alloc(&G.main->gpencil, ID_GD, name);
207         
208         /* initial settings */
209         gpd->flag = (GP_DATA_DISPINFO | GP_DATA_EXPAND);
210         
211         /* for now, stick to view is also enabled by default
212          * since this is more useful...
213          */
214         gpd->flag |= GP_DATA_VIEWALIGN;
215         
216         return gpd;
217 }
218
219 /* -------- Data Duplication ---------- */
220
221 /* make a copy of a given gpencil frame */
222 bGPDframe *gpencil_frame_duplicate(bGPDframe *src)
223 {
224         bGPDstroke *gps, *gpsd;
225         bGPDframe *dst;
226         
227         /* error checking */
228         if (src == NULL)
229                 return NULL;
230                 
231         /* make a copy of the source frame */
232         dst = MEM_dupallocN(src);
233         dst->prev = dst->next = NULL;
234         
235         /* copy strokes */
236         dst->strokes.first = dst->strokes.last = NULL;
237         for (gps = src->strokes.first; gps; gps = gps->next) {
238                 /* make copy of source stroke, then adjust pointer to points too */
239                 gpsd = MEM_dupallocN(gps);
240                 gpsd->points = MEM_dupallocN(gps->points);
241                 
242                 BLI_addtail(&dst->strokes, gpsd);
243         }
244         
245         /* return new frame */
246         return dst;
247 }
248
249 /* make a copy of a given gpencil layer */
250 bGPDlayer *gpencil_layer_duplicate(bGPDlayer *src)
251 {
252         bGPDframe *gpf, *gpfd;
253         bGPDlayer *dst;
254         
255         /* error checking */
256         if (src == NULL)
257                 return NULL;
258                 
259         /* make a copy of source layer */
260         dst = MEM_dupallocN(src);
261         dst->prev = dst->next = NULL;
262         
263         /* copy frames */
264         dst->frames.first = dst->frames.last = NULL;
265         for (gpf = src->frames.first; gpf; gpf = gpf->next) {
266                 /* make a copy of source frame */
267                 gpfd = gpencil_frame_duplicate(gpf);
268                 BLI_addtail(&dst->frames, gpfd);
269                 
270                 /* if source frame was the current layer's 'active' frame, reassign that too */
271                 if (gpf == dst->actframe)
272                         dst->actframe = gpfd;
273         }
274         
275         /* return new layer */
276         return dst;
277 }
278
279 /* make a copy of a given gpencil datablock */
280 bGPdata *gpencil_data_duplicate(bGPdata *src)
281 {
282         bGPDlayer *gpl, *gpld;
283         bGPdata *dst;
284         
285         /* error checking */
286         if (src == NULL)
287                 return NULL;
288         
289         /* make a copy of the base-data */
290         dst = MEM_dupallocN(src);
291         
292         /* copy layers */
293         dst->layers.first = dst->layers.last = NULL;
294         for (gpl = src->layers.first; gpl; gpl = gpl->next) {
295                 /* make a copy of source layer and its data */
296                 gpld = gpencil_layer_duplicate(gpl);
297                 BLI_addtail(&dst->layers, gpld);
298         }
299         
300         /* return new */
301         return dst;
302 }
303
304 /* -------- GP-Frame API ---------- */
305
306 /* delete the last stroke of the given frame */
307 void gpencil_frame_delete_laststroke(bGPDlayer *gpl, bGPDframe *gpf)
308 {
309         bGPDstroke *gps = (gpf) ? gpf->strokes.last : NULL;
310         int cfra = (gpf) ? gpf->framenum : 0; /* assume that the current frame was not locked */
311         
312         /* error checking */
313         if (ELEM(NULL, gpf, gps))
314                 return;
315         
316         /* free the stroke and its data */
317         MEM_freeN(gps->points);
318         BLI_freelinkN(&gpf->strokes, gps);
319         
320         /* if frame has no strokes after this, delete it */
321         if (gpf->strokes.first == NULL) {
322                 gpencil_layer_delframe(gpl, gpf);
323                 gpencil_layer_getframe(gpl, cfra, 0);
324         }
325 }
326
327 /* -------- GP-Layer API ---------- */
328
329 bGPDframe *BKE_gpencil_layer_find_frame(bGPDlayer *gpl, int cframe)
330 {
331         bGPDframe *gpf;
332
333         for (gpf = gpl->frames.last; gpf; gpf = gpf->prev) {
334                 if (gpf->framenum == cframe) {
335                         return gpf;
336                 }
337         }
338
339         return NULL;
340 }
341
342 /* get the appropriate gp-frame from a given layer
343  *      - this sets the layer's actframe var (if allowed to)
344  *      - extension beyond range (if first gp-frame is after all frame in interest and cannot add)
345  */
346 bGPDframe *gpencil_layer_getframe(bGPDlayer *gpl, int cframe, short addnew)
347 {
348         bGPDframe *gpf = NULL;
349         short found = 0;
350         
351         /* error checking */
352         if (gpl == NULL) return NULL;
353         /* No reason to forbid negative frames when they are allowed in Blender! */
354         if ((U.flag & USER_NONEGFRAMES) && cframe <= 0) cframe = 1;
355         
356         /* check if there is already an active frame */
357         if (gpl->actframe) {
358                 gpf = gpl->actframe;
359                 
360                 /* do not allow any changes to layer's active frame if layer is locked from changes
361                  * or if the layer has been set to stay on the current frame
362                  */
363                 if (gpl->flag & (GP_LAYER_LOCKED | GP_LAYER_FRAMELOCK))
364                         return gpf;
365                 /* do not allow any changes to actframe if frame has painting tag attached to it */
366                 if (gpf->flag & GP_FRAME_PAINT) 
367                         return gpf;
368                 
369                 /* try to find matching frame */
370                 if (gpf->framenum < cframe) {
371                         for (; gpf; gpf = gpf->next) {
372                                 if (gpf->framenum == cframe) {
373                                         found = 1;
374                                         break;
375                                 }
376                                 else if ((gpf->next) && (gpf->next->framenum > cframe)) {
377                                         found = 1;
378                                         break;
379                                 }
380                         }
381                         
382                         /* set the appropriate frame */
383                         if (addnew) {
384                                 if ((found) && (gpf->framenum == cframe))
385                                         gpl->actframe = gpf;
386                                 else
387                                         gpl->actframe = gpencil_frame_addnew(gpl, cframe);
388                         }
389                         else if (found)
390                                 gpl->actframe = gpf;
391                         else
392                                 gpl->actframe = gpl->frames.last;
393                 }
394                 else {
395                         for (; gpf; gpf = gpf->prev) {
396                                 if (gpf->framenum <= cframe) {
397                                         found = 1;
398                                         break;
399                                 }
400                         }
401                         
402                         /* set the appropriate frame */
403                         if (addnew) {
404                                 if ((found) && (gpf->framenum == cframe))
405                                         gpl->actframe = gpf;
406                                 else
407                                         gpl->actframe = gpencil_frame_addnew(gpl, cframe);
408                         }
409                         else if (found)
410                                 gpl->actframe = gpf;
411                         else
412                                 gpl->actframe = gpl->frames.first;
413                 }
414         }
415         else if (gpl->frames.first) {
416                 /* check which of the ends to start checking from */
417                 const int first = ((bGPDframe *)(gpl->frames.first))->framenum;
418                 const int last = ((bGPDframe *)(gpl->frames.last))->framenum;
419                 
420                 if (abs(cframe - first) > abs(cframe - last)) {
421                         /* find gp-frame which is less than or equal to cframe */
422                         for (gpf = gpl->frames.last; gpf; gpf = gpf->prev) {
423                                 if (gpf->framenum <= cframe) {
424                                         found = 1;
425                                         break;
426                                 }
427                         }
428                 }
429                 else {
430                         /* find gp-frame which is less than or equal to cframe */
431                         for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
432                                 if (gpf->framenum <= cframe) {
433                                         found = 1;
434                                         break;
435                                 }
436                         }
437                 }
438                 
439                 /* set the appropriate frame */
440                 if (addnew) {
441                         if ((found) && (gpf->framenum == cframe))
442                                 gpl->actframe = gpf;
443                         else
444                                 gpl->actframe = gpencil_frame_addnew(gpl, cframe);
445                 }
446                 else if (found)
447                         gpl->actframe = gpf;
448                 else {
449                         /* unresolved errogenous situation! */
450                         printf("Error: cannot find appropriate gp-frame\n");
451                         /* gpl->actframe should still be NULL */
452                 }
453         }
454         else {
455                 /* currently no frames (add if allowed to) */
456                 if (addnew)
457                         gpl->actframe = gpencil_frame_addnew(gpl, cframe);
458                 else {
459                         /* don't do anything... this may be when no frames yet! */
460                         /* gpl->actframe should still be NULL */
461                 }
462         }
463         
464         /* return */
465         return gpl->actframe;
466 }
467
468 /* delete the given frame from a layer */
469 void gpencil_layer_delframe(bGPDlayer *gpl, bGPDframe *gpf)
470 {
471         /* error checking */
472         if (ELEM(NULL, gpl, gpf))
473                 return;
474                 
475         /* free the frame and its data */
476         free_gpencil_strokes(gpf);
477         BLI_freelinkN(&gpl->frames, gpf);
478         gpl->actframe = NULL;
479 }
480
481 /* get the active gp-layer for editing */
482 bGPDlayer *gpencil_layer_getactive(bGPdata *gpd)
483 {
484         bGPDlayer *gpl;
485         
486         /* error checking */
487         if (ELEM(NULL, gpd, gpd->layers.first))
488                 return NULL;
489                 
490         /* loop over layers until found (assume only one active) */
491         for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
492                 if (gpl->flag & GP_LAYER_ACTIVE)
493                         return gpl;
494         }
495         
496         /* no active layer found */
497         return NULL;
498 }
499
500 /* set the active gp-layer */
501 void gpencil_layer_setactive(bGPdata *gpd, bGPDlayer *active)
502 {
503         bGPDlayer *gpl;
504         
505         /* error checking */
506         if (ELEM3(NULL, gpd, gpd->layers.first, active))
507                 return;
508                 
509         /* loop over layers deactivating all */
510         for (gpl = gpd->layers.first; gpl; gpl = gpl->next)
511                 gpl->flag &= ~GP_LAYER_ACTIVE;
512         
513         /* set as active one */
514         active->flag |= GP_LAYER_ACTIVE;
515 }
516
517 /* delete the active gp-layer */
518 void gpencil_layer_delete(bGPdata *gpd, bGPDlayer *gpl)
519 {
520         /* error checking */
521         if (ELEM(NULL, gpd, gpl)) 
522                 return;
523         
524         /* free layer */
525         free_gpencil_frames(gpl);
526         BLI_freelinkN(&gpd->layers, gpl);
527 }
528
529 /* ************************************************** */