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