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