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 static void emdm_pass_attrib_update_uniforms(const DMVertexAttribs *attribs)
1406 {
1407         int i;
1408         if (attribs->totorco) {
1409                 glUniform1i(attribs->orco.gl_info_index, 0);
1410         }
1411         for (i = 0; i < attribs->tottface; i++) {
1412                 glUniform1i(attribs->tface[i].gl_info_index, 0);
1413         }
1414         for (i = 0; i < attribs->totmcol; i++) {
1415                 glUniform1i(attribs->mcol[i].gl_info_index, GPU_ATTR_INFO_SRGB);
1416         }
1417
1418         for (i = 0; i < attribs->tottang; i++) {
1419                 glUniform1i(attribs->tang[i].gl_info_index, 0);
1420         }
1421 }
1422
1423 /**
1424  * \note
1425  *
1426  * For UV's:
1427  *   const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(loop, attribs->tface[i].em_offset);
1428  *
1429  * This is intentionally different to calling:
1430  *   CustomData_bmesh_get_n(&bm->ldata, loop->head.data, CD_MLOOPUV, i);
1431  *
1432  * ... because the material may use layer names to select different UV's
1433  * see: [#34378]
1434  */
1435 static void emdm_pass_attrib_vertex_glsl(const DMVertexAttribs *attribs, const BMLoop *loop)
1436 {
1437         BMVert *eve = loop->v;
1438         int i;
1439         const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
1440
1441         if (attribs->totorco) {
1442                 int index = BM_elem_index_get(eve);
1443                 const float *orco = (attribs->orco.array) ? attribs->orco.array[index] : zero;
1444
1445                 if (attribs->orco.gl_texco)
1446                         glTexCoord3fv(orco);
1447                 else
1448                         glVertexAttrib3fv(attribs->orco.gl_index, orco);
1449         }
1450         for (i = 0; i < attribs->tottface; i++) {
1451                 const float *uv;
1452
1453                 if (attribs->tface[i].em_offset != -1) {
1454                         const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(loop, attribs->tface[i].em_offset);
1455                         uv = luv->uv;
1456                 }
1457                 else {
1458                         uv = zero;
1459                 }
1460
1461                 if (attribs->tface[i].gl_texco)
1462                         glTexCoord2fv(uv);
1463                 else
1464                         glVertexAttrib2fv(attribs->tface[i].gl_index, uv);
1465         }
1466         for (i = 0; i < attribs->totmcol; i++) {
1467                 float col[4];
1468                 if (attribs->mcol[i].em_offset != -1) {
1469                         const MLoopCol *cp = BM_ELEM_CD_GET_VOID_P(loop, attribs->mcol[i].em_offset);
1470                         rgba_uchar_to_float(col, &cp->r);
1471                 }
1472                 else {
1473                         col[0] = 0.0f; col[1] = 0.0f; col[2] = 0.0f; col[3] = 0.0f;
1474                 }
1475                 glVertexAttrib4fv(attribs->mcol[i].gl_index, col);
1476         }
1477
1478         for (i = 0; i < attribs->tottang; i++) {
1479                 const float *tang;
1480                 if (attribs->tang[i].em_offset != -1) {
1481                         tang = attribs->tang[i].array[BM_elem_index_get(loop)];
1482                 }
1483                 else {
1484                         tang = zero;
1485                 }
1486                 glVertexAttrib4fv(attribs->tang[i].gl_index, tang);
1487         }
1488 }
1489
1490 static void emDM_drawMappedFacesGLSL(
1491         DerivedMesh *dm,
1492         DMSetMaterial setMaterial,
1493         DMSetDrawOptions setDrawOptions,
1494         void *userData)
1495 {
1496         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1497         BMEditMesh *em = bmdm->em;
1498         BMesh *bm = em->bm;
1499         struct BMLoop *(*looptris)[3] = em->looptris;
1500         /* add direct access */
1501         const float (*vertexCos)[3] = bmdm->vertexCos;
1502         const float (*vertexNos)[3];
1503         const float (*polyNos)[3];
1504         const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
1505
1506         BMFace *efa;
1507         DMVertexAttribs attribs;
1508         GPUVertexAttribs gattribs;
1509
1510         int i, matnr, new_matnr, fi;
1511         bool do_draw;
1512
1513         do_draw = false;
1514         matnr = -1;
1515
1516         memset(&attribs, 0, sizeof(attribs));
1517
1518         emDM_ensureVertNormals(bmdm);
1519         emDM_ensurePolyNormals(bmdm);
1520         vertexNos = bmdm->vertexNos;
1521         polyNos = bmdm->polyNos;
1522
1523         BM_mesh_elem_index_ensure(bm, (BM_VERT | BM_FACE) | (lnors ? BM_LOOP : 0));
1524
1525         for (i = 0; i < em->tottri; i++) {
1526                 BMLoop **ltri = looptris[i];
1527                 int drawSmooth;
1528
1529                 efa = ltri[0]->f;
1530
1531                 if (setDrawOptions && (setDrawOptions(userData, BM_elem_index_get(efa)) == DM_DRAW_OPTION_SKIP))
1532                         continue;
1533
1534                 /* material */
1535                 new_matnr = efa->mat_nr + 1;
1536                 if (new_matnr != matnr) {
1537                         if (matnr != -1)
1538                                 glEnd();
1539
1540                         do_draw = setMaterial(matnr = new_matnr, &gattribs);
1541                         if (do_draw) {
1542                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1543                                 emdm_pass_attrib_update_uniforms(&attribs);
1544                                 if (UNLIKELY(attribs.tottang && bm->elem_index_dirty & BM_LOOP)) {
1545                                         BM_mesh_elem_index_ensure(bm, BM_LOOP);
1546                                 }
1547                         }
1548
1549                         glBegin(GL_TRIANGLES);
1550                 }
1551
1552                 if (do_draw) {
1553
1554                         /* draw face */
1555                         drawSmooth = lnors || BM_elem_flag_test(efa, BM_ELEM_SMOOTH);
1556
1557                         if (!drawSmooth) {
1558                                 if (vertexCos) {
1559                                         glNormal3fv(polyNos[BM_elem_index_get(efa)]);
1560                                         for (fi = 0; fi < 3; fi++) {
1561                                                 emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]);
1562                                                 glVertex3fv(vertexCos[BM_elem_index_get(ltri[fi]->v)]);
1563                                         }
1564                                 }
1565                                 else {
1566                                         glNormal3fv(efa->no);
1567                                         for (fi = 0; fi < 3; fi++) {
1568                                                 emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]);
1569                                                 glVertex3fv(ltri[fi]->v->co);
1570                                         }
1571                                 }
1572                         }
1573                         else {
1574                                 if (vertexCos) {
1575                                         for (fi = 0; fi < 3; fi++) {
1576                                                 const int j = BM_elem_index_get(ltri[fi]->v);
1577                                                 emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]);
1578                                                 if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[fi])]);
1579                                                 else glNormal3fv(vertexNos[j]);
1580                                                 glVertex3fv(vertexCos[j]);
1581                                         }
1582                                 }
1583                                 else {
1584                                         for (fi = 0; fi < 3; fi++) {
1585                                                 emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]);
1586                                                 if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[fi])]);
1587                                                 else glNormal3fv(ltri[fi]->v->no);
1588                                                 glVertex3fv(ltri[fi]->v->co);
1589                                         }
1590                                 }
1591                         }
1592                 }
1593         }
1594
1595         if (matnr != -1) {
1596                 glEnd();
1597         }
1598 }
1599
1600 static void emDM_drawFacesGLSL(
1601         DerivedMesh *dm,
1602         int (*setMaterial)(int matnr, void *attribs))
1603 {
1604         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1605 }
1606
1607 static void emDM_drawMappedFacesMat(
1608         DerivedMesh *dm,
1609         void (*setMaterial)(void *userData, int matnr, void *attribs),
1610         bool (*setFace)(void *userData, int index), void *userData)
1611 {
1612         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1613         BMEditMesh *em = bmdm->em;
1614         BMesh *bm = em->bm;
1615         struct BMLoop *(*looptris)[3] = em->looptris;
1616         const float (*vertexCos)[3] = bmdm->vertexCos;
1617         const float (*vertexNos)[3];
1618         const float (*polyNos)[3];
1619         const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
1620         BMFace *efa;
1621         DMVertexAttribs attribs = {{{NULL}}};
1622         GPUVertexAttribs gattribs;
1623         int i, matnr, new_matnr, fi;
1624
1625         matnr = -1;
1626
1627         emDM_ensureVertNormals(bmdm);
1628         emDM_ensurePolyNormals(bmdm);
1629
1630         vertexNos = bmdm->vertexNos;
1631         polyNos = bmdm->polyNos;
1632
1633         BM_mesh_elem_index_ensure(bm, (BM_VERT | BM_FACE) | (lnors ? BM_LOOP : 0));
1634
1635         for (i = 0; i < em->tottri; i++) {
1636                 BMLoop **ltri = looptris[i];
1637                 int drawSmooth;
1638
1639                 efa = ltri[0]->f;
1640
1641                 /* face hiding */
1642                 if (setFace && !setFace(userData, BM_elem_index_get(efa)))
1643                         continue;
1644
1645                 /* material */
1646                 new_matnr = efa->mat_nr + 1;
1647                 if (new_matnr != matnr) {
1648                         if (matnr != -1)
1649                                 glEnd();
1650
1651                         setMaterial(userData, matnr = new_matnr, &gattribs);
1652                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1653                         if (UNLIKELY(attribs.tottang && bm->elem_index_dirty & BM_LOOP)) {
1654                                 BM_mesh_elem_index_ensure(bm, BM_LOOP);
1655                         }
1656
1657                         glBegin(GL_TRIANGLES);
1658                 }
1659
1660                 /* draw face */
1661                 drawSmooth = lnors || BM_elem_flag_test(efa, BM_ELEM_SMOOTH);
1662
1663                 if (!drawSmooth) {
1664                         if (vertexCos) {
1665                                 glNormal3fv(polyNos[BM_elem_index_get(efa)]);
1666                                 for (fi = 0; fi < 3; fi++) {
1667                                         emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]);
1668                                         glVertex3fv(vertexCos[BM_elem_index_get(ltri[fi]->v)]);
1669                                 }
1670                         }
1671                         else {
1672                                 glNormal3fv(efa->no);
1673                                 for (fi = 0; fi < 3; fi++) {
1674                                         emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]);
1675                                         glVertex3fv(ltri[fi]->v->co);
1676                                 }
1677                         }
1678                 }
1679                 else {
1680                         if (vertexCos) {
1681                                 for (fi = 0; fi < 3; fi++) {
1682                                         const int j = BM_elem_index_get(ltri[fi]->v);
1683                                         emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]);
1684                                         if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[fi])]);
1685                                         else glNormal3fv(vertexNos[j]);
1686                                         glVertex3fv(vertexCos[j]);
1687                                 }
1688                         }
1689                         else {
1690                                 for (fi = 0; fi < 3; fi++) {
1691                                         emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]);
1692                                         if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[fi])]);
1693                                         else glNormal3fv(ltri[fi]->v->no);
1694                                         glVertex3fv(ltri[fi]->v->co);
1695                                 }
1696                         }
1697                 }
1698         }
1699
1700         if (matnr != -1) {
1701                 glEnd();
1702         }
1703 }
1704
1705 static void emDM_getMinMax(DerivedMesh *dm, float r_min[3], float r_max[3])
1706 {
1707         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1708         BMesh *bm = bmdm->em->bm;
1709         BMVert *eve;
1710         BMIter iter;
1711         int i;
1712
1713         if (bm->totvert) {
1714                 if (bmdm->vertexCos) {
1715                         BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
1716                                 minmax_v3v3_v3(r_min, r_max, bmdm->vertexCos[i]);
1717                         }
1718                 }
1719                 else {
1720                         BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
1721                                 minmax_v3v3_v3(r_min, r_max, eve->co);
1722                         }
1723                 }
1724         }
1725         else {
1726                 zero_v3(r_min);
1727                 zero_v3(r_max);
1728         }
1729 }
1730 static int emDM_getNumVerts(DerivedMesh *dm)
1731 {
1732         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1733
1734         return bmdm->em->bm->totvert;
1735 }
1736
1737 static int emDM_getNumEdges(DerivedMesh *dm)
1738 {
1739         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1740
1741         return bmdm->em->bm->totedge;
1742 }
1743
1744 static int emDM_getNumTessFaces(DerivedMesh *dm)
1745 {
1746         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1747
1748         return bmdm->em->tottri;
1749 }
1750
1751 static int emDM_getNumLoops(DerivedMesh *dm)
1752 {
1753         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1754
1755         return bmdm->em->bm->totloop;
1756 }
1757
1758 static int emDM_getNumPolys(DerivedMesh *dm)
1759 {
1760         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1761
1762         return bmdm->em->bm->totface;
1763 }
1764
1765 static void bmvert_to_mvert(BMesh *bm, BMVert *ev, MVert *r_vert)
1766 {
1767         const float *f;
1768
1769         copy_v3_v3(r_vert->co, ev->co);
1770
1771         normal_float_to_short_v3(r_vert->no, ev->no);
1772
1773         r_vert->flag = BM_vert_flag_to_mflag(ev);
1774
1775         if ((f = CustomData_bmesh_get(&bm->vdata, ev->head.data, CD_BWEIGHT))) {
1776                 r_vert->bweight = (unsigned char)((*f) * 255.0f);
1777         }
1778 }
1779
1780 static void emDM_getVert(DerivedMesh *dm, int index, MVert *r_vert)
1781 {
1782         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1783         BMesh *bm = bmdm->em->bm;
1784         BMVert *ev;
1785
1786         if (UNLIKELY(index < 0 || index >= bm->totvert)) {
1787                 BLI_assert(!"error in emDM_getVert");
1788                 return;
1789         }
1790
1791         BLI_assert((bm->elem_table_dirty & BM_VERT) == 0);
1792         ev = bm->vtable[index];  /* should be BM_vert_at_index() */
1793         // ev = BM_vert_at_index(bm, index); /* warning, does list loop, _not_ ideal */
1794
1795         bmvert_to_mvert(bm, ev, r_vert);
1796         if (bmdm->vertexCos)
1797                 copy_v3_v3(r_vert->co, bmdm->vertexCos[index]);
1798 }
1799
1800 static void emDM_getVertCo(DerivedMesh *dm, int index, float r_co[3])
1801 {
1802         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1803         BMesh *bm = bmdm->em->bm;
1804
1805         if (UNLIKELY(index < 0 || index >= bm->totvert)) {
1806                 BLI_assert(!"error in emDM_getVertCo");
1807                 return;
1808         }
1809
1810         if (bmdm->vertexCos) {
1811                 copy_v3_v3(r_co, bmdm->vertexCos[index]);
1812         }
1813         else {
1814                 BMVert *ev;
1815
1816                 BLI_assert((bm->elem_table_dirty & BM_VERT) == 0);
1817                 ev = bm->vtable[index];  /* should be BM_vert_at_index() */
1818                 // ev = BM_vert_at_index(bm, index); /* warning, does list loop, _not_ ideal */
1819                 copy_v3_v3(r_co, ev->co);
1820         }
1821 }
1822
1823 static void emDM_getVertNo(DerivedMesh *dm, int index, float r_no[3])
1824 {
1825         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1826         BMesh *bm = bmdm->em->bm;
1827
1828         if (UNLIKELY(index < 0 || index >= bm->totvert)) {
1829                 BLI_assert(!"error in emDM_getVertNo");
1830                 return;
1831         }
1832
1833
1834         if (bmdm->vertexCos) {
1835                 emDM_ensureVertNormals(bmdm);
1836                 copy_v3_v3(r_no, bmdm->vertexNos[index]);
1837         }
1838         else {
1839                 BMVert *ev;
1840
1841                 BLI_assert((bm->elem_table_dirty & BM_VERT) == 0);
1842                 ev = bm->vtable[index];  /* should be BM_vert_at_index() */
1843                 // ev = BM_vert_at_index(bm, index); /* warning, does list loop, _not_ ideal */
1844                 copy_v3_v3(r_no, ev->no);
1845         }
1846 }
1847
1848 static void emDM_getPolyNo(DerivedMesh *dm, int index, float r_no[3])
1849 {
1850         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1851         BMesh *bm = bmdm->em->bm;
1852
1853         if (UNLIKELY(index < 0 || index >= bm->totface)) {
1854                 BLI_assert(!"error in emDM_getPolyNo");
1855                 return;
1856         }
1857
1858         if (bmdm->vertexCos) {
1859                 emDM_ensurePolyNormals(bmdm);
1860                 copy_v3_v3(r_no, bmdm->polyNos[index]);
1861         }
1862         else {
1863                 BMFace *efa;
1864
1865                 BLI_assert((bm->elem_table_dirty & BM_FACE) == 0);
1866                 efa = bm->ftable[index];  /* should be BM_vert_at_index() */
1867                 // efa = BM_face_at_index(bm, index); /* warning, does list loop, _not_ ideal */
1868                 copy_v3_v3(r_no, efa->no);
1869         }
1870 }
1871
1872 static void emDM_getEdge(DerivedMesh *dm, int index, MEdge *r_edge)
1873 {
1874         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1875         BMesh *bm = bmdm->em->bm;
1876         BMEdge *e;
1877         const float *f;
1878
1879         if (UNLIKELY(index < 0 || index >= bm->totedge)) {
1880                 BLI_assert(!"error in emDM_getEdge");
1881                 return;
1882         }
1883
1884         BLI_assert((bm->elem_table_dirty & BM_EDGE) == 0);
1885         e = bm->etable[index];  /* should be BM_edge_at_index() */
1886         // e = BM_edge_at_index(bm, index); /* warning, does list loop, _not_ ideal */
1887
1888         r_edge->flag = BM_edge_flag_to_mflag(e);
1889
1890         r_edge->v1 = BM_elem_index_get(e->v1);
1891         r_edge->v2 = BM_elem_index_get(e->v2);
1892
1893         if ((f = CustomData_bmesh_get(&bm->edata, e->head.data, CD_BWEIGHT))) {
1894                 r_edge->bweight = (unsigned char)((*f) * 255.0f);
1895         }
1896         if ((f = CustomData_bmesh_get(&bm->edata, e->head.data, CD_CREASE))) {
1897                 r_edge->crease = (unsigned char)((*f) * 255.0f);
1898         }
1899 }
1900
1901 static void emDM_getTessFace(DerivedMesh *dm, int index, MFace *r_face)
1902 {
1903         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1904         BMFace *ef;
1905         BMLoop **ltri;
1906
1907         if (UNLIKELY(index < 0 || index >= bmdm->em->tottri)) {
1908                 BLI_assert(!"error in emDM_getTessFace");
1909                 return;
1910         }
1911
1912         ltri = bmdm->em->looptris[index];
1913
1914         ef = ltri[0]->f;
1915
1916         r_face->mat_nr = (unsigned char) ef->mat_nr;
1917         r_face->flag = BM_face_flag_to_mflag(ef);
1918
1919         r_face->v1 = BM_elem_index_get(ltri[0]->v);
1920         r_face->v2 = BM_elem_index_get(ltri[1]->v);
1921         r_face->v3 = BM_elem_index_get(ltri[2]->v);
1922         r_face->v4 = 0;
1923
1924         test_index_face(r_face, NULL, 0, 3);
1925 }
1926
1927 static void emDM_copyVertArray(DerivedMesh *dm, MVert *r_vert)
1928 {
1929         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1930         BMesh *bm = bmdm->em->bm;
1931         BMVert *eve;
1932         BMIter iter;
1933         const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
1934
1935         if (bmdm->vertexCos) {
1936                 int i;
1937
1938                 BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
1939                         copy_v3_v3(r_vert->co, bmdm->vertexCos[i]);
1940                         normal_float_to_short_v3(r_vert->no, eve->no);
1941                         r_vert->flag = BM_vert_flag_to_mflag(eve);
1942
1943                         r_vert->bweight = (cd_vert_bweight_offset != -1) ? BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset) : 0;
1944
1945                         r_vert++;
1946                 }
1947         }
1948         else {
1949                 BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
1950                         copy_v3_v3(r_vert->co, eve->co);
1951                         normal_float_to_short_v3(r_vert->no, eve->no);
1952                         r_vert->flag = BM_vert_flag_to_mflag(eve);
1953
1954                         r_vert->bweight = (cd_vert_bweight_offset != -1) ? BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset) : 0;
1955
1956                         r_vert++;
1957                 }
1958         }
1959 }
1960
1961 static void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *r_edge)
1962 {
1963         BMesh *bm = ((EditDerivedBMesh *)dm)->em->bm;
1964         BMEdge *eed;
1965         BMIter iter;
1966
1967         const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
1968         const int cd_edge_crease_offset  = CustomData_get_offset(&bm->edata, CD_CREASE);
1969
1970         BM_mesh_elem_index_ensure(bm, BM_VERT);
1971
1972         BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
1973                 r_edge->v1 = BM_elem_index_get(eed->v1);
1974                 r_edge->v2 = BM_elem_index_get(eed->v2);
1975
1976                 r_edge->flag = BM_edge_flag_to_mflag(eed);
1977
1978                 r_edge->crease  = (cd_edge_crease_offset  != -1) ? BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_crease_offset)  : 0;
1979                 r_edge->bweight = (cd_edge_bweight_offset != -1) ? BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_bweight_offset) : 0;
1980
1981                 r_edge++;
1982         }
1983 }
1984
1985 static void emDM_copyTessFaceArray(DerivedMesh *dm, MFace *r_face)
1986 {
1987         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1988         BMesh *bm = bmdm->em->bm;
1989         struct BMLoop *(*looptris)[3] = bmdm->em->looptris;
1990         BMFace *ef;
1991         int i;
1992
1993         BM_mesh_elem_index_ensure(bm, BM_VERT);
1994
1995         for (i = 0; i < bmdm->em->tottri; i++, r_face++) {
1996                 BMLoop **ltri = looptris[i];
1997                 ef = ltri[0]->f;
1998
1999                 r_face->mat_nr = (unsigned char) ef->mat_nr;
2000
2001                 r_face->flag = BM_face_flag_to_mflag(ef);
2002                 r_face->edcode = 0;
2003
2004                 r_face->v1 = BM_elem_index_get(ltri[0]->v);
2005                 r_face->v2 = BM_elem_index_get(ltri[1]->v);
2006                 r_face->v3 = BM_elem_index_get(ltri[2]->v);
2007                 r_face->v4 = 0;
2008
2009                 test_index_face(r_face, NULL, 0, 3);
2010         }
2011 }
2012
2013 static void emDM_copyLoopArray(DerivedMesh *dm, MLoop *r_loop)
2014 {
2015         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
2016         BMesh *bm = bmdm->em->bm;
2017         BMIter iter;
2018         BMFace *efa;
2019
2020         BM_mesh_elem_index_ensure(bm, BM_VERT | BM_EDGE);
2021
2022         BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
2023                 BMLoop *l_iter, *l_first;
2024                 l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
2025                 do {
2026                         r_loop->v = BM_elem_index_get(l_iter->v);
2027                         r_loop->e = BM_elem_index_get(l_iter->e);
2028                         r_loop++;
2029                 } while ((l_iter = l_iter->next) != l_first);
2030         }
2031 }
2032
2033 static void emDM_copyPolyArray(DerivedMesh *dm, MPoly *r_poly)
2034 {
2035         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
2036         BMesh *bm = bmdm->em->bm;
2037         BMIter iter;
2038         BMFace *efa;
2039         int i;
2040
2041         i = 0;
2042         BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
2043                 r_poly->flag = BM_face_flag_to_mflag(efa);
2044                 r_poly->loopstart = i;
2045                 r_poly->totloop = efa->len;
2046                 r_poly->mat_nr = efa->mat_nr;
2047
2048                 r_poly++;
2049                 i += efa->len;
2050         }
2051 }
2052
2053 static void *emDM_getTessFaceDataArray(DerivedMesh *dm, int type)
2054 {
2055         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
2056         BMesh *bm = bmdm->em->bm;
2057         void *datalayer;
2058
2059         datalayer = DM_get_tessface_data_layer(dm, type);
2060         if (datalayer)
2061                 return datalayer;
2062
2063         /* layers are store per face for editmesh, we convert to a temporary
2064          * data layer array in the derivedmesh when these are requested */
2065         if (type == CD_MTFACE || type == CD_MCOL) {
2066                 const int type_from = (type == CD_MTFACE) ? CD_MTEXPOLY : CD_MLOOPCOL;
2067                 int index;
2068                 const char *bmdata;
2069                 char *data;
2070                 index = CustomData_get_layer_index(&bm->pdata, type_from);
2071
2072                 if (index != -1) {
2073                         /* offset = bm->pdata.layers[index].offset; */ /* UNUSED */
2074                         BMLoop *(*looptris)[3] = bmdm->em->looptris;
2075                         const int size = CustomData_sizeof(type);
2076                         int i, j;
2077
2078                         DM_add_tessface_layer(dm, type, CD_CALLOC, NULL);
2079                         index = CustomData_get_layer_index(&dm->faceData, type);
2080                         dm->faceData.layers[index].flag |= CD_FLAG_TEMPORARY;
2081
2082                         data = datalayer = DM_get_tessface_data_layer(dm, type);
2083
2084                         if (type == CD_MTFACE) {
2085                                 const int cd_loop_uv_offset  = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
2086                                 const int cd_poly_tex_offset = CustomData_get_offset(&bm->pdata, CD_MTEXPOLY);
2087
2088                                 for (i = 0; i < bmdm->em->tottri; i++, data += size) {
2089                                         BMFace *efa = looptris[i][0]->f;
2090
2091                                         // bmdata = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY);
2092                                         bmdata = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
2093
2094                                         ME_MTEXFACE_CPY(((MTFace *)data), ((const MTexPoly *)bmdata));
2095                                         for (j = 0; j < 3; j++) {
2096                                                 // bmdata = CustomData_bmesh_get(&bm->ldata, looptris[i][j]->head.data, CD_MLOOPUV);
2097                                                 bmdata = BM_ELEM_CD_GET_VOID_P(looptris[i][j], cd_loop_uv_offset);
2098                                                 copy_v2_v2(((MTFace *)data)->uv[j], ((const MLoopUV *)bmdata)->uv);
2099                                         }
2100                                 }
2101                         }
2102                         else {
2103                                 const int cd_loop_color_offset  = CustomData_get_offset(&bm->ldata, CD_MLOOPCOL);
2104                                 for (i = 0; i < bmdm->em->tottri; i++, data += size) {
2105                                         for (j = 0; j < 3; j++) {
2106                                                 // bmdata = CustomData_bmesh_get(&bm->ldata, looptris[i][j]->head.data, CD_MLOOPCOL);
2107                                                 bmdata = BM_ELEM_CD_GET_VOID_P(looptris[i][j], cd_loop_color_offset);
2108                                                 MESH_MLOOPCOL_TO_MCOL(((const MLoopCol *)bmdata), (((MCol *)data) + j));
2109                                         }
2110                                 }
2111                         }
2112                 }
2113         }
2114
2115         /* Special handling for CD_TESSLOOPNORMAL, we generate it on demand as well. */
2116         if (type == CD_TESSLOOPNORMAL) {
2117                 const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
2118
2119                 if (lnors) {
2120                         BMLoop *(*looptris)[3] = bmdm->em->looptris;
2121                         short (*tlnors)[4][3], (*tlnor)[4][3];
2122                         int index, i, j;
2123
2124                         DM_add_tessface_layer(dm, type, CD_CALLOC, NULL);
2125                         index = CustomData_get_layer_index(&dm->faceData, type);
2126                         dm->faceData.layers[index].flag |= CD_FLAG_TEMPORARY;
2127
2128                         tlnor = tlnors = DM_get_tessface_data_layer(dm, type);
2129
2130                         BM_mesh_elem_index_ensure(bm, BM_LOOP);
2131
2132                         for (i = 0; i < bmdm->em->tottri; i++, tlnor++, looptris++) {
2133                                 for (j = 0; j < 3; j++) {
2134                                         normal_float_to_short_v3((*tlnor)[j], lnors[BM_elem_index_get((*looptris)[j])]);
2135                                 }
2136                         }
2137                 }
2138         }
2139
2140         return datalayer;
2141 }
2142
2143 static void emDM_getVertCos(DerivedMesh *dm, float (*r_cos)[3])
2144 {
2145         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
2146         BMesh *bm = bmdm->em->bm;
2147         BMVert *eve;
2148         BMIter iter;
2149         int i;
2150
2151         if (bmdm->vertexCos) {
2152                 BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
2153                         copy_v3_v3(r_cos[i], bmdm->vertexCos[i]);
2154                 }
2155         }
2156         else {
2157                 BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
2158                         copy_v3_v3(r_cos[i], eve->co);
2159                 }
2160         }
2161 }
2162
2163 static void emDM_release(DerivedMesh *dm)
2164 {
2165         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
2166
2167         if (DM_release(dm)) {
2168                 if (bmdm->vertexCos) {
2169                         MEM_freeN((void *)bmdm->vertexCos);
2170                         if (bmdm->vertexNos) {
2171                                 MEM_freeN((void *)bmdm->vertexNos);
2172                         }
2173                         if (bmdm->polyNos) {
2174                                 MEM_freeN((void *)bmdm->polyNos);
2175                         }
2176                 }
2177
2178                 if (bmdm->polyCos) {
2179                         MEM_freeN((void *)bmdm->polyCos);
2180                 }
2181
2182                 MEM_freeN(bmdm);
2183         }
2184 }
2185
2186 static CustomData *bmDm_getVertDataLayout(DerivedMesh *dm)
2187 {
2188         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
2189
2190         return &bmdm->em->bm->vdata;
2191 }
2192
2193 static CustomData *bmDm_getEdgeDataLayout(DerivedMesh *dm)
2194 {
2195         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
2196
2197         return &bmdm->em->bm->edata;
2198 }
2199
2200 static CustomData *bmDm_getTessFaceDataLayout(DerivedMesh *dm)
2201 {
2202         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
2203
2204         return &bmdm->dm.faceData;
2205 }
2206
2207 static CustomData *bmDm_getLoopDataLayout(DerivedMesh *dm)
2208 {
2209         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
2210
2211         return &bmdm->em->bm->ldata;
2212 }
2213
2214 static CustomData *bmDm_getPolyDataLayout(DerivedMesh *dm)
2215 {
2216         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
2217
2218         return &bmdm->em->bm->pdata;
2219 }
2220
2221
2222 DerivedMesh *getEditDerivedBMesh(
2223         BMEditMesh *em,
2224         Object *UNUSED(ob),
2225         float (*vertexCos)[3])
2226 {
2227         EditDerivedBMesh *bmdm = MEM_callocN(sizeof(*bmdm), __func__);
2228         BMesh *bm = em->bm;
2229         const int cd_dvert_offset = CustomData_get_offset(&bm->vdata, CD_MDEFORMVERT);
2230         const int cd_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN);
2231
2232         bmdm->em = em;
2233
2234         DM_init((DerivedMesh *)bmdm, DM_TYPE_EDITBMESH, bm->totvert,
2235                 bm->totedge, em->tottri, bm->totloop, bm->totface);
2236
2237         /* could also get from the objects mesh directly */
2238         bmdm->dm.cd_flag = BM_mesh_cd_flag_from_bmesh(bm);
2239
2240         bmdm->dm.getVertCos = emDM_getVertCos;
2241         bmdm->dm.getMinMax = emDM_getMinMax;
2242
2243         bmdm->dm.getVertDataLayout = bmDm_getVertDataLayout;
2244         bmdm->dm.getEdgeDataLayout = bmDm_getEdgeDataLayout;
2245         bmdm->dm.getTessFaceDataLayout = bmDm_getTessFaceDataLayout;
2246         bmdm->dm.getLoopDataLayout = bmDm_getLoopDataLayout;
2247         bmdm->dm.getPolyDataLayout = bmDm_getPolyDataLayout;
2248
2249         bmdm->dm.getNumVerts = emDM_getNumVerts;
2250         bmdm->dm.getNumEdges = emDM_getNumEdges;
2251         bmdm->dm.getNumTessFaces = emDM_getNumTessFaces;
2252         bmdm->dm.getNumLoops = emDM_getNumLoops;
2253         bmdm->dm.getNumPolys = emDM_getNumPolys;
2254
2255         bmdm->dm.getLoopTriArray = emDM_getLoopTriArray;
2256
2257         bmdm->dm.getVert = emDM_getVert;
2258         bmdm->dm.getVertCo = emDM_getVertCo;
2259         bmdm->dm.getVertNo = emDM_getVertNo;
2260         bmdm->dm.getPolyNo = emDM_getPolyNo;
2261         bmdm->dm.getEdge = emDM_getEdge;
2262         bmdm->dm.getTessFace = emDM_getTessFace;
2263         bmdm->dm.copyVertArray = emDM_copyVertArray;
2264         bmdm->dm.copyEdgeArray = emDM_copyEdgeArray;
2265         bmdm->dm.copyTessFaceArray = emDM_copyTessFaceArray;
2266         bmdm->dm.copyLoopArray = emDM_copyLoopArray;
2267         bmdm->dm.copyPolyArray = emDM_copyPolyArray;
2268
2269         bmdm->dm.getTessFaceDataArray = emDM_getTessFaceDataArray;
2270
2271         bmdm->dm.calcNormals = emDM_calcNormals;
2272         bmdm->dm.calcLoopNormals = emDM_calcLoopNormals;
2273         bmdm->dm.calcLoopNormalsSpaceArray = emDM_calcLoopNormalsSpaceArray;
2274         bmdm->dm.calcLoopTangents = emDM_calc_loop_tangents;
2275         bmdm->dm.recalcTessellation = emDM_recalcTessellation;
2276         bmdm->dm.recalcLoopTri = emDM_recalcLoopTri;
2277
2278         bmdm->dm.foreachMappedVert = emDM_foreachMappedVert;
2279         bmdm->dm.foreachMappedLoop = emDM_foreachMappedLoop;
2280         bmdm->dm.foreachMappedEdge = emDM_foreachMappedEdge;
2281         bmdm->dm.foreachMappedFaceCenter = emDM_foreachMappedFaceCenter;
2282
2283         bmdm->dm.drawEdges = emDM_drawEdges;
2284         bmdm->dm.drawMappedEdges = emDM_drawMappedEdges;
2285         bmdm->dm.drawMappedEdgesInterp = emDM_drawMappedEdgesInterp;
2286         bmdm->dm.drawMappedFaces = emDM_drawMappedFaces;
2287         bmdm->dm.drawMappedFacesTex = emDM_drawMappedFacesTex;
2288         bmdm->dm.drawMappedFacesGLSL = emDM_drawMappedFacesGLSL;
2289         bmdm->dm.drawMappedFacesMat = emDM_drawMappedFacesMat;
2290         bmdm->dm.drawFacesTex = emDM_drawFacesTex;
2291         bmdm->dm.drawFacesGLSL = emDM_drawFacesGLSL;
2292         bmdm->dm.drawUVEdges = emDM_drawUVEdges;
2293
2294         bmdm->dm.release = emDM_release;
2295
2296         bmdm->vertexCos = (const float (*)[3])vertexCos;
2297         bmdm->dm.deformedOnly = (vertexCos != NULL);
2298
2299         if (cd_dvert_offset != -1) {
2300                 BMIter iter;
2301                 BMVert *eve;
2302                 int i;
2303
2304                 DM_add_vert_layer(&bmdm->dm, CD_MDEFORMVERT, CD_CALLOC, NULL);
2305
2306                 BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
2307                         DM_set_vert_data(&bmdm->dm, i, CD_MDEFORMVERT,
2308                                          BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset));
2309                 }
2310         }
2311
2312         if (cd_skin_offset != -1) {
2313                 BMIter iter;
2314                 BMVert *eve;
2315                 int i;
2316
2317                 DM_add_vert_layer(&bmdm->dm, CD_MVERT_SKIN, CD_CALLOC, NULL);
2318
2319                 BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
2320                         DM_set_vert_data(&bmdm->dm, i, CD_MVERT_SKIN,
2321                                          BM_ELEM_CD_GET_VOID_P(eve, cd_skin_offset));
2322                 }
2323         }
2324
2325         return (DerivedMesh *)bmdm;
2326 }
2327
2328
2329
2330 /* -------------------------------------------------------------------- */
2331 /* StatVis Functions */
2332
2333 static void axis_from_enum_v3(float v[3], const char axis)
2334 {
2335         zero_v3(v);
2336         if (axis < 3) v[axis]     =  1.0f;
2337         else          v[axis - 3] = -1.0f;
2338 }
2339
2340 static void statvis_calc_overhang(
2341         BMEditMesh *em,
2342         const float (*polyNos)[3],
2343         /* values for calculating */
2344         const float min, const float max, const char axis,
2345         /* result */
2346         unsigned char (*r_face_colors)[4])
2347 {
2348         BMIter iter;
2349         BMesh *bm = em->bm;
2350         BMFace *f;
2351         float dir[3];
2352         int index;
2353         const float minmax_irange = 1.0f / (max - min);
2354         bool is_max;
2355
2356         /* fallback */
2357         unsigned char col_fallback[4] = {64, 64, 64, 255}; /* gray */
2358         unsigned char col_fallback_max[4] = {0,  0,  0,  255}; /* max color */
2359
2360         BLI_assert(min <= max);
2361
2362         axis_from_enum_v3(dir, axis);
2363
2364         if (LIKELY(em->ob)) {
2365                 mul_transposed_mat3_m4_v3(em->ob->obmat, dir);
2366                 normalize_v3(dir);
2367         }
2368
2369         /* fallback max */
2370         {
2371                 float fcol[3];
2372                 weight_to_rgb(fcol, 1.0f);
2373                 rgb_float_to_uchar(col_fallback_max, fcol);
2374         }
2375
2376         /* now convert into global space */
2377         BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, index) {
2378                 float fac = angle_normalized_v3v3(polyNos ? polyNos[index] : f->no, dir) / (float)M_PI;
2379
2380                 /* remap */
2381                 if ((is_max = (fac <= max)) && (fac >= min)) {
2382                         float fcol[3];
2383                         fac = (fac - min) * minmax_irange;
2384                         fac = 1.0f - fac;
2385                         CLAMP(fac, 0.0f, 1.0f);
2386                         weight_to_rgb(fcol, fac);
2387                         rgb_float_to_uchar(r_face_colors[index], fcol);
2388                 }
2389                 else {
2390                         const unsigned char *fallback = is_max ? col_fallback_max : col_fallback;
2391                         copy_v4_v4_uchar(r_face_colors[index], fallback);
2392                 }
2393         }
2394 }
2395
2396 /* so we can use jitter values for face interpolation */
2397 static void uv_from_jitter_v2(float uv[2])
2398 {
2399         uv[0] += 0.5f;
2400         uv[1] += 0.5f;
2401         if (uv[0] + uv[1] > 1.0f) {
2402                 uv[0] = 1.0f - uv[0];
2403                 uv[1] = 1.0f - uv[1];
2404         }
2405
2406         CLAMP(uv[0], 0.0f, 1.0f);
2407         CLAMP(uv[1], 0.0f, 1.0f);
2408 }
2409
2410 static void statvis_calc_thickness(
2411         BMEditMesh *em,
2412         const float (*vertexCos)[3],
2413         /* values for calculating */
2414         const float min, const float max, const int samples,
2415         /* result */
2416         unsigned char (*r_face_colors)[4])
2417 {
2418         const float eps_offset = 0.00002f;  /* values <= 0.00001 give errors */
2419         float *face_dists = (float *)r_face_colors;  /* cheating */
2420         const bool use_jit = samples < 32;
2421         float jit_ofs[32][2];
2422         BMesh *bm = em->bm;
2423         const int tottri = em->tottri;
2424         const float minmax_irange = 1.0f / (max - min);
2425         int i;
2426
2427         struct BMLoop *(*looptris)[3] = em->looptris;
2428
2429         /* fallback */
2430         const unsigned char col_fallback[4] = {64, 64, 64, 255};
2431
2432         struct BMBVHTree *bmtree;
2433
2434         BLI_assert(min <= max);
2435
2436         copy_vn_fl(face_dists, em->bm->totface, max);
2437
2438         if (use_jit) {
2439                 int j;
2440                 BLI_assert(samples < 32);
2441                 BLI_jitter_init(jit_ofs, samples);
2442
2443                 for (j = 0; j < samples; j++) {
2444                         uv_from_jitter_v2(jit_ofs[j]);
2445                 }
2446         }
2447
2448         BM_mesh_elem_index_ensure(bm, BM_FACE);
2449         if (vertexCos) {
2450                 BM_mesh_elem_index_ensure(bm, BM_VERT);
2451         }
2452
2453         bmtree = BKE_bmbvh_new_from_editmesh(em, 0, vertexCos, false);
2454
2455         for (i = 0; i < tottri; i++) {
2456                 BMFace *f_hit;
2457                 BMLoop **ltri = looptris[i];
2458                 const int index = BM_elem_index_get(ltri[0]->f);
2459                 const float *cos[3];
2460                 float ray_co[3];
2461                 float ray_no[3];
2462
2463                 if (vertexCos) {
2464                         cos[0] = vertexCos[BM_elem_index_get(ltri[0]->v)];
2465                         cos[1] = vertexCos[BM_elem_index_get(ltri[1]->v)];
2466                         cos[2] = vertexCos[BM_elem_index_get(ltri[2]->v)];
2467                 }
2468                 else {
2469                         cos[0] = ltri[0]->v->co;
2470                         cos[1] = ltri[1]->v->co;
2471                         cos[2] = ltri[2]->v->co;
2472                 }
2473
2474                 normal_tri_v3(ray_no, cos[2], cos[1], cos[0]);
2475
2476 #define FACE_RAY_TEST_ANGLE \
2477                 f_hit = BKE_bmbvh_ray_cast(bmtree, ray_co, ray_no, 0.0f, \
2478                                            &dist, NULL, NULL); \
2479                 if (f_hit && dist < face_dists[index]) { \
2480                         float angle_fac = fabsf(dot_v3v3(ltri[0]->f->no, f_hit->no)); \
2481                         angle_fac = 1.0f - angle_fac; \
2482                         angle_fac = angle_fac * angle_fac * angle_fac; \
2483                         angle_fac = 1.0f - angle_fac; \
2484                         dist /= angle_fac; \
2485                         if (dist < face_dists[index]) { \
2486                                 face_dists[index] = dist; \
2487                         } \
2488                 } (void)0
2489
2490                 if (use_jit) {
2491                         int j;
2492                         for (j = 0; j < samples; j++) {
2493                                 float dist = face_dists[index];
2494                                 interp_v3_v3v3v3_uv(ray_co, cos[0], cos[1], cos[2], jit_ofs[j]);
2495                                 madd_v3_v3fl(ray_co, ray_no, eps_offset);
2496
2497                                 FACE_RAY_TEST_ANGLE;
2498                         }
2499                 }
2500                 else {
2501                         float dist = face_dists[index];
2502                         mid_v3_v3v3v3(ray_co, cos[0], cos[1], cos[2]);
2503                         madd_v3_v3fl(ray_co, ray_no, eps_offset);
2504
2505                         FACE_RAY_TEST_ANGLE;
2506                 }
2507         }
2508
2509         BKE_bmbvh_free(bmtree);
2510
2511         /* convert floats into color! */
2512         for (i = 0; i < bm->totface; i++) {
2513                 float fac = face_dists[i];
2514
2515                 /* important not '<=' */
2516                 if (fac < max) {
2517                         float fcol[3];
2518                         fac = (fac - min) * minmax_irange;
2519                         fac = 1.0f - fac;
2520                         CLAMP(fac, 0.0f, 1.0f);
2521                         weight_to_rgb(fcol, fac);
2522                         rgb_float_to_uchar(r_face_colors[i], fcol);
2523                 }
2524                 else {
2525                         copy_v4_v4_uchar(r_face_colors[i], col_fallback);
2526                 }
2527         }
2528 }
2529
2530 static void statvis_calc_intersect(
2531         BMEditMesh *em,
2532         const float (*vertexCos)[3],
2533         /* result */
2534         unsigned char (*r_face_colors)[4])
2535 {
2536         BMesh *bm = em->bm;
2537         int i;
2538
2539         /* fallback */
2540         // const char col_fallback[4] = {64, 64, 64, 255};
2541         float fcol[3];
2542         unsigned char col[3];
2543
2544         struct BMBVHTree *bmtree;
2545         BVHTreeOverlap *overlap;
2546         unsigned int overlap_len;
2547
2548         memset(r_face_colors, 64, sizeof(int) * em->bm->totface);
2549
2550         BM_mesh_elem_index_ensure(bm, BM_FACE);
2551         if (vertexCos) {
2552                 BM_mesh_elem_index_ensure(bm, BM_VERT);
2553         }
2554
2555         bmtree = BKE_bmbvh_new_from_editmesh(em, 0, vertexCos, false);
2556
2557         overlap = BKE_bmbvh_overlap(bmtree, bmtree, &overlap_len);
2558
2559         /* same for all faces */
2560         weight_to_rgb(fcol, 1.0f);
2561         rgb_float_to_uchar(col, fcol);
2562
2563         if (overlap) {
2564                 for (i = 0; i < overlap_len; i++) {
2565                         BMFace *f_hit_pair[2] = {
2566                             em->looptris[overlap[i].indexA][0]->f,
2567                             em->looptris[overlap[i].indexB][0]->f,
2568                         };
2569                         int j;
2570
2571                         for (j = 0; j < 2; j++) {
2572                                 BMFace *f_hit = f_hit_pair[j];
2573                                 int index;
2574
2575                                 index = BM_elem_index_get(f_hit);
2576
2577                                 copy_v3_v3_uchar(r_face_colors[index], col);
2578                         }
2579                 }
2580                 MEM_freeN(overlap);
2581         }
2582
2583         BKE_bmbvh_free(bmtree);
2584 }
2585
2586 static void statvis_calc_distort(
2587         BMEditMesh *em,
2588         const float (*vertexCos)[3], const float (*polyNos)[3],
2589         /* values for calculating */
2590         const float min, const float max,
2591         /* result */
2592         unsigned char (*r_face_colors)[4])
2593 {
2594         BMIter iter;
2595         BMesh *bm = em->bm;
2596         BMFace *f;
2597         const float *f_no;
2598         int index;
2599         const float minmax_irange = 1.0f / (max - min);
2600
2601         /* fallback */
2602         const unsigned char col_fallback[4] = {64, 64, 64, 255};
2603
2604         /* now convert into global space */
2605         BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, index) {
2606                 float fac;
2607
2608                 if (f->len == 3) {
2609                         fac = -1.0f;
2610                 }
2611                 else {
2612                         BMLoop *l_iter, *l_first;
2613                         if (vertexCos) {
2614                                 f_no = polyNos[index];
2615                         }
2616                         else {
2617                                 f_no = f->no;
2618                         }
2619
2620                         fac = 0.0f;
2621                         l_iter = l_first = BM_FACE_FIRST_LOOP(f);
2622                         do {
2623                                 float no_corner[3];
2624                                 if (vertexCos) {
2625                                         normal_tri_v3(no_corner,
2626                                                       vertexCos[BM_elem_index_get(l_iter->prev->v)],
2627                                                       vertexCos[BM_elem_index_get(l_iter->v)],
2628                                                       vertexCos[BM_elem_index_get(l_iter->next->v)]);
2629                                 }
2630                                 else {
2631                                         BM_loop_calc_face_normal(l_iter, no_corner);
2632                                 }
2633                                 /* simple way to detect (what is most likely) concave */
2634                                 if (dot_v3v3(f_no, no_corner) < 0.0f) {
2635                                         negate_v3(no_corner);
2636                                 }
2637                                 fac = max_ff(fac, angle_normalized_v3v3(f_no, no_corner));
2638                         } while ((l_iter = l_iter->next) != l_first);
2639                         fac *= 2.0f;
2640                 }
2641
2642                 /* remap */
2643                 if (fac >= min) {
2644                         float fcol[3];
2645                         fac = (fac - min) * minmax_irange;
2646                         CLAMP(fac, 0.0f, 1.0f);
2647                         weight_to_rgb(fcol, fac);
2648                         rgb_float_to_uchar(r_face_colors[index], fcol);
2649                 }
2650                 else {
2651                         copy_v4_v4_uchar(r_face_colors[index], col_fallback);
2652                 }
2653         }
2654 }
2655
2656 static void statvis_calc_sharp(
2657         BMEditMesh *em,
2658         const float (*vertexCos)[3],
2659         /* values for calculating */
2660         const float min, const float max,
2661         /* result */
2662         unsigned char (*r_vert_colors)[4])
2663 {
2664         float *vert_angles = (float *)r_vert_colors;  /* cheating */
2665         BMIter iter;
2666         BMesh *bm = em->bm;
2667         BMEdge *e;
2668         //float f_no[3];
2669         const float minmax_irange = 1.0f / (max - min);
2670         int i;
2671
2672         /* fallback */
2673         const unsigned char col_fallback[4] = {64, 64, 64, 255};
2674
2675         (void)vertexCos;  /* TODO */
2676
2677         copy_vn_fl(vert_angles, em->bm->totvert, -M_PI);
2678
2679         /* first assign float values to verts */
2680         BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
2681                 float angle = BM_edge_calc_face_angle_signed(e);
2682                 float *col1 = &vert_angles[BM_elem_index_get(e->v1)];
2683                 float *col2 = &vert_angles[BM_elem_index_get(e->v2)];
2684                 *col1 = max_ff(*col1, angle);
2685                 *col2 = max_ff(*col2, angle);
2686         }
2687
2688         /* convert floats into color! */
2689         for (i = 0; i < bm->totvert; i++) {
2690                 float fac = vert_angles[i];
2691
2692                 /* important not '<=' */
2693                 if (fac > min) {
2694                         float fcol[3];
2695                         fac = (fac - min) * minmax_irange;
2696                         CLAMP(fac, 0.0f, 1.0f);
2697                         weight_to_rgb(fcol, fac);
2698                         rgb_float_to_uchar(r_vert_colors[i], fcol);
2699                 }
2700                 else {
2701                         copy_v4_v4_uchar(r_vert_colors[i], col_fallback);
2702                 }
2703         }
2704 }
2705
2706 void BKE_editmesh_statvis_calc(
2707         BMEditMesh *em, DerivedMesh *dm,
2708         const MeshStatVis *statvis)
2709 {
2710         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
2711         BLI_assert(dm == NULL || dm->type == DM_TYPE_EDITBMESH);
2712
2713         switch (statvis->type) {
2714                 case SCE_STATVIS_OVERHANG:
2715                 {
2716                         BKE_editmesh_color_ensure(em, BM_FACE);
2717                         statvis_calc_overhang(
2718                                     em, bmdm ? bmdm->polyNos : NULL,
2719                                     statvis->overhang_min / (float)M_PI,
2720                                     statvis->overhang_max / (float)M_PI,
2721                                     statvis->overhang_axis,
2722                                     em->derivedFaceColor);
2723                         break;
2724                 }
2725                 case SCE_STATVIS_THICKNESS:
2726                 {
2727                         const float scale = 1.0f / mat4_to_scale(em->ob->obmat);
2728                         BKE_editmesh_color_ensure(em, BM_FACE);
2729                         statvis_calc_thickness(
2730                                     em, bmdm ? bmdm->vertexCos : NULL,
2731                                     statvis->thickness_min * scale,
2732                                     statvis->thickness_max * scale,
2733                                     statvis->thickness_samples,
2734                                     em->derivedFaceColor);
2735                         break;
2736                 }
2737                 case SCE_STATVIS_INTERSECT:
2738                 {
2739                         BKE_editmesh_color_ensure(em, BM_FACE);
2740                         statvis_calc_intersect(
2741                                     em, bmdm ? bmdm->vertexCos : NULL,
2742                                     em->derivedFaceColor);
2743                         break;
2744                 }
2745                 case SCE_STATVIS_DISTORT:
2746                 {
2747                         BKE_editmesh_color_ensure(em, BM_FACE);
2748
2749                         if (bmdm)
2750                                 emDM_ensurePolyNormals(bmdm);
2751
2752                         statvis_calc_distort(
2753                                 em, bmdm ? bmdm->vertexCos : NULL, bmdm ? bmdm->polyNos : NULL,
2754                                 statvis->distort_min,
2755                                 statvis->distort_max,
2756                                 em->derivedFaceColor);
2757                         break;
2758                 }
2759                 case SCE_STATVIS_SHARP:
2760                 {
2761                         BKE_editmesh_color_ensure(em, BM_VERT);
2762                         statvis_calc_sharp(
2763                                 em, bmdm ? bmdm->vertexCos : NULL,
2764                                 statvis->sharp_min,
2765                                 statvis->sharp_max,
2766                                 /* in this case they are vertex colors */
2767                                 em->derivedVertColor);
2768                         break;
2769                 }
2770         }
2771 }
2772
2773
2774
2775 /* -------------------------------------------------------------------- */
2776 /* Editmesh Vert Coords */
2777
2778 struct CageUserData {
2779         int totvert;
2780         float (*cos_cage)[3];
2781         BLI_bitmap *visit_bitmap;
2782 };
2783
2784 static void cage_mapped_verts_callback(
2785         void *userData, int index, const float co[3],
2786         const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
2787 {
2788         struct CageUserData *data = userData;
2789
2790         if ((index >= 0 && index < data->totvert) && (!BLI_BITMAP_TEST(data->visit_bitmap, index))) {
2791                 BLI_BITMAP_ENABLE(data->visit_bitmap, index);
2792                 copy_v3_v3(data->cos_cage[index], co);
2793         }
2794 }
2795
2796 float (*BKE_editmesh_vertexCos_get(BMEditMesh *em, Scene *scene, int *r_numVerts))[3]
2797 {
2798         DerivedMesh *cage, *final;
2799         BLI_bitmap *visit_bitmap;
2800         struct CageUserData data;
2801         float (*cos_cage)[3];
2802
2803         cage = editbmesh_get_derived_cage_and_final(scene, em->ob, em, CD_MASK_BAREMESH, &final);
2804         cos_cage = MEM_callocN(sizeof(*cos_cage) * em->bm->totvert, "bmbvh cos_cage");
2805
2806         /* when initializing cage verts, we only want the first cage coordinate for each vertex,
2807          * so that e.g. mirror or array use original vertex coordinates and not mirrored or duplicate */
2808         visit_bitmap = BLI_BITMAP_NEW(em->bm->totvert, __func__);
2809
2810         data.totvert = em->bm->totvert;
2811         data.cos_cage = cos_cage;
2812         data.visit_bitmap = visit_bitmap;
2813
2814         cage->foreachMappedVert(cage, cage_mapped_verts_callback, &data, DM_FOREACH_NOP);
2815
2816         MEM_freeN(visit_bitmap);
2817
2818         if (r_numVerts) {
2819                 *r_numVerts = em->bm->totvert;
2820         }
2821
2822         return cos_cage;
2823 }