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