1c70d40d6f1dc945f656f69174acdd5d66470a8d
[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
1335 /* First 2 bytes are bit flags
1336  * 3rd is for sharp edges
1337  * 4rd is for creased edges */
1338 enum {
1339         VFLAG_VERTEX_ACTIVE   = 1 << 0,
1340         VFLAG_VERTEX_SELECTED = 1 << 1,
1341         VFLAG_FACE_ACTIVE     = 1 << 2,
1342         VFLAG_FACE_SELECTED   = 1 << 3,
1343         VFLAG_FACE_FREESTYLE  = 1 << 4,
1344 };
1345
1346 enum {
1347         VFLAG_EDGE_EXISTS   = 1 << 0,
1348         VFLAG_EDGE_ACTIVE   = 1 << 1,
1349         VFLAG_EDGE_SELECTED = 1 << 2,
1350         VFLAG_EDGE_SEAM     = 1 << 3,
1351         VFLAG_EDGE_SHARP    = 1 << 4,
1352         VFLAG_EDGE_FREESTYLE = 1 << 5,
1353         /* Beware to not go over 1 << 7
1354          * (see gpu_shader_edit_mesh_overlay_geom.glsl) */
1355 };
1356
1357 static uchar mesh_render_data_looptri_flag(MeshRenderData *rdata, const BMFace *efa)
1358 {
1359         uchar fflag = 0;
1360
1361         if (efa == rdata->efa_act)
1362                 fflag |= VFLAG_FACE_ACTIVE;
1363
1364         if (BM_elem_flag_test(efa, BM_ELEM_SELECT))
1365                 fflag |= VFLAG_FACE_SELECTED;
1366
1367 #ifdef WITH_FREESTYLE
1368         BMesh *bm = rdata->edit_bmesh->bm;
1369         if (CustomData_has_layer(&bm->edata, CD_FREESTYLE_EDGE)) {
1370                 FreestyleFace *ffa = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_FREESTYLE_FACE);
1371
1372                 if (ffa->flag & FREESTYLE_FACE_MARK)
1373                         fflag |= VFLAG_FACE_FREESTYLE;
1374         }
1375 #endif
1376
1377         return fflag;
1378 }
1379
1380 static void mesh_render_data_edge_flag(
1381         const MeshRenderData *rdata, const BMEdge *eed,
1382         EdgeDrawAttr *eattr)
1383 {
1384         eattr->e_flag |= VFLAG_EDGE_EXISTS;
1385
1386         if (eed == rdata->eed_act)
1387                 eattr->e_flag |= VFLAG_EDGE_ACTIVE;
1388
1389         if (BM_elem_flag_test(eed, BM_ELEM_SELECT))
1390                 eattr->e_flag |= VFLAG_EDGE_SELECTED;
1391
1392         if (BM_elem_flag_test(eed, BM_ELEM_SEAM))
1393                 eattr->e_flag |= VFLAG_EDGE_SEAM;
1394
1395         if (!BM_elem_flag_test(eed, BM_ELEM_SMOOTH))
1396                 eattr->e_flag |= VFLAG_EDGE_SHARP;
1397
1398 #ifdef WITH_FREESTYLE
1399         BMesh *bm = rdata->edit_bmesh->bm;
1400         if (CustomData_has_layer(&bm->edata, CD_FREESTYLE_EDGE)) {
1401                 FreestyleEdge *fed = CustomData_bmesh_get(&bm->edata, eed->head.data, CD_FREESTYLE_EDGE);
1402
1403                 if (fed->flag & FREESTYLE_EDGE_MARK)
1404                         eattr->e_flag |= VFLAG_EDGE_FREESTYLE;
1405         }
1406 #endif
1407
1408         /* Use a byte for value range */
1409         if (rdata->cd.offset.crease != -1) {
1410                 float crease = BM_ELEM_CD_GET_FLOAT(eed, rdata->cd.offset.crease);
1411                 if (crease > 0) {
1412                         eattr->crease = (uchar)(crease * 255.0f);
1413                 }
1414         }
1415
1416         /* Use a byte for value range */
1417         if (rdata->cd.offset.bweight != -1) {
1418                 float bweight = BM_ELEM_CD_GET_FLOAT(eed, rdata->cd.offset.bweight);
1419                 if (bweight > 0) {
1420                         eattr->bweight = (uchar)(bweight * 255.0f);
1421                 }
1422         }
1423 }
1424
1425 static uchar mesh_render_data_vertex_flag(MeshRenderData *rdata, const BMVert *eve)
1426 {
1427         uchar vflag = 0;
1428
1429         /* Current vertex */
1430         if (eve == rdata->eve_act)
1431                 vflag |= VFLAG_VERTEX_ACTIVE;
1432
1433         if (BM_elem_flag_test(eve, BM_ELEM_SELECT))
1434                 vflag |= VFLAG_VERTEX_SELECTED;
1435
1436         return vflag;
1437 }
1438
1439 static void add_overlay_tri(
1440         MeshRenderData *rdata, GPUVertBuf *vbo_pos, GPUVertBuf *vbo_nor, GPUVertBuf *vbo_data,
1441         const uint pos_id, const uint vnor_id, const uint lnor_id, const uint data_id,
1442         const BMLoop **bm_looptri, const int base_vert_idx)
1443 {
1444         uchar fflag;
1445         uchar vflag;
1446
1447         if (vbo_pos) {
1448                 /* TODO(sybren): deduplicate this and all the other places it's pasted to in this file. */
1449                 if (rdata->edit_data && rdata->edit_data->vertexCos) {
1450                         for (uint i = 0; i < 3; i++) {
1451                                 int vidx = BM_elem_index_get(bm_looptri[i]->v);
1452                                 const float *pos = rdata->edit_data->vertexCos[vidx];
1453                                 GPU_vertbuf_attr_set(vbo_pos, pos_id, base_vert_idx + i, pos);
1454                         }
1455                 }
1456                 else {
1457                         for (uint i = 0; i < 3; i++) {
1458                                 const float *pos = bm_looptri[i]->v->co;
1459                                 GPU_vertbuf_attr_set(vbo_pos, pos_id, base_vert_idx + i, pos);
1460                         }
1461                 }
1462         }
1463
1464         if (vbo_nor) {
1465                 /* TODO real loop normal */
1466                 GPUPackedNormal lnor = GPU_normal_convert_i10_v3(bm_looptri[0]->f->no);
1467                 for (uint i = 0; i < 3; i++) {
1468                         GPUPackedNormal vnor = GPU_normal_convert_i10_v3(bm_looptri[i]->v->no);
1469                         GPU_vertbuf_attr_set(vbo_nor, vnor_id, base_vert_idx + i, &vnor);
1470                         GPU_vertbuf_attr_set(vbo_nor, lnor_id, base_vert_idx + i, &lnor);
1471                 }
1472         }
1473
1474         if (vbo_data) {
1475                 fflag = mesh_render_data_looptri_flag(rdata, bm_looptri[0]->f);
1476                 uint i_prev = 1, i = 2;
1477                 for (uint i_next = 0; i_next < 3; i_next++) {
1478                         vflag = mesh_render_data_vertex_flag(rdata, bm_looptri[i]->v);
1479                         EdgeDrawAttr eattr = {0};
1480                         if (bm_looptri[i_next] == bm_looptri[i_prev]->prev) {
1481                                 mesh_render_data_edge_flag(rdata, bm_looptri[i_next]->e, &eattr);
1482                         }
1483                         eattr.v_flag = fflag | vflag;
1484                         GPU_vertbuf_attr_set(vbo_data, data_id, base_vert_idx + i, &eattr);
1485
1486                         i_prev = i;
1487                         i = i_next;
1488                 }
1489         }
1490 }
1491
1492 static void add_overlay_loose_edge(
1493         MeshRenderData *rdata, GPUVertBuf *vbo_pos, GPUVertBuf *vbo_nor, GPUVertBuf *vbo_data,
1494         const uint pos_id, const uint vnor_id, const uint data_id,
1495         const BMEdge *eed, const int base_vert_idx)
1496 {
1497         if (vbo_pos) {
1498                 /* TODO(sybren): deduplicate this and all the other places it's pasted to in this file. */
1499                 if (rdata->edit_data && rdata->edit_data->vertexCos) {
1500                         for (uint i = 0; i < 2; i++) {
1501                                 int vidx = BM_elem_index_get((&eed->v1)[i]);
1502                                 const float *pos = rdata->edit_data->vertexCos[vidx];
1503                                 GPU_vertbuf_attr_set(vbo_pos, pos_id, base_vert_idx + i, pos);
1504                         }
1505                 }
1506                 else {
1507                         for (int i = 0; i < 2; ++i) {
1508                                 const float *pos = (&eed->v1)[i]->co;
1509                                 GPU_vertbuf_attr_set(vbo_pos, pos_id, base_vert_idx + i, pos);
1510                         }
1511                 }
1512         }
1513
1514         if (vbo_nor) {
1515                 for (int i = 0; i < 2; ++i) {
1516                         GPUPackedNormal vnor = GPU_normal_convert_i10_v3((&eed->v1)[i]->no);
1517                         GPU_vertbuf_attr_set(vbo_nor, vnor_id, base_vert_idx + i, &vnor);
1518                 }
1519         }
1520
1521         if (vbo_data) {
1522                 EdgeDrawAttr eattr = {0};
1523                 mesh_render_data_edge_flag(rdata, eed, &eattr);
1524                 for (int i = 0; i < 2; ++i) {
1525                         eattr.v_flag = mesh_render_data_vertex_flag(rdata, (&eed->v1)[i]);
1526                         GPU_vertbuf_attr_set(vbo_data, data_id, base_vert_idx + i, &eattr);
1527                 }
1528         }
1529 }
1530
1531 static void add_overlay_loose_vert(
1532         MeshRenderData *rdata, GPUVertBuf *vbo_pos, GPUVertBuf *vbo_nor, GPUVertBuf *vbo_data,
1533         const uint pos_id, const uint vnor_id, const uint data_id,
1534         const BMVert *eve, const int base_vert_idx)
1535 {
1536         if (vbo_pos) {
1537                 /* TODO(sybren): deduplicate this and all the other places it's pasted to in this file. */
1538                 if (rdata->edit_data && rdata->edit_data->vertexCos) {
1539                         int vidx = BM_elem_index_get(eve);
1540                         const float *pos = rdata->edit_data->vertexCos[vidx];
1541                         GPU_vertbuf_attr_set(vbo_pos, pos_id, base_vert_idx, pos);
1542                 }
1543                 else {
1544                         const float *pos = eve->co;
1545                         GPU_vertbuf_attr_set(vbo_pos, pos_id, base_vert_idx, pos);
1546                 }
1547         }
1548
1549         if (vbo_nor) {
1550                 GPUPackedNormal vnor = GPU_normal_convert_i10_v3(eve->no);
1551                 GPU_vertbuf_attr_set(vbo_nor, vnor_id, base_vert_idx, &vnor);
1552         }
1553
1554         if (vbo_data) {
1555                 uchar vflag[4] = {0, 0, 0, 0};
1556                 vflag[0] = mesh_render_data_vertex_flag(rdata, eve);
1557                 GPU_vertbuf_attr_set(vbo_data, data_id, base_vert_idx, vflag);
1558         }
1559 }
1560
1561 /** \} */
1562
1563
1564 /* ---------------------------------------------------------------------- */
1565
1566 /** \name Mesh GPUBatch Cache
1567  * \{ */
1568
1569 typedef struct MeshBatchCache {
1570         GPUVertBuf *pos_in_order;
1571         GPUIndexBuf *edges_in_order;
1572         GPUIndexBuf *edges_adjacency; /* Store edges with adjacent vertices. */
1573         GPUIndexBuf *triangles_in_order;
1574         GPUIndexBuf *ledges_in_order;
1575
1576         GPUTexture *pos_in_order_tx; /* Depending on pos_in_order */
1577
1578         GPUBatch *all_verts;
1579         GPUBatch *all_edges;
1580         GPUBatch *all_triangles;
1581
1582         GPUVertBuf *pos_with_normals;
1583         GPUVertBuf *tri_aligned_uv;  /* Active UV layer (mloopuv) */
1584
1585         /**
1586          * Other uses are all positions or loose elements.
1587          * This stores all visible elements, needed for selection.
1588          */
1589         GPUVertBuf *ed_fcenter_pos_with_nor_and_sel;
1590         GPUVertBuf *ed_edge_pos;
1591         GPUVertBuf *ed_vert_pos;
1592
1593         GPUBatch *triangles_with_normals;
1594         GPUBatch *ledges_with_normals;
1595
1596         /* Skip hidden (depending on paint select mode) */
1597         GPUBatch *triangles_with_weights;
1598         GPUBatch *triangles_with_vert_colors;
1599         /* Always skip hidden */
1600         GPUBatch *triangles_with_select_mask;
1601         GPUBatch *triangles_with_select_id;
1602         uint       triangles_with_select_id_offset;
1603
1604         GPUBatch *facedot_with_select_id;  /* shares vbo with 'overlay_facedots' */
1605         GPUBatch *edges_with_select_id;
1606         GPUBatch *verts_with_select_id;
1607
1608         uint facedot_with_select_id_offset;
1609         uint edges_with_select_id_offset;
1610         uint verts_with_select_id_offset;
1611
1612         GPUBatch *points_with_normals;
1613         GPUBatch *fancy_edges; /* owns its vertex buffer (not shared) */
1614
1615         GPUBatch *edge_detection;
1616
1617         GPUVertBuf *edges_face_overlay;
1618         GPUTexture *edges_face_overlay_tx;
1619         int edges_face_overlay_tri_count; /* Number of tri in edges_face_overlay(_adj)_tx */
1620
1621         /* Maybe have shaded_triangles_data split into pos_nor and uv_tangent
1622          * to minimize data transfer for skinned mesh. */
1623         GPUVertFormat shaded_triangles_format;
1624         GPUVertBuf *shaded_triangles_data;
1625         GPUIndexBuf **shaded_triangles_in_order;
1626         GPUBatch **shaded_triangles;
1627
1628         /* Texture Paint.*/
1629         /* per-texture batch */
1630         GPUBatch **texpaint_triangles;
1631         GPUBatch  *texpaint_triangles_single;
1632
1633         /* Edit Cage Mesh buffers */
1634         GPUVertBuf *ed_tri_pos;
1635         GPUVertBuf *ed_tri_nor; /* LoopNor, VertNor */
1636         GPUVertBuf *ed_tri_data;
1637
1638         GPUVertBuf *ed_ledge_pos;
1639         GPUVertBuf *ed_ledge_nor; /* VertNor */
1640         GPUVertBuf *ed_ledge_data;
1641
1642         GPUVertBuf *ed_lvert_pos;
1643         GPUVertBuf *ed_lvert_nor; /* VertNor */
1644         GPUVertBuf *ed_lvert_data;
1645
1646         GPUBatch *overlay_triangles;
1647         GPUBatch *overlay_triangles_nor; /* GPU_PRIM_POINTS */
1648         GPUBatch *overlay_loose_edges;
1649         GPUBatch *overlay_loose_edges_nor; /* GPU_PRIM_POINTS */
1650         GPUBatch *overlay_loose_verts;
1651         GPUBatch *overlay_facedots;
1652
1653         GPUBatch *overlay_weight_faces;
1654         GPUBatch *overlay_weight_verts;
1655         GPUBatch *overlay_paint_edges;
1656
1657         /* arrays of bool uniform names (and value) that will be use to
1658          * set srgb conversion for auto attribs.*/
1659         char *auto_layer_names;
1660         int *auto_layer_is_srgb;
1661         int auto_layer_len;
1662
1663         /* settings to determine if cache is invalid */
1664         bool is_maybe_dirty;
1665         bool is_dirty; /* Instantly invalidates cache, skipping mesh check */
1666         int edge_len;
1667         int tri_len;
1668         int poly_len;
1669         int vert_len;
1670         int mat_len;
1671         bool is_editmode;
1672
1673         /* XXX, only keep for as long as sculpt mode uses shaded drawing. */
1674         bool is_sculpt_points_tag;
1675
1676         /* Valid only if edges_adjacency is up to date. */
1677         bool is_manifold;
1678 } MeshBatchCache;
1679
1680 /* GPUBatch cache management. */
1681
1682 static bool mesh_batch_cache_valid(Mesh *me)
1683 {
1684         MeshBatchCache *cache = me->runtime.batch_cache;
1685
1686         if (cache == NULL) {
1687                 return false;
1688         }
1689
1690         /* XXX find another place for this */
1691         if (cache->mat_len != mesh_render_mat_len_get(me)) {
1692                 cache->is_maybe_dirty = true;
1693         }
1694
1695         if (cache->is_editmode != (me->edit_btmesh != NULL)) {
1696                 return false;
1697         }
1698
1699         if (cache->is_dirty) {
1700                 return false;
1701         }
1702
1703         if (cache->is_maybe_dirty == false) {
1704                 return true;
1705         }
1706         else {
1707                 if (cache->is_editmode) {
1708                         return false;
1709                 }
1710                 else if ((cache->vert_len != mesh_render_verts_len_get(me)) ||
1711                          (cache->edge_len != mesh_render_edges_len_get(me)) ||
1712                          (cache->tri_len  != mesh_render_looptri_len_get(me)) ||
1713                          (cache->poly_len != mesh_render_polys_len_get(me)) ||
1714                          (cache->mat_len   != mesh_render_mat_len_get(me)))
1715                 {
1716                         return false;
1717                 }
1718         }
1719
1720         return true;
1721 }
1722
1723 static void mesh_batch_cache_init(Mesh *me)
1724 {
1725         MeshBatchCache *cache = me->runtime.batch_cache;
1726
1727         if (!cache) {
1728                 cache = me->runtime.batch_cache = MEM_callocN(sizeof(*cache), __func__);
1729         }
1730         else {
1731                 memset(cache, 0, sizeof(*cache));
1732         }
1733
1734         cache->is_editmode = me->edit_btmesh != NULL;
1735
1736         if (cache->is_editmode == false) {
1737                 cache->edge_len = mesh_render_edges_len_get(me);
1738                 cache->tri_len = mesh_render_looptri_len_get(me);
1739                 cache->poly_len = mesh_render_polys_len_get(me);
1740                 cache->vert_len = mesh_render_verts_len_get(me);
1741         }
1742
1743         cache->mat_len = mesh_render_mat_len_get(me);
1744
1745         cache->is_maybe_dirty = false;
1746         cache->is_dirty = false;
1747 }
1748
1749 static MeshBatchCache *mesh_batch_cache_get(Mesh *me)
1750 {
1751         if (!mesh_batch_cache_valid(me)) {
1752                 mesh_batch_cache_clear(me);
1753                 mesh_batch_cache_init(me);
1754         }
1755         return me->runtime.batch_cache;
1756 }
1757
1758 void DRW_mesh_batch_cache_dirty_tag(Mesh *me, int mode)
1759 {
1760         MeshBatchCache *cache = me->runtime.batch_cache;
1761         if (cache == NULL) {
1762                 return;
1763         }
1764         switch (mode) {
1765                 case BKE_MESH_BATCH_DIRTY_MAYBE_ALL:
1766                         cache->is_maybe_dirty = true;
1767                         break;
1768                 case BKE_MESH_BATCH_DIRTY_SELECT:
1769                         GPU_VERTBUF_DISCARD_SAFE(cache->ed_tri_data);
1770                         GPU_VERTBUF_DISCARD_SAFE(cache->ed_ledge_data);
1771                         GPU_VERTBUF_DISCARD_SAFE(cache->ed_lvert_data);
1772                         GPU_VERTBUF_DISCARD_SAFE(cache->ed_fcenter_pos_with_nor_and_sel); /* Contains select flag */
1773                         GPU_VERTBUF_DISCARD_SAFE(cache->ed_edge_pos);
1774                         GPU_VERTBUF_DISCARD_SAFE(cache->ed_vert_pos);
1775
1776                         GPU_BATCH_DISCARD_SAFE(cache->overlay_triangles);
1777                         GPU_BATCH_DISCARD_SAFE(cache->overlay_loose_verts);
1778                         GPU_BATCH_DISCARD_SAFE(cache->overlay_loose_edges);
1779                         GPU_BATCH_DISCARD_SAFE(cache->overlay_facedots);
1780                         /* Edit mode selection. */
1781                         GPU_BATCH_DISCARD_SAFE(cache->facedot_with_select_id);
1782                         GPU_BATCH_DISCARD_SAFE(cache->edges_with_select_id);
1783                         GPU_BATCH_DISCARD_SAFE(cache->verts_with_select_id);
1784                         break;
1785                 case BKE_MESH_BATCH_DIRTY_ALL:
1786                         cache->is_dirty = true;
1787                         break;
1788                 case BKE_MESH_BATCH_DIRTY_SHADING:
1789                         /* TODO: This should only update UV and tangent data,
1790                          * and not free the entire cache. */
1791                         cache->is_dirty = true;
1792                         break;
1793                 case BKE_MESH_BATCH_DIRTY_SCULPT_COORDS:
1794                         cache->is_sculpt_points_tag = true;
1795                         break;
1796                 default:
1797                         BLI_assert(0);
1798         }
1799 }
1800
1801 /**
1802  * This only clear the batches associated to the given vertex buffer.
1803  **/
1804 static void mesh_batch_cache_clear_selective(Mesh *me, GPUVertBuf *vert)
1805 {
1806         MeshBatchCache *cache = me->runtime.batch_cache;
1807         if (!cache) {
1808                 return;
1809         }
1810
1811         BLI_assert(vert != NULL);
1812
1813         if (cache->pos_with_normals == vert) {
1814                 GPU_BATCH_DISCARD_SAFE(cache->triangles_with_normals);
1815                 GPU_BATCH_DISCARD_SAFE(cache->triangles_with_weights);
1816                 GPU_BATCH_DISCARD_SAFE(cache->triangles_with_vert_colors);
1817                 GPU_BATCH_DISCARD_SAFE(cache->triangles_with_select_id);
1818                 GPU_BATCH_DISCARD_SAFE(cache->triangles_with_select_mask);
1819                 GPU_BATCH_DISCARD_SAFE(cache->points_with_normals);
1820                 GPU_BATCH_DISCARD_SAFE(cache->ledges_with_normals);
1821                 if (cache->shaded_triangles) {
1822                         for (int i = 0; i < cache->mat_len; ++i) {
1823                                 GPU_BATCH_DISCARD_SAFE(cache->shaded_triangles[i]);
1824                         }
1825                 }
1826                 MEM_SAFE_FREE(cache->shaded_triangles);
1827                 if (cache->texpaint_triangles) {
1828                         for (int i = 0; i < cache->mat_len; ++i) {
1829                                 GPU_BATCH_DISCARD_SAFE(cache->texpaint_triangles[i]);
1830                         }
1831                 }
1832                 MEM_SAFE_FREE(cache->texpaint_triangles);
1833                 GPU_BATCH_DISCARD_SAFE(cache->texpaint_triangles_single);
1834         }
1835         /* TODO: add the other ones if needed. */
1836         else {
1837                 /* Does not match any vertbuf in the batch cache! */
1838                 BLI_assert(0);
1839         }
1840 }
1841
1842 static void mesh_batch_cache_clear(Mesh *me)
1843 {
1844         MeshBatchCache *cache = me->runtime.batch_cache;
1845         if (!cache) {
1846                 return;
1847         }
1848
1849         GPU_BATCH_DISCARD_SAFE(cache->all_verts);
1850         GPU_BATCH_DISCARD_SAFE(cache->all_edges);
1851         GPU_BATCH_DISCARD_SAFE(cache->all_triangles);
1852
1853         GPU_VERTBUF_DISCARD_SAFE(cache->pos_in_order);
1854         DRW_TEXTURE_FREE_SAFE(cache->pos_in_order_tx);
1855         GPU_INDEXBUF_DISCARD_SAFE(cache->edges_in_order);
1856         GPU_INDEXBUF_DISCARD_SAFE(cache->triangles_in_order);
1857         GPU_INDEXBUF_DISCARD_SAFE(cache->ledges_in_order);
1858
1859         GPU_VERTBUF_DISCARD_SAFE(cache->ed_tri_pos);
1860         GPU_VERTBUF_DISCARD_SAFE(cache->ed_tri_nor);
1861         GPU_VERTBUF_DISCARD_SAFE(cache->ed_tri_data);
1862         GPU_VERTBUF_DISCARD_SAFE(cache->ed_ledge_pos);
1863         GPU_VERTBUF_DISCARD_SAFE(cache->ed_ledge_nor);
1864         GPU_VERTBUF_DISCARD_SAFE(cache->ed_ledge_data);
1865         GPU_VERTBUF_DISCARD_SAFE(cache->ed_lvert_pos);
1866         GPU_VERTBUF_DISCARD_SAFE(cache->ed_lvert_nor);
1867         GPU_VERTBUF_DISCARD_SAFE(cache->ed_lvert_data);
1868         GPU_BATCH_DISCARD_SAFE(cache->overlay_triangles);
1869         GPU_BATCH_DISCARD_SAFE(cache->overlay_triangles_nor);
1870         GPU_BATCH_DISCARD_SAFE(cache->overlay_loose_verts);
1871         GPU_BATCH_DISCARD_SAFE(cache->overlay_loose_edges);
1872         GPU_BATCH_DISCARD_SAFE(cache->overlay_loose_edges_nor);
1873
1874         GPU_BATCH_DISCARD_SAFE(cache->overlay_weight_faces);
1875         GPU_BATCH_DISCARD_SAFE(cache->overlay_weight_verts);
1876         GPU_BATCH_DISCARD_SAFE(cache->overlay_paint_edges);
1877         GPU_BATCH_DISCARD_SAFE(cache->overlay_facedots);
1878
1879         GPU_BATCH_DISCARD_SAFE(cache->triangles_with_normals);
1880         GPU_BATCH_DISCARD_SAFE(cache->points_with_normals);
1881         GPU_BATCH_DISCARD_SAFE(cache->ledges_with_normals);
1882         GPU_VERTBUF_DISCARD_SAFE(cache->pos_with_normals);
1883         GPU_BATCH_DISCARD_SAFE(cache->triangles_with_weights);
1884         GPU_BATCH_DISCARD_SAFE(cache->triangles_with_vert_colors);
1885         GPU_VERTBUF_DISCARD_SAFE(cache->tri_aligned_uv);
1886         GPU_VERTBUF_DISCARD_SAFE(cache->ed_fcenter_pos_with_nor_and_sel);
1887         GPU_VERTBUF_DISCARD_SAFE(cache->ed_edge_pos);
1888         GPU_VERTBUF_DISCARD_SAFE(cache->ed_vert_pos);
1889         GPU_BATCH_DISCARD_SAFE(cache->triangles_with_select_mask);
1890         GPU_BATCH_DISCARD_SAFE(cache->triangles_with_select_id);
1891         GPU_BATCH_DISCARD_SAFE(cache->facedot_with_select_id);
1892         GPU_BATCH_DISCARD_SAFE(cache->edges_with_select_id);
1893         GPU_BATCH_DISCARD_SAFE(cache->verts_with_select_id);
1894
1895         GPU_BATCH_DISCARD_SAFE(cache->fancy_edges);
1896
1897         GPU_INDEXBUF_DISCARD_SAFE(cache->edges_adjacency);
1898         GPU_BATCH_DISCARD_SAFE(cache->edge_detection);
1899
1900         GPU_VERTBUF_DISCARD_SAFE(cache->edges_face_overlay);
1901         DRW_TEXTURE_FREE_SAFE(cache->edges_face_overlay_tx);
1902
1903         GPU_VERTBUF_DISCARD_SAFE(cache->shaded_triangles_data);
1904         if (cache->shaded_triangles_in_order) {
1905                 for (int i = 0; i < cache->mat_len; ++i) {
1906                         GPU_INDEXBUF_DISCARD_SAFE(cache->shaded_triangles_in_order[i]);
1907                 }
1908         }
1909         if (cache->shaded_triangles) {
1910                 for (int i = 0; i < cache->mat_len; ++i) {
1911                         GPU_BATCH_DISCARD_SAFE(cache->shaded_triangles[i]);
1912                 }
1913         }
1914
1915         MEM_SAFE_FREE(cache->shaded_triangles_in_order);
1916         MEM_SAFE_FREE(cache->shaded_triangles);
1917
1918         MEM_SAFE_FREE(cache->auto_layer_names);
1919         MEM_SAFE_FREE(cache->auto_layer_is_srgb);
1920
1921         if (cache->texpaint_triangles) {
1922                 for (int i = 0; i < cache->mat_len; ++i) {
1923                         GPU_BATCH_DISCARD_SAFE(cache->texpaint_triangles[i]);
1924                 }
1925         }
1926         MEM_SAFE_FREE(cache->texpaint_triangles);
1927
1928         GPU_BATCH_DISCARD_SAFE(cache->texpaint_triangles_single);
1929
1930 }
1931
1932 void DRW_mesh_batch_cache_free(Mesh *me)
1933 {
1934         mesh_batch_cache_clear(me);
1935         MEM_SAFE_FREE(me->runtime.batch_cache);
1936 }
1937
1938 /* GPUBatch cache usage. */
1939
1940 static GPUVertBuf *mesh_batch_cache_get_tri_shading_data(MeshRenderData *rdata, MeshBatchCache *cache)
1941 {
1942         BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
1943 #define USE_COMP_MESH_DATA
1944
1945         if (cache->shaded_triangles_data == NULL) {
1946                 const uint uv_len = rdata->cd.layers.uv_len;
1947                 const uint tangent_len = rdata->cd.layers.tangent_len;
1948                 const uint vcol_len = rdata->cd.layers.vcol_len;
1949                 const uint layers_combined_len = uv_len + vcol_len + tangent_len;
1950
1951                 if (layers_combined_len == 0) {
1952                         return NULL;
1953                 }
1954
1955                 GPUVertFormat *format = &cache->shaded_triangles_format;
1956
1957                 GPU_vertformat_clear(format);
1958
1959                 /* initialize vertex format */
1960                 uint *layers_combined_id = BLI_array_alloca(layers_combined_id, layers_combined_len);
1961                 uint *uv_id = layers_combined_id;
1962                 uint *tangent_id = uv_id + uv_len;
1963                 uint *vcol_id = tangent_id + tangent_len;
1964
1965                 /* Not needed, just for sanity. */
1966                 if (uv_len == 0) { uv_id = NULL; }
1967                 if (tangent_len == 0) { tangent_id = NULL; }
1968                 if (vcol_len == 0) { vcol_id = NULL; }
1969
1970                 /* Count number of auto layer and allocate big enough name buffer. */
1971                 uint auto_names_len = 0;
1972                 uint auto_ofs = 0;
1973                 uint auto_id = 0;
1974                 cache->auto_layer_len = 0;
1975                 for (uint i = 0; i < uv_len; i++) {
1976                         const char *attrib_name = mesh_render_data_uv_auto_layer_uuid_get(rdata, i);
1977                         auto_names_len += strlen(attrib_name) + 2; /* include null terminator and b prefix. */
1978                         cache->auto_layer_len++;
1979                 }
1980                 for (uint i = 0; i < vcol_len; i++) {
1981                         if (rdata->cd.layers.auto_vcol[i]) {
1982                                 const char *attrib_name = mesh_render_data_vcol_auto_layer_uuid_get(rdata, i);
1983                                 auto_names_len += strlen(attrib_name) + 2; /* include null terminator and b prefix. */
1984                                 cache->auto_layer_len++;
1985                         }
1986                 }
1987                 auto_names_len += 1; /* add an ultimate '\0' terminator */
1988                 cache->auto_layer_names = MEM_callocN(auto_names_len * sizeof(char), "Auto layer name buf");
1989                 cache->auto_layer_is_srgb = MEM_mallocN(cache->auto_layer_len * sizeof(int), "Auto layer value buf");
1990
1991                 for (uint i = 0; i < uv_len; i++) {
1992                         /* UV */
1993                         const char *attrib_name = mesh_render_data_uv_layer_uuid_get(rdata, i);
1994 #if defined(USE_COMP_MESH_DATA) && 0 /* these are clamped. Maybe use them as an option in the future */
1995                         uv_id[i] = GPU_vertformat_attr_add(format, attrib_name, GPU_COMP_I16, 2, GPU_FETCH_INT_TO_FLOAT_UNIT);
1996 #else
1997                         uv_id[i] = GPU_vertformat_attr_add(format, attrib_name, GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
1998 #endif
1999
2000                         /* Auto Name */
2001                         attrib_name = mesh_render_data_uv_auto_layer_uuid_get(rdata, i);
2002                         GPU_vertformat_alias_add(format, attrib_name);
2003
2004                         /* +1 include null terminator. */
2005                         auto_ofs += 1 + BLI_snprintf_rlen(
2006                                 cache->auto_layer_names + auto_ofs, auto_names_len - auto_ofs, "b%s", attrib_name);
2007                         cache->auto_layer_is_srgb[auto_id++] = 0; /* tag as not srgb */
2008
2009                         if (i == rdata->cd.layers.uv_active) {
2010                                 GPU_vertformat_alias_add(format, "u");
2011                         }
2012                 }
2013
2014                 for (uint i = 0; i < tangent_len; i++) {
2015                         const char *attrib_name = mesh_render_data_tangent_layer_uuid_get(rdata, i);
2016                         /* WATCH IT : only specifying 3 component instead of 4 (4th is sign).
2017                          * That may cause some problem but I could not make it to fail (fclem) */
2018 #ifdef USE_COMP_MESH_DATA
2019                         /* Tangents need more precision than 10_10_10 */
2020                         tangent_id[i] = GPU_vertformat_attr_add(format, attrib_name, GPU_COMP_I16, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
2021 #else
2022                         tangent_id[i] = GPU_vertformat_attr_add(format, attrib_name, GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
2023 #endif
2024
2025                         if (i == rdata->cd.layers.tangent_active) {
2026                                 GPU_vertformat_alias_add(format, "t");
2027                         }
2028                 }
2029
2030                 for (uint i = 0; i < vcol_len; i++) {
2031                         const char *attrib_name = mesh_render_data_vcol_layer_uuid_get(rdata, i);
2032                         vcol_id[i] = GPU_vertformat_attr_add(format, attrib_name, GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
2033
2034                         /* Auto layer */
2035                         if (rdata->cd.layers.auto_vcol[i]) {
2036                                 attrib_name = mesh_render_data_vcol_auto_layer_uuid_get(rdata, i);
2037
2038                                 GPU_vertformat_alias_add(format, attrib_name);
2039
2040                                 /* +1 include null terminator. */
2041                                 auto_ofs += 1 + BLI_snprintf_rlen(
2042                                         cache->auto_layer_names + auto_ofs, auto_names_len - auto_ofs, "b%s", attrib_name);
2043                                 cache->auto_layer_is_srgb[auto_id++] = 1; /* tag as srgb */
2044                         }
2045
2046                         if (i == rdata->cd.layers.vcol_active) {
2047                                 GPU_vertformat_alias_add(format, "c");
2048                         }
2049                 }
2050
2051                 const uint tri_len = mesh_render_data_looptri_len_get(rdata);
2052
2053                 GPUVertBuf *vbo = cache->shaded_triangles_data = GPU_vertbuf_create_with_format(format);
2054
2055                 const int vbo_len_capacity = tri_len * 3;
2056                 int vbo_len_used = 0;
2057                 GPU_vertbuf_data_alloc(vbo, vbo_len_capacity);
2058
2059                 GPUVertBufRaw *layers_combined_step = BLI_array_alloca(layers_combined_step, layers_combined_len);
2060
2061                 GPUVertBufRaw *uv_step      = layers_combined_step;
2062                 GPUVertBufRaw *tangent_step = uv_step + uv_len;
2063                 GPUVertBufRaw *vcol_step    = tangent_step + tangent_len;
2064
2065                 /* Not needed, just for sanity. */
2066                 if (uv_len == 0) { uv_step = NULL; }
2067                 if (tangent_len == 0) { tangent_step = NULL; }
2068                 if (vcol_len == 0) { vcol_step = NULL; }
2069
2070                 for (uint i = 0; i < uv_len; i++) {
2071                         GPU_vertbuf_attr_get_raw_data(vbo, uv_id[i], &uv_step[i]);
2072                 }
2073                 for (uint i = 0; i < tangent_len; i++) {
2074                         GPU_vertbuf_attr_get_raw_data(vbo, tangent_id[i], &tangent_step[i]);
2075                 }
2076                 for (uint i = 0; i < vcol_len; i++) {
2077                         GPU_vertbuf_attr_get_raw_data(vbo, vcol_id[i], &vcol_step[i]);
2078                 }
2079
2080                 /* TODO deduplicate all verts and make use of GPUIndexBuf in
2081                  * mesh_batch_cache_get_triangles_in_order_split_by_material. */
2082                 if (rdata->edit_bmesh) {
2083                         for (uint i = 0; i < tri_len; i++) {
2084                                 const BMLoop **bm_looptri = (const BMLoop **)rdata->edit_bmesh->looptris[i];
2085                                 if (BM_elem_flag_test(bm_looptri[0]->f, BM_ELEM_HIDDEN)) {
2086                                         continue;
2087                                 }
2088                                 /* UVs */
2089                                 for (uint j = 0; j < uv_len; j++) {
2090                                         const uint layer_offset = rdata->cd.offset.uv[j];
2091                                         for (uint t = 0; t < 3; t++) {
2092                                                 const float *elem = ((MLoopUV *)BM_ELEM_CD_GET_VOID_P(bm_looptri[t], layer_offset))->uv;
2093                                                 copy_v2_v2(GPU_vertbuf_raw_step(&uv_step[j]), elem);
2094                                         }
2095                                 }
2096                                 /* TANGENTs */
2097                                 for (uint j = 0; j < tangent_len; j++) {
2098                                         float (*layer_data)[4] = rdata->cd.layers.tangent[j];
2099                                         for (uint t = 0; t < 3; t++) {
2100                                                 const float *elem = layer_data[BM_elem_index_get(bm_looptri[t])];
2101                                                 normal_float_to_short_v3(GPU_vertbuf_raw_step(&tangent_step[j]), elem);
2102                                         }
2103                                 }
2104                                 /* VCOLs */
2105                                 for (uint j = 0; j < vcol_len; j++) {
2106                                         const uint layer_offset = rdata->cd.offset.vcol[j];
2107                                         for (uint t = 0; t < 3; t++) {
2108                                                 const uchar *elem = &((MLoopCol *)BM_ELEM_CD_GET_VOID_P(bm_looptri[t], layer_offset))->r;
2109                                                 copy_v3_v3_uchar(GPU_vertbuf_raw_step(&vcol_step[j]), elem);
2110                                         }
2111                                 }
2112                         }
2113                 }
2114                 else {
2115                         for (uint i = 0; i < tri_len; i++) {
2116                                 const MLoopTri *mlt = &rdata->mlooptri[i];
2117
2118                                 /* UVs */
2119                                 for (uint j = 0; j < uv_len; j++) {
2120                                         const MLoopUV *layer_data = rdata->cd.layers.uv[j];
2121                                         for (uint t = 0; t < 3; t++) {
2122                                                 const float *elem = layer_data[mlt->tri[t]].uv;
2123                                                 copy_v2_v2(GPU_vertbuf_raw_step(&uv_step[j]), elem);
2124                                         }
2125                                 }
2126                                 /* TANGENTs */
2127                                 for (uint j = 0; j < tangent_len; j++) {
2128                                         float (*layer_data)[4] = rdata->cd.layers.tangent[j];
2129                                         for (uint t = 0; t < 3; t++) {
2130                                                 const float *elem = layer_data[mlt->tri[t]];
2131 #ifdef USE_COMP_MESH_DATA
2132                                                 normal_float_to_short_v3(GPU_vertbuf_raw_step(&tangent_step[j]), elem);
2133 #else
2134                                                 copy_v3_v3(GPU_vertbuf_raw_step(&tangent_step[j]), elem);
2135 #endif
2136                                         }
2137                                 }
2138                                 /* VCOLs */
2139                                 for (uint j = 0; j < vcol_len; j++) {
2140                                         const MLoopCol *layer_data = rdata->cd.layers.vcol[j];
2141                                         for (uint t = 0; t < 3; t++) {
2142                                                 const uchar *elem = &layer_data[mlt->tri[t]].r;
2143                                                 copy_v3_v3_uchar(GPU_vertbuf_raw_step(&vcol_step[j]), elem);
2144                                         }
2145                                 }
2146                         }
2147                 }
2148
2149                 vbo_len_used = GPU_vertbuf_raw_used(&layers_combined_step[0]);
2150
2151 #ifndef NDEBUG
2152                 /* Check all layers are write aligned. */
2153                 if (layers_combined_len > 1) {
2154                         for (uint i = 1; i < layers_combined_len; i++) {
2155                                 BLI_assert(vbo_len_used == GPU_vertbuf_raw_used(&layers_combined_step[i]));
2156                         }
2157                 }
2158 #endif
2159
2160                 if (vbo_len_capacity != vbo_len_used) {
2161                         GPU_vertbuf_data_resize(vbo, vbo_len_used);
2162                 }
2163         }
2164
2165 #undef USE_COMP_MESH_DATA
2166
2167         return cache->shaded_triangles_data;
2168 }
2169
2170 static GPUVertBuf *mesh_batch_cache_get_tri_uv_active(
2171         MeshRenderData *rdata, MeshBatchCache *cache)
2172 {
2173         BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPUV));
2174
2175
2176         if (cache->tri_aligned_uv == NULL) {
2177                 const MLoopUV *mloopuv = rdata->mloopuv;
2178                 if (mloopuv == NULL) {
2179                         return NULL;
2180                 }
2181
2182                 uint vidx = 0;
2183
2184                 static GPUVertFormat format = { 0 };
2185                 static struct { uint uv; } attr_id;
2186                 if (format.attr_len == 0) {
2187                         attr_id.uv = GPU_vertformat_attr_add(&format, "uv", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
2188                 }
2189
2190                 const int tri_len = mesh_render_data_looptri_len_get(rdata);
2191
2192                 GPUVertBuf *vbo = cache->tri_aligned_uv = GPU_vertbuf_create_with_format(&format);
2193
2194                 const int vbo_len_capacity = tri_len * 3;
2195                 int vbo_len_used = 0;
2196                 GPU_vertbuf_data_alloc(vbo, vbo_len_capacity);
2197
2198
2199                 BMEditMesh *embm = rdata->edit_bmesh;
2200                 /* get uv's from active UVMap */
2201                 if (rdata->edit_bmesh) {
2202                         /* edit mode */
2203                         BMesh *bm = embm->bm;
2204
2205                         const int layer_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
2206                         for (uint i = 0; i < tri_len; i++) {
2207                                 const BMLoop **bm_looptri = (const BMLoop **)embm->looptris[i];
2208                                 if (BM_elem_flag_test(bm_looptri[0]->f, BM_ELEM_HIDDEN)) {
2209                                         continue;
2210                                 }
2211                                 for (uint t = 0; t < 3; t++) {
2212                                         const BMLoop *loop = bm_looptri[t];
2213                                         const int index = BM_elem_index_get(loop);
2214                                         if (index != -1) {
2215                                                 const float *elem = ((MLoopUV *)BM_ELEM_CD_GET_VOID_P(loop, layer_offset))->uv;
2216                                                 GPU_vertbuf_attr_set(vbo, attr_id.uv, vidx++, elem);
2217                                         }
2218                                 }
2219                         }
2220                 }
2221                 else {
2222                         /* object mode */
2223                         for (int i = 0; i < tri_len; i++) {
2224                                 const MLoopTri *mlt = &rdata->mlooptri[i];
2225                                 GPU_vertbuf_attr_set(vbo, attr_id.uv, vidx++, mloopuv[mlt->tri[0]].uv);
2226                                 GPU_vertbuf_attr_set(vbo, attr_id.uv, vidx++, mloopuv[mlt->tri[1]].uv);
2227                                 GPU_vertbuf_attr_set(vbo, attr_id.uv, vidx++, mloopuv[mlt->tri[2]].uv);
2228                         }
2229                 }
2230
2231                 vbo_len_used = vidx;
2232
2233                 BLI_assert(vbo_len_capacity == vbo_len_used);
2234                 UNUSED_VARS_NDEBUG(vbo_len_used);
2235         }
2236
2237         return cache->tri_aligned_uv;
2238 }
2239
2240 static GPUVertBuf *mesh_batch_cache_get_tri_pos_and_normals_ex(
2241         MeshRenderData *rdata, const bool use_hide,
2242         GPUVertBuf **r_vbo)
2243 {
2244         BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
2245
2246         if (*r_vbo == NULL) {
2247                 static GPUVertFormat format = { 0 };
2248                 static struct { uint pos, nor; } attr_id;
2249                 if (format.attr_len == 0) {
2250                         attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
2251                         attr_id.nor = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_I10, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
2252                 }
2253
2254                 const int tri_len = mesh_render_data_looptri_len_get(rdata);
2255
2256                 GPUVertBuf *vbo = *r_vbo = GPU_vertbuf_create_with_format(&format);
2257
2258                 const int vbo_len_capacity = tri_len * 3;
2259                 int vbo_len_used = 0;
2260                 GPU_vertbuf_data_alloc(vbo, vbo_len_capacity);
2261
2262                 GPUVertBufRaw pos_step, nor_step;
2263                 GPU_vertbuf_attr_get_raw_data(vbo, attr_id.pos, &pos_step);
2264                 GPU_vertbuf_attr_get_raw_data(vbo, attr_id.nor, &nor_step);
2265
2266                 float (*lnors)[3] = rdata->loop_normals;
2267
2268                 if (rdata->edit_bmesh) {
2269                         GPUPackedNormal *pnors_pack, *vnors_pack;
2270
2271                         if (lnors == NULL) {
2272                                 mesh_render_data_ensure_poly_normals_pack(rdata);
2273                                 mesh_render_data_ensure_vert_normals_pack(rdata);
2274
2275                                 pnors_pack = rdata->poly_normals_pack;
2276                                 vnors_pack = rdata->vert_normals_pack;
2277                         }
2278
2279                         for (int i = 0; i < tri_len; i++) {
2280                                 const BMLoop **bm_looptri = (const BMLoop **)rdata->edit_bmesh->looptris[i];
2281                                 const BMFace *bm_face = bm_looptri[0]->f;
2282
2283                                 /* use_hide always for edit-mode */
2284                                 if (BM_elem_flag_test(bm_face, BM_ELEM_HIDDEN)) {
2285                                         continue;
2286                                 }
2287
2288                                 if (lnors) {
2289                                         for (uint t = 0; t < 3; t++) {
2290                                                 const float *nor = lnors[BM_elem_index_get(bm_looptri[t])];
2291                                                 *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = GPU_normal_convert_i10_v3(nor);
2292                                         }
2293                                 }
2294                                 else if (BM_elem_flag_test(bm_face, BM_ELEM_SMOOTH)) {
2295                                         for (uint t = 0; t < 3; t++) {
2296                                                 *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = vnors_pack[BM_elem_index_get(bm_looptri[t]->v)];
2297                                         }
2298                                 }
2299                                 else {
2300                                         const GPUPackedNormal *snor_pack = &pnors_pack[BM_elem_index_get(bm_face)];
2301                                         for (uint t = 0; t < 3; t++) {
2302                                                 *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = *snor_pack;
2303                                         }
2304                                 }
2305
2306                                 /* TODO(sybren): deduplicate this and all the other places it's pasted to in this file. */
2307                                 if (rdata->edit_data && rdata->edit_data->vertexCos) {
2308                                         for (uint t = 0; t < 3; t++) {
2309                                                 int vidx = BM_elem_index_get(bm_looptri[t]->v);
2310                                                 const float *pos = rdata->edit_data->vertexCos[vidx];
2311                                                 copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), pos);
2312                                         }
2313                                 }
2314                                 else {
2315                                         for (uint t = 0; t < 3; t++) {
2316                                                 copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), bm_looptri[t]->v->co);
2317                                         }
2318                                 }
2319                         }
2320                 }
2321                 else {
2322                         if (lnors == NULL) {
2323                                 /* Use normals from vertex. */
2324                                 mesh_render_data_ensure_poly_normals_pack(rdata);
2325                         }
2326
2327                         for (int i = 0; i < tri_len; i++) {
2328                                 const MLoopTri *mlt = &rdata->mlooptri[i];
2329                                 const MPoly *mp = &rdata->mpoly[mlt->poly];
2330
2331                                 if (use_hide && (mp->flag & ME_HIDE)) {
2332                                         continue;
2333                                 }
2334
2335                                 const uint vtri[3] = {
2336                                         rdata->mloop[mlt->tri[0]].v,
2337                                         rdata->mloop[mlt->tri[1]].v,
2338                                         rdata->mloop[mlt->tri[2]].v,
2339                                 };
2340
2341                                 if (lnors) {
2342                                         for (uint t = 0; t < 3; t++) {
2343                                                 const float *nor = lnors[mlt->tri[t]];
2344                                                 *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = GPU_normal_convert_i10_v3(nor);
2345                                         }
2346                                 }
2347                                 else if (mp->flag & ME_SMOOTH) {
2348                                         for (uint t = 0; t < 3; t++) {
2349                                                 const MVert *mv = &rdata->mvert[vtri[t]];
2350                                                 *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = GPU_normal_convert_i10_s3(mv->no);
2351                                         }
2352                                 }
2353                                 else {
2354                                         const GPUPackedNormal *pnors_pack = &rdata->poly_normals_pack[mlt->poly];
2355                                         for (uint t = 0; t < 3; t++) {
2356                                                 *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = *pnors_pack;
2357                                         }
2358                                 }
2359
2360                                 for (uint t = 0; t < 3; t++) {
2361                                         const MVert *mv = &rdata->mvert[vtri[t]];
2362                                         copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mv->co);
2363                                 }
2364                         }
2365                 }
2366
2367                 vbo_len_used = GPU_vertbuf_raw_used(&pos_step);
2368                 BLI_assert(vbo_len_used == GPU_vertbuf_raw_used(&nor_step));
2369
2370                 if (vbo_len_capacity != vbo_len_used) {
2371                         GPU_vertbuf_data_resize(vbo, vbo_len_used);
2372                 }
2373         }
2374         return *r_vbo;
2375 }
2376
2377 static GPUVertBuf *mesh_batch_cache_get_tri_pos_and_normals(
2378         MeshRenderData *rdata, MeshBatchCache *cache)
2379 {
2380         return mesh_batch_cache_get_tri_pos_and_normals_ex(
2381                 rdata, false,
2382                 &cache->pos_with_normals);
2383 }
2384 static GPUVertBuf *mesh_create_tri_pos_and_normals_visible_only(
2385         MeshRenderData *rdata)
2386 {
2387         GPUVertBuf *vbo_dummy = NULL;
2388         return mesh_batch_cache_get_tri_pos_and_normals_ex(
2389                 rdata, true,
2390                 &vbo_dummy);
2391 }
2392
2393 static GPUVertBuf *mesh_batch_cache_get_facedot_pos_with_normals_and_flag(
2394         MeshRenderData *rdata, MeshBatchCache *cache)
2395 {
2396         BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
2397
2398         if (cache->ed_fcenter_pos_with_nor_and_sel == NULL) {
2399                 static GPUVertFormat format = { 0 };
2400                 static struct { uint pos, data; } attr_id;
2401                 if (format.attr_len == 0) {
2402                         attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
2403                         attr_id.data = GPU_vertformat_attr_add(&format, "norAndFlag", GPU_COMP_I10, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
2404                 }
2405
2406                 const int vbo_len_capacity = mesh_render_data_polys_len_get(rdata);
2407                 int vidx = 0;
2408
2409                 GPUVertBuf *vbo = cache->ed_fcenter_pos_with_nor_and_sel = GPU_vertbuf_create_with_format(&format);
2410                 GPU_vertbuf_data_alloc(vbo, vbo_len_capacity);
2411                 for (int i = 0; i < vbo_len_capacity; ++i) {
2412                         float pcenter[3], pnor[3];
2413                         bool selected = false;
2414
2415                         if (mesh_render_data_pnors_pcenter_select_get(rdata, i, pnor, pcenter, &selected)) {
2416
2417                                 GPUPackedNormal nor = { .x = 0, .y = 0, .z = -511 };
2418                                 nor = GPU_normal_convert_i10_v3(pnor);
2419                                 nor.w = selected ? 1 : 0;
2420                                 GPU_vertbuf_attr_set(vbo, attr_id.data, vidx, &nor);
2421
2422                                 GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, pcenter);
2423
2424                                 vidx += 1;
2425                         }
2426                 }
2427                 const int vbo_len_used = vidx;
2428                 BLI_assert(vbo_len_used <= vbo_len_capacity);
2429                 if (vbo_len_used != vbo_len_capacity) {
2430                         GPU_vertbuf_data_resize(vbo, vbo_len_used);
2431                 }
2432         }
2433
2434         return cache->ed_fcenter_pos_with_nor_and_sel;
2435 }
2436
2437 static GPUVertBuf *mesh_batch_cache_get_edges_visible(
2438         MeshRenderData *rdata, MeshBatchCache *cache)
2439 {
2440         BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_EDGE));
2441
2442         if (cache->ed_edge_pos == NULL) {
2443                 static GPUVertFormat format = { 0 };
2444                 static struct { uint pos, data; } attr_id;
2445                 if (format.attr_len == 0) {
2446                         attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
2447                 }
2448
2449                 const int vbo_len_capacity = mesh_render_data_edges_len_get(rdata) * 2;
2450                 int vidx = 0;
2451
2452                 GPUVertBuf *vbo = cache->ed_edge_pos = GPU_vertbuf_create_with_format(&format);
2453                 GPU_vertbuf_data_alloc(vbo, vbo_len_capacity);
2454                 if (rdata->edit_bmesh) {
2455                         BMesh *bm = rdata->edit_bmesh->bm;
2456                         BMIter iter;
2457                         BMEdge *eed;
2458
2459                         BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
2460                                 if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
2461                                         GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, eed->v1->co);
2462                                         vidx += 1;
2463                                         GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, eed->v2->co);
2464                                         vidx += 1;
2465                                 }
2466                         }
2467                 }
2468                 else {
2469                         /* not yet done! */
2470                         BLI_assert(0);
2471                 }
2472                 const int vbo_len_used = vidx;
2473                 if (vbo_len_used != vbo_len_capacity) {
2474                         GPU_vertbuf_data_resize(vbo, vbo_len_used);
2475                 }
2476                 UNUSED_VARS_NDEBUG(vbo_len_used);
2477         }
2478
2479         return cache->ed_edge_pos;
2480 }
2481
2482 static GPUVertBuf *mesh_batch_cache_get_verts_visible(
2483         MeshRenderData *rdata, MeshBatchCache *cache)
2484 {
2485         BLI_assert(rdata->types & MR_DATATYPE_VERT);
2486
2487         if (cache->ed_vert_pos == NULL) {
2488                 static GPUVertFormat format = { 0 };
2489                 static struct { uint pos, data; } attr_id;
2490                 if (format.attr_len == 0) {
2491                         attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
2492                 }
2493
2494                 const int vbo_len_capacity = mesh_render_data_verts_len_get(rdata);
2495                 uint vidx = 0;
2496
2497                 GPUVertBuf *vbo = cache->ed_vert_pos = GPU_vertbuf_create_with_format(&format);
2498                 GPU_vertbuf_data_alloc(vbo, vbo_len_capacity);
2499                 if (rdata->edit_bmesh) {
2500                         BMesh *bm = rdata->edit_bmesh->bm;
2501                         BMIter iter;
2502                         BMVert *eve;
2503
2504                         BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
2505                                 if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
2506                                         GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, eve->co);
2507                                         vidx += 1;
2508                                 }
2509                         }
2510                 }
2511                 else {
2512                         for (int i = 0; i < vbo_len_capacity; i++) {
2513                                 const MVert *mv = &rdata->mvert[i];
2514                                 if (!(mv->flag & ME_HIDE)) {
2515                                         GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, mv->co);
2516                                         vidx += 1;
2517                                 }
2518                         }
2519                 }
2520                 const uint vbo_len_used = vidx;
2521                 if (vbo_len_used != vbo_len_capacity) {
2522                         GPU_vertbuf_data_resize(vbo, vbo_len_used);
2523                 }
2524
2525                 UNUSED_VARS_NDEBUG(vbo_len_used);
2526         }
2527
2528         return cache->ed_vert_pos;
2529 }
2530
2531 static GPUVertBuf *mesh_create_facedot_select_id(
2532         MeshRenderData *rdata, uint select_id_offset)
2533 {
2534         BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
2535
2536         GPUVertBuf *vbo;
2537         {
2538                 static GPUVertFormat format = { 0 };
2539                 static struct { uint pos, col; } attr_id;
2540                 if (format.attr_len == 0) {
2541                         attr_id.col = GPU_vertformat_attr_add(&format, "color", GPU_COMP_I32, 1, GPU_FETCH_INT);
2542                 }
2543
2544                 const int vbo_len_capacity = mesh_render_data_polys_len_get(rdata);
2545                 int vidx = 0;
2546
2547                 vbo = GPU_vertbuf_create_with_format(&format);
2548                 GPU_vertbuf_data_alloc(vbo, vbo_len_capacity);
2549                 uint select_index = select_id_offset;
2550
2551                 if (rdata->edit_bmesh) {
2552                         BMesh *bm = rdata->edit_bmesh->bm;
2553                         BMIter iter;
2554                         BMEdge *efa;
2555
2556                         BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
2557                                 if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
2558                                         int select_id;
2559                                         GPU_select_index_get(select_index, &select_id);
2560                                         GPU_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id);
2561                                         vidx += 1;
2562                                 }
2563                                 select_index += 1;
2564                         }
2565                 }
2566                 else {
2567                         /* not yet done! */
2568                         BLI_assert(0);
2569                 }
2570                 const int vbo_len_used = vidx;
2571                 if (vbo_len_used != vbo_len_capacity) {
2572                         GPU_vertbuf_data_resize(vbo, vbo_len_used);
2573                 }
2574         }
2575
2576         return vbo;
2577 }
2578
2579 static GPUVertBuf *mesh_create_edges_select_id(
2580         MeshRenderData *rdata, uint select_id_offset)
2581 {
2582         BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_EDGE));
2583
2584         GPUVertBuf *vbo;
2585         {
2586                 static GPUVertFormat format = { 0 };
2587                 static struct { uint pos, col; } attr_id;
2588                 if (format.attr_len == 0) {
2589                         attr_id.col = GPU_vertformat_attr_add(&format, "color", GPU_COMP_I32, 1, GPU_FETCH_INT);
2590                 }
2591
2592                 const int vbo_len_capacity = mesh_render_data_edges_len_get(rdata) * 2;
2593                 int vidx = 0;
2594
2595                 vbo = GPU_vertbuf_create_with_format(&format);
2596                 GPU_vertbuf_data_alloc(vbo, vbo_len_capacity);
2597                 uint select_index = select_id_offset;
2598
2599                 if (rdata->edit_bmesh) {
2600                         BMesh *bm = rdata->edit_bmesh->bm;
2601                         BMIter iter;
2602                         BMEdge *eed;
2603
2604                         BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
2605                                 if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
2606                                         int select_id;
2607                                         GPU_select_index_get(select_index, &select_id);
2608                                         GPU_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id);
2609                                         vidx += 1;
2610                                         GPU_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id);
2611                                         vidx += 1;
2612                                 }
2613                                 select_index += 1;
2614                         }
2615                 }
2616                 else {
2617                         /* not yet done! */
2618                         BLI_assert(0);
2619                 }
2620                 const int vbo_len_used = vidx;
2621                 if (vbo_len_used != vbo_len_capacity) {
2622                         GPU_vertbuf_data_resize(vbo, vbo_len_used);
2623                 }
2624         }
2625
2626         return vbo;
2627 }
2628
2629 static GPUVertBuf *mesh_create_verts_select_id(
2630         MeshRenderData *rdata, uint select_id_offset)
2631 {
2632         BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
2633
2634         GPUVertBuf *vbo;
2635         {
2636                 static GPUVertFormat format = { 0 };
2637                 static struct { uint pos, col; } attr_id;
2638                 if (format.attr_len == 0) {
2639                         attr_id.col = GPU_vertformat_attr_add(&format, "color", GPU_COMP_I32, 1, GPU_FETCH_INT);
2640                 }
2641
2642                 const int vbo_len_capacity = mesh_render_data_verts_len_get(rdata);
2643                 int vidx = 0;
2644
2645                 vbo = GPU_vertbuf_create_with_format(&format);
2646                 GPU_vertbuf_data_alloc(vbo, vbo_len_capacity);
2647                 uint select_index = select_id_offset;
2648
2649                 if (rdata->edit_bmesh) {
2650                         BMesh *bm = rdata->edit_bmesh->bm;
2651                         BMIter iter;
2652                         BMVert *eve;
2653
2654                         BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
2655                                 if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
2656                                         int select_id;
2657                                         GPU_select_index_get(select_index, &select_id);
2658                                         GPU_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id);
2659                                         vidx += 1;
2660                                 }
2661                                 select_index += 1;
2662                         }
2663                 }
2664                 else {
2665                         for (int i = 0; i < vbo_len_capacity; i++) {
2666                                 const MVert *mv = &rdata->mvert[i];
2667                                 if (!(mv->flag & ME_HIDE)) {
2668                                         int select_id;
2669                                         GPU_select_index_get(select_index, &select_id);
2670                                         GPU_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id);
2671                                         vidx += 1;
2672                                 }
2673                                 select_index += 1;
2674                         }
2675                 }
2676                 const int vbo_len_used = vidx;
2677                 if (vbo_len_used != vbo_len_capacity) {
2678                         GPU_vertbuf_data_resize(vbo, vbo_len_used);
2679                 }
2680         }
2681
2682         return vbo;
2683 }
2684
2685 static GPUVertBuf *mesh_create_tri_weights(
2686         MeshRenderData *rdata, bool use_hide, int defgroup)
2687 {
2688         BLI_assert(
2689                 rdata->types &
2690                 (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_DVERT));
2691
2692         GPUVertBuf *vbo;
2693         {
2694                 uint cidx = 0;
2695
2696                 static GPUVertFormat format = { 0 };
2697                 static struct { uint col; } attr_id;
2698                 if (format.attr_len == 0) {
2699                         attr_id.col = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
2700                 }
2701
2702                 vbo = GPU_vertbuf_create_with_format(&format);
2703
2704                 const int tri_len = mesh_render_data_looptri_len_get(rdata);
2705                 const int vbo_len_capacity = tri_len * 3;
2706                 int vbo_len_used = 0;
2707                 GPU_vertbuf_data_alloc(vbo, vbo_len_capacity);
2708
2709                 mesh_render_data_ensure_vert_weight_color(rdata, defgroup);
2710                 const float (*vert_weight_color)[3] = rdata->vert_weight_color;
2711
2712                 if (rdata->edit_bmesh) {
2713                         for (int i = 0; i < tri_len; i++) {
2714                                 const BMLoop **ltri = (const BMLoop **)rdata->edit_bmesh->looptris[i];
2715                                 /* Assume 'use_hide' */
2716                                 if (!BM_elem_flag_test(ltri[0]->f, BM_ELEM_HIDDEN)) {
2717                                         for (uint tri_corner = 0; tri_corner < 3; tri_corner++) {
2718                                                 const int v_index = BM_elem_index_get(ltri[tri_corner]->v);
2719                                                 GPU_vertbuf_attr_set(vbo, attr_id.col, cidx++, vert_weight_color[v_index]);
2720                                         }
2721                                 }
2722                         }
2723                 }
2724                 else {
2725                         for (int i = 0; i < tri_len; i++) {
2726                                 const MLoopTri *mlt = &rdata->mlooptri[i];
2727                                 if (!(use_hide && (rdata->mpoly[mlt->poly].flag & ME_HIDE))) {
2728                                         for (uint tri_corner = 0; tri_corner < 3; tri_corner++) {
2729                                                 const uint v_index = rdata->mloop[mlt->tri[tri_corner]].v;
2730                                                 GPU_vertbuf_attr_set(vbo, attr_id.col, cidx++, vert_weight_color[v_index]);
2731                                         }
2732                                 }
2733                         }
2734                 }
2735                 vbo_len_used = cidx;
2736
2737                 if (vbo_len_capacity != vbo_len_used) {
2738                         GPU_vertbuf_data_resize(vbo, vbo_len_used);
2739                 }
2740         }
2741
2742         return vbo;
2743 }
2744
2745 static GPUVertBuf *mesh_create_tri_vert_colors(
2746         MeshRenderData *rdata, bool use_hide)
2747 {
2748         BLI_assert(
2749                 rdata->types &
2750                 (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_LOOPCOL));
2751
2752         GPUVertBuf *vbo;
2753         {
2754                 uint cidx = 0;
2755
2756                 static GPUVertFormat format = { 0 };
2757                 static struct { uint col; } attr_id;
2758                 if (format.attr_len == 0) {
2759                         attr_id.col = GPU_vertformat_attr_add(&format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
2760                 }
2761
2762                 const int tri_len = mesh_render_data_looptri_len_get(rdata);
2763
2764                 vbo = GPU_vertbuf_create_with_format(&format);
2765
2766                 const uint vbo_len_capacity = tri_len * 3;
2767                 GPU_vertbuf_data_alloc(vbo, vbo_len_capacity);
2768
2769                 mesh_render_data_ensure_vert_color(rdata);
2770                 const char (*vert_color)[3] = rdata->vert_color;
2771
2772                 if (rdata->edit_bmesh) {
2773                         for (int i = 0; i < tri_len; i++) {
2774                                 const BMLoop **ltri = (const BMLoop **)rdata->edit_bmesh->looptris[i];
2775                                 /* Assume 'use_hide' */
2776                                 if (!BM_elem_flag_test(ltri[0]->f, BM_ELEM_HIDDEN)) {
2777                                         for (uint tri_corner = 0; tri_corner < 3; tri_corner++) {
2778                                                 const int l_index = BM_elem_index_get(ltri[tri_corner]);
2779                                                 GPU_vertbuf_attr_set(vbo, attr_id.col, cidx++, vert_color[l_index]);
2780                                         }
2781                                 }
2782                         }
2783                 }
2784                 else {
2785                         for (int i = 0; i < tri_len; i++) {
2786                                 const MLoopTri *mlt = &rdata->mlooptri[i];
2787                                 if (!(use_hide && (rdata->mpoly[mlt->poly].flag & ME_HIDE))) {
2788                                         for (uint tri_corner = 0; tri_corner < 3; tri_corner++) {
2789                                                 const uint l_index = mlt->tri[tri_corner];
2790                                                 GPU_vertbuf_attr_set(vbo, attr_id.col, cidx++, vert_color[l_index]);
2791                                         }
2792                                 }
2793                         }
2794                 }
2795                 const uint vbo_len_used = cidx;
2796
2797                 if (vbo_len_capacity != vbo_len_used) {
2798                         GPU_vertbuf_data_resize(vbo, vbo_len_used);
2799                 }
2800         }
2801
2802         return vbo;
2803 }
2804
2805 static GPUVertBuf *mesh_create_tri_select_id(
2806         MeshRenderData *rdata, bool use_hide, uint select_id_offset)
2807 {
2808         BLI_assert(
2809                 rdata->types &
2810                 (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
2811
2812         GPUVertBuf *vbo;
2813         {
2814                 uint cidx = 0;
2815
2816                 static GPUVertFormat format = { 0 };
2817                 static struct { uint col; } attr_id;
2818                 if (format.attr_len == 0) {
2819                         attr_id.col = GPU_vertformat_attr_add(&format, "color", GPU_COMP_I32, 1, GPU_FETCH_INT);
2820                 }
2821
2822                 const int tri_len = mesh_render_data_looptri_len_get(rdata);
2823
2824                 vbo = GPU_vertbuf_create_with_format(&format);
2825
2826                 const int vbo_len_capacity = tri_len * 3;
2827                 int vbo_len_used = 0;
2828                 GPU_vertbuf_data_alloc(vbo, vbo_len_capacity);
2829
2830                 if (rdata->edit_bmesh) {
2831                         for (int i = 0; i < tri_len; i++) {
2832                                 const BMLoop **ltri = (const BMLoop **)rdata->edit_bmesh->looptris[i];
2833                                 /* Assume 'use_hide' */
2834                                 if (!BM_elem_flag_test(ltri[0]->f, BM_ELEM_HIDDEN)) {
2835                                         const int poly_index = BM_elem_index_get(ltri[0]->f);
2836                                         int select_id;
2837                                         GPU_select_index_get(poly_index + select_id_offset, &select_id);
2838                                         for (uint tri_corner = 0; tri_corner < 3; tri_corner++) {
2839                                                 GPU_vertbuf_attr_set(vbo, attr_id.col, cidx++, &select_id);
2840                                         }
2841                                 }
2842                         }
2843                 }
2844                 else {
2845                         for (int i = 0; i < tri_len; i++) {
2846                                 const MLoopTri *mlt = &rdata->mlooptri[i];
2847                                 const int poly_index = mlt->poly;
2848                                 if (!(use_hide && (rdata->mpoly[poly_index].flag & ME_HIDE))) {
2849                                         int select_id;
2850                                         GPU_select_index_get(poly_index + select_id_offset, &select_id);
2851                                         for (uint tri_corner = 0; tri_corner < 3; tri_corner++) {
2852                                                 GPU_vertbuf_attr_set(vbo, attr_id.col, cidx++, &select_id);
2853                                         }
2854                                 }
2855                         }
2856                 }
2857                 vbo_len_used = cidx;
2858
2859                 if (vbo_len_capacity != vbo_len_used) {
2860                         GPU_vertbuf_data_resize(vbo, vbo_len_used);
2861                 }
2862         }
2863         return vbo;
2864 }
2865
2866 static GPUVertBuf *mesh_batch_cache_get_vert_pos_and_nor_in_order(
2867         MeshRenderData *rdata, MeshBatchCache *cache)
2868 {
2869         BLI_assert(rdata->types & MR_DATATYPE_VERT);
2870
2871         if (cache->pos_in_order == NULL) {
2872                 static GPUVertFormat format = { 0 };
2873                 static struct { uint pos, nor; } attr_id;
2874                 if (format.attr_len == 0) {
2875                         /* Normal is padded so that the vbo can be used as a buffer texture */
2876                         attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
2877                         attr_id.nor = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_I16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
2878                 }
2879
2880                 GPUVertBuf *vbo = cache->pos_in_order = GPU_vertbuf_create_with_format(&format);
2881                 const int vbo_len_capacity = mesh_render_data_verts_len_get(rdata);
2882                 GPU_vertbuf_data_alloc(vbo, vbo_len_capacity);