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