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