svn merge ^/trunk/blender -r43976:43995
[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
32 #include <string.h>
33 #include <limits.h>
34 #include <math.h>
35
36 #include "GL/glew.h"
37
38 #include "BLI_utildefines.h"
39 #include "BLI_blenlib.h"
40 #include "BLI_edgehash.h"
41 #include "BLI_editVert.h"
42 #include "BLI_math.h"
43 #include "BLI_pbvh.h"
44
45 #include "BKE_cdderivedmesh.h"
46 #include "BKE_global.h"
47 #include "BKE_mesh.h"
48 #include "BKE_paint.h"
49
50
51 #include "DNA_meshdata_types.h"
52 #include "DNA_object_types.h"
53 #include "DNA_curve_types.h" /* for Curve */
54
55 #include "MEM_guardedalloc.h"
56
57 #include "GPU_buffers.h"
58 #include "GPU_draw.h"
59 #include "GPU_extensions.h"
60 #include "GPU_material.h"
61
62 /* bmesh */
63 #include "BKE_tessmesh.h"
64 #include "BLI_array.h"
65 #include "BLI_scanfill.h"
66
67 #include "bmesh.h"
68 /* end bmesh */
69
70 extern GLubyte stipple_quarttone[128]; /* glutil.c, bad level data */
71
72
73 BMEditMesh *BMEdit_Create(BMesh *bm, int do_tesselate)
74 {
75         BMEditMesh *tm = MEM_callocN(sizeof(BMEditMesh), __func__);
76
77         tm->bm = bm;
78         if (do_tesselate) {
79                 BMEdit_RecalcTesselation(tm);
80         }
81
82         return tm;
83 }
84
85 BMEditMesh *BMEdit_Copy(BMEditMesh *tm)
86 {
87         BMEditMesh *tm2 = MEM_callocN(sizeof(BMEditMesh), __func__);
88         *tm2 = *tm;
89
90         tm2->derivedCage = tm2->derivedFinal = NULL;
91
92         tm2->bm = BM_Copy_Mesh(tm->bm);
93
94         /*The tesselation is NOT calculated on the copy here,
95           because currently all the callers of this function use
96           it to make a backup copy of the BMEditMesh to restore
97           it in the case of errors in an operation. For perf
98           reasons, in that case it makes more sense to do the
99           tesselation only when/if that copy ends up getting
100           used.*/
101         tm2->looptris = NULL;
102
103         tm2->vert_index = NULL;
104         tm2->edge_index = NULL;
105         tm2->face_index = NULL;
106
107         return tm2;
108 }
109
110 static void BMEdit_RecalcTesselation_intern(BMEditMesh *tm)
111 {
112         /* use this to avoid locking pthread for _every_ polygon
113          * and calling the fill function */
114 #define USE_TESSFACE_SPEEDUP
115
116         BMesh *bm = tm->bm;
117         BMLoop *(*looptris)[3]= NULL;
118         BLI_array_declare(looptris);
119         BMIter iter, liter;
120         BMFace *f;
121         BMLoop *l;
122         int i = 0, j;
123
124 #if 0
125         /* note, we could be clever and re-use this array but would need to ensure
126          * its realloced at some point, for now just free it */
127         if (tm->looptris) MEM_freeN(tm->looptris);
128
129         /* Use tm->tottri when set, this means no reallocs while transforming,
130          * (unless scanfill fails), otherwise... */
131         /* allocate the length of totfaces, avoid many small reallocs,
132          * if all faces are tri's it will be correct, quads == 2x allocs */
133         BLI_array_reserve(looptris, (tm->tottri && tm->tottri < bm->totface * 3) ? tm->tottri : bm->totface);
134 #else
135
136         /* this means no reallocs for quad dominant models, for */
137         if ( (tm->looptris != NULL) &&
138              (tm->tottri != 0) &&
139              /* (totrti <= bm->totface * 2) would be fine for all quads,
140                   * but incase there are some ngons, still re-use the array */
141              (tm->tottri <= bm->totface * 3))
142         {
143                 looptris = tm->looptris;
144         }
145         else {
146                 if (tm->looptris) MEM_freeN(tm->looptris);
147                 BLI_array_reserve(looptris, bm->totface);
148         }
149
150 #endif
151
152         f = BMIter_New(&iter, bm, BM_FACES_OF_MESH, NULL);
153         for ( ; f; f=BMIter_Step(&iter)) {
154                 /*don't consider two-edged faces*/
155                 if (f->len < 3) {
156                         /* do nothing */
157                 }
158
159 #ifdef USE_TESSFACE_SPEEDUP
160
161                 /* no need to ensure the loop order, we know its ok */
162
163                 else if (f->len == 3) {
164                         BLI_array_growone(looptris);
165                         l = BMIter_New(&liter, bm, BM_LOOPS_OF_FACE, f);
166                         for (j=0; l; l=BMIter_Step(&liter), j++) {
167                                 looptris[i][j] = l;
168                         }
169                         i += 1;
170                 }
171                 else if (f->len == 4) {
172                         BMLoop *ltmp[4];
173                         BLI_array_growitems(looptris, 2);
174
175                         l = BMIter_New(&liter, bm, BM_LOOPS_OF_FACE, f);
176                         for (j=0; l; l=BMIter_Step(&liter), j++) {
177                                 ltmp[j] = l;
178                         }
179
180                         looptris[i][0] = ltmp[0];
181                         looptris[i][1] = ltmp[1];
182                         looptris[i][2] = ltmp[2];
183                         i += 1;
184
185                         looptris[i][0] = ltmp[0];
186                         looptris[i][1] = ltmp[2];
187                         looptris[i][2] = ltmp[3];
188                         i += 1;
189                 }
190
191 #endif /* USE_TESSFACE_SPEEDUP */
192
193                 else {
194                         EditVert *v, *lastv=NULL, *firstv=NULL;
195                         EditEdge *e;
196                         EditFace *efa;
197                         int totfilltri;
198
199                         BLI_begin_edgefill();
200                         /*scanfill time*/
201                         l = BMIter_New(&liter, bm, BM_LOOPS_OF_FACE, f);
202                         for (j=0; l; l=BMIter_Step(&liter), j++) {
203                                 /*mark order*/
204                                 BM_SetIndex(l, j); /* set_loop */
205
206                                 v = BLI_addfillvert(l->v->co);
207                                 v->tmp.p = l;
208
209                                 if (lastv) {
210                                         e = BLI_addfilledge(lastv, v);
211                                 }
212
213                                 lastv = v;
214                                 if (firstv==NULL) firstv = v;
215                         }
216
217                         /*complete the loop*/
218                         BLI_addfilledge(firstv, v);
219
220                         totfilltri = BLI_edgefill(2);
221                         BLI_array_growitems(looptris, totfilltri);
222
223                         for (efa = fillfacebase.first; efa; efa=efa->next) {
224                                 BMLoop *l1= efa->v1->tmp.p;
225                                 BMLoop *l2= efa->v2->tmp.p;
226                                 BMLoop *l3= efa->v3->tmp.p;
227
228                                 if (BM_GetIndex(l1) > BM_GetIndex(l2)) { SWAP(BMLoop*, l1, l2); }
229                                 if (BM_GetIndex(l2) > BM_GetIndex(l3)) { SWAP(BMLoop*, l2, l3); }
230                                 if (BM_GetIndex(l1) > BM_GetIndex(l2)) { SWAP(BMLoop*, l1, l2); }
231
232                                 looptris[i][0] = l1;
233                                 looptris[i][1] = l2;
234                                 looptris[i][2] = l3;
235                                 i += 1;
236                         }
237
238                         BLI_end_edgefill();
239                 }
240         }
241
242         tm->tottri = i;
243         tm->looptris = looptris;
244
245 #undef USE_TESSFACE_SPEEDUP
246
247 }
248
249 void BMEdit_RecalcTesselation(BMEditMesh *em)
250 {
251         BMEdit_RecalcTesselation_intern(em);
252
253         /* commented because editbmesh_build_data() ensures we get tessfaces */
254 #if 0
255         if (em->derivedFinal && em->derivedFinal == em->derivedCage) {
256                 if (em->derivedFinal->recalcTesselation)
257                         em->derivedFinal->recalcTesselation(em->derivedFinal);
258         }
259         else if (em->derivedFinal) {
260                 if (em->derivedCage->recalcTesselation)
261                         em->derivedCage->recalcTesselation(em->derivedCage);
262                 if (em->derivedFinal->recalcTesselation)
263                         em->derivedFinal->recalcTesselation(em->derivedFinal);
264         }
265 #endif
266 }
267
268 void BMEdit_UpdateLinkedCustomData(BMEditMesh *em)
269 {
270         BMesh *bm = em->bm;
271         int act;
272
273         if (CustomData_has_layer(&bm->pdata, CD_MTEXPOLY)) {
274                 act = CustomData_get_active_layer(&bm->pdata, CD_MTEXPOLY);
275                 CustomData_set_layer_active(&bm->ldata, CD_MLOOPUV, act);
276
277                 act = CustomData_get_render_layer(&bm->pdata, CD_MTEXPOLY);
278                 CustomData_set_layer_render(&bm->ldata, CD_MLOOPUV, act);
279
280                 act = CustomData_get_clone_layer(&bm->pdata, CD_MTEXPOLY);
281                 CustomData_set_layer_clone(&bm->ldata, CD_MLOOPUV, act);
282
283                 act = CustomData_get_stencil_layer(&bm->pdata, CD_MTEXPOLY);
284                 CustomData_set_layer_stencil(&bm->ldata, CD_MLOOPUV, act);
285         }
286 }
287
288 /*does not free the BMEditMesh struct itself*/
289 void BMEdit_Free(BMEditMesh *em)
290 {
291         if (em->derivedFinal) {
292                 if (em->derivedFinal!=em->derivedCage) {
293                         em->derivedFinal->needsFree= 1;
294                         em->derivedFinal->release(em->derivedFinal);
295                 }
296                 em->derivedFinal= NULL;
297         }
298         if (em->derivedCage) {
299                 em->derivedCage->needsFree= 1;
300                 em->derivedCage->release(em->derivedCage);
301                 em->derivedCage= NULL;
302         }
303
304         if (em->looptris) MEM_freeN(em->looptris);
305
306         if (em->vert_index) MEM_freeN(em->vert_index);
307         if (em->edge_index) MEM_freeN(em->edge_index);
308         if (em->face_index) MEM_freeN(em->face_index);
309
310         if (em->bm)
311                 BM_Free_Mesh(em->bm);
312 }
313
314 /*
315 ok, basic design:
316
317 the bmesh derivedmesh exposes the mesh as triangles.  it stores pointers
318 to three loops per triangle.  the derivedmesh stores a cache of tesselations
319 for each face.  this cache will smartly update as needed (though at first
320 it'll simply be more brute force).  keeping track of face/edge counts may
321 be a small problbm.
322
323 this won't be the most efficient thing, considering that internal edges and
324 faces of tesselations are exposed.  looking up an edge by index in particular
325 is likely to be a little slow.
326 */
327
328 typedef struct EditDerivedBMesh {
329         DerivedMesh dm;
330
331         Object *ob;
332         BMEditMesh *tc;
333
334         float (*vertexCos)[3];
335         float (*vertexNos)[3];
336         float (*polyNos)[3];
337
338         /*lookup caches; these are rebuilt on dm->RecalcTesselation()
339           (or when the derivedmesh is created, of course)*/
340         BMVert **vtable;
341         BMEdge **etable;
342         BMFace **ftable;
343
344         /*private variables, for number of verts/edges/faces
345           within the above hash/table members*/
346         int tv, te, tf;
347 } EditDerivedBMesh;
348
349 /* BMESH_TODO, since this is not called get functions fail! */
350 static void UNUSED_FUNCTION(bmdm_recalc_lookups)(EditDerivedBMesh *bmdm)
351 {
352         const char iter_types[3] = {BM_VERTS_OF_MESH,
353                                     BM_EDGES_OF_MESH,
354                                     BM_FACES_OF_MESH};
355
356         BMHeader **iters_table[3] = {(BMHeader **)bmdm->vtable,
357                                      (BMHeader **)bmdm->etable,
358                                      (BMHeader **)bmdm->ftable};
359
360         BMIter iter;
361         int a, i;
362
363         bmdm->tv = bmdm->tc->bm->totvert;
364         bmdm->te = bmdm->tc->bm->totedge;
365         bmdm->tf = bmdm->tc->bm->totface;
366
367         if (bmdm->vtable) MEM_freeN(bmdm->vtable);
368         if (bmdm->etable) MEM_freeN(bmdm->etable);
369         if (bmdm->ftable) MEM_freeN(bmdm->ftable);
370
371         if (bmdm->tc->bm->totvert)
372                 bmdm->vtable = MEM_mallocN(sizeof(void**)*bmdm->tc->bm->totvert, "bmdm->vtable");
373         else bmdm->vtable = NULL;
374
375         if (bmdm->tc->bm->totedge)
376                 bmdm->etable = MEM_mallocN(sizeof(void**)*bmdm->tc->bm->totedge, "bmdm->etable");
377         else bmdm->etable = NULL;
378
379         if (bmdm->tc->bm->totface)
380                 bmdm->ftable = MEM_mallocN(sizeof(void**)*bmdm->tc->bm->totface, "bmdm->ftable");
381         else bmdm->ftable = NULL;
382
383         for (a=0; a<3; a++) {
384                 BMHeader **table = iters_table[a];
385                 BMHeader *ele;
386
387                 ele = BMIter_New(&iter, bmdm->tc->bm, iter_types[a], NULL);
388                 for (i=0; ele; ele=BMIter_Step(&iter), i++) {
389                         table[i] = ele;
390                         BM_SetIndex(ele, i);  /* set_ok */
391                 }
392         }
393         bmdm->tc->bm->elem_index_dirty &= ~(BM_VERT|BM_EDGE|BM_FACE);
394
395 }
396
397 static void emDM_calcNormals(DerivedMesh *UNUSED(dm))
398 {
399         /* Nothing to do: normals are already calculated and stored on the
400            BMVerts and BMFaces */
401 }
402
403 static void emDM_recalcTesselation(DerivedMesh *UNUSED(dm))
404 {
405         //EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
406
407         //bmdm_recalc_lookups(bmdm);
408 }
409
410 static void emDM_foreachMappedVert(
411                 DerivedMesh *dm,
412                 void (*func)(void *userData, int index, float *co, float *no_f, short *no_s),
413                 void *userData)
414 {
415         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
416         BMVert *eve;
417         BMIter iter;
418         int i;
419
420         eve = BMIter_New(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
421         for (i=0; eve; i++, eve=BMIter_Step(&iter)) {
422                 if (bmdm->vertexCos) {
423                         func(userData, i, bmdm->vertexCos[i], bmdm->vertexNos[i], NULL);
424                 }
425                 else {
426                         func(userData, i, eve->co, eve->no, NULL);
427                 }
428         }
429 }
430 static void emDM_foreachMappedEdge(
431                 DerivedMesh *dm,
432                 void (*func)(void *userData, int index, float *v0co, float *v1co),
433                 void *userData)
434 {
435         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
436         BMEdge *eed;
437         BMIter iter;
438         int i;
439
440         if (bmdm->vertexCos) {
441
442                 BM_ElemIndex_Ensure(bmdm->tc->bm, BM_VERT);
443
444                 eed = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
445                 for (i=0; eed; i++,eed=BMIter_Step(&iter))
446                         func(userData, i,
447                                  bmdm->vertexCos[BM_GetIndex(eed->v1)],
448                                  bmdm->vertexCos[BM_GetIndex(eed->v2)]);
449         }
450         else {
451                 eed = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
452                 for (i=0; eed; i++,eed=BMIter_Step(&iter))
453                         func(userData, i, eed->v1->co, eed->v2->co);
454         }
455 }
456
457 static void emDM_drawMappedEdges(
458                 DerivedMesh *dm,
459                 int (*setDrawOptions)(void *userData, int index),
460                 void *userData)
461 {
462         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
463         BMEdge *eed;
464         BMIter iter;
465         int i;
466
467         if (bmdm->vertexCos) {
468
469                 BM_ElemIndex_Ensure(bmdm->tc->bm, BM_VERT);
470
471                 glBegin(GL_LINES);
472                 eed = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
473                 for (i=0; eed; i++,eed=BMIter_Step(&iter)) {
474                         if (!setDrawOptions || setDrawOptions(userData, i)) {
475                                 glVertex3fv(bmdm->vertexCos[BM_GetIndex(eed->v1)]);
476                                 glVertex3fv(bmdm->vertexCos[BM_GetIndex(eed->v2)]);
477                         }
478                 }
479                 glEnd();
480         }
481         else {
482                 glBegin(GL_LINES);
483                 eed = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
484                 for (i=0; eed; i++,eed=BMIter_Step(&iter)) {
485                         if (!setDrawOptions || setDrawOptions(userData, i)) {
486                                 glVertex3fv(eed->v1->co);
487                                 glVertex3fv(eed->v2->co);
488                         }
489                 }
490                 glEnd();
491         }
492 }
493 static void emDM_drawEdges(
494                 DerivedMesh *dm,
495                 int UNUSED(drawLooseEdges),
496                 int UNUSED(drawAllEdges))
497 {
498         emDM_drawMappedEdges(dm, NULL, NULL);
499 }
500
501 static void emDM_drawMappedEdgesInterp(
502                 DerivedMesh *dm,
503                 int (*setDrawOptions)(void *userData, int index),
504                 void (*setDrawInterpOptions)(void *userData, int index, float t),
505                 void *userData)
506 {
507         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
508         BMEdge *eed;
509         BMIter iter;
510         int i;
511
512         if (bmdm->vertexCos) {
513
514                 BM_ElemIndex_Ensure(bmdm->tc->bm, BM_VERT);
515
516                 glBegin(GL_LINES);
517                 eed = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
518                 for (i=0; eed; i++,eed=BMIter_Step(&iter)) {
519                         if (!setDrawOptions || setDrawOptions(userData, i)) {
520                                 setDrawInterpOptions(userData, i, 0.0);
521                                 glVertex3fv(bmdm->vertexCos[BM_GetIndex(eed->v1)]);
522                                 setDrawInterpOptions(userData, i, 1.0);
523                                 glVertex3fv(bmdm->vertexCos[BM_GetIndex(eed->v2)]);
524                         }
525                 }
526                 glEnd();
527         }
528         else {
529                 glBegin(GL_LINES);
530                 eed = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
531                 for (i=0; eed; i++,eed=BMIter_Step(&iter)) {
532                         if (!setDrawOptions || setDrawOptions(userData, i)) {
533                                 setDrawInterpOptions(userData, i, 0.0);
534                                 glVertex3fv(eed->v1->co);
535                                 setDrawInterpOptions(userData, i, 1.0);
536                                 glVertex3fv(eed->v2->co);
537                         }
538                 }
539                 glEnd();
540         }
541 }
542
543 static void emDM_drawUVEdges(DerivedMesh *dm)
544 {
545         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
546         BMEditMesh *em = bmdm->tc;
547         BMFace *efa;
548         BMIter iter;
549
550         glBegin(GL_LINES);
551         BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
552                 BMIter liter;
553                 BMLoop *l;
554                 MLoopUV *lastluv = NULL, *firstluv = NULL;
555
556                 if (BM_TestHFlag(efa, BM_HIDDEN))
557                         continue;
558
559                 BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
560                         MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
561
562                         if (luv) {
563                                 if (lastluv)
564                                         glVertex2fv(luv->uv);
565                                 glVertex2fv(luv->uv);
566
567                                 lastluv = luv;
568                                 if (!firstluv)
569                                         firstluv = luv;
570                         }
571                 }
572
573                 if (lastluv) {
574                         glVertex2fv(lastluv->uv);
575                         glVertex2fv(firstluv->uv);
576                 }
577         }
578         glEnd();
579 }
580
581 static void emDM__calcFaceCent(BMesh *bm, BMFace *efa, float cent[3], float (*vertexCos)[3])
582 {
583         BMIter iter;
584         BMLoop *l;
585         int tot = 0;
586
587         zero_v3(cent);
588
589         /*simple (and stupid) median (average) based method :/ */
590
591         if (vertexCos) {
592                 l = BMIter_New(&iter, bm, BM_LOOPS_OF_FACE, efa);
593                 for (; l; l=BMIter_Step(&iter)) {
594                         add_v3_v3(cent, vertexCos[BM_GetIndex(l->v)]);
595                         tot++;
596                 }
597         }
598         else {
599                 l = BMIter_New(&iter, bm, BM_LOOPS_OF_FACE, efa);
600                 for (; l; l=BMIter_Step(&iter)) {
601                         add_v3_v3(cent, l->v->co);
602                         tot++;
603                 }
604         }
605
606         if (tot==0) return;
607         mul_v3_fl(cent, 1.0f/(float)tot);
608 }
609
610 static void emDM_foreachMappedFaceCenter(
611                 DerivedMesh *dm,
612                 void (*func)(void *userData, int index, float *co, float *no),
613                 void *userData)
614 {
615         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
616         float (*polyNos)[3] = NULL;
617         BMFace *efa;
618         BMIter iter;
619         float cent[3];
620         int i;
621
622         /* ensure for face center calculation */
623         if (bmdm->vertexCos) {
624                 BM_ElemIndex_Ensure(bmdm->tc->bm, BM_VERT);
625                 polyNos = bmdm->polyNos;
626
627                 BLI_assert(polyNos != NULL);
628         }
629
630         efa = BMIter_New(&iter, bmdm->tc->bm, BM_FACES_OF_MESH, NULL);
631         for (i=0; efa; efa=BMIter_Step(&iter), i++) {
632                 emDM__calcFaceCent(bmdm->tc->bm, efa, cent, bmdm->vertexCos);
633                 func(userData, i, cent, polyNos ? polyNos[i] : efa->no);
634         }
635 }
636
637 static void emDM_drawMappedFaces(
638                 DerivedMesh *dm,
639                 int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r),
640                 int (*setMaterial)(int, void *attribs),
641                 int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
642                 void *userData, int UNUSED(useColors))
643 {
644         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
645         BMFace *efa;
646         struct BMLoop *(*looptris)[3]= bmdm->tc->looptris;
647         const int tottri= bmdm->tc->tottri;
648         const int lasttri= tottri - 1; /* compare agasint this a lot */
649         int i, draw, flush;
650         const int skip_normals= !glIsEnabled(GL_LIGHTING); /* could be passed as an arg */
651
652         /* GL_ZERO is used to detect if drawing has started or not */
653         GLenum poly_prev= GL_ZERO;
654         GLenum shade_prev= GL_ZERO;
655
656         (void)setMaterial; /* UNUSED */
657
658         /* currently unused -- each original face is handled separately */
659         (void)compareDrawOptions;
660
661         if (bmdm->vertexCos) {
662                 /* add direct access */
663                 float (*vertexCos)[3]= bmdm->vertexCos;
664                 float (*vertexNos)[3]= bmdm->vertexNos;
665                 float (*polyNos)[3]=   bmdm->polyNos;
666                 // int *triPolyMap= bmdm->triPolyMap;
667
668                 BM_ElemIndex_Ensure(bmdm->tc->bm, BM_VERT | BM_FACE);
669
670                 for (i=0; i < tottri; i++) {
671                         BMLoop **l = looptris[i];
672                         int drawSmooth;
673
674                         efa = l[0]->f;
675                         drawSmooth= BM_TestHFlag(efa, BM_SMOOTH);
676
677                         draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, BM_GetIndex(efa), &drawSmooth);
678                         if (draw) {
679                                 const GLenum poly_type= GL_TRIANGLES; /* BMESH NOTE, this is odd but keep it for now to match trunk */
680                                 if (draw==2) { /* enabled with stipple */
681
682                                         if (poly_prev != GL_ZERO) glEnd();
683                                         poly_prev= GL_ZERO; /* force glBegin */
684
685                                         glEnable(GL_POLYGON_STIPPLE);
686                                         glPolygonStipple(stipple_quarttone);
687                                 }
688
689                                 if (skip_normals) {
690                                         if (poly_type != poly_prev) {
691                                                 if (poly_prev != GL_ZERO) glEnd();
692                                                 glBegin((poly_prev= poly_type)); /* BMesh: will always be GL_TRIANGLES */
693                                         }
694                                         glVertex3fv(vertexCos[BM_GetIndex(l[0]->v)]);
695                                         glVertex3fv(vertexCos[BM_GetIndex(l[1]->v)]);
696                                         glVertex3fv(vertexCos[BM_GetIndex(l[2]->v)]);
697                                 }
698                                 else {
699                                         const GLenum shade_type= drawSmooth ? GL_SMOOTH : GL_FLAT;
700                                         if (shade_type != shade_prev) {
701                                                 if (poly_prev != GL_ZERO) glEnd();
702                                                 glShadeModel((shade_prev= shade_type)); /* same as below but switch shading */
703                                                 glBegin((poly_prev= poly_type)); /* BMesh: will always be GL_TRIANGLES */
704                                         }
705                                         if (poly_type != poly_prev) {
706                                                 if (poly_prev != GL_ZERO) glEnd();
707                                                 glBegin((poly_prev= poly_type)); /* BMesh: will always be GL_TRIANGLES */
708                                         }
709
710                                         if (!drawSmooth) {
711                                                 glNormal3fv(polyNos[BM_GetIndex(efa)]);
712                                                 glVertex3fv(vertexCos[BM_GetIndex(l[0]->v)]);
713                                                 glVertex3fv(vertexCos[BM_GetIndex(l[1]->v)]);
714                                                 glVertex3fv(vertexCos[BM_GetIndex(l[2]->v)]);
715                                         }
716                                         else {
717                                                 glNormal3fv(vertexNos[BM_GetIndex(l[0]->v)]);
718                                                 glVertex3fv(vertexCos[BM_GetIndex(l[0]->v)]);
719                                                 glNormal3fv(vertexNos[BM_GetIndex(l[1]->v)]);
720                                                 glVertex3fv(vertexCos[BM_GetIndex(l[1]->v)]);
721                                                 glNormal3fv(vertexNos[BM_GetIndex(l[2]->v)]);
722                                                 glVertex3fv(vertexCos[BM_GetIndex(l[2]->v)]);
723                                         }
724                                 }
725
726                                 flush= (draw==2);
727                                 if (!skip_normals && !flush && (i != lasttri))
728                                         flush|= efa->mat_nr != looptris[i + 1][0]->f->mat_nr; /* TODO, make this neater */
729
730                                 if (flush) {
731                                         glEnd();
732                                         poly_prev= GL_ZERO; /* force glBegin */
733
734                                         glDisable(GL_POLYGON_STIPPLE);
735                                 }
736                         }
737                 }
738         }
739         else {
740                 BM_ElemIndex_Ensure(bmdm->tc->bm, BM_FACE);
741
742                 for (i=0; i < tottri; i++) {
743                         BMLoop **l = looptris[i];
744                         int drawSmooth;
745
746                         efa = l[0]->f;
747                         drawSmooth= BM_TestHFlag(efa, BM_SMOOTH);
748
749                         draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, BM_GetIndex(efa), &drawSmooth);
750                         if (draw) {
751                                 const GLenum poly_type= GL_TRIANGLES; /* BMESH NOTE, this is odd but keep it for now to match trunk */
752                                 if (draw==2) { /* enabled with stipple */
753
754                                         if (poly_prev != GL_ZERO) glEnd();
755                                         poly_prev= GL_ZERO; /* force glBegin */
756
757                                         glEnable(GL_POLYGON_STIPPLE);
758                                         glPolygonStipple(stipple_quarttone);
759                                 }
760
761                                 if (skip_normals) {
762                                         if (poly_type != poly_prev) {
763                                                 if (poly_prev != GL_ZERO) glEnd();
764                                                 glBegin((poly_prev= poly_type)); /* BMesh: will always be GL_TRIANGLES */
765                                         }
766                                         glVertex3fv(l[0]->v->co);
767                                         glVertex3fv(l[1]->v->co);
768                                         glVertex3fv(l[2]->v->co);
769                                 }
770                                 else {
771                                         const GLenum shade_type= drawSmooth ? GL_SMOOTH : GL_FLAT;
772                                         if (shade_type != shade_prev) {
773                                                 if (poly_prev != GL_ZERO) glEnd();
774                                                 glShadeModel((shade_prev= shade_type)); /* same as below but switch shading */
775                                                 glBegin((poly_prev= poly_type)); /* BMesh: will always be GL_TRIANGLES */
776                                         }
777                                         if (poly_type != poly_prev) {
778                                                 if (poly_prev != GL_ZERO) glEnd();
779                                                 glBegin((poly_prev= poly_type)); /* BMesh: will always be GL_TRIANGLES */
780                                         }
781
782                                         if (!drawSmooth) {
783                                                 glNormal3fv(efa->no);
784                                                 glVertex3fv(l[0]->v->co);
785                                                 glVertex3fv(l[1]->v->co);
786                                                 glVertex3fv(l[2]->v->co);
787                                         }
788                                         else {
789                                                 glNormal3fv(l[0]->v->no);
790                                                 glVertex3fv(l[0]->v->co);
791                                                 glNormal3fv(l[1]->v->no);
792                                                 glVertex3fv(l[1]->v->co);
793                                                 glNormal3fv(l[2]->v->no);
794                                                 glVertex3fv(l[2]->v->co);
795                                         }
796                                 }
797
798                                 flush= (draw==2);
799                                 if (!skip_normals && !flush && (i != lasttri)) {
800                                         flush|= efa->mat_nr != looptris[i + 1][0]->f->mat_nr; /* TODO, make this neater */
801                                 }
802
803                                 if (flush) {
804                                         glEnd();
805                                         poly_prev= GL_ZERO; /* force glBegin */
806
807                                         glDisable(GL_POLYGON_STIPPLE);
808                                 }
809                         }
810                 }
811         }
812
813         /* if non zero we know a face was rendered */
814         if (poly_prev != GL_ZERO) glEnd();
815 }
816
817 static void bmdm_get_tri_tex(BMesh *bm, BMLoop **ls, MLoopUV *luv[3], MLoopCol *lcol[3],
818                                  int has_uv, int has_col)
819 {
820         if (has_uv) {
821                 luv[0] = CustomData_bmesh_get(&bm->ldata, ls[0]->head.data, CD_MLOOPUV);
822                 luv[1] = CustomData_bmesh_get(&bm->ldata, ls[1]->head.data, CD_MLOOPUV);
823                 luv[2] = CustomData_bmesh_get(&bm->ldata, ls[2]->head.data, CD_MLOOPUV);
824         }
825
826         if (has_col) {
827                 lcol[0] = CustomData_bmesh_get(&bm->ldata, ls[0]->head.data, CD_MLOOPCOL);
828                 lcol[1] = CustomData_bmesh_get(&bm->ldata, ls[1]->head.data, CD_MLOOPCOL);
829                 lcol[2] = CustomData_bmesh_get(&bm->ldata, ls[2]->head.data, CD_MLOOPCOL);
830         }
831
832
833 }
834
835 static void emDM_drawFacesTex_common(
836                 DerivedMesh *dm,
837                 int (*drawParams)(MTFace *tface, int has_vcol, int matnr),
838                 int (*drawParamsMapped)(void *userData, int index),
839                 int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
840                 void *userData)
841 {
842         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
843         BMEditMesh *em = bmdm->tc;
844         BMesh *bm= bmdm->tc->bm;
845         float (*vertexCos)[3]= bmdm->vertexCos;
846         float (*vertexNos)[3]= bmdm->vertexNos;
847         BMFace *efa;
848         MLoopUV *luv[3], dummyluv = {{0}};
849         MLoopCol *lcol[3], dummylcol = {0};
850         int i, has_vcol = CustomData_has_layer(&bm->ldata, CD_MLOOPCOL);
851         int has_uv = CustomData_has_layer(&bm->pdata, CD_MTEXPOLY);
852
853         (void) compareDrawOptions;
854
855         luv[0] = luv[1] = luv[2] = &dummyluv;
856         lcol[0] = lcol[1] = lcol[2] = &dummylcol;
857
858         dummylcol.a = dummylcol.r = dummylcol.g = dummylcol.b = 255;
859
860         /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
861         glShadeModel(GL_SMOOTH);
862
863         BM_ElemIndex_Ensure(bm, BM_FACE);
864
865         if (vertexCos) {
866                 BM_ElemIndex_Ensure(bm, BM_VERT);
867
868                 glBegin(GL_TRIANGLES);
869                 for (i=0; i<em->tottri; i++) {
870                         BMLoop **ls = em->looptris[i];
871                         MTexPoly *tp= CustomData_bmesh_get(&bm->pdata, ls[0]->f->head.data, CD_MTEXPOLY);
872                         MTFace mtf = {{{0}}};
873                         /*unsigned char *cp= NULL;*/ /*UNUSED*/
874                         int drawSmooth= BM_TestHFlag(ls[0]->f, BM_SMOOTH);
875                         int flag;
876
877                         efa = ls[0]->f;
878
879                         if (has_uv) {
880                                 ME_MTEXFACE_CPY(&mtf, tp);
881                         }
882
883                         if (drawParams)
884                                 flag= drawParams(&mtf, has_vcol, efa->mat_nr);
885                         else if (drawParamsMapped)
886                                 flag= drawParamsMapped(userData, BM_GetIndex(efa));
887                         else
888                                 flag= 1;
889
890                         if (flag != 0) { /* flag 0 == the face is hidden or invisible */
891
892                                 /* we always want smooth here since otherwise vertex colors dont interpolate */
893                                 if (!has_vcol) {
894                                         glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
895                                 }
896
897                                 if (!drawSmooth) {
898                                         glNormal3fv(bmdm->polyNos[BM_GetIndex(efa)]);
899
900                                         bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol);
901
902                                         glTexCoord2fv(luv[0]->uv);
903                                         glColor3ub(lcol[0]->b, lcol[0]->g, lcol[0]->r);
904                                         glVertex3fv(vertexCos[BM_GetIndex(ls[0]->v)]);
905
906                                         glTexCoord2fv(luv[1]->uv);
907                                         glColor3ub(lcol[1]->b, lcol[1]->g, lcol[1]->r);
908                                         glVertex3fv(vertexCos[BM_GetIndex(ls[1]->v)]);
909
910                                         glTexCoord2fv(luv[2]->uv);
911                                         glColor3ub(lcol[2]->b, lcol[2]->g, lcol[2]->r);
912                                         glVertex3fv(vertexCos[BM_GetIndex(ls[2]->v)]);
913                                 }
914                                 else {
915                                         bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol);
916
917                                         glTexCoord2fv(luv[0]->uv);
918                                         glColor3ub(lcol[0]->b, lcol[0]->g, lcol[0]->r);
919                                         glNormal3fv(vertexNos[BM_GetIndex(ls[0]->v)]);
920                                         glVertex3fv(vertexCos[BM_GetIndex(ls[0]->v)]);
921
922                                         glTexCoord2fv(luv[1]->uv);
923                                         glColor3ub(lcol[1]->b, lcol[1]->g, lcol[1]->r);
924                                         glNormal3fv(vertexNos[BM_GetIndex(ls[1]->v)]);
925                                         glVertex3fv(vertexCos[BM_GetIndex(ls[1]->v)]);
926
927                                         glTexCoord2fv(luv[2]->uv);
928                                         glColor3ub(lcol[2]->b, lcol[2]->g, lcol[2]->r);
929                                         glNormal3fv(vertexNos[BM_GetIndex(ls[2]->v)]);
930                                         glVertex3fv(vertexCos[BM_GetIndex(ls[2]->v)]);
931                                 }
932                         }
933                 }
934                 glEnd();
935         }
936         else {
937                 BM_ElemIndex_Ensure(bm, BM_VERT);
938
939                 for (i=0; i<em->tottri; i++) {
940                         BMLoop **ls = em->looptris[i];
941                         MTexPoly *tp= CustomData_bmesh_get(&bm->pdata, ls[0]->f->head.data, CD_MTEXPOLY);
942                         MTFace mtf = {{{0}}};
943                         /*unsigned char *cp= NULL;*/ /*UNUSED*/
944                         int drawSmooth= BM_TestHFlag(ls[0]->f, BM_SMOOTH);
945                         int flag;
946
947                         efa = ls[0]->f;
948
949                         if (has_uv) {
950                                 ME_MTEXFACE_CPY(&mtf, tp);
951                         }
952
953                         if (drawParams)
954                                 flag= drawParams(&mtf, has_vcol, efa->mat_nr);
955                         else if (drawParamsMapped)
956                                 flag= drawParamsMapped(userData, BM_GetIndex(efa));
957                         else
958                                 flag= 1;
959
960                         if (flag != 0) { /* flag 0 == the face is hidden or invisible */
961
962                                 /* we always want smooth here since otherwise vertex colors dont interpolate */
963                                 if (!has_vcol) {
964                                         glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
965                                 }
966
967                                 glBegin(GL_TRIANGLES);
968                                 if (!drawSmooth) {
969                                         glNormal3fv(efa->no);
970
971                                         bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol);
972
973                                         if (luv[0])
974                                                 glTexCoord2fv(luv[0]->uv);
975                                         if (lcol[0])
976                                                 glColor3ub(lcol[0]->b, lcol[0]->g, lcol[0]->r);
977                                         else glColor3ub(0, 0, 0);
978                                         glVertex3fv(ls[0]->v->co);
979
980                                         if (luv[1])
981                                                 glTexCoord2fv(luv[1]->uv);
982                                         if (lcol[1])
983                                                 glColor3ub(lcol[1]->b, lcol[1]->g, lcol[1]->r);
984                                         else glColor3ub(0, 0, 0);
985                                         glVertex3fv(ls[1]->v->co);
986
987                                         if (luv[2])
988                                                 glTexCoord2fv(luv[2]->uv);
989                                         if (lcol[2])
990                                                 glColor3ub(lcol[2]->b, lcol[2]->g, lcol[2]->r);
991                                         else glColor3ub(0, 0, 0);
992                                         glVertex3fv(ls[2]->v->co);
993                                 }
994                                 else {
995                                         bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol);
996
997                                         if (luv[0])
998                                                 glTexCoord2fv(luv[0]->uv);
999                                         if (lcol[0])
1000                                                 glColor3ub(lcol[0]->b, lcol[0]->g, lcol[0]->r);
1001                                         else glColor3ub(0, 0, 0);
1002                                         glNormal3fv(ls[0]->v->no);
1003                                         glVertex3fv(ls[0]->v->co);
1004
1005                                         if (luv[1])
1006                                                 glTexCoord2fv(luv[1]->uv);
1007                                         if (lcol[1])
1008                                                 glColor3ub(lcol[1]->b, lcol[1]->g, lcol[1]->r);
1009                                         else glColor3ub(0, 0, 0);
1010                                         glNormal3fv(ls[1]->v->no);
1011                                         glVertex3fv(ls[1]->v->co);
1012
1013                                         if (luv[2])
1014                                                 glTexCoord2fv(luv[2]->uv);
1015                                         if (lcol[2])
1016                                                 glColor3ub(lcol[2]->b, lcol[2]->g, lcol[2]->r);
1017                                         else glColor3ub(0, 0, 0);
1018                                         glNormal3fv(ls[2]->v->no);
1019                                         glVertex3fv(ls[2]->v->co);
1020                                 }
1021                                 glEnd();
1022                         }
1023                 }
1024         }
1025 }
1026
1027 static void emDM_drawFacesTex(
1028                 DerivedMesh *dm,
1029                 int (*setDrawOptions)(MTFace *tface, int has_vcol, int matnr),
1030                 int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
1031                 void *userData)
1032 {
1033         emDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData);
1034 }
1035
1036 static void emDM_drawMappedFacesTex(
1037                 DerivedMesh *dm,
1038                 int (*setDrawOptions)(void *userData, int index),
1039                 int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
1040                 void *userData)
1041 {
1042         emDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData);
1043 }
1044
1045 static void emDM_drawMappedFacesGLSL(
1046                 DerivedMesh *dm,
1047                 int (*setMaterial)(int, void *attribs),
1048                 int (*setDrawOptions)(void *userData, int index),
1049                 void *userData)
1050 {
1051         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1052         BMesh *bm= bmdm->tc->bm;
1053         BMEditMesh *em = bmdm->tc;
1054         float (*vertexCos)[3]= bmdm->vertexCos;
1055         float (*vertexNos)[3]= bmdm->vertexNos;
1056         BMFace *efa;
1057         BMLoop **ltri;
1058         DMVertexAttribs attribs;
1059         GPUVertexAttribs gattribs;
1060
1061         int i, b, matnr, new_matnr, dodraw;
1062
1063         dodraw = 0;
1064         matnr = -1;
1065
1066         memset(&attribs, 0, sizeof(attribs));
1067
1068         /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
1069         glShadeModel(GL_SMOOTH);
1070         BM_ElemIndex_Ensure(bm, BM_VERT | BM_FACE);
1071
1072 #define PASSATTRIB(loop, eve, vert) {                                                                                   \
1073         if (attribs.totorco) {                                                                                                          \
1074                 float *orco = attribs.orco.array[BM_GetIndex(eve)];                                             \
1075                 glVertexAttrib3fvARB(attribs.orco.glIndex, orco);                                               \
1076         }                                                                                                                                                       \
1077         for (b = 0; b < attribs.tottface; b++) {                                                                        \
1078                 MLoopUV *_luv = CustomData_bmesh_get_n(&bm->ldata, loop->head.data, CD_MLOOPUV, b);\
1079                 glVertexAttrib2fvARB(attribs.tface[b].glIndex, _luv->uv);                               \
1080         }                                                                                                                                                       \
1081         for (b = 0; b < attribs.totmcol; b++) {                                                                         \
1082                 MLoopCol *_cp = CustomData_bmesh_get_n(&bm->ldata, loop->head.data, CD_MLOOPCOL, b);\
1083                 GLubyte _col[4];                                                                                                                \
1084                 _col[0]= _cp->b; _col[1]= _cp->g; _col[2]= _cp->r; _col[3]= _cp->a;             \
1085                 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, _col);                                   \
1086         }                                                                                                                                                       \
1087         if (attribs.tottang) {                                                                                                          \
1088                 float *tang = attribs.tang.array[i*4 + vert];                                                   \
1089                 glVertexAttrib3fvARB(attribs.tang.glIndex, tang);                                               \
1090         }                                                                                                                                                       \
1091         }
1092
1093
1094         for (i=0, ltri=em->looptris[0]; i<em->tottri; i++, ltri += 3) {
1095                 int drawSmooth;
1096
1097                 efa = ltri[0]->f;
1098                 drawSmooth= BM_TestHFlag(efa, BM_SMOOTH);
1099
1100                 if (setDrawOptions && !setDrawOptions(userData, BM_GetIndex(efa)))
1101                         continue;
1102
1103                 new_matnr = efa->mat_nr + 1;
1104                 if (new_matnr != matnr) {
1105                         dodraw = setMaterial(matnr = new_matnr, &gattribs);
1106                         if (dodraw)
1107                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1108                 }
1109
1110                 if (dodraw) {
1111                         glBegin(GL_TRIANGLES);
1112                         if (!drawSmooth) {
1113                                 if (vertexCos) glNormal3fv(bmdm->polyNos[BM_GetIndex(efa)]);
1114                                 else glNormal3fv(efa->no);
1115
1116                                 PASSATTRIB(ltri[0], ltri[0]->v, 0);
1117                                 if (vertexCos) glVertex3fv(vertexCos[BM_GetIndex(ltri[0]->v)]);
1118                                 else glVertex3fv(ltri[0]->v->co);
1119
1120                                 PASSATTRIB(ltri[1], ltri[1]->v, 1);
1121                                 if (vertexCos) glVertex3fv(vertexCos[BM_GetIndex(ltri[1]->v)]);
1122                                 else glVertex3fv(ltri[1]->v->co);
1123
1124                                 PASSATTRIB(ltri[2], ltri[2]->v, 2);
1125                                 if (vertexCos) glVertex3fv(vertexCos[BM_GetIndex(ltri[2]->v)]);
1126                                 else glVertex3fv(ltri[2]->v->co);
1127                         }
1128                         else {
1129                                 PASSATTRIB(ltri[0], ltri[0]->v, 0);
1130                                 if (vertexCos) {
1131                                         glNormal3fv(vertexNos[BM_GetIndex(ltri[0]->v)]);
1132                                         glVertex3fv(vertexCos[BM_GetIndex(ltri[0]->v)]);
1133                                 }
1134                                 else {
1135                                         glNormal3fv(ltri[0]->v->no);
1136                                         glVertex3fv(ltri[0]->v->co);
1137                                 }
1138
1139                                 PASSATTRIB(ltri[1], ltri[1]->v, 1);
1140                                 if (vertexCos) {
1141                                         glNormal3fv(vertexNos[BM_GetIndex(ltri[1]->v)]);
1142                                         glVertex3fv(vertexCos[BM_GetIndex(ltri[1]->v)]);
1143                                 }
1144                                 else {
1145                                         glNormal3fv(ltri[1]->v->no);
1146                                         glVertex3fv(ltri[1]->v->co);
1147                                 }
1148
1149                                 PASSATTRIB(ltri[2], ltri[2]->v, 2);
1150                                 if (vertexCos) {
1151                                         glNormal3fv(vertexNos[BM_GetIndex(ltri[2]->v)]);
1152                                         glVertex3fv(vertexCos[BM_GetIndex(ltri[2]->v)]);
1153                                 }
1154                                 else {
1155                                         glNormal3fv(ltri[2]->v->no);
1156                                         glVertex3fv(ltri[2]->v->co);
1157                                 }
1158                         }
1159                         glEnd();
1160                 }
1161         }
1162 #undef PASSATTRIB
1163 }
1164
1165 static void emDM_drawFacesGLSL(
1166                 DerivedMesh *dm,
1167                 int (*setMaterial)(int, void *attribs))
1168 {
1169         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1170 }
1171
1172 static void emDM_drawMappedFacesMat(
1173                 DerivedMesh *dm,
1174                 void (*setMaterial)(void *userData, int, void *attribs),
1175                 int (*setFace)(void *userData, int index), void *userData)
1176 {
1177         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1178         BMesh *bm= bmdm->tc->bm;
1179         BMEditMesh *em = bmdm->tc;
1180         float (*vertexCos)[3]= bmdm->vertexCos;
1181         float (*vertexNos)[3]= bmdm->vertexNos;
1182         BMFace *efa;
1183         BMLoop **ltri;
1184         DMVertexAttribs attribs= {{{0}}};
1185         GPUVertexAttribs gattribs;
1186         int i, b, matnr, new_matnr;
1187
1188         matnr = -1;
1189
1190         /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
1191         glShadeModel(GL_SMOOTH);
1192
1193         BM_ElemIndex_Ensure(bm, BM_VERT);
1194
1195 #define PASSATTRIB(loop, eve, vert) {                                                                                   \
1196         if (attribs.totorco) {                                                                                                          \
1197                 float *orco = attribs.orco.array[BM_GetIndex(eve)];                                             \
1198                 glVertexAttrib3fvARB(attribs.orco.glIndex, orco);                                               \
1199         }                                                                                                                                                       \
1200         for (b = 0; b < attribs.tottface; b++) {                                                                        \
1201                 MLoopUV *_luv = CustomData_bmesh_get_n(&bm->ldata, loop->head.data, CD_MLOOPUV, b);\
1202                 glVertexAttrib2fvARB(attribs.tface[b].glIndex, _luv->uv);                               \
1203         }                                                                                                                                                       \
1204         for (b = 0; b < attribs.totmcol; b++) {                                                                         \
1205                 MLoopCol *_cp = CustomData_bmesh_get_n(&bm->ldata, loop->head.data, CD_MLOOPCOL, b);\
1206                 GLubyte _col[4];                                                                                                                \
1207                 _col[0]= _cp->b; _col[1]= _cp->g; _col[2]= _cp->r; _col[3]= _cp->a;             \
1208                 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, _col);                                   \
1209         }                                                                                                                                                       \
1210         if (attribs.tottang) {                                                                                                          \
1211                 float *tang = attribs.tang.array[i*4 + vert];                                                   \
1212                 glVertexAttrib4fvARB(attribs.tang.glIndex, tang);                                               \
1213         }                                                                                                                                                       \
1214 }
1215
1216         for (i=0, ltri=em->looptris[0]; i<em->tottri; i++, ltri += 3) {
1217                 int drawSmooth;
1218
1219                 efa = ltri[0]->f;
1220                 drawSmooth = BM_TestHFlag(efa, BM_SMOOTH);
1221
1222                 /* face hiding */
1223                 if (setFace && !setFace(userData, BM_GetIndex(efa)))
1224                         continue;
1225
1226                 /* material */
1227                 new_matnr = efa->mat_nr + 1;
1228                 if (new_matnr != matnr) {
1229                         setMaterial(userData, matnr = new_matnr, &gattribs);
1230                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1231                 }
1232
1233                 /* face */
1234                 glBegin(GL_TRIANGLES);
1235                 if (!drawSmooth) {
1236                         if (vertexCos) glNormal3fv(bmdm->polyNos[BM_GetIndex(efa)]);
1237                         else glNormal3fv(efa->no);
1238
1239                         PASSATTRIB(ltri[0], ltri[0]->v, 0);
1240                         if (vertexCos) glVertex3fv(vertexCos[BM_GetIndex(ltri[0]->v)]);
1241                         else glVertex3fv(ltri[0]->v->co);
1242
1243                         PASSATTRIB(ltri[1], ltri[1]->v, 1);
1244                         if (vertexCos) glVertex3fv(vertexCos[BM_GetIndex(ltri[1]->v)]);
1245                         else glVertex3fv(ltri[1]->v->co);
1246
1247                         PASSATTRIB(ltri[2], ltri[2]->v, 2);
1248                         if (vertexCos) glVertex3fv(vertexCos[BM_GetIndex(ltri[2]->v)]);
1249                         else glVertex3fv(ltri[2]->v->co);
1250
1251                 }
1252                 else {
1253                         PASSATTRIB(ltri[0], ltri[0]->v, 0);
1254                         if (vertexCos) {
1255                                 glNormal3fv(vertexNos[BM_GetIndex(ltri[0]->v)]);
1256                                 glVertex3fv(vertexCos[BM_GetIndex(ltri[0]->v)]);
1257                         }
1258                         else {
1259                                 glNormal3fv(ltri[0]->v->no);
1260                                 glVertex3fv(ltri[0]->v->co);
1261                         }
1262
1263                         PASSATTRIB(ltri[1], ltri[1]->v, 1);
1264                         if (vertexCos) {
1265                                 glNormal3fv(vertexNos[BM_GetIndex(ltri[1]->v)]);
1266                                 glVertex3fv(vertexCos[BM_GetIndex(ltri[1]->v)]);
1267                         }
1268                         else {
1269                                 glNormal3fv(ltri[1]->v->no);
1270                                 glVertex3fv(ltri[1]->v->co);
1271                         }
1272
1273                         PASSATTRIB(ltri[2], ltri[2]->v, 2);
1274                         if (vertexCos) {
1275                                 glNormal3fv(vertexNos[BM_GetIndex(ltri[2]->v)]);
1276                                 glVertex3fv(vertexCos[BM_GetIndex(ltri[2]->v)]);
1277                         }
1278                         else {
1279                                 glNormal3fv(ltri[2]->v->no);
1280                                 glVertex3fv(ltri[2]->v->co);
1281                         }
1282                 }
1283                 glEnd();
1284         }
1285 #undef PASSATTRIB
1286 }
1287
1288 static void emDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
1289 {
1290         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1291         BMVert *eve;
1292         BMIter iter;
1293         int i;
1294
1295         if (bmdm->tc->bm->totvert) {
1296                 eve = BMIter_New(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
1297                 for (i=0; eve; eve=BMIter_Step(&iter), i++) {
1298                         if (bmdm->vertexCos) {
1299                                 DO_MINMAX(bmdm->vertexCos[i], min_r, max_r);
1300                         }
1301                         else {
1302                                 DO_MINMAX(eve->co, min_r, max_r);
1303                         }
1304                 }
1305         }
1306         else {
1307                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
1308         }
1309 }
1310 static int emDM_getNumVerts(DerivedMesh *dm)
1311 {
1312         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1313
1314         return bmdm->tc->bm->totvert;
1315 }
1316
1317 static int emDM_getNumEdges(DerivedMesh *dm)
1318 {
1319         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1320
1321         return bmdm->tc->bm->totedge;
1322 }
1323
1324 static int emDM_getNumTessFaces(DerivedMesh *dm)
1325 {
1326         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1327
1328         return bmdm->tc->tottri;
1329 }
1330
1331 static int emDM_getNumLoops(DerivedMesh *dm)
1332 {
1333         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1334
1335         return bmdm->tc->bm->totloop;
1336 }
1337
1338 static int emDM_getNumPolys(DerivedMesh *dm)
1339 {
1340         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1341
1342         return bmdm->tc->bm->totface;
1343 }
1344
1345 static int bmvert_to_mvert(BMesh *bm, BMVert *ev, MVert *vert_r)
1346 {
1347         copy_v3_v3(vert_r->co, ev->co);
1348
1349         normal_float_to_short_v3(vert_r->no, ev->no);
1350
1351         vert_r->flag = BM_Vert_Flag_To_MEFlag(ev);
1352
1353         if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
1354                 vert_r->bweight = (unsigned char) (BM_GetCDf(&bm->vdata, ev, CD_BWEIGHT)*255.0f);
1355         }
1356
1357         return 1;
1358 }
1359
1360 static void emDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
1361 {
1362         BMVert *ev;
1363
1364         if (index < 0 || index >= ((EditDerivedBMesh *)dm)->tv) {
1365                 printf("error in emDM_getVert.\n");
1366                 return;
1367         }
1368
1369         ev = ((EditDerivedBMesh *)dm)->vtable[index];
1370         bmvert_to_mvert(((EditDerivedBMesh *)dm)->tc->bm, ev, vert_r);
1371 }
1372
1373 static void emDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
1374 {
1375         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1376         BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
1377         BMEdge *e;
1378
1379         if (index < 0 || index >= ((EditDerivedBMesh *)dm)->te) {
1380                 printf("error in emDM_getEdge.\n");
1381                 return;
1382         }
1383
1384         e = bmdm->etable[index];
1385
1386         if (CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
1387                 edge_r->bweight = (unsigned char) (BM_GetCDf(&bm->edata, e, CD_BWEIGHT)*255.0f);
1388         }
1389
1390         if (CustomData_has_layer(&bm->edata, CD_CREASE)) {
1391                 edge_r->crease = (unsigned char) (BM_GetCDf(&bm->edata, e, CD_CREASE)*255.0f);
1392         }
1393
1394         edge_r->flag = BM_Edge_Flag_To_MEFlag(e);
1395
1396         edge_r->v1 = BM_GetIndex(e->v1);
1397         edge_r->v2 = BM_GetIndex(e->v2);
1398 }
1399
1400 static void emDM_getTessFace(DerivedMesh *dm, int index, MFace *face_r)
1401 {
1402         /* EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm; */
1403         BMFace *ef;
1404         BMLoop **l;
1405
1406         if (index < 0 || index >= ((EditDerivedBMesh *)dm)->tf) {
1407                 printf("error in emDM_getTessFace.\n");
1408                 return;
1409         }
1410
1411         l = ((EditDerivedBMesh *)dm)->tc->looptris[index];
1412
1413         ef = l[0]->f;
1414
1415         face_r->mat_nr = (unsigned char) ef->mat_nr;
1416         face_r->flag = BM_Face_Flag_To_MEFlag(ef);
1417
1418         face_r->v1 = BM_GetIndex(l[0]->v);
1419         face_r->v2 = BM_GetIndex(l[1]->v);
1420         face_r->v3 = BM_GetIndex(l[2]->v);
1421         face_r->v4 = 0;
1422
1423         test_index_face(face_r, NULL, 0, 3);
1424 }
1425
1426 static void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
1427 {
1428         BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
1429         BMVert *ev;
1430         BMIter iter;
1431
1432         ev = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
1433         for ( ; ev; ev = BMIter_Step(&iter), ++vert_r) {
1434                 copy_v3_v3(vert_r->co, ev->co);
1435
1436                 normal_float_to_short_v3(vert_r->no, ev->no);
1437
1438                 vert_r->flag = BM_Vert_Flag_To_MEFlag(ev);
1439
1440                 if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
1441                         vert_r->bweight = (unsigned char) (BM_GetCDf(&bm->vdata, ev, CD_BWEIGHT)*255.0f);
1442                 }
1443         }
1444 }
1445
1446 static void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
1447 {
1448         BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
1449         BMEdge *ee;
1450         BMIter iter;
1451         int has_bweight = CustomData_has_layer(&bm->edata, CD_BWEIGHT);
1452         int has_crease = CustomData_has_layer(&bm->edata, CD_CREASE);
1453
1454         BM_ElemIndex_Ensure(bm, BM_VERT);
1455
1456         ee = BMIter_New(&iter, bm, BM_EDGES_OF_MESH, NULL);
1457         for ( ; ee; ee=BMIter_Step(&iter), edge_r++) {
1458                 if (has_bweight) {
1459                         edge_r->bweight = (unsigned char) (BM_GetCDf(&bm->edata, ee, CD_BWEIGHT)*255.0f);
1460                 }
1461
1462                 if (has_crease) {
1463                         edge_r->crease = (unsigned char) (BM_GetCDf(&bm->edata, ee, CD_CREASE)*255.0f);
1464                 }
1465
1466                 edge_r->flag = BM_Edge_Flag_To_MEFlag(ee);
1467
1468                 edge_r->v1 = BM_GetIndex(ee->v1);
1469                 edge_r->v2 = BM_GetIndex(ee->v2);
1470         }
1471 }
1472
1473 static void emDM_copyTessFaceArray(DerivedMesh *dm, MFace *face_r)
1474 {
1475         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1476         BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
1477         BMFace *ef;
1478         BMLoop **l;
1479         int i;
1480
1481         BM_ElemIndex_Ensure(bm, BM_VERT);
1482
1483         for (i=0; i<bmdm->tc->tottri; i++, face_r++) {
1484                 l = bmdm->tc->looptris[i];
1485                 ef = l[0]->f;
1486
1487                 face_r->mat_nr = (unsigned char) ef->mat_nr;
1488
1489                 face_r->flag = BM_Face_Flag_To_MEFlag(ef);
1490
1491                 face_r->v1 = BM_GetIndex(l[0]->v);
1492                 face_r->v2 = BM_GetIndex(l[1]->v);
1493                 face_r->v3 = BM_GetIndex(l[2]->v);
1494                 face_r->v4 = 0;
1495
1496                 test_index_face(face_r, NULL, 0, 3);
1497         }
1498 }
1499
1500
1501 static void emDM_copyLoopArray(DerivedMesh *dm, MLoop *loop_r)
1502 {
1503         /* EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm; */ /* UNUSED */
1504         BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
1505         BMIter iter, liter;
1506         BMFace *f;
1507         BMLoop *l;
1508
1509         BM_ElemIndex_Ensure(bm, BM_VERT | BM_EDGE);
1510
1511         BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
1512                 BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) {
1513                         loop_r->v = BM_GetIndex(l->v);
1514                         loop_r->e = BM_GetIndex(l->e);
1515                         loop_r++;
1516                 }
1517         }
1518 }
1519
1520 static void emDM_copyPolyArray(DerivedMesh *dm, MPoly *poly_r)
1521 {
1522         /* EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm; */ /* UNUSED */
1523         BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
1524         BMIter iter;
1525         BMFace *f;
1526         int i;
1527
1528         i = 0;
1529         BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
1530                 poly_r->flag = BM_Face_Flag_To_MEFlag(f);
1531                 poly_r->loopstart = i;
1532                 poly_r->totloop = f->len;
1533                 poly_r->mat_nr = f->mat_nr;
1534
1535                 poly_r++;
1536                 i += f->len;
1537         }
1538 }
1539
1540 static void *emDM_getTessFaceDataArray(DerivedMesh *dm, int type)
1541 {
1542         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1543         BMesh *bm= bmdm->tc->bm;
1544         BMFace *efa;
1545         char *data, *bmdata;
1546         void *datalayer;
1547         int index /*, offset*/ /*UNUSED */, size, i;
1548
1549         datalayer = DM_get_tessface_data_layer(dm, type);
1550         if (datalayer)
1551                 return datalayer;
1552
1553         /* layers are store per face for editmesh, we convert to a tbmporary
1554          * data layer array in the derivedmesh when these are requested */
1555         if (type == CD_MTFACE || type == CD_MCOL) {
1556                 index = CustomData_get_layer_index(&bm->pdata, type);
1557
1558                 if (index != -1) {
1559                         /* offset = bm->pdata.layers[index].offset; */ /* UNUSED */
1560                         size = CustomData_sizeof(type);
1561
1562                         DM_add_tessface_layer(dm, type, CD_CALLOC, NULL);
1563                         index = CustomData_get_layer_index(&dm->faceData, type);
1564                         dm->faceData.layers[index].flag |= CD_FLAG_TEMPORARY;
1565
1566                         data = datalayer = DM_get_tessface_data_layer(dm, type);
1567                         for (i=0; i<bmdm->tc->tottri; i++, data+=size) {
1568                                 efa = bmdm->tc->looptris[i][0]->f;
1569                                 /*BMESH_TODO: need to still add tface data,
1570                                   derived from the loops.*/
1571                                 bmdata = CustomData_bmesh_get(&bm->pdata, efa->head.data, type);
1572                                 memcpy(data, bmdata, size);
1573                         }
1574                 }
1575         }
1576
1577         return datalayer;
1578 }
1579
1580 static void emDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
1581 {
1582         EditDerivedBMesh *emdm= (EditDerivedBMesh*) dm;
1583         BMVert *eve;
1584         BMIter iter;
1585         int i;
1586
1587         i= 0;
1588         BM_ITER(eve, &iter, emdm->tc->bm, BM_VERTS_OF_MESH, NULL) {
1589                 if (emdm->vertexCos) {
1590                         copy_v3_v3(cos_r[i], emdm->vertexCos[i]);
1591                 }
1592                 else {
1593                         copy_v3_v3(cos_r[i], eve->co);
1594                 }
1595
1596                 i++;
1597         }
1598 }
1599
1600 static void emDM_release(DerivedMesh *dm)
1601 {
1602         EditDerivedBMesh *bmdm= (EditDerivedBMesh *)dm;
1603
1604         if (DM_release(dm)) {
1605                 if (bmdm->vertexCos) {
1606                         MEM_freeN(bmdm->vertexCos);
1607                         MEM_freeN(bmdm->vertexNos);
1608                         MEM_freeN(bmdm->polyNos);
1609                 }
1610
1611                 if (bmdm->vtable) MEM_freeN(bmdm->vtable);
1612                 if (bmdm->etable) MEM_freeN(bmdm->etable);
1613                 if (bmdm->ftable) MEM_freeN(bmdm->ftable);
1614
1615                 MEM_freeN(bmdm);
1616         }
1617 }
1618
1619 static CustomData *bmDm_getVertDataLayout(DerivedMesh *dm)
1620 {
1621         EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm;
1622
1623         return &bmdm->tc->bm->vdata;
1624 }
1625
1626 static CustomData *bmDm_getEdgeDataLayout(DerivedMesh *dm)
1627 {
1628         EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm;
1629
1630         return &bmdm->tc->bm->edata;
1631 }
1632
1633 static CustomData *bmDm_getTessFaceDataLayout(DerivedMesh *dm)
1634 {
1635         EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm;
1636
1637         return &bmdm->dm.faceData;
1638 }
1639
1640 static CustomData *bmDm_getLoopDataLayout(DerivedMesh *dm)
1641 {
1642         EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm;
1643
1644         return &bmdm->tc->bm->ldata;
1645 }
1646
1647 static CustomData *bmDm_getPolyDataLayout(DerivedMesh *dm)
1648 {
1649         EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm;
1650
1651         return &bmdm->tc->bm->pdata;
1652 }
1653
1654
1655 DerivedMesh *getEditDerivedBMesh(
1656                 BMEditMesh *em,
1657                 Object *UNUSED(ob),
1658                 float (*vertexCos)[3])
1659 {
1660         EditDerivedBMesh *bmdm = MEM_callocN(sizeof(*bmdm), __func__);
1661         BMesh *bm = em->bm;
1662
1663         bmdm->tc = em;
1664
1665         DM_init((DerivedMesh*)bmdm, DM_TYPE_EDITBMESH, em->bm->totvert,
1666                  em->bm->totedge, em->tottri, em->bm->totloop, em->bm->totface);
1667
1668         CustomData_from_bmeshpoly(&bmdm->dm.faceData, &em->bm->pdata, &em->bm->ldata, 0);
1669
1670         bmdm->dm.getVertCos = emDM_getVertCos;
1671         bmdm->dm.getMinMax = emDM_getMinMax;
1672
1673         bmdm->dm.getVertDataLayout = bmDm_getVertDataLayout;
1674         bmdm->dm.getEdgeDataLayout = bmDm_getEdgeDataLayout;
1675         bmdm->dm.getTessFaceDataLayout = bmDm_getTessFaceDataLayout;
1676         bmdm->dm.getLoopDataLayout = bmDm_getLoopDataLayout;
1677         bmdm->dm.getPolyDataLayout = bmDm_getPolyDataLayout;
1678
1679         bmdm->dm.getNumVerts = emDM_getNumVerts;
1680         bmdm->dm.getNumEdges = emDM_getNumEdges;
1681         bmdm->dm.getNumTessFaces = emDM_getNumTessFaces;
1682         bmdm->dm.getNumLoops = emDM_getNumLoops;
1683         bmdm->dm.getNumPolys = emDM_getNumPolys;
1684
1685         bmdm->dm.getVert = emDM_getVert;
1686         bmdm->dm.getEdge = emDM_getEdge;
1687         bmdm->dm.getTessFace = emDM_getTessFace;
1688         bmdm->dm.copyVertArray = emDM_copyVertArray;
1689         bmdm->dm.copyEdgeArray = emDM_copyEdgeArray;
1690         bmdm->dm.copyTessFaceArray = emDM_copyTessFaceArray;
1691         bmdm->dm.copyLoopArray = emDM_copyLoopArray;
1692         bmdm->dm.copyPolyArray = emDM_copyPolyArray;
1693
1694         bmdm->dm.getTessFaceDataArray = emDM_getTessFaceDataArray;
1695
1696         bmdm->dm.calcNormals = emDM_calcNormals;
1697         bmdm->dm.recalcTesselation = emDM_recalcTesselation;
1698
1699         bmdm->dm.foreachMappedVert = emDM_foreachMappedVert;
1700         bmdm->dm.foreachMappedEdge = emDM_foreachMappedEdge;
1701         bmdm->dm.foreachMappedFaceCenter = emDM_foreachMappedFaceCenter;
1702
1703         bmdm->dm.drawEdges = emDM_drawEdges;
1704         bmdm->dm.drawMappedEdges = emDM_drawMappedEdges;
1705         bmdm->dm.drawMappedEdgesInterp = emDM_drawMappedEdgesInterp;
1706         bmdm->dm.drawMappedFaces = emDM_drawMappedFaces;
1707         bmdm->dm.drawMappedFacesTex = emDM_drawMappedFacesTex;
1708         bmdm->dm.drawMappedFacesGLSL = emDM_drawMappedFacesGLSL;
1709         bmdm->dm.drawMappedFacesMat = emDM_drawMappedFacesMat;
1710         bmdm->dm.drawFacesTex = emDM_drawFacesTex;
1711         bmdm->dm.drawFacesGLSL = emDM_drawFacesGLSL;
1712         bmdm->dm.drawUVEdges = emDM_drawUVEdges;
1713
1714         bmdm->dm.release = emDM_release;
1715
1716         bmdm->vertexCos = vertexCos;
1717
1718         if (CustomData_has_layer(&bm->vdata, CD_MDEFORMVERT)) {
1719                 BMIter iter;
1720                 BMVert *eve;
1721                 int i;
1722
1723                 DM_add_vert_layer(&bmdm->dm, CD_MDEFORMVERT, CD_CALLOC, NULL);
1724
1725                 eve = BMIter_New(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
1726                 for (i=0; eve; eve=BMIter_Step(&iter), i++)
1727                         DM_set_vert_data(&bmdm->dm, i, CD_MDEFORMVERT,
1728                                                          CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MDEFORMVERT));
1729         }
1730
1731         if (vertexCos) {
1732                 BMFace *efa;
1733                 BMVert *eve;
1734                 BMIter fiter;
1735                 BMIter viter;
1736                 int i;
1737
1738                 BM_ElemIndex_Ensure(bm, BM_VERT);
1739
1740                 bmdm->vertexNos = MEM_callocN(sizeof(*bmdm->vertexNos) * bm->totvert, "bmdm_vno");
1741                 bmdm->polyNos = MEM_mallocN(sizeof(*bmdm->polyNos)*bm->totface, "bmdm_pno");
1742
1743                 i = 0;
1744                 BM_ITER(efa, &fiter, bm, BM_FACES_OF_MESH, NULL) {
1745                         BM_SetIndex(efa, i); /* set_inline */
1746                         BM_Face_UpdateNormal_VertexCos(bm, efa, bmdm->polyNos[i], vertexCos);
1747                         i++;
1748                 }
1749                 bm->elem_index_dirty &= ~BM_FACE;
1750
1751                 eve=BMIter_New(&viter, bm, BM_VERTS_OF_MESH, NULL);
1752                 for (i=0; eve; eve=BMIter_Step(&viter), i++) {
1753                         float *no = bmdm->vertexNos[i];
1754                         BM_ITER(efa, &fiter, bm, BM_FACES_OF_VERT, eve) {
1755                                 add_v3_v3(no, bmdm->polyNos[BM_GetIndex(efa)]);
1756                         }
1757
1758                         /* following Mesh convention; we use vertex coordinate itself
1759                          * for normal in this case */
1760                         if (normalize_v3(no)==0.0) {
1761                                 copy_v3_v3(no, vertexCos[i]);
1762                                 normalize_v3(no);
1763                         }
1764                 }
1765         }
1766
1767         //bmdm_recalc_lookups(bmdm);
1768
1769         return (DerivedMesh*) bmdm;
1770 }