Undo revision 23130 which was a merge with 2.5, a messy one because I did something...
[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         return gpd;
218 }
219
220 /* -------- Data Duplication ---------- */
221
222 /* make a copy of a given gpencil frame */
223 bGPDframe *gpencil_frame_duplicate (bGPDframe *src)
224 {
225         bGPDstroke *gps, *gpsd;
226         bGPDframe *dst;
227         
228         /* error checking */
229         if (src == NULL)
230                 return NULL;
231                 
232         /* make a copy of the source frame */
233         dst= MEM_dupallocN(src);
234         dst->prev= dst->next= NULL;
235         
236         /* copy strokes */
237         dst->strokes.first = dst->strokes.last= NULL;
238         for (gps= src->strokes.first; gps; gps= gps->next) {
239                 /* make copy of source stroke, then adjust pointer to points too */
240                 gpsd= MEM_dupallocN(gps);
241                 gpsd->points= MEM_dupallocN(gps->points);
242                 
243                 BLI_addtail(&dst->strokes, gpsd);
244         }
245         
246         /* return new frame */
247         return dst;
248 }
249
250 /* make a copy of a given gpencil layer */
251 bGPDlayer *gpencil_layer_duplicate (bGPDlayer *src)
252 {
253         bGPDframe *gpf, *gpfd;
254         bGPDlayer *dst;
255         
256         /* error checking */
257         if (src == NULL)
258                 return NULL;
259                 
260         /* make a copy of source layer */
261         dst= MEM_dupallocN(src);
262         dst->prev= dst->next= NULL;
263         
264         /* copy frames */
265         dst->frames.first= dst->frames.last= NULL;
266         for (gpf= src->frames.first; gpf; gpf= gpf->next) {
267                 /* make a copy of source frame */
268                 gpfd= gpencil_frame_duplicate(gpf);
269                 BLI_addtail(&dst->frames, gpfd);
270                 
271                 /* if source frame was the current layer's 'active' frame, reassign that too */
272                 if (gpf == dst->actframe)
273                         dst->actframe= gpfd;
274         }
275         
276         /* return new layer */
277         return dst;
278 }
279
280 /* make a copy of a given gpencil datablock */
281 bGPdata *gpencil_data_duplicate (bGPdata *src)
282 {
283         bGPDlayer *gpl, *gpld;
284         bGPdata *dst;
285         
286         /* error checking */
287         if (src == NULL)
288                 return NULL;
289         
290         /* make a copy of the base-data */
291         dst= MEM_dupallocN(src);
292         
293         /* copy layers */
294         dst->layers.first= dst->layers.last= NULL;
295         for (gpl= src->layers.first; gpl; gpl= gpl->next) {
296                 /* make a copy of source layer and its data */
297                 gpld= gpencil_layer_duplicate(gpl);
298                 BLI_addtail(&dst->layers, gpld);
299         }
300         
301         /* return new */
302         return dst;
303 }
304
305 /* -------- GP-Frame API ---------- */
306
307 /* delete the last stroke of the given frame */
308 void gpencil_frame_delete_laststroke (bGPDlayer *gpl, bGPDframe *gpf)
309 {
310         bGPDstroke *gps= (gpf) ? gpf->strokes.last : NULL;
311         int cfra = 1; // XXX FIXME!!!
312         
313         /* error checking */
314         if (ELEM(NULL, gpf, gps))
315                 return;
316         
317         /* free the stroke and its data */
318         MEM_freeN(gps->points);
319         BLI_freelinkN(&gpf->strokes, gps);
320         
321         /* if frame has no strokes after this, delete it */
322         if (gpf->strokes.first == NULL) {
323                 gpencil_layer_delframe(gpl, gpf);
324                 gpencil_layer_getframe(gpl, cfra, 0);
325         }
326 }
327
328 /* -------- GP-Layer API ---------- */
329
330 /* get the appropriate gp-frame from a given layer
331  *      - this sets the layer's actframe var (if allowed to)
332  *      - extension beyond range (if first gp-frame is after all frame in interest and cannot add)
333  */
334 bGPDframe *gpencil_layer_getframe (bGPDlayer *gpl, int cframe, short addnew)
335 {
336         bGPDframe *gpf = NULL;
337         short found = 0;
338         
339         /* error checking */
340         if (gpl == NULL) return NULL;
341         if (cframe <= 0) cframe = 1;
342         
343         /* check if there is already an active frame */
344         if (gpl->actframe) {
345                 gpf= gpl->actframe;
346                 
347                 /* do not allow any changes to layer's active frame if layer is locked */
348                 if (gpl->flag & GP_LAYER_LOCKED)
349                         return gpf;
350                 /* do not allow any changes to actframe if frame has painting tag attached to it */
351                 if (gpf->flag & GP_FRAME_PAINT) 
352                         return gpf;
353                 
354                 /* try to find matching frame */
355                 if (gpf->framenum < cframe) {
356                         for (; gpf; gpf= gpf->next) {
357                                 if (gpf->framenum == cframe) {
358                                         found= 1;
359                                         break;
360                                 }
361                                 else if ((gpf->next) && (gpf->next->framenum > cframe)) {
362                                         found= 1;
363                                         break;
364                                 }
365                         }
366                         
367                         /* set the appropriate frame */
368                         if (addnew) {
369                                 if ((found) && (gpf->framenum == cframe))
370                                         gpl->actframe= gpf;
371                                 else
372                                         gpl->actframe= gpencil_frame_addnew(gpl, cframe);
373                         }
374                         else if (found)
375                                 gpl->actframe= gpf;
376                         else
377                                 gpl->actframe= gpl->frames.last;
378                 }
379                 else {
380                         for (; gpf; gpf= gpf->prev) {
381                                 if (gpf->framenum <= cframe) {
382                                         found= 1;
383                                         break;
384                                 }
385                         }
386                         
387                         /* set the appropriate frame */
388                         if (addnew) {
389                                 if ((found) && (gpf->framenum == cframe))
390                                         gpl->actframe= gpf;
391                                 else
392                                         gpl->actframe= gpencil_frame_addnew(gpl, cframe);
393                         }
394                         else if (found)
395                                 gpl->actframe= gpf;
396                         else
397                                 gpl->actframe= gpl->frames.first;
398                 }
399         }
400         else if (gpl->frames.first) {
401                 /* check which of the ends to start checking from */
402                 const int first= ((bGPDframe *)(gpl->frames.first))->framenum;
403                 const int last= ((bGPDframe *)(gpl->frames.last))->framenum;
404                 
405                 if (abs(cframe-first) > abs(cframe-last)) {
406                         /* find gp-frame which is less than or equal to cframe */
407                         for (gpf= gpl->frames.last; gpf; gpf= gpf->prev) {
408                                 if (gpf->framenum <= cframe) {
409                                         found= 1;
410                                         break;
411                                 }
412                         }
413                 }
414                 else {
415                         /* find gp-frame which is less than or equal to cframe */
416                         for (gpf= gpl->frames.first; gpf; gpf= gpf->next) {
417                                 if (gpf->framenum <= cframe) {
418                                         found= 1;
419                                         break;
420                                 }
421                         }
422                 }
423                 
424                 /* set the appropriate frame */
425                 if (addnew) {
426                         if ((found) && (gpf->framenum == cframe))
427                                 gpl->actframe= gpf;
428                         else
429                                 gpl->actframe= gpencil_frame_addnew(gpl, cframe);
430                 }
431                 else if (found)
432                         gpl->actframe= gpf;
433                 else {
434                         /* unresolved errogenous situation! */
435                         printf("Error: cannot find appropriate gp-frame \n");
436                         /* gpl->actframe should still be NULL */
437                 }
438         }
439         else {
440                 /* currently no frames (add if allowed to) */
441                 if (addnew)
442                         gpl->actframe= gpencil_frame_addnew(gpl, cframe);
443                 else {
444                         /* don't do anything... this may be when no frames yet! */
445                         /* gpl->actframe should still be NULL */
446                 }
447         }
448         
449         /* return */
450         return gpl->actframe;
451 }
452
453 /* delete the given frame from a layer */
454 void gpencil_layer_delframe (bGPDlayer *gpl, bGPDframe *gpf)
455 {
456         /* error checking */
457         if (ELEM(NULL, gpl, gpf))
458                 return;
459                 
460         /* free the frame and its data */
461         free_gpencil_strokes(gpf);
462         BLI_freelinkN(&gpl->frames, gpf);
463         gpl->actframe = NULL;
464 }
465
466 /* get the active gp-layer for editing */
467 bGPDlayer *gpencil_layer_getactive (bGPdata *gpd)
468 {
469         bGPDlayer *gpl;
470         
471         /* error checking */
472         if (ELEM(NULL, gpd, gpd->layers.first))
473                 return NULL;
474                 
475         /* loop over layers until found (assume only one active) */
476         for (gpl=gpd->layers.first; gpl; gpl=gpl->next) {
477                 if (gpl->flag & GP_LAYER_ACTIVE)
478                         return gpl;
479         }
480         
481         /* no active layer found */
482         return NULL;
483 }
484
485 /* set the active gp-layer */
486 void gpencil_layer_setactive (bGPdata *gpd, bGPDlayer *active)
487 {
488         bGPDlayer *gpl;
489         
490         /* error checking */
491         if (ELEM3(NULL, gpd, gpd->layers.first, active))
492                 return;
493                 
494         /* loop over layers deactivating all */
495         for (gpl=gpd->layers.first; gpl; gpl=gpl->next)
496                 gpl->flag &= ~GP_LAYER_ACTIVE;
497         
498         /* set as active one */
499         active->flag |= GP_LAYER_ACTIVE;
500 }
501
502 /* delete the active gp-layer */
503 void gpencil_layer_delactive (bGPdata *gpd)
504 {
505         bGPDlayer *gpl= gpencil_layer_getactive(gpd);
506         
507         /* error checking */
508         if (ELEM(NULL, gpd, gpl)) 
509                 return;
510         
511         /* free layer */        
512         free_gpencil_frames(gpl);
513         BLI_freelinkN(&gpd->layers, gpl);
514 }
515
516 /* ************************************************** */