GP: Remove duplicate code moving to single function
[blender.git] / source / blender / draw / engines / gpencil / gpencil_draw_utils.c
1 /*
2  * Copyright 2017, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Antonio Vazquez
19  *
20  */
21
22 /** \file blender/draw/engines/gpencil/gpencil_draw_utils.c
23  *  \ingroup draw
24  */
25
26 #include "BLI_polyfill_2d.h"
27
28 #include "DRW_engine.h"
29 #include "DRW_render.h"
30
31 #include "BKE_brush.h"
32 #include "BKE_gpencil.h"
33 #include "BKE_gpencil_modifier.h"
34 #include "BKE_image.h"
35 #include "BKE_material.h"
36 #include "BKE_paint.h"
37
38 #include "ED_gpencil.h"
39 #include "ED_view3d.h"
40
41 #include "DNA_gpencil_types.h"
42 #include "DNA_material_types.h"
43 #include "DNA_view3d_types.h"
44 #include "DNA_gpencil_modifier_types.h"
45
46 /* If builtin shaders are needed */
47 #include "GPU_shader.h"
48 #include "GPU_texture.h"
49
50 /* For EvaluationContext... */
51 #include "DEG_depsgraph.h"
52 #include "DEG_depsgraph_query.h"
53
54 #include "IMB_imbuf_types.h"
55
56 #include "gpencil_engine.h"
57
58 /* fill type to communicate to shader */
59 #define SOLID 0
60 #define GRADIENT 1
61 #define RADIAL 2
62 #define CHESS 3
63 #define TEXTURE 4
64 #define PATTERN 5
65
66 #define GP_SET_SRC_GPS(src_gps) if (src_gps) src_gps = src_gps->next
67
68 /* Get number of vertex for using in GPU VBOs */
69 static void gpencil_calc_vertex(
70         GPENCIL_StorageList *stl, tGPencilObjectCache *cache_ob,
71         GpencilBatchCache *cache, bGPdata *gpd,
72         int cfra_eval)
73 {
74         Object *ob = cache_ob->ob;
75         const DRWContextState *draw_ctx = DRW_context_state_get();
76         const bool main_onion = draw_ctx->v3d != NULL ? (draw_ctx->v3d->gp_flag & V3D_GP_SHOW_ONION_SKIN) : true;
77         const bool do_onion = (bool)((gpd->flag & GP_DATA_STROKE_WEIGHTMODE) == 0) &&
78                 main_onion && DRW_gpencil_onion_active(gpd);
79
80         const bool time_remap = BKE_gpencil_has_time_modifiers(ob);
81
82         cache_ob->tot_vertex = 0;
83         cache_ob->tot_triangles = 0;
84
85         for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
86                 bGPDframe *init_gpf = NULL;
87                 const bool is_onion = ((do_onion) && (gpl->onion_flag & GP_LAYER_ONIONSKIN));
88                 if (gpl->flag & GP_LAYER_HIDE) {
89                         continue;
90                 }
91
92                 /* if onion skin need to count all frames of the layer */
93                 if (is_onion) {
94                         init_gpf = gpl->actframe;
95                 }
96                 else {
97                         /* verify time modifiers */
98                         if ((time_remap) && (!stl->storage->simplify_modif)) {
99                                 int remap_cfra = BKE_gpencil_time_modifier(
100                                         draw_ctx->depsgraph, draw_ctx->scene, ob, gpl, cfra_eval,
101                                         stl->storage->is_render);
102                                 init_gpf = BKE_gpencil_layer_getframe(gpl, remap_cfra, GP_GETFRAME_USE_PREV);
103                         }
104                         else {
105                                 init_gpf = gpl->actframe;
106                         }
107                 }
108
109                 if (init_gpf == NULL) {
110                         continue;
111                 }
112
113                 for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
114                         for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
115                                 cache_ob->tot_vertex += gps->totpoints + 3;
116                                 cache_ob->tot_triangles += gps->totpoints - 1;
117                         }
118                         if (!is_onion) {
119                                 break;
120                         }
121                 }
122         }
123
124         cache->b_fill.tot_vertex = cache_ob->tot_triangles * 3;
125         cache->b_stroke.tot_vertex = cache_ob->tot_vertex;
126         cache->b_point.tot_vertex = cache_ob->tot_vertex;
127
128         /* some modifiers can change the number of points */
129         int factor = 0;
130         GpencilModifierData *md;
131         for (md = ob->greasepencil_modifiers.first; md; md = md->next) {
132                 const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type);
133                 /* only modifiers that change size */
134                 if (mti && mti->getDuplicationFactor) {
135                         factor = mti->getDuplicationFactor(md);
136
137                         cache->b_fill.tot_vertex *= factor;
138                         cache->b_stroke.tot_vertex *= factor;
139                         cache->b_point.tot_vertex *= factor;
140                 }
141         }
142 }
143
144 /* Helper for doing all the checks on whether a stroke can be drawn */
145 static bool gpencil_can_draw_stroke(
146         struct MaterialGPencilStyle *gp_style, const bGPDstroke *gps,
147         const bool onion, const bool is_mat_preview)
148 {
149         /* skip stroke if it doesn't have any valid data */
150         if ((gps->points == NULL) || (gps->totpoints < 1) || (gp_style == NULL))
151                 return false;
152
153         /* if mat preview render always visible */
154         if (is_mat_preview) {
155                 return true;
156         }
157
158         /* check if the color is visible */
159         if ((gp_style == NULL) ||
160             (gp_style->flag & GP_STYLE_COLOR_HIDE) ||
161             (onion && (gp_style->flag & GP_STYLE_COLOR_ONIONSKIN)))
162         {
163                 return false;
164         }
165
166         /* stroke can be drawn */
167         return true;
168 }
169
170 /* calc bounding box in 2d using flat projection data */
171 static void gpencil_calc_2d_bounding_box(
172         const float(*points2d)[2], int totpoints, float minv[2], float maxv[2])
173 {
174         minv[0] = points2d[0][0];
175         minv[1] = points2d[0][1];
176         maxv[0] = points2d[0][0];
177         maxv[1] = points2d[0][1];
178
179         for (int i = 1; i < totpoints; i++) {
180                 /* min */
181                 if (points2d[i][0] < minv[0]) {
182                         minv[0] = points2d[i][0];
183                 }
184                 if (points2d[i][1] < minv[1]) {
185                         minv[1] = points2d[i][1];
186                 }
187                 /* max */
188                 if (points2d[i][0] > maxv[0]) {
189                         maxv[0] = points2d[i][0];
190                 }
191                 if (points2d[i][1] > maxv[1]) {
192                         maxv[1] = points2d[i][1];
193                 }
194         }
195         /* use a perfect square */
196         if (maxv[0] > maxv[1]) {
197                 maxv[1] = maxv[0];
198         }
199         else {
200                 maxv[0] = maxv[1];
201         }
202 }
203
204 /* calc texture coordinates using flat projected points */
205 static void gpencil_calc_stroke_fill_uv(
206         const float(*points2d)[2], int totpoints, float minv[2], float maxv[2], float(*r_uv)[2])
207 {
208         float d[2];
209         d[0] = maxv[0] - minv[0];
210         d[1] = maxv[1] - minv[1];
211         for (int i = 0; i < totpoints; i++) {
212                 r_uv[i][0] = (points2d[i][0] - minv[0]) / d[0];
213                 r_uv[i][1] = (points2d[i][1] - minv[1]) / d[1];
214         }
215 }
216
217 /* recalc the internal geometry caches for fill and uvs */
218 static void DRW_gpencil_recalc_geometry_caches(
219         Object *ob, bGPDlayer *gpl, MaterialGPencilStyle *gp_style, bGPDstroke *gps)
220 {
221         if (gps->flag & GP_STROKE_RECALC_CACHES) {
222                 /* Calculate triangles cache for filling area (must be done only after changes) */
223                 if ((gps->tot_triangles == 0) || (gps->triangles == NULL)) {
224                         if ((gps->totpoints > 2) &&
225                             ((gp_style->fill_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH) ||
226                              (gp_style->fill_style > 0) || (gpl->blend_mode != eGplBlendMode_Normal)))
227                         {
228                                 DRW_gpencil_triangulate_stroke_fill(ob, gps);
229                         }
230                 }
231
232                 /* calc uv data along the stroke */
233                 ED_gpencil_calc_stroke_uv(ob, gps);
234
235                 /* clear flag */
236                 gps->flag &= ~GP_STROKE_RECALC_CACHES;
237         }
238 }
239
240 /* create shading group for filling */
241 static DRWShadingGroup *DRW_gpencil_shgroup_fill_create(
242         GPENCIL_e_data *e_data, GPENCIL_Data *vedata, DRWPass *pass,
243         GPUShader *shader, bGPdata *gpd, bGPDlayer *gpl,
244         MaterialGPencilStyle *gp_style, int id)
245 {
246         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
247
248         /* e_data.gpencil_fill_sh */
249         DRWShadingGroup *grp = DRW_shgroup_create(shader, pass);
250
251         DRW_shgroup_uniform_vec4(grp, "color2", gp_style->mix_rgba, 1);
252
253         /* set style type */
254         switch (gp_style->fill_style) {
255                 case GP_STYLE_FILL_STYLE_SOLID:
256                         stl->shgroups[id].fill_style = SOLID;
257                         break;
258                 case GP_STYLE_FILL_STYLE_GRADIENT:
259                         if (gp_style->gradient_type == GP_STYLE_GRADIENT_LINEAR) {
260                                 stl->shgroups[id].fill_style = GRADIENT;
261                         }
262                         else {
263                                 stl->shgroups[id].fill_style = RADIAL;
264                         }
265                         break;
266                 case GP_STYLE_FILL_STYLE_CHESSBOARD:
267                         stl->shgroups[id].fill_style = CHESS;
268                         break;
269                 case GP_STYLE_FILL_STYLE_TEXTURE:
270                         if (gp_style->flag & GP_STYLE_FILL_PATTERN) {
271                                 stl->shgroups[id].fill_style = PATTERN;
272                         }
273                         else {
274                                 stl->shgroups[id].fill_style = TEXTURE;
275                         }
276                         break;
277                 default:
278                         stl->shgroups[id].fill_style = GP_STYLE_FILL_STYLE_SOLID;
279                         break;
280         }
281         DRW_shgroup_uniform_int(grp, "fill_type", &stl->shgroups[id].fill_style, 1);
282
283         DRW_shgroup_uniform_float(grp, "mix_factor", &gp_style->mix_factor, 1);
284
285         DRW_shgroup_uniform_float(grp, "gradient_angle", &gp_style->gradient_angle, 1);
286         DRW_shgroup_uniform_float(grp, "gradient_radius", &gp_style->gradient_radius, 1);
287         DRW_shgroup_uniform_float(grp, "pattern_gridsize", &gp_style->pattern_gridsize, 1);
288         DRW_shgroup_uniform_vec2(grp, "gradient_scale", gp_style->gradient_scale, 1);
289         DRW_shgroup_uniform_vec2(grp, "gradient_shift", gp_style->gradient_shift, 1);
290
291         DRW_shgroup_uniform_float(grp, "texture_angle", &gp_style->texture_angle, 1);
292         DRW_shgroup_uniform_vec2(grp, "texture_scale", gp_style->texture_scale, 1);
293         DRW_shgroup_uniform_vec2(grp, "texture_offset", gp_style->texture_offset, 1);
294         DRW_shgroup_uniform_float(grp, "texture_opacity", &gp_style->texture_opacity, 1);
295         DRW_shgroup_uniform_float(grp, "layer_opacity", &gpl->opacity, 1);
296
297         stl->shgroups[id].texture_mix = gp_style->flag & GP_STYLE_COLOR_TEX_MIX ? 1 : 0;
298         DRW_shgroup_uniform_int(grp, "texture_mix", &stl->shgroups[id].texture_mix, 1);
299
300         stl->shgroups[id].texture_flip = gp_style->flag & GP_STYLE_COLOR_FLIP_FILL ? 1 : 0;
301         DRW_shgroup_uniform_int(grp, "texture_flip", &stl->shgroups[id].texture_flip, 1);
302
303         DRW_shgroup_uniform_int(grp, "xraymode", (const int *) &gpd->xray_mode, 1);
304         /* image texture */
305         if ((gp_style->flag & GP_STYLE_COLOR_TEX_MIX) ||
306             (gp_style->fill_style & GP_STYLE_FILL_STYLE_TEXTURE))
307         {
308                 ImBuf *ibuf;
309                 Image *image = gp_style->ima;
310                 ImageUser iuser = { NULL };
311                 void *lock;
312
313                 iuser.ok = true;
314
315                 ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
316
317                 if (ibuf == NULL || ibuf->rect == NULL) {
318                         BKE_image_release_ibuf(image, ibuf, NULL);
319                 }
320                 else {
321                         GPUTexture *texture = GPU_texture_from_blender(gp_style->ima, &iuser, GL_TEXTURE_2D, true, 0.0);
322                         DRW_shgroup_uniform_texture(grp, "myTexture", texture);
323
324                         stl->shgroups[id].texture_clamp = gp_style->flag & GP_STYLE_COLOR_TEX_CLAMP ? 1 : 0;
325                         DRW_shgroup_uniform_int(grp, "texture_clamp", &stl->shgroups[id].texture_clamp, 1);
326
327                         BKE_image_release_ibuf(image, ibuf, NULL);
328                 }
329         }
330         else {
331                 /* if no texture defined, need a blank texture to avoid errors in draw manager */
332                 DRW_shgroup_uniform_texture(grp, "myTexture", e_data->gpencil_blank_texture);
333                 stl->shgroups[id].texture_clamp = 0;
334                 DRW_shgroup_uniform_int(grp, "texture_clamp", &stl->shgroups[id].texture_clamp, 1);
335         }
336
337         return grp;
338 }
339
340 /* check if some onion is enabled */
341 bool DRW_gpencil_onion_active(bGPdata *gpd)
342 {
343         for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
344                 if (gpl->onion_flag & GP_LAYER_ONIONSKIN) {
345                         return true;
346                 }
347         }
348         return false;
349 }
350
351 /* create shading group for strokes */
352 DRWShadingGroup *DRW_gpencil_shgroup_stroke_create(
353         GPENCIL_e_data *e_data, GPENCIL_Data *vedata, DRWPass *pass, GPUShader *shader, Object *ob,
354         bGPdata *gpd, MaterialGPencilStyle *gp_style, int id, bool onion)
355 {
356         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
357         const float *viewport_size = DRW_viewport_size_get();
358
359         /* e_data.gpencil_stroke_sh */
360         DRWShadingGroup *grp = DRW_shgroup_create(shader, pass);
361
362         DRW_shgroup_uniform_vec2(grp, "Viewport", viewport_size, 1);
363
364         DRW_shgroup_uniform_float(grp, "pixsize", stl->storage->pixsize, 1);
365
366         /* avoid wrong values */
367         if ((gpd) && (gpd->pixfactor == 0)) {
368                 gpd->pixfactor = GP_DEFAULT_PIX_FACTOR;
369         }
370
371         /* object scale and depth */
372         if ((ob) && (id > -1)) {
373                 stl->shgroups[id].obj_scale = mat4_to_scale(ob->obmat);
374                 DRW_shgroup_uniform_float(grp, "objscale", &stl->shgroups[id].obj_scale, 1);
375                 stl->shgroups[id].keep_size = (int)((gpd) && (gpd->flag & GP_DATA_STROKE_KEEPTHICKNESS));
376                 DRW_shgroup_uniform_int(grp, "keep_size", &stl->shgroups[id].keep_size, 1);
377
378                 stl->shgroups[id].stroke_style = gp_style->stroke_style;
379                 stl->shgroups[id].color_type = GPENCIL_COLOR_SOLID;
380                 if ((gp_style->stroke_style == GP_STYLE_STROKE_STYLE_TEXTURE) && (!onion)) {
381                         stl->shgroups[id].color_type = GPENCIL_COLOR_TEXTURE;
382                         if (gp_style->flag & GP_STYLE_STROKE_PATTERN) {
383                                 stl->shgroups[id].color_type = GPENCIL_COLOR_PATTERN;
384                         }
385                 }
386                 DRW_shgroup_uniform_int(grp, "color_type", &stl->shgroups[id].color_type, 1);
387                 DRW_shgroup_uniform_float(grp, "pixfactor", &gpd->pixfactor, 1);
388         }
389         else {
390                 stl->storage->obj_scale = 1.0f;
391                 stl->storage->keep_size = 0;
392                 stl->storage->pixfactor = GP_DEFAULT_PIX_FACTOR;
393                 DRW_shgroup_uniform_float(grp, "objscale", &stl->storage->obj_scale, 1);
394                 DRW_shgroup_uniform_int(grp, "keep_size", &stl->storage->keep_size, 1);
395                 DRW_shgroup_uniform_int(grp, "color_type", &stl->storage->color_type, 1);
396                 if (gpd) {
397                         DRW_shgroup_uniform_float(grp, "pixfactor", &gpd->pixfactor, 1);
398                 }
399                 else {
400                         DRW_shgroup_uniform_float(grp, "pixfactor", &stl->storage->pixfactor, 1);
401                 }
402         }
403
404         if ((gpd) && (id > -1)) {
405                 DRW_shgroup_uniform_int(grp, "xraymode", (const int *) &gpd->xray_mode, 1);
406         }
407         else {
408                 /* for drawing always on predefined z-depth */
409                 DRW_shgroup_uniform_int(grp, "xraymode", &stl->storage->xray, 1);
410         }
411
412         /* image texture for pattern */
413         if ((gp_style) && (gp_style->stroke_style == GP_STYLE_STROKE_STYLE_TEXTURE) && (!onion)) {
414                 ImBuf *ibuf;
415                 Image *image = gp_style->sima;
416                 ImageUser iuser = { NULL };
417                 void *lock;
418
419                 iuser.ok = true;
420
421                 ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
422
423                 if (ibuf == NULL || ibuf->rect == NULL) {
424                         BKE_image_release_ibuf(image, ibuf, NULL);
425                 }
426                 else {
427                         GPUTexture *texture = GPU_texture_from_blender(gp_style->sima, &iuser, GL_TEXTURE_2D, true, 0.0f);
428                         DRW_shgroup_uniform_texture(grp, "myTexture", texture);
429
430                         BKE_image_release_ibuf(image, ibuf, NULL);
431                 }
432         }
433         else {
434                 /* if no texture defined, need a blank texture to avoid errors in draw manager */
435                 DRW_shgroup_uniform_texture(grp, "myTexture", e_data->gpencil_blank_texture);
436         }
437
438         return grp;
439 }
440
441 /* create shading group for points */
442 static DRWShadingGroup *DRW_gpencil_shgroup_point_create(
443         GPENCIL_e_data *e_data, GPENCIL_Data *vedata, DRWPass *pass, GPUShader *shader, Object *ob,
444         bGPdata *gpd, MaterialGPencilStyle *gp_style, int id, bool onion)
445 {
446         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
447         const float *viewport_size = DRW_viewport_size_get();
448
449         /* e_data.gpencil_stroke_sh */
450         DRWShadingGroup *grp = DRW_shgroup_create(shader, pass);
451
452         DRW_shgroup_uniform_vec2(grp, "Viewport", viewport_size, 1);
453         DRW_shgroup_uniform_float(grp, "pixsize", stl->storage->pixsize, 1);
454
455         /* avoid wrong values */
456         if ((gpd) && (gpd->pixfactor == 0)) {
457                 gpd->pixfactor = GP_DEFAULT_PIX_FACTOR;
458         }
459
460         /* object scale and depth */
461         if ((ob) && (id > -1)) {
462                 stl->shgroups[id].obj_scale = mat4_to_scale(ob->obmat);
463                 DRW_shgroup_uniform_float(grp, "objscale", &stl->shgroups[id].obj_scale, 1);
464                 stl->shgroups[id].keep_size = (int)((gpd) && (gpd->flag & GP_DATA_STROKE_KEEPTHICKNESS));
465                 DRW_shgroup_uniform_int(grp, "keep_size", &stl->shgroups[id].keep_size, 1);
466
467                 stl->shgroups[id].mode = gp_style->mode;
468                 stl->shgroups[id].stroke_style = gp_style->stroke_style;
469                 stl->shgroups[id].color_type = GPENCIL_COLOR_SOLID;
470                 if ((gp_style->stroke_style == GP_STYLE_STROKE_STYLE_TEXTURE) && (!onion)) {
471                         stl->shgroups[id].color_type = GPENCIL_COLOR_TEXTURE;
472                         if (gp_style->flag & GP_STYLE_STROKE_PATTERN) {
473                                 stl->shgroups[id].color_type = GPENCIL_COLOR_PATTERN;
474                         }
475                 }
476                 DRW_shgroup_uniform_int(grp, "color_type", &stl->shgroups[id].color_type, 1);
477                 DRW_shgroup_uniform_int(grp, "mode", &stl->shgroups[id].mode, 1);
478                 DRW_shgroup_uniform_float(grp, "pixfactor", &gpd->pixfactor, 1);
479         }
480         else {
481                 stl->storage->obj_scale = 1.0f;
482                 stl->storage->keep_size = 0;
483                 stl->storage->pixfactor = GP_DEFAULT_PIX_FACTOR;
484                 stl->storage->mode = gp_style->mode;
485                 DRW_shgroup_uniform_float(grp, "objscale", &stl->storage->obj_scale, 1);
486                 DRW_shgroup_uniform_int(grp, "keep_size", &stl->storage->keep_size, 1);
487                 DRW_shgroup_uniform_int(grp, "color_type", &stl->storage->color_type, 1);
488                 DRW_shgroup_uniform_int(grp, "mode", &stl->storage->mode, 1);
489                 if (gpd) {
490                         DRW_shgroup_uniform_float(grp, "pixfactor", &gpd->pixfactor, 1);
491                 }
492                 else {
493                         DRW_shgroup_uniform_float(grp, "pixfactor", &stl->storage->pixfactor, 1);
494                 }
495         }
496
497         if (gpd) {
498                 DRW_shgroup_uniform_int(grp, "xraymode", (const int *)&gpd->xray_mode, 1);
499         }
500         else {
501                 /* for drawing always on on predefined z-depth */
502                 DRW_shgroup_uniform_int(grp, "xraymode", &stl->storage->xray, 1);
503         }
504
505         /* image texture */
506         if ((gp_style) && (gp_style->stroke_style == GP_STYLE_STROKE_STYLE_TEXTURE) && (!onion)) {
507                 ImBuf *ibuf;
508                 Image *image = gp_style->sima;
509                 ImageUser iuser = { NULL };
510                 void *lock;
511
512                 iuser.ok = true;
513
514                 ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
515
516                 if (ibuf == NULL || ibuf->rect == NULL) {
517                         BKE_image_release_ibuf(image, ibuf, NULL);
518                 }
519                 else {
520                         GPUTexture *texture = GPU_texture_from_blender(gp_style->sima, &iuser, GL_TEXTURE_2D, true, 0.0f);
521                         DRW_shgroup_uniform_texture(grp, "myTexture", texture);
522
523                         BKE_image_release_ibuf(image, ibuf, NULL);
524                 }
525         }
526         else {
527                 /* if no texture defined, need a blank texture to avoid errors in draw manager */
528                 DRW_shgroup_uniform_texture(grp, "myTexture", e_data->gpencil_blank_texture);
529         }
530
531         return grp;
532 }
533
534 /* add fill vertex info  */
535 static void gpencil_add_fill_vertexdata(
536         GpencilBatchCache *cache,
537         Object *ob, bGPDlayer *gpl, bGPDframe *gpf, bGPDstroke *gps,
538         float opacity, const float tintcolor[4], const bool onion, const bool custonion)
539 {
540         MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1);
541         if (gps->totpoints >= 3) {
542                 float tfill[4];
543                 /* set color using material, tint color and opacity */
544                 interp_v3_v3v3(tfill, gps->runtime.tmp_fill_rgba, tintcolor, tintcolor[3]);
545                 tfill[3] = gps->runtime.tmp_fill_rgba[3] * opacity;
546                 if ((tfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) ||
547                     (gp_style->fill_style > 0) ||
548                     (gpl->blend_mode != eGplBlendMode_Normal))
549                 {
550                         if (cache->is_dirty) {
551                                 const float *color;
552                                 if (!onion) {
553                                         color = tfill;
554                                 }
555                                 else {
556                                         if (custonion) {
557                                                 color = tintcolor;
558                                         }
559                                         else {
560                                                 ARRAY_SET_ITEMS(tfill, UNPACK3(gps->runtime.tmp_fill_rgba), tintcolor[3]);
561                                                 color = tfill;
562                                         }
563                                 }
564                                 /* create vertex data */
565                                 const int old_len = cache->b_fill.vbo_len;
566                                 DRW_gpencil_get_fill_geom(&cache->b_fill, ob, gps, color);
567
568                                 /* add to list of groups */
569                                 if (old_len < cache->b_fill.vbo_len) {
570                                         cache->grp_cache = gpencil_group_cache_add(
571                                                 cache->grp_cache, gpl, gpf, gps,
572                                                 eGpencilBatchGroupType_Fill, onion,
573                                                 cache->b_fill.vbo_len,
574                                                 &cache->grp_size, &cache->grp_used);
575                                 }
576                         }
577                 }
578         }
579 }
580
581 /* add stroke vertex info */
582 static void gpencil_add_stroke_vertexdata(
583         GpencilBatchCache *cache,
584         Object *ob, bGPDlayer *gpl, bGPDframe *gpf, bGPDstroke *gps,
585         const float opacity, const float tintcolor[4], const bool onion,
586         const bool custonion)
587 {
588         float tcolor[4];
589         float ink[4];
590         short sthickness;
591         MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1);
592
593         /* set color using base color, tint color and opacity */
594         if (cache->is_dirty) {
595                 if (!onion) {
596                         /* if special stroke, use fill color as stroke color */
597                         if (gps->flag & GP_STROKE_NOFILL) {
598                                 interp_v3_v3v3(tcolor, gps->runtime.tmp_fill_rgba, tintcolor, tintcolor[3]);
599                                 tcolor[3] = gps->runtime.tmp_fill_rgba[3] * opacity;
600                         }
601                         else {
602                                 interp_v3_v3v3(tcolor, gps->runtime.tmp_stroke_rgba, tintcolor, tintcolor[3]);
603                                 tcolor[3] = gps->runtime.tmp_stroke_rgba[3] * opacity;
604                         }
605                         copy_v4_v4(ink, tcolor);
606                 }
607                 else {
608                         if (custonion) {
609                                 copy_v4_v4(ink, tintcolor);
610                         }
611                         else {
612                                 ARRAY_SET_ITEMS(tcolor, UNPACK3(gps->runtime.tmp_stroke_rgba), opacity);
613                                 copy_v4_v4(ink, tcolor);
614                         }
615                 }
616
617                 sthickness = gps->thickness + gpl->line_change;
618                 CLAMP_MIN(sthickness, 1);
619
620                 if ((gps->totpoints > 1) && (gp_style->mode == GP_STYLE_MODE_LINE)) {
621                         /* create vertex data */
622                         const int old_len = cache->b_stroke.vbo_len;
623                         DRW_gpencil_get_stroke_geom(&cache->b_stroke, gps, sthickness, ink);
624
625                         /* add to list of groups */
626                         if (old_len < cache->b_stroke.vbo_len) {
627                                 cache->grp_cache = gpencil_group_cache_add(
628                                         cache->grp_cache, gpl, gpf, gps,
629                                         eGpencilBatchGroupType_Stroke, onion,
630                                         cache->b_stroke.vbo_len,
631                                         &cache->grp_size, &cache->grp_used);
632                         }
633                 }
634                 else {
635                         /* create vertex data */
636                         const int old_len = cache->b_point.vbo_len;
637                         DRW_gpencil_get_point_geom(&cache->b_point, gps, sthickness, ink);
638
639                         /* add to list of groups */
640                         if (old_len < cache->b_point.vbo_len) {
641                                 cache->grp_cache = gpencil_group_cache_add(
642                                         cache->grp_cache, gpl, gpf, gps, eGpencilBatchGroupType_Point, onion,
643                                         cache->b_point.vbo_len,
644                                         &cache->grp_size, &cache->grp_used);
645                         }
646                 }
647         }
648 }
649
650 /* add edit points vertex info */
651 static void gpencil_add_editpoints_vertexdata(
652         GPENCIL_StorageList *UNUSED(stl), GpencilBatchCache *cache, ToolSettings *UNUSED(ts), Object *ob,
653         bGPdata *gpd, bGPDlayer *gpl, bGPDframe *gpf, bGPDstroke *gps)
654 {
655         const DRWContextState *draw_ctx = DRW_context_state_get();
656         View3D *v3d = draw_ctx->v3d;
657         MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1);
658
659         /* alpha factor for edit points/line to make them more subtle */
660         float edit_alpha = v3d->vertex_opacity;
661
662         if (GPENCIL_ANY_EDIT_MODE(gpd)) {
663                 Object *obact = DRW_context_state_get()->obact;
664                 if ((!obact) || (obact->type != OB_GPENCIL)) {
665                         return;
666                 }
667                 const bool is_weight_paint = (gpd) && (gpd->flag & GP_DATA_STROKE_WEIGHTMODE);
668
669                 if (cache->is_dirty) {
670                         if ((obact == ob) &&
671                             ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) &&
672                             (v3d->gp_flag & V3D_GP_SHOW_EDIT_LINES))
673                         {
674                                 /* line of the original stroke */
675                                 DRW_gpencil_get_edlin_geom(&cache->b_edlin, gps, edit_alpha, gpd->flag);
676
677                                 /* add to list of groups */
678                                 cache->grp_cache = gpencil_group_cache_add(
679                                         cache->grp_cache, gpl, gpf, gps,
680                                         eGpencilBatchGroupType_Edlin, false,
681                                         cache->b_edlin.vbo_len,
682                                         &cache->grp_size, &cache->grp_used);
683                         }
684                         /* edit points */
685                         if ((gps->flag & GP_STROKE_SELECT) || (is_weight_paint)) {
686                                 if ((gpl->flag & GP_LAYER_UNLOCK_COLOR) || ((gp_style->flag & GP_STYLE_COLOR_LOCKED) == 0)) {
687                                         if (obact == ob) {
688                                                 DRW_gpencil_get_edit_geom(&cache->b_edit, gps, edit_alpha, gpd->flag);
689
690                                                 /* add to list of groups */
691                                                 cache->grp_cache = gpencil_group_cache_add(
692                                                         cache->grp_cache, gpl, gpf, gps,
693                                                         eGpencilBatchGroupType_Edit, false,
694                                                         cache->b_edit.vbo_len,
695                                                         &cache->grp_size, &cache->grp_used);
696                                         }
697                                 }
698                         }
699                 }
700         }
701 }
702
703 /* main function to draw strokes */
704 static void gpencil_draw_strokes(
705         GpencilBatchCache *cache, GPENCIL_e_data *e_data, void *vedata, ToolSettings *ts, Object *ob,
706         bGPdata *gpd, bGPDlayer *gpl, bGPDframe *src_gpf, bGPDframe *derived_gpf,
707         const float opacity, const float tintcolor[4],
708         const bool custonion, tGPencilObjectCache *cache_ob)
709 {
710         GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
711         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
712         const DRWContextState *draw_ctx = DRW_context_state_get();
713         Scene *scene = draw_ctx->scene;
714         View3D *v3d = draw_ctx->v3d;
715         bGPDstroke *gps, *src_gps;
716         float viewmatrix[4][4];
717         const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
718         const bool playing = stl->storage->is_playing;
719         const bool is_render = (bool)stl->storage->is_render;
720         const bool is_mat_preview = (bool)stl->storage->is_mat_preview;
721         const bool overlay_multiedit = v3d != NULL ? (v3d->gp_flag & V3D_GP_SHOW_MULTIEDIT_LINES) : true;
722
723         /* Get evaluation context */
724         /* NOTE: We must check if C is valid, otherwise we get crashes when trying to save files
725          * (i.e. the thumbnail offscreen rendering fails)
726          */
727         Depsgraph *depsgraph = DRW_context_state_get()->depsgraph;
728
729         /* get parent matrix and save as static data */
730         ED_gpencil_parent_location(depsgraph, ob, gpd, gpl, viewmatrix);
731         copy_m4_m4(derived_gpf->runtime.viewmatrix, viewmatrix);
732
733         if ((cache_ob != NULL) && (cache_ob->is_dup_ob)) {
734                 copy_m4_m4(derived_gpf->runtime.viewmatrix, cache_ob->obmat);
735         }
736
737         /* apply geometry modifiers */
738         if ((cache->is_dirty) && (ob->greasepencil_modifiers.first) && (!is_multiedit)) {
739                 if (!stl->storage->simplify_modif) {
740                         if (BKE_gpencil_has_geometry_modifiers(ob)) {
741                                 BKE_gpencil_geometry_modifiers(depsgraph, ob, gpl, derived_gpf, stl->storage->is_render);
742                         }
743                 }
744         }
745
746         if (src_gpf) {
747                 src_gps = src_gpf->strokes.first;
748         }
749         else {
750                 src_gps = NULL;
751         }
752
753         for (gps = derived_gpf->strokes.first; gps; gps = gps->next) {
754                 MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1);
755
756                 /* check if stroke can be drawn */
757                 if (gpencil_can_draw_stroke(gp_style, gps, false, is_mat_preview) == false) {
758                         GP_SET_SRC_GPS(src_gps);
759                         continue;
760                 }
761
762                 /* be sure recalc all cache in source stroke to avoid recalculation when frame change
763                  * and improve fps */
764                 if (src_gps) {
765                         DRW_gpencil_recalc_geometry_caches(ob, gpl, gp_style, src_gps);
766                 }
767
768                 /* if the fill has any value, it's considered a fill and is not drawn if simplify fill is enabled */
769                 if ((stl->storage->simplify_fill) && (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_REMOVE_FILL_LINE)) {
770                         if ((gp_style->fill_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH) ||
771                             (gp_style->fill_style > GP_STYLE_FILL_STYLE_SOLID) ||
772                             (gpl->blend_mode != eGplBlendMode_Normal))
773                         {
774                                 GP_SET_SRC_GPS(src_gps);
775                                 continue;
776                         }
777                 }
778
779                 if ((gpl->actframe->framenum == derived_gpf->framenum) ||
780                     (!is_multiedit) || (overlay_multiedit))
781                 {
782                         /* copy color to temp fields to apply temporal changes in the stroke */
783                         copy_v4_v4(gps->runtime.tmp_stroke_rgba, gp_style->stroke_rgba);
784                         copy_v4_v4(gps->runtime.tmp_fill_rgba, gp_style->fill_rgba);
785
786                         /* apply modifiers (only modify geometry, but not create ) */
787                         if ((cache->is_dirty) && (ob->greasepencil_modifiers.first) && (!is_multiedit)) {
788                                 if (!stl->storage->simplify_modif) {
789                                         BKE_gpencil_stroke_modifiers(depsgraph, ob, gpl, derived_gpf, gps, stl->storage->is_render);
790                                 }
791                         }
792
793                         /* hide any blend layer */
794                         if ((!stl->storage->simplify_blend) ||
795                             (gpl->blend_mode == eGplBlendMode_Normal))
796                         {
797                                 /* fill */
798                                 if ((gp_style->flag & GP_STYLE_FILL_SHOW) &&
799                                     (!stl->storage->simplify_fill) &&
800                                     ((gps->flag & GP_STROKE_NOFILL) == 0))
801                                 {
802                                         gpencil_add_fill_vertexdata(
803                                                 cache, ob, gpl, derived_gpf, gps,
804                                                 opacity, tintcolor, false, custonion);
805                                 }
806                                 /* stroke */
807                                 if ((gp_style->flag & GP_STYLE_STROKE_SHOW) &&
808                                     ((gp_style->stroke_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH) ||
809                                      (gpl->blend_mode == eGplBlendMode_Normal)))
810                                 {
811                                         gpencil_add_stroke_vertexdata(
812                                                 cache, ob, gpl, derived_gpf, gps,
813                                                 opacity, tintcolor, false, custonion);
814                                 }
815                         }
816                 }
817
818                 /* edit points (only in edit mode and not play animation not render) */
819                 if ((draw_ctx->obact == ob) && (src_gps) &&
820                     (!playing) && (!is_render) && (!cache_ob->is_dup_ob))
821                 {
822                         if ((gpl->flag & GP_LAYER_LOCKED) == 0) {
823                                 if (!stl->g_data->shgrps_edit_line) {
824                                         stl->g_data->shgrps_edit_line = DRW_shgroup_create(e_data->gpencil_line_sh, psl->edit_pass);
825                                 }
826                                 if (!stl->g_data->shgrps_edit_point) {
827                                         stl->g_data->shgrps_edit_point = DRW_shgroup_create(e_data->gpencil_edit_point_sh, psl->edit_pass);
828                                         const float *viewport_size = DRW_viewport_size_get();
829                                         DRW_shgroup_uniform_vec2(stl->g_data->shgrps_edit_point, "Viewport", viewport_size, 1);
830                                 }
831
832                                 gpencil_add_editpoints_vertexdata(stl, cache, ts, ob, gpd, gpl, derived_gpf, src_gps);
833                         }
834                 }
835
836                 GP_SET_SRC_GPS(src_gps);
837         }
838 }
839
840 /* get alpha factor for onion strokes */
841 static void gpencil_get_onion_alpha(float color[4], bGPdata *gpd)
842 {
843 #define MIN_ALPHA_VALUE 0.01f
844
845         /* if fade is disabled, opacity is equal in all frames */
846         if ((gpd->onion_flag & GP_ONION_FADE) == 0) {
847                 color[3] = gpd->onion_factor;
848         }
849         else {
850                 /* add override opacity factor */
851                 color[3] += gpd->onion_factor - 0.5f;
852         }
853
854         CLAMP(color[3], MIN_ALPHA_VALUE, 1.0f);
855 }
856
857 /* function to draw strokes for onion only */
858 static void gpencil_draw_onion_strokes(
859         GpencilBatchCache *cache, GPENCIL_e_data *UNUSED(e_data), void *vedata, Object *ob,
860         bGPdata *gpd, bGPDlayer *gpl, bGPDframe *gpf,
861         const float opacity, const float tintcolor[4], const bool custonion)
862 {
863         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
864         Depsgraph *depsgraph = DRW_context_state_get()->depsgraph;
865
866         float viewmatrix[4][4];
867
868         /* get parent matrix and save as static data */
869         ED_gpencil_parent_location(depsgraph, ob, gpd, gpl, viewmatrix);
870         copy_m4_m4(gpf->runtime.viewmatrix, viewmatrix);
871
872         for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
873                 MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1);
874                 copy_v4_v4(gps->runtime.tmp_stroke_rgba, gp_style->stroke_rgba);
875                 copy_v4_v4(gps->runtime.tmp_fill_rgba, gp_style->fill_rgba);
876
877                 int id = stl->storage->shgroup_id;
878                 /* check if stroke can be drawn */
879                 if (gpencil_can_draw_stroke(gp_style, gps, true, false) == false) {
880                         continue;
881                 }
882                 /* limit the number of shading groups */
883                 if (id >= GPENCIL_MAX_SHGROUPS) {
884                         continue;
885                 }
886
887                 /* stroke */
888                 gpencil_add_stroke_vertexdata(
889                         cache, ob, gpl, gpf, gps, opacity, tintcolor, true, custonion);
890
891                 stl->storage->shgroup_id++;
892         }
893 }
894
895 /* draw onion-skinning for a layer */
896 static void gpencil_draw_onionskins(
897         GpencilBatchCache *cache, GPENCIL_e_data *e_data, void *vedata,
898         Object *ob, bGPdata *gpd, bGPDlayer *gpl, bGPDframe *gpf)
899 {
900
901         const float default_color[3] = { UNPACK3(U.gpencil_new_layer_col) };
902         const float alpha = 1.0f;
903         float color[4];
904         int idx;
905         float fac = 1.0f;
906         int step = 0;
907         int mode = 0;
908         bool colflag = false;
909         bGPDframe *gpf_loop = NULL;
910         int last = gpf->framenum;
911
912         colflag = (bool)gpd->onion_flag & GP_ONION_GHOST_PREVCOL;
913
914         /* -------------------------------
915          * 1) Draw Previous Frames First
916          * ------------------------------- */
917         step = gpd->gstep;
918         mode = gpd->onion_mode;
919
920         if (gpd->onion_flag & GP_ONION_GHOST_PREVCOL) {
921                 copy_v3_v3(color, gpd->gcolor_prev);
922         }
923         else {
924                 copy_v3_v3(color, default_color);
925         }
926
927         idx = 0;
928         for (bGPDframe *gf = gpf->prev; gf; gf = gf->prev) {
929                 /* only selected frames */
930                 if ((mode == GP_ONION_MODE_SELECTED) && ((gf->flag & GP_FRAME_SELECT) == 0)) {
931                         continue;
932                 }
933                 /* absolute range */
934                 if (mode == GP_ONION_MODE_ABSOLUTE) {
935                         if ((gpf->framenum - gf->framenum) > step) {
936                                 break;
937                         }
938                 }
939                 /* relative range */
940                 if (mode == GP_ONION_MODE_RELATIVE) {
941                         idx++;
942                         if (idx > step) {
943                                 break;
944                         }
945
946                 }
947                 /* alpha decreases with distance from curframe index */
948                 if (mode != GP_ONION_MODE_SELECTED) {
949                         if (mode == GP_ONION_MODE_ABSOLUTE) {
950                                 fac = 1.0f - ((float)(gpf->framenum - gf->framenum) / (float)(step + 1));
951                         }
952                         else {
953                                 fac = 1.0f - ((float)idx / (float)(step + 1));
954                         }
955                         color[3] = alpha * fac * 0.66f;
956                 }
957                 else {
958                         idx++;
959                         fac = alpha - ((1.1f - (1.0f / (float)idx)) * 0.66f);
960                         color[3] = fac;
961                 }
962
963                 /* if loop option, save the frame to use later */
964                 if ((mode != GP_ONION_MODE_ABSOLUTE) && (gpd->onion_flag & GP_ONION_LOOP)) {
965                         gpf_loop = gf;
966                 }
967
968                 gpencil_get_onion_alpha(color, gpd);
969                 gpencil_draw_onion_strokes(cache, e_data, vedata, ob, gpd, gpl, gf, color[3], color, colflag);
970         }
971         /* -------------------------------
972          * 2) Now draw next frames
973          * ------------------------------- */
974         step = gpd->gstep_next;
975         mode = gpd->onion_mode;
976
977         if (gpd->onion_flag & GP_ONION_GHOST_NEXTCOL) {
978                 copy_v3_v3(color, gpd->gcolor_next);
979         }
980         else {
981                 copy_v3_v3(color, default_color);
982         }
983
984         idx = 0;
985         for (bGPDframe *gf = gpf->next; gf; gf = gf->next) {
986                 /* only selected frames */
987                 if ((mode == GP_ONION_MODE_SELECTED) && ((gf->flag & GP_FRAME_SELECT) == 0)) {
988                         continue;
989                 }
990                 /* absolute range */
991                 if (mode == GP_ONION_MODE_ABSOLUTE) {
992                         if ((gf->framenum - gpf->framenum) > step) {
993                                 break;
994                         }
995                 }
996                 /* relative range */
997                 if (mode == GP_ONION_MODE_RELATIVE) {
998                         idx++;
999                         if (idx > step) {
1000                                 break;
1001                         }
1002
1003                 }
1004                 /* alpha decreases with distance from curframe index */
1005                 if (mode != GP_ONION_MODE_SELECTED) {
1006                         if (mode == GP_ONION_MODE_ABSOLUTE) {
1007                                 fac = 1.0f - ((float)(gf->framenum - gpf->framenum) / (float)(step + 1));
1008                         }
1009                         else {
1010                                 fac = 1.0f - ((float)idx / (float)(step + 1));
1011                         }
1012                         color[3] = alpha * fac * 0.66f;
1013                 }
1014                 else {
1015                         idx++;
1016                         fac = alpha - ((1.1f - (1.0f / (float)idx)) * 0.66f);
1017                         color[3] = fac;
1018                 }
1019
1020                 gpencil_get_onion_alpha(color, gpd);
1021                 gpencil_draw_onion_strokes(cache, e_data, vedata, ob, gpd, gpl, gf, color[3], color, colflag);
1022                 if (last < gf->framenum) {
1023                         last = gf->framenum;
1024                 }
1025         }
1026
1027         /* Draw first frame in blue for loop mode */
1028         if ((gpd->onion_flag & GP_ONION_LOOP) && (gpf_loop != NULL)) {
1029                 if ((last == gpf->framenum) || (gpf->next == NULL)) {
1030                         gpencil_get_onion_alpha(color, gpd);
1031                         gpencil_draw_onion_strokes(
1032                                 cache, e_data, vedata, ob, gpd, gpl,
1033                                 gpf_loop, color[3], color, colflag);
1034                 }
1035         }
1036 }
1037
1038 static void gpencil_copy_frame(bGPDframe *gpf, bGPDframe *derived_gpf)
1039 {
1040         derived_gpf->prev = gpf->prev;
1041         derived_gpf->next = gpf->next;
1042         derived_gpf->framenum = gpf->framenum;
1043         derived_gpf->flag = gpf->flag;
1044         derived_gpf->key_type = gpf->key_type;
1045         derived_gpf->runtime = gpf->runtime;
1046         copy_m4_m4(derived_gpf->runtime.viewmatrix, gpf->runtime.viewmatrix);
1047
1048         /* copy strokes */
1049         BLI_listbase_clear(&derived_gpf->strokes);
1050         for (bGPDstroke *gps_src = gpf->strokes.first; gps_src; gps_src = gps_src->next) {
1051                 /* make copy of source stroke */
1052                 bGPDstroke *gps_dst = BKE_gpencil_stroke_duplicate(gps_src);
1053                 BLI_addtail(&derived_gpf->strokes, gps_dst);
1054         }
1055 }
1056
1057 /* Triangulate stroke for high quality fill (this is done only if cache is null or stroke was modified) */
1058 void DRW_gpencil_triangulate_stroke_fill(Object *ob, bGPDstroke *gps)
1059 {
1060         BLI_assert(gps->totpoints >= 3);
1061
1062         bGPdata *gpd = (bGPdata *)ob->data;
1063
1064         /* allocate memory for temporary areas */
1065         gps->tot_triangles = gps->totpoints - 2;
1066         uint(*tmp_triangles)[3] = MEM_mallocN(sizeof(*tmp_triangles) * gps->tot_triangles, "GP Stroke temp triangulation");
1067         float(*points2d)[2] = MEM_mallocN(sizeof(*points2d) * gps->totpoints, "GP Stroke temp 2d points");
1068         float(*uv)[2] = MEM_mallocN(sizeof(*uv) * gps->totpoints, "GP Stroke temp 2d uv data");
1069
1070         int direction = 0;
1071
1072         /* convert to 2d and triangulate */
1073         BKE_gpencil_stroke_2d_flat(gps->points, gps->totpoints, points2d, &direction);
1074         BLI_polyfill_calc(points2d, (uint)gps->totpoints, direction, tmp_triangles);
1075
1076         /* calc texture coordinates automatically */
1077         float minv[2];
1078         float maxv[2];
1079         /* first needs bounding box data */
1080         if (gpd->flag & GP_DATA_UV_ADAPTIVE) {
1081                 gpencil_calc_2d_bounding_box(points2d, gps->totpoints, minv, maxv);
1082         }
1083         else {
1084                 ARRAY_SET_ITEMS(minv, -1.0f, -1.0f);
1085                 ARRAY_SET_ITEMS(maxv, 1.0f, 1.0f);
1086         }
1087
1088         /* calc uv data */
1089         gpencil_calc_stroke_fill_uv(points2d, gps->totpoints, minv, maxv, uv);
1090
1091         /* Number of triangles */
1092         gps->tot_triangles = gps->totpoints - 2;
1093         /* save triangulation data in stroke cache */
1094         if (gps->tot_triangles > 0) {
1095                 if (gps->triangles == NULL) {
1096                         gps->triangles = MEM_callocN(sizeof(*gps->triangles) * gps->tot_triangles, "GP Stroke triangulation");
1097                 }
1098                 else {
1099                         gps->triangles = MEM_recallocN(gps->triangles, sizeof(*gps->triangles) * gps->tot_triangles);
1100                 }
1101
1102                 for (int i = 0; i < gps->tot_triangles; i++) {
1103                         bGPDtriangle *stroke_triangle = &gps->triangles[i];
1104                         memcpy(gps->triangles[i].verts, tmp_triangles[i], sizeof(uint[3]));
1105                         /* copy texture coordinates */
1106                         copy_v2_v2(stroke_triangle->uv[0], uv[tmp_triangles[i][0]]);
1107                         copy_v2_v2(stroke_triangle->uv[1], uv[tmp_triangles[i][1]]);
1108                         copy_v2_v2(stroke_triangle->uv[2], uv[tmp_triangles[i][2]]);
1109                 }
1110         }
1111         else {
1112                 /* No triangles needed - Free anything allocated previously */
1113                 if (gps->triangles)
1114                         MEM_freeN(gps->triangles);
1115
1116                 gps->triangles = NULL;
1117         }
1118
1119         /* disable recalculation flag */
1120         if (gps->flag & GP_STROKE_RECALC_CACHES) {
1121                 gps->flag &= ~GP_STROKE_RECALC_CACHES;
1122         }
1123
1124         /* clear memory */
1125         MEM_SAFE_FREE(tmp_triangles);
1126         MEM_SAFE_FREE(points2d);
1127         MEM_SAFE_FREE(uv);
1128 }
1129
1130 /* draw stroke in drawing buffer */
1131 void DRW_gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data, void *vedata, ToolSettings *ts, Object *ob)
1132 {
1133         GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
1134         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
1135         const DRWContextState *draw_ctx = DRW_context_state_get();
1136         View3D *v3d = draw_ctx->v3d;
1137         const bool overlay = v3d != NULL ? (bool)((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) : true;
1138         Brush *brush = BKE_paint_brush(&ts->gp_paint->paint);
1139         bGPdata *gpd_eval = ob->data;
1140         /* need the original to avoid cow overhead while drawing */
1141         bGPdata *gpd = (bGPdata *)DEG_get_original_id(&gpd_eval->id);
1142
1143         MaterialGPencilStyle *gp_style = NULL;
1144
1145         float obscale = mat4_to_scale(ob->obmat);
1146
1147         /* use the brush material */
1148         Material *ma = BKE_gpencil_get_material_from_brush(brush);
1149         if (ma != NULL) {
1150                 gp_style = ma->gp_style;
1151         }
1152         /* this is not common, but avoid any special situations when brush could be without material */
1153         if (gp_style == NULL) {
1154                 gp_style = BKE_material_gpencil_settings_get(ob, ob->actcol);
1155         }
1156
1157         /* drawing strokes */
1158         /* Check if may need to draw the active stroke cache, only if this layer is the active layer
1159          * that is being edited. (Stroke buffer is currently stored in gp-data)
1160          */
1161         if (gpd->runtime.sbuffer_size > 0) {
1162                 if ((gpd->runtime.sbuffer_sflag & GP_STROKE_ERASER) == 0) {
1163                         /* It should also be noted that sbuffer contains temporary point types
1164                          * i.e. tGPspoints NOT bGPDspoints
1165                          */
1166                         short lthick = brush->size * obscale;
1167                         /* if only one point, don't need to draw buffer because the user has no time to see it */
1168                         if (gpd->runtime.sbuffer_size > 1) {
1169                                 if ((gp_style) && (gp_style->mode == GP_STYLE_MODE_LINE)) {
1170                                         stl->g_data->shgrps_drawing_stroke = DRW_gpencil_shgroup_stroke_create(
1171                                                 e_data, vedata, psl->drawing_pass, e_data->gpencil_stroke_sh, NULL, gpd, gp_style, -1, false);
1172                                 }
1173                                 else {
1174                                         stl->g_data->shgrps_drawing_stroke = DRW_gpencil_shgroup_point_create(
1175                                                 e_data, vedata, psl->drawing_pass, e_data->gpencil_point_sh, NULL, gpd, gp_style, -1, false);
1176                                 }
1177
1178                                 /* clean previous version of the batch */
1179                                 if (stl->storage->buffer_stroke) {
1180                                         GPU_BATCH_DISCARD_SAFE(e_data->batch_buffer_stroke);
1181                                         MEM_SAFE_FREE(e_data->batch_buffer_stroke);
1182                                         stl->storage->buffer_stroke = false;
1183                                 }
1184
1185                                 /* use unit matrix because the buffer is in screen space and does not need conversion */
1186                                 if (gpd->runtime.mode == GP_STYLE_MODE_LINE) {
1187                                         e_data->batch_buffer_stroke = DRW_gpencil_get_buffer_stroke_geom(
1188                                                 gpd, lthick);
1189                                 }
1190                                 else {
1191                                         e_data->batch_buffer_stroke = DRW_gpencil_get_buffer_point_geom(
1192                                                 gpd, lthick);
1193                                 }
1194
1195                                 if (gp_style->flag & GP_STYLE_STROKE_SHOW) {
1196                                         DRW_shgroup_call_add(
1197                                                 stl->g_data->shgrps_drawing_stroke,
1198                                                 e_data->batch_buffer_stroke,
1199                                                 stl->storage->unit_matrix);
1200                                 }
1201
1202                                 if ((gpd->runtime.sbuffer_size >= 3) &&
1203                                     (gpd->runtime.sfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) &&
1204                                     ((gpd->runtime.sbuffer_sflag & GP_STROKE_NOFILL) == 0) &&
1205                                     ((brush->gpencil_settings->flag & GP_BRUSH_DISSABLE_LASSO) == 0) &&
1206                                     (gp_style->flag & GP_STYLE_FILL_SHOW))
1207                                 {
1208                                         /* if not solid, fill is simulated with solid color */
1209                                         if (gpd->runtime.bfill_style > 0) {
1210                                                 gpd->runtime.sfill[3] = 0.5f;
1211                                         }
1212                                         stl->g_data->shgrps_drawing_fill = DRW_shgroup_create(
1213                                                 e_data->gpencil_drawing_fill_sh, psl->drawing_pass);
1214
1215                                         /* clean previous version of the batch */
1216                                         if (stl->storage->buffer_fill) {
1217                                                 GPU_BATCH_DISCARD_SAFE(e_data->batch_buffer_fill);
1218                                                 MEM_SAFE_FREE(e_data->batch_buffer_fill);
1219                                                 stl->storage->buffer_fill = false;
1220                                         }
1221
1222                                         e_data->batch_buffer_fill = DRW_gpencil_get_buffer_fill_geom(gpd);
1223                                         DRW_shgroup_call_add(
1224                                                 stl->g_data->shgrps_drawing_fill,
1225                                                 e_data->batch_buffer_fill,
1226                                                 stl->storage->unit_matrix);
1227                                         stl->storage->buffer_fill = true;
1228                                 }
1229                                 stl->storage->buffer_stroke = true;
1230                         }
1231                 }
1232         }
1233
1234         /* control points */
1235         if ((overlay) && (gpd->runtime.tot_cp_points > 0) &&
1236             ((gpd->runtime.sbuffer_sflag & GP_STROKE_ERASER) == 0) &&
1237             ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) &&
1238             ((v3d->gizmo_flag & V3D_GIZMO_HIDE_TOOL) == 0))
1239         {
1240
1241                 DRWShadingGroup *shgrp = DRW_shgroup_create(
1242                         e_data->gpencil_edit_point_sh, psl->drawing_pass);
1243                 const float *viewport_size = DRW_viewport_size_get();
1244                 DRW_shgroup_uniform_vec2(shgrp, "Viewport", viewport_size, 1);
1245
1246                 /* clean previous version of the batch */
1247                 if (stl->storage->buffer_ctrlpoint) {
1248                         GPU_BATCH_DISCARD_SAFE(e_data->batch_buffer_ctrlpoint);
1249                         MEM_SAFE_FREE(e_data->batch_buffer_ctrlpoint);
1250                         stl->storage->buffer_ctrlpoint = false;
1251                 }
1252
1253                 e_data->batch_buffer_ctrlpoint = DRW_gpencil_get_buffer_ctrlpoint_geom(gpd);
1254
1255                 DRW_shgroup_call_add(
1256                         shgrp,
1257                         e_data->batch_buffer_ctrlpoint,
1258                         stl->storage->unit_matrix);
1259
1260                 stl->storage->buffer_ctrlpoint = true;
1261         }
1262 }
1263
1264 /* create all missing batches */
1265 static void DRW_gpencil_create_batches(GpencilBatchCache *cache)
1266 {
1267         if ((cache->b_point.vbo) && (cache->b_point.batch == NULL)) {
1268                 cache->b_point.batch = GPU_batch_create_ex(GPU_PRIM_POINTS, cache->b_point.vbo, NULL, GPU_BATCH_OWNS_VBO);
1269         }
1270         if ((cache->b_stroke.vbo) && (cache->b_stroke.batch == NULL)) {
1271                 cache->b_stroke.batch = GPU_batch_create_ex(GPU_PRIM_LINE_STRIP_ADJ, cache->b_stroke.vbo, NULL, GPU_BATCH_OWNS_VBO);
1272         }
1273         if ((cache->b_fill.vbo) && (cache->b_fill.batch == NULL)) {
1274                 cache->b_fill.batch = GPU_batch_create_ex(GPU_PRIM_TRIS, cache->b_fill.vbo, NULL, GPU_BATCH_OWNS_VBO);
1275         }
1276         if ((cache->b_edit.vbo) && (cache->b_edit.batch == NULL)) {
1277                 cache->b_edit.batch = GPU_batch_create_ex(GPU_PRIM_POINTS, cache->b_edit.vbo, NULL, GPU_BATCH_OWNS_VBO);
1278         }
1279         if ((cache->b_edlin.vbo) && (cache->b_edlin.batch == NULL)) {
1280                 cache->b_edlin.batch = GPU_batch_create_ex(GPU_PRIM_LINE_STRIP, cache->b_edlin.vbo, NULL, GPU_BATCH_OWNS_VBO);
1281         }
1282 }
1283
1284 /* create all shading groups */
1285 static void DRW_gpencil_shgroups_create(
1286         GPENCIL_e_data *e_data, void *vedata,
1287         Object *ob,
1288         GpencilBatchCache *cache, tGPencilObjectCache *cache_ob)
1289 {
1290         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
1291         GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
1292         bGPdata *gpd = (bGPdata *)ob->data;
1293
1294         GpencilBatchGroup *elm = NULL;
1295         DRWShadingGroup *shgrp = NULL;
1296         tGPencilObjectCache_shgrp *array_elm = NULL;
1297
1298         bGPDlayer *gpl = NULL;
1299         bGPDlayer *gpl_prev = NULL;
1300         int idx = 0;
1301         bool tag_first = false;
1302
1303         int start_stroke = 0;
1304         int start_point = 0;
1305         int start_fill = 0;
1306         int start_edit = 0;
1307         int start_edlin = 0;
1308
1309         for (int i = 0; i < cache->grp_used; i++) {
1310                 elm = &cache->grp_cache[i];
1311                 array_elm = &cache_ob->shgrp_array[idx];
1312
1313                 /* save last group when change */
1314                 if (gpl_prev == NULL) {
1315                         gpl_prev = elm->gpl;
1316                         tag_first = true;
1317                 }
1318                 else {
1319                         if (elm->gpl != gpl_prev) {
1320                                 /* first layer is always blend Normal */
1321                                 array_elm->mode = idx == 0 ? eGplBlendMode_Normal: gpl->blend_mode;
1322                                 array_elm->end_shgrp = shgrp;
1323                                 gpl_prev = elm->gpl;
1324                                 tag_first = true;
1325                                 idx++;
1326                         }
1327                 }
1328
1329                 gpl = elm->gpl;
1330                 bGPDframe *gpf = elm->gpf;
1331                 bGPDstroke *gps = elm->gps;
1332                 MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1);
1333                 /* if the user switch used material from data to object,
1334                  * the material could not be available */
1335                 if (gp_style == NULL) {
1336                         break;
1337                 }
1338
1339                 /* limit the number of shading groups */
1340                 if (i >= GPENCIL_MAX_SHGROUPS) {
1341                         break;
1342                 }
1343
1344                 switch (elm->type) {
1345                         case eGpencilBatchGroupType_Stroke:
1346                         {
1347                                 const int len = elm->vertex_idx - start_stroke;
1348
1349                                 shgrp = DRW_gpencil_shgroup_stroke_create(
1350                                         e_data, vedata, psl->stroke_pass, e_data->gpencil_stroke_sh,
1351                                         ob, gpd, gp_style, stl->storage->shgroup_id, elm->onion);
1352
1353                                 DRW_shgroup_call_range_add(
1354                                         shgrp, cache->b_stroke.batch,
1355                                         (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix : cache_ob->obmat,
1356                                         start_stroke, len);
1357
1358                                 stl->storage->shgroup_id++;
1359                                 start_stroke = elm->vertex_idx;
1360                                 break;
1361                         }
1362                         case eGpencilBatchGroupType_Point:
1363                         {
1364                                 const int len = elm->vertex_idx - start_point;
1365
1366                                 shgrp = DRW_gpencil_shgroup_point_create(
1367                                         e_data, vedata, psl->stroke_pass, e_data->gpencil_point_sh,
1368                                         ob, gpd, gp_style, stl->storage->shgroup_id, elm->onion);
1369
1370                                 DRW_shgroup_call_range_add(
1371                                         shgrp, cache->b_point.batch,
1372                                         (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix : cache_ob->obmat,
1373                                         start_point, len);
1374
1375                                 stl->storage->shgroup_id++;
1376                                 start_point = elm->vertex_idx;
1377                                 break;
1378                         }
1379                         case eGpencilBatchGroupType_Fill:
1380                         {
1381                                 const int len = elm->vertex_idx - start_fill;
1382
1383                                 shgrp = DRW_gpencil_shgroup_fill_create(
1384                                         e_data, vedata, psl->stroke_pass, e_data->gpencil_fill_sh,
1385                                         gpd, gpl, gp_style, stl->storage->shgroup_id);
1386
1387                                 DRW_shgroup_call_range_add(
1388                                         shgrp, cache->b_fill.batch,
1389                                         (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix : cache_ob->obmat,
1390                                         start_fill, len);
1391
1392                                 stl->storage->shgroup_id++;
1393                                 start_fill = elm->vertex_idx;
1394                                 break;
1395                         }
1396                         case eGpencilBatchGroupType_Edit:
1397                         {
1398                                 if (stl->g_data->shgrps_edit_point) {
1399                                         const int len = elm->vertex_idx - start_edit;
1400                                         /* use always the same group */
1401                                         DRW_shgroup_call_range_add(
1402                                                 stl->g_data->shgrps_edit_point,
1403                                                 cache->b_edit.batch,
1404                                                 (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix : cache_ob->obmat,
1405                                                 start_edit, len);
1406
1407                                         start_edit = elm->vertex_idx;
1408                                 }
1409                                 break;
1410                         }
1411                         case eGpencilBatchGroupType_Edlin:
1412                         {
1413                                 if (stl->g_data->shgrps_edit_line) {
1414                                         const int len = elm->vertex_idx - start_edlin;
1415                                         /* use always the same group */
1416                                         DRW_shgroup_call_range_add(
1417                                                 stl->g_data->shgrps_edit_line,
1418                                                 cache->b_edlin.batch,
1419                                                 (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix : cache_ob->obmat,
1420                                                 start_edlin, len);
1421
1422                                         start_edlin = elm->vertex_idx;
1423                                 }
1424                                 break;
1425                         }
1426                         default:
1427                         {
1428                                 break;
1429                         }
1430                 }
1431                 /* save first group */
1432                 if ((shgrp != NULL) && (tag_first)) {
1433                         array_elm = &cache_ob->shgrp_array[idx];
1434                         array_elm->mode = idx == 0 ? eGplBlendMode_Normal: gpl->blend_mode;
1435                         array_elm->clamp_layer = gpl->flag & GP_LAYER_USE_MASK;
1436                         array_elm->blend_opacity = gpl->opacity;
1437                         array_elm->init_shgrp = shgrp;
1438                         cache_ob->tot_layers++;
1439
1440                         tag_first = false;
1441                 }
1442         }
1443
1444         /* save last group */
1445         if (shgrp != NULL) {
1446                 array_elm->mode = idx == 0 ? eGplBlendMode_Normal : gpl->blend_mode;
1447                 array_elm->end_shgrp = shgrp;
1448         }
1449 }
1450 /* populate a datablock for multiedit (no onions, no modifiers) */
1451 void DRW_gpencil_populate_multiedit(
1452         GPENCIL_e_data *e_data, void *vedata, Object *ob,
1453         tGPencilObjectCache *cache_ob)
1454 {
1455         bGPdata *gpd = (bGPdata *)ob->data;
1456         bGPDframe *gpf = NULL;
1457
1458         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
1459         const DRWContextState *draw_ctx = DRW_context_state_get();
1460         int cfra_eval = (int)DEG_get_ctime(draw_ctx->depsgraph);
1461         GpencilBatchCache *cache = gpencil_batch_cache_get(ob, cfra_eval);
1462         Scene *scene = draw_ctx->scene;
1463         ToolSettings *ts = scene->toolsettings;
1464
1465         /* check if playing animation */
1466         bool playing = stl->storage->is_playing;
1467
1468         /* calc max size of VBOs */
1469         gpencil_calc_vertex(stl, cache_ob, cache, gpd, cfra_eval);
1470
1471         /* draw strokes */
1472         for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
1473                 /* don't draw layer if hidden */
1474                 if (gpl->flag & GP_LAYER_HIDE)
1475                         continue;
1476
1477                 /* list of frames to draw */
1478                 if (!playing) {
1479                         for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
1480                                 if ((gpf == gpl->actframe) || (gpf->flag & GP_FRAME_SELECT)) {
1481                                         gpencil_draw_strokes(
1482                                                 cache, e_data, vedata, ts, ob, gpd, gpl, gpf, gpf,
1483                                                 gpl->opacity, gpl->tintcolor, false, cache_ob);
1484                                 }
1485                         }
1486                 }
1487                 else {
1488                         gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, GP_GETFRAME_USE_PREV);
1489                         if (gpf) {
1490                                 gpencil_draw_strokes(
1491                                         cache, e_data, vedata, ts, ob, gpd, gpl, gpf, gpf,
1492                                         gpl->opacity, gpl->tintcolor, false, cache_ob);
1493                         }
1494                 }
1495
1496         }
1497
1498         /* create batchs and shading groups */
1499         DRW_gpencil_create_batches(cache);
1500         DRW_gpencil_shgroups_create(e_data, vedata, ob, cache, cache_ob);
1501
1502         cache->is_dirty = false;
1503 }
1504
1505 /* helper for populate a complete grease pencil datablock */
1506 void DRW_gpencil_populate_datablock(
1507         GPENCIL_e_data *e_data, void *vedata,
1508         Object *ob,
1509         tGPencilObjectCache *cache_ob)
1510 {
1511         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
1512         const DRWContextState *draw_ctx = DRW_context_state_get();
1513         const ViewLayer *view_layer = DEG_get_evaluated_view_layer(draw_ctx->depsgraph);
1514         Scene *scene = draw_ctx->scene;
1515
1516         bGPdata *gpd_eval = (bGPdata *)ob->data;
1517         bGPdata *gpd = (bGPdata *)DEG_get_original_id(&gpd_eval->id);
1518
1519         View3D *v3d = draw_ctx->v3d;
1520         int cfra_eval = (int)DEG_get_ctime(draw_ctx->depsgraph);
1521         ToolSettings *ts = scene->toolsettings;
1522
1523         bGPDframe *derived_gpf = NULL;
1524         const bool main_onion = v3d != NULL ? (v3d->gp_flag & V3D_GP_SHOW_ONION_SKIN) : true;
1525         const bool do_onion = (bool)((gpd->flag & GP_DATA_STROKE_WEIGHTMODE) == 0) &&
1526                 main_onion && DRW_gpencil_onion_active(gpd);
1527         const bool overlay = v3d != NULL ? (bool)((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) : true;
1528         const bool time_remap = BKE_gpencil_has_time_modifiers(ob);
1529
1530         float opacity;
1531         bGPDframe *gpf = NULL;
1532         bGPDlayer *gpl_active = BKE_gpencil_layer_getactive(gpd);
1533
1534         /* check if playing animation */
1535         bool playing = stl->storage->is_playing;
1536
1537         GpencilBatchCache *cache = gpencil_batch_cache_get(ob, cfra_eval);
1538
1539         /* if object is duplicate, only create shading groups */
1540         if (cache_ob->is_dup_ob) {
1541                 DRW_gpencil_shgroups_create(e_data, vedata, ob, cache, cache_ob);
1542                 return;
1543         }
1544
1545         /* calc max size of VBOs */
1546         gpencil_calc_vertex(stl, cache_ob, cache, gpd, cfra_eval);
1547
1548         /* init general modifiers data */
1549         if (!stl->storage->simplify_modif) {
1550                 if ((cache->is_dirty) && (ob->greasepencil_modifiers.first)) {
1551                         BKE_gpencil_lattice_init(ob);
1552                 }
1553         }
1554         /* draw normal strokes */
1555         for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
1556                 /* don't draw layer if hidden */
1557                 if (gpl->flag & GP_LAYER_HIDE) {
1558                         continue;
1559                 }
1560
1561                 /* filter view layer to gp layers in the same view layer (for compo) */
1562                 if ((stl->storage->is_render) && (gpl->viewlayername[0] != '\0')) {
1563                         if (!STREQ(view_layer->name, gpl->viewlayername)) {
1564                                 continue;
1565                         }
1566                 }
1567
1568                 /* remap time */
1569                 int remap_cfra = cfra_eval;
1570                 if ((time_remap) && (!stl->storage->simplify_modif)) {
1571                         remap_cfra = BKE_gpencil_time_modifier(
1572                                 draw_ctx->depsgraph, scene, ob, gpl, cfra_eval,
1573                                 stl->storage->is_render);
1574                 }
1575
1576                 gpf = BKE_gpencil_layer_getframe(gpl, remap_cfra, GP_GETFRAME_USE_PREV);
1577                 if (gpf == NULL)
1578                         continue;
1579
1580                 opacity = gpl->opacity;
1581                 /* if pose mode, maybe the overlay to fade geometry is enabled */
1582                 if ((draw_ctx->obact) && (draw_ctx->object_mode == OB_MODE_POSE) &&
1583                     (v3d->overlay.flag & V3D_OVERLAY_BONE_SELECT))
1584                 {
1585                         opacity = opacity * v3d->overlay.xray_alpha_bone;
1586                 }
1587                 /* fade no active layers */
1588                 if ((overlay) && (draw_ctx->object_mode == OB_MODE_PAINT_GPENCIL) &&
1589                     (v3d->gp_flag & V3D_GP_FADE_NOACTIVE_LAYERS) &&
1590                     (draw_ctx->obact) && (draw_ctx->obact == ob) &&
1591                     (gpl != gpl_active))
1592                 {
1593                         opacity = opacity * v3d->overlay.gpencil_fade_layer;
1594                 }
1595
1596                 /* create derived frames array data or expand */
1597                 int derived_idx = BLI_findindex(&gpd->layers, gpl);
1598                 derived_gpf = &cache->derived_array[derived_idx];
1599
1600                 /* if no derived frame or dirty cache, create a new one */
1601                 if ((derived_gpf == NULL) || (cache->is_dirty)) {
1602                         if (derived_gpf != NULL) {
1603                                 /* first clear temp data */
1604                                 BKE_gpencil_free_frame_runtime_data(derived_gpf);
1605                         }
1606                         /* create new data (do not assign new memory)*/
1607                         gpencil_copy_frame(gpf, derived_gpf);
1608                 }
1609
1610                 /* draw onion skins */
1611                 if (!ID_IS_LINKED(&gpd->id)) {
1612                         if ((do_onion) && (gpl->onion_flag & GP_LAYER_ONIONSKIN) &&
1613                             ((!playing) || (gpd->onion_flag & GP_ONION_GHOST_ALWAYS)) &&
1614                             (!cache_ob->is_dup_ob) && (gpd->id.us <= 1))
1615                         {
1616                                 if (((!stl->storage->is_render) && (overlay)) ||
1617                                     ((stl->storage->is_render) && (gpd->onion_flag & GP_ONION_GHOST_ALWAYS)))
1618                                 {
1619                                         gpencil_draw_onionskins(cache, e_data, vedata, ob, gpd, gpl, gpf);
1620                                 }
1621                         }
1622                 }
1623                 /* draw normal strokes */
1624                 gpencil_draw_strokes(
1625                         cache, e_data, vedata, ts, ob, gpd, gpl, gpf, derived_gpf,
1626                         opacity, gpl->tintcolor, false, cache_ob);
1627         }
1628
1629         /* clear any lattice data */
1630         if ((cache->is_dirty) && (ob->greasepencil_modifiers.first)) {
1631                 BKE_gpencil_lattice_clear(ob);
1632         }
1633
1634         /* create batchs and shading groups */
1635         DRW_gpencil_create_batches(cache);
1636         DRW_gpencil_shgroups_create(e_data, vedata, ob, cache, cache_ob);
1637
1638         cache->is_dirty = false;
1639 }
1640
1641 void DRW_gpencil_populate_particles(GPENCIL_e_data *e_data, void *vedata)
1642 {
1643         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
1644
1645         /* add particles */
1646         for (int i = 0; i < stl->g_data->gp_cache_used; i++) {
1647                 tGPencilObjectCache *cache_ob = &stl->g_data->gp_object_cache[i];
1648                 Object *ob = cache_ob->ob;
1649                 if (cache_ob->is_dup_ob) {
1650                         GpencilBatchCache *cache = ob->runtime.gpencil_cache;
1651                         if (cache != NULL) {
1652                                 DRW_gpencil_shgroups_create(e_data, vedata, ob, cache, cache_ob);
1653                         }
1654                 }
1655         }
1656 }