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