Merge branch 'master' into blender2.8
[blender.git] / source / blender / blenkernel / intern / editderivedmesh.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) 2005 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/blenkernel/intern/editderivedmesh.c
29  *  \ingroup bke
30  *
31  * basic design:
32  *
33  * the bmesh derivedmesh exposes the mesh as triangles.  it stores pointers
34  * to three loops per triangle.  the derivedmesh stores a cache of tessellations
35  * for each face.  this cache will smartly update as needed (though at first
36  * it'll simply be more brute force).  keeping track of face/edge counts may
37  * be a small problem.
38  *
39  * this won't be the most efficient thing, considering that internal edges and
40  * faces of tessellations are exposed.  looking up an edge by index in particular
41  * is likely to be a little slow.
42  */
43
44 #include "BLI_math.h"
45 #include "BLI_jitter.h"
46 #include "BLI_bitmap.h"
47 #include "BLI_task.h"
48
49 #include "BKE_cdderivedmesh.h"
50 #include "BKE_mesh.h"
51 #include "BKE_editmesh.h"
52 #include "BKE_editmesh_bvh.h"
53
54 #include "DNA_scene_types.h"
55 #include "DNA_object_types.h"
56
57 #include "MEM_guardedalloc.h"
58
59 #include "GPU_glew.h"
60 #include "GPU_buffers.h"
61 #include "GPU_shader.h"
62 #include "GPU_basic_shader.h"
63
64 static void bmdm_get_tri_colpreview(BMLoop *ls[3], MLoopCol *lcol[3], unsigned char(*color_vert_array)[4]);
65
66 typedef struct EditDerivedBMesh {
67         DerivedMesh dm;
68
69         BMEditMesh *em;
70
71         /** when set, \a vertexNos, polyNos are lazy initialized */
72         const float (*vertexCos)[3];
73
74         /** lazy initialize (when \a vertexCos is set) */
75         float const (*vertexNos)[3];
76         float const (*polyNos)[3];
77         /** also lazy init but dont depend on \a vertexCos */
78         const float (*polyCos)[3];
79 } EditDerivedBMesh;
80
81 /* -------------------------------------------------------------------- */
82 /* Lazy initialize datastructures */
83
84 static void emDM_ensurePolyNormals(EditDerivedBMesh *bmdm);
85
86 static void emDM_ensureVertNormals(EditDerivedBMesh *bmdm)
87 {
88         if (bmdm->vertexCos && (bmdm->vertexNos == NULL)) {
89
90                 BMesh *bm = bmdm->em->bm;
91                 const float (*vertexCos)[3], (*polyNos)[3];
92                 float (*vertexNos)[3];
93
94                 /* calculate vertex normals from poly normals */
95                 emDM_ensurePolyNormals(bmdm);
96
97                 BM_mesh_elem_index_ensure(bm, BM_FACE);
98
99                 polyNos = bmdm->polyNos;
100                 vertexCos = bmdm->vertexCos;
101                 vertexNos = MEM_callocN(sizeof(*vertexNos) * bm->totvert, __func__);
102
103                 BM_verts_calc_normal_vcos(bm, polyNos, vertexCos, vertexNos);
104
105                 bmdm->vertexNos = (const float (*)[3])vertexNos;
106         }
107 }
108
109 static void emDM_ensurePolyNormals(EditDerivedBMesh *bmdm)
110 {
111         if (bmdm->vertexCos && (bmdm->polyNos == NULL)) {
112                 BMesh *bm = bmdm->em->bm;
113                 const float (*vertexCos)[3];
114                 float (*polyNos)[3];
115
116                 BMFace *efa;
117                 BMIter fiter;
118                 int i;
119
120                 BM_mesh_elem_index_ensure(bm, BM_VERT);
121
122                 polyNos = MEM_mallocN(sizeof(*polyNos) * bm->totface, __func__);
123
124                 vertexCos = bmdm->vertexCos;
125
126                 BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) {
127                         BM_elem_index_set(efa, i); /* set_inline */
128                         BM_face_calc_normal_vcos(bm, efa, polyNos[i], vertexCos);
129                 }
130                 bm->elem_index_dirty &= ~BM_FACE;
131
132                 bmdm->polyNos = (const float (*)[3])polyNos;
133         }
134 }
135
136 static void emDM_ensurePolyCenters(EditDerivedBMesh *bmdm)
137 {
138         if (bmdm->polyCos == NULL) {
139                 BMesh *bm = bmdm->em->bm;
140                 float (*polyCos)[3];
141
142                 BMFace *efa;
143                 BMIter fiter;
144                 int i;
145
146                 polyCos = MEM_mallocN(sizeof(*polyCos) * bm->totface, __func__);
147
148                 if (bmdm->vertexCos) {
149                         const float (*vertexCos)[3];
150                         vertexCos = bmdm->vertexCos;
151
152                         BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) {
153                                 BM_face_calc_center_mean_vcos(bm, efa, polyCos[i], vertexCos);
154                         }
155                 }
156                 else {
157                         BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) {
158                                 BM_face_calc_center_mean(efa, polyCos[i]);
159                         }
160                 }
161
162                 bmdm->polyCos = (const float (*)[3])polyCos;
163         }
164 }
165
166 static void emDM_calcNormals(DerivedMesh *dm)
167 {
168         /* Nothing to do: normals are already calculated and stored on the
169          * BMVerts and BMFaces */
170         dm->dirty &= ~DM_DIRTY_NORMALS;
171 }
172
173 static void emDM_calcLoopNormalsSpaceArray(
174         DerivedMesh *dm, const bool use_split_normals, const float split_angle, MLoopNorSpaceArray *r_lnors_spacearr);
175
176 static void emDM_calcLoopNormals(DerivedMesh *dm, const bool use_split_normals, const float split_angle)
177 {
178         emDM_calcLoopNormalsSpaceArray(dm, use_split_normals, split_angle, NULL);
179 }
180
181 /* #define DEBUG_CLNORS */
182
183 static void emDM_calcLoopNormalsSpaceArray(
184         DerivedMesh *dm, const bool use_split_normals, const float split_angle, MLoopNorSpaceArray *r_lnors_spacearr)
185 {
186         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
187         BMesh *bm = bmdm->em->bm;
188         const float (*vertexCos)[3], (*vertexNos)[3], (*polyNos)[3];
189         float (*loopNos)[3];
190         short (*clnors_data)[2];
191         int cd_loop_clnors_offset;
192
193         /* calculate loop normals from poly and vertex normals */
194         emDM_ensureVertNormals(bmdm);
195         emDM_ensurePolyNormals(bmdm);
196         dm->dirty &= ~DM_DIRTY_NORMALS;
197
198         vertexCos = bmdm->vertexCos;
199         vertexNos = bmdm->vertexNos;
200         polyNos = bmdm->polyNos;
201
202         loopNos = dm->getLoopDataArray(dm, CD_NORMAL);
203         if (!loopNos) {
204                 DM_add_loop_layer(dm, CD_NORMAL, CD_CALLOC, NULL);
205                 loopNos = dm->getLoopDataArray(dm, CD_NORMAL);
206         }
207
208         /* We can have both, give priority to dm's data, and fallback to bm's ones. */
209         clnors_data = dm->getLoopDataArray(dm, CD_CUSTOMLOOPNORMAL);
210         cd_loop_clnors_offset = clnors_data ? -1 : CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL);
211
212         BM_loops_calc_normal_vcos(bm, vertexCos, vertexNos, polyNos, use_split_normals, split_angle, loopNos,
213                                   r_lnors_spacearr, clnors_data, cd_loop_clnors_offset);
214 #ifdef DEBUG_CLNORS
215         if (r_lnors_spacearr) {
216                 int i;
217                 for (i = 0; i < numLoops; i++) {
218                         if (r_lnors_spacearr->lspacearr[i]->ref_alpha != 0.0f) {
219                                 LinkNode *loops = r_lnors_spacearr->lspacearr[i]->loops;
220                                 printf("Loop %d uses lnor space %p:\n", i, r_lnors_spacearr->lspacearr[i]);
221                                 print_v3("\tfinal lnor:", loopNos[i]);
222                                 print_v3("\tauto lnor:", r_lnors_spacearr->lspacearr[i]->vec_lnor);
223                                 print_v3("\tref_vec:", r_lnors_spacearr->lspacearr[i]->vec_ref);
224                                 printf("\talpha: %f\n\tbeta: %f\n\tloops: %p\n", r_lnors_spacearr->lspacearr[i]->ref_alpha,
225                                        r_lnors_spacearr->lspacearr[i]->ref_beta, r_lnors_spacearr->lspacearr[i]->loops);
226                                 printf("\t\t(shared with loops");
227                                 while (loops) {
228                                         printf(" %d", GET_INT_FROM_POINTER(loops->link));
229                                         loops = loops->next;
230                                 }
231                                 printf(")\n");
232                         }
233                         else {
234                                 printf("Loop %d has no lnor space\n", i);
235                         }
236                 }
237         }
238 #endif
239 }
240
241
242 /** \name Tangent Space Calculation
243  * \{ */
244
245 /* Necessary complexity to handle looptri's as quads for correct tangents */
246 #define USE_LOOPTRI_DETECT_QUADS
247
248 typedef struct {
249         const float (*precomputedFaceNormals)[3];
250         const float (*precomputedLoopNormals)[3];
251         const BMLoop *(*looptris)[3];
252         int cd_loop_uv_offset;   /* texture coordinates */
253         const float (*orco)[3];
254         float (*tangent)[4];    /* destination */
255         int numTessFaces;
256
257 #ifdef USE_LOOPTRI_DETECT_QUADS
258         /* map from 'fake' face index to looptri,
259          * quads will point to the first looptri of the quad */
260         const int    *face_as_quad_map;
261         int       num_face_as_quad_map;
262 #endif
263
264 } SGLSLEditMeshToTangent;
265
266 #ifdef USE_LOOPTRI_DETECT_QUADS
267 /* seems weak but only used on quads */
268 static const BMLoop *bm_loop_at_face_index(const BMFace *f, int vert_index)
269 {
270         const BMLoop *l = BM_FACE_FIRST_LOOP(f);
271         while (vert_index--) {
272                 l = l->next;
273         }
274         return l;
275 }
276 #endif
277
278 /* interface */
279 #include "mikktspace.h"
280
281 static int emdm_ts_GetNumFaces(const SMikkTSpaceContext *pContext)
282 {
283         SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
284
285 #ifdef USE_LOOPTRI_DETECT_QUADS
286         return pMesh->num_face_as_quad_map;
287 #else
288         return pMesh->numTessFaces;
289 #endif
290 }
291
292 static int emdm_ts_GetNumVertsOfFace(const SMikkTSpaceContext *pContext, const int face_num)
293 {
294 #ifdef USE_LOOPTRI_DETECT_QUADS
295         SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
296         if (pMesh->face_as_quad_map) {
297                 const BMLoop **lt = pMesh->looptris[pMesh->face_as_quad_map[face_num]];
298                 if (lt[0]->f->len == 4) {
299                         return 4;
300                 }
301         }
302         return 3;
303 #else
304         UNUSED_VARS(pContext, face_num);
305         return 3;
306 #endif
307 }
308
309 static void emdm_ts_GetPosition(
310         const SMikkTSpaceContext *pContext, float r_co[3],
311         const int face_num, const int vert_index)
312 {
313         //assert(vert_index >= 0 && vert_index < 4);
314         SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
315         const BMLoop **lt;
316         const BMLoop *l;
317
318 #ifdef USE_LOOPTRI_DETECT_QUADS
319         if (pMesh->face_as_quad_map) {
320                 lt = pMesh->looptris[pMesh->face_as_quad_map[face_num]];
321                 if (lt[0]->f->len == 4) {
322                         l = bm_loop_at_face_index(lt[0]->f, vert_index);
323                         goto finally;
324                 }
325                 /* fall through to regular triangle */
326         }
327         else {
328                 lt = pMesh->looptris[face_num];
329         }
330 #else
331         lt = pMesh->looptris[face_num];
332 #endif
333         l = lt[vert_index];
334
335         const float *co;
336
337 finally:
338         co = l->v->co;
339         copy_v3_v3(r_co, co);
340 }
341
342 static void emdm_ts_GetTextureCoordinate(
343         const SMikkTSpaceContext *pContext, float r_uv[2],
344         const int face_num, const int vert_index)
345 {
346         //assert(vert_index >= 0 && vert_index < 4);
347         SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
348         const BMLoop **lt;
349         const BMLoop *l;
350
351 #ifdef USE_LOOPTRI_DETECT_QUADS
352         if (pMesh->face_as_quad_map) {
353                 lt = pMesh->looptris[pMesh->face_as_quad_map[face_num]];
354                 if (lt[0]->f->len == 4) {
355                         l = bm_loop_at_face_index(lt[0]->f, vert_index);
356                         goto finally;
357                 }
358                 /* fall through to regular triangle */
359         }
360         else {
361                 lt = pMesh->looptris[face_num];
362         }
363 #else
364         lt = pMesh->looptris[face_num];
365 #endif
366         l = lt[vert_index];
367
368 finally:
369         if (pMesh->cd_loop_uv_offset != -1) {
370                 const float *uv = BM_ELEM_CD_GET_VOID_P(l, pMesh->cd_loop_uv_offset);
371                 copy_v2_v2(r_uv, uv);
372         }
373         else {
374                 const float *orco = pMesh->orco[BM_elem_index_get(l->v)];
375                 map_to_sphere(&r_uv[0], &r_uv[1], orco[0], orco[1], orco[2]);
376         }
377 }
378
379 static void emdm_ts_GetNormal(
380         const SMikkTSpaceContext *pContext, float r_no[3],
381         const int face_num, const int vert_index)
382 {
383         //assert(vert_index >= 0 && vert_index < 4);
384         SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
385         const BMLoop **lt;
386         const BMLoop *l;
387
388 #ifdef USE_LOOPTRI_DETECT_QUADS
389         if (pMesh->face_as_quad_map) {
390                 lt = pMesh->looptris[pMesh->face_as_quad_map[face_num]];
391                 if (lt[0]->f->len == 4) {
392                         l = bm_loop_at_face_index(lt[0]->f, vert_index);
393                         goto finally;
394                 }
395                 /* fall through to regular triangle */
396         }
397         else {
398                 lt = pMesh->looptris[face_num];
399         }
400 #else
401         lt = pMesh->looptris[face_num];
402 #endif
403         l = lt[vert_index];
404
405 finally:
406         if (pMesh->precomputedLoopNormals) {
407                 copy_v3_v3(r_no, pMesh->precomputedLoopNormals[BM_elem_index_get(l)]);
408         }
409         else if (BM_elem_flag_test(l->f, BM_ELEM_SMOOTH) == 0) {  /* flat */
410                 if (pMesh->precomputedFaceNormals) {
411                         copy_v3_v3(r_no, pMesh->precomputedFaceNormals[BM_elem_index_get(l->f)]);
412                 }
413                 else {
414                         copy_v3_v3(r_no, l->f->no);
415                 }
416         }
417         else {
418                 copy_v3_v3(r_no, l->v->no);
419         }
420 }
421
422 static void emdm_ts_SetTSpace(
423         const SMikkTSpaceContext *pContext, const float fvTangent[3], const float fSign,
424         const int face_num, const int vert_index)
425 {
426         //assert(vert_index >= 0 && vert_index < 4);
427         SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
428         const BMLoop **lt;
429         const BMLoop *l;
430
431 #ifdef USE_LOOPTRI_DETECT_QUADS
432         if (pMesh->face_as_quad_map) {
433                 lt = pMesh->looptris[pMesh->face_as_quad_map[face_num]];
434                 if (lt[0]->f->len == 4) {
435                         l = bm_loop_at_face_index(lt[0]->f, vert_index);
436                         goto finally;
437                 }
438                 /* fall through to regular triangle */
439         }
440         else {
441                 lt = pMesh->looptris[face_num];
442         }
443 #else
444         lt = pMesh->looptris[face_num];
445 #endif
446         l = lt[vert_index];
447
448         float *pRes;
449
450 finally:
451         pRes = pMesh->tangent[BM_elem_index_get(l)];
452         copy_v3_v3(pRes, fvTangent);
453         pRes[3] = fSign;
454 }
455
456 static void emDM_calc_loop_tangents_thread(TaskPool *UNUSED(pool), void *taskdata, int UNUSED(threadid))
457 {
458         struct SGLSLEditMeshToTangent *mesh2tangent = taskdata;
459         /* new computation method */
460         {
461                 SMikkTSpaceContext sContext = {NULL};
462                 SMikkTSpaceInterface sInterface = {NULL};
463                 sContext.m_pUserData = mesh2tangent;
464                 sContext.m_pInterface = &sInterface;
465                 sInterface.m_getNumFaces = emdm_ts_GetNumFaces;
466                 sInterface.m_getNumVerticesOfFace = emdm_ts_GetNumVertsOfFace;
467                 sInterface.m_getPosition = emdm_ts_GetPosition;
468                 sInterface.m_getTexCoord = emdm_ts_GetTextureCoordinate;
469                 sInterface.m_getNormal = emdm_ts_GetNormal;
470                 sInterface.m_setTSpaceBasic = emdm_ts_SetTSpace;
471                 /* 0 if failed */
472                 genTangSpaceDefault(&sContext);
473         }
474 }
475
476 /**
477  * \see #DM_calc_loop_tangents, same logic but used arrays instead of #BMesh data.
478  *
479  * \note This function is not so normal, its using `bm->ldata` as input, but output's to `dm->loopData`.
480  * This is done because #CD_TANGENT is cache data used only for drawing.
481  */
482
483 static void emDM_calc_loop_tangents(
484         DerivedMesh *dm, bool calc_active_tangent,
485         const char (*tangent_names)[MAX_NAME], int tangent_names_count)
486 {
487         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
488         BMEditMesh *em = bmdm->em;
489         BMesh *bm = bmdm->em->bm;
490         if (CustomData_number_of_layers(&bm->ldata, CD_MLOOPUV) == 0)
491                 return;
492
493         int act_uv_n = -1;
494         int ren_uv_n = -1;
495         bool calc_act = false;
496         bool calc_ren = false;
497         char act_uv_name[MAX_NAME];
498         char ren_uv_name[MAX_NAME];
499         char tangent_mask = 0;
500
501         DM_calc_loop_tangents_step_0(
502                 &bm->ldata, calc_active_tangent, tangent_names, tangent_names_count,
503                 &calc_act, &calc_ren, &act_uv_n, &ren_uv_n, act_uv_name, ren_uv_name, &tangent_mask);
504
505         if ((dm->tangent_mask | tangent_mask) != dm->tangent_mask) {
506                 for (int i = 0; i < tangent_names_count; i++)
507                         if (tangent_names[i][0])
508                                 DM_add_named_tangent_layer_for_uv(&bm->ldata, &dm->loopData, dm->numLoopData, tangent_names[i]);
509                 if (calc_act && act_uv_name[0])
510                         DM_add_named_tangent_layer_for_uv(&bm->ldata, &dm->loopData, dm->numLoopData, act_uv_name);
511                 if (calc_ren && ren_uv_name[0])
512                         DM_add_named_tangent_layer_for_uv(&bm->ldata, &dm->loopData, dm->numLoopData, ren_uv_name);
513                 int totface = em->tottri;
514 #ifdef USE_LOOPTRI_DETECT_QUADS
515                 int num_face_as_quad_map;
516                 int *face_as_quad_map = NULL;
517
518                 /* map faces to quads */
519                 if (bmdm->em->tottri != bm->totface) {
520                         /* over alloc, since we dont know how many ngon or quads we have */
521
522                         /* map fake face index to looptri */
523                         face_as_quad_map = MEM_mallocN(sizeof(int) * totface, __func__);
524                         int i, j;
525                         for (i = 0, j = 0; j < totface; i++, j++) {
526                                 face_as_quad_map[i] = j;
527                                 /* step over all quads */
528                                 if (em->looptris[j][0]->f->len == 4) {
529                                         j++;  /* skips the nest looptri */
530                                 }
531                         }
532                         num_face_as_quad_map = i;
533                 }
534                 else {
535                         num_face_as_quad_map = totface;
536                 }
537 #endif
538                 /* Calculation */
539                 {
540                         TaskScheduler *scheduler = BLI_task_scheduler_get();
541                         TaskPool *task_pool;
542                         task_pool = BLI_task_pool_create(scheduler, NULL);
543
544                         dm->tangent_mask = 0;
545                         /* Calculate tangent layers */
546                         SGLSLEditMeshToTangent data_array[MAX_MTFACE];
547                         int index = 0;
548                         int n = 0;
549                         CustomData_update_typemap(&dm->loopData);
550                         const int tangent_layer_num = CustomData_number_of_layers(&dm->loopData, CD_TANGENT);
551                         for (n = 0; n < tangent_layer_num; n++) {
552                                 index = CustomData_get_layer_index_n(&dm->loopData, CD_TANGENT, n);
553                                 BLI_assert(n < MAX_MTFACE);
554                                 SGLSLEditMeshToTangent *mesh2tangent = &data_array[n];
555                                 mesh2tangent->numTessFaces = em->tottri;
556 #ifdef USE_LOOPTRI_DETECT_QUADS
557                                 mesh2tangent->face_as_quad_map = face_as_quad_map;
558                                 mesh2tangent->num_face_as_quad_map = num_face_as_quad_map;
559 #endif
560                                 mesh2tangent->precomputedFaceNormals = bmdm->polyNos;  /* dm->getPolyDataArray(dm, CD_NORMAL) */
561                                 /* Note, we assume we do have tessellated loop normals at this point (in case it is object-enabled),
562                                  * have to check this is valid...
563                                  */
564                                 mesh2tangent->precomputedLoopNormals = CustomData_get_layer(&dm->loopData, CD_NORMAL);
565                                 mesh2tangent->cd_loop_uv_offset = CustomData_get_n_offset(&bm->ldata, CD_MLOOPUV, n);
566
567                                 /* needed for indexing loop-tangents */
568                                 int htype_index = BM_LOOP;
569                                 if (mesh2tangent->cd_loop_uv_offset == -1) {
570                                         mesh2tangent->orco = dm->getVertDataArray(dm, CD_ORCO);
571                                         if (!mesh2tangent->orco)
572                                                 continue;
573                                         /* needed for orco lookups */
574                                         htype_index |= BM_VERT;
575                                 }
576                                 if (mesh2tangent->precomputedFaceNormals) {
577                                         /* needed for face normal lookups */
578                                         htype_index |= BM_FACE;
579                                 }
580                                 BM_mesh_elem_index_ensure(bm, htype_index);
581
582                                 mesh2tangent->looptris = (const BMLoop *(*)[3])em->looptris;
583                                 mesh2tangent->tangent = dm->loopData.layers[index].data;
584
585                                 /* Fill the resulting tangent_mask */
586                                 int uv_ind = CustomData_get_named_layer_index(&bm->ldata, CD_MLOOPUV, dm->loopData.layers[index].name);
587                                 int uv_start = CustomData_get_layer_index(&bm->ldata, CD_MLOOPUV);
588                                 BLI_assert(uv_ind != -1 && uv_start != -1);
589                                 BLI_assert(uv_ind - uv_start < MAX_MTFACE);
590                                 dm->tangent_mask |= 1 << (uv_ind - uv_start);
591                                 BLI_task_pool_push(task_pool, emDM_calc_loop_tangents_thread, mesh2tangent, false, TASK_PRIORITY_LOW);
592                         }
593
594                         BLI_assert(dm->tangent_mask == tangent_mask);
595                         BLI_task_pool_work_and_wait(task_pool);
596                         BLI_task_pool_free(task_pool);
597                 }
598 #ifdef USE_LOOPTRI_DETECT_QUADS
599                 if (face_as_quad_map) {
600                         MEM_freeN(face_as_quad_map);
601                 }
602 #undef USE_LOOPTRI_DETECT_QUADS
603 #endif
604         }
605         /* Update active layer index */
606         int uv_index = CustomData_get_layer_index_n(&bm->ldata, CD_MLOOPUV, act_uv_n);
607         int tan_index = CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, bm->ldata.layers[uv_index].name);
608         CustomData_set_layer_active_index(&dm->loopData, CD_TANGENT, tan_index);
609
610         /* Update render layer index */
611         uv_index = CustomData_get_layer_index_n(&bm->ldata, CD_MLOOPUV, ren_uv_n);
612         tan_index = CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, bm->ldata.layers[uv_index].name);
613         CustomData_set_layer_render_index(&dm->loopData, CD_TANGENT, tan_index);
614 }
615
616 /** \} */
617
618
619 static void emDM_recalcTessellation(DerivedMesh *UNUSED(dm))
620 {
621         /* do nothing */
622 }
623
624 static void emDM_recalcLoopTri(DerivedMesh *UNUSED(dm))
625 {
626         /* Nothing to do: emDM tessellation is known,
627          * allocate and fill in with emDM_getLoopTriArray */
628 }
629
630 static const MLoopTri *emDM_getLoopTriArray(DerivedMesh *dm)
631 {
632         if (dm->looptris.array) {
633                 BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
634         }
635         else {
636                 EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
637                 BMLoop *(*looptris)[3] = bmdm->em->looptris;
638                 MLoopTri *mlooptri;
639                 const int tottri = bmdm->em->tottri;
640                 int i;
641
642                 DM_ensure_looptri_data(dm);
643                 mlooptri = dm->looptris.array;
644
645                 BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
646                 BLI_assert(tottri == dm->looptris.num);
647
648                 BM_mesh_elem_index_ensure(bmdm->em->bm, BM_FACE | BM_LOOP);
649
650                 for (i = 0; i < tottri; i++) {
651                         BMLoop **ltri = looptris[i];
652                         MLoopTri *lt = &mlooptri[i];
653
654                         ARRAY_SET_ITEMS(
655                                 lt->tri,
656                                 BM_elem_index_get(ltri[0]),
657                                 BM_elem_index_get(ltri[1]),
658                                 BM_elem_index_get(ltri[2]));
659                         lt->poly = BM_elem_index_get(ltri[0]->f);
660                 }
661         }
662         return dm->looptris.array;
663 }
664
665 static void emDM_foreachMappedVert(
666         DerivedMesh *dm,
667         void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]),
668         void *userData,
669         DMForeachFlag flag)
670 {
671         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
672         BMesh *bm = bmdm->em->bm;
673         BMVert *eve;
674         BMIter iter;
675         int i;
676
677         if (bmdm->vertexCos) {
678                 const float (*vertexCos)[3] = bmdm->vertexCos;
679                 const float (*vertexNos)[3];
680
681                 if (flag & DM_FOREACH_USE_NORMAL) {
682                         emDM_ensureVertNormals(bmdm);
683                         vertexNos = bmdm->vertexNos;
684                 }
685                 else {
686                         vertexNos = NULL;
687                 }
688
689                 BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
690                         const float *no = (flag & DM_FOREACH_USE_NORMAL) ? vertexNos[i] : NULL;
691                         func(userData, i, vertexCos[i], no, NULL);
692                 }
693         }
694         else {
695                 BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
696                         const float *no = (flag & DM_FOREACH_USE_NORMAL) ? eve->no : NULL;
697                         func(userData, i, eve->co, no, NULL);
698                 }
699         }
700 }
701 static void emDM_foreachMappedEdge(
702         DerivedMesh *dm,
703         void (*func)(void *userData, int index, const float v0co[3], const float v1co[3]),
704         void *userData)
705 {
706         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
707         BMesh *bm = bmdm->em->bm;
708         BMEdge *eed;
709         BMIter iter;
710         int i;
711
712         if (bmdm->vertexCos) {
713
714                 BM_mesh_elem_index_ensure(bm, BM_VERT);
715
716                 BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) {
717                         func(userData, i,
718                              bmdm->vertexCos[BM_elem_index_get(eed->v1)],
719                              bmdm->vertexCos[BM_elem_index_get(eed->v2)]);
720                 }
721         }
722         else {
723                 BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) {
724                         func(userData, i, eed->v1->co, eed->v2->co);
725                 }
726         }
727 }
728
729 static void emDM_drawMappedEdges(
730         DerivedMesh *dm,
731         DMSetDrawOptions setDrawOptions,
732         void *userData)
733 {
734         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
735         BMesh *bm = bmdm->em->bm;
736         BMEdge *eed;
737         BMIter iter;
738         int i;
739
740         if (bmdm->vertexCos) {
741
742                 BM_mesh_elem_index_ensure(bm, BM_VERT);
743
744                 glBegin(GL_LINES);
745                 BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) {
746                         if (!setDrawOptions || (setDrawOptions(userData, i) != DM_DRAW_OPTION_SKIP)) {
747                                 glVertex3fv(bmdm->vertexCos[BM_elem_index_get(eed->v1)]);
748                                 glVertex3fv(bmdm->vertexCos[BM_elem_index_get(eed->v2)]);
749                         }
750                 }
751                 glEnd();
752         }
753         else {
754                 glBegin(GL_LINES);
755                 BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) {
756                         if (!setDrawOptions || (setDrawOptions(userData, i) != DM_DRAW_OPTION_SKIP)) {
757                                 glVertex3fv(eed->v1->co);
758                                 glVertex3fv(eed->v2->co);
759                         }
760                 }
761                 glEnd();
762         }
763 }
764 static void emDM_drawEdges(
765         DerivedMesh *dm,
766         bool UNUSED(drawLooseEdges),
767         bool UNUSED(drawAllEdges))
768 {
769         emDM_drawMappedEdges(dm, NULL, NULL);
770 }
771
772 static void emDM_drawMappedEdgesInterp(
773         DerivedMesh *dm,
774         DMSetDrawOptions setDrawOptions,
775         DMSetDrawInterpOptions setDrawInterpOptions,
776         void *userData)
777 {
778         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
779         BMesh *bm = bmdm->em->bm;
780         BMEdge *eed;
781         BMIter iter;
782         int i;
783
784         if (bmdm->vertexCos) {
785
786                 BM_mesh_elem_index_ensure(bm, BM_VERT);
787
788                 glBegin(GL_LINES);
789                 BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) {
790                         if (!setDrawOptions || (setDrawOptions(userData, i) != DM_DRAW_OPTION_SKIP)) {
791                                 setDrawInterpOptions(userData, i, 0.0);
792                                 glVertex3fv(bmdm->vertexCos[BM_elem_index_get(eed->v1)]);
793                                 setDrawInterpOptions(userData, i, 1.0);
794                                 glVertex3fv(bmdm->vertexCos[BM_elem_index_get(eed->v2)]);
795                         }
796                 }
797                 glEnd();
798         }
799         else {
800                 glBegin(GL_LINES);
801                 BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) {
802                         if (!setDrawOptions || (setDrawOptions(userData, i) != DM_DRAW_OPTION_SKIP)) {
803                                 setDrawInterpOptions(userData, i, 0.0);
804                                 glVertex3fv(eed->v1->co);
805                                 setDrawInterpOptions(userData, i, 1.0);
806                                 glVertex3fv(eed->v2->co);
807                         }
808                 }
809                 glEnd();
810         }
811 }
812
813 static void emDM_drawUVEdges(DerivedMesh *dm)
814 {
815         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
816         BMesh *bm = bmdm->em->bm;
817         BMFace *efa;
818         BMIter iter;
819
820         const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
821
822         if (UNLIKELY(cd_loop_uv_offset == -1)) {
823                 return;
824         }
825
826         glBegin(GL_LINES);
827         BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
828                 BMLoop *l_iter, *l_first;
829                 const float *uv, *uv_prev;
830
831                 if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN))
832                         continue;
833
834                 l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
835                 uv_prev = ((MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_iter->prev, cd_loop_uv_offset))->uv;
836                 do {
837                         uv = ((MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset))->uv;
838                         glVertex2fv(uv);
839                         glVertex2fv(uv_prev);
840                         uv_prev = uv;
841                 } while ((l_iter = l_iter->next) != l_first);
842         }
843         glEnd();
844 }
845
846 static void emDM_foreachMappedLoop(
847         DerivedMesh *dm,
848         void (*func)(void *userData, int vertex_index, int face_index, const float co[3], const float no[3]),
849         void *userData,
850         DMForeachFlag flag)
851 {
852         /* We can't use dm->getLoopDataLayout(dm) here, we want to always access dm->loopData, EditDerivedBMesh would
853          * return loop data from bmesh itself. */
854         const float (*lnors)[3] = (flag & DM_FOREACH_USE_NORMAL) ? DM_get_loop_data_layer(dm, CD_NORMAL) : NULL;
855
856         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
857         BMesh *bm = bmdm->em->bm;
858         BMFace *efa;
859         BMIter iter;
860
861         const float (*vertexCos)[3] = bmdm->vertexCos;
862         int f_idx;
863
864         BM_mesh_elem_index_ensure(bm, BM_VERT);
865
866         BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, f_idx) {
867                 BMLoop *l_iter, *l_first;
868
869                 l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
870                 do {
871                         const BMVert *eve = l_iter->v;
872                         const int v_idx = BM_elem_index_get(eve);
873                         const float *no = lnors ? *lnors++ : NULL;
874                         func(userData, v_idx, f_idx, vertexCos ? vertexCos[v_idx] : eve->co, no);
875                 } while ((l_iter = l_iter->next) != l_first);
876         }
877 }
878
879 static void emDM_foreachMappedFaceCenter(
880         DerivedMesh *dm,
881         void (*func)(void *userData, int index, const float co[3], const float no[3]),
882         void *userData,
883         DMForeachFlag flag)
884 {
885         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
886         BMesh *bm = bmdm->em->bm;
887         const float (*polyNos)[3];
888         const float (*polyCos)[3];
889         BMFace *efa;
890         BMIter iter;
891         int i;
892
893         emDM_ensurePolyCenters(bmdm);
894         polyCos = bmdm->polyCos;  /* always set */
895
896         if (flag & DM_FOREACH_USE_NORMAL) {
897                 emDM_ensurePolyNormals(bmdm);
898                 polyNos = bmdm->polyNos;  /* maybe NULL */
899         }
900         else {
901                 polyNos = NULL;
902         }
903
904         if (polyNos) {
905                 BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
906                         const float *no = polyNos[i];
907                         func(userData, i, polyCos[i], no);
908                 }
909         }
910         else {
911                 BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
912                         const float *no = (flag & DM_FOREACH_USE_NORMAL) ? efa->no : NULL;
913                         func(userData, i, polyCos[i], no);
914                 }
915         }
916 }
917
918 static void emDM_drawMappedFaces(
919         DerivedMesh *dm,
920         DMSetDrawOptions setDrawOptions,
921         DMSetMaterial setMaterial,
922         /* currently unused -- each original face is handled separately */
923         DMCompareDrawOptions UNUSED(compareDrawOptions),
924         void *userData,
925         DMDrawFlag flag)
926 {
927         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
928         BMEditMesh *em = bmdm->em;
929         BMesh *bm = em->bm;
930         BMFace *efa;
931         struct BMLoop *(*looptris)[3] = bmdm->em->looptris;
932         const int tottri = bmdm->em->tottri;
933         DMDrawOption draw_option;
934         int i;
935         const int skip_normals = !(flag & DM_DRAW_NEED_NORMALS);
936         const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
937         MLoopCol *lcol[3] = {NULL} /* , dummylcol = {0} */;
938         unsigned char(*color_vert_array)[4] = em->derivedVertColor;
939         unsigned char(*color_face_array)[4] = em->derivedFaceColor;
940         bool has_vcol_preview = (color_vert_array != NULL) && !skip_normals;
941         bool has_fcol_preview = (color_face_array != NULL) && !skip_normals;
942         bool has_vcol_any = has_vcol_preview;
943
944         /* GL_ZERO is used to detect if drawing has started or not */
945         GLenum poly_prev = GL_ZERO;
946         GLenum shade_prev = GL_ZERO;
947         DMDrawOption draw_option_prev = DM_DRAW_OPTION_SKIP;
948
949         /* call again below is ok */
950         if (has_vcol_preview) {
951                 BM_mesh_elem_index_ensure(bm, BM_VERT);
952         }
953         if (has_fcol_preview) {
954                 BM_mesh_elem_index_ensure(bm, BM_FACE);
955         }
956         if (has_vcol_preview || has_fcol_preview) {
957                 flag |= DM_DRAW_ALWAYS_SMOOTH;
958                 /* weak, this logic should really be moved higher up */
959                 setMaterial = NULL;
960         }
961
962         if (bmdm->vertexCos) {
963                 short prev_mat_nr = -1;
964
965                 /* add direct access */
966                 const float (*vertexCos)[3] = bmdm->vertexCos;
967                 const float (*vertexNos)[3];
968                 const float (*polyNos)[3];
969
970                 if (skip_normals) {
971                         vertexNos = NULL;
972                         polyNos = NULL;
973                 }
974                 else {
975                         emDM_ensureVertNormals(bmdm);
976                         emDM_ensurePolyNormals(bmdm);
977                         vertexNos = bmdm->vertexNos;
978                         polyNos = bmdm->polyNos;
979                 }
980
981                 BM_mesh_elem_index_ensure(bm, lnors ? BM_VERT | BM_FACE | BM_LOOP : BM_VERT | BM_FACE);
982
983                 for (i = 0; i < tottri; i++) {
984                         BMLoop **ltri = looptris[i];
985                         int drawSmooth;
986
987                         efa = ltri[0]->f;
988                         drawSmooth = lnors || ((flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : BM_elem_flag_test(efa, BM_ELEM_SMOOTH));
989
990                         draw_option = (!setDrawOptions ?
991                                        DM_DRAW_OPTION_NORMAL :
992                                        setDrawOptions(userData, BM_elem_index_get(efa)));
993                         if (draw_option != DM_DRAW_OPTION_SKIP) {
994                                 const GLenum poly_type = GL_TRIANGLES; /* BMESH NOTE, this is odd but keep it for now to match trunk */
995
996                                 if (draw_option_prev != draw_option) {
997                                         if (draw_option_prev == DM_DRAW_OPTION_STIPPLE) {
998                                                 if (poly_prev != GL_ZERO) glEnd();
999                                                 poly_prev = GL_ZERO; /* force glBegin */
1000
1001                                                 GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
1002                                         }
1003                                         draw_option_prev = draw_option;
1004                                 }
1005
1006
1007                                 if (efa->mat_nr != prev_mat_nr) {
1008                                         if (setMaterial) {
1009                                                 if (poly_prev != GL_ZERO) glEnd();
1010                                                 poly_prev = GL_ZERO; /* force glBegin */
1011
1012                                                 setMaterial(efa->mat_nr + 1, NULL);
1013                                         }
1014                                         prev_mat_nr = efa->mat_nr;
1015                                 }
1016
1017                                 if (draw_option == DM_DRAW_OPTION_STIPPLE) { /* enabled with stipple */
1018
1019                                         if (poly_prev != GL_ZERO) glEnd();
1020                                         poly_prev = GL_ZERO; /* force glBegin */
1021
1022                                         GPU_basic_shader_bind(GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR);
1023                                         GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_QUARTTONE);
1024                                 }
1025
1026                                 if      (has_vcol_preview) bmdm_get_tri_colpreview(ltri, lcol, color_vert_array);
1027                                 else if (has_fcol_preview) glColor3ubv((const GLubyte *)&(color_face_array[BM_elem_index_get(efa)]));
1028                                 if (skip_normals) {
1029                                         if (poly_type != poly_prev) {
1030                                                 if (poly_prev != GL_ZERO) glEnd();
1031                                                 glBegin((poly_prev = poly_type)); /* BMesh: will always be GL_TRIANGLES */
1032                                         }
1033                                         if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r));
1034                                         glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
1035                                         if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r));
1036                                         glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
1037                                         if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r));
1038                                         glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
1039                                 }
1040                                 else {
1041                                         const GLenum shade_type = drawSmooth ? GL_SMOOTH : GL_FLAT;
1042                                         if (shade_type != shade_prev) {
1043                                                 if (poly_prev != GL_ZERO) glEnd();
1044                                                 glShadeModel((shade_prev = shade_type)); /* same as below but switch shading */
1045                                                 glBegin((poly_prev = poly_type)); /* BMesh: will always be GL_TRIANGLES */
1046                                         }
1047                                         if (poly_type != poly_prev) {
1048                                                 if (poly_prev != GL_ZERO) glEnd();
1049                                                 glBegin((poly_prev = poly_type)); /* BMesh: will always be GL_TRIANGLES */
1050                                         }
1051
1052                                         if (!drawSmooth) {
1053                                                 glNormal3fv(polyNos[BM_elem_index_get(efa)]);
1054                                                 if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r));
1055                                                 glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
1056                                                 if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r));
1057                                                 glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
1058                                                 if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r));
1059                                                 glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
1060                                         }
1061                                         else {
1062                                                 if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r));
1063                                                 if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[0])]);
1064                                                 else glNormal3fv(vertexNos[BM_elem_index_get(ltri[0]->v)]);
1065                                                 glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
1066                                                 if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r));
1067                                                 if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[1])]);
1068                                                 else glNormal3fv(vertexNos[BM_elem_index_get(ltri[1]->v)]);
1069                                                 glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
1070                                                 if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r));
1071                                                 if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[2])]);
1072                                                 else glNormal3fv(vertexNos[BM_elem_index_get(ltri[2]->v)]);
1073                                                 glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
1074                                         }
1075                                 }
1076                         }
1077                 }
1078         }
1079         else {
1080                 short prev_mat_nr = -1;
1081
1082                 BM_mesh_elem_index_ensure(bm, lnors ? BM_FACE | BM_LOOP : BM_FACE);
1083
1084                 for (i = 0; i < tottri; i++) {
1085                         BMLoop **ltri = looptris[i];
1086                         int drawSmooth;
1087
1088                         efa = ltri[0]->f;
1089                         drawSmooth = lnors || ((flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : BM_elem_flag_test(efa, BM_ELEM_SMOOTH));
1090                         
1091                         draw_option = (setDrawOptions ?
1092                                            setDrawOptions(userData, BM_elem_index_get(efa)) :
1093                                            DM_DRAW_OPTION_NORMAL);
1094
1095                         if (draw_option != DM_DRAW_OPTION_SKIP) {
1096                                 const GLenum poly_type = GL_TRIANGLES; /* BMESH NOTE, this is odd but keep it for now to match trunk */
1097
1098                                 if (draw_option_prev != draw_option) {
1099                                         if (draw_option_prev == DM_DRAW_OPTION_STIPPLE) {
1100                                                 if (poly_prev != GL_ZERO) glEnd();
1101                                                 poly_prev = GL_ZERO; /* force glBegin */
1102
1103                                                 GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
1104                                         }
1105                                         draw_option_prev = draw_option;
1106                                 }
1107
1108                                 if (efa->mat_nr != prev_mat_nr) {
1109                                         if (setMaterial) {
1110                                                 if (poly_prev != GL_ZERO) glEnd();
1111                                                 poly_prev = GL_ZERO; /* force glBegin */
1112
1113                                                 setMaterial(efa->mat_nr + 1, NULL);
1114                                         }
1115                                         prev_mat_nr = efa->mat_nr;
1116                                 }
1117                                 
1118                                 if (draw_option == DM_DRAW_OPTION_STIPPLE) { /* enabled with stipple */
1119
1120                                         if (poly_prev != GL_ZERO) glEnd();
1121                                         poly_prev = GL_ZERO; /* force glBegin */
1122
1123                                         GPU_basic_shader_bind(GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR);
1124                                         GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_QUARTTONE);
1125                                 }
1126
1127                                 if      (has_vcol_preview) bmdm_get_tri_colpreview(ltri, lcol, color_vert_array);
1128                                 else if (has_fcol_preview) glColor3ubv((const GLubyte *)&(color_face_array[BM_elem_index_get(efa)]));
1129
1130                                 if (skip_normals) {
1131                                         if (poly_type != poly_prev) {
1132                                                 if (poly_prev != GL_ZERO) glEnd();
1133                                                 glBegin((poly_prev = poly_type)); /* BMesh: will always be GL_TRIANGLES */
1134                                         }
1135                                         if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r));
1136                                         glVertex3fv(ltri[0]->v->co);
1137                                         if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r));
1138                                         glVertex3fv(ltri[1]->v->co);
1139                                         if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r));
1140                                         glVertex3fv(ltri[2]->v->co);
1141                                 }
1142                                 else {
1143                                         const GLenum shade_type = drawSmooth ? GL_SMOOTH : GL_FLAT;
1144                                         if (shade_type != shade_prev) {
1145                                                 if (poly_prev != GL_ZERO) glEnd();
1146                                                 glShadeModel((shade_prev = shade_type)); /* same as below but switch shading */
1147                                                 glBegin((poly_prev = poly_type)); /* BMesh: will always be GL_TRIANGLES */
1148                                         }
1149                                         if (poly_type != poly_prev) {
1150                                                 if (poly_prev != GL_ZERO) glEnd();
1151                                                 glBegin((poly_prev = poly_type)); /* BMesh: will always be GL_TRIANGLES */
1152                                         }
1153
1154                                         if (!drawSmooth) {
1155                                                 glNormal3fv(efa->no);
1156                                                 if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r));
1157                                                 glVertex3fv(ltri[0]->v->co);
1158                                                 if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r));
1159                                                 glVertex3fv(ltri[1]->v->co);
1160                                                 if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r));
1161                                                 glVertex3fv(ltri[2]->v->co);
1162                                         }
1163                                         else {
1164                                                 if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r));
1165                                                 if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[0])]);
1166                                                 else glNormal3fv(ltri[0]->v->no);
1167                                                 glVertex3fv(ltri[0]->v->co);
1168                                                 if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r));
1169                                                 if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[1])]);
1170                                                 else glNormal3fv(ltri[1]->v->no);
1171                                                 glVertex3fv(ltri[1]->v->co);
1172                                                 if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r));
1173                                                 if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[2])]);
1174                                                 else glNormal3fv(ltri[2]->v->no);
1175                                                 glVertex3fv(ltri[2]->v->co);
1176                                         }
1177                                 }
1178                         }
1179                 }
1180         }
1181
1182         /* if non zero we know a face was rendered */
1183         if (poly_prev != GL_ZERO) glEnd();
1184 }
1185
1186 static void bmdm_get_tri_uv(BMLoop *ltri[3], MLoopUV *luv[3], const int cd_loop_uv_offset)
1187 {
1188         luv[0] = BM_ELEM_CD_GET_VOID_P(ltri[0], cd_loop_uv_offset);
1189         luv[1] = BM_ELEM_CD_GET_VOID_P(ltri[1], cd_loop_uv_offset);
1190         luv[2] = BM_ELEM_CD_GET_VOID_P(ltri[2], cd_loop_uv_offset);
1191 }
1192
1193 static void bmdm_get_tri_col(BMLoop *ltri[3], MLoopCol *lcol[3], const int cd_loop_color_offset)
1194 {
1195         lcol[0] = BM_ELEM_CD_GET_VOID_P(ltri[0], cd_loop_color_offset);
1196         lcol[1] = BM_ELEM_CD_GET_VOID_P(ltri[1], cd_loop_color_offset);
1197         lcol[2] = BM_ELEM_CD_GET_VOID_P(ltri[2], cd_loop_color_offset);
1198 }
1199
1200 static void bmdm_get_tri_colpreview(BMLoop *ls[3], MLoopCol *lcol[3], unsigned char(*color_vert_array)[4])
1201 {
1202         lcol[0] = (MLoopCol *)color_vert_array[BM_elem_index_get(ls[0]->v)];
1203         lcol[1] = (MLoopCol *)color_vert_array[BM_elem_index_get(ls[1]->v)];
1204         lcol[2] = (MLoopCol *)color_vert_array[BM_elem_index_get(ls[2]->v)];
1205 }
1206
1207 static void emDM_drawFacesTex_common(
1208         DerivedMesh *dm,
1209         DMSetDrawOptionsTex drawParams,
1210         DMSetDrawOptionsMappedTex drawParamsMapped,
1211         DMCompareDrawOptions compareDrawOptions,
1212         void *userData)
1213 {
1214         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1215         BMEditMesh *em = bmdm->em;
1216         BMesh *bm = em->bm;
1217         struct BMLoop *(*looptris)[3] = em->looptris;
1218         BMFace *efa;
1219         const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
1220         MLoopUV *luv[3], dummyluv = {{0}};
1221         MLoopCol *lcol[3] = {NULL} /* , dummylcol = {0} */;
1222         const int cd_loop_uv_offset    = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
1223         const int cd_loop_color_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPCOL);
1224         const int cd_poly_tex_offset   = CustomData_get_offset(&bm->pdata, CD_MTEXPOLY);
1225         unsigned char(*color_vert_array)[4] = em->derivedVertColor;
1226         bool has_uv   = (cd_loop_uv_offset    != -1);
1227         bool has_vcol_preview = (color_vert_array != NULL);
1228         bool has_vcol = (cd_loop_color_offset != -1) && (has_vcol_preview == false);
1229         bool has_vcol_any = (has_vcol_preview || has_vcol);
1230         int i;
1231
1232         (void) compareDrawOptions;
1233
1234         luv[0] = luv[1] = luv[2] = &dummyluv;
1235
1236         // dummylcol.r = dummylcol.g = dummylcol.b = dummylcol.a = 255;  /* UNUSED */
1237
1238         /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
1239         BM_mesh_elem_index_ensure(bm, BM_FACE);
1240
1241         /* call again below is ok */
1242         if (has_vcol_preview) {
1243                 BM_mesh_elem_index_ensure(bm, BM_VERT);
1244         }
1245
1246         if (bmdm->vertexCos) {
1247                 /* add direct access */
1248                 const float (*vertexCos)[3] = bmdm->vertexCos;
1249                 const float (*vertexNos)[3];
1250                 const float (*polyNos)[3];
1251
1252                 emDM_ensureVertNormals(bmdm);
1253                 emDM_ensurePolyNormals(bmdm);
1254                 vertexNos = bmdm->vertexNos;
1255                 polyNos = bmdm->polyNos;
1256
1257                 BM_mesh_elem_index_ensure(bm, lnors ? BM_LOOP | BM_VERT : BM_VERT);
1258
1259                 for (i = 0; i < em->tottri; i++) {
1260                         BMLoop **ltri = looptris[i];
1261                         MTexPoly *tp = (cd_poly_tex_offset != -1) ? BM_ELEM_CD_GET_VOID_P(ltri[0]->f, cd_poly_tex_offset) : NULL;
1262                         /*unsigned char *cp = NULL;*/ /*UNUSED*/
1263                         int drawSmooth = lnors || BM_elem_flag_test(ltri[0]->f, BM_ELEM_SMOOTH);
1264                         DMDrawOption draw_option;
1265
1266                         efa = ltri[0]->f;
1267
1268                         if (drawParams) {
1269                                 draw_option = drawParams(tp, has_vcol, efa->mat_nr);
1270                         }
1271                         else if (drawParamsMapped)
1272                                 draw_option = drawParamsMapped(userData, BM_elem_index_get(efa), efa->mat_nr);
1273                         else
1274                                 draw_option = DM_DRAW_OPTION_NORMAL;
1275
1276                         if (draw_option != DM_DRAW_OPTION_SKIP) {
1277
1278                                 if      (has_uv)            bmdm_get_tri_uv(ltri,  luv,  cd_loop_uv_offset);
1279                                 if      (has_vcol)          bmdm_get_tri_col(ltri, lcol, cd_loop_color_offset);
1280                                 else if (has_vcol_preview)  bmdm_get_tri_colpreview(ltri, lcol, color_vert_array);
1281
1282                                 glBegin(GL_TRIANGLES);
1283                                 if (!drawSmooth) {
1284                                         glNormal3fv(polyNos[BM_elem_index_get(efa)]);
1285
1286                                         glTexCoord2fv(luv[0]->uv);
1287                                         if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r));
1288                                         glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
1289
1290                                         glTexCoord2fv(luv[1]->uv);
1291                                         if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r));
1292                                         glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
1293
1294                                         glTexCoord2fv(luv[2]->uv);
1295                                         if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r));
1296                                         glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
1297                                 }
1298                                 else {
1299                                         glTexCoord2fv(luv[0]->uv);
1300                                         if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r));
1301                                         if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[0])]);
1302                                         else glNormal3fv(vertexNos[BM_elem_index_get(ltri[0]->v)]);
1303                                         glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
1304
1305                                         glTexCoord2fv(luv[1]->uv);
1306                                         if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r));
1307                                         if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[1])]);
1308                                         else glNormal3fv(vertexNos[BM_elem_index_get(ltri[1]->v)]);
1309                                         glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
1310
1311                                         glTexCoord2fv(luv[2]->uv);
1312                                         if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r));
1313                                         if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[2])]);
1314                                         else glNormal3fv(vertexNos[BM_elem_index_get(ltri[2]->v)]);
1315                                         glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
1316                                 }
1317                                 glEnd();
1318                         }
1319                 }
1320         }
1321         else {
1322                 BM_mesh_elem_index_ensure(bm, lnors ? BM_LOOP | BM_VERT : BM_VERT);
1323
1324                 for (i = 0; i < em->tottri; i++) {
1325                         BMLoop **ltri = looptris[i];
1326                         MTexPoly *tp = (cd_poly_tex_offset != -1) ? BM_ELEM_CD_GET_VOID_P(ltri[0]->f, cd_poly_tex_offset) : NULL;
1327                         /*unsigned char *cp = NULL;*/ /*UNUSED*/
1328                         int drawSmooth = lnors || BM_elem_flag_test(ltri[0]->f, BM_ELEM_SMOOTH);
1329                         DMDrawOption draw_option;
1330
1331                         efa = ltri[0]->f;
1332
1333                         if (drawParams)
1334                                 draw_option = drawParams(tp, has_vcol, efa->mat_nr);
1335                         else if (drawParamsMapped)
1336                                 draw_option = drawParamsMapped(userData, BM_elem_index_get(efa), efa->mat_nr);
1337                         else
1338                                 draw_option = DM_DRAW_OPTION_NORMAL;
1339
1340                         if (draw_option != DM_DRAW_OPTION_SKIP) {
1341
1342                                 if      (has_uv)            bmdm_get_tri_uv(ltri,  luv,  cd_loop_uv_offset);
1343                                 if      (has_vcol)          bmdm_get_tri_col(ltri, lcol, cd_loop_color_offset);
1344                                 else if (has_vcol_preview)  bmdm_get_tri_colpreview(ltri, lcol, color_vert_array);
1345
1346                                 glBegin(GL_TRIANGLES);
1347                                 if (!drawSmooth) {
1348                                         glNormal3fv(efa->no);
1349
1350                                         glTexCoord2fv(luv[0]->uv);
1351                                         if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r));
1352                                         glVertex3fv(ltri[0]->v->co);
1353
1354                                         glTexCoord2fv(luv[1]->uv);
1355                                         if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r));
1356                                         glVertex3fv(ltri[1]->v->co);
1357
1358                                         glTexCoord2fv(luv[2]->uv);
1359                                         if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r));
1360                                         glVertex3fv(ltri[2]->v->co);
1361                                 }
1362                                 else {
1363                                         glTexCoord2fv(luv[0]->uv);
1364                                         if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r));
1365                                         if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[0])]);
1366                                         else glNormal3fv(ltri[0]->v->no);
1367                                         glVertex3fv(ltri[0]->v->co);
1368
1369                                         glTexCoord2fv(luv[1]->uv);
1370                                         if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r));
1371                                         if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[1])]);
1372                                         else glNormal3fv(ltri[1]->v->no);
1373                                         glVertex3fv(ltri[1]->v->co);
1374
1375                                         glTexCoord2fv(luv[2]->uv);
1376                                         if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r));
1377                                         if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[2])]);
1378                                         else glNormal3fv(ltri[2]->v->no);
1379                                         glVertex3fv(ltri[2]->v->co);
1380                                 }
1381                                 glEnd();
1382                         }
1383                 }
1384         }
1385 }
1386
1387 static void emDM_drawFacesTex(
1388         DerivedMesh *dm,
1389         DMSetDrawOptionsTex setDrawOptions,
1390         DMCompareDrawOptions compareDrawOptions,
1391         void *userData, DMDrawFlag UNUSED(flag))
1392 {
1393         emDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData);
1394 }
1395
1396 static void emDM_drawMappedFacesTex(
1397         DerivedMesh *dm,
1398         DMSetDrawOptionsMappedTex setDrawOptions,
1399         DMCompareDrawOptions compareDrawOptions,
1400         void *userData, DMDrawFlag UNUSED(flag))
1401 {
1402         emDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData);
1403 }
1404
1405 /**
1406  * \note
1407  *
1408  * For UV's:
1409  *   const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(loop, attribs->tface[i].em_offset);
1410  *
1411  * This is intentionally different to calling:
1412  *   CustomData_bmesh_get_n(&bm->ldata, loop->head.data, CD_MLOOPUV, i);
1413  *
1414  * ... because the material may use layer names to select different UV's
1415  * see: [#34378]
1416  */
1417 static void emdm_pass_attrib_vertex_glsl(const DMVertexAttribs *attribs, const BMLoop *loop)
1418 {
1419         BMVert *eve = loop->v;
1420         int i;
1421         const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
1422
1423         if (attribs->totorco) {
1424                 int index = BM_elem_index_get(eve);
1425                 const float *orco = (attribs->orco.array) ? attribs->orco.array[index] : zero;
1426
1427                 if (attribs->orco.gl_texco)
1428                         glTexCoord3fv(orco);
1429                 else
1430                         glVertexAttrib3fv(attribs->orco.gl_index, orco);
1431                 glUniform1i(attribs->orco.gl_info_index, 0);
1432         }
1433         for (i = 0; i < attribs->tottface; i++) {
1434                 const float *uv;
1435
1436                 if (attribs->tface[i].em_offset != -1) {
1437                         const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(loop, attribs->tface[i].em_offset);
1438                         uv = luv->uv;
1439                 }
1440                 else {
1441                         uv = zero;
1442                 }
1443
1444                 if (attribs->tface[i].gl_texco)
1445                         glTexCoord2fv(uv);
1446                 else
1447                         glVertexAttrib2fv(attribs->tface[i].gl_index, uv);
1448                 glUniform1i(attribs->tface[i].gl_info_index, 0);
1449         }
1450         for (i = 0; i < attribs->totmcol; i++) {
1451                 float col[4];
1452                 if (attribs->mcol[i].em_offset != -1) {
1453                         const MLoopCol *cp = BM_ELEM_CD_GET_VOID_P(loop, attribs->mcol[i].em_offset);
1454                         rgba_uchar_to_float(col, &cp->r);
1455                 }
1456                 else {
1457                         col[0] = 0.0f; col[1] = 0.0f; col[2] = 0.0f; col[3] = 0.0f;
1458                 }
1459                 glVertexAttrib4fv(attribs->mcol[i].gl_index, col);
1460                 glUniform1i(attribs->mcol[i].gl_info_index, GPU_ATTR_INFO_SRGB);
1461         }
1462
1463         for (i = 0; i < attribs->tottang; i++) {
1464                 const float *tang;
1465                 if (attribs->tang[i].em_offset != -1) {
1466                         tang = attribs->tang[i].array[BM_elem_index_get(loop)];
1467                 }
1468                 else {
1469                         tang = zero;
1470                 }
1471                 glVertexAttrib4fv(attribs->tang[i].gl_index, tang);
1472                 glUniform1i(attribs->tang[i].gl_info_index, 0);
1473         }
1474 }
1475
1476 static void emDM_drawMappedFacesGLSL(
1477         DerivedMesh *dm,
1478         DMSetMaterial setMaterial,
1479         DMSetDrawOptions setDrawOptions,
1480         void *userData)
1481 {
1482         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1483         BMEditMesh *em = bmdm->em;
1484         BMesh *bm = em->bm;
1485         struct BMLoop *(*looptris)[3] = em->looptris;
1486         /* add direct access */
1487         const float (*vertexCos)[3] = bmdm->vertexCos;
1488         const float (*vertexNos)[3];
1489         const float (*polyNos)[3];
1490         const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
1491
1492         BMFace *efa;
1493         DMVertexAttribs attribs;
1494         GPUVertexAttribs gattribs;
1495
1496         int i, matnr, new_matnr, fi;
1497         bool do_draw;
1498
1499         do_draw = false;
1500         matnr = -1;
1501
1502         memset(&attribs, 0, sizeof(attribs));
1503
1504         emDM_ensureVertNormals(bmdm);
1505         emDM_ensurePolyNormals(bmdm);
1506         vertexNos = bmdm->vertexNos;
1507         polyNos = bmdm->polyNos;
1508
1509         BM_mesh_elem_index_ensure(bm, (BM_VERT | BM_FACE) | (lnors ? BM_LOOP : 0));
1510
1511         for (i = 0; i < em->tottri; i++) {
1512                 BMLoop **ltri = looptris[i];
1513                 int drawSmooth;
1514
1515                 efa = ltri[0]->f;
1516
1517                 if (setDrawOptions && (setDrawOptions(userData, BM_elem_index_get(efa)) == DM_DRAW_OPTION_SKIP))
1518                         continue;
1519
1520                 /* material */
1521                 new_matnr = efa->mat_nr + 1;
1522                 if (new_matnr != matnr) {
1523                         if (matnr != -1)
1524                                 glEnd();
1525
1526                         do_draw = setMaterial(matnr = new_matnr, &gattribs);
1527                         if (do_draw) {
1528                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1529                                 if (UNLIKELY(attribs.tottang && bm->elem_index_dirty & BM_LOOP)) {
1530                                         BM_mesh_elem_index_ensure(bm, BM_LOOP);
1531                                 }
1532                         }
1533
1534                         glBegin(GL_TRIANGLES);
1535                 }
1536
1537                 if (do_draw) {
1538
1539                         /* draw face */
1540                         drawSmooth = lnors || BM_elem_flag_test(efa, BM_ELEM_SMOOTH);
1541
1542                         if (!drawSmooth) {
1543                                 if (vertexCos) {
1544                                         glNormal3fv(polyNos[BM_elem_index_get(efa)]);
1545                                         for (fi = 0; fi < 3; fi++) {
1546                                                 emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]);
1547                                                 glVertex3fv(vertexCos[BM_elem_index_get(ltri[fi]->v)]);
1548                                         }
1549                                 }
1550                                 else {
1551                                         glNormal3fv(efa->no);
1552                                         for (fi = 0; fi < 3; fi++) {
1553                                                 emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]);
1554                                                 glVertex3fv(ltri[fi]->v->co);
1555                                         }
1556                                 }
1557                         }
1558                         else {
1559                                 if (vertexCos) {
1560                                         for (fi = 0; fi < 3; fi++) {
1561                                                 const int j = BM_elem_index_get(ltri[fi]->v);
1562                                                 emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]);
1563                                                 if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[fi])]);
1564                                                 else glNormal3fv(vertexNos[j]);
1565                                                 glVertex3fv(vertexCos[j]);
1566                                         }
1567                                 }
1568                                 else {
1569                                         for (fi = 0; fi < 3; fi++) {
1570                                                 emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]);
1571                                                 if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[fi])]);
1572                                                 else glNormal3fv(ltri[fi]->v->no);
1573                                                 glVertex3fv(ltri[fi]->v->co);
1574                                         }
1575                                 }
1576                         }
1577                 }
1578         }
1579
1580         if (matnr != -1) {
1581                 glEnd();
1582         }
1583 }
1584
1585 static void emDM_drawFacesGLSL(
1586         DerivedMesh *dm,
1587         int (*setMaterial)(int matnr, void *attribs))
1588 {
1589         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1590 }
1591
1592 static void emDM_drawMappedFacesMat(
1593         DerivedMesh *dm,
1594         void (*setMaterial)(void *userData, int matnr, void *attribs),
1595         bool (*setFace)(void *userData, int index), void *userData)
1596 {
1597         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1598         BMEditMesh *em = bmdm->em;
1599         BMesh *bm = em->bm;
1600         struct BMLoop *(*looptris)[3] = em->looptris;
1601         const float (*vertexCos)[3] = bmdm->vertexCos;
1602         const float (*vertexNos)[3];
1603         const float (*polyNos)[3];
1604         const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
1605         BMFace *efa;
1606         DMVertexAttribs attribs = {{{NULL}}};
1607         GPUVertexAttribs gattribs;
1608         int i, matnr, new_matnr, fi;
1609
1610         matnr = -1;
1611
1612         emDM_ensureVertNormals(bmdm);
1613         emDM_ensurePolyNormals(bmdm);
1614
1615         vertexNos = bmdm->vertexNos;
1616         polyNos = bmdm->polyNos;
1617
1618         BM_mesh_elem_index_ensure(bm, (BM_VERT | BM_FACE) | (lnors ? BM_LOOP : 0));
1619
1620         for (i = 0; i < em->tottri; i++) {
1621                 BMLoop **ltri = looptris[i];
1622                 int drawSmooth;
1623
1624                 efa = ltri[0]->f;
1625
1626                 /* face hiding */
1627                 if (setFace && !setFace(userData, BM_elem_index_get(efa)))
1628                         continue;
1629
1630                 /* material */
1631                 new_matnr = efa->mat_nr + 1;
1632                 if (new_matnr != matnr) {
1633                         if (matnr != -1)
1634                                 glEnd();
1635
1636                         setMaterial(userData, matnr = new_matnr, &gattribs);
1637                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1638                         if (UNLIKELY(attribs.tottang && bm->elem_index_dirty & BM_LOOP)) {
1639                                 BM_mesh_elem_index_ensure(bm, BM_LOOP);
1640                         }
1641
1642                         glBegin(GL_TRIANGLES);
1643                 }
1644
1645                 /* draw face */
1646                 drawSmooth = lnors || BM_elem_flag_test(efa, BM_ELEM_SMOOTH);
1647
1648                 if (!drawSmooth) {
1649                         if (vertexCos) {
1650                                 glNormal3fv(polyNos[BM_elem_index_get(efa)]);
1651                                 for (fi = 0; fi < 3; fi++) {
1652                                         emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]);
1653                                         glVertex3fv(vertexCos[BM_elem_index_get(ltri[fi]->v)]);
1654                                 }
1655                         }
1656                         else {
1657                                 glNormal3fv(efa->no);
1658                                 for (fi = 0; fi < 3; fi++) {
1659                                         emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]);
1660                                         glVertex3fv(ltri[fi]->v->co);
1661                                 }
1662                         }
1663                 }
1664                 else {
1665                         if (vertexCos) {
1666                                 for (fi = 0; fi < 3; fi++) {
1667                                         const int j = BM_elem_index_get(ltri[fi]->v);
1668                                         emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]);
1669                                         if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[fi])]);
1670                                         else glNormal3fv(vertexNos[j]);
1671                                         glVertex3fv(vertexCos[j]);
1672                                 }
1673                         }
1674                         else {
1675                                 for (fi = 0; fi < 3; fi++) {
1676                                         emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]);
1677                                         if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[fi])]);
1678                                         else glNormal3fv(ltri[fi]->v->no);
1679                                         glVertex3fv(ltri[fi]->v->co);
1680                                 }
1681                         }
1682                 }
1683         }
1684
1685         if (matnr != -1) {
1686                 glEnd();
1687         }
1688 }
1689
1690 static void emDM_getMinMax(DerivedMesh *dm, float r_min[3], float r_max[3])
1691 {
1692         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1693         BMesh *bm = bmdm->em->bm;
1694         BMVert *eve;
1695         BMIter iter;
1696         int i;
1697
1698         if (bm->totvert) {
1699                 if (bmdm->vertexCos) {
1700                         BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
1701                                 minmax_v3v3_v3(r_min, r_max, bmdm->vertexCos[i]);
1702                         }
1703                 }
1704                 else {
1705                         BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
1706                                 minmax_v3v3_v3(r_min, r_max, eve->co);
1707                         }
1708                 }
1709         }
1710         else {
1711                 zero_v3(r_min);
1712                 zero_v3(r_max);
1713         }
1714 }
1715 static int emDM_getNumVerts(DerivedMesh *dm)
1716 {
1717         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1718
1719         return bmdm->em->bm->totvert;
1720 }
1721
1722 static int emDM_getNumEdges(DerivedMesh *dm)
1723 {
1724         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1725
1726         return bmdm->em->bm->totedge;
1727 }
1728
1729 static int emDM_getNumTessFaces(DerivedMesh *dm)
1730 {
1731         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1732
1733         return bmdm->em->tottri;
1734 }
1735
1736 static int emDM_getNumLoops(DerivedMesh *dm)
1737 {
1738         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1739
1740         return bmdm->em->bm->totloop;
1741 }
1742
1743 static int emDM_getNumPolys(DerivedMesh *dm)
1744 {
1745         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1746
1747         return bmdm->em->bm->totface;
1748 }
1749
1750 static void bmvert_to_mvert(BMesh *bm, BMVert *ev, MVert *r_vert)
1751 {
1752         const float *f;
1753
1754         copy_v3_v3(r_vert->co, ev->co);
1755
1756         normal_float_to_short_v3(r_vert->no, ev->no);
1757
1758         r_vert->flag = BM_vert_flag_to_mflag(ev);
1759
1760         if ((f = CustomData_bmesh_get(&bm->vdata, ev->head.data, CD_BWEIGHT))) {
1761                 r_vert->bweight = (unsigned char)((*f) * 255.0f);
1762         }
1763 }
1764
1765 static void emDM_getVert(DerivedMesh *dm, int index, MVert *r_vert)
1766 {
1767         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1768         BMesh *bm = bmdm->em->bm;
1769         BMVert *ev;
1770
1771         if (UNLIKELY(index < 0 || index >= bm->totvert)) {
1772                 BLI_assert(!"error in emDM_getVert");
1773                 return;
1774         }
1775
1776         BLI_assert((bm->elem_table_dirty & BM_VERT) == 0);
1777         ev = bm->vtable[index];  /* should be BM_vert_at_index() */
1778         // ev = BM_vert_at_index(bm, index); /* warning, does list loop, _not_ ideal */
1779
1780         bmvert_to_mvert(bm, ev, r_vert);
1781         if (bmdm->vertexCos)
1782                 copy_v3_v3(r_vert->co, bmdm->vertexCos[index]);
1783 }
1784
1785 static void emDM_getVertCo(DerivedMesh *dm, int index, float r_co[3])
1786 {
1787         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1788         BMesh *bm = bmdm->em->bm;
1789
1790         if (UNLIKELY(index < 0 || index >= bm->totvert)) {
1791                 BLI_assert(!"error in emDM_getVertCo");
1792                 return;
1793         }
1794
1795         if (bmdm->vertexCos) {
1796                 copy_v3_v3(r_co, bmdm->vertexCos[index]);
1797         }
1798         else {
1799                 BMVert *ev;
1800
1801                 BLI_assert((bm->elem_table_dirty & BM_VERT) == 0);
1802                 ev = bm->vtable[index];  /* should be BM_vert_at_index() */
1803                 // ev = BM_vert_at_index(bm, index); /* warning, does list loop, _not_ ideal */
1804                 copy_v3_v3(r_co, ev->co);
1805         }
1806 }
1807
1808 static void emDM_getVertNo(DerivedMesh *dm, int index, float r_no[3])
1809 {
1810         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1811         BMesh *bm = bmdm->em->bm;
1812
1813         if (UNLIKELY(index < 0 || index >= bm->totvert)) {
1814                 BLI_assert(!"error in emDM_getVertNo");
1815                 return;
1816         }
1817
1818
1819         if (bmdm->vertexCos) {
1820                 emDM_ensureVertNormals(bmdm);
1821                 copy_v3_v3(r_no, bmdm->vertexNos[index]);
1822         }
1823         else {
1824                 BMVert *ev;
1825
1826                 BLI_assert((bm->elem_table_dirty & BM_VERT) == 0);
1827                 ev = bm->vtable[index];  /* should be BM_vert_at_index() */
1828                 // ev = BM_vert_at_index(bm, index); /* warning, does list loop, _not_ ideal */
1829                 copy_v3_v3(r_no, ev->no);
1830         }
1831 }
1832
1833 static void emDM_getPolyNo(DerivedMesh *dm, int index, float r_no[3])
1834 {
1835         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1836         BMesh *bm = bmdm->em->bm;
1837
1838         if (UNLIKELY(index < 0 || index >= bm->totface)) {
1839                 BLI_assert(!"error in emDM_getPolyNo");
1840                 return;
1841         }
1842
1843         if (bmdm->vertexCos) {
1844                 emDM_ensurePolyNormals(bmdm);
1845                 copy_v3_v3(r_no, bmdm->polyNos[index]);
1846         }
1847         else {
1848                 BMFace *efa;
1849
1850                 BLI_assert((bm->elem_table_dirty & BM_FACE) == 0);
1851                 efa = bm->ftable[index];  /* should be BM_vert_at_index() */
1852                 // efa = BM_face_at_index(bm, index); /* warning, does list loop, _not_ ideal */
1853                 copy_v3_v3(r_no, efa->no);
1854         }
1855 }
1856
1857 static void emDM_getEdge(DerivedMesh *dm, int index, MEdge *r_edge)
1858 {
1859         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1860         BMesh *bm = bmdm->em->bm;
1861         BMEdge *e;
1862         const float *f;
1863
1864         if (UNLIKELY(index < 0 || index >= bm->totedge)) {
1865                 BLI_assert(!"error in emDM_getEdge");
1866                 return;
1867         }
1868
1869         BLI_assert((bm->elem_table_dirty & BM_EDGE) == 0);
1870         e = bm->etable[index];  /* should be BM_edge_at_index() */
1871         // e = BM_edge_at_index(bm, index); /* warning, does list loop, _not_ ideal */
1872
1873         r_edge->flag = BM_edge_flag_to_mflag(e);
1874
1875         r_edge->v1 = BM_elem_index_get(e->v1);
1876         r_edge->v2 = BM_elem_index_get(e->v2);
1877
1878         if ((f = CustomData_bmesh_get(&bm->edata, e->head.data, CD_BWEIGHT))) {
1879                 r_edge->bweight = (unsigned char)((*f) * 255.0f);
1880         }
1881         if ((f = CustomData_bmesh_get(&bm->edata, e->head.data, CD_CREASE))) {
1882                 r_edge->crease = (unsigned char)((*f) * 255.0f);
1883         }
1884 }
1885
1886 static void emDM_getTessFace(DerivedMesh *dm, int index, MFace *r_face)
1887 {
1888         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1889         BMFace *ef;
1890         BMLoop **ltri;
1891
1892         if (UNLIKELY(index < 0 || index >= bmdm->em->tottri)) {
1893                 BLI_assert(!"error in emDM_getTessFace");
1894                 return;
1895         }
1896
1897         ltri = bmdm->em->looptris[index];
1898
1899         ef = ltri[0]->f;
1900
1901         r_face->mat_nr = (unsigned char) ef->mat_nr;
1902         r_face->flag = BM_face_flag_to_mflag(ef);
1903
1904         r_face->v1 = BM_elem_index_get(ltri[0]->v);
1905         r_face->v2 = BM_elem_index_get(ltri[1]->v);
1906         r_face->v3 = BM_elem_index_get(ltri[2]->v);
1907         r_face->v4 = 0;
1908
1909         test_index_face(r_face, NULL, 0, 3);
1910 }
1911
1912 static void emDM_copyVertArray(DerivedMesh *dm, MVert *r_vert)
1913 {
1914         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1915         BMesh *bm = bmdm->em->bm;
1916         BMVert *eve;
1917         BMIter iter;
1918         const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
1919
1920         if (bmdm->vertexCos) {
1921                 int i;
1922
1923                 BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
1924                         copy_v3_v3(r_vert->co, bmdm->vertexCos[i]);
1925                         normal_float_to_short_v3(r_vert->no, eve->no);
1926                         r_vert->flag = BM_vert_flag_to_mflag(eve);
1927
1928                         r_vert->bweight = (cd_vert_bweight_offset != -1) ? BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset) : 0;
1929
1930                         r_vert++;
1931                 }
1932         }
1933         else {
1934                 BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
1935                         copy_v3_v3(r_vert->co, eve->co);
1936                         normal_float_to_short_v3(r_vert->no, eve->no);
1937                         r_vert->flag = BM_vert_flag_to_mflag(eve);
1938
1939                         r_vert->bweight = (cd_vert_bweight_offset != -1) ? BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset) : 0;
1940
1941                         r_vert++;
1942                 }
1943         }
1944 }
1945
1946 static void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *r_edge)
1947 {
1948         BMesh *bm = ((EditDerivedBMesh *)dm)->em->bm;
1949         BMEdge *eed;
1950         BMIter iter;
1951
1952         const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
1953         const int cd_edge_crease_offset  = CustomData_get_offset(&bm->edata, CD_CREASE);
1954
1955         BM_mesh_elem_index_ensure(bm, BM_VERT);
1956
1957         BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
1958                 r_edge->v1 = BM_elem_index_get(eed->v1);
1959                 r_edge->v2 = BM_elem_index_get(eed->v2);
1960
1961                 r_edge->flag = BM_edge_flag_to_mflag(eed);
1962
1963                 r_edge->crease  = (cd_edge_crease_offset  != -1) ? BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_crease_offset)  : 0;
1964                 r_edge->bweight = (cd_edge_bweight_offset != -1) ? BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_bweight_offset) : 0;
1965
1966                 r_edge++;
1967         }
1968 }
1969
1970 static void emDM_copyTessFaceArray(DerivedMesh *dm, MFace *r_face)
1971 {
1972         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1973         BMesh *bm = bmdm->em->bm;
1974         struct BMLoop *(*looptris)[3] = bmdm->em->looptris;
1975         BMFace *ef;
1976         int i;
1977
1978         BM_mesh_elem_index_ensure(bm, BM_VERT);
1979
1980         for (i = 0; i < bmdm->em->tottri; i++, r_face++) {
1981                 BMLoop **ltri = looptris[i];
1982                 ef = ltri[0]->f;
1983
1984                 r_face->mat_nr = (unsigned char) ef->mat_nr;
1985
1986                 r_face->flag = BM_face_flag_to_mflag(ef);
1987                 r_face->edcode = 0;
1988
1989                 r_face->v1 = BM_elem_index_get(ltri[0]->v);
1990                 r_face->v2 = BM_elem_index_get(ltri[1]->v);
1991                 r_face->v3 = BM_elem_index_get(ltri[2]->v);
1992                 r_face->v4 = 0;
1993
1994                 test_index_face(r_face, NULL, 0, 3);
1995         }
1996 }
1997
1998 static void emDM_copyLoopArray(DerivedMesh *dm, MLoop *r_loop)
1999 {
2000         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
2001         BMesh *bm = bmdm->em->bm;
2002         BMIter iter;
2003         BMFace *efa;
2004
2005         BM_mesh_elem_index_ensure(bm, BM_VERT | BM_EDGE);
2006
2007         BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
2008                 BMLoop *l_iter, *l_first;
2009                 l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
2010                 do {
2011                         r_loop->v = BM_elem_index_get(l_iter->v);
2012                         r_loop->e = BM_elem_index_get(l_iter->e);
2013                         r_loop++;
2014                 } while ((l_iter = l_iter->next) != l_first);
2015         }
2016 }
2017
2018 static void emDM_copyPolyArray(DerivedMesh *dm, MPoly *r_poly)
2019 {
2020         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
2021         BMesh *bm = bmdm->em->bm;
2022         BMIter iter;
2023         BMFace *efa;
2024         int i;
2025
2026         i = 0;
2027         BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
2028                 r_poly->flag = BM_face_flag_to_mflag(efa);
2029                 r_poly->loopstart = i;
2030                 r_poly->totloop = efa->len;
2031                 r_poly->mat_nr = efa->mat_nr;
2032
2033                 r_poly++;
2034                 i += efa->len;
2035         }
2036 }
2037
2038 static void *emDM_getTessFaceDataArray(DerivedMesh *dm, int type)
2039 {
2040         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
2041         BMesh *bm = bmdm->em->bm;
2042         void *datalayer;
2043
2044         datalayer = DM_get_tessface_data_layer(dm, type);
2045         if (datalayer)
2046                 return datalayer;
2047
2048         /* layers are store per face for editmesh, we convert to a temporary
2049          * data layer array in the derivedmesh when these are requested */
2050         if (type == CD_MTFACE || type == CD_MCOL) {
2051                 const int type_from = (type == CD_MTFACE) ? CD_MTEXPOLY : CD_MLOOPCOL;
2052                 int index;
2053                 const char *bmdata;
2054                 char *data;
2055                 index = CustomData_get_layer_index(&bm->pdata, type_from);
2056
2057                 if (index != -1) {
2058                         /* offset = bm->pdata.layers[index].offset; */ /* UNUSED */
2059                         BMLoop *(*looptris)[3] = bmdm->em->looptris;
2060                         const int size = CustomData_sizeof(type);
2061                         int i, j;
2062
2063                         DM_add_tessface_layer(dm, type, CD_CALLOC, NULL);
2064                         index = CustomData_get_layer_index(&dm->faceData, type);
2065                         dm->faceData.layers[index].flag |= CD_FLAG_TEMPORARY;
2066
2067                         data = datalayer = DM_get_tessface_data_layer(dm, type);
2068
2069                         if (type == CD_MTFACE) {
2070                                 const int cd_loop_uv_offset  = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
2071                                 const int cd_poly_tex_offset = CustomData_get_offset(&bm->pdata, CD_MTEXPOLY);
2072
2073                                 for (i = 0; i < bmdm->em->tottri; i++, data += size) {
2074                                         BMFace *efa = looptris[i][0]->f;
2075
2076                                         // bmdata = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY);
2077                                         bmdata = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
2078
2079                                         ME_MTEXFACE_CPY(((MTFace *)data), ((const MTexPoly *)bmdata));
2080                                         for (j = 0; j < 3; j++) {
2081                                                 // bmdata = CustomData_bmesh_get(&bm->ldata, looptris[i][j]->head.data, CD_MLOOPUV);
2082                                                 bmdata = BM_ELEM_CD_GET_VOID_P(looptris[i][j], cd_loop_uv_offset);
2083                                                 copy_v2_v2(((MTFace *)data)->uv[j], ((const MLoopUV *)bmdata)->uv);
2084                                         }
2085                                 }
2086                         }
2087                         else {
2088                                 const int cd_loop_color_offset  = CustomData_get_offset(&bm->ldata, CD_MLOOPCOL);
2089                                 for (i = 0; i < bmdm->em->tottri; i++, data += size) {
2090                                         for (j = 0; j < 3; j++) {
2091                                                 // bmdata = CustomData_bmesh_get(&bm->ldata, looptris[i][j]->head.data, CD_MLOOPCOL);
2092                                                 bmdata = BM_ELEM_CD_GET_VOID_P(looptris[i][j], cd_loop_color_offset);
2093                                                 MESH_MLOOPCOL_TO_MCOL(((const MLoopCol *)bmdata), (((MCol *)data) + j));
2094                                         }
2095                                 }
2096                         }
2097                 }
2098         }
2099
2100         /* Special handling for CD_TESSLOOPNORMAL, we generate it on demand as well. */
2101         if (type == CD_TESSLOOPNORMAL) {
2102                 const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
2103
2104                 if (lnors) {
2105                         BMLoop *(*looptris)[3] = bmdm->em->looptris;
2106                         short (*tlnors)[4][3], (*tlnor)[4][3];
2107                         int index, i, j;
2108
2109                         DM_add_tessface_layer(dm, type, CD_CALLOC, NULL);
2110                         index = CustomData_get_layer_index(&dm->faceData, type);
2111                         dm->faceData.layers[index].flag |= CD_FLAG_TEMPORARY;
2112
2113                         tlnor = tlnors = DM_get_tessface_data_layer(dm, type);
2114
2115                         BM_mesh_elem_index_ensure(bm, BM_LOOP);
2116
2117                         for (i = 0; i < bmdm->em->tottri; i++, tlnor++, looptris++) {
2118                                 for (j = 0; j < 3; j++) {
2119                                         normal_float_to_short_v3((*tlnor)[j], lnors[BM_elem_index_get((*looptris)[j])]);
2120                                 }
2121                         }
2122                 }
2123         }
2124
2125         return datalayer;
2126 }
2127
2128 static void emDM_getVertCos(DerivedMesh *dm, float (*r_cos)[3])
2129 {
2130         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
2131         BMesh *bm = bmdm->em->bm;
2132         BMVert *eve;
2133         BMIter iter;
2134         int i;
2135
2136         if (bmdm->vertexCos) {
2137                 BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
2138                         copy_v3_v3(r_cos[i], bmdm->vertexCos[i]);
2139                 }
2140         }
2141         else {
2142                 BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
2143                         copy_v3_v3(r_cos[i], eve->co);
2144                 }
2145         }
2146 }
2147
2148 static void emDM_release(DerivedMesh *dm)
2149 {
2150         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
2151
2152         if (DM_release(dm)) {
2153                 if (bmdm->vertexCos) {
2154                         MEM_freeN((void *)bmdm->vertexCos);
2155                         if (bmdm->vertexNos) {
2156                                 MEM_freeN((void *)bmdm->vertexNos);
2157                         }
2158                         if (bmdm->polyNos) {
2159                                 MEM_freeN((void *)bmdm->polyNos);
2160                         }
2161                 }
2162
2163                 if (bmdm->polyCos) {
2164                         MEM_freeN((void *)bmdm->polyCos);
2165                 }
2166
2167                 MEM_freeN(bmdm);
2168         }
2169 }
2170
2171 static CustomData *bmDm_getVertDataLayout(DerivedMesh *dm)
2172 {
2173         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
2174
2175         return &bmdm->em->bm->vdata;
2176 }
2177
2178 static CustomData *bmDm_getEdgeDataLayout(DerivedMesh *dm)
2179 {
2180         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
2181
2182         return &bmdm->em->bm->edata;
2183 }
2184
2185 static CustomData *bmDm_getTessFaceDataLayout(DerivedMesh *dm)
2186 {
2187         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
2188
2189         return &bmdm->dm.faceData;
2190 }
2191
2192 static CustomData *bmDm_getLoopDataLayout(DerivedMesh *dm)
2193 {
2194         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
2195
2196         return &bmdm->em->bm->ldata;
2197 }
2198
2199 static CustomData *bmDm_getPolyDataLayout(DerivedMesh *dm)
2200 {
2201         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
2202
2203         return &bmdm->em->bm->pdata;
2204 }
2205
2206
2207 DerivedMesh *getEditDerivedBMesh(
2208         BMEditMesh *em,
2209         Object *UNUSED(ob),
2210         float (*vertexCos)[3])
2211 {
2212         EditDerivedBMesh *bmdm = MEM_callocN(sizeof(*bmdm), __func__);
2213         BMesh *bm = em->bm;
2214         const int cd_dvert_offset = CustomData_get_offset(&bm->vdata, CD_MDEFORMVERT);
2215         const int cd_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN);
2216
2217         bmdm->em = em;
2218
2219         DM_init((DerivedMesh *)bmdm, DM_TYPE_EDITBMESH, bm->totvert,
2220                 bm->totedge, em->tottri, bm->totloop, bm->totface);
2221
2222         /* could also get from the objects mesh directly */
2223         bmdm->dm.cd_flag = BM_mesh_cd_flag_from_bmesh(bm);
2224
2225         bmdm->dm.getVertCos = emDM_getVertCos;
2226         bmdm->dm.getMinMax = emDM_getMinMax;
2227
2228         bmdm->dm.getVertDataLayout = bmDm_getVertDataLayout;
2229         bmdm->dm.getEdgeDataLayout = bmDm_getEdgeDataLayout;
2230         bmdm->dm.getTessFaceDataLayout = bmDm_getTessFaceDataLayout;
2231         bmdm->dm.getLoopDataLayout = bmDm_getLoopDataLayout;
2232         bmdm->dm.getPolyDataLayout = bmDm_getPolyDataLayout;
2233
2234         bmdm->dm.getNumVerts = emDM_getNumVerts;
2235         bmdm->dm.getNumEdges = emDM_getNumEdges;
2236         bmdm->dm.getNumTessFaces = emDM_getNumTessFaces;
2237         bmdm->dm.getNumLoops = emDM_getNumLoops;
2238         bmdm->dm.getNumPolys = emDM_getNumPolys;
2239
2240         bmdm->dm.getLoopTriArray = emDM_getLoopTriArray;
2241
2242         bmdm->dm.getVert = emDM_getVert;
2243         bmdm->dm.getVertCo = emDM_getVertCo;
2244         bmdm->dm.getVertNo = emDM_getVertNo;
2245         bmdm->dm.getPolyNo = emDM_getPolyNo;
2246         bmdm->dm.getEdge = emDM_getEdge;
2247         bmdm->dm.getTessFace = emDM_getTessFace;
2248         bmdm->dm.copyVertArray = emDM_copyVertArray;
2249         bmdm->dm.copyEdgeArray = emDM_copyEdgeArray;
2250         bmdm->dm.copyTessFaceArray = emDM_copyTessFaceArray;
2251         bmdm->dm.copyLoopArray = emDM_copyLoopArray;
2252         bmdm->dm.copyPolyArray = emDM_copyPolyArray;
2253
2254         bmdm->dm.getTessFaceDataArray = emDM_getTessFaceDataArray;
2255
2256         bmdm->dm.calcNormals = emDM_calcNormals;
2257         bmdm->dm.calcLoopNormals = emDM_calcLoopNormals;
2258         bmdm->dm.calcLoopNormalsSpaceArray = emDM_calcLoopNormalsSpaceArray;
2259         bmdm->dm.calcLoopTangents = emDM_calc_loop_tangents;
2260         bmdm->dm.recalcTessellation = emDM_recalcTessellation;
2261         bmdm->dm.recalcLoopTri = emDM_recalcLoopTri;
2262
2263         bmdm->dm.foreachMappedVert = emDM_foreachMappedVert;
2264         bmdm->dm.foreachMappedLoop = emDM_foreachMappedLoop;
2265         bmdm->dm.foreachMappedEdge = emDM_foreachMappedEdge;
2266         bmdm->dm.foreachMappedFaceCenter = emDM_foreachMappedFaceCenter;
2267
2268         bmdm->dm.drawEdges = emDM_drawEdges;
2269         bmdm->dm.drawMappedEdges = emDM_drawMappedEdges;
2270         bmdm->dm.drawMappedEdgesInterp = emDM_drawMappedEdgesInterp;
2271         bmdm->dm.drawMappedFaces = emDM_drawMappedFaces;
2272         bmdm->dm.drawMappedFacesTex = emDM_drawMappedFacesTex;
2273         bmdm->dm.drawMappedFacesGLSL = emDM_drawMappedFacesGLSL;
2274         bmdm->dm.drawMappedFacesMat = emDM_drawMappedFacesMat;
2275         bmdm->dm.drawFacesTex = emDM_drawFacesTex;
2276         bmdm->dm.drawFacesGLSL = emDM_drawFacesGLSL;
2277         bmdm->dm.drawUVEdges = emDM_drawUVEdges;
2278
2279         bmdm->dm.release = emDM_release;
2280
2281         bmdm->vertexCos = (const float (*)[3])vertexCos;
2282         bmdm->dm.deformedOnly = (vertexCos != NULL);
2283
2284         if (cd_dvert_offset != -1) {
2285                 BMIter iter;
2286                 BMVert *eve;
2287                 int i;
2288
2289                 DM_add_vert_layer(&bmdm->dm, CD_MDEFORMVERT, CD_CALLOC, NULL);
2290
2291                 BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
2292                         DM_set_vert_data(&bmdm->dm, i, CD_MDEFORMVERT,
2293                                          BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset));
2294                 }
2295         }
2296
2297         if (cd_skin_offset != -1) {
2298                 BMIter iter;
2299                 BMVert *eve;
2300                 int i;
2301
2302                 DM_add_vert_layer(&bmdm->dm, CD_MVERT_SKIN, CD_CALLOC, NULL);
2303
2304                 BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
2305                         DM_set_vert_data(&bmdm->dm, i, CD_MVERT_SKIN,
2306                                          BM_ELEM_CD_GET_VOID_P(eve, cd_skin_offset));
2307                 }
2308         }
2309
2310         return (DerivedMesh *)bmdm;
2311 }
2312
2313
2314
2315 /* -------------------------------------------------------------------- */
2316 /* StatVis Functions */
2317
2318 static void axis_from_enum_v3(float v[3], const char axis)
2319 {
2320         zero_v3(v);
2321         if (axis < 3) v[axis]     =  1.0f;
2322         else          v[axis - 3] = -1.0f;
2323 }
2324
2325 static void statvis_calc_overhang(
2326         BMEditMesh *em,
2327         const float (*polyNos)[3],
2328         /* values for calculating */
2329         const float min, const float max, const char axis,
2330         /* result */
2331         unsigned char (*r_face_colors)[4])
2332 {
2333         BMIter iter;
2334         BMesh *bm = em->bm;
2335         BMFace *f;
2336         float dir[3];
2337         int index;
2338         const float minmax_irange = 1.0f / (max - min);
2339         bool is_max;
2340
2341         /* fallback */
2342         unsigned char col_fallback[4] = {64, 64, 64, 255}; /* gray */
2343         unsigned char col_fallback_max[4] = {0,  0,  0,  255}; /* max color */
2344
2345         BLI_assert(min <= max);
2346
2347         axis_from_enum_v3(dir, axis);
2348
2349         if (LIKELY(em->ob)) {
2350                 mul_transposed_mat3_m4_v3(em->ob->obmat, dir);
2351                 normalize_v3(dir);
2352         }
2353
2354         /* fallback max */
2355         {
2356                 float fcol[3];
2357                 weight_to_rgb(fcol, 1.0f);
2358                 rgb_float_to_uchar(col_fallback_max, fcol);
2359         }
2360
2361         /* now convert into global space */
2362         BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, index) {
2363                 float fac = angle_normalized_v3v3(polyNos ? polyNos[index] : f->no, dir) / (float)M_PI;
2364
2365                 /* remap */
2366                 if ((is_max = (fac <= max)) && (fac >= min)) {
2367                         float fcol[3];
2368                         fac = (fac - min) * minmax_irange;
2369                         fac = 1.0f - fac;
2370                         CLAMP(fac, 0.0f, 1.0f);
2371                         weight_to_rgb(fcol, fac);
2372                         rgb_float_to_uchar(r_face_colors[index], fcol);
2373                 }
2374                 else {
2375                         const unsigned char *fallback = is_max ? col_fallback_max : col_fallback;
2376                         copy_v4_v4_uchar(r_face_colors[index], fallback);
2377                 }
2378         }
2379 }
2380
2381 /* so we can use jitter values for face interpolation */
2382 static void uv_from_jitter_v2(float uv[2])
2383 {
2384         uv[0] += 0.5f;
2385         uv[1] += 0.5f;
2386         if (uv[0] + uv[1] > 1.0f) {
2387                 uv[0] = 1.0f - uv[0];
2388                 uv[1] = 1.0f - uv[1];
2389         }
2390
2391         CLAMP(uv[0], 0.0f, 1.0f);
2392         CLAMP(uv[1], 0.0f, 1.0f);
2393 }
2394
2395 static void statvis_calc_thickness(
2396         BMEditMesh *em,
2397         const float (*vertexCos)[3],
2398         /* values for calculating */
2399         const float min, const float max, const int samples,
2400         /* result */
2401         unsigned char (*r_face_colors)[4])
2402 {
2403         const float eps_offset = 0.00002f;  /* values <= 0.00001 give errors */
2404         float *face_dists = (float *)r_face_colors;  /* cheating */
2405         const bool use_jit = samples < 32;
2406         float jit_ofs[32][2];
2407         BMesh *bm = em->bm;
2408         const int tottri = em->tottri;
2409         const float minmax_irange = 1.0f / (max - min);
2410         int i;
2411
2412         struct BMLoop *(*looptris)[3] = em->looptris;
2413
2414         /* fallback */
2415         const unsigned char col_fallback[4] = {64, 64, 64, 255};
2416
2417         struct BMBVHTree *bmtree;
2418
2419         BLI_assert(min <= max);
2420
2421         copy_vn_fl(face_dists, em->bm->totface, max);
2422
2423         if (use_jit) {
2424                 int j;
2425                 BLI_assert(samples < 32);
2426                 BLI_jitter_init(jit_ofs, samples);
2427
2428                 for (j = 0; j < samples; j++) {
2429                         uv_from_jitter_v2(jit_ofs[j]);
2430                 }
2431         }
2432
2433         BM_mesh_elem_index_ensure(bm, BM_FACE);
2434         if (vertexCos) {
2435                 BM_mesh_elem_index_ensure(bm, BM_VERT);
2436         }
2437
2438         bmtree = BKE_bmbvh_new_from_editmesh(em, 0, vertexCos, false);
2439
2440         for (i = 0; i < tottri; i++) {
2441                 BMFace *f_hit;
2442                 BMLoop **ltri = looptris[i];
2443                 const int index = BM_elem_index_get(ltri[0]->f);
2444                 const float *cos[3];
2445                 float ray_co[3];
2446                 float ray_no[3];
2447
2448                 if (vertexCos) {
2449                         cos[0] = vertexCos[BM_elem_index_get(ltri[0]->v)];
2450                         cos[1] = vertexCos[BM_elem_index_get(ltri[1]->v)];
2451                         cos[2] = vertexCos[BM_elem_index_get(ltri[2]->v)];
2452                 }
2453                 else {
2454                         cos[0] = ltri[0]->v->co;
2455                         cos[1] = ltri[1]->v->co;
2456                         cos[2] = ltri[2]->v->co;
2457                 }
2458
2459                 normal_tri_v3(ray_no, cos[2], cos[1], cos[0]);
2460
2461 #define FACE_RAY_TEST_ANGLE \
2462                 f_hit = BKE_bmbvh_ray_cast(bmtree, ray_co, ray_no, 0.0f, \
2463                                            &dist, NULL, NULL); \
2464                 if (f_hit && dist < face_dists[index]) { \
2465                         float angle_fac = fabsf(dot_v3v3(ltri[0]->f->no, f_hit->no)); \
2466                         angle_fac = 1.0f - angle_fac; \
2467                         angle_fac = angle_fac * angle_fac * angle_fac; \
2468                         angle_fac = 1.0f - angle_fac; \
2469                         dist /= angle_fac; \
2470                         if (dist < face_dists[index]) { \
2471                                 face_dists[index] = dist; \
2472                         } \
2473                 } (void)0
2474
2475                 if (use_jit) {
2476                         int j;
2477                         for (j = 0; j < samples; j++) {
2478                                 float dist = face_dists[index];
2479                                 interp_v3_v3v3v3_uv(ray_co, cos[0], cos[1], cos[2], jit_ofs[j]);
2480                                 madd_v3_v3fl(ray_co, ray_no, eps_offset);
2481
2482                                 FACE_RAY_TEST_ANGLE;
2483                         }
2484                 }
2485                 else {
2486                         float dist = face_dists[index];
2487                         mid_v3_v3v3v3(ray_co, cos[0], cos[1], cos[2]);
2488                         madd_v3_v3fl(ray_co, ray_no, eps_offset);
2489
2490                         FACE_RAY_TEST_ANGLE;
2491                 }
2492         }
2493
2494         BKE_bmbvh_free(bmtree);
2495
2496         /* convert floats into color! */
2497         for (i = 0; i < bm->totface; i++) {
2498                 float fac = face_dists[i];
2499
2500                 /* important not '<=' */
2501                 if (fac < max) {
2502                         float fcol[3];
2503                         fac = (fac - min) * minmax_irange;
2504                         fac = 1.0f - fac;
2505                         CLAMP(fac, 0.0f, 1.0f);
2506                         weight_to_rgb(fcol, fac);
2507                         rgb_float_to_uchar(r_face_colors[i], fcol);
2508                 }
2509                 else {
2510                         copy_v4_v4_uchar(r_face_colors[i], col_fallback);
2511                 }
2512         }
2513 }
2514
2515 static void statvis_calc_intersect(
2516         BMEditMesh *em,
2517         const float (*vertexCos)[3],
2518         /* result */
2519         unsigned char (*r_face_colors)[4])
2520 {
2521         BMesh *bm = em->bm;
2522         int i;
2523
2524         /* fallback */
2525         // const char col_fallback[4] = {64, 64, 64, 255};
2526         float fcol[3];
2527         unsigned char col[3];
2528
2529         struct BMBVHTree *bmtree;
2530         BVHTreeOverlap *overlap;
2531         unsigned int overlap_len;
2532
2533         memset(r_face_colors, 64, sizeof(int) * em->bm->totface);
2534
2535         BM_mesh_elem_index_ensure(bm, BM_FACE);
2536         if (vertexCos) {
2537                 BM_mesh_elem_index_ensure(bm, BM_VERT);
2538         }
2539
2540         bmtree = BKE_bmbvh_new_from_editmesh(em, 0, vertexCos, false);
2541
2542         overlap = BKE_bmbvh_overlap(bmtree, bmtree, &overlap_len);
2543
2544         /* same for all faces */
2545         weight_to_rgb(fcol, 1.0f);
2546         rgb_float_to_uchar(col, fcol);
2547
2548         if (overlap) {
2549                 for (i = 0; i < overlap_len; i++) {
2550                         BMFace *f_hit_pair[2] = {
2551                             em->looptris[overlap[i].indexA][0]->f,
2552                             em->looptris[overlap[i].indexB][0]->f,
2553                         };
2554                         int j;
2555
2556                         for (j = 0; j < 2; j++) {
2557                                 BMFace *f_hit = f_hit_pair[j];
2558                                 int index;
2559
2560                                 index = BM_elem_index_get(f_hit);
2561
2562                                 copy_v3_v3_uchar(r_face_colors[index], col);
2563                         }
2564                 }
2565                 MEM_freeN(overlap);
2566         }
2567
2568         BKE_bmbvh_free(bmtree);
2569 }
2570
2571 static void statvis_calc_distort(
2572         BMEditMesh *em,
2573         const float (*vertexCos)[3], const float (*polyNos)[3],
2574         /* values for calculating */
2575         const float min, const float max,
2576         /* result */
2577         unsigned char (*r_face_colors)[4])
2578 {
2579         BMIter iter;
2580         BMesh *bm = em->bm;
2581         BMFace *f;
2582         const float *f_no;
2583         int index;
2584         const float minmax_irange = 1.0f / (max - min);
2585
2586         /* fallback */
2587         const unsigned char col_fallback[4] = {64, 64, 64, 255};
2588
2589         /* now convert into global space */
2590         BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, index) {
2591                 float fac;
2592
2593                 if (f->len == 3) {
2594                         fac = -1.0f;
2595                 }
2596                 else {
2597                         BMLoop *l_iter, *l_first;
2598                         if (vertexCos) {
2599                                 f_no = polyNos[index];
2600                         }
2601                         else {
2602                                 f_no = f->no;
2603                         }
2604
2605                         fac = 0.0f;
2606                         l_iter = l_first = BM_FACE_FIRST_LOOP(f);
2607                         do {
2608                                 float no_corner[3];
2609                                 if (vertexCos) {
2610                                         normal_tri_v3(no_corner,
2611                                                       vertexCos[BM_elem_index_get(l_iter->prev->v)],
2612                                                       vertexCos[BM_elem_index_get(l_iter->v)],
2613                                                       vertexCos[BM_elem_index_get(l_iter->next->v)]);
2614                                 }
2615                                 else {
2616                                         BM_loop_calc_face_normal(l_iter, no_corner);
2617                                 }
2618                                 /* simple way to detect (what is most likely) concave */
2619                                 if (dot_v3v3(f_no, no_corner) < 0.0f) {
2620                                         negate_v3(no_corner);
2621                                 }
2622                                 fac = max_ff(fac, angle_normalized_v3v3(f_no, no_corner));
2623                         } while ((l_iter = l_iter->next) != l_first);
2624                         fac *= 2.0f;
2625                 }
2626
2627                 /* remap */
2628                 if (fac >= min) {
2629                         float fcol[3];
2630                         fac = (fac - min) * minmax_irange;
2631                         CLAMP(fac, 0.0f, 1.0f);
2632                         weight_to_rgb(fcol, fac);
2633                         rgb_float_to_uchar(r_face_colors[index], fcol);
2634                 }
2635                 else {
2636                         copy_v4_v4_uchar(r_face_colors[index], col_fallback);
2637                 }
2638         }
2639 }
2640
2641 static void statvis_calc_sharp(
2642         BMEditMesh *em,
2643         const float (*vertexCos)[3],
2644         /* values for calculating */
2645         const float min, const float max,
2646         /* result */
2647         unsigned char (*r_vert_colors)[4])
2648 {
2649         float *vert_angles = (float *)r_vert_colors;  /* cheating */
2650         BMIter iter;
2651         BMesh *bm = em->bm;
2652         BMEdge *e;
2653         //float f_no[3];
2654         const float minmax_irange = 1.0f / (max - min);
2655         int i;
2656
2657         /* fallback */
2658         const unsigned char col_fallback[4] = {64, 64, 64, 255};
2659
2660         (void)vertexCos;  /* TODO */
2661
2662         copy_vn_fl(vert_angles, em->bm->totvert, -M_PI);
2663
2664         /* first assign float values to verts */
2665         BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
2666                 float angle = BM_edge_calc_face_angle_signed(e);
2667                 float *col1 = &vert_angles[BM_elem_index_get(e->v1)];
2668                 float *col2 = &vert_angles[BM_elem_index_get(e->v2)];
2669                 *col1 = max_ff(*col1, angle);
2670                 *col2 = max_ff(*col2, angle);
2671         }
2672
2673         /* convert floats into color! */
2674         for (i = 0; i < bm->totvert; i++) {
2675                 float fac = vert_angles[i];
2676
2677                 /* important not '<=' */
2678                 if (fac > min) {
2679                         float fcol[3];
2680                         fac = (fac - min) * minmax_irange;
2681                         CLAMP(fac, 0.0f, 1.0f);
2682                         weight_to_rgb(fcol, fac);
2683                         rgb_float_to_uchar(r_vert_colors[i], fcol);
2684                 }
2685                 else {
2686                         copy_v4_v4_uchar(r_vert_colors[i], col_fallback);
2687                 }
2688         }
2689 }
2690
2691 void BKE_editmesh_statvis_calc(
2692         BMEditMesh *em, DerivedMesh *dm,
2693         const MeshStatVis *statvis)
2694 {
2695         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
2696         BLI_assert(dm == NULL || dm->type == DM_TYPE_EDITBMESH);
2697
2698         switch (statvis->type) {
2699                 case SCE_STATVIS_OVERHANG:
2700                 {
2701                         BKE_editmesh_color_ensure(em, BM_FACE);
2702                         statvis_calc_overhang(
2703                                     em, bmdm ? bmdm->polyNos : NULL,
2704                                     statvis->overhang_min / (float)M_PI,
2705                                     statvis->overhang_max / (float)M_PI,
2706                                     statvis->overhang_axis,
2707                                     em->derivedFaceColor);
2708                         break;
2709                 }
2710                 case SCE_STATVIS_THICKNESS:
2711                 {
2712                         const float scale = 1.0f / mat4_to_scale(em->ob->obmat);
2713                         BKE_editmesh_color_ensure(em, BM_FACE);
2714                         statvis_calc_thickness(
2715                                     em, bmdm ? bmdm->vertexCos : NULL,
2716                                     statvis->thickness_min * scale,
2717                                     statvis->thickness_max * scale,
2718                                     statvis->thickness_samples,
2719                                     em->derivedFaceColor);
2720                         break;
2721                 }
2722                 case SCE_STATVIS_INTERSECT:
2723                 {
2724                         BKE_editmesh_color_ensure(em, BM_FACE);
2725                         statvis_calc_intersect(
2726                                     em, bmdm ? bmdm->vertexCos : NULL,
2727                                     em->derivedFaceColor);
2728                         break;
2729                 }
2730                 case SCE_STATVIS_DISTORT:
2731                 {
2732                         BKE_editmesh_color_ensure(em, BM_FACE);
2733
2734                         if (bmdm)
2735                                 emDM_ensurePolyNormals(bmdm);
2736
2737                         statvis_calc_distort(
2738                                 em, bmdm ? bmdm->vertexCos : NULL, bmdm ? bmdm->polyNos : NULL,
2739                                 statvis->distort_min,
2740                                 statvis->distort_max,
2741                                 em->derivedFaceColor);
2742                         break;
2743                 }
2744                 case SCE_STATVIS_SHARP:
2745                 {
2746                         BKE_editmesh_color_ensure(em, BM_VERT);
2747                         statvis_calc_sharp(
2748                                 em, bmdm ? bmdm->vertexCos : NULL,
2749                                 statvis->sharp_min,
2750                                 statvis->sharp_max,
2751                                 /* in this case they are vertex colors */
2752                                 em->derivedVertColor);
2753                         break;
2754                 }
2755         }
2756 }
2757
2758
2759
2760 /* -------------------------------------------------------------------- */
2761 /* Editmesh Vert Coords */
2762
2763 struct CageUserData {
2764         int totvert;
2765         float (*cos_cage)[3];
2766         BLI_bitmap *visit_bitmap;
2767 };
2768
2769 static void cage_mapped_verts_callback(
2770         void *userData, int index, const float co[3],
2771         const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
2772 {
2773         struct CageUserData *data = userData;
2774
2775         if ((index >= 0 && index < data->totvert) && (!BLI_BITMAP_TEST(data->visit_bitmap, index))) {
2776                 BLI_BITMAP_ENABLE(data->visit_bitmap, index);
2777                 copy_v3_v3(data->cos_cage[index], co);
2778         }
2779 }
2780
2781 float (*BKE_editmesh_vertexCos_get(BMEditMesh *em, Scene *scene, int *r_numVerts))[3]
2782 {
2783         DerivedMesh *cage, *final;
2784         BLI_bitmap *visit_bitmap;
2785         struct CageUserData data;
2786         float (*cos_cage)[3];
2787
2788         cage = editbmesh_get_derived_cage_and_final(scene, em->ob, em, CD_MASK_BAREMESH, &final);
2789         cos_cage = MEM_callocN(sizeof(*cos_cage) * em->bm->totvert, "bmbvh cos_cage");
2790
2791         /* when initializing cage verts, we only want the first cage coordinate for each vertex,
2792          * so that e.g. mirror or array use original vertex coordinates and not mirrored or duplicate */
2793         visit_bitmap = BLI_BITMAP_NEW(em->bm->totvert, __func__);
2794
2795         data.totvert = em->bm->totvert;
2796         data.cos_cage = cos_cage;
2797         data.visit_bitmap = visit_bitmap;
2798
2799         cage->foreachMappedVert(cage, cage_mapped_verts_callback, &data, DM_FOREACH_NOP);
2800
2801         MEM_freeN(visit_bitmap);
2802
2803         if (r_numVerts) {
2804                 *r_numVerts = em->bm->totvert;
2805         }
2806
2807         return cos_cage;
2808 }