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