Mesh Batch Cache: Port Texture paint wires to new batch request
[blender.git] / source / blender / draw / intern / draw_cache_impl_mesh.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2017 by Blender Foundation.
19  * All rights reserved.
20  *
21  * Contributor(s): Blender Foundation, Mike Erwin, Dalai Felinto
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 /** \file draw_cache_impl_mesh.c
27  *  \ingroup draw
28  *
29  * \brief Mesh API for render engines
30  */
31
32 #include "MEM_guardedalloc.h"
33
34 #include "BLI_buffer.h"
35 #include "BLI_utildefines.h"
36 #include "BLI_math_vector.h"
37 #include "BLI_math_bits.h"
38 #include "BLI_math_color.h"
39 #include "BLI_string.h"
40 #include "BLI_alloca.h"
41 #include "BLI_edgehash.h"
42
43 #include "DNA_mesh_types.h"
44 #include "DNA_meshdata_types.h"
45 #include "DNA_object_types.h"
46 #include "DNA_space_types.h"
47
48 #include "BKE_customdata.h"
49 #include "BKE_deform.h"
50 #include "BKE_editmesh.h"
51 #include "BKE_editmesh_cache.h"
52 #include "BKE_editmesh_tangent.h"
53 #include "BKE_mesh.h"
54 #include "BKE_mesh_tangent.h"
55 #include "BKE_mesh_runtime.h"
56 #include "BKE_colorband.h"
57 #include "BKE_cdderivedmesh.h"
58
59 #include "DEG_depsgraph_query.h"
60
61 #include "bmesh.h"
62
63 #include "GPU_batch.h"
64 #include "GPU_batch_presets.h"
65 #include "GPU_draw.h"
66 #include "GPU_material.h"
67
68 #include "DRW_render.h"
69
70 #include "ED_image.h"
71 #include "ED_mesh.h"
72 #include "ED_uvedit.h"
73
74 #include "draw_cache_impl.h"  /* own include */
75
76
77 static void mesh_batch_cache_clear(Mesh *me);
78
79
80 /* ---------------------------------------------------------------------- */
81
82 /** \name Mesh/BMesh Interface (direct access to basic data).
83  * \{ */
84
85 static int mesh_render_verts_len_get(Mesh *me)
86 {
87         return me->edit_btmesh ? me->edit_btmesh->bm->totvert : me->totvert;
88 }
89
90 static int mesh_render_edges_len_get(Mesh *me)
91 {
92         return me->edit_btmesh ? me->edit_btmesh->bm->totedge : me->totedge;
93 }
94
95 static int mesh_render_looptri_len_get(Mesh *me)
96 {
97         return me->edit_btmesh ? me->edit_btmesh->tottri : poly_to_tri_count(me->totpoly, me->totloop);
98 }
99
100 static int mesh_render_polys_len_get(Mesh *me)
101 {
102         return me->edit_btmesh ? me->edit_btmesh->bm->totface : me->totpoly;
103 }
104
105 static int mesh_render_mat_len_get(Mesh *me)
106 {
107         return MAX2(1, me->totcol);
108 }
109
110 static int UNUSED_FUNCTION(mesh_render_loops_len_get)(Mesh *me)
111 {
112         return me->edit_btmesh ? me->edit_btmesh->bm->totloop : me->totloop;
113 }
114
115 /** \} */
116
117
118 /* ---------------------------------------------------------------------- */
119
120 /** \name Mesh/BMesh Interface (indirect, partially cached access to complex data).
121  * \{ */
122
123 typedef struct EdgeAdjacentPolys {
124         int count;
125         int face_index[2];
126 } EdgeAdjacentPolys;
127
128 typedef struct EdgeAdjacentVerts {
129         int vert_index[2]; /* -1 if none */
130 } EdgeAdjacentVerts;
131
132 typedef struct EdgeDrawAttr {
133         uchar v_flag;
134         uchar e_flag;
135         uchar crease;
136         uchar bweight;
137 } EdgeDrawAttr;
138
139 typedef struct MeshRenderData {
140         int types;
141
142         int vert_len;
143         int edge_len;
144         int tri_len;
145         int loop_len;
146         int poly_len;
147         int mat_len;
148         int loose_vert_len;
149         int loose_edge_len;
150
151         /* Support for mapped mesh data. */
152         struct {
153                 /* Must be set if we want to get mapped data. */
154                 bool use;
155                 bool supported;
156
157                 Mesh *me_cage;
158
159                 int vert_len;
160                 int edge_len;
161                 int tri_len;
162                 int loop_len;
163                 int poly_len;
164
165                 int *loose_verts;
166                 int  loose_vert_len;
167
168                 int *loose_edges;
169                 int  loose_edge_len;
170
171                 /* origindex layers */
172                 int *v_origindex;
173                 int *e_origindex;
174                 int *l_origindex;
175                 int *p_origindex;
176         } mapped;
177
178         BMEditMesh *edit_bmesh;
179         struct EditMeshData *edit_data;
180
181         Mesh *me;
182
183         MVert *mvert;
184         const MEdge *medge;
185         const MLoop *mloop;
186         const MPoly *mpoly;
187         float (*orco)[3];  /* vertex coordinates normalized to bounding box */
188         bool is_orco_allocated;
189         MDeformVert *dvert;
190         MLoopUV *mloopuv;
191         MLoopCol *mloopcol;
192         float (*loop_normals)[3];
193
194         /* CustomData 'cd' cache for efficient access. */
195         struct {
196                 struct {
197                         MLoopUV **uv;
198                         int       uv_len;
199                         int       uv_active;
200
201                         MLoopCol **vcol;
202                         int        vcol_len;
203                         int        vcol_active;
204
205                         float (**tangent)[4];
206                         int      tangent_len;
207                         int      tangent_active;
208
209                         bool *auto_vcol;
210                 } layers;
211
212                 /* Custom-data offsets (only needed for BMesh access) */
213                 struct {
214                         int crease;
215                         int bweight;
216                         int *uv;
217                         int *vcol;
218 #ifdef WITH_FREESTYLE
219                         int freestyle_edge;
220                         int freestyle_face;
221 #endif
222                 } offset;
223
224                 struct {
225                         char (*auto_mix)[32];
226                         char (*uv)[32];
227                         char (*vcol)[32];
228                         char (*tangent)[32];
229                 } uuid;
230
231                 /* for certain cases we need an output loop-data storage (bmesh tangents) */
232                 struct {
233                         CustomData ldata;
234                         /* grr, special case variable (use in place of 'dm->tangent_mask') */
235                         short tangent_mask;
236                 } output;
237         } cd;
238
239         BMVert *eve_act;
240         BMEdge *eed_act;
241         BMFace *efa_act;
242
243         /* Data created on-demand (usually not for bmesh-based data). */
244         EdgeAdjacentPolys *edges_adjacent_polys;
245         MLoopTri *mlooptri;
246         int *loose_edges;
247         int *loose_verts;
248
249         float (*poly_normals)[3];
250         float (*vert_weight);
251         char (*vert_color)[3];
252         GPUPackedNormal *poly_normals_pack;
253         GPUPackedNormal *vert_normals_pack;
254         bool *edge_select_bool;
255         bool *edge_visible_bool;
256 } MeshRenderData;
257
258 enum {
259         MR_DATATYPE_VERT       = 1 << 0,
260         MR_DATATYPE_EDGE       = 1 << 1,
261         MR_DATATYPE_LOOPTRI    = 1 << 2,
262         MR_DATATYPE_LOOP       = 1 << 3,
263         MR_DATATYPE_POLY       = 1 << 4,
264         MR_DATATYPE_OVERLAY    = 1 << 5,
265         MR_DATATYPE_SHADING    = 1 << 6,
266         MR_DATATYPE_DVERT      = 1 << 7,
267         MR_DATATYPE_LOOPCOL    = 1 << 8,
268         MR_DATATYPE_LOOPUV     = 1 << 9,
269         MR_DATATYPE_LOOSE_VERT = 1 << 10,
270         MR_DATATYPE_LOOSE_EDGE = 1 << 11,
271 };
272
273 /**
274  * These functions look like they would be slow but they will typically return true on the first iteration.
275  * Only false when all attached elements are hidden.
276  */
277 static bool bm_vert_has_visible_edge(const BMVert *v)
278 {
279         const BMEdge *e_iter, *e_first;
280
281         e_iter = e_first = v->e;
282         do {
283                 if (!BM_elem_flag_test(e_iter, BM_ELEM_HIDDEN)) {
284                         return true;
285                 }
286         } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, v)) != e_first);
287         return false;
288 }
289
290 static bool bm_edge_has_visible_face(const BMEdge *e)
291 {
292         const BMLoop *l_iter, *l_first;
293         l_iter = l_first = e->l;
294         do {
295                 if (!BM_elem_flag_test(l_iter->f, BM_ELEM_HIDDEN)) {
296                         return true;
297                 }
298         } while ((l_iter = l_iter->radial_next) != l_first);
299         return false;
300 }
301
302 /* Return true is all layers in _b_ are inside _a_. */
303 static bool mesh_cd_layers_type_overlap(
304         const uchar av[CD_NUMTYPES], const ushort al[CD_NUMTYPES],
305         const uchar bv[CD_NUMTYPES], const ushort bl[CD_NUMTYPES])
306 {
307         for (int i = 0; i < CD_NUMTYPES; ++i) {
308                 if ((av[i] & bv[i]) != bv[i]) {
309                         return false;
310                 }
311                 if ((al[i] & bl[i]) != bl[i]) {
312                         return false;
313                 }
314         }
315         return true;
316 }
317
318 static void mesh_cd_layers_type_merge(
319         uchar av[CD_NUMTYPES], ushort al[CD_NUMTYPES],
320         uchar bv[CD_NUMTYPES], ushort bl[CD_NUMTYPES])
321 {
322         for (int i = 0; i < CD_NUMTYPES; ++i) {
323                 av[i] |= bv[i];
324                 al[i] |= bl[i];
325         }
326 }
327
328 static void mesh_cd_calc_active_uv_layer(
329         const Mesh *me, ushort cd_lused[CD_NUMTYPES])
330 {
331         const CustomData *cd_ldata = (me->edit_btmesh) ? &me->edit_btmesh->bm->ldata : &me->ldata;
332
333         int layer = CustomData_get_active_layer(cd_ldata, CD_MLOOPUV);
334         if (layer != -1) {
335                 cd_lused[CD_MLOOPUV] |= (1 << layer);
336         }
337 }
338
339 static void mesh_cd_calc_used_gpu_layers(
340         const Mesh *me, uchar cd_vused[CD_NUMTYPES], ushort cd_lused[CD_NUMTYPES],
341         struct GPUMaterial **gpumat_array, int gpumat_array_len)
342 {
343         const CustomData *cd_ldata = (me->edit_btmesh) ? &me->edit_btmesh->bm->ldata : &me->ldata;
344
345         /* See: DM_vertex_attributes_from_gpu for similar logic */
346         GPUVertexAttribs gattribs = {{{0}}};
347
348         for (int i = 0; i < gpumat_array_len; i++) {
349                 GPUMaterial *gpumat = gpumat_array[i];
350                 if (gpumat) {
351                         GPU_material_vertex_attributes(gpumat, &gattribs);
352                         for (int j = 0; j < gattribs.totlayer; j++) {
353                                 const char *name = gattribs.layer[j].name;
354                                 int type = gattribs.layer[j].type;
355                                 int layer = -1;
356
357                                 if (type == CD_AUTO_FROM_NAME) {
358                                         /* We need to deduct what exact layer is used.
359                                          *
360                                          * We do it based on the specified name.
361                                          */
362                                         if (name[0] != '\0') {
363                                                 layer = CustomData_get_named_layer(cd_ldata, CD_MLOOPUV, name);
364                                                 type = CD_MTFACE;
365
366                                                 if (layer == -1) {
367                                                         layer = CustomData_get_named_layer(cd_ldata, CD_MLOOPCOL, name);
368                                                         type = CD_MCOL;
369                                                 }
370 #if 0                                   /* Tangents are always from UV's - this will never happen. */
371                                                 if (layer == -1) {
372                                                         layer = CustomData_get_named_layer(cd_ldata, CD_TANGENT, name);
373                                                         type = CD_TANGENT;
374                                                 }
375 #endif
376                                                 if (layer == -1) {
377                                                         continue;
378                                                 }
379                                         }
380                                         else {
381                                                 /* Fall back to the UV layer, which matches old behavior. */
382                                                 type = CD_MTFACE;
383                                         }
384                                 }
385
386                                 switch (type) {
387                                         case CD_MTFACE:
388                                         {
389                                                 if (layer == -1) {
390                                                         layer = (name[0] != '\0') ?
391                                                                 CustomData_get_named_layer(cd_ldata, CD_MLOOPUV, name) :
392                                                                 CustomData_get_active_layer(cd_ldata, CD_MLOOPUV);
393                                                 }
394                                                 if (layer != -1) {
395                                                         cd_lused[CD_MLOOPUV] |= (1 << layer);
396                                                 }
397                                                 break;
398                                         }
399                                         case CD_TANGENT:
400                                         {
401                                                 if (layer == -1) {
402                                                         layer = (name[0] != '\0') ?
403                                                                 CustomData_get_named_layer(cd_ldata, CD_MLOOPUV, name) :
404                                                                 CustomData_get_active_layer(cd_ldata, CD_MLOOPUV);
405                                                 }
406                                                 if (layer != -1) {
407                                                         cd_lused[CD_TANGENT] |= (1 << layer);
408                                                 }
409                                                 else {
410                                                         /* no UV layers at all => requesting orco */
411                                                         cd_lused[CD_TANGENT] |= DM_TANGENT_MASK_ORCO;
412                                                         cd_vused[CD_ORCO] |= 1;
413                                                 }
414                                                 break;
415                                         }
416                                         case CD_MCOL:
417                                         {
418                                                 if (layer == -1) {
419                                                         layer = (name[0] != '\0') ?
420                                                                 CustomData_get_named_layer(cd_ldata, CD_MLOOPCOL, name) :
421                                                                 CustomData_get_active_layer(cd_ldata, CD_MLOOPCOL);
422                                                 }
423                                                 if (layer != -1) {
424                                                         cd_lused[CD_MLOOPCOL] |= (1 << layer);
425                                                 }
426                                                 break;
427                                         }
428                                         case CD_ORCO:
429                                         {
430                                                 cd_vused[CD_ORCO] |= 1;
431                                                 break;
432                                         }
433                                 }
434                         }
435                 }
436         }
437 }
438
439
440 static void mesh_render_calc_normals_loop_and_poly(const Mesh *me, const float split_angle, MeshRenderData *rdata)
441 {
442         BLI_assert((me->flag & ME_AUTOSMOOTH) != 0);
443
444         int totloop = me->totloop;
445         int totpoly = me->totpoly;
446         float (*loop_normals)[3] = MEM_mallocN(sizeof(*loop_normals) * totloop, __func__);
447         float (*poly_normals)[3] = MEM_mallocN(sizeof(*poly_normals) * totpoly, __func__);
448         short (*clnors)[2] = CustomData_get_layer(&me->ldata, CD_CUSTOMLOOPNORMAL);
449
450         BKE_mesh_calc_normals_poly(
451                 me->mvert, NULL, me->totvert,
452                 me->mloop, me->mpoly, totloop, totpoly, poly_normals, false);
453
454         BKE_mesh_normals_loop_split(
455                 me->mvert, me->totvert, me->medge, me->totedge,
456                 me->mloop, loop_normals, totloop, me->mpoly, poly_normals, totpoly,
457                 true, split_angle, NULL, clnors, NULL);
458
459         rdata->loop_len = totloop;
460         rdata->poly_len = totpoly;
461         rdata->loop_normals = loop_normals;
462         rdata->poly_normals = poly_normals;
463 }
464
465 static void mesh_cd_extract_auto_layers_names_and_srgb(
466         Mesh *me, const ushort cd_lused[CD_NUMTYPES],
467         char **r_auto_layers_names, int **r_auto_layers_srgb, int *r_auto_layers_len)
468 {
469         const CustomData *cd_ldata = (me->edit_btmesh) ? &me->edit_btmesh->bm->ldata : &me->ldata;
470
471         int uv_len_used = count_bits_i(cd_lused[CD_MLOOPUV]);
472         int vcol_len_used = count_bits_i(cd_lused[CD_MLOOPCOL]);
473         int uv_len = CustomData_number_of_layers(cd_ldata, CD_MLOOPUV);
474         int vcol_len = CustomData_number_of_layers(cd_ldata, CD_MLOOPCOL);
475
476         uint auto_names_len = 32 * (uv_len_used + vcol_len_used);
477         uint auto_ofs = 0;
478         /* Allocate max, resize later. */
479         char *auto_names = MEM_callocN(sizeof(char) * auto_names_len, __func__);
480         int *auto_is_srgb = MEM_callocN(sizeof(int) * (uv_len_used + vcol_len_used), __func__);
481
482         for (int i = 0; i < uv_len; i++) {
483                 if ((cd_lused[CD_MLOOPUV] & (1 << i)) != 0) {
484                         const char *name = CustomData_get_layer_name(cd_ldata, CD_MLOOPUV, i);
485                         uint hash = BLI_ghashutil_strhash_p(name);
486                         /* +1 to include '\0' terminator. */
487                         auto_ofs += 1 + BLI_snprintf_rlen(auto_names + auto_ofs, auto_names_len - auto_ofs, "ba%u", hash);
488                 }
489         }
490
491         uint auto_is_srgb_ofs = uv_len_used;
492         for (int i = 0; i < vcol_len; i++) {
493                 if ((cd_lused[CD_MLOOPCOL] & (1 << i)) != 0) {
494                         const char *name = CustomData_get_layer_name(cd_ldata, CD_MLOOPCOL, i);
495                         /* We only do vcols that are not overridden by a uv layer with same name. */
496                         if (CustomData_get_named_layer_index(cd_ldata, CD_MLOOPUV, name) == -1) {
497                                 uint hash = BLI_ghashutil_strhash_p(name);
498                                 /* +1 to include '\0' terminator. */
499                                 auto_ofs += 1 + BLI_snprintf_rlen(auto_names + auto_ofs, auto_names_len - auto_ofs, "ba%u", hash);
500                                 auto_is_srgb[auto_is_srgb_ofs] = true;
501                                 auto_is_srgb_ofs++;
502                         }
503                 }
504         }
505
506         auto_names = MEM_reallocN(auto_names, sizeof(char) * auto_ofs);
507         auto_is_srgb = MEM_reallocN(auto_is_srgb, sizeof(int) * auto_is_srgb_ofs);
508
509         *r_auto_layers_names = auto_names;
510         *r_auto_layers_srgb = auto_is_srgb;
511         *r_auto_layers_len = auto_is_srgb_ofs;
512 }
513
514 /**
515  * TODO(campbell): 'gpumat_array' may include materials linked to the object.
516  * While not default, object materials should be supported.
517  * Although this only impacts the data that's generated, not the materials that display.
518  */
519 static MeshRenderData *mesh_render_data_create_ex(
520         Mesh *me, const int types, const uchar cd_vused[CD_NUMTYPES], const ushort cd_lused[CD_NUMTYPES])
521 {
522         MeshRenderData *rdata = MEM_callocN(sizeof(*rdata), __func__);
523         rdata->types = types;
524         rdata->mat_len = mesh_render_mat_len_get(me);
525
526         CustomData_reset(&rdata->cd.output.ldata);
527
528         const bool is_auto_smooth = (me->flag & ME_AUTOSMOOTH) != 0;
529         const float split_angle = is_auto_smooth ? me->smoothresh : (float)M_PI;
530
531         if (me->edit_btmesh) {
532                 BMEditMesh *embm = me->edit_btmesh;
533                 BMesh *bm = embm->bm;
534
535                 rdata->edit_bmesh = embm;
536                 rdata->edit_data = me->runtime.edit_data;
537
538                 if (embm->mesh_eval_cage && (embm->mesh_eval_cage->runtime.is_original == false)) {
539                         Mesh *me_cage = embm->mesh_eval_cage;
540
541                         rdata->mapped.me_cage = me_cage;
542                         if (types & MR_DATATYPE_VERT) {
543                                 rdata->mapped.vert_len = me_cage->totvert;
544                         }
545                         if (types & MR_DATATYPE_EDGE) {
546                                 rdata->mapped.edge_len = me_cage->totedge;
547                         }
548                         if (types & MR_DATATYPE_LOOP) {
549                                 rdata->mapped.loop_len = me_cage->totloop;
550                         }
551                         if (types & MR_DATATYPE_POLY) {
552                                 rdata->mapped.poly_len = me_cage->totpoly;
553                         }
554                         if (types & MR_DATATYPE_LOOPTRI) {
555                                 rdata->mapped.tri_len = poly_to_tri_count(me_cage->totpoly, me_cage->totloop);
556                         }
557
558                         rdata->mapped.v_origindex = CustomData_get_layer(&me_cage->vdata, CD_ORIGINDEX);
559                         rdata->mapped.e_origindex = CustomData_get_layer(&me_cage->edata, CD_ORIGINDEX);
560                         rdata->mapped.l_origindex = CustomData_get_layer(&me_cage->ldata, CD_ORIGINDEX);
561                         rdata->mapped.p_origindex = CustomData_get_layer(&me_cage->pdata, CD_ORIGINDEX);
562                         rdata->mapped.supported = (
563                                 rdata->mapped.v_origindex &&
564                                 rdata->mapped.e_origindex &&
565                                 rdata->mapped.p_origindex);
566                 }
567
568                 int bm_ensure_types = 0;
569                 if (types & MR_DATATYPE_VERT) {
570                         rdata->vert_len = bm->totvert;
571                         bm_ensure_types |= BM_VERT;
572                 }
573                 if (types & MR_DATATYPE_EDGE) {
574                         rdata->edge_len = bm->totedge;
575                         bm_ensure_types |= BM_EDGE;
576                 }
577                 if (types & MR_DATATYPE_LOOPTRI) {
578                         bm_ensure_types |= BM_LOOP;
579                 }
580                 if (types & MR_DATATYPE_LOOP) {
581                         int totloop = bm->totloop;
582                         if (is_auto_smooth) {
583                                 rdata->loop_normals = MEM_mallocN(sizeof(*rdata->loop_normals) * totloop, __func__);
584                                 int cd_loop_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL);
585                                 BM_loops_calc_normal_vcos(
586                                         bm, NULL, NULL, NULL, true, split_angle, rdata->loop_normals, NULL, NULL,
587                                         cd_loop_clnors_offset, false);
588                         }
589                         rdata->loop_len = totloop;
590                         bm_ensure_types |= BM_LOOP;
591                 }
592                 if (types & MR_DATATYPE_POLY) {
593                         rdata->poly_len = bm->totface;
594                         bm_ensure_types |= BM_FACE;
595                 }
596                 if (types & MR_DATATYPE_OVERLAY) {
597                         rdata->efa_act = BM_mesh_active_face_get(bm, false, true);
598                         rdata->eed_act = BM_mesh_active_edge_get(bm);
599                         rdata->eve_act = BM_mesh_active_vert_get(bm);
600                         rdata->cd.offset.crease = CustomData_get_offset(&bm->edata, CD_CREASE);
601                         rdata->cd.offset.bweight = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
602
603 #ifdef WITH_FREESTYLE
604                         rdata->cd.offset.freestyle_edge = CustomData_get_offset(&bm->edata, CD_FREESTYLE_EDGE);
605                         rdata->cd.offset.freestyle_face = CustomData_get_offset(&bm->pdata, CD_FREESTYLE_FACE);
606 #endif
607                 }
608                 if (types & (MR_DATATYPE_DVERT)) {
609                         bm_ensure_types |= BM_VERT;
610                 }
611                 if (rdata->edit_data != NULL) {
612                         bm_ensure_types |= BM_VERT;
613                 }
614
615                 BM_mesh_elem_index_ensure(bm, bm_ensure_types);
616                 BM_mesh_elem_table_ensure(bm, bm_ensure_types & ~BM_LOOP);
617
618                 if (types & MR_DATATYPE_LOOPTRI) {
619                         /* Edit mode ensures this is valid, no need to calculate. */
620                         BLI_assert((bm->totloop == 0) || (embm->looptris != NULL));
621                         int tottri = embm->tottri;
622                         MLoopTri *mlooptri = MEM_mallocN(sizeof(*rdata->mlooptri) * embm->tottri, __func__);
623                         for (int index = 0; index < tottri ; index ++ ) {
624                                 BMLoop **bmtri = embm->looptris[index];
625                                 MLoopTri *mtri = &mlooptri[index];
626                                 mtri->tri[0] = BM_elem_index_get(bmtri[0]);
627                                 mtri->tri[1] = BM_elem_index_get(bmtri[1]);
628                                 mtri->tri[2] = BM_elem_index_get(bmtri[2]);
629                         }
630                         rdata->mlooptri = mlooptri;
631                         rdata->tri_len = tottri;
632                 }
633
634                 if (types & MR_DATATYPE_LOOSE_VERT) {
635                         BLI_assert(types & MR_DATATYPE_VERT);
636                         rdata->loose_vert_len = 0;
637
638                         {
639                                 int *lverts = MEM_mallocN(rdata->vert_len * sizeof(int), __func__);
640                                 BLI_assert((bm->elem_table_dirty & BM_VERT) == 0);
641                                 for (int i = 0; i < bm->totvert; i++) {
642                                         const BMVert *eve = BM_vert_at_index(bm, i);
643                                         if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
644                                                 /* Loose vert */
645                                                 if (eve->e == NULL || !bm_vert_has_visible_edge(eve)) {
646                                                         lverts[rdata->loose_vert_len++] = i;
647                                                 }
648                                         }
649                                 }
650                                 rdata->loose_verts = MEM_reallocN(lverts, rdata->loose_vert_len * sizeof(int));
651                         }
652
653                         if (rdata->mapped.supported) {
654                                 Mesh *me_cage = embm->mesh_eval_cage;
655                                 rdata->mapped.loose_vert_len = 0;
656
657                                 if (rdata->loose_vert_len) {
658                                         int *lverts = MEM_mallocN(me_cage->totvert * sizeof(int), __func__);
659                                         const int *v_origindex = rdata->mapped.v_origindex;
660                                         for (int i = 0; i < me_cage->totvert; i++) {
661                                                 const int v_orig = v_origindex[i];
662                                                 if (v_orig != ORIGINDEX_NONE) {
663                                                         BMVert *eve = BM_vert_at_index(bm, v_orig);
664                                                         if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
665                                                                 /* Loose vert */
666                                                                 if (eve->e == NULL || !bm_vert_has_visible_edge(eve)) {
667                                                                         lverts[rdata->mapped.loose_vert_len++] = i;
668                                                                 }
669                                                         }
670                                                 }
671                                         }
672                                         rdata->mapped.loose_verts = MEM_reallocN(lverts, rdata->mapped.loose_vert_len * sizeof(int));
673                                 }
674                         }
675                 }
676
677                 if (types & MR_DATATYPE_LOOSE_EDGE) {
678                         BLI_assert(types & MR_DATATYPE_EDGE);
679                         rdata->loose_edge_len = 0;
680
681                         {
682                                 int *ledges = MEM_mallocN(rdata->edge_len * sizeof(int), __func__);
683                                 BLI_assert((bm->elem_table_dirty & BM_EDGE) == 0);
684                                 for (int i = 0; i < bm->totedge; i++) {
685                                         const BMEdge *eed = BM_edge_at_index(bm, i);
686                                         if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
687                                                 /* Loose edge */
688                                                 if (eed->l == NULL || !bm_edge_has_visible_face(eed)) {
689                                                         ledges[rdata->loose_edge_len++] = i;
690                                                 }
691                                         }
692                                 }
693                                 rdata->loose_edges = MEM_reallocN(ledges, rdata->loose_edge_len * sizeof(int));
694                         }
695
696                         if (rdata->mapped.supported) {
697                                 Mesh *me_cage = embm->mesh_eval_cage;
698                                 rdata->mapped.loose_edge_len = 0;
699
700                                 if (rdata->loose_edge_len) {
701                                         int *ledges = MEM_mallocN(me_cage->totedge * sizeof(int), __func__);
702                                         const int *e_origindex = rdata->mapped.e_origindex;
703                                         for (int i = 0; i < me_cage->totedge; i++) {
704                                                 const int e_orig = e_origindex[i];
705                                                 if (e_orig != ORIGINDEX_NONE) {
706                                                         BMEdge *eed = BM_edge_at_index(bm, e_orig);
707                                                         if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
708                                                                 /* Loose edge */
709                                                                 if (eed->l == NULL || !bm_edge_has_visible_face(eed)) {
710                                                                         ledges[rdata->mapped.loose_edge_len++] = i;
711                                                                 }
712                                                         }
713                                                 }
714                                         }
715                                         rdata->mapped.loose_edges = MEM_reallocN(ledges, rdata->mapped.loose_edge_len * sizeof(int));
716                                 }
717                         }
718                 }
719         }
720         else {
721                 rdata->me = me;
722
723                 if (types & (MR_DATATYPE_VERT)) {
724                         rdata->vert_len = me->totvert;
725                         rdata->mvert = CustomData_get_layer(&me->vdata, CD_MVERT);
726                 }
727                 if (types & (MR_DATATYPE_EDGE)) {
728                         rdata->edge_len = me->totedge;
729                         rdata->medge = CustomData_get_layer(&me->edata, CD_MEDGE);
730                 }
731                 if (types & MR_DATATYPE_LOOPTRI) {
732                         const int tri_len = rdata->tri_len = poly_to_tri_count(me->totpoly, me->totloop);
733                         MLoopTri *mlooptri = MEM_mallocN(sizeof(*mlooptri) * tri_len, __func__);
734                         BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, mlooptri);
735                         rdata->mlooptri = mlooptri;
736                 }
737                 if (types & MR_DATATYPE_LOOP) {
738                         rdata->loop_len = me->totloop;
739                         rdata->mloop = CustomData_get_layer(&me->ldata, CD_MLOOP);
740
741                         if (is_auto_smooth) {
742                                 mesh_render_calc_normals_loop_and_poly(me, split_angle, rdata);
743                         }
744                 }
745                 if (types & MR_DATATYPE_POLY) {
746                         rdata->poly_len = me->totpoly;
747                         rdata->mpoly = CustomData_get_layer(&me->pdata, CD_MPOLY);
748                 }
749                 if (types & MR_DATATYPE_DVERT) {
750                         rdata->vert_len = me->totvert;
751                         rdata->dvert = CustomData_get_layer(&me->vdata, CD_MDEFORMVERT);
752                 }
753                 if (types & MR_DATATYPE_LOOPCOL) {
754                         rdata->loop_len = me->totloop;
755                         rdata->mloopcol = CustomData_get_layer(&me->ldata, CD_MLOOPCOL);
756                 }
757                 if (types & MR_DATATYPE_LOOPUV) {
758                         rdata->loop_len = me->totloop;
759                         rdata->mloopuv = CustomData_get_layer(&me->ldata, CD_MLOOPUV);
760                 }
761         }
762
763         if (types & MR_DATATYPE_SHADING) {
764                 CustomData *cd_vdata, *cd_ldata;
765
766                 BLI_assert(cd_vused != NULL && cd_lused != NULL);
767
768                 if (me->edit_btmesh) {
769                         BMesh *bm = me->edit_btmesh->bm;
770                         cd_vdata = &bm->vdata;
771                         cd_ldata = &bm->ldata;
772                 }
773                 else {
774                         cd_vdata = &me->vdata;
775                         cd_ldata = &me->ldata;
776                 }
777
778                 rdata->cd.layers.uv_active = CustomData_get_active_layer(cd_ldata, CD_MLOOPUV);
779                 rdata->cd.layers.vcol_active = CustomData_get_active_layer(cd_ldata, CD_MLOOPCOL);
780                 rdata->cd.layers.tangent_active = rdata->cd.layers.uv_active;
781
782 #define CD_VALIDATE_ACTIVE_LAYER(active_index, used) \
783                 if ((active_index != -1) && (used & (1 << active_index)) == 0) { \
784                         active_index = -1; \
785                 } ((void)0)
786
787                 CD_VALIDATE_ACTIVE_LAYER(rdata->cd.layers.uv_active, cd_lused[CD_MLOOPUV]);
788                 CD_VALIDATE_ACTIVE_LAYER(rdata->cd.layers.tangent_active, cd_lused[CD_TANGENT]);
789                 CD_VALIDATE_ACTIVE_LAYER(rdata->cd.layers.vcol_active, cd_lused[CD_MLOOPCOL]);
790
791 #undef CD_VALIDATE_ACTIVE_LAYER
792
793                 rdata->is_orco_allocated = false;
794                 if (cd_vused[CD_ORCO] & 1) {
795                         rdata->orco = CustomData_get_layer(cd_vdata, CD_ORCO);
796                         /* If orco is not available compute it ourselves */
797                         if (!rdata->orco) {
798                                 rdata->is_orco_allocated = true;
799                                 if (me->edit_btmesh) {
800                                         BMesh *bm = me->edit_btmesh->bm;
801                                         rdata->orco = MEM_mallocN(sizeof(*rdata->orco) * rdata->vert_len, "orco mesh");
802                                         BLI_assert((bm->elem_table_dirty & BM_VERT) == 0);
803                                         for (int i = 0; i < bm->totvert; i++) {
804                                                 copy_v3_v3(rdata->orco[i], BM_vert_at_index(bm, i)->co);
805                                         }
806                                         BKE_mesh_orco_verts_transform(me, rdata->orco, rdata->vert_len, 0);
807                                 }
808                                 else {
809                                         rdata->orco = MEM_mallocN(sizeof(*rdata->orco) * rdata->vert_len, "orco mesh");
810                                         MVert *mvert = rdata->mvert;
811                                         for (int a = 0; a < rdata->vert_len; a++, mvert++) {
812                                                 copy_v3_v3(rdata->orco[a], mvert->co);
813                                         }
814                                         BKE_mesh_orco_verts_transform(me, rdata->orco, rdata->vert_len, 0);
815                                 }
816                         }
817                 }
818                 else {
819                         rdata->orco = NULL;
820                 }
821
822                 /* don't access mesh directly, instead use vars taken from BMesh or Mesh */
823 #define me DONT_USE_THIS
824 #ifdef  me /* quiet warning */
825 #endif
826                 struct {
827                         uint uv_len;
828                         uint vcol_len;
829                 } cd_layers_src = {
830                         .uv_len = CustomData_number_of_layers(cd_ldata, CD_MLOOPUV),
831                         .vcol_len = CustomData_number_of_layers(cd_ldata, CD_MLOOPCOL),
832                 };
833
834                 rdata->cd.layers.uv_len = count_bits_i(cd_lused[CD_MLOOPUV]);
835                 rdata->cd.layers.tangent_len = count_bits_i(cd_lused[CD_TANGENT]);
836                 rdata->cd.layers.vcol_len = count_bits_i(cd_lused[CD_MLOOPCOL]);
837
838                 rdata->cd.layers.uv = MEM_mallocN(sizeof(*rdata->cd.layers.uv) * rdata->cd.layers.uv_len, __func__);
839                 rdata->cd.layers.vcol = MEM_mallocN(sizeof(*rdata->cd.layers.vcol) * rdata->cd.layers.vcol_len, __func__);
840                 rdata->cd.layers.tangent = MEM_mallocN(sizeof(*rdata->cd.layers.tangent) * rdata->cd.layers.tangent_len, __func__);
841
842                 rdata->cd.uuid.uv = MEM_mallocN(sizeof(*rdata->cd.uuid.uv) * rdata->cd.layers.uv_len, __func__);
843                 rdata->cd.uuid.vcol = MEM_mallocN(sizeof(*rdata->cd.uuid.vcol) * rdata->cd.layers.vcol_len, __func__);
844                 rdata->cd.uuid.tangent = MEM_mallocN(sizeof(*rdata->cd.uuid.tangent) * rdata->cd.layers.tangent_len, __func__);
845
846                 rdata->cd.offset.uv = MEM_mallocN(sizeof(*rdata->cd.offset.uv) * rdata->cd.layers.uv_len, __func__);
847                 rdata->cd.offset.vcol = MEM_mallocN(sizeof(*rdata->cd.offset.vcol) * rdata->cd.layers.vcol_len, __func__);
848
849                 /* Allocate max */
850                 rdata->cd.layers.auto_vcol = MEM_callocN(
851                         sizeof(*rdata->cd.layers.auto_vcol) * rdata->cd.layers.vcol_len, __func__);
852                 rdata->cd.uuid.auto_mix = MEM_mallocN(
853                         sizeof(*rdata->cd.uuid.auto_mix) * (rdata->cd.layers.vcol_len + rdata->cd.layers.uv_len), __func__);
854
855                 /* XXX FIXME XXX */
856                 /* We use a hash to identify each data layer based on its name.
857                  * Gawain then search for this name in the current shader and bind if it exists.
858                  * NOTE : This is prone to hash collision.
859                  * One solution to hash collision would be to format the cd layer name
860                  * to a safe glsl var name, but without name clash.
861                  * NOTE 2 : Replicate changes to code_generate_vertex_new() in gpu_codegen.c */
862                 if (rdata->cd.layers.vcol_len != 0) {
863                         for (int i_src = 0, i_dst = 0; i_src < cd_layers_src.vcol_len; i_src++, i_dst++) {
864                                 if ((cd_lused[CD_MLOOPCOL] & (1 << i_src)) == 0) {
865                                         i_dst--;
866                                         if (rdata->cd.layers.vcol_active >= i_src) {
867                                                 rdata->cd.layers.vcol_active--;
868                                         }
869                                 }
870                                 else {
871                                         const char *name = CustomData_get_layer_name(cd_ldata, CD_MLOOPCOL, i_src);
872                                         uint hash = BLI_ghashutil_strhash_p(name);
873                                         BLI_snprintf(rdata->cd.uuid.vcol[i_dst], sizeof(*rdata->cd.uuid.vcol), "c%u", hash);
874                                         rdata->cd.layers.vcol[i_dst] = CustomData_get_layer_n(cd_ldata, CD_MLOOPCOL, i_src);
875                                         if (rdata->edit_bmesh) {
876                                                 rdata->cd.offset.vcol[i_dst] = CustomData_get_n_offset(
877                                                         &rdata->edit_bmesh->bm->ldata, CD_MLOOPCOL, i_src);
878                                         }
879
880                                         /* Gather number of auto layers. */
881                                         /* We only do vcols that are not overridden by uvs */
882                                         if (CustomData_get_named_layer_index(cd_ldata, CD_MLOOPUV, name) == -1) {
883                                                 BLI_snprintf(
884                                                         rdata->cd.uuid.auto_mix[rdata->cd.layers.uv_len + i_dst],
885                                                         sizeof(*rdata->cd.uuid.auto_mix), "a%u", hash);
886                                                 rdata->cd.layers.auto_vcol[i_dst] = true;
887                                         }
888                                 }
889                         }
890                 }
891
892                 /* Start Fresh */
893                 CustomData_free_layers(cd_ldata, CD_TANGENT, rdata->loop_len);
894                 CustomData_free_layers(cd_ldata, CD_MLOOPTANGENT, rdata->loop_len);
895
896                 if (rdata->cd.layers.uv_len != 0) {
897                         for (int i_src = 0, i_dst = 0; i_src < cd_layers_src.uv_len; i_src++, i_dst++) {
898                                 if ((cd_lused[CD_MLOOPUV] & (1 << i_src)) == 0) {
899                                         i_dst--;
900                                         if (rdata->cd.layers.uv_active >= i_src) {
901                                                 rdata->cd.layers.uv_active--;
902                                         }
903                                 }
904                                 else {
905                                         const char *name = CustomData_get_layer_name(cd_ldata, CD_MLOOPUV, i_src);
906                                         uint hash = BLI_ghashutil_strhash_p(name);
907
908                                         BLI_snprintf(rdata->cd.uuid.uv[i_dst], sizeof(*rdata->cd.uuid.uv), "u%u", hash);
909                                         rdata->cd.layers.uv[i_dst] = CustomData_get_layer_n(cd_ldata, CD_MLOOPUV, i_src);
910                                         if (rdata->edit_bmesh) {
911                                                 rdata->cd.offset.uv[i_dst] = CustomData_get_n_offset(
912                                                         &rdata->edit_bmesh->bm->ldata, CD_MLOOPUV, i_src);
913                                         }
914                                         BLI_snprintf(rdata->cd.uuid.auto_mix[i_dst], sizeof(*rdata->cd.uuid.auto_mix), "a%u", hash);
915                                 }
916                         }
917                 }
918
919                 if (rdata->cd.layers.tangent_len != 0) {
920
921                         /* -------------------------------------------------------------------- */
922                         /* Pre-calculate tangents into 'rdata->cd.output.ldata' */
923
924                         BLI_assert(!CustomData_has_layer(&rdata->cd.output.ldata, CD_TANGENT));
925
926                         /* Tangent Names */
927                         char tangent_names[MAX_MTFACE][MAX_NAME];
928                         for (int i_src = 0, i_dst = 0; i_src < cd_layers_src.uv_len; i_src++, i_dst++) {
929                                 if ((cd_lused[CD_TANGENT] & (1 << i_src)) == 0) {
930                                         i_dst--;
931                                 }
932                                 else {
933                                         BLI_strncpy(
934                                                 tangent_names[i_dst],
935                                                 CustomData_get_layer_name(cd_ldata, CD_MLOOPUV, i_src), MAX_NAME);
936                                 }
937                         }
938
939                         /* If tangent from orco is requested, decrement tangent_len */
940                         int actual_tangent_len = (cd_lused[CD_TANGENT] & DM_TANGENT_MASK_ORCO) ?
941                                 rdata->cd.layers.tangent_len - 1 : rdata->cd.layers.tangent_len;
942                         if (rdata->edit_bmesh) {
943                                 BMEditMesh *em = rdata->edit_bmesh;
944                                 BMesh *bm = em->bm;
945
946                                 if (is_auto_smooth && rdata->loop_normals == NULL) {
947                                         /* Should we store the previous array of `loop_normals` in somewhere? */
948                                         rdata->loop_len = bm->totloop;
949                                         rdata->loop_normals = MEM_mallocN(sizeof(*rdata->loop_normals) * rdata->loop_len, __func__);
950                                         BM_loops_calc_normal_vcos(bm, NULL, NULL, NULL, true, split_angle, rdata->loop_normals, NULL, NULL, -1, false);
951                                 }
952
953                                 bool calc_active_tangent = false;
954
955                                 BKE_editmesh_loop_tangent_calc(
956                                         em, calc_active_tangent,
957                                         tangent_names, actual_tangent_len,
958                                         rdata->poly_normals, rdata->loop_normals,
959                                         rdata->orco,
960                                         &rdata->cd.output.ldata, bm->totloop,
961                                         &rdata->cd.output.tangent_mask);
962                         }
963                         else {
964 #undef me
965
966                                 if (is_auto_smooth && rdata->loop_normals == NULL) {
967                                         /* Should we store the previous array of `loop_normals` in CustomData? */
968                                         mesh_render_calc_normals_loop_and_poly(me, split_angle, rdata);
969                                 }
970
971                                 bool calc_active_tangent = false;
972
973                                 BKE_mesh_calc_loop_tangent_ex(
974                                         me->mvert,
975                                         me->mpoly, me->totpoly,
976                                         me->mloop,
977                                         rdata->mlooptri, rdata->tri_len,
978                                         cd_ldata,
979                                         calc_active_tangent,
980                                         tangent_names, actual_tangent_len,
981                                         rdata->poly_normals, rdata->loop_normals,
982                                         rdata->orco,
983                                         &rdata->cd.output.ldata, me->totloop,
984                                         &rdata->cd.output.tangent_mask);
985
986                                         /* If we store tangents in the mesh, set temporary. */
987 #if 0
988                                 CustomData_set_layer_flag(cd_ldata, CD_TANGENT, CD_FLAG_TEMPORARY);
989 #endif
990
991 #define me DONT_USE_THIS
992 #ifdef  me /* quiet warning */
993 #endif
994                         }
995
996                         /* End tangent calculation */
997                         /* -------------------------------------------------------------------- */
998
999                         BLI_assert(CustomData_number_of_layers(&rdata->cd.output.ldata, CD_TANGENT) == rdata->cd.layers.tangent_len);
1000
1001                         int i_dst = 0;
1002                         for (int i_src = 0; i_src < cd_layers_src.uv_len; i_src++, i_dst++) {
1003                                 if ((cd_lused[CD_TANGENT] & (1 << i_src)) == 0) {
1004                                         i_dst--;
1005                                         if (rdata->cd.layers.tangent_active >= i_src) {
1006                                                 rdata->cd.layers.tangent_active--;
1007                                         }
1008                                 }
1009                                 else {
1010                                         const char *name = CustomData_get_layer_name(cd_ldata, CD_MLOOPUV, i_src);
1011                                         uint hash = BLI_ghashutil_strhash_p(name);
1012
1013                                         BLI_snprintf(rdata->cd.uuid.tangent[i_dst], sizeof(*rdata->cd.uuid.tangent), "t%u", hash);
1014
1015                                         /* Done adding tangents. */
1016
1017                                         /* note: BKE_editmesh_loop_tangent_calc calculates 'CD_TANGENT',
1018                                          * not 'CD_MLOOPTANGENT' (as done below). It's OK, they're compatible. */
1019
1020                                         /* note: normally we'd use 'i_src' here, but 'i_dst' is in sync with 'rdata->cd.output' */
1021                                         rdata->cd.layers.tangent[i_dst] = CustomData_get_layer_n(&rdata->cd.output.ldata, CD_TANGENT, i_dst);
1022                                         if (rdata->tri_len != 0) {
1023                                                 BLI_assert(rdata->cd.layers.tangent[i_dst] != NULL);
1024                                         }
1025                                 }
1026                         }
1027                         if (cd_lused[CD_TANGENT] & DM_TANGENT_MASK_ORCO) {
1028                                 const char *name = CustomData_get_layer_name(&rdata->cd.output.ldata, CD_TANGENT, i_dst);
1029                                 uint hash = BLI_ghashutil_strhash_p(name);
1030                                 BLI_snprintf(rdata->cd.uuid.tangent[i_dst], sizeof(*rdata->cd.uuid.tangent), "t%u", hash);
1031
1032                                 rdata->cd.layers.tangent[i_dst] = CustomData_get_layer_n(&rdata->cd.output.ldata, CD_TANGENT, i_dst);
1033                         }
1034                 }
1035
1036 #undef me
1037         }
1038
1039         return rdata;
1040 }
1041
1042 /* Warning replace mesh pointer. */
1043 #define MBC_GET_FINAL_MESH(me) \
1044         /* Hack to show the final result. */ \
1045         const bool _use_em_final = ( \
1046                 (me)->edit_btmesh && \
1047                 (me)->edit_btmesh->mesh_eval_final && \
1048                 ((me)->edit_btmesh->mesh_eval_final->runtime.is_original == false)); \
1049         Mesh _me_fake; \
1050         if (_use_em_final) { \
1051                 _me_fake = *(me)->edit_btmesh->mesh_eval_final; \
1052                 _me_fake.mat = (me)->mat; \
1053                 _me_fake.totcol = (me)->totcol; \
1054                 (me) = &_me_fake; \
1055         } ((void)0)
1056
1057 static void mesh_render_data_free(MeshRenderData *rdata)
1058 {
1059         if (rdata->is_orco_allocated) {
1060                 MEM_SAFE_FREE(rdata->orco);
1061         }
1062         MEM_SAFE_FREE(rdata->cd.offset.uv);
1063         MEM_SAFE_FREE(rdata->cd.offset.vcol);
1064         MEM_SAFE_FREE(rdata->cd.uuid.auto_mix);
1065         MEM_SAFE_FREE(rdata->cd.uuid.uv);
1066         MEM_SAFE_FREE(rdata->cd.uuid.vcol);
1067         MEM_SAFE_FREE(rdata->cd.uuid.tangent);
1068         MEM_SAFE_FREE(rdata->cd.layers.uv);
1069         MEM_SAFE_FREE(rdata->cd.layers.vcol);
1070         MEM_SAFE_FREE(rdata->cd.layers.tangent);
1071         MEM_SAFE_FREE(rdata->cd.layers.auto_vcol);
1072         MEM_SAFE_FREE(rdata->loose_verts);
1073         MEM_SAFE_FREE(rdata->loose_edges);
1074         MEM_SAFE_FREE(rdata->edges_adjacent_polys);
1075         MEM_SAFE_FREE(rdata->mlooptri);
1076         MEM_SAFE_FREE(rdata->loop_normals);
1077         MEM_SAFE_FREE(rdata->poly_normals);
1078         MEM_SAFE_FREE(rdata->poly_normals_pack);
1079         MEM_SAFE_FREE(rdata->vert_normals_pack);
1080         MEM_SAFE_FREE(rdata->vert_weight);
1081         MEM_SAFE_FREE(rdata->edge_select_bool);
1082         MEM_SAFE_FREE(rdata->edge_visible_bool);
1083         MEM_SAFE_FREE(rdata->vert_color);
1084
1085         MEM_SAFE_FREE(rdata->mapped.loose_verts);
1086         MEM_SAFE_FREE(rdata->mapped.loose_edges);
1087
1088         CustomData_free(&rdata->cd.output.ldata, rdata->loop_len);
1089
1090         MEM_freeN(rdata);
1091 }
1092
1093 static MeshRenderData *mesh_render_data_create(Mesh *me, const int types)
1094 {
1095         return mesh_render_data_create_ex(me, types, NULL, NULL);
1096 }
1097
1098 /** \} */
1099
1100 /* ---------------------------------------------------------------------- */
1101
1102 /** \name Accessor Functions
1103  * \{ */
1104
1105 static const char *mesh_render_data_uv_auto_layer_uuid_get(const MeshRenderData *rdata, int layer)
1106 {
1107         BLI_assert(rdata->types & MR_DATATYPE_SHADING);
1108         return rdata->cd.uuid.auto_mix[layer];
1109 }
1110
1111 static const char *mesh_render_data_vcol_auto_layer_uuid_get(const MeshRenderData *rdata, int layer)
1112 {
1113         BLI_assert(rdata->types & MR_DATATYPE_SHADING);
1114         return rdata->cd.uuid.auto_mix[rdata->cd.layers.uv_len + layer];
1115 }
1116
1117 static const char *mesh_render_data_uv_layer_uuid_get(const MeshRenderData *rdata, int layer)
1118 {
1119         BLI_assert(rdata->types & MR_DATATYPE_SHADING);
1120         return rdata->cd.uuid.uv[layer];
1121 }
1122
1123 static const char *mesh_render_data_vcol_layer_uuid_get(const MeshRenderData *rdata, int layer)
1124 {
1125         BLI_assert(rdata->types & MR_DATATYPE_SHADING);
1126         return rdata->cd.uuid.vcol[layer];
1127 }
1128
1129 static const char *mesh_render_data_tangent_layer_uuid_get(const MeshRenderData *rdata, int layer)
1130 {
1131         BLI_assert(rdata->types & MR_DATATYPE_SHADING);
1132         return rdata->cd.uuid.tangent[layer];
1133 }
1134
1135 static int mesh_render_data_verts_len_get(const MeshRenderData *rdata)
1136 {
1137         BLI_assert(rdata->types & MR_DATATYPE_VERT);
1138         return rdata->vert_len;
1139 }
1140 static int mesh_render_data_verts_len_get_maybe_mapped(const MeshRenderData *rdata)
1141 {
1142         BLI_assert(rdata->types & MR_DATATYPE_VERT);
1143         return ((rdata->mapped.use == false) ? rdata->vert_len : rdata->mapped.vert_len);
1144 }
1145
1146 static int UNUSED_FUNCTION(mesh_render_data_loose_verts_len_get)(const MeshRenderData *rdata)
1147 {
1148         BLI_assert(rdata->types & MR_DATATYPE_OVERLAY);
1149         return rdata->loose_vert_len;
1150 }
1151 static int mesh_render_data_loose_verts_len_get_maybe_mapped(const MeshRenderData *rdata)
1152 {
1153         BLI_assert(rdata->types & MR_DATATYPE_OVERLAY);
1154         return ((rdata->mapped.use == false) ? rdata->loose_vert_len : rdata->mapped.loose_vert_len);
1155 }
1156
1157 static int mesh_render_data_edges_len_get(const MeshRenderData *rdata)
1158 {
1159         BLI_assert(rdata->types & MR_DATATYPE_EDGE);
1160         return rdata->edge_len;
1161 }
1162 static int mesh_render_data_edges_len_get_maybe_mapped(const MeshRenderData *rdata)
1163 {
1164         BLI_assert(rdata->types & MR_DATATYPE_EDGE);
1165         return ((rdata->mapped.use == false) ? rdata->edge_len : rdata->mapped.edge_len);
1166 }
1167
1168 static int UNUSED_FUNCTION(mesh_render_data_loose_edges_len_get)(const MeshRenderData *rdata)
1169 {
1170         BLI_assert(rdata->types & MR_DATATYPE_OVERLAY);
1171         return rdata->loose_edge_len;
1172 }
1173 static int mesh_render_data_loose_edges_len_get_maybe_mapped(const MeshRenderData *rdata)
1174 {
1175         BLI_assert(rdata->types & MR_DATATYPE_OVERLAY);
1176         return ((rdata->mapped.use == false) ? rdata->loose_edge_len : rdata->mapped.loose_edge_len);
1177 }
1178
1179 static int mesh_render_data_looptri_len_get(const MeshRenderData *rdata)
1180 {
1181         BLI_assert(rdata->types & MR_DATATYPE_LOOPTRI);
1182         return rdata->tri_len;
1183 }
1184 static int mesh_render_data_looptri_len_get_maybe_mapped(const MeshRenderData *rdata)
1185 {
1186         BLI_assert(rdata->types & MR_DATATYPE_LOOPTRI);
1187         return ((rdata->mapped.use == false) ? rdata->tri_len : rdata->mapped.tri_len);
1188 }
1189
1190 static int UNUSED_FUNCTION(mesh_render_data_mat_len_get)(const MeshRenderData *rdata)
1191 {
1192         BLI_assert(rdata->types & MR_DATATYPE_POLY);
1193         return rdata->mat_len;
1194 }
1195
1196 static int mesh_render_data_loops_len_get(const MeshRenderData *rdata)
1197 {
1198         BLI_assert(rdata->types & MR_DATATYPE_LOOP);
1199         return rdata->loop_len;
1200 }
1201
1202 static int mesh_render_data_polys_len_get(const MeshRenderData *rdata)
1203 {
1204         BLI_assert(rdata->types & MR_DATATYPE_POLY);
1205         return rdata->poly_len;
1206 }
1207 static int mesh_render_data_polys_len_get_maybe_mapped(const MeshRenderData *rdata)
1208 {
1209         BLI_assert(rdata->types & MR_DATATYPE_POLY);
1210         return ((rdata->mapped.use == false) ? rdata->poly_len : rdata->mapped.poly_len);
1211 }
1212
1213 /** \} */
1214
1215
1216 /* ---------------------------------------------------------------------- */
1217
1218 /* TODO remove prototype. */
1219 static void mesh_create_edit_facedots(MeshRenderData *rdata, GPUVertBuf *vbo_pos_nor_data_facedots);
1220
1221 /** \name Internal Cache (Lazy Initialization)
1222  * \{ */
1223
1224 /** Ensure #MeshRenderData.poly_normals_pack */
1225 static void mesh_render_data_ensure_poly_normals_pack(MeshRenderData *rdata)
1226 {
1227         GPUPackedNormal *pnors_pack = rdata->poly_normals_pack;
1228         if (pnors_pack == NULL) {
1229                 if (rdata->edit_bmesh) {
1230                         BMesh *bm = rdata->edit_bmesh->bm;
1231                         BMIter fiter;
1232                         BMFace *efa;
1233                         int i;
1234
1235                         pnors_pack = rdata->poly_normals_pack = MEM_mallocN(sizeof(*pnors_pack) * rdata->poly_len, __func__);
1236                         if (rdata->edit_data && rdata->edit_data->vertexCos != NULL) {
1237                                 BKE_editmesh_cache_ensure_poly_normals(rdata->edit_bmesh, rdata->edit_data);
1238                                 const float (*pnors)[3] = rdata->edit_data->polyNos;
1239                                 for (i = 0; i < bm->totface; i++) {
1240                                         pnors_pack[i] = GPU_normal_convert_i10_v3(pnors[i]);
1241                                 }
1242                         }
1243                         else {
1244                                 BM_ITER_MESH_INDEX(efa, &fiter, bm, BM_FACES_OF_MESH, i) {
1245                                         pnors_pack[i] = GPU_normal_convert_i10_v3(efa->no);
1246                                 }
1247                         }
1248                 }
1249                 else {
1250                         float (*pnors)[3] = rdata->poly_normals;
1251
1252                         if (!pnors) {
1253                                 pnors = rdata->poly_normals = MEM_mallocN(sizeof(*pnors) * rdata->poly_len, __func__);
1254                                 BKE_mesh_calc_normals_poly(
1255                                         rdata->mvert, NULL, rdata->vert_len,
1256                                         rdata->mloop, rdata->mpoly, rdata->loop_len, rdata->poly_len, pnors, true);
1257                         }
1258
1259                         pnors_pack = rdata->poly_normals_pack = MEM_mallocN(sizeof(*pnors_pack) * rdata->poly_len, __func__);
1260                         for (int i = 0; i < rdata->poly_len; i++) {
1261                                 pnors_pack[i] = GPU_normal_convert_i10_v3(pnors[i]);
1262                         }
1263                 }
1264         }
1265 }
1266
1267 /** Ensure #MeshRenderData.vert_normals_pack */
1268 static void mesh_render_data_ensure_vert_normals_pack(MeshRenderData *rdata)
1269 {
1270         GPUPackedNormal *vnors_pack = rdata->vert_normals_pack;
1271         if (vnors_pack == NULL) {
1272                 if (rdata->edit_bmesh) {
1273                         BMesh *bm = rdata->edit_bmesh->bm;
1274                         BMIter viter;
1275                         BMVert *eve;
1276                         int i;
1277
1278                         vnors_pack = rdata->vert_normals_pack = MEM_mallocN(sizeof(*vnors_pack) * rdata->vert_len, __func__);
1279                         BM_ITER_MESH_INDEX(eve, &viter, bm, BM_VERT, i) {
1280                                 vnors_pack[i] = GPU_normal_convert_i10_v3(eve->no);
1281                         }
1282                 }
1283                 else {
1284                         /* data from mesh used directly */
1285                         BLI_assert(0);
1286                 }
1287         }
1288 }
1289
1290
1291 /** Ensure #MeshRenderData.vert_color */
1292 static void mesh_render_data_ensure_vert_color(MeshRenderData *rdata)
1293 {
1294         char (*vcol)[3] = rdata->vert_color;
1295         if (vcol == NULL) {
1296                 if (rdata->edit_bmesh) {
1297                         BMesh *bm = rdata->edit_bmesh->bm;
1298                         const int cd_loop_color_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPCOL);
1299                         if (cd_loop_color_offset == -1) {
1300                                 goto fallback;
1301                         }
1302
1303                         vcol = rdata->vert_color = MEM_mallocN(sizeof(*vcol) * rdata->loop_len, __func__);
1304
1305                         BMIter fiter;
1306                         BMFace *efa;
1307                         int i = 0;
1308
1309                         BM_ITER_MESH(efa, &fiter, bm, BM_FACES_OF_MESH) {
1310                                 BMLoop *l_iter, *l_first;
1311                                 l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
1312                                 do {
1313                                         const MLoopCol *lcol = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_color_offset);
1314                                         vcol[i][0] = lcol->r;
1315                                         vcol[i][1] = lcol->g;
1316                                         vcol[i][2] = lcol->b;
1317                                         i += 1;
1318                                 } while ((l_iter = l_iter->next) != l_first);
1319                         }
1320                         BLI_assert(i == rdata->loop_len);
1321                 }
1322                 else {
1323                         if (rdata->mloopcol == NULL) {
1324                                 goto fallback;
1325                         }
1326
1327                         vcol = rdata->vert_color = MEM_mallocN(sizeof(*vcol) * rdata->loop_len, __func__);
1328
1329                         for (int i = 0; i < rdata->loop_len; i++) {
1330                                 vcol[i][0] = rdata->mloopcol[i].r;
1331                                 vcol[i][1] = rdata->mloopcol[i].g;
1332                                 vcol[i][2] = rdata->mloopcol[i].b;
1333                         }
1334                 }
1335         }
1336         return;
1337
1338 fallback:
1339         vcol = rdata->vert_color = MEM_mallocN(sizeof(*vcol) * rdata->loop_len, __func__);
1340
1341         for (int i = 0; i < rdata->loop_len; i++) {
1342                 vcol[i][0] = 255;
1343                 vcol[i][1] = 255;
1344                 vcol[i][2] = 255;
1345         }
1346 }
1347
1348 static float evaluate_vertex_weight(const MDeformVert *dvert, const struct DRW_MeshWeightState *wstate)
1349 {
1350         float input = 0.0f;
1351         bool show_alert_color = false;
1352
1353         if (wstate->flags & DRW_MESH_WEIGHT_STATE_MULTIPAINT) {
1354                 /* Multi-Paint feature */
1355                 input = BKE_defvert_multipaint_collective_weight(
1356                         dvert, wstate->defgroup_len, wstate->defgroup_sel, wstate->defgroup_sel_count,
1357                         (wstate->flags & DRW_MESH_WEIGHT_STATE_AUTO_NORMALIZE) != 0);
1358
1359                 /* make it black if the selected groups have no weight on a vertex */
1360                 if (input == 0.0f) {
1361                         show_alert_color = true;
1362                 }
1363         }
1364         else {
1365                 /* default, non tricky behavior */
1366                 input = defvert_find_weight(dvert, wstate->defgroup_active);
1367
1368                 if (input == 0.0f) {
1369                         switch (wstate->alert_mode) {
1370                                 case OB_DRAW_GROUPUSER_ACTIVE:
1371                                         show_alert_color = true;
1372                                         break;
1373
1374                                 case OB_DRAW_GROUPUSER_ALL:
1375                                         show_alert_color = defvert_is_weight_zero(dvert, wstate->defgroup_len);
1376                                         break;
1377                         }
1378                 }
1379         }
1380
1381         if (show_alert_color) {
1382                 return -1.0f;
1383         }
1384         else {
1385                 CLAMP(input, 0.0f, 1.0f);
1386                 return input;
1387         }
1388 }
1389
1390 /** Ensure #MeshRenderData.vert_weight */
1391 static void mesh_render_data_ensure_vert_weight(MeshRenderData *rdata, const struct DRW_MeshWeightState *wstate)
1392 {
1393         float (*vweight) = rdata->vert_weight;
1394         if (vweight == NULL) {
1395                 if (wstate->defgroup_active == -1) {
1396                         goto fallback;
1397                 }
1398
1399                 if (rdata->edit_bmesh) {
1400                         BMesh *bm = rdata->edit_bmesh->bm;
1401                         const int cd_dvert_offset = CustomData_get_offset(&bm->vdata, CD_MDEFORMVERT);
1402                         if (cd_dvert_offset == -1) {
1403                                 goto fallback;
1404                         }
1405
1406                         BMIter viter;
1407                         BMVert *eve;
1408                         int i;
1409
1410                         vweight = rdata->vert_weight = MEM_mallocN(sizeof(*vweight) * rdata->vert_len, __func__);
1411                         BM_ITER_MESH_INDEX(eve, &viter, bm, BM_VERT, i) {
1412                                 const MDeformVert *dvert = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
1413                                 vweight[i] = evaluate_vertex_weight(dvert, wstate);
1414                         }
1415                 }
1416                 else {
1417                         if (rdata->dvert == NULL) {
1418                                 goto fallback;
1419                         }
1420
1421                         vweight = rdata->vert_weight = MEM_mallocN(sizeof(*vweight) * rdata->vert_len, __func__);
1422                         for (int i = 0; i < rdata->vert_len; i++) {
1423                                 vweight[i] = evaluate_vertex_weight(&rdata->dvert[i], wstate);
1424                         }
1425                 }
1426         }
1427         return;
1428
1429 fallback:
1430         vweight = rdata->vert_weight = MEM_callocN(sizeof(*vweight) * rdata->vert_len, __func__);
1431
1432         if ((wstate->defgroup_active < 0) && (wstate->defgroup_len > 0)) {
1433                 copy_vn_fl(vweight, rdata->vert_len, -2.0f);
1434         }
1435         else if (wstate->alert_mode != OB_DRAW_GROUPUSER_NONE) {
1436                 copy_vn_fl(vweight, rdata->vert_len, -1.0f);
1437         }
1438 }
1439
1440 /** \} */
1441
1442 /* ---------------------------------------------------------------------- */
1443
1444 /** \name Internal Cache Generation
1445  * \{ */
1446
1447 static bool mesh_render_data_edge_vcos_manifold_pnors(
1448         MeshRenderData *rdata, const int edge_index,
1449         float **r_vco1, float **r_vco2, float **r_pnor1, float **r_pnor2, bool *r_is_manifold)
1450 {
1451         BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
1452
1453         if (rdata->edit_bmesh) {
1454                 BMesh *bm = rdata->edit_bmesh->bm;
1455                 BMEdge *eed = BM_edge_at_index(bm, edge_index);
1456                 if (BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
1457                         return false;
1458                 }
1459                 *r_vco1 = eed->v1->co;
1460                 *r_vco2 = eed->v2->co;
1461                 if (BM_edge_is_manifold(eed)) {
1462                         *r_pnor1 = eed->l->f->no;
1463                         *r_pnor2 = eed->l->radial_next->f->no;
1464                         *r_is_manifold = true;
1465                 }
1466                 else if (eed->l != NULL) {
1467                         *r_pnor1 = eed->l->f->no;
1468                         *r_pnor2 = eed->l->f->no;
1469                         *r_is_manifold = false;
1470                 }
1471                 else {
1472                         *r_pnor1 = eed->v1->no;
1473                         *r_pnor2 = eed->v1->no;
1474                         *r_is_manifold = false;
1475                 }
1476         }
1477         else {
1478                 MVert *mvert = rdata->mvert;
1479                 const MEdge *medge = rdata->medge;
1480                 EdgeAdjacentPolys *eap = rdata->edges_adjacent_polys;
1481                 float (*pnors)[3] = rdata->poly_normals;
1482
1483                 if (!eap) {
1484                         const MLoop *mloop = rdata->mloop;
1485                         const MPoly *mpoly = rdata->mpoly;
1486                         const int poly_len = rdata->poly_len;
1487                         const bool do_pnors = (poly_len != 0 && pnors == NULL);
1488
1489                         eap = rdata->edges_adjacent_polys = MEM_mallocN(sizeof(*eap) * rdata->edge_len, __func__);
1490                         for (int i = 0; i < rdata->edge_len; i++) {
1491                                 eap[i].count = 0;
1492                                 eap[i].face_index[0] = -1;
1493                                 eap[i].face_index[1] = -1;
1494                         }
1495                         if (do_pnors) {
1496                                 pnors = rdata->poly_normals = MEM_mallocN(sizeof(*pnors) * poly_len, __func__);
1497                         }
1498
1499                         for (int i = 0; i < poly_len; i++, mpoly++) {
1500                                 if (do_pnors) {
1501                                         BKE_mesh_calc_poly_normal(mpoly, mloop + mpoly->loopstart, mvert, pnors[i]);
1502                                 }
1503
1504                                 const int loopend = mpoly->loopstart + mpoly->totloop;
1505                                 for (int j = mpoly->loopstart; j < loopend; j++) {
1506                                         const int edge_idx = mloop[j].e;
1507                                         if (eap[edge_idx].count < 2) {
1508                                                 eap[edge_idx].face_index[eap[edge_idx].count] = i;
1509                                         }
1510                                         eap[edge_idx].count++;
1511                                 }
1512                         }
1513                 }
1514                 BLI_assert(eap && (rdata->poly_len == 0 || pnors != NULL));
1515
1516                 *r_vco1 = mvert[medge[edge_index].v1].co;
1517                 *r_vco2 = mvert[medge[edge_index].v2].co;
1518                 if (eap[edge_index].face_index[0] == -1) {
1519                         /* Edge has no poly... */
1520                         *r_pnor1 = *r_pnor2 = mvert[medge[edge_index].v1].co; /* XXX mvert.no are shorts... :( */
1521                         *r_is_manifold = false;
1522                 }
1523                 else {
1524                         *r_pnor1 = pnors[eap[edge_index].face_index[0]];
1525
1526                         float nor[3], v1[3], v2[3], r_center[3];
1527                         const MPoly *mpoly = rdata->mpoly + eap[edge_index].face_index[0];
1528                         const MLoop *mloop = rdata->mloop + mpoly->loopstart;
1529
1530                         BKE_mesh_calc_poly_center(mpoly, mloop, mvert, r_center);
1531                         sub_v3_v3v3(v1, *r_vco2, *r_vco1);
1532                         sub_v3_v3v3(v2, r_center, *r_vco1);
1533                         cross_v3_v3v3(nor, v1, v2);
1534
1535                         if (dot_v3v3(nor, *r_pnor1) < 0.0) {
1536                                 SWAP(float *, *r_vco1, *r_vco2);
1537                         }
1538
1539                         if (eap[edge_index].count == 2) {
1540                                 BLI_assert(eap[edge_index].face_index[1] >= 0);
1541                                 *r_pnor2 = pnors[eap[edge_index].face_index[1]];
1542                                 *r_is_manifold = true;
1543                         }
1544                         else {
1545                                 *r_pnor2 = pnors[eap[edge_index].face_index[0]];
1546                                 *r_is_manifold = false;
1547                         }
1548                 }
1549         }
1550
1551         return true;
1552 }
1553
1554 static uchar mesh_render_data_looptri_flag(MeshRenderData *rdata, const BMFace *efa)
1555 {
1556         uchar fflag = 0;
1557
1558         if (efa == rdata->efa_act)
1559                 fflag |= VFLAG_FACE_ACTIVE;
1560
1561         if (BM_elem_flag_test(efa, BM_ELEM_SELECT))
1562                 fflag |= VFLAG_FACE_SELECTED;
1563
1564 #ifdef WITH_FREESTYLE
1565         if (rdata->cd.offset.freestyle_face != -1) {
1566                 const FreestyleFace *ffa = BM_ELEM_CD_GET_VOID_P(efa, rdata->cd.offset.freestyle_face);
1567                 if (ffa->flag & FREESTYLE_FACE_MARK) {
1568                         fflag |= VFLAG_FACE_FREESTYLE;
1569                 }
1570         }
1571 #endif
1572
1573         return fflag;
1574 }
1575
1576 static void mesh_render_data_edge_flag(
1577         const MeshRenderData *rdata, const BMEdge *eed,
1578         EdgeDrawAttr *eattr)
1579 {
1580         eattr->e_flag |= VFLAG_EDGE_EXISTS;
1581
1582         if (eed == rdata->eed_act)
1583                 eattr->e_flag |= VFLAG_EDGE_ACTIVE;
1584
1585         if (BM_elem_flag_test(eed, BM_ELEM_SELECT))
1586                 eattr->e_flag |= VFLAG_EDGE_SELECTED;
1587
1588         if (BM_elem_flag_test(eed, BM_ELEM_SEAM))
1589                 eattr->e_flag |= VFLAG_EDGE_SEAM;
1590
1591         if (!BM_elem_flag_test(eed, BM_ELEM_SMOOTH))
1592                 eattr->e_flag |= VFLAG_EDGE_SHARP;
1593
1594         /* Use a byte for value range */
1595         if (rdata->cd.offset.crease != -1) {
1596                 float crease = BM_ELEM_CD_GET_FLOAT(eed, rdata->cd.offset.crease);
1597                 if (crease > 0) {
1598                         eattr->crease = (uchar)(crease * 255.0f);
1599                 }
1600         }
1601
1602         /* Use a byte for value range */
1603         if (rdata->cd.offset.bweight != -1) {
1604                 float bweight = BM_ELEM_CD_GET_FLOAT(eed, rdata->cd.offset.bweight);
1605                 if (bweight > 0) {
1606                         eattr->bweight = (uchar)(bweight * 255.0f);
1607                 }
1608         }
1609
1610 #ifdef WITH_FREESTYLE
1611         if (rdata->cd.offset.freestyle_edge != -1) {
1612                 const FreestyleEdge *fed = BM_ELEM_CD_GET_VOID_P(eed, rdata->cd.offset.freestyle_edge);
1613                 if (fed->flag & FREESTYLE_EDGE_MARK) {
1614                         eattr->e_flag |= VFLAG_EDGE_FREESTYLE;
1615                 }
1616         }
1617 #endif
1618 }
1619
1620 static uchar mesh_render_data_vertex_flag(MeshRenderData *rdata, const BMVert *eve)
1621 {
1622         uchar vflag = VFLAG_VERTEX_EXISTS;
1623
1624         /* Current vertex */
1625         if (eve == rdata->eve_act)
1626                 vflag |= VFLAG_VERTEX_ACTIVE;
1627
1628         if (BM_elem_flag_test(eve, BM_ELEM_SELECT))
1629                 vflag |= VFLAG_VERTEX_SELECTED;
1630
1631         return vflag;
1632 }
1633
1634 static void add_edit_tri(
1635         MeshRenderData *rdata, GPUVertBuf *vbo_pos_nor, GPUVertBuf *vbo_lnor, GPUVertBuf *vbo_data, GPUIndexBufBuilder *elb,
1636         const uint pos_id, const uint vnor_id, const uint lnor_id, const uint data_id,
1637         const BMLoop **bm_looptri, const int base_vert_idx)
1638 {
1639         uchar fflag;
1640         uchar vflag;
1641
1642         /* Only draw vertices once. */
1643         if (elb) {
1644                 for (int i = 0; i < 3; ++i) {
1645                         if (!BM_elem_flag_test(bm_looptri[i]->v, BM_ELEM_TAG)) {
1646                                 BM_elem_flag_enable(bm_looptri[i]->v, BM_ELEM_TAG);
1647                                 GPU_indexbuf_add_generic_vert(elb, base_vert_idx + i);
1648                         }
1649                 }
1650         }
1651
1652         if (vbo_pos_nor) {
1653                 /* TODO(sybren): deduplicate this and all the other places it's pasted to in this file. */
1654                 if (rdata->edit_data && rdata->edit_data->vertexCos) {
1655                         for (uint i = 0; i < 3; i++) {
1656                                 int vidx = BM_elem_index_get(bm_looptri[i]->v);
1657                                 const float *pos = rdata->edit_data->vertexCos[vidx];
1658                                 GPU_vertbuf_attr_set(vbo_pos_nor, pos_id, base_vert_idx + i, pos);
1659                         }
1660                 }
1661                 else {
1662                         for (uint i = 0; i < 3; i++) {
1663                                 const float *pos = bm_looptri[i]->v->co;
1664                                 GPU_vertbuf_attr_set(vbo_pos_nor, pos_id, base_vert_idx + i, pos);
1665                         }
1666                 }
1667
1668                 for (uint i = 0; i < 3; i++) {
1669                         GPUPackedNormal vnor = GPU_normal_convert_i10_v3(bm_looptri[i]->v->no);
1670                         GPU_vertbuf_attr_set(vbo_pos_nor, vnor_id, base_vert_idx + i, &vnor);
1671                 }
1672         }
1673
1674         if (vbo_lnor) {
1675                 float (*lnors)[3] = rdata->loop_normals;
1676                 for (uint i = 0; i < 3; i++) {
1677                         const float *nor = (lnors) ? lnors[BM_elem_index_get(bm_looptri[i])] : bm_looptri[0]->f->no;
1678                         GPUPackedNormal lnor = GPU_normal_convert_i10_v3(nor);
1679                         GPU_vertbuf_attr_set(vbo_lnor, lnor_id, base_vert_idx + i, &lnor);
1680                 }
1681         }
1682
1683         if (vbo_data) {
1684                 fflag = mesh_render_data_looptri_flag(rdata, bm_looptri[0]->f);
1685                 for (uint i = 0; i < 3; i++) {
1686                         const int i_next = (i + 1) % 3;
1687                         const int i_prev = (i + 2) % 3;
1688                         vflag = mesh_render_data_vertex_flag(rdata, bm_looptri[i]->v);
1689                         /* Opposite edge to the vertex at 'i'. */
1690                         EdgeDrawAttr eattr = {0};
1691                         const bool is_edge_real = (bm_looptri[i_next] == bm_looptri[i_prev]->prev);
1692                         if (is_edge_real) {
1693                                 mesh_render_data_edge_flag(rdata, bm_looptri[i_next]->e, &eattr);
1694                         }
1695                         eattr.v_flag = fflag | vflag;
1696                         GPU_vertbuf_attr_set(vbo_data, data_id, base_vert_idx + i, &eattr);
1697                 }
1698         }
1699 }
1700 static bool add_edit_tri_mapped(
1701         MeshRenderData *rdata, GPUVertBuf *vbo_pos_nor, GPUVertBuf *vbo_lnor, GPUVertBuf *vbo_data, GPUIndexBufBuilder *elb,
1702         const uint pos_id, const uint vnor_id, const uint lnor_id, const uint data_id,
1703         BMFace *efa, const MLoopTri *mlt, const float (*poly_normals)[3], const float (*loop_normals)[3], const int base_vert_idx)
1704 {
1705         if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
1706                 return false;
1707         }
1708
1709         BMEditMesh *embm = rdata->edit_bmesh;
1710         BMesh *bm = embm->bm;
1711         Mesh *me_cage = embm->mesh_eval_cage;
1712
1713         const MVert *mvert = me_cage->mvert;
1714         const MEdge *medge = me_cage->medge;
1715         const MLoop *mloop = me_cage->mloop;
1716
1717         const int *v_origindex = rdata->mapped.v_origindex;
1718         const int *e_origindex = rdata->mapped.e_origindex;
1719
1720         if (elb) {
1721                 for (int i = 0; i < 3; ++i) {
1722                         const int v_orig = v_origindex[mloop[mlt->tri[i]].v];
1723                         if (v_orig == ORIGINDEX_NONE) {
1724                                 continue;
1725                         }
1726                         BMVert *v = BM_vert_at_index(bm, v_orig);
1727                         if (!BM_elem_flag_test(v, BM_ELEM_TAG)) {
1728                                 BM_elem_flag_enable(v, BM_ELEM_TAG);
1729                                 GPU_indexbuf_add_generic_vert(elb, base_vert_idx + i);
1730                         }
1731                 }
1732         }
1733
1734         if (vbo_pos_nor) {
1735                 for (uint i = 0; i < 3; i++) {
1736                         const float *pos = mvert[mloop[mlt->tri[i]].v].co;
1737                         GPUPackedNormal vnor = GPU_normal_convert_i10_s3(mvert[mloop[mlt->tri[i]].v].no);
1738                         GPU_vertbuf_attr_set(vbo_pos_nor, pos_id, base_vert_idx + i, pos);
1739                         GPU_vertbuf_attr_set(vbo_pos_nor, vnor_id, base_vert_idx + i, &vnor);
1740                 }
1741         }
1742
1743         if (vbo_lnor) {
1744                 for (uint i = 0; i < 3; i++) {
1745                         const float *nor = loop_normals ? loop_normals[mlt->tri[i]] : poly_normals[mlt->poly];
1746                         GPUPackedNormal lnor = GPU_normal_convert_i10_v3(nor);
1747                         GPU_vertbuf_attr_set(vbo_lnor, lnor_id, base_vert_idx + i, &lnor);
1748                 }
1749         }
1750
1751         if (vbo_data) {
1752                 EdgeDrawAttr eattr[3] = {{0}}; /* Importantly VFLAG_VERTEX_EXISTS is not set. */
1753                 uchar fflag = mesh_render_data_looptri_flag(rdata, efa);
1754                 for (uint i = 0; i < 3; i++) {
1755                         const int i_next = (i + 1) % 3;
1756                         const int i_prev = (i + 2) % 3;
1757                         const int v_orig = v_origindex[mloop[mlt->tri[i]].v];
1758                         if (v_orig != ORIGINDEX_NONE) {
1759                                 BMVert *v = BM_vert_at_index(bm, v_orig);
1760                                 eattr[i].v_flag |= mesh_render_data_vertex_flag(rdata, v);
1761                         }
1762                         /* Opposite edge to the vertex at 'i'. */
1763                         const int e_idx = mloop[mlt->tri[i_next]].e;
1764                         const int e_orig = e_origindex[e_idx];
1765                         if (e_orig != ORIGINDEX_NONE) {
1766                                 const MEdge *ed = &medge[e_idx];
1767                                 const uint tri_edge[2]  = {mloop[mlt->tri[i_prev]].v, mloop[mlt->tri[i_next]].v};
1768                                 const bool is_edge_real = (
1769                                         ((ed->v1 == tri_edge[0]) && (ed->v2 == tri_edge[1])) ||
1770                                         ((ed->v1 == tri_edge[1]) && (ed->v2 == tri_edge[0])));
1771                                 if (is_edge_real) {
1772                                         BMEdge *eed = BM_edge_at_index(bm, e_orig);
1773                                         mesh_render_data_edge_flag(rdata, eed, &eattr[i]);
1774                                         /* Set vertex selected if both original verts are selected. */
1775                                         if (BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) &&
1776                                             BM_elem_flag_test(eed->v2, BM_ELEM_SELECT))
1777                                         {
1778                                                 eattr[i_next].v_flag |= VFLAG_VERTEX_SELECTED;
1779                                                 eattr[i_prev].v_flag |= VFLAG_VERTEX_SELECTED;
1780                                         }
1781                                 }
1782                         }
1783                 }
1784                 for (uint i = 0; i < 3; i++) {
1785                         eattr[i].v_flag |= fflag;
1786                         GPU_vertbuf_attr_set(vbo_data, data_id, base_vert_idx + i, &eattr[i]);
1787                 }
1788         }
1789
1790         return true;
1791 }
1792
1793 static void add_edit_loose_edge(
1794         MeshRenderData *rdata, GPUVertBuf *vbo_pos_nor, GPUVertBuf *vbo_data,
1795         const uint pos_id, const uint vnor_id, const uint data_id,
1796         const BMEdge *eed, const int base_vert_idx)
1797 {
1798         if (vbo_pos_nor) {
1799                 /* TODO(sybren): deduplicate this and all the other places it's pasted to in this file. */
1800                 if (rdata->edit_data && rdata->edit_data->vertexCos) {
1801                         for (uint i = 0; i < 2; i++) {
1802                                 int vidx = BM_elem_index_get((&eed->v1)[i]);
1803                                 const float *pos = rdata->edit_data->vertexCos[vidx];
1804                                 GPU_vertbuf_attr_set(vbo_pos_nor, pos_id, base_vert_idx + i, pos);
1805                         }
1806                 }
1807                 else {
1808                         for (int i = 0; i < 2; i++) {
1809                                 const float *pos = (&eed->v1)[i]->co;
1810                                 GPU_vertbuf_attr_set(vbo_pos_nor, pos_id, base_vert_idx + i, pos);
1811                         }
1812                 }
1813
1814                 for (int i = 0; i < 2; i++) {
1815                         GPUPackedNormal vnor = GPU_normal_convert_i10_v3((&eed->v1)[i]->no);
1816                         GPU_vertbuf_attr_set(vbo_pos_nor, vnor_id, base_vert_idx + i, &vnor);
1817                 }
1818         }
1819
1820         if (vbo_data) {
1821                 EdgeDrawAttr eattr = {0};
1822                 mesh_render_data_edge_flag(rdata, eed, &eattr);
1823                 for (int i = 0; i < 2; i++) {
1824                         eattr.v_flag = mesh_render_data_vertex_flag(rdata, (&eed->v1)[i]);
1825                         GPU_vertbuf_attr_set(vbo_data, data_id, base_vert_idx + i, &eattr);
1826                 }
1827         }
1828 }
1829 static void add_edit_loose_edge_mapped(
1830         MeshRenderData *rdata, GPUVertBuf *vbo_pos_nor, GPUVertBuf *vbo_data,
1831         const uint pos_id, const uint vnor_id, const uint data_id,
1832         BMEdge *eed, const MVert *mvert, const MEdge *ed, const int base_vert_idx)
1833 {
1834         if (vbo_pos_nor) {
1835                 /* TODO(sybren): deduplicate this and all the other places it's pasted to in this file. */
1836                 for (int i = 0; i < 2; i++) {
1837                         const float *pos = mvert[*(&ed->v1 + i)].co;
1838                         GPU_vertbuf_attr_set(vbo_pos_nor, pos_id, base_vert_idx + i, pos);
1839
1840                         GPUPackedNormal vnor = GPU_normal_convert_i10_s3(mvert[*(&ed->v1 + i)].no);
1841                         GPU_vertbuf_attr_set(vbo_pos_nor, vnor_id, base_vert_idx + i, &vnor);
1842                 }
1843         }
1844
1845         if (vbo_data) {
1846                 EdgeDrawAttr eattr = {0};
1847                 mesh_render_data_edge_flag(rdata, eed, &eattr);
1848                 for (int i = 0; i < 2; i++) {
1849                         const int v_orig = rdata->mapped.v_origindex[*(&ed->v1 + i)];
1850                         eattr.v_flag = (v_orig != ORIGINDEX_NONE) ? mesh_render_data_vertex_flag(rdata, (&eed->v1)[i]) : 0;
1851                         GPU_vertbuf_attr_set(vbo_data, data_id, base_vert_idx + i, &eattr);
1852                 }
1853         }
1854 }
1855
1856 static void add_edit_loose_vert(
1857         MeshRenderData *rdata, GPUVertBuf *vbo_pos_nor, GPUVertBuf *vbo_data,
1858         const uint pos_id, const uint vnor_id, const uint data_id,
1859         const BMVert *eve, const int base_vert_idx)
1860 {
1861         if (vbo_pos_nor) {
1862                 /* TODO(sybren): deduplicate this and all the other places it's pasted to in this file. */
1863                 if (rdata->edit_data && rdata->edit_data->vertexCos) {
1864                         int vidx = BM_elem_index_get(eve);
1865                         const float *pos = rdata->edit_data->vertexCos[vidx];
1866                         GPU_vertbuf_attr_set(vbo_pos_nor, pos_id, base_vert_idx, pos);
1867                 }
1868                 else {
1869                         const float *pos = eve->co;
1870                         GPU_vertbuf_attr_set(vbo_pos_nor, pos_id, base_vert_idx, pos);
1871                 }
1872
1873                 GPUPackedNormal vnor = GPU_normal_convert_i10_v3(eve->no);
1874                 GPU_vertbuf_attr_set(vbo_pos_nor, vnor_id, base_vert_idx, &vnor);
1875         }
1876
1877         if (vbo_data) {
1878                 uchar vflag[4] = {0, 0, 0, 0};
1879                 vflag[0] = mesh_render_data_vertex_flag(rdata, eve);
1880                 GPU_vertbuf_attr_set(vbo_data, data_id, base_vert_idx, vflag);
1881         }
1882 }
1883 static void add_edit_loose_vert_mapped(
1884         MeshRenderData *rdata, GPUVertBuf *vbo_pos_nor, GPUVertBuf *vbo_data,
1885         const uint pos_id, const uint vnor_id, const uint data_id,
1886         const BMVert *eve, const MVert *mv, const int base_vert_idx)
1887 {
1888         if (vbo_pos_nor) {
1889                 const float *pos = mv->co;
1890                 GPU_vertbuf_attr_set(vbo_pos_nor, pos_id, base_vert_idx, pos);
1891
1892                 GPUPackedNormal vnor = GPU_normal_convert_i10_s3(mv->no);
1893                 GPU_vertbuf_attr_set(vbo_pos_nor, vnor_id, base_vert_idx, &vnor);
1894         }
1895
1896         if (vbo_data) {
1897                 uchar vflag[4] = {0, 0, 0, 0};
1898                 vflag[0] = mesh_render_data_vertex_flag(rdata, eve);
1899                 GPU_vertbuf_attr_set(vbo_data, data_id, base_vert_idx, vflag);
1900         }
1901 }
1902
1903 static bool add_edit_facedot(
1904         MeshRenderData *rdata, GPUVertBuf *vbo,
1905         const uint fdot_pos_id, const uint fdot_nor_flag_id,
1906         const int poly, const int base_vert_idx)
1907 {
1908         BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
1909         float pnor[3], center[3];
1910         bool selected;
1911         if (rdata->edit_bmesh) {
1912                 const BMFace *efa = BM_face_at_index(rdata->edit_bmesh->bm, poly);
1913                 if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
1914                         return false;
1915                 }
1916                 if (rdata->edit_data && rdata->edit_data->vertexCos) {
1917                         copy_v3_v3(center, rdata->edit_data->polyCos[poly]);
1918                         copy_v3_v3(pnor, rdata->edit_data->polyNos[poly]);
1919                 }
1920                 else {
1921                         BM_face_calc_center_median(efa, center);
1922                         copy_v3_v3(pnor, efa->no);
1923                 }
1924                 selected = (BM_elem_flag_test(efa, BM_ELEM_SELECT) != 0) ? true : false;
1925         }
1926         else {
1927                 MVert *mvert = rdata->mvert;
1928                 const MPoly *mpoly = rdata->mpoly + poly;
1929                 const MLoop *mloop = rdata->mloop + mpoly->loopstart;
1930
1931                 BKE_mesh_calc_poly_center(mpoly, mloop, mvert, center);
1932                 BKE_mesh_calc_poly_normal(mpoly, mloop, mvert, pnor);
1933
1934                 selected = false; /* No selection if not in edit mode */
1935         }
1936
1937         GPUPackedNormal nor = GPU_normal_convert_i10_v3(pnor);
1938         nor.w = (selected) ? 1 : 0;
1939         GPU_vertbuf_attr_set(vbo, fdot_nor_flag_id, base_vert_idx, &nor);
1940         GPU_vertbuf_attr_set(vbo, fdot_pos_id, base_vert_idx, center);
1941
1942         return true;
1943 }
1944 static bool add_edit_facedot_mapped(
1945         MeshRenderData *rdata, GPUVertBuf *vbo,
1946         const uint fdot_pos_id, const uint fdot_nor_flag_id,
1947         const int poly, const int base_vert_idx)
1948 {
1949         BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
1950         float pnor[3], center[3];
1951         const int *p_origindex = rdata->mapped.p_origindex;
1952         const int p_orig = p_origindex[poly];
1953         if (p_orig == ORIGINDEX_NONE) {
1954                 return false;
1955         }
1956         BMEditMesh *em = rdata->edit_bmesh;
1957         const BMFace *efa = BM_face_at_index(rdata->edit_bmesh->bm, p_orig);
1958         if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
1959                 return false;
1960         }
1961
1962         Mesh *me_cage = em->mesh_eval_cage;
1963         const MVert *mvert = me_cage->mvert;
1964         const MLoop *mloop = me_cage->mloop;
1965         const MPoly *mpoly = me_cage->mpoly;
1966
1967         const MPoly *mp = mpoly + poly;
1968         const MLoop *ml = mloop + mp->loopstart;
1969
1970         BKE_mesh_calc_poly_center(mp, ml, mvert, center);
1971         BKE_mesh_calc_poly_normal(mp, ml, mvert, pnor);
1972
1973         GPUPackedNormal nor = GPU_normal_convert_i10_v3(pnor);
1974         nor.w = (BM_elem_flag_test(efa, BM_ELEM_SELECT) != 0) ? 1 : 0;
1975         GPU_vertbuf_attr_set(vbo, fdot_nor_flag_id, base_vert_idx, &nor);
1976         GPU_vertbuf_attr_set(vbo, fdot_pos_id, base_vert_idx, center);
1977
1978         return true;
1979 }
1980
1981 /** \} */
1982
1983 /* ---------------------------------------------------------------------- */
1984
1985 /** \name Vertex Group Selection
1986  * \{ */
1987
1988 /** Reset the selection structure, deallocating heap memory as appropriate. */
1989 void DRW_mesh_weight_state_clear(struct DRW_MeshWeightState *wstate)
1990 {
1991         MEM_SAFE_FREE(wstate->defgroup_sel);
1992
1993         memset(wstate, 0, sizeof(*wstate));
1994
1995         wstate->defgroup_active = -1;
1996 }
1997
1998 /** Copy selection data from one structure to another, including heap memory. */
1999 void DRW_mesh_weight_state_copy(struct DRW_MeshWeightState *wstate_dst, const struct DRW_MeshWeightState *wstate_src)
2000 {
2001         MEM_SAFE_FREE(wstate_dst->defgroup_sel);
2002
2003         memcpy(wstate_dst, wstate_src, sizeof(*wstate_dst));
2004
2005         if (wstate_src->defgroup_sel) {
2006                 wstate_dst->defgroup_sel = MEM_dupallocN(wstate_src->defgroup_sel);
2007         }
2008 }
2009
2010 /** Compare two selection structures. */
2011 bool DRW_mesh_weight_state_compare(const struct DRW_MeshWeightState *a, const struct DRW_MeshWeightState *b)
2012 {
2013         return a->defgroup_active == b->defgroup_active &&
2014                a->defgroup_len == b->defgroup_len &&
2015                a->flags == b->flags &&
2016                a->alert_mode == b->alert_mode &&
2017                a->defgroup_sel_count == b->defgroup_sel_count &&
2018                ((!a->defgroup_sel && !b->defgroup_sel) ||
2019                 (a->defgroup_sel && b->defgroup_sel &&
2020                  memcmp(a->defgroup_sel, b->defgroup_sel, a->defgroup_len * sizeof(bool)) == 0));
2021 }
2022
2023 /** \} */
2024
2025 /* ---------------------------------------------------------------------- */
2026
2027 /** \name Mesh GPUBatch Cache
2028  * \{ */
2029
2030 typedef struct MeshBatchCache {
2031         /* In order buffers: All verts only specified once.
2032          * To be used with a GPUIndexBuf. */
2033         struct {
2034                 GPUVertBuf *pos_nor;
2035                 /* Specify one vertex per loop. */
2036                 GPUVertBuf *loop_pos_nor;
2037                 GPUVertBuf *loop_uv_tan;
2038                 GPUVertBuf *loop_vcol;
2039         } ordered;
2040
2041         /* Tesselated: (all verts specified for each triangles).
2042          * Indices does not match the CPU data structure's. */
2043         struct {
2044                 GPUVertBuf *pos_nor;
2045
2046                 GPUVertBuf *wireframe_data;
2047         } tess;
2048
2049         /* Edit Mesh Data:
2050          * Data is also tesselated because of barycentric wireframe rendering. */
2051         struct {
2052                 GPUVertBuf *pos_nor;
2053                 GPUVertBuf *pos_nor_ledges;
2054                 GPUVertBuf *pos_nor_lverts;
2055                 GPUVertBuf *pos_nor_data_facedots;
2056                 GPUVertBuf *data;
2057                 GPUVertBuf *data_ledges;
2058                 GPUVertBuf *data_lverts;
2059                 GPUVertBuf *lnor;
2060         } edit;
2061
2062         /* Index Buffers:
2063          * Only need to be updated when topology changes. */
2064         struct {
2065                 /* Indices to vloops. */
2066                 GPUIndexBuf *surface_tris;
2067                 GPUIndexBuf *loops_lines;
2068                 /* Contains indices to unique edit vertices to not
2069                  * draw the same vert multiple times (because of tesselation). */
2070                 GPUIndexBuf *edit_verts_points;
2071         } ibo;
2072
2073         struct {
2074                 /* Surfaces / Render */
2075                 GPUBatch *surface;
2076                 /* Edit mode */
2077                 GPUBatch *edit_triangles;
2078                 GPUBatch *edit_vertices;
2079                 GPUBatch *edit_loose_edges;
2080                 GPUBatch *edit_loose_verts;
2081                 GPUBatch *edit_triangles_nor;
2082                 GPUBatch *edit_triangles_lnor;
2083                 GPUBatch *edit_loose_edges_nor;
2084                 GPUBatch *edit_facedots;
2085                 /* Common display / Other */
2086                 GPUBatch *all_verts;
2087                 GPUBatch *wire_loops; /* Loops around faces. */
2088                 GPUBatch *wire_triangles; /* Triangles for object mode wireframe. */
2089         } batch;
2090
2091         GPUIndexBuf **surf_per_mat_tris;
2092         GPUBatch **surf_per_mat;
2093
2094         /* OLD BATCH METHOD, thoses needs to be ported and added in the structs above. */
2095
2096         /* Indices buffers. */
2097         GPUIndexBuf *edges_in_order;
2098         GPUIndexBuf *edges_adjacency; /* Store edges with adjacent vertices. */
2099         GPUIndexBuf *triangles_in_order;
2100         GPUIndexBuf *ledges_in_order;
2101
2102         GPUBatch *all_edges;
2103         GPUBatch *all_triangles;
2104
2105         GPUVertBuf *pos_with_normals;
2106         GPUVertBuf *pos_with_normals_visible_only;
2107         GPUVertBuf *pos_with_normals_edit;
2108         GPUVertBuf *pos_with_normals_visible_only_edit;
2109         GPUVertBuf *tri_aligned_uv;  /* Active UV layer (mloopuv) */
2110
2111         /**
2112          * Other uses are all positions or loose elements.
2113          * This stores all visible elements, needed for selection.
2114          */
2115         GPUVertBuf *ed_fcenter_pos_with_nor_and_sel;
2116         GPUVertBuf *ed_edge_pos;
2117         GPUVertBuf *ed_vert_pos;
2118
2119         GPUBatch *triangles_with_normals;
2120         GPUBatch *ledges_with_normals;
2121
2122         /* Skip hidden (depending on paint select mode) */
2123         GPUBatch *triangles_with_weights;
2124         GPUBatch *triangles_with_vert_colors;
2125         /* Always skip hidden */
2126         GPUBatch *triangles_with_select_mask;
2127         GPUBatch *triangles_with_select_id;
2128         uint       triangles_with_select_id_offset;
2129
2130         GPUBatch *facedot_with_select_id;  /* shares vbo with 'edit_facedots' */
2131         GPUBatch *edges_with_select_id;
2132         GPUBatch *verts_with_select_id;
2133
2134         uint facedot_with_select_id_offset;
2135         uint edges_with_select_id_offset;
2136         uint verts_with_select_id_offset;
2137
2138         GPUBatch *points_with_normals;
2139         GPUBatch *fancy_edges; /* owns its vertex buffer (not shared) */
2140
2141         GPUBatch *edge_detection;
2142
2143         /* Texture Paint.*/
2144         /* per-texture batch */
2145         GPUBatch **texpaint_triangles;
2146         GPUBatch  *texpaint_triangles_single;
2147
2148         GPUBatch *overlay_weight_faces;
2149         GPUBatch *overlay_weight_verts;
2150         GPUBatch *overlay_paint_edges;
2151
2152         /* 2D/UV edit */
2153         GPUVertBuf *edituv_pos;
2154         GPUVertBuf *edituv_area;
2155         GPUVertBuf *edituv_angle;
2156         GPUVertBuf *edituv_data;
2157
2158         GPUIndexBuf *edituv_visible_faces;
2159         GPUIndexBuf *edituv_visible_edges;
2160
2161         GPUBatch *texpaint_uv_loops;
2162
2163         GPUBatch *edituv_faces_strech_area;
2164         GPUBatch *edituv_faces_strech_angle;
2165         GPUBatch *edituv_faces;
2166         GPUBatch *edituv_edges;
2167         GPUBatch *edituv_verts;
2168         GPUBatch *edituv_facedots;
2169
2170         char edituv_state;
2171
2172         /* arrays of bool uniform names (and value) that will be use to
2173          * set srgb conversion for auto attribs.*/
2174         char *auto_layer_names;
2175         int *auto_layer_is_srgb;
2176         int auto_layer_len;
2177
2178         /* settings to determine if cache is invalid */
2179         bool is_maybe_dirty;
2180         bool is_dirty; /* Instantly invalidates cache, skipping mesh check */
2181         int edge_len;
2182         int tri_len;
2183         int poly_len;
2184         int vert_len;
2185         int mat_len;
2186         bool is_editmode;
2187
2188         struct DRW_MeshWeightState weight_state;
2189
2190         uchar cd_vused[CD_NUMTYPES];
2191         uchar cd_vneeded[CD_NUMTYPES];
2192         ushort cd_lused[CD_NUMTYPES];
2193         ushort cd_lneeded[CD_NUMTYPES];
2194
2195         /* XXX, only keep for as long as sculpt mode uses shaded drawing. */
2196         bool is_sculpt_points_tag;
2197
2198         /* Valid only if edges_adjacency is up to date. */
2199         bool is_manifold;
2200 } MeshBatchCache;
2201
2202 /* GPUBatch cache management. */
2203
2204 static bool mesh_batch_cache_valid(Mesh *me)
2205 {
2206         MeshBatchCache *cache = me->runtime.batch_cache;
2207
2208         if (cache == NULL) {
2209                 return false;
2210         }
2211
2212         if (cache->mat_len != mesh_render_mat_len_get(me)) {
2213                 return false;
2214         }
2215
2216         if (cache->is_editmode != (me->edit_btmesh != NULL)) {
2217                 return false;
2218         }
2219
2220         if (cache->is_dirty) {
2221                 return false;
2222         }
2223
2224         if (cache->is_maybe_dirty == false) {
2225                 return true;
2226         }
2227         else {
2228                 if (cache->is_editmode) {
2229                         return false;
2230                 }
2231                 else if ((cache->vert_len != mesh_render_verts_len_get(me)) ||
2232                          (cache->edge_len != mesh_render_edges_len_get(me)) ||
2233                          (cache->tri_len  != mesh_render_looptri_len_get(me)) ||
2234                          (cache->poly_len != mesh_render_polys_len_get(me)) ||
2235                          (cache->mat_len   != mesh_render_mat_len_get(me)))
2236                 {
2237                         return false;
2238                 }
2239         }
2240
2241         return true;
2242 }
2243
2244 static void mesh_batch_cache_init(Mesh *me)
2245 {
2246         MeshBatchCache *cache = me->runtime.batch_cache;
2247
2248         if (!cache) {
2249                 cache = me->runtime.batch_cache = MEM_callocN(sizeof(*cache), __func__);
2250         }
2251         else {
2252                 memset(cache, 0, sizeof(*cache));
2253         }
2254
2255         cache->is_editmode = me->edit_btmesh != NULL;
2256
2257         if (cache->is_editmode == false) {
2258                 cache->edge_len = mesh_render_edges_len_get(me);
2259                 cache->tri_len = mesh_render_looptri_len_get(me);
2260                 cache->poly_len = mesh_render_polys_len_get(me);
2261                 cache->vert_len = mesh_render_verts_len_get(me);
2262         }
2263
2264         cache->mat_len = mesh_render_mat_len_get(me);
2265         cache->surf_per_mat_tris = MEM_callocN(sizeof(*cache->surf_per_mat_tris) * cache->mat_len, __func__);
2266         cache->surf_per_mat = MEM_callocN(sizeof(*cache->surf_per_mat) * cache->mat_len, __func__);
2267
2268         /* TODO Might be wiser to alloc in one chunck. */
2269         for (int i = 0; i < cache->mat_len; ++i) {
2270                 cache->surf_per_mat_tris[i] = MEM_callocN(sizeof(GPUIndexBuf), "GPUIndexBuf");
2271                 cache->surf_per_mat[i] = MEM_callocN(sizeof(GPUBatch), "GPUBatch");
2272         }
2273
2274         cache->is_maybe_dirty = false;
2275         cache->is_dirty = false;
2276
2277         DRW_mesh_weight_state_clear(&cache->weight_state);
2278 }
2279
2280 static MeshBatchCache *mesh_batch_cache_get(Mesh *me)
2281 {
2282         if (!mesh_batch_cache_valid(me)) {
2283                 mesh_batch_cache_clear(me);
2284                 mesh_batch_cache_init(me);
2285         }
2286         return me->runtime.batch_cache;
2287 }
2288
2289 static void mesh_batch_cache_check_vertex_group(MeshBatchCache *cache, const struct DRW_MeshWeightState *wstate)
2290 {
2291         if (!DRW_mesh_weight_state_compare(&cache->weight_state, wstate)) {
2292                 GPU_BATCH_DISCARD_SAFE(cache->triangles_with_weights);
2293
2294                 DRW_mesh_weight_state_clear(&cache->weight_state);
2295         }
2296 }
2297
2298 static void mesh_batch_cache_discard_shaded_tri(MeshBatchCache *cache)
2299 {
2300         GPU_VERTBUF_DISCARD_SAFE(cache->ordered.loop_pos_nor);
2301         GPU_VERTBUF_DISCARD_SAFE(cache->ordered.loop_uv_tan);
2302         GPU_VERTBUF_DISCARD_SAFE(cache->ordered.loop_vcol);
2303         /* TODO */
2304         // GPU_VERTBUF_DISCARD_SAFE(cache->ordered.loop_orco);
2305
2306         if (cache->surf_per_mat_tris) {
2307                 for (int i = 0; i < cache->mat_len; i++) {
2308                         GPU_INDEXBUF_DISCARD_SAFE(cache->surf_per_mat_tris[i]);
2309                 }
2310         }
2311         MEM_SAFE_FREE(cache->surf_per_mat_tris);
2312         if (cache->surf_per_mat) {
2313                 for (int i = 0; i < cache->mat_len; i++) {
2314                         GPU_BATCH_DISCARD_SAFE(cache->surf_per_mat[i]);
2315                 }
2316         }
2317         MEM_SAFE_FREE(cache->surf_per_mat);
2318
2319         MEM_SAFE_FREE(cache->texpaint_triangles);
2320
2321         MEM_SAFE_FREE(cache->auto_layer_names);
2322         MEM_SAFE_FREE(cache->auto_layer_is_srgb);
2323
2324         cache->mat_len = 0;
2325 }
2326
2327 static void mesh_batch_cache_discard_uvedit(MeshBatchCache *cache)
2328 {
2329         GPU_VERTBUF_DISCARD_SAFE(cache->edituv_pos);
2330         GPU_VERTBUF_DISCARD_SAFE(cache->edituv_area);
2331         GPU_VERTBUF_DISCARD_SAFE(cache->edituv_angle);
2332         GPU_VERTBUF_DISCARD_SAFE(cache->edituv_data);
2333
2334         GPU_INDEXBUF_DISCARD_SAFE(cache->edituv_visible_faces);
2335         GPU_INDEXBUF_DISCARD_SAFE(cache->edituv_visible_edges);
2336
2337         if (cache->edituv_faces_strech_area) {
2338                 gpu_batch_presets_unregister(cache->edituv_faces_strech_area);
2339         }
2340         if (cache->edituv_faces_strech_angle) {
2341                 gpu_batch_presets_unregister(cache->edituv_faces_strech_angle);
2342         }
2343         if (cache->edituv_faces) {
2344                 gpu_batch_presets_unregister(cache->edituv_faces);
2345         }
2346         if (cache->edituv_edges) {
2347                 gpu_batch_presets_unregister(cache->edituv_edges);
2348         }
2349         if (cache->edituv_verts) {
2350                 gpu_batch_presets_unregister(cache->edituv_verts);
2351         }
2352         if (cache->edituv_facedots) {
2353                 gpu_batch_presets_unregister(cache->edituv_facedots);
2354         }
2355
2356         GPU_BATCH_DISCARD_SAFE(cache->edituv_faces_strech_area);
2357         GPU_BATCH_DISCARD_SAFE(cache->edituv_faces_strech_angle);
2358         GPU_BATCH_DISCARD_SAFE(cache->edituv_faces);
2359         GPU_BATCH_DISCARD_SAFE(cache->edituv_edges);
2360         GPU_BATCH_DISCARD_SAFE(cache->edituv_verts);
2361         GPU_BATCH_DISCARD_SAFE(cache->edituv_facedots);
2362
2363         gpu_batch_presets_unregister(cache->texpaint_uv_loops);
2364
2365         GPU_BATCH_DISCARD_SAFE(cache->texpaint_uv_loops);
2366
2367         cache->edituv_state = 0;
2368 }
2369
2370 void DRW_mesh_batch_cache_dirty_tag(Mesh *me, int mode)
2371 {
2372         MeshBatchCache *cache = me->runtime.batch_cache;
2373         if (cache == NULL) {
2374                 return;
2375         }
2376         switch (mode) {
2377                 case BKE_MESH_BATCH_DIRTY_MAYBE_ALL:
2378                         cache->is_maybe_dirty = true;
2379                         break;
2380                 case BKE_MESH_BATCH_DIRTY_SELECT:
2381                         GPU_VERTBUF_DISCARD_SAFE(cache->edit.data);
2382                         GPU_VERTBUF_DISCARD_SAFE(cache->edit.data_ledges);
2383                         GPU_VERTBUF_DISCARD_SAFE(cache->edit.data_lverts);
2384                         GPU_VERTBUF_DISCARD_SAFE(cache->edit.pos_nor_data_facedots);
2385                         GPU_BATCH_DISCARD_SAFE(cache->batch.edit_triangles);
2386                         GPU_BATCH_DISCARD_SAFE(cache->batch.edit_vertices);
2387                         GPU_BATCH_DISCARD_SAFE(cache->batch.edit_loose_verts);
2388                         GPU_BATCH_DISCARD_SAFE(cache->batch.edit_loose_edges);
2389                         GPU_BATCH_DISCARD_SAFE(cache->batch.edit_facedots);
2390                         GPU_VERTBUF_DISCARD_SAFE(cache->ed_edge_pos);
2391                         GPU_VERTBUF_DISCARD_SAFE(cache->ed_vert_pos);
2392                         /* Edit mode selection. */
2393                         GPU_BATCH_DISCARD_SAFE(cache->facedot_with_select_id);
2394                         GPU_BATCH_DISCARD_SAFE(cache->edges_with_select_id);
2395                         GPU_BATCH_DISCARD_SAFE(cache->verts_with_select_id);
2396                         /* Paint mode selection */
2397                         /* TODO only do that in paint mode. */
2398                         GPU_VERTBUF_DISCARD_SAFE(cache->ordered.loop_pos_nor);
2399                         GPU_BATCH_DISCARD_SAFE(cache->batch.surface);
2400                         GPU_BATCH_DISCARD_SAFE(cache->batch.wire_loops);
2401                         if (cache->surf_per_mat) {
2402                                 for (int i = 0; i < cache->mat_len; i++) {
2403                                         GPU_BATCH_DISCARD_SAFE(cache->surf_per_mat[i]);
2404                                 }
2405                         }
2406                         GPU_BATCH_DISCARD_SAFE(cache->overlay_paint_edges);
2407                         GPU_BATCH_DISCARD_SAFE(cache->overlay_weight_faces);
2408                         GPU_BATCH_DISCARD_SAFE(cache->overlay_weight_verts);
2409                         /* Because visible UVs depends on edit mode selection, discard everything. */
2410                         mesh_batch_cache_discard_uvedit(cache);
2411                         break;
2412                 case BKE_MESH_BATCH_DIRTY_ALL:
2413                         cache->is_dirty = true;
2414                         break;
2415                 case BKE_MESH_BATCH_DIRTY_SHADING:
2416                         mesh_batch_cache_discard_shaded_tri(cache);
2417                         mesh_batch_cache_discard_uvedit(cache);
2418                         break;
2419                 case BKE_MESH_BATCH_DIRTY_SCULPT_COORDS:
2420                         cache->is_sculpt_points_tag = true;
2421                         break;
2422                 case BKE_MESH_BATCH_DIRTY_UVEDIT_ALL:
2423                         mesh_batch_cache_discard_uvedit(cache);
2424                         break;
2425                 case BKE_MESH_BATCH_DIRTY_UVEDIT_SELECT:
2426                         /* For now same as above. */
2427                         mesh_batch_cache_discard_uvedit(cache);
2428                         break;
2429                 default:
2430                         BLI_assert(0);
2431         }
2432 }
2433
2434 /**
2435  * This only clear the batches associated to the given vertex buffer.
2436  **/
2437 static void mesh_batch_cache_clear_selective(Mesh *me, GPUVertBuf *vert)
2438 {
2439         MeshBatchCache *cache = me->runtime.batch_cache;
2440         if (!cache) {
2441                 return;
2442         }
2443
2444         BLI_assert(vert != NULL);
2445
2446         if (ELEM(vert, cache->pos_with_normals, cache->pos_with_normals_visible_only,
2447                        cache->pos_with_normals_edit, cache->pos_with_normals_visible_only_edit))
2448         {
2449                 GPU_BATCH_DISCARD_SAFE(cache->triangles_with_normals);
2450                 GPU_BATCH_DISCARD_SAFE(cache->triangles_with_weights);
2451                 GPU_BATCH_DISCARD_SAFE(cache->triangles_with_vert_colors);
2452                 GPU_BATCH_DISCARD_SAFE(cache->triangles_with_select_id);
2453                 GPU_BATCH_DISCARD_SAFE(cache->triangles_with_select_mask);
2454                 GPU_BATCH_DISCARD_SAFE(cache->points_with_normals);
2455                 GPU_BATCH_DISCARD_SAFE(cache->ledges_with_normals);
2456                 // if (cache->shaded_triangles) {
2457                 //      for (int i = 0; i < cache->mat_len; i++) {
2458                 //              GPU_BATCH_DISCARD_SAFE(cache->shaded_triangles[i]);
2459                 //      }
2460                 // }
2461                 // MEM_SAFE_FREE(cache->shaded_triangles);
2462                 // if (cache->texpaint_triangles) {
2463                 //      for (int i = 0; i < cache->mat_len; i++) {
2464                 //              GPU_BATCH_DISCARD_SAFE(cache->texpaint_triangles[i]);
2465                 //      }
2466                 // }
2467                 MEM_SAFE_FREE(cache->texpaint_triangles);
2468                 GPU_BATCH_DISCARD_SAFE(cache->texpaint_triangles_single);
2469         }
2470         /* TODO: add the other ones if needed. */
2471         else {
2472                 /* Does not match any vertbuf in the batch cache! */
2473                 BLI_assert(0);
2474         }
2475 }
2476
2477 static void mesh_batch_cache_clear(Mesh *me)
2478 {
2479         MeshBatchCache *cache = me->runtime.batch_cache;
2480         if (!cache) {
2481                 return;
2482         }
2483
2484         for (int i = 0; i < sizeof(cache->ordered) / sizeof(void *); ++i) {
2485                 GPUVertBuf **vbo = (GPUVertBuf **)&cache->ordered;
2486                 GPU_VERTBUF_DISCARD_SAFE(vbo[i]);
2487         }
2488         for (int i = 0; i < sizeof(cache->tess) / sizeof(void *); ++i) {
2489                 GPUVertBuf **vbo = (GPUVertBuf **)&cache->tess;
2490                 GPU_VERTBUF_DISCARD_SAFE(vbo[i]);
2491         }
2492         for (int i = 0; i < sizeof(cache->edit) / sizeof(void *); ++i) {
2493                 GPUVertBuf **vbo = (GPUVertBuf **)&cache->edit;
2494                 GPU_VERTBUF_DISCARD_SAFE(vbo[i]);
2495         }
2496         for (int i = 0; i < sizeof(cache->ibo) / sizeof(void *); ++i) {
2497                 GPUIndexBuf **ibo = (GPUIndexBuf **)&cache->ibo;
2498                 GPU_INDEXBUF_DISCARD_SAFE(ibo[i]);
2499         }
2500         for (int i = 0; i < sizeof(cache->batch) / sizeof(void *); ++i) {
2501                 GPUBatch **batch = (GPUBatch **)&cache->batch;
2502                 GPU_BATCH_DISCARD_SAFE(batch[i]);
2503         }
2504
2505         GPU_BATCH_DISCARD_SAFE(cache->all_edges);
2506         GPU_BATCH_DISCARD_SAFE(cache->all_triangles);
2507
2508         GPU_INDEXBUF_DISCARD_SAFE(cache->edges_in_order);
2509         GPU_INDEXBUF_DISCARD_SAFE(cache->triangles_in_order);
2510         GPU_INDEXBUF_DISCARD_SAFE(cache->ledges_in_order);
2511
2512         GPU_BATCH_DISCARD_SAFE(cache->overlay_weight_faces);
2513         GPU_BATCH_DISCARD_SAFE(cache->overlay_weight_verts);
2514         GPU_BATCH_DISCARD_SAFE(cache->overlay_paint_edges);
2515
2516         GPU_BATCH_DISCARD_SAFE(cache->triangles_with_normals);
2517         GPU_BATCH_DISCARD_SAFE(cache->points_with_normals);
2518         GPU_BATCH_DISCARD_SAFE(cache->ledges_with_normals);
2519         GPU_VERTBUF_DISCARD_SAFE(cache->pos_with_normals);
2520         GPU_VERTBUF_DISCARD_SAFE(cache->pos_with_normals_visible_only);
2521         GPU_VERTBUF_DISCARD_SAFE(cache->pos_with_normals_edit);
2522         GPU_VERTBUF_DISCARD_SAFE(cache->pos_with_normals_visible_only_edit);
2523         GPU_BATCH_DISCARD_SAFE(cache->triangles_with_weights);
2524         GPU_BATCH_DISCARD_SAFE(cache->triangles_with_vert_colors);
2525         GPU_VERTBUF_DISCARD_SAFE(cache->tri_aligned_uv);
2526         GPU_VERTBUF_DISCARD_SAFE(cache->ed_fcenter_pos_with_nor_and_sel);
2527         GPU_VERTBUF_DISCARD_SAFE(cache->ed_edge_pos);
2528         GPU_VERTBUF_DISCARD_SAFE(cache->ed_vert_pos);
2529         GPU_BATCH_DISCARD_SAFE(cache->triangles_with_select_mask);
2530         GPU_BATCH_DISCARD_SAFE(cache->triangles_with_select_id);
2531         GPU_BATCH_DISCARD_SAFE(cache->facedot_with_select_id);
2532         GPU_BATCH_DISCARD_SAFE(cache->edges_with_select_id);
2533         GPU_BATCH_DISCARD_SAFE(cache->verts_with_select_id);
2534
2535         GPU_BATCH_DISCARD_SAFE(cache->fancy_edges);
2536
2537         GPU_INDEXBUF_DISCARD_SAFE(cache->edges_adjacency);
2538         GPU_BATCH_DISCARD_SAFE(cache->edge_detection);
2539
2540         mesh_batch_cache_discard_shaded_tri(cache);
2541
2542         mesh_batch_cache_discard_uvedit(cache);
2543
2544         if (cache->texpaint_triangles) {
2545                 for (int i = 0; i < cache->mat_len; i++) {
2546                         GPU_BATCH_DISCARD_SAFE(cache->texpaint_triangles[i]);
2547                 }
2548         }
2549         MEM_SAFE_FREE(cache->texpaint_triangles);
2550
2551         DRW_mesh_weight_state_clear(&cache->weight_state);
2552 }
2553
2554 void DRW_mesh_batch_cache_free(Mesh *me)
2555 {
2556         mesh_batch_cache_clear(me);
2557         MEM_SAFE_FREE(me->runtime.batch_cache);
2558 }
2559
2560 /* GPUBatch cache usage. */
2561
2562 static void mesh_create_pos_and_nor_tess(MeshRenderData *rdata, GPUVertBuf *vbo, bool use_hide)
2563 {
2564         static GPUVertFormat format = { 0 };
2565         static struct { uint pos, nor; } attr_id;
2566         if (format.attr_len == 0) {
2567                 attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
2568                 attr_id.nor = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_I10, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
2569                 GPU_vertformat_triple_load(&format);
2570         }
2571
2572         GPU_vertbuf_init_with_format(vbo, &format);
2573
2574         const int tri_len = mesh_render_data_looptri_len_get_maybe_mapped(rdata);
2575         const int vbo_len_capacity = tri_len * 3;
2576         int vbo_len_used = 0;
2577         GPU_vertbuf_data_alloc(vbo, vbo_len_capacity);
2578
2579         GPUVertBufRaw pos_step, nor_step;
2580         GPU_vertbuf_attr_get_raw_data(vbo, attr_id.pos, &pos_step);
2581         GPU_vertbuf_attr_get_raw_data(vbo, attr_id.nor, &nor_step);
2582
2583         if (rdata->mapped.use == false) {
2584                 float (*lnors)[3] = rdata->loop_normals;
2585                 if (rdata->edit_bmesh) {
2586                         GPUPackedNormal *pnors_pack, *vnors_pack;
2587
2588                         if (lnors == NULL) {
2589                                 mesh_render_data_ensure_poly_normals_pack(rdata);
2590                                 mesh_render_data_ensure_vert_normals_pack(rdata);
2591
2592                                 pnors_pack = rdata->poly_normals_pack;
2593                                 vnors_pack = rdata->vert_normals_pack;
2594                         }
2595
2596                         for (int i = 0; i < tri_len; i++) {
2597                                 const BMLoop **bm_looptri = (const BMLoop **)rdata->edit_bmesh->looptris[i];
2598                                 const BMFace *bm_face = bm_looptri[0]->f;
2599
2600                                 /* use_hide always for edit-mode */
2601                                 if (BM_elem_flag_test(bm_face, BM_ELEM_HIDDEN)) {
2602                                         continue;
2603                                 }
2604
2605                                 if (lnors) {
2606                                         for (uint t = 0; t < 3; t++) {
2607                                                 const float *nor = lnors[BM_elem_index_get(bm_looptri[t])];
2608                                                 *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = GPU_normal_convert_i10_v3(nor);
2609                                         }
2610                                 }
2611                                 else if (BM_elem_flag_test(bm_face, BM_ELEM_SMOOTH)) {
2612                                         for (uint t = 0; t < 3; t++) {
2613                                                 *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = vnors_pack[BM_elem_index_get(bm_looptri[t]->v)];
2614                                         }
2615                                 }
2616                                 else {
2617                                         const GPUPackedNormal *snor_pack = &pnors_pack[BM_elem_index_get(bm_face)];
2618                                         for (uint t = 0; t < 3; t++) {
2619                                                 *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = *snor_pack;
2620                                         }
2621                                 }
2622
2623                                 /* TODO(sybren): deduplicate this and all the other places it's pasted to in this file. */
2624                                 if (rdata->edit_data && rdata->edit_data->vertexCos) {
2625                                         for (uint t = 0; t < 3; t++) {
2626                                                 int vidx = BM_elem_index_get(bm_looptri[t]->v);
2627                                                 const float *pos = rdata->edit_data->vertexCos[vidx];
2628                                                 copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), pos);
2629                                         }
2630                                 }
2631                                 else {
2632                                         for (uint t = 0; t < 3; t++) {
2633                                                 copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), bm_looptri[t]->v->co);
2634                                         }
2635                                 }
2636                         }
2637                 }
2638                 else {
2639                         if (lnors == NULL) {
2640                                 /* Use normals from vertex. */
2641                                 mesh_render_data_ensure_poly_normals_pack(rdata);
2642                         }
2643
2644                         for (int i = 0; i < tri_len; i++) {
2645                                 const MLoopTri *mlt = &rdata->mlooptri[i];
2646                                 const MPoly *mp = &rdata->mpoly[mlt->poly];
2647
2648                                 if (use_hide && (mp->flag & ME_HIDE)) {
2649                                         continue;
2650                                 }
2651
2652                                 const uint vtri[3] = {
2653                                         rdata->mloop[mlt->tri[0]].v,
2654                                         rdata->mloop[mlt->tri[1]].v,
2655                                         rdata->mloop[mlt->tri[2]].v,
2656                                 };
2657
2658                                 if (lnors) {
2659                                         for (uint t = 0; t < 3; t++) {
2660                                                 const float *nor = lnors[mlt->tri[t]];
2661                                                 *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = GPU_normal_convert_i10_v3(nor);
2662                                         }
2663                                 }
2664                                 else if (mp->flag & ME_SMOOTH) {
2665                                         for (uint t = 0; t < 3; t++) {
2666                                                 const MVert *mv = &rdata->mvert[vtri[t]];
2667                                                 *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = GPU_normal_convert_i10_s3(mv->no);
2668                                         }
2669                                 }
2670                                 else {
2671                                         const GPUPackedNormal *pnors_pack = &rdata->poly_normals_pack[mlt->poly];
2672                                         for (uint t = 0; t < 3; t++) {
2673                                                 *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = *pnors_pack;
2674                                         }
2675                                 }
2676
2677                                 for (uint t = 0; t < 3; t++) {
2678                                         const MVert *mv = &rdata->mvert[vtri[t]];
2679                                         copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mv->co);
2680                                 }
2681                         }
2682                 }
2683         }
2684         else {
2685                 /* Note: mapped doesn't support lnors yet. */
2686                 BMesh *bm = rdata->edit_bmesh->bm;
2687                 Mesh *me_cage = rdata->mapped.me_cage;
2688
2689                 /* TODO(campbell): unlike non-mapped modes we don't generate these on demand, just use if they exist.
2690                  * this seems like a low priority TODO since mapped meshes typically
2691                  * use the final mesh evaluated mesh for showing faces. */
2692                 const float (*lnors)[3] = CustomData_get_layer(&me_cage->ldata, CD_NORMAL);
2693
2694                 /* TODO(campbell): this is quite an expensive operation for something
2695                  * that's not used unless 'normal' display option is enabled. */
2696                 if (!CustomData_has_layer(&me_cage->pdata, CD_NORMAL)) {
2697                         /* TODO(campbell): this is quite an expensive operation for something
2698                          * that's not used unless 'normal' display option is enabled. */
2699                         BKE_mesh_ensure_normals_for_display(me_cage);
2700                 }
2701                 const float (*polynors)[3] = CustomData_get_layer(&me_cage->pdata, CD_NORMAL);
2702
2703                 const MVert *mvert = rdata->mapped.me_cage->mvert;
2704                 const MLoop *mloop = rdata->mapped.me_cage->mloop;
2705                 const MPoly *mpoly = rdata->mapped.me_cage->mpoly;
2706
2707                 const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(me_cage);
2708                 for (int i = 0; i < tri_len; i++) {
2709                         const MLoopTri *mlt = &mlooptri[i];
2710                         const int p_orig = rdata->mapped.p_origindex[mlt->poly];
2711                         if (p_orig != ORIGINDEX_NONE) {
2712                                 /* Assume 'use_hide' */
2713                                 BMFace *efa = BM_face_at_index(bm, p_orig);
2714                                 if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
2715                                         const MPoly *mp = &mpoly[mlt->poly];
2716                                         const uint vtri[3] = {
2717                                                 mloop[mlt->tri[0]].v,
2718                                                 mloop[mlt->tri[1]].v,
2719                                                 mloop[mlt->tri[2]].v,
2720                                         };
2721
2722                                         if (lnors) {
2723                                                 for (uint t = 0; t < 3; t++) {
2724                                                         const float *nor = lnors[mlt->tri[t]];
2725                                                         *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = GPU_normal_convert_i10_v3(nor);
2726                                                 }
2727                                         }
2728                                         else if (mp->flag & ME_SMOOTH) {
2729                                                 for (uint t = 0; t < 3; t++) {
2730                                                         const MVert *mv = &mvert[vtri[t]];
2731                                                         *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = GPU_normal_convert_i10_s3(mv->no);
2732                                                 }
2733                                         }
2734                                         else {
2735                                                 /* we don't have cached 'rdata->poly_normals_pack'. */
2736                                                 const GPUPackedNormal pnor = GPU_normal_convert_i10_v3(polynors[mlt->poly]);
2737                                                 for (uint t = 0; t < 3; t++) {
2738                                                         *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = pnor;
2739                                                 }
2740                                         }
2741
2742                                         for (uint t = 0; t < 3; t++) {
2743                                                 const MVert *mv = &mvert[vtri[t]];
2744                                                 copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mv->co);
2745                                         }
2746                                 }
2747                         }
2748                 }
2749         }
2750
2751         vbo_len_used = GPU_vertbuf_raw_used(&pos_step);
2752         BLI_assert(vbo_len_used == GPU_vertbuf_raw_used(&nor_step));
2753
2754         if (vbo_len_capacity != vbo_len_used) {
2755                 GPU_vertbuf_data_resize(vbo, vbo_len_used);
2756         }
2757 }
2758
2759 static GPUVertBuf *mesh_batch_cache_get_tri_pos_and_normals_ex(
2760         MeshRenderData *rdata, const bool use_hide,
2761         GPUVertBuf **r_vbo)
2762 {
2763         BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
2764
2765         if (*r_vbo == NULL) {
2766                 *r_vbo = GPU_vertbuf_create(GPU_USAGE_STATIC);
2767                 mesh_create_pos_and_nor_tess(rdata, *r_vbo, use_hide);
2768         }
2769         return *r_vbo;
2770 }
2771
2772 static GPUVertBuf *mesh_batch_cache_get_tri_pos_and_normals_edit(
2773         MeshRenderData *rdata, MeshBatchCache *cache, bool use_hide)
2774 {
2775         return mesh_batch_cache_get_tri_pos_and_normals_ex(
2776                 rdata, use_hide,
2777                 use_hide ? &cache->pos_with_normals_visible_only_edit : &cache->pos_with_normals_edit);
2778 }
2779
2780 static GPUVertBuf *mesh_batch_cache_get_tri_pos_and_normals_final(
2781         MeshRenderData *rdata, MeshBatchCache *cache, bool use_hide)
2782 {
2783         return mesh_batch_cache_get_tri_pos_and_normals_ex(
2784                 rdata, use_hide,
2785                 use_hide ? &cache->pos_with_normals_visible_only : &cache->pos_with_normals);
2786 }
2787
2788 /* DEPRECATED Need to be ported */
2789 static GPUVertBuf *mesh_batch_cache_get_facedot_pos_with_normals_and_flag(
2790         MeshRenderData *rdata, MeshBatchCache *cache)
2791 {
2792         BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
2793
2794         if (cache->edit.pos_nor_data_facedots == NULL) {
2795                 cache->edit.pos_nor_data_facedots = GPU_vertbuf_create(GPU_USAGE_STATIC);
2796                 mesh_create_edit_facedots(rdata, cache->edit.pos_nor_data_facedots);
2797         }
2798
2799         return cache->edit.pos_nor_data_facedots;
2800 }
2801
2802 static GPUVertBuf *mesh_batch_cache_get_edges_visible(
2803         MeshRenderData *rdata, MeshBatchCache *cache)
2804 {
2805         BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_EDGE));
2806
2807         if (cache->ed_edge_pos == NULL) {
2808                 static GPUVertFormat format = { 0 };
2809                 static struct { uint pos, data; } attr_id;
2810                 if (format.attr_len == 0) {
2811                         attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
2812                 }
2813
2814                 const int vbo_len_capacity = mesh_render_data_edges_len_get_maybe_mapped(rdata) * 2;
2815                 int vidx = 0;
2816
2817                 GPUVertBuf *vbo = cache->ed_edge_pos = GPU_vertbuf_create_with_format(&format);
2818                 GPU_vertbuf_data_alloc(vbo, vbo_len_capacity);
2819
2820                 if (rdata->mapped.use == false) {
2821                         if (rdata->edit_bmesh) {
2822                                 BMesh *bm = rdata->edit_bmesh->bm;
2823                                 BMIter iter;
2824                                 BMEdge *eed;
2825
2826                                 BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
2827                                         if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
2828                                                 GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, eed->v1->co);
2829                                                 vidx += 1;
2830                                                 GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, eed->v2->co);
2831                                                 vidx += 1;
2832                                         }
2833                                 }
2834                         }
2835                         else {
2836                                 /* not yet done! */
2837                                 BLI_assert(0);
2838                         }
2839                 }
2840                 else {
2841                         BMesh *bm = rdata->edit_bmesh->bm;
2842                         const MVert *mvert = rdata->mapped.me_cage->mvert;
2843                         const MEdge *medge = rdata->mapped.me_cage->medge;
2844                         const int *e_origindex = rdata->mapped.e_origindex;
2845                         for (int i = 0; i < rdata->mapped.edge_len; i++) {
2846                                 const int e_orig = e_origindex[i];
2847                                 if (e_orig != ORIGINDEX_NONE) {
2848                                         BMEdge *eed = BM_edge_at_index(bm, e_orig);
2849                                         if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
2850                                                 const MEdge *ed = &medge[i];
2851                                                 GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, mvert[ed->v1].co);
2852                                                 vidx += 1;
2853                                                 GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, mvert[ed->v2].co);
2854                                                 vidx += 1;
2855                                         }
2856                                 }
2857                         }
2858                 }
2859                 const int vbo_len_used = vidx;
2860                 if (vbo_len_used != vbo_len_capacity) {
2861                         GPU_vertbuf_data_resize(vbo, vbo_len_used);
2862                 }
2863                 UNUSED_VARS_NDEBUG(vbo_len_used);
2864         }
2865
2866         return cache->ed_edge_pos;
2867 }
2868
2869 static GPUVertBuf *mesh_batch_cache_get_verts_visible(
2870         MeshRenderData *rdata, MeshBatchCache *cache)
2871 {
2872         BLI_assert(rdata->types & MR_DATATYPE_VERT);
2873
2874         if (cache->ed_vert_pos == NULL) {
2875                 static GPUVertFormat format = { 0 };
2876                 static struct { uint pos, data; } attr_id;
2877                 if (format.attr_len == 0) {
2878                         attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
2879                 }
2880
2881                 const int vbo_len_capacity = mesh_render_data_verts_len_get_maybe_mapped(rdata);
2882                 uint vidx = 0;
2883
2884                 GPUVertBuf *vbo = cache->ed_vert_pos = GPU_vertbuf_create_with_format(&format);
2885                 GPU_vertbuf_data_alloc(vbo, vbo_len_capacity);
2886                 if (rdata->mapped.use == false) {
2887                         if (rdata->edit_bmesh) {
2888                                 BMesh *bm = rdata->edit_bmesh->bm;
2889                                 BMIter iter;
2890                                 BMVert *eve;
2891
2892                                 BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
2893                                         if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
2894                                                 GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, eve->co);
2895                                                 vidx += 1;
2896                                         }
2897                                 }
2898                         }
2899                         else {
2900                                 for (int i = 0; i < vbo_len_capacity; i++) {
2901                                         const MVert *mv = &rdata->mvert[i];
2902                                         if (!(mv->flag & ME_HIDE)) {
2903                                                 GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, mv->co);
2904                                                 vidx += 1;
2905                                         }
2906                                 }