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