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