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