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