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