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