f2225bca3f5b980c71bc88a5860298e2f2dca02e
[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, Antonio Vazquez
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 #include "BLI_math_vector.h"
42 #include "BLI_math_color.h"
43 #include "BLI_string_utils.h"
44 #include "BLI_rand.h"
45 #include "BLI_ghash.h"
46
47 #include "BLT_translation.h"
48
49 #include "DNA_anim_types.h"
50 #include "DNA_meshdata_types.h"
51 #include "DNA_material_types.h"
52 #include "DNA_gpencil_types.h"
53 #include "DNA_userdef_types.h"
54 #include "DNA_scene_types.h"
55 #include "DNA_object_types.h"
56
57 #include "BKE_context.h"
58 #include "BKE_action.h"
59 #include "BKE_animsys.h"
60 #include "BKE_deform.h"
61 #include "BKE_global.h"
62 #include "BKE_gpencil.h"
63 #include "BKE_colortools.h"
64 #include "BKE_icons.h"
65 #include "BKE_library.h"
66 #include "BKE_main.h"
67 #include "BKE_object.h"
68 #include "BKE_material.h"
69
70 #include "DEG_depsgraph.h"
71
72 /* ************************************************** */
73 /* Draw Engine */
74
75 void(*BKE_gpencil_batch_cache_dirty_tag_cb)(bGPdata *gpd) = NULL;
76 void(*BKE_gpencil_batch_cache_free_cb)(bGPdata *gpd) = NULL;
77
78 void BKE_gpencil_batch_cache_dirty_tag(bGPdata *gpd)
79 {
80         if (gpd) {
81                 DEG_id_tag_update(&gpd->id, OB_RECALC_DATA);
82                 BKE_gpencil_batch_cache_dirty_tag_cb(gpd);
83         }
84 }
85
86 void BKE_gpencil_batch_cache_free(bGPdata *gpd)
87 {
88         if (gpd) {
89                 BKE_gpencil_batch_cache_free_cb(gpd);
90         }
91 }
92
93 /* ************************************************** */
94 /* Memory Management */
95
96 /* clean vertex groups weights */
97 void BKE_gpencil_free_point_weights(MDeformVert *dvert)
98 {
99         if (dvert == NULL) {
100                 return;
101         }
102         MEM_SAFE_FREE(dvert->dw);
103 }
104
105 void BKE_gpencil_free_stroke_weights(bGPDstroke *gps)
106 {
107         if (gps == NULL) {
108                 return;
109         }
110
111         if (gps->dvert == NULL) {
112                 return;
113         }
114
115         for (int i = 0; i < gps->totpoints; i++) {
116                 MDeformVert *dvert = &gps->dvert[i];
117                 BKE_gpencil_free_point_weights(dvert);
118         }
119 }
120
121 /* free stroke, doesn't unlink from any listbase */
122 void BKE_gpencil_free_stroke(bGPDstroke *gps)
123 {
124         if (gps == NULL) {
125                 return;
126         }
127         /* free stroke memory arrays, then stroke itself */
128         if (gps->points) {
129                 MEM_freeN(gps->points);
130         }
131         if (gps->dvert) {
132                 BKE_gpencil_free_stroke_weights(gps);
133                 MEM_freeN(gps->dvert);
134         }
135         if (gps->triangles)
136                 MEM_freeN(gps->triangles);
137
138         MEM_freeN(gps);
139 }
140
141 /* Free strokes belonging to a gp-frame */
142 bool BKE_gpencil_free_strokes(bGPDframe *gpf)
143 {
144         bGPDstroke *gps_next;
145         bool changed = (BLI_listbase_is_empty(&gpf->strokes) == false);
146
147         /* free strokes */
148         for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps_next) {
149                 gps_next = gps->next;
150                 BKE_gpencil_free_stroke(gps);
151         }
152         BLI_listbase_clear(&gpf->strokes);
153
154         return changed;
155 }
156
157 /* Free strokes and colors belonging to a gp-frame */
158 bool BKE_gpencil_free_frame_runtime_data(bGPDframe *derived_gpf)
159 {
160         bGPDstroke *gps_next;
161         if (!derived_gpf) {
162                 return false;
163         }
164
165         /* free strokes */
166         for (bGPDstroke *gps = derived_gpf->strokes.first; gps; gps = gps_next) {
167                 gps_next = gps->next;
168                 BKE_gpencil_free_stroke(gps);
169         }
170         BLI_listbase_clear(&derived_gpf->strokes);
171
172         return true;
173 }
174
175 /* Free all of a gp-layer's frames */
176 void BKE_gpencil_free_frames(bGPDlayer *gpl)
177 {
178         bGPDframe *gpf_next;
179
180         /* error checking */
181         if (gpl == NULL) return;
182
183         /* free frames */
184         for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf_next) {
185                 gpf_next = gpf->next;
186
187                 /* free strokes and their associated memory */
188                 BKE_gpencil_free_strokes(gpf);
189                 BLI_freelinkN(&gpl->frames, gpf);
190         }
191         gpl->actframe = NULL;
192 }
193
194
195
196 /* Free all of the gp-layers for a viewport (list should be &gpd->layers or so) */
197 void BKE_gpencil_free_layers(ListBase *list)
198 {
199         bGPDlayer *gpl_next;
200
201         /* error checking */
202         if (list == NULL) return;
203
204         /* delete layers */
205         for (bGPDlayer *gpl = list->first; gpl; gpl = gpl_next) {
206                 gpl_next = gpl->next;
207
208                 /* free layers and their data */
209                 BKE_gpencil_free_frames(gpl);
210                 BLI_freelinkN(list, gpl);
211         }
212 }
213
214 /* clear all runtime derived data */
215 static void BKE_gpencil_clear_derived(bGPDlayer *gpl)
216 {
217         if (gpl->runtime.derived_array == NULL) {
218                 return;
219         }
220
221         for (int i = 0; i < gpl->runtime.len_derived; i++) {
222                 bGPDframe *derived_gpf = &gpl->runtime.derived_array[i];
223                 BKE_gpencil_free_frame_runtime_data(derived_gpf);
224                 derived_gpf = NULL;
225         }
226         gpl->runtime.len_derived = 0;
227         MEM_SAFE_FREE(gpl->runtime.derived_array);
228 }
229
230 /* Free all of the gp-layers temp data*/
231 static void BKE_gpencil_free_layers_temp_data(ListBase *list)
232 {
233         bGPDlayer *gpl_next;
234
235         /* error checking */
236         if (list == NULL) return;
237         /* delete layers */
238         for (bGPDlayer *gpl = list->first; gpl; gpl = gpl_next) {
239                 gpl_next = gpl->next;
240                 BKE_gpencil_clear_derived(gpl);
241         }
242 }
243
244 /* Free temp gpf derived frames */
245 void BKE_gpencil_free_derived_frames(bGPdata *gpd)
246 {
247         /* error checking */
248         if (gpd == NULL) return;
249         for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
250                 BKE_gpencil_clear_derived(gpl);
251         }
252 }
253
254 /** Free (or release) any data used by this grease pencil (does not free the gpencil itself). */
255 void BKE_gpencil_free(bGPdata *gpd, bool free_all)
256 {
257         /* clear animation data */
258         BKE_animdata_free(&gpd->id, false);
259
260         /* free layers */
261         if (free_all) {
262                 BKE_gpencil_free_layers_temp_data(&gpd->layers);
263         }
264         BKE_gpencil_free_layers(&gpd->layers);
265
266         /* materials */
267         MEM_SAFE_FREE(gpd->mat);
268
269         /* free all data */
270         if (free_all) {
271                 /* clear cache */
272                 BKE_gpencil_batch_cache_free(gpd);
273         }
274 }
275
276 /* ************************************************** */
277 /* Container Creation */
278
279 /* add a new gp-frame to the given layer */
280 bGPDframe *BKE_gpencil_frame_addnew(bGPDlayer *gpl, int cframe)
281 {
282         bGPDframe *gpf = NULL, *gf = NULL;
283         short state = 0;
284
285         /* error checking */
286         if (gpl == NULL)
287                 return NULL;
288
289         /* allocate memory for this frame */
290         gpf = MEM_callocN(sizeof(bGPDframe), "bGPDframe");
291         gpf->framenum = cframe;
292
293         /* find appropriate place to add frame */
294         if (gpl->frames.first) {
295                 for (gf = gpl->frames.first; gf; gf = gf->next) {
296                         /* check if frame matches one that is supposed to be added */
297                         if (gf->framenum == cframe) {
298                                 state = -1;
299                                 break;
300                         }
301
302                         /* if current frame has already exceeded the frame to add, add before */
303                         if (gf->framenum > cframe) {
304                                 BLI_insertlinkbefore(&gpl->frames, gf, gpf);
305                                 state = 1;
306                                 break;
307                         }
308                 }
309         }
310
311         /* check whether frame was added successfully */
312         if (state == -1) {
313                 printf("Error: Frame (%d) existed already for this layer. Using existing frame\n", cframe);
314
315                 /* free the newly created one, and use the old one instead */
316                 MEM_freeN(gpf);
317
318                 /* return existing frame instead... */
319                 BLI_assert(gf != NULL);
320                 gpf = gf;
321         }
322         else if (state == 0) {
323                 /* add to end then! */
324                 BLI_addtail(&gpl->frames, gpf);
325         }
326
327         /* return frame */
328         return gpf;
329 }
330
331 /* add a copy of the active gp-frame to the given layer */
332 bGPDframe *BKE_gpencil_frame_addcopy(bGPDlayer *gpl, int cframe)
333 {
334         bGPDframe *new_frame;
335         bool found = false;
336
337         /* Error checking/handling */
338         if (gpl == NULL) {
339                 /* no layer */
340                 return NULL;
341         }
342         else if (gpl->actframe == NULL) {
343                 /* no active frame, so just create a new one from scratch */
344                 return BKE_gpencil_frame_addnew(gpl, cframe);
345         }
346
347         /* Create a copy of the frame */
348         new_frame = BKE_gpencil_frame_duplicate(gpl->actframe);
349
350         /* Find frame to insert it before */
351         for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) {
352                 if (gpf->framenum > cframe) {
353                         /* Add it here */
354                         BLI_insertlinkbefore(&gpl->frames, gpf, new_frame);
355
356                         found = true;
357                         break;
358                 }
359                 else if (gpf->framenum == cframe) {
360                         /* This only happens when we're editing with framelock on...
361                          * - Delete the new frame and don't do anything else here...
362                          */
363                         BKE_gpencil_free_strokes(new_frame);
364                         MEM_freeN(new_frame);
365                         new_frame = NULL;
366
367                         found = true;
368                         break;
369                 }
370         }
371
372         if (found == false) {
373                 /* Add new frame to the end */
374                 BLI_addtail(&gpl->frames, new_frame);
375         }
376
377         /* Ensure that frame is set up correctly, and return it */
378         if (new_frame) {
379                 new_frame->framenum = cframe;
380                 gpl->actframe = new_frame;
381         }
382
383         return new_frame;
384 }
385
386 /* add a new gp-layer and make it the active layer */
387 bGPDlayer *BKE_gpencil_layer_addnew(bGPdata *gpd, const char *name, bool setactive)
388 {
389         bGPDlayer *gpl = NULL;
390         bGPDlayer *gpl_active = NULL;
391
392         /* check that list is ok */
393         if (gpd == NULL)
394                 return NULL;
395
396         /* allocate memory for frame and add to end of list */
397         gpl = MEM_callocN(sizeof(bGPDlayer), "bGPDlayer");
398
399         gpl_active = BKE_gpencil_layer_getactive(gpd);
400
401         /* add to datablock */
402         if (gpl_active == NULL) {
403                 BLI_addtail(&gpd->layers, gpl);
404         }
405         else {
406                 /* if active layer, add after that layer */
407                 BLI_insertlinkafter(&gpd->layers, gpl_active, gpl);
408         }
409
410         /* annotation vs GP Object behaviour is slightly different */
411         if (gpd->flag & GP_DATA_ANNOTATIONS) {
412                 /* set default color of new strokes for this layer */
413                 copy_v4_v4(gpl->color, U.gpencil_new_layer_col);
414                 gpl->opacity = 1.0f;
415
416                 /* set default thickness of new strokes for this layer */
417                 gpl->thickness = 3;
418
419         }
420         else {
421                 /* thickness parameter represents "thickness change", not absolute thickness */
422                 gpl->thickness = 0;
423                 gpl->opacity = 1.0f;
424                 /* onion-skinning settings */
425                 gpl->onion_flag |= GP_LAYER_ONIONSKIN;
426         }
427
428         /* auto-name */
429         BLI_strncpy(gpl->info, name, sizeof(gpl->info));
430         BLI_uniquename(&gpd->layers, gpl,
431                        (gpd->flag & GP_DATA_ANNOTATIONS) ? DATA_("Note") : DATA_("GP_Layer"),
432                        '.',
433                        offsetof(bGPDlayer, info),
434                        sizeof(gpl->info));
435
436         /* make this one the active one */
437         if (setactive)
438                 BKE_gpencil_layer_setactive(gpd, gpl);
439
440         /* return layer */
441         return gpl;
442 }
443
444 /* add a new gp-datablock */
445 bGPdata *BKE_gpencil_data_addnew(Main *bmain, const char name[])
446 {
447         bGPdata *gpd;
448
449         /* allocate memory for a new block */
450         gpd = BKE_libblock_alloc(bmain, ID_GD, name, 0);
451
452         /* initial settings */
453         gpd->flag = (GP_DATA_DISPINFO | GP_DATA_EXPAND);
454
455         /* general flags */
456         gpd->flag |= GP_DATA_VIEWALIGN;
457         gpd->flag |= GP_DATA_STROKE_FORCE_RECALC;
458
459         /* GP object specific settings */
460         ARRAY_SET_ITEMS(gpd->line_color, 0.6f, 0.6f, 0.6f, 0.5f);
461
462         gpd->xray_mode = GP_XRAY_3DSPACE;
463         gpd->pixfactor = GP_DEFAULT_PIX_FACTOR;
464
465         /* grid settings */
466         ARRAY_SET_ITEMS(gpd->grid.color, 0.5f, 0.5f, 0.5f); // Color
467         ARRAY_SET_ITEMS(gpd->grid.scale, 1.0f, 1.0f); // Scale
468         gpd->grid.lines = GP_DEFAULT_GRID_LINES; // Number of lines
469
470         /* onion-skinning settings (datablock level) */
471         gpd->onion_flag |= (GP_ONION_GHOST_PREVCOL | GP_ONION_GHOST_NEXTCOL);
472         gpd->onion_flag |= GP_ONION_FADE;
473         gpd->onion_mode = GP_ONION_MODE_RELATIVE;
474         gpd->onion_factor = 0.5f;
475         ARRAY_SET_ITEMS(gpd->gcolor_prev, 0.145098f, 0.419608f, 0.137255f); /* green */
476         ARRAY_SET_ITEMS(gpd->gcolor_next, 0.125490f, 0.082353f, 0.529412f); /* blue */
477         gpd->gstep = 1;
478         gpd->gstep_next = 1;
479
480         return gpd;
481 }
482
483
484 /* ************************************************** */
485 /* Primitive Creation */
486 /* Utilities for easier bulk-creation of geometry */
487
488 /**
489  * Populate stroke with point data from data buffers
490  *
491  * \param array Flat array of point data values. Each entry has GP_PRIM_DATABUF_SIZE values
492  * \param mat   4x4 transform matrix to transform points into the right coordinate space
493  */
494 void BKE_gpencil_stroke_add_points(bGPDstroke *gps, const float *array, const int totpoints, const float mat[4][4])
495 {
496         for (int i = 0; i < totpoints; i++) {
497                 bGPDspoint *pt = &gps->points[i];
498                 const int x = GP_PRIM_DATABUF_SIZE * i;
499
500                 pt->x = array[x];
501                 pt->y = array[x + 1];
502                 pt->z = array[x + 2];
503                 mul_m4_v3(mat, &pt->x);
504
505                 pt->pressure = array[x + 3];
506                 pt->strength = array[x + 4];
507         }
508 }
509
510 /* Create a new stroke, with pre-allocated data buffers */
511 bGPDstroke *BKE_gpencil_add_stroke(bGPDframe *gpf, int mat_idx, int totpoints, short thickness)
512 {
513         /* allocate memory for a new stroke */
514         bGPDstroke *gps = MEM_callocN(sizeof(bGPDstroke), "gp_stroke");
515
516         gps->thickness = thickness * 25;
517         gps->inittime = 0;
518
519         /* enable recalculation flag by default */
520         gps->flag = GP_STROKE_RECALC_CACHES | GP_STROKE_3DSPACE;
521
522         gps->totpoints = totpoints;
523         gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
524
525         /* initialize triangle memory to dummy data */
526         gps->triangles = MEM_callocN(sizeof(bGPDtriangle), "GP Stroke triangulation");
527         gps->flag |= GP_STROKE_RECALC_CACHES;
528         gps->tot_triangles = 0;
529
530         gps->mat_nr = mat_idx;
531
532         /* add to frame */
533         BLI_addtail(&gpf->strokes, gps);
534
535         return gps;
536 }
537
538
539 /* ************************************************** */
540 /* Data Duplication */
541
542 /* make a copy of a given gpencil weights */
543 void BKE_gpencil_stroke_weights_duplicate(bGPDstroke *gps_src, bGPDstroke *gps_dst)
544 {
545         if (gps_src == NULL) {
546                 return;
547         }
548         BLI_assert(gps_src->totpoints == gps_dst->totpoints);
549
550         BKE_defvert_array_copy(gps_dst->dvert, gps_src->dvert, gps_src->totpoints);
551 }
552
553 /* make a copy of a given gpencil stroke */
554 bGPDstroke *BKE_gpencil_stroke_duplicate(bGPDstroke *gps_src)
555 {
556         bGPDstroke *gps_dst = NULL;
557
558         gps_dst = MEM_dupallocN(gps_src);
559         gps_dst->prev = gps_dst->next = NULL;
560
561         gps_dst->points = MEM_dupallocN(gps_src->points);
562
563         if (gps_src->dvert != NULL) {
564                 gps_dst->dvert = MEM_dupallocN(gps_src->dvert);
565                 BKE_gpencil_stroke_weights_duplicate(gps_src, gps_dst);
566         }
567         else {
568                 gps_dst->dvert = NULL;
569         }
570
571         /* Don't clear triangles, so that modifier evaluation can just use
572          * this without extra work first. Most places that need to force
573          * this data to get recalculated will destroy the data anyway though.
574          */
575         gps_dst->triangles = MEM_dupallocN(gps_dst->triangles);
576         /* gps_dst->flag |= GP_STROKE_RECALC_CACHES; */
577
578         /* return new stroke */
579         return gps_dst;
580 }
581
582 /* make a copy of a given gpencil frame */
583 bGPDframe *BKE_gpencil_frame_duplicate(const bGPDframe *gpf_src)
584 {
585         bGPDstroke *gps_dst = NULL;
586         bGPDframe *gpf_dst;
587
588         /* error checking */
589         if (gpf_src == NULL) {
590                 return NULL;
591         }
592
593         /* make a copy of the source frame */
594         gpf_dst = MEM_dupallocN(gpf_src);
595         gpf_dst->prev = gpf_dst->next = NULL;
596
597         /* copy strokes */
598         BLI_listbase_clear(&gpf_dst->strokes);
599         for (bGPDstroke *gps_src = gpf_src->strokes.first; gps_src; gps_src = gps_src->next) {
600                 /* make copy of source stroke */
601                 gps_dst = BKE_gpencil_stroke_duplicate(gps_src);
602                 BLI_addtail(&gpf_dst->strokes, gps_dst);
603         }
604
605         /* return new frame */
606         return gpf_dst;
607 }
608
609 /* make a copy of strokes between gpencil frames */
610 void BKE_gpencil_frame_copy_strokes(bGPDframe *gpf_src, struct bGPDframe *gpf_dst)
611 {
612         bGPDstroke *gps_dst = NULL;
613         /* error checking */
614         if ((gpf_src == NULL) || (gpf_dst == NULL)) {
615                 return;
616         }
617
618         /* copy strokes */
619         BLI_listbase_clear(&gpf_dst->strokes);
620         for (bGPDstroke *gps_src = gpf_src->strokes.first; gps_src; gps_src = gps_src->next) {
621                 /* make copy of source stroke */
622                 gps_dst = BKE_gpencil_stroke_duplicate(gps_src);
623                 BLI_addtail(&gpf_dst->strokes, gps_dst);
624         }
625 }
626
627 /* make a copy of a given gpencil layer */
628 bGPDlayer *BKE_gpencil_layer_duplicate(const bGPDlayer *gpl_src)
629 {
630         const bGPDframe *gpf_src;
631         bGPDframe *gpf_dst;
632         bGPDlayer *gpl_dst;
633
634         /* error checking */
635         if (gpl_src == NULL) {
636                 return NULL;
637         }
638
639         /* make a copy of source layer */
640         gpl_dst = MEM_dupallocN(gpl_src);
641         gpl_dst->prev = gpl_dst->next = NULL;
642         gpl_dst->runtime.derived_array = NULL;
643         gpl_dst->runtime.len_derived = 0;
644
645         /* copy frames */
646         BLI_listbase_clear(&gpl_dst->frames);
647         for (gpf_src = gpl_src->frames.first; gpf_src; gpf_src = gpf_src->next) {
648                 /* make a copy of source frame */
649                 gpf_dst = BKE_gpencil_frame_duplicate(gpf_src);
650                 BLI_addtail(&gpl_dst->frames, gpf_dst);
651
652                 /* if source frame was the current layer's 'active' frame, reassign that too */
653                 if (gpf_src == gpl_dst->actframe)
654                         gpl_dst->actframe = gpf_dst;
655         }
656
657         /* return new layer */
658         return gpl_dst;
659 }
660
661 /**
662  * Only copy internal data of GreasePencil ID from source to already allocated/initialized destination.
663  * You probably never want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
664  *
665  * WARNING! This function will not handle ID user count!
666  *
667  * \param flag  Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
668  */
669 void BKE_gpencil_copy_data(bGPdata *gpd_dst, const bGPdata *gpd_src, const int UNUSED(flag))
670 {
671         /* duplicate material array */
672         if (gpd_src->mat) {
673                 gpd_dst->mat = MEM_dupallocN(gpd_src->mat);
674         }
675
676         /* copy layers */
677         BLI_listbase_clear(&gpd_dst->layers);
678         for (const bGPDlayer *gpl_src = gpd_src->layers.first; gpl_src; gpl_src = gpl_src->next) {
679                 /* make a copy of source layer and its data */
680                 bGPDlayer *gpl_dst = BKE_gpencil_layer_duplicate(gpl_src);  /* TODO here too could add unused flags... */
681                 BLI_addtail(&gpd_dst->layers, gpl_dst);
682         }
683
684 }
685
686 /* Standard API to make a copy of GP datablock, separate from copying its data */
687 bGPdata *BKE_gpencil_copy(Main *bmain, const bGPdata *gpd)
688 {
689         bGPdata *gpd_copy;
690         BKE_id_copy_ex(bmain, &gpd->id, (ID **)&gpd_copy, 0, false);
691         return gpd_copy;
692 }
693
694 /* make a copy of a given gpencil datablock */
695 // XXX: Should this be deprecated?
696 bGPdata *BKE_gpencil_data_duplicate(Main *bmain, const bGPdata *gpd_src, bool internal_copy)
697 {
698         bGPdata *gpd_dst;
699
700         /* Yuck and super-uber-hyper yuck!!!
701          * Should be replaceable with a no-main copy (LIB_ID_COPY_NO_MAIN etc.), but not sure about it,
702          * so for now keep old code for that one. */
703
704         /* error checking */
705         if (gpd_src == NULL) {
706                 return NULL;
707         }
708
709         if (internal_copy) {
710                 /* make a straight copy for undo buffers used during stroke drawing */
711                 gpd_dst = MEM_dupallocN(gpd_src);
712         }
713         else {
714                 BLI_assert(bmain != NULL);
715                 BKE_id_copy_ex(bmain, &gpd_src->id, (ID **)&gpd_dst, 0, false);
716         }
717
718         /* Copy internal data (layers, etc.) */
719         BKE_gpencil_copy_data(gpd_dst, gpd_src, 0);
720
721         /* return new */
722         return gpd_dst;
723 }
724
725 void BKE_gpencil_make_local(Main *bmain, bGPdata *gpd, const bool lib_local)
726 {
727         BKE_id_make_local_generic(bmain, &gpd->id, true, lib_local);
728 }
729
730 /* ************************************************** */
731 /* GP Stroke API */
732
733 /* ensure selection status of stroke is in sync with its points */
734 void BKE_gpencil_stroke_sync_selection(bGPDstroke *gps)
735 {
736         bGPDspoint *pt;
737         int i;
738
739         /* error checking */
740         if (gps == NULL)
741                 return;
742
743         /* we'll stop when we find the first selected point,
744          * so initially, we must deselect
745          */
746         gps->flag &= ~GP_STROKE_SELECT;
747
748         for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
749                 if (pt->flag & GP_SPOINT_SELECT) {
750                         gps->flag |= GP_STROKE_SELECT;
751                         break;
752                 }
753         }
754 }
755
756 /* ************************************************** */
757 /* GP Frame API */
758
759 /* delete the last stroke of the given frame */
760 void BKE_gpencil_frame_delete_laststroke(bGPDlayer *gpl, bGPDframe *gpf)
761 {
762         bGPDstroke *gps = (gpf) ? gpf->strokes.last : NULL;
763         int cfra = (gpf) ? gpf->framenum : 0; /* assume that the current frame was not locked */
764
765         /* error checking */
766         if (ELEM(NULL, gpf, gps))
767                 return;
768
769         /* free the stroke and its data */
770         if (gps->points) {
771                 MEM_freeN(gps->points);
772         }
773         if (gps->dvert) {
774                 BKE_gpencil_free_stroke_weights(gps);
775                 MEM_freeN(gps->dvert);
776         }
777         MEM_freeN(gps->triangles);
778         BLI_freelinkN(&gpf->strokes, gps);
779
780         /* if frame has no strokes after this, delete it */
781         if (BLI_listbase_is_empty(&gpf->strokes)) {
782                 BKE_gpencil_layer_delframe(gpl, gpf);
783                 BKE_gpencil_layer_getframe(gpl, cfra, GP_GETFRAME_USE_PREV);
784         }
785 }
786
787 /* ************************************************** */
788 /* GP Layer API */
789
790 /* Check if the given layer is able to be edited or not */
791 bool gpencil_layer_is_editable(const bGPDlayer *gpl)
792 {
793         /* Sanity check */
794         if (gpl == NULL)
795                 return false;
796
797         /* Layer must be: Visible + Editable */
798         if ((gpl->flag & (GP_LAYER_HIDE | GP_LAYER_LOCKED)) == 0) {
799                 /* Opacity must be sufficiently high that it is still "visible"
800                  * Otherwise, it's not really "visible" to the user, so no point editing...
801                  */
802                 if (gpl->opacity > GPENCIL_ALPHA_OPACITY_THRESH) {
803                         return true;
804                 }
805         }
806
807         /* Something failed */
808         return false;
809 }
810
811 /* Look up the gp-frame on the requested frame number, but don't add a new one */
812 bGPDframe *BKE_gpencil_layer_find_frame(bGPDlayer *gpl, int cframe)
813 {
814         bGPDframe *gpf;
815
816         /* Search in reverse order, since this is often used for playback/adding,
817          * where it's less likely that we're interested in the earlier frames
818          */
819         for (gpf = gpl->frames.last; gpf; gpf = gpf->prev) {
820                 if (gpf->framenum == cframe) {
821                         return gpf;
822                 }
823         }
824
825         return NULL;
826 }
827
828 /* get the appropriate gp-frame from a given layer
829  * - this sets the layer's actframe var (if allowed to)
830  * - extension beyond range (if first gp-frame is after all frame in interest and cannot add)
831  */
832 bGPDframe *BKE_gpencil_layer_getframe(bGPDlayer *gpl, int cframe, eGP_GetFrame_Mode addnew)
833 {
834         bGPDframe *gpf = NULL;
835         short found = 0;
836
837         /* error checking */
838         if (gpl == NULL) return NULL;
839
840         /* check if there is already an active frame */
841         if (gpl->actframe) {
842                 gpf = gpl->actframe;
843
844                 /* do not allow any changes to layer's active frame if layer is locked from changes
845                  * or if the layer has been set to stay on the current frame
846                  */
847                 if (gpl->flag & GP_LAYER_FRAMELOCK)
848                         return gpf;
849                 /* do not allow any changes to actframe if frame has painting tag attached to it */
850                 if (gpf->flag & GP_FRAME_PAINT)
851                         return gpf;
852
853                 /* try to find matching frame */
854                 if (gpf->framenum < cframe) {
855                         for (; gpf; gpf = gpf->next) {
856                                 if (gpf->framenum == cframe) {
857                                         found = 1;
858                                         break;
859                                 }
860                                 else if ((gpf->next) && (gpf->next->framenum > cframe)) {
861                                         found = 1;
862                                         break;
863                                 }
864                         }
865
866                         /* set the appropriate frame */
867                         if (addnew) {
868                                 if ((found) && (gpf->framenum == cframe))
869                                         gpl->actframe = gpf;
870                                 else if (addnew == GP_GETFRAME_ADD_COPY)
871                                         gpl->actframe = BKE_gpencil_frame_addcopy(gpl, cframe);
872                                 else
873                                         gpl->actframe = BKE_gpencil_frame_addnew(gpl, cframe);
874                         }
875                         else if (found)
876                                 gpl->actframe = gpf;
877                         else
878                                 gpl->actframe = gpl->frames.last;
879                 }
880                 else {
881                         for (; gpf; gpf = gpf->prev) {
882                                 if (gpf->framenum <= cframe) {
883                                         found = 1;
884                                         break;
885                                 }
886                         }
887
888                         /* set the appropriate frame */
889                         if (addnew) {
890                                 if ((found) && (gpf->framenum == cframe))
891                                         gpl->actframe = gpf;
892                                 else if (addnew == GP_GETFRAME_ADD_COPY)
893                                         gpl->actframe = BKE_gpencil_frame_addcopy(gpl, cframe);
894                                 else
895                                         gpl->actframe = BKE_gpencil_frame_addnew(gpl, cframe);
896                         }
897                         else if (found)
898                                 gpl->actframe = gpf;
899                         else
900                                 gpl->actframe = gpl->frames.first;
901                 }
902         }
903         else if (gpl->frames.first) {
904                 /* check which of the ends to start checking from */
905                 const int first = ((bGPDframe *)(gpl->frames.first))->framenum;
906                 const int last = ((bGPDframe *)(gpl->frames.last))->framenum;
907
908                 if (abs(cframe - first) > abs(cframe - last)) {
909                         /* find gp-frame which is less than or equal to cframe */
910                         for (gpf = gpl->frames.last; gpf; gpf = gpf->prev) {
911                                 if (gpf->framenum <= cframe) {
912                                         found = 1;
913                                         break;
914                                 }
915                         }
916                 }
917                 else {
918                         /* find gp-frame which is less than or equal to cframe */
919                         for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
920                                 if (gpf->framenum <= cframe) {
921                                         found = 1;
922                                         break;
923                                 }
924                         }
925                 }
926
927                 /* set the appropriate frame */
928                 if (addnew) {
929                         if ((found) && (gpf->framenum == cframe))
930                                 gpl->actframe = gpf;
931                         else
932                                 gpl->actframe = BKE_gpencil_frame_addnew(gpl, cframe);
933                 }
934                 else if (found)
935                         gpl->actframe = gpf;
936                 else {
937                         /* unresolved errogenous situation! */
938                         printf("Error: cannot find appropriate gp-frame\n");
939                         /* gpl->actframe should still be NULL */
940                 }
941         }
942         else {
943                 /* currently no frames (add if allowed to) */
944                 if (addnew)
945                         gpl->actframe = BKE_gpencil_frame_addnew(gpl, cframe);
946                 else {
947                         /* don't do anything... this may be when no frames yet! */
948                         /* gpl->actframe should still be NULL */
949                 }
950         }
951
952         /* return */
953         return gpl->actframe;
954 }
955
956 /* delete the given frame from a layer */
957 bool BKE_gpencil_layer_delframe(bGPDlayer *gpl, bGPDframe *gpf)
958 {
959         bool changed = false;
960
961         /* error checking */
962         if (ELEM(NULL, gpl, gpf))
963                 return false;
964
965         /* if this frame was active, make the previous frame active instead
966          * since it's tricky to set active frame otherwise
967          */
968         if (gpl->actframe == gpf)
969                 gpl->actframe = gpf->prev;
970
971         /* free the frame and its data */
972         changed = BKE_gpencil_free_strokes(gpf);
973         BLI_freelinkN(&gpl->frames, gpf);
974
975         return changed;
976 }
977
978 /* get the active gp-layer for editing */
979 bGPDlayer *BKE_gpencil_layer_getactive(bGPdata *gpd)
980 {
981         bGPDlayer *gpl;
982
983         /* error checking */
984         if (ELEM(NULL, gpd, gpd->layers.first))
985                 return NULL;
986
987         /* loop over layers until found (assume only one active) */
988         for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
989                 if (gpl->flag & GP_LAYER_ACTIVE)
990                         return gpl;
991         }
992
993         /* no active layer found */
994         return NULL;
995 }
996
997 /* set the active gp-layer */
998 void BKE_gpencil_layer_setactive(bGPdata *gpd, bGPDlayer *active)
999 {
1000         bGPDlayer *gpl;
1001
1002         /* error checking */
1003         if (ELEM(NULL, gpd, gpd->layers.first, active))
1004                 return;
1005
1006         /* loop over layers deactivating all */
1007         for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
1008                 gpl->flag &= ~GP_LAYER_ACTIVE;
1009                 if (gpd->flag & GP_DATA_AUTOLOCK_LAYERS) {
1010                         gpl->flag |= GP_LAYER_LOCKED;
1011                 }
1012         }
1013
1014         /* set as active one */
1015         active->flag |= GP_LAYER_ACTIVE;
1016         if (gpd->flag & GP_DATA_AUTOLOCK_LAYERS) {
1017                 active->flag &= ~GP_LAYER_LOCKED;
1018         }
1019 }
1020
1021 /* delete the active gp-layer */
1022 void BKE_gpencil_layer_delete(bGPdata *gpd, bGPDlayer *gpl)
1023 {
1024         /* error checking */
1025         if (ELEM(NULL, gpd, gpl))
1026                 return;
1027
1028         /* free layer */
1029         BKE_gpencil_free_frames(gpl);
1030
1031         /* free icon providing preview of icon color */
1032         BKE_icon_delete(gpl->runtime.icon_id);
1033
1034         /* free derived data */
1035         BKE_gpencil_clear_derived(gpl);
1036
1037         BLI_freelinkN(&gpd->layers, gpl);
1038 }
1039
1040 Material *BKE_gpencil_get_material_from_brush(Brush *brush)
1041 {
1042         Material *ma = NULL;
1043
1044         if ((brush != NULL) && (brush->gpencil_settings != NULL) &&
1045             (brush->gpencil_settings->material != NULL))
1046         {
1047                 ma = brush->gpencil_settings->material;
1048         }
1049
1050         return ma;
1051 }
1052
1053 /* Get active color, and add all default settings if we don't find anything */
1054 Material *BKE_gpencil_material_ensure(Main *bmain, Object *ob)
1055 {
1056         Material *ma = NULL;
1057
1058         /* sanity checks */
1059         if (ELEM(NULL, bmain, ob))
1060                 return NULL;
1061
1062         ma = give_current_material(ob, ob->actcol);
1063         if (ma == NULL) {
1064                 if (ob->totcol == 0) {
1065                         BKE_object_material_slot_add(bmain, ob);
1066                 }
1067                 ma = BKE_material_add_gpencil(bmain, DATA_("Material"));
1068                 assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_USERPREF);
1069         }
1070         else if (ma->gp_style == NULL) {
1071                 BKE_material_init_gpencil_settings(ma);
1072         }
1073
1074         return ma;
1075 }
1076
1077 /* ************************************************** */
1078 /* GP Object - Boundbox Support */
1079
1080 /**
1081  * Get min/max coordinate bounds for single stroke
1082  * \return Returns whether we found any selected points
1083  */
1084 bool BKE_gpencil_stroke_minmax(
1085         const bGPDstroke *gps, const bool use_select,
1086         float r_min[3], float r_max[3])
1087 {
1088         const bGPDspoint *pt;
1089         int i;
1090         bool changed = false;
1091
1092         if (ELEM(NULL, gps, r_min, r_max))
1093                 return false;
1094
1095         for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
1096                 if ((use_select == false) || (pt->flag & GP_SPOINT_SELECT)) {
1097                         minmax_v3v3_v3(r_min, r_max, &pt->x);
1098                         changed = true;
1099                 }
1100         }
1101         return changed;
1102 }
1103
1104 /* get min/max bounds of all strokes in GP datablock */
1105 bool BKE_gpencil_data_minmax(Object *ob, const bGPdata *gpd, float r_min[3], float r_max[3])
1106 {
1107         float bmat[3][3];
1108         bool changed = false;
1109
1110         INIT_MINMAX(r_min, r_max);
1111
1112         if (gpd == NULL)
1113                 return changed;
1114
1115         for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
1116                 bGPDframe *gpf = gpl->actframe;
1117
1118                 if (gpf != NULL) {
1119                         for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
1120                                 changed = BKE_gpencil_stroke_minmax(gps, false, r_min, r_max);
1121                         }
1122                 }
1123         }
1124
1125         if ((changed) && (ob)) {
1126                 copy_m3_m4(bmat, ob->obmat);
1127                 mul_m3_v3(bmat, r_min);
1128                 add_v3_v3(r_min, ob->obmat[3]);
1129                 mul_m3_v3(bmat, r_max);
1130                 add_v3_v3(r_max, ob->obmat[3]);
1131         }
1132
1133         return changed;
1134 }
1135
1136 bool BKE_gpencil_stroke_select_check(
1137         const bGPDstroke *gps)
1138 {
1139         const bGPDspoint *pt;
1140         int i;
1141         for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
1142                 if (pt->flag & GP_SPOINT_SELECT) {
1143                         return true;
1144                 }
1145         }
1146         return false;
1147 }
1148
1149 /* compute center of bounding box */
1150 void BKE_gpencil_centroid_3d(bGPdata *gpd, float r_centroid[3])
1151 {
1152         float min[3], max[3], tot[3];
1153
1154         BKE_gpencil_data_minmax(NULL, gpd, min, max);
1155
1156         add_v3_v3v3(tot, min, max);
1157         mul_v3_v3fl(r_centroid, tot, 0.5f);
1158 }
1159
1160
1161 /* create bounding box values */
1162 static void boundbox_gpencil(Object *ob)
1163 {
1164         BoundBox *bb;
1165         bGPdata *gpd;
1166         float min[3], max[3];
1167
1168         if (ob->bb == NULL) {
1169                 ob->bb = MEM_callocN(sizeof(BoundBox), "GPencil boundbox");
1170         }
1171
1172         bb  = ob->bb;
1173         gpd = ob->data;
1174
1175         BKE_gpencil_data_minmax(NULL, gpd, min, max);
1176         BKE_boundbox_init_from_minmax(bb, min, max);
1177
1178         bb->flag &= ~BOUNDBOX_DIRTY;
1179 }
1180
1181 /* get bounding box */
1182 BoundBox *BKE_gpencil_boundbox_get(Object *ob)
1183 {
1184         bGPdata *gpd;
1185
1186         if (ELEM(NULL, ob, ob->data))
1187                 return NULL;
1188
1189         gpd = ob->data;
1190         if ((ob->bb) && ((ob->bb->flag & BOUNDBOX_DIRTY) == 0) &&
1191             ((gpd->flag & GP_DATA_CACHE_IS_DIRTY) == 0))
1192         {
1193                 return ob->bb;
1194         }
1195
1196         boundbox_gpencil(ob);
1197
1198         return ob->bb;
1199 }
1200
1201 /* ************************************************** */
1202 /* Apply Transforms */
1203
1204 void BKE_gpencil_transform(bGPdata *gpd, float mat[4][4])
1205 {
1206         if (gpd == NULL)
1207                 return;
1208
1209         for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
1210                 /* FIXME: For now, we just skip parented layers.
1211                  * Otherwise, we have to update each frame to find
1212                  * the current parent position/effects.
1213                  */
1214                 if (gpl->parent) {
1215                         continue;
1216                 }
1217
1218                 for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) {
1219                         for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
1220                                 bGPDspoint *pt;
1221                                 int i;
1222
1223                                 for (pt = gps->points, i = 0; i < gps->totpoints; pt++, i++) {
1224                                         mul_m4_v3(mat, &pt->x);
1225                                 }
1226
1227                                 /* TODO: Do we need to do this? distortion may mean we need to re-triangulate */
1228                                 gps->flag |= GP_STROKE_RECALC_CACHES;
1229                                 gps->tot_triangles = 0;
1230                         }
1231                 }
1232         }
1233
1234 }
1235
1236 /* ************************************************** */
1237 /* GP Object - Vertex Groups */
1238
1239 /* remove a vertex group */
1240 void BKE_gpencil_vgroup_remove(Object *ob, bDeformGroup *defgroup)
1241 {
1242         bGPdata *gpd = ob->data;
1243         MDeformVert *dvert = NULL;
1244         const int def_nr = BLI_findindex(&ob->defbase, defgroup);
1245
1246         /* Remove points data */
1247         if (gpd) {
1248                 for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
1249                         for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) {
1250                                 for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
1251                                         if (gps->dvert != NULL) {
1252                                                 for (int i = 0; i < gps->totpoints; i++) {
1253                                                         dvert = &gps->dvert[i];
1254                                                         MDeformWeight *dw = defvert_find_index(dvert, def_nr);
1255                                                         if (dw != NULL) {
1256                                                                 defvert_remove_group(dvert, dw);
1257                                                         }
1258                                                 }
1259                                         }
1260                                 }
1261                         }
1262                 }
1263         }
1264
1265         /* Remove the group */
1266         BLI_freelinkN(&ob->defbase, defgroup);
1267         DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
1268 }
1269
1270
1271 void BKE_gpencil_dvert_ensure(bGPDstroke *gps)
1272 {
1273         if (gps->dvert == NULL) {
1274                 gps->dvert = MEM_callocN(sizeof(MDeformVert) * gps->totpoints, "gp_stroke_weights");
1275         }
1276 }
1277
1278 /* ************************************************** */
1279
1280 /**
1281  * Apply smooth to stroke point
1282  * \param gps              Stroke to smooth
1283  * \param i                Point index
1284  * \param inf              Amount of smoothing to apply
1285  */
1286 bool BKE_gpencil_smooth_stroke(bGPDstroke *gps, int i, float inf)
1287 {
1288         bGPDspoint *pt = &gps->points[i];
1289         // float pressure = 0.0f;
1290         float sco[3] = { 0.0f };
1291
1292         /* Do nothing if not enough points to smooth out */
1293         if (gps->totpoints <= 2) {
1294                 return false;
1295         }
1296
1297         /* Only affect endpoints by a fraction of the normal strength,
1298          * to prevent the stroke from shrinking too much
1299          */
1300         if ((i == 0) || (i == gps->totpoints - 1)) {
1301                 inf *= 0.1f;
1302         }
1303
1304         /* Compute smoothed coordinate by taking the ones nearby */
1305         /* XXX: This is potentially slow, and suffers from accumulation error as earlier points are handled before later ones */
1306         {
1307                 // XXX: this is hardcoded to look at 2 points on either side of the current one (i.e. 5 items total)
1308                 const int   steps = 2;
1309                 const float average_fac = 1.0f / (float)(steps * 2 + 1);
1310                 int step;
1311
1312                 /* add the point itself */
1313                 madd_v3_v3fl(sco, &pt->x, average_fac);
1314
1315                 /* n-steps before/after current point */
1316                 // XXX: review how the endpoints are treated by this algorithm
1317                 // XXX: falloff measures should also introduce some weighting variations, so that further-out points get less weight
1318                 for (step = 1; step <= steps; step++) {
1319                         bGPDspoint *pt1, *pt2;
1320                         int before = i - step;
1321                         int after = i + step;
1322
1323                         CLAMP_MIN(before, 0);
1324                         CLAMP_MAX(after, gps->totpoints - 1);
1325
1326                         pt1 = &gps->points[before];
1327                         pt2 = &gps->points[after];
1328
1329                         /* add both these points to the average-sum (s += p[i]/n) */
1330                         madd_v3_v3fl(sco, &pt1->x, average_fac);
1331                         madd_v3_v3fl(sco, &pt2->x, average_fac);
1332
1333                 }
1334         }
1335
1336         /* Based on influence factor, blend between original and optimal smoothed coordinate */
1337         interp_v3_v3v3(&pt->x, &pt->x, sco, inf);
1338
1339         return true;
1340 }
1341
1342 /**
1343  * Apply smooth for strength to stroke point */
1344 bool BKE_gpencil_smooth_stroke_strength(bGPDstroke *gps, int point_index, float influence)
1345 {
1346         bGPDspoint *ptb = &gps->points[point_index];
1347
1348         /* Do nothing if not enough points */
1349         if (gps->totpoints <= 2) {
1350                 return false;
1351         }
1352
1353         /* Compute theoretical optimal value using distances */
1354         bGPDspoint *pta, *ptc;
1355         int before = point_index - 1;
1356         int after = point_index + 1;
1357
1358         CLAMP_MIN(before, 0);
1359         CLAMP_MAX(after, gps->totpoints - 1);
1360
1361         pta = &gps->points[before];
1362         ptc = &gps->points[after];
1363
1364         /* the optimal value is the corresponding to the interpolation of the strength
1365          * at the distance of point b
1366          */
1367         float fac = line_point_factor_v3(&ptb->x, &pta->x, &ptc->x);
1368         /* sometimes the factor can be wrong due stroke geometry, so use middle point */
1369         if ((fac < 0.0f) || (fac > 1.0f)) {
1370                 fac = 0.5f;
1371         }
1372         const float optimal = (1.0f - fac) * pta->strength + fac * ptc->strength;
1373
1374         /* Based on influence factor, blend between original and optimal */
1375         ptb->strength = (1.0f - influence) * ptb->strength + influence * optimal;
1376
1377         return true;
1378 }
1379
1380 /**
1381  * Apply smooth for thickness to stroke point (use pressure) */
1382 bool BKE_gpencil_smooth_stroke_thickness(bGPDstroke *gps, int point_index, float influence)
1383 {
1384         bGPDspoint *ptb = &gps->points[point_index];
1385
1386         /* Do nothing if not enough points */
1387         if ((gps->totpoints <= 2) || (point_index < 1)) {
1388                 return false;
1389         }
1390
1391         /* Compute theoretical optimal value using distances */
1392         bGPDspoint *pta, *ptc;
1393         int before = point_index - 1;
1394         int after = point_index + 1;
1395
1396         CLAMP_MIN(before, 0);
1397         CLAMP_MAX(after, gps->totpoints - 1);
1398
1399         pta = &gps->points[before];
1400         ptc = &gps->points[after];
1401
1402         /* the optimal value is the corresponding to the interpolation of the pressure
1403          * at the distance of point b
1404          */
1405         float fac = line_point_factor_v3(&ptb->x, &pta->x, &ptc->x);
1406         /* sometimes the factor can be wrong due stroke geometry, so use middle point */
1407         if ((fac < 0.0f) || (fac > 1.0f)) {
1408                 fac = 0.5f;
1409         }
1410         float optimal = interpf(ptc->pressure, pta->pressure, fac);
1411
1412         /* Based on influence factor, blend between original and optimal */
1413         ptb->pressure = interpf(optimal, ptb->pressure, influence);
1414
1415         return true;
1416 }
1417
1418 /**
1419 * Apply smooth for UV rotation to stroke point (use pressure) */
1420 bool BKE_gpencil_smooth_stroke_uv(bGPDstroke *gps, int point_index, float influence)
1421 {
1422         bGPDspoint *ptb = &gps->points[point_index];
1423
1424         /* Do nothing if not enough points */
1425         if (gps->totpoints <= 2) {
1426                 return false;
1427         }
1428
1429         /* Compute theoretical optimal value */
1430         bGPDspoint *pta, *ptc;
1431         int before = point_index - 1;
1432         int after = point_index + 1;
1433
1434         CLAMP_MIN(before, 0);
1435         CLAMP_MAX(after, gps->totpoints - 1);
1436
1437         pta = &gps->points[before];
1438         ptc = &gps->points[after];
1439
1440         /* the optimal value is the corresponding to the interpolation of the pressure
1441          * at the distance of point b
1442          */
1443         float fac = line_point_factor_v3(&ptb->x, &pta->x, &ptc->x);
1444         /* sometimes the factor can be wrong due stroke geometry, so use middle point */
1445         if ((fac < 0.0f) || (fac > 1.0f)) {
1446                 fac = 0.5f;
1447         }
1448         float optimal = interpf(ptc->uv_rot, pta->uv_rot, fac);
1449
1450         /* Based on influence factor, blend between original and optimal */
1451         ptb->uv_rot = interpf(optimal, ptb->uv_rot, influence);
1452         CLAMP(ptb->uv_rot, -M_PI_2, M_PI_2);
1453
1454         return true;
1455 }
1456
1457 /**
1458  * Get range of selected frames in layer.
1459  * Always the active frame is considered as selected, so if no more selected the range
1460  * will be equal to the current active frame.
1461  * \param gpl              Layer
1462  * \param r_initframe      Number of first selected frame
1463  * \param r_endframe       Number of last selected frame
1464  */
1465 void BKE_gpencil_get_range_selected(bGPDlayer *gpl, int *r_initframe, int *r_endframe)
1466 {
1467         *r_initframe = gpl->actframe->framenum;
1468         *r_endframe = gpl->actframe->framenum;
1469
1470         for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) {
1471                 if (gpf->flag & GP_FRAME_SELECT) {
1472                         if (gpf->framenum < *r_initframe) {
1473                                 *r_initframe = gpf->framenum;
1474                         }
1475                         if (gpf->framenum > *r_endframe) {
1476                                 *r_endframe = gpf->framenum;
1477                         }
1478                 }
1479         }
1480 }
1481
1482 /**
1483  * Get Falloff factor base on frame range
1484  * \param gpf          Frame
1485  * \param actnum       Number of active frame in layer
1486  * \param f_init       Number of first selected frame
1487  * \param f_end        Number of last selected frame
1488  * \param cur_falloff  Curve with falloff factors
1489  */
1490 float BKE_gpencil_multiframe_falloff_calc(bGPDframe *gpf, int actnum, int f_init, int f_end, CurveMapping *cur_falloff)
1491 {
1492         float fnum = 0.5f; /* default mid curve */
1493         float value;
1494
1495         /* check curve is available */
1496         if (cur_falloff == NULL) {
1497                 return 1.0f;
1498         }
1499
1500         /* frames to the right of the active frame */
1501         if (gpf->framenum < actnum) {
1502                 fnum = (float)(gpf->framenum - f_init) / (actnum - f_init);
1503                 fnum *= 0.5f;
1504                 value = curvemapping_evaluateF(cur_falloff, 0, fnum);
1505         }
1506         /* frames to the left of the active frame */
1507         else if (gpf->framenum > actnum) {
1508                 fnum = (float)(gpf->framenum - actnum) / (f_end - actnum);
1509                 fnum *= 0.5f;
1510                 value = curvemapping_evaluateF(cur_falloff, 0, fnum + 0.5f);
1511         }
1512         else {
1513                 value = 1.0f;
1514         }
1515
1516         return value;
1517 }
1518
1519 /* remove strokes using a material */
1520 void BKE_gpencil_material_index_remove(bGPdata *gpd, int index)
1521 {
1522         bGPDstroke *gps, *gpsn;
1523
1524                 for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
1525                         for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) {
1526                                 for (gps = gpf->strokes.first; gps; gps = gpsn) {
1527                                         gpsn = gps->next;
1528                                         if (gps->mat_nr == index) {
1529                                                 if (gps->points) {
1530                                                         MEM_freeN(gps->points);
1531                                                 }
1532                                                 if (gps->dvert) {
1533                                                         BKE_gpencil_free_stroke_weights(gps);
1534                                                         MEM_freeN(gps->dvert);
1535                                                 }
1536                                                 if (gps->triangles) MEM_freeN(gps->triangles);
1537                                                 BLI_freelinkN(&gpf->strokes, gps);
1538                                         }
1539                                         else {
1540                                                 /* reassign strokes */
1541                                                 if (gps->mat_nr > index) {
1542                                                         gps->mat_nr--;
1543                                                 }
1544                                         }
1545                                 }
1546                         }
1547                 }
1548 }
1549
1550 void BKE_gpencil_material_remap(struct bGPdata *gpd, const unsigned int *remap, unsigned int remap_len)
1551 {
1552         const short remap_len_short = (short)remap_len;
1553
1554 #define MAT_NR_REMAP(n) \
1555         if (n < remap_len_short) { \
1556                 BLI_assert(n >= 0 && remap[n] < remap_len_short); \
1557                 n = remap[n]; \
1558         } ((void)0)
1559
1560         for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
1561                 for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) {
1562                         for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
1563                                 /* reassign strokes */
1564                                 MAT_NR_REMAP(gps->mat_nr);
1565                         }
1566                 }
1567         }
1568
1569 #undef MAT_NR_REMAP
1570
1571 }
1572
1573 /* statistics functions */
1574 void BKE_gpencil_stats_update(bGPdata *gpd)
1575 {
1576         gpd->totlayer = 0;
1577         gpd->totframe = 0;
1578         gpd->totstroke = 0;
1579         gpd->totpoint = 0;
1580
1581         for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
1582                 gpd->totlayer++;
1583                 for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) {
1584                         gpd->totframe++;
1585                         for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
1586                                 gpd->totstroke++;
1587                                 gpd->totpoint += gps->totpoints;
1588                         }
1589                 }
1590         }
1591
1592 }
1593
1594 /* get material index */
1595 int BKE_gpencil_get_material_index(Object *ob, Material *ma)
1596 {
1597         short *totcol = give_totcolp(ob);
1598         Material *read_ma = NULL;
1599         for (short i = 0; i < *totcol; i++) {
1600                 read_ma = give_current_material(ob, i + 1);
1601                 if (ma == read_ma) {
1602                         return i + 1;
1603                 }
1604         }
1605
1606         return 0;
1607 }