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