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