skip per face texface poly lookup while drawing when the layer isnt found.
[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_mesh_copy(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 = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, NULL);
153         for ( ; f; f=BM_iter_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 = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, f);
166                         for (j=0; l; l=BM_iter_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 = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, f);
176                         for (j=0; l; l=BM_iter_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 = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, f);
202                         for (j=0; l; l=BM_iter_step(&liter), j++) {
203                                 /*mark order*/
204                                 BM_elem_index_set(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_elem_index_get(l1) > BM_elem_index_get(l2)) { SWAP(BMLoop*, l1, l2); }
229                                 if (BM_elem_index_get(l2) > BM_elem_index_get(l3)) { SWAP(BMLoop*, l2, l3); }
230                                 if (BM_elem_index_get(l1) > BM_elem_index_get(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_mesh_free(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         /* private variables, for number of verts/edges/faces
339          * within the above hash/table members*/
340         int tv, te, tf;
341 } EditDerivedBMesh;
342
343 static void emDM_calcNormals(DerivedMesh *UNUSED(dm))
344 {
345         /* Nothing to do: normals are already calculated and stored on the
346            BMVerts and BMFaces */
347 }
348
349 static void emDM_recalcTesselation(DerivedMesh *UNUSED(dm))
350 {
351         /* do nothing */
352 }
353
354 static void emDM_foreachMappedVert(
355                 DerivedMesh *dm,
356                 void (*func)(void *userData, int index, float *co, float *no_f, short *no_s),
357                 void *userData)
358 {
359         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
360         BMVert *eve;
361         BMIter iter;
362         int i;
363
364         eve = BM_iter_new(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
365         for (i=0; eve; i++, eve=BM_iter_step(&iter)) {
366                 if (bmdm->vertexCos) {
367                         func(userData, i, bmdm->vertexCos[i], bmdm->vertexNos[i], NULL);
368                 }
369                 else {
370                         func(userData, i, eve->co, eve->no, NULL);
371                 }
372         }
373 }
374 static void emDM_foreachMappedEdge(
375                 DerivedMesh *dm,
376                 void (*func)(void *userData, int index, float *v0co, float *v1co),
377                 void *userData)
378 {
379         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
380         BMEdge *eed;
381         BMIter iter;
382         int i;
383
384         if (bmdm->vertexCos) {
385
386                 BM_mesh_elem_index_ensure(bmdm->tc->bm, BM_VERT);
387
388                 eed = BM_iter_new(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
389                 for (i=0; eed; i++,eed=BM_iter_step(&iter))
390                         func(userData, i,
391                                  bmdm->vertexCos[BM_elem_index_get(eed->v1)],
392                                  bmdm->vertexCos[BM_elem_index_get(eed->v2)]);
393         }
394         else {
395                 eed = BM_iter_new(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
396                 for (i=0; eed; i++,eed=BM_iter_step(&iter))
397                         func(userData, i, eed->v1->co, eed->v2->co);
398         }
399 }
400
401 static void emDM_drawMappedEdges(
402                 DerivedMesh *dm,
403                 int (*setDrawOptions)(void *userData, int index),
404                 void *userData)
405 {
406         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
407         BMEdge *eed;
408         BMIter iter;
409         int i;
410
411         if (bmdm->vertexCos) {
412
413                 BM_mesh_elem_index_ensure(bmdm->tc->bm, BM_VERT);
414
415                 glBegin(GL_LINES);
416                 eed = BM_iter_new(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
417                 for (i=0; eed; i++,eed=BM_iter_step(&iter)) {
418                         if (!setDrawOptions || setDrawOptions(userData, i)) {
419                                 glVertex3fv(bmdm->vertexCos[BM_elem_index_get(eed->v1)]);
420                                 glVertex3fv(bmdm->vertexCos[BM_elem_index_get(eed->v2)]);
421                         }
422                 }
423                 glEnd();
424         }
425         else {
426                 glBegin(GL_LINES);
427                 eed = BM_iter_new(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
428                 for (i=0; eed; i++,eed=BM_iter_step(&iter)) {
429                         if (!setDrawOptions || setDrawOptions(userData, i)) {
430                                 glVertex3fv(eed->v1->co);
431                                 glVertex3fv(eed->v2->co);
432                         }
433                 }
434                 glEnd();
435         }
436 }
437 static void emDM_drawEdges(
438                 DerivedMesh *dm,
439                 int UNUSED(drawLooseEdges),
440                 int UNUSED(drawAllEdges))
441 {
442         emDM_drawMappedEdges(dm, NULL, NULL);
443 }
444
445 static void emDM_drawMappedEdgesInterp(
446                 DerivedMesh *dm,
447                 int (*setDrawOptions)(void *userData, int index),
448                 void (*setDrawInterpOptions)(void *userData, int index, float t),
449                 void *userData)
450 {
451         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
452         BMEdge *eed;
453         BMIter iter;
454         int i;
455
456         if (bmdm->vertexCos) {
457
458                 BM_mesh_elem_index_ensure(bmdm->tc->bm, BM_VERT);
459
460                 glBegin(GL_LINES);
461                 eed = BM_iter_new(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
462                 for (i=0; eed; i++,eed=BM_iter_step(&iter)) {
463                         if (!setDrawOptions || setDrawOptions(userData, i)) {
464                                 setDrawInterpOptions(userData, i, 0.0);
465                                 glVertex3fv(bmdm->vertexCos[BM_elem_index_get(eed->v1)]);
466                                 setDrawInterpOptions(userData, i, 1.0);
467                                 glVertex3fv(bmdm->vertexCos[BM_elem_index_get(eed->v2)]);
468                         }
469                 }
470                 glEnd();
471         }
472         else {
473                 glBegin(GL_LINES);
474                 eed = BM_iter_new(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
475                 for (i=0; eed; i++,eed=BM_iter_step(&iter)) {
476                         if (!setDrawOptions || setDrawOptions(userData, i)) {
477                                 setDrawInterpOptions(userData, i, 0.0);
478                                 glVertex3fv(eed->v1->co);
479                                 setDrawInterpOptions(userData, i, 1.0);
480                                 glVertex3fv(eed->v2->co);
481                         }
482                 }
483                 glEnd();
484         }
485 }
486
487 static void emDM_drawUVEdges(DerivedMesh *dm)
488 {
489         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
490         BMEditMesh *em = bmdm->tc;
491         BMFace *efa;
492         BMIter iter;
493
494         glBegin(GL_LINES);
495         BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
496                 BMIter liter;
497                 BMLoop *l;
498                 MLoopUV *lastluv = NULL, *firstluv = NULL;
499
500                 if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN))
501                         continue;
502
503                 BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
504                         MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
505
506                         if (luv) {
507                                 if (lastluv)
508                                         glVertex2fv(luv->uv);
509                                 glVertex2fv(luv->uv);
510
511                                 lastluv = luv;
512                                 if (!firstluv)
513                                         firstluv = luv;
514                         }
515                 }
516
517                 if (lastluv) {
518                         glVertex2fv(lastluv->uv);
519                         glVertex2fv(firstluv->uv);
520                 }
521         }
522         glEnd();
523 }
524
525 static void emDM__calcFaceCent(BMesh *bm, BMFace *efa, float cent[3], float (*vertexCos)[3])
526 {
527         BMIter iter;
528         BMLoop *l;
529         int tot = 0;
530
531         zero_v3(cent);
532
533         /*simple (and stupid) median (average) based method :/ */
534
535         if (vertexCos) {
536                 l = BM_iter_new(&iter, bm, BM_LOOPS_OF_FACE, efa);
537                 for (; l; l=BM_iter_step(&iter)) {
538                         add_v3_v3(cent, vertexCos[BM_elem_index_get(l->v)]);
539                         tot++;
540                 }
541         }
542         else {
543                 l = BM_iter_new(&iter, bm, BM_LOOPS_OF_FACE, efa);
544                 for (; l; l=BM_iter_step(&iter)) {
545                         add_v3_v3(cent, l->v->co);
546                         tot++;
547                 }
548         }
549
550         if (tot==0) return;
551         mul_v3_fl(cent, 1.0f/(float)tot);
552 }
553
554 static void emDM_foreachMappedFaceCenter(
555                 DerivedMesh *dm,
556                 void (*func)(void *userData, int index, float *co, float *no),
557                 void *userData)
558 {
559         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
560         float (*polyNos)[3] = NULL;
561         BMFace *efa;
562         BMIter iter;
563         float cent[3];
564         int i;
565
566         /* ensure for face center calculation */
567         if (bmdm->vertexCos) {
568                 BM_mesh_elem_index_ensure(bmdm->tc->bm, BM_VERT);
569                 polyNos = bmdm->polyNos;
570
571                 BLI_assert(polyNos != NULL);
572         }
573
574         efa = BM_iter_new(&iter, bmdm->tc->bm, BM_FACES_OF_MESH, NULL);
575         for (i=0; efa; efa=BM_iter_step(&iter), i++) {
576                 emDM__calcFaceCent(bmdm->tc->bm, efa, cent, bmdm->vertexCos);
577                 func(userData, i, cent, polyNos ? polyNos[i] : efa->no);
578         }
579 }
580
581 static void emDM_drawMappedFaces(
582                 DerivedMesh *dm,
583                 int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r),
584                 int (*setMaterial)(int, void *attribs),
585                 int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
586                 void *userData, int UNUSED(useColors))
587 {
588         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
589         BMFace *efa;
590         struct BMLoop *(*looptris)[3]= bmdm->tc->looptris;
591         const int tottri= bmdm->tc->tottri;
592         const int lasttri= tottri - 1; /* compare agasint this a lot */
593         int i, draw, flush;
594         const int skip_normals= !glIsEnabled(GL_LIGHTING); /* could be passed as an arg */
595
596         /* GL_ZERO is used to detect if drawing has started or not */
597         GLenum poly_prev= GL_ZERO;
598         GLenum shade_prev= GL_ZERO;
599
600         (void)setMaterial; /* UNUSED */
601
602         /* currently unused -- each original face is handled separately */
603         (void)compareDrawOptions;
604
605         if (bmdm->vertexCos) {
606                 /* add direct access */
607                 float (*vertexCos)[3]= bmdm->vertexCos;
608                 float (*vertexNos)[3]= bmdm->vertexNos;
609                 float (*polyNos)[3]=   bmdm->polyNos;
610                 // int *triPolyMap= bmdm->triPolyMap;
611
612                 BM_mesh_elem_index_ensure(bmdm->tc->bm, BM_VERT | BM_FACE);
613
614                 for (i=0; i < tottri; i++) {
615                         BMLoop **l = looptris[i];
616                         int drawSmooth;
617
618                         efa = l[0]->f;
619                         drawSmooth= BM_elem_flag_test(efa, BM_ELEM_SMOOTH);
620
621                         draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, BM_elem_index_get(efa), &drawSmooth);
622                         if (draw) {
623                                 const GLenum poly_type= GL_TRIANGLES; /* BMESH NOTE, this is odd but keep it for now to match trunk */
624                                 if (draw==2) { /* enabled with stipple */
625
626                                         if (poly_prev != GL_ZERO) glEnd();
627                                         poly_prev= GL_ZERO; /* force glBegin */
628
629                                         glEnable(GL_POLYGON_STIPPLE);
630                                         glPolygonStipple(stipple_quarttone);
631                                 }
632
633                                 if (skip_normals) {
634                                         if (poly_type != poly_prev) {
635                                                 if (poly_prev != GL_ZERO) glEnd();
636                                                 glBegin((poly_prev= poly_type)); /* BMesh: will always be GL_TRIANGLES */
637                                         }
638                                         glVertex3fv(vertexCos[BM_elem_index_get(l[0]->v)]);
639                                         glVertex3fv(vertexCos[BM_elem_index_get(l[1]->v)]);
640                                         glVertex3fv(vertexCos[BM_elem_index_get(l[2]->v)]);
641                                 }
642                                 else {
643                                         const GLenum shade_type= drawSmooth ? GL_SMOOTH : GL_FLAT;
644                                         if (shade_type != shade_prev) {
645                                                 if (poly_prev != GL_ZERO) glEnd();
646                                                 glShadeModel((shade_prev= shade_type)); /* same as below but switch shading */
647                                                 glBegin((poly_prev= poly_type)); /* BMesh: will always be GL_TRIANGLES */
648                                         }
649                                         if (poly_type != poly_prev) {
650                                                 if (poly_prev != GL_ZERO) glEnd();
651                                                 glBegin((poly_prev= poly_type)); /* BMesh: will always be GL_TRIANGLES */
652                                         }
653
654                                         if (!drawSmooth) {
655                                                 glNormal3fv(polyNos[BM_elem_index_get(efa)]);
656                                                 glVertex3fv(vertexCos[BM_elem_index_get(l[0]->v)]);
657                                                 glVertex3fv(vertexCos[BM_elem_index_get(l[1]->v)]);
658                                                 glVertex3fv(vertexCos[BM_elem_index_get(l[2]->v)]);
659                                         }
660                                         else {
661                                                 glNormal3fv(vertexNos[BM_elem_index_get(l[0]->v)]);
662                                                 glVertex3fv(vertexCos[BM_elem_index_get(l[0]->v)]);
663                                                 glNormal3fv(vertexNos[BM_elem_index_get(l[1]->v)]);
664                                                 glVertex3fv(vertexCos[BM_elem_index_get(l[1]->v)]);
665                                                 glNormal3fv(vertexNos[BM_elem_index_get(l[2]->v)]);
666                                                 glVertex3fv(vertexCos[BM_elem_index_get(l[2]->v)]);
667                                         }
668                                 }
669
670                                 flush= (draw==2);
671                                 if (!skip_normals && !flush && (i != lasttri))
672                                         flush|= efa->mat_nr != looptris[i + 1][0]->f->mat_nr; /* TODO, make this neater */
673
674                                 if (flush) {
675                                         glEnd();
676                                         poly_prev= GL_ZERO; /* force glBegin */
677
678                                         glDisable(GL_POLYGON_STIPPLE);
679                                 }
680                         }
681                 }
682         }
683         else {
684                 BM_mesh_elem_index_ensure(bmdm->tc->bm, BM_FACE);
685
686                 for (i=0; i < tottri; i++) {
687                         BMLoop **l = looptris[i];
688                         int drawSmooth;
689
690                         efa = l[0]->f;
691                         drawSmooth= BM_elem_flag_test(efa, BM_ELEM_SMOOTH);
692
693                         draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, BM_elem_index_get(efa), &drawSmooth);
694                         if (draw) {
695                                 const GLenum poly_type= GL_TRIANGLES; /* BMESH NOTE, this is odd but keep it for now to match trunk */
696                                 if (draw==2) { /* enabled with stipple */
697
698                                         if (poly_prev != GL_ZERO) glEnd();
699                                         poly_prev= GL_ZERO; /* force glBegin */
700
701                                         glEnable(GL_POLYGON_STIPPLE);
702                                         glPolygonStipple(stipple_quarttone);
703                                 }
704
705                                 if (skip_normals) {
706                                         if (poly_type != poly_prev) {
707                                                 if (poly_prev != GL_ZERO) glEnd();
708                                                 glBegin((poly_prev= poly_type)); /* BMesh: will always be GL_TRIANGLES */
709                                         }
710                                         glVertex3fv(l[0]->v->co);
711                                         glVertex3fv(l[1]->v->co);
712                                         glVertex3fv(l[2]->v->co);
713                                 }
714                                 else {
715                                         const GLenum shade_type= drawSmooth ? GL_SMOOTH : GL_FLAT;
716                                         if (shade_type != shade_prev) {
717                                                 if (poly_prev != GL_ZERO) glEnd();
718                                                 glShadeModel((shade_prev= shade_type)); /* same as below but switch shading */
719                                                 glBegin((poly_prev= poly_type)); /* BMesh: will always be GL_TRIANGLES */
720                                         }
721                                         if (poly_type != poly_prev) {
722                                                 if (poly_prev != GL_ZERO) glEnd();
723                                                 glBegin((poly_prev= poly_type)); /* BMesh: will always be GL_TRIANGLES */
724                                         }
725
726                                         if (!drawSmooth) {
727                                                 glNormal3fv(efa->no);
728                                                 glVertex3fv(l[0]->v->co);
729                                                 glVertex3fv(l[1]->v->co);
730                                                 glVertex3fv(l[2]->v->co);
731                                         }
732                                         else {
733                                                 glNormal3fv(l[0]->v->no);
734                                                 glVertex3fv(l[0]->v->co);
735                                                 glNormal3fv(l[1]->v->no);
736                                                 glVertex3fv(l[1]->v->co);
737                                                 glNormal3fv(l[2]->v->no);
738                                                 glVertex3fv(l[2]->v->co);
739                                         }
740                                 }
741
742                                 flush= (draw==2);
743                                 if (!skip_normals && !flush && (i != lasttri)) {
744                                         flush|= efa->mat_nr != looptris[i + 1][0]->f->mat_nr; /* TODO, make this neater */
745                                 }
746
747                                 if (flush) {
748                                         glEnd();
749                                         poly_prev= GL_ZERO; /* force glBegin */
750
751                                         glDisable(GL_POLYGON_STIPPLE);
752                                 }
753                         }
754                 }
755         }
756
757         /* if non zero we know a face was rendered */
758         if (poly_prev != GL_ZERO) glEnd();
759 }
760
761 static void bmdm_get_tri_tex(BMesh *bm, BMLoop **ls, MLoopUV *luv[3], MLoopCol *lcol[3],
762                                  int has_uv, int has_col)
763 {
764         if (has_uv) {
765                 luv[0] = CustomData_bmesh_get(&bm->ldata, ls[0]->head.data, CD_MLOOPUV);
766                 luv[1] = CustomData_bmesh_get(&bm->ldata, ls[1]->head.data, CD_MLOOPUV);
767                 luv[2] = CustomData_bmesh_get(&bm->ldata, ls[2]->head.data, CD_MLOOPUV);
768         }
769
770         if (has_col) {
771                 lcol[0] = CustomData_bmesh_get(&bm->ldata, ls[0]->head.data, CD_MLOOPCOL);
772                 lcol[1] = CustomData_bmesh_get(&bm->ldata, ls[1]->head.data, CD_MLOOPCOL);
773                 lcol[2] = CustomData_bmesh_get(&bm->ldata, ls[2]->head.data, CD_MLOOPCOL);
774         }
775
776
777 }
778
779 static void emDM_drawFacesTex_common(
780                 DerivedMesh *dm,
781                 int (*drawParams)(MTFace *tface, int has_vcol, int matnr),
782                 int (*drawParamsMapped)(void *userData, int index),
783                 int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
784                 void *userData)
785 {
786         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
787         BMEditMesh *em = bmdm->tc;
788         BMesh *bm= bmdm->tc->bm;
789         float (*vertexCos)[3]= bmdm->vertexCos;
790         float (*vertexNos)[3]= bmdm->vertexNos;
791         BMFace *efa;
792         MLoopUV *luv[3], dummyluv = {{0}};
793         MLoopCol *lcol[3], dummylcol = {0};
794         int i, has_vcol = CustomData_has_layer(&bm->ldata, CD_MLOOPCOL);
795         int has_uv = CustomData_has_layer(&bm->pdata, CD_MTEXPOLY);
796
797         (void) compareDrawOptions;
798
799         luv[0] = luv[1] = luv[2] = &dummyluv;
800         lcol[0] = lcol[1] = lcol[2] = &dummylcol;
801
802         dummylcol.a = dummylcol.r = dummylcol.g = dummylcol.b = 255;
803
804         /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
805         glShadeModel(GL_SMOOTH);
806
807         BM_mesh_elem_index_ensure(bm, BM_FACE);
808
809         if (vertexCos) {
810                 BM_mesh_elem_index_ensure(bm, BM_VERT);
811
812                 glBegin(GL_TRIANGLES);
813                 for (i=0; i<em->tottri; i++) {
814                         BMLoop **ls = em->looptris[i];
815                         MTexPoly *tp= has_uv ? CustomData_bmesh_get(&bm->pdata, ls[0]->f->head.data, CD_MTEXPOLY) : NULL;
816                         MTFace mtf = {{{0}}};
817                         /*unsigned char *cp= NULL;*/ /*UNUSED*/
818                         int drawSmooth= BM_elem_flag_test(ls[0]->f, BM_ELEM_SMOOTH);
819                         int flag;
820
821                         efa = ls[0]->f;
822
823                         if (has_uv) {
824                                 ME_MTEXFACE_CPY(&mtf, tp);
825                         }
826
827                         if (drawParams)
828                                 flag= drawParams(&mtf, has_vcol, efa->mat_nr);
829                         else if (drawParamsMapped)
830                                 flag= drawParamsMapped(userData, BM_elem_index_get(efa));
831                         else
832                                 flag= 1;
833
834                         if (flag != 0) { /* flag 0 == the face is hidden or invisible */
835
836                                 /* we always want smooth here since otherwise vertex colors dont interpolate */
837                                 if (!has_vcol) {
838                                         glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
839                                 }
840
841                                 if (!drawSmooth) {
842                                         glNormal3fv(bmdm->polyNos[BM_elem_index_get(efa)]);
843
844                                         bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol);
845
846                                         glTexCoord2fv(luv[0]->uv);
847                                         glColor3ub(lcol[0]->b, lcol[0]->g, lcol[0]->r);
848                                         glVertex3fv(vertexCos[BM_elem_index_get(ls[0]->v)]);
849
850                                         glTexCoord2fv(luv[1]->uv);
851                                         glColor3ub(lcol[1]->b, lcol[1]->g, lcol[1]->r);
852                                         glVertex3fv(vertexCos[BM_elem_index_get(ls[1]->v)]);
853
854                                         glTexCoord2fv(luv[2]->uv);
855                                         glColor3ub(lcol[2]->b, lcol[2]->g, lcol[2]->r);
856                                         glVertex3fv(vertexCos[BM_elem_index_get(ls[2]->v)]);
857                                 }
858                                 else {
859                                         bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol);
860
861                                         glTexCoord2fv(luv[0]->uv);
862                                         glColor3ub(lcol[0]->b, lcol[0]->g, lcol[0]->r);
863                                         glNormal3fv(vertexNos[BM_elem_index_get(ls[0]->v)]);
864                                         glVertex3fv(vertexCos[BM_elem_index_get(ls[0]->v)]);
865
866                                         glTexCoord2fv(luv[1]->uv);
867                                         glColor3ub(lcol[1]->b, lcol[1]->g, lcol[1]->r);
868                                         glNormal3fv(vertexNos[BM_elem_index_get(ls[1]->v)]);
869                                         glVertex3fv(vertexCos[BM_elem_index_get(ls[1]->v)]);
870
871                                         glTexCoord2fv(luv[2]->uv);
872                                         glColor3ub(lcol[2]->b, lcol[2]->g, lcol[2]->r);
873                                         glNormal3fv(vertexNos[BM_elem_index_get(ls[2]->v)]);
874                                         glVertex3fv(vertexCos[BM_elem_index_get(ls[2]->v)]);
875                                 }
876                         }
877                 }
878                 glEnd();
879         }
880         else {
881                 BM_mesh_elem_index_ensure(bm, BM_VERT);
882
883                 for (i=0; i<em->tottri; i++) {
884                         BMLoop **ls = em->looptris[i];
885                         MTexPoly *tp= has_uv ? CustomData_bmesh_get(&bm->pdata, ls[0]->f->head.data, CD_MTEXPOLY) : NULL;
886                         MTFace mtf = {{{0}}};
887                         /*unsigned char *cp= NULL;*/ /*UNUSED*/
888                         int drawSmooth= BM_elem_flag_test(ls[0]->f, BM_ELEM_SMOOTH);
889                         int flag;
890
891                         efa = ls[0]->f;
892
893                         if (has_uv) {
894                                 ME_MTEXFACE_CPY(&mtf, tp);
895                         }
896
897                         if (drawParams)
898                                 flag= drawParams(&mtf, has_vcol, efa->mat_nr);
899                         else if (drawParamsMapped)
900                                 flag= drawParamsMapped(userData, BM_elem_index_get(efa));
901                         else
902                                 flag= 1;
903
904                         if (flag != 0) { /* flag 0 == the face is hidden or invisible */
905
906                                 /* we always want smooth here since otherwise vertex colors dont interpolate */
907                                 if (!has_vcol) {
908                                         glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
909                                 }
910
911                                 glBegin(GL_TRIANGLES);
912                                 if (!drawSmooth) {
913                                         glNormal3fv(efa->no);
914
915                                         bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol);
916
917                                         if (luv[0])
918                                                 glTexCoord2fv(luv[0]->uv);
919                                         if (lcol[0])
920                                                 glColor3ub(lcol[0]->b, lcol[0]->g, lcol[0]->r);
921                                         else glColor3ub(0, 0, 0);
922                                         glVertex3fv(ls[0]->v->co);
923
924                                         if (luv[1])
925                                                 glTexCoord2fv(luv[1]->uv);
926                                         if (lcol[1])
927                                                 glColor3ub(lcol[1]->b, lcol[1]->g, lcol[1]->r);
928                                         else glColor3ub(0, 0, 0);
929                                         glVertex3fv(ls[1]->v->co);
930
931                                         if (luv[2])
932                                                 glTexCoord2fv(luv[2]->uv);
933                                         if (lcol[2])
934                                                 glColor3ub(lcol[2]->b, lcol[2]->g, lcol[2]->r);
935                                         else glColor3ub(0, 0, 0);
936                                         glVertex3fv(ls[2]->v->co);
937                                 }
938                                 else {
939                                         bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol);
940
941                                         if (luv[0])
942                                                 glTexCoord2fv(luv[0]->uv);
943                                         if (lcol[0])
944                                                 glColor3ub(lcol[0]->b, lcol[0]->g, lcol[0]->r);
945                                         else glColor3ub(0, 0, 0);
946                                         glNormal3fv(ls[0]->v->no);
947                                         glVertex3fv(ls[0]->v->co);
948
949                                         if (luv[1])
950                                                 glTexCoord2fv(luv[1]->uv);
951                                         if (lcol[1])
952                                                 glColor3ub(lcol[1]->b, lcol[1]->g, lcol[1]->r);
953                                         else glColor3ub(0, 0, 0);
954                                         glNormal3fv(ls[1]->v->no);
955                                         glVertex3fv(ls[1]->v->co);
956
957                                         if (luv[2])
958                                                 glTexCoord2fv(luv[2]->uv);
959                                         if (lcol[2])
960                                                 glColor3ub(lcol[2]->b, lcol[2]->g, lcol[2]->r);
961                                         else glColor3ub(0, 0, 0);
962                                         glNormal3fv(ls[2]->v->no);
963                                         glVertex3fv(ls[2]->v->co);
964                                 }
965                                 glEnd();
966                         }
967                 }
968         }
969 }
970
971 static void emDM_drawFacesTex(
972                 DerivedMesh *dm,
973                 int (*setDrawOptions)(MTFace *tface, int has_vcol, int matnr),
974                 int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
975                 void *userData)
976 {
977         emDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData);
978 }
979
980 static void emDM_drawMappedFacesTex(
981                 DerivedMesh *dm,
982                 int (*setDrawOptions)(void *userData, int index),
983                 int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
984                 void *userData)
985 {
986         emDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData);
987 }
988
989 static void emDM_drawMappedFacesGLSL(
990                 DerivedMesh *dm,
991                 int (*setMaterial)(int, void *attribs),
992                 int (*setDrawOptions)(void *userData, int index),
993                 void *userData)
994 {
995         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
996         BMesh *bm= bmdm->tc->bm;
997         BMEditMesh *em = bmdm->tc;
998         float (*vertexCos)[3]= bmdm->vertexCos;
999         float (*vertexNos)[3]= bmdm->vertexNos;
1000         BMFace *efa;
1001         BMLoop **ltri;
1002         DMVertexAttribs attribs;
1003         GPUVertexAttribs gattribs;
1004
1005         int i, b, matnr, new_matnr, dodraw;
1006
1007         dodraw = 0;
1008         matnr = -1;
1009
1010         memset(&attribs, 0, sizeof(attribs));
1011
1012         /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
1013         glShadeModel(GL_SMOOTH);
1014         BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE);
1015
1016 #define PASSATTRIB(loop, eve, vert) {                                                                                   \
1017         if (attribs.totorco) {                                                                                                          \
1018                 float *orco = attribs.orco.array[BM_elem_index_get(eve)];                                               \
1019                 glVertexAttrib3fvARB(attribs.orco.glIndex, orco);                                               \
1020         }                                                                                                                                                       \
1021         for (b = 0; b < attribs.tottface; b++) {                                                                        \
1022                 MLoopUV *_luv = CustomData_bmesh_get_n(&bm->ldata, loop->head.data, CD_MLOOPUV, b);\
1023                 glVertexAttrib2fvARB(attribs.tface[b].glIndex, _luv->uv);                               \
1024         }                                                                                                                                                       \
1025         for (b = 0; b < attribs.totmcol; b++) {                                                                         \
1026                 MLoopCol *_cp = CustomData_bmesh_get_n(&bm->ldata, loop->head.data, CD_MLOOPCOL, b);\
1027                 GLubyte _col[4];                                                                                                                \
1028                 _col[0]= _cp->b; _col[1]= _cp->g; _col[2]= _cp->r; _col[3]= _cp->a;             \
1029                 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, _col);                                   \
1030         }                                                                                                                                                       \
1031         if (attribs.tottang) {                                                                                                          \
1032                 float *tang = attribs.tang.array[i*4 + vert];                                                   \
1033                 glVertexAttrib3fvARB(attribs.tang.glIndex, tang);                                               \
1034         }                                                                                                                                                       \
1035         }
1036
1037
1038         for (i=0, ltri=em->looptris[0]; i<em->tottri; i++, ltri += 3) {
1039                 int drawSmooth;
1040
1041                 efa = ltri[0]->f;
1042                 drawSmooth= BM_elem_flag_test(efa, BM_ELEM_SMOOTH);
1043
1044                 if (setDrawOptions && !setDrawOptions(userData, BM_elem_index_get(efa)))
1045                         continue;
1046
1047                 new_matnr = efa->mat_nr + 1;
1048                 if (new_matnr != matnr) {
1049                         dodraw = setMaterial(matnr = new_matnr, &gattribs);
1050                         if (dodraw)
1051                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1052                 }
1053
1054                 if (dodraw) {
1055                         glBegin(GL_TRIANGLES);
1056                         if (!drawSmooth) {
1057                                 if (vertexCos) glNormal3fv(bmdm->polyNos[BM_elem_index_get(efa)]);
1058                                 else glNormal3fv(efa->no);
1059
1060                                 PASSATTRIB(ltri[0], ltri[0]->v, 0);
1061                                 if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
1062                                 else glVertex3fv(ltri[0]->v->co);
1063
1064                                 PASSATTRIB(ltri[1], ltri[1]->v, 1);
1065                                 if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
1066                                 else glVertex3fv(ltri[1]->v->co);
1067
1068                                 PASSATTRIB(ltri[2], ltri[2]->v, 2);
1069                                 if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
1070                                 else glVertex3fv(ltri[2]->v->co);
1071                         }
1072                         else {
1073                                 PASSATTRIB(ltri[0], ltri[0]->v, 0);
1074                                 if (vertexCos) {
1075                                         glNormal3fv(vertexNos[BM_elem_index_get(ltri[0]->v)]);
1076                                         glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
1077                                 }
1078                                 else {
1079                                         glNormal3fv(ltri[0]->v->no);
1080                                         glVertex3fv(ltri[0]->v->co);
1081                                 }
1082
1083                                 PASSATTRIB(ltri[1], ltri[1]->v, 1);
1084                                 if (vertexCos) {
1085                                         glNormal3fv(vertexNos[BM_elem_index_get(ltri[1]->v)]);
1086                                         glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
1087                                 }
1088                                 else {
1089                                         glNormal3fv(ltri[1]->v->no);
1090                                         glVertex3fv(ltri[1]->v->co);
1091                                 }
1092
1093                                 PASSATTRIB(ltri[2], ltri[2]->v, 2);
1094                                 if (vertexCos) {
1095                                         glNormal3fv(vertexNos[BM_elem_index_get(ltri[2]->v)]);
1096                                         glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
1097                                 }
1098                                 else {
1099                                         glNormal3fv(ltri[2]->v->no);
1100                                         glVertex3fv(ltri[2]->v->co);
1101                                 }
1102                         }
1103                         glEnd();
1104                 }
1105         }
1106 #undef PASSATTRIB
1107 }
1108
1109 static void emDM_drawFacesGLSL(
1110                 DerivedMesh *dm,
1111                 int (*setMaterial)(int, void *attribs))
1112 {
1113         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1114 }
1115
1116 static void emDM_drawMappedFacesMat(
1117                 DerivedMesh *dm,
1118                 void (*setMaterial)(void *userData, int, void *attribs),
1119                 int (*setFace)(void *userData, int index), void *userData)
1120 {
1121         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1122         BMesh *bm= bmdm->tc->bm;
1123         BMEditMesh *em = bmdm->tc;
1124         float (*vertexCos)[3]= bmdm->vertexCos;
1125         float (*vertexNos)[3]= bmdm->vertexNos;
1126         BMFace *efa;
1127         BMLoop **ltri;
1128         DMVertexAttribs attribs= {{{0}}};
1129         GPUVertexAttribs gattribs;
1130         int i, b, matnr, new_matnr;
1131
1132         matnr = -1;
1133
1134         /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
1135         glShadeModel(GL_SMOOTH);
1136
1137         BM_mesh_elem_index_ensure(bm, BM_VERT);
1138
1139 #define PASSATTRIB(loop, eve, vert) {                                                                                   \
1140         if (attribs.totorco) {                                                                                                          \
1141                 float *orco = attribs.orco.array[BM_elem_index_get(eve)];                                               \
1142                 glVertexAttrib3fvARB(attribs.orco.glIndex, orco);                                               \
1143         }                                                                                                                                                       \
1144         for (b = 0; b < attribs.tottface; b++) {                                                                        \
1145                 MLoopUV *_luv = CustomData_bmesh_get_n(&bm->ldata, loop->head.data, CD_MLOOPUV, b);\
1146                 glVertexAttrib2fvARB(attribs.tface[b].glIndex, _luv->uv);                               \
1147         }                                                                                                                                                       \
1148         for (b = 0; b < attribs.totmcol; b++) {                                                                         \
1149                 MLoopCol *_cp = CustomData_bmesh_get_n(&bm->ldata, loop->head.data, CD_MLOOPCOL, b);\
1150                 GLubyte _col[4];                                                                                                                \
1151                 _col[0]= _cp->b; _col[1]= _cp->g; _col[2]= _cp->r; _col[3]= _cp->a;             \
1152                 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, _col);                                   \
1153         }                                                                                                                                                       \
1154         if (attribs.tottang) {                                                                                                          \
1155                 float *tang = attribs.tang.array[i*4 + vert];                                                   \
1156                 glVertexAttrib4fvARB(attribs.tang.glIndex, tang);                                               \
1157         }                                                                                                                                                       \
1158 }
1159
1160         for (i=0, ltri=em->looptris[0]; i<em->tottri; i++, ltri += 3) {
1161                 int drawSmooth;
1162
1163                 efa = ltri[0]->f;
1164                 drawSmooth = BM_elem_flag_test(efa, BM_ELEM_SMOOTH);
1165
1166                 /* face hiding */
1167                 if (setFace && !setFace(userData, BM_elem_index_get(efa)))
1168                         continue;
1169
1170                 /* material */
1171                 new_matnr = efa->mat_nr + 1;
1172                 if (new_matnr != matnr) {
1173                         setMaterial(userData, matnr = new_matnr, &gattribs);
1174                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1175                 }
1176
1177                 /* face */
1178                 glBegin(GL_TRIANGLES);
1179                 if (!drawSmooth) {
1180                         if (vertexCos) glNormal3fv(bmdm->polyNos[BM_elem_index_get(efa)]);
1181                         else glNormal3fv(efa->no);
1182
1183                         PASSATTRIB(ltri[0], ltri[0]->v, 0);
1184                         if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
1185                         else glVertex3fv(ltri[0]->v->co);
1186
1187                         PASSATTRIB(ltri[1], ltri[1]->v, 1);
1188                         if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
1189                         else glVertex3fv(ltri[1]->v->co);
1190
1191                         PASSATTRIB(ltri[2], ltri[2]->v, 2);
1192                         if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
1193                         else glVertex3fv(ltri[2]->v->co);
1194
1195                 }
1196                 else {
1197                         PASSATTRIB(ltri[0], ltri[0]->v, 0);
1198                         if (vertexCos) {
1199                                 glNormal3fv(vertexNos[BM_elem_index_get(ltri[0]->v)]);
1200                                 glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
1201                         }
1202                         else {
1203                                 glNormal3fv(ltri[0]->v->no);
1204                                 glVertex3fv(ltri[0]->v->co);
1205                         }
1206
1207                         PASSATTRIB(ltri[1], ltri[1]->v, 1);
1208                         if (vertexCos) {
1209                                 glNormal3fv(vertexNos[BM_elem_index_get(ltri[1]->v)]);
1210                                 glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
1211                         }
1212                         else {
1213                                 glNormal3fv(ltri[1]->v->no);
1214                                 glVertex3fv(ltri[1]->v->co);
1215                         }
1216
1217                         PASSATTRIB(ltri[2], ltri[2]->v, 2);
1218                         if (vertexCos) {
1219                                 glNormal3fv(vertexNos[BM_elem_index_get(ltri[2]->v)]);
1220                                 glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
1221                         }
1222                         else {
1223                                 glNormal3fv(ltri[2]->v->no);
1224                                 glVertex3fv(ltri[2]->v->co);
1225                         }
1226                 }
1227                 glEnd();
1228         }
1229 #undef PASSATTRIB
1230 }
1231
1232 static void emDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
1233 {
1234         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1235         BMVert *eve;
1236         BMIter iter;
1237         int i;
1238
1239         if (bmdm->tc->bm->totvert) {
1240                 eve = BM_iter_new(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
1241                 for (i=0; eve; eve=BM_iter_step(&iter), i++) {
1242                         if (bmdm->vertexCos) {
1243                                 DO_MINMAX(bmdm->vertexCos[i], min_r, max_r);
1244                         }
1245                         else {
1246                                 DO_MINMAX(eve->co, min_r, max_r);
1247                         }
1248                 }
1249         }
1250         else {
1251                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
1252         }
1253 }
1254 static int emDM_getNumVerts(DerivedMesh *dm)
1255 {
1256         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1257
1258         return bmdm->tc->bm->totvert;
1259 }
1260
1261 static int emDM_getNumEdges(DerivedMesh *dm)
1262 {
1263         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1264
1265         return bmdm->tc->bm->totedge;
1266 }
1267
1268 static int emDM_getNumTessFaces(DerivedMesh *dm)
1269 {
1270         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1271
1272         return bmdm->tc->tottri;
1273 }
1274
1275 static int emDM_getNumLoops(DerivedMesh *dm)
1276 {
1277         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1278
1279         return bmdm->tc->bm->totloop;
1280 }
1281
1282 static int emDM_getNumPolys(DerivedMesh *dm)
1283 {
1284         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1285
1286         return bmdm->tc->bm->totface;
1287 }
1288
1289 static int bmvert_to_mvert(BMesh *bm, BMVert *ev, MVert *vert_r)
1290 {
1291         copy_v3_v3(vert_r->co, ev->co);
1292
1293         normal_float_to_short_v3(vert_r->no, ev->no);
1294
1295         vert_r->flag = BM_vert_flag_to_mflag(ev);
1296
1297         if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
1298                 vert_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->vdata, ev, CD_BWEIGHT)*255.0f);
1299         }
1300
1301         return 1;
1302 }
1303
1304 static void emDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
1305 {
1306         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1307         BMVert *ev;
1308
1309         if (index < 0 || index >= bmdm->tv) {
1310                 printf("error in emDM_getVert.\n");
1311                 return;
1312         }
1313
1314         // ev = EDBM_get_vert_for_index(bmdm->tc, index);
1315         ev = BM_vert_at_index(bmdm->tc->bm, index); /* warning, does list loop, _not_ ideal */
1316
1317         bmvert_to_mvert(bmdm->tc->bm, ev, vert_r);
1318 }
1319
1320 static void emDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
1321 {
1322         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1323         BMesh *bm = bmdm->tc->bm;
1324         BMEdge *e;
1325
1326         if (index < 0 || index >= bmdm->te) {
1327                 printf("error in emDM_getEdge.\n");
1328                 return;
1329         }
1330
1331         // e = EDBM_get_edge_for_index(bmdm->tc, index);
1332         e = BM_edge_at_index(bmdm->tc->bm, index); /* warning, does list loop, _not_ ideal */
1333
1334         if (CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
1335                 edge_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->edata, e, CD_BWEIGHT)*255.0f);
1336         }
1337
1338         if (CustomData_has_layer(&bm->edata, CD_CREASE)) {
1339                 edge_r->crease = (unsigned char) (BM_elem_float_data_get(&bm->edata, e, CD_CREASE)*255.0f);
1340         }
1341
1342         edge_r->flag = BM_edge_flag_to_mflag(e);
1343
1344         edge_r->v1 = BM_elem_index_get(e->v1);
1345         edge_r->v2 = BM_elem_index_get(e->v2);
1346 }
1347
1348 static void emDM_getTessFace(DerivedMesh *dm, int index, MFace *face_r)
1349 {
1350         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1351         BMFace *ef;
1352         BMLoop **l;
1353
1354         if (index < 0 || index >= bmdm->tf) {
1355                 printf("error in emDM_getTessFace.\n");
1356                 return;
1357         }
1358
1359         l = bmdm->tc->looptris[index];
1360
1361         ef = l[0]->f;
1362
1363         face_r->mat_nr = (unsigned char) ef->mat_nr;
1364         face_r->flag = BM_face_flag_to_mflag(ef);
1365
1366         face_r->v1 = BM_elem_index_get(l[0]->v);
1367         face_r->v2 = BM_elem_index_get(l[1]->v);
1368         face_r->v3 = BM_elem_index_get(l[2]->v);
1369         face_r->v4 = 0;
1370
1371         test_index_face(face_r, NULL, 0, 3);
1372 }
1373
1374 static void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
1375 {
1376         BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
1377         BMVert *ev;
1378         BMIter iter;
1379
1380         ev = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL);
1381         for ( ; ev; ev = BM_iter_step(&iter), ++vert_r) {
1382                 copy_v3_v3(vert_r->co, ev->co);
1383
1384                 normal_float_to_short_v3(vert_r->no, ev->no);
1385
1386                 vert_r->flag = BM_vert_flag_to_mflag(ev);
1387
1388                 if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
1389                         vert_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->vdata, ev, CD_BWEIGHT)*255.0f);
1390                 }
1391         }
1392 }
1393
1394 static void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
1395 {
1396         BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
1397         BMEdge *ee;
1398         BMIter iter;
1399         int has_bweight = CustomData_has_layer(&bm->edata, CD_BWEIGHT);
1400         int has_crease = CustomData_has_layer(&bm->edata, CD_CREASE);
1401
1402         BM_mesh_elem_index_ensure(bm, BM_VERT);
1403
1404         ee = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, NULL);
1405         for ( ; ee; ee=BM_iter_step(&iter), edge_r++) {
1406                 if (has_bweight) {
1407                         edge_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->edata, ee, CD_BWEIGHT)*255.0f);
1408                 }
1409
1410                 if (has_crease) {
1411                         edge_r->crease = (unsigned char) (BM_elem_float_data_get(&bm->edata, ee, CD_CREASE)*255.0f);
1412                 }
1413
1414                 edge_r->flag = BM_edge_flag_to_mflag(ee);
1415
1416                 edge_r->v1 = BM_elem_index_get(ee->v1);
1417                 edge_r->v2 = BM_elem_index_get(ee->v2);
1418         }
1419 }
1420
1421 static void emDM_copyTessFaceArray(DerivedMesh *dm, MFace *face_r)
1422 {
1423         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1424         BMesh *bm = bmdm->tc->bm;
1425         BMFace *ef;
1426         BMLoop **l;
1427         int i;
1428
1429         BM_mesh_elem_index_ensure(bm, BM_VERT);
1430
1431         for (i=0; i<bmdm->tc->tottri; i++, face_r++) {
1432                 l = bmdm->tc->looptris[i];
1433                 ef = l[0]->f;
1434
1435                 face_r->mat_nr = (unsigned char) ef->mat_nr;
1436
1437                 face_r->flag = BM_face_flag_to_mflag(ef);
1438
1439                 face_r->v1 = BM_elem_index_get(l[0]->v);
1440                 face_r->v2 = BM_elem_index_get(l[1]->v);
1441                 face_r->v3 = BM_elem_index_get(l[2]->v);
1442                 face_r->v4 = 0;
1443
1444                 test_index_face(face_r, NULL, 0, 3);
1445         }
1446 }
1447
1448
1449 static void emDM_copyLoopArray(DerivedMesh *dm, MLoop *loop_r)
1450 {
1451         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1452         BMesh *bm = bmdm->tc->bm;
1453         BMIter iter, liter;
1454         BMFace *f;
1455         BMLoop *l;
1456
1457         BM_mesh_elem_index_ensure(bm, BM_VERT | BM_EDGE);
1458
1459         BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
1460                 BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) {
1461                         loop_r->v = BM_elem_index_get(l->v);
1462                         loop_r->e = BM_elem_index_get(l->e);
1463                         loop_r++;
1464                 }
1465         }
1466 }
1467
1468 static void emDM_copyPolyArray(DerivedMesh *dm, MPoly *poly_r)
1469 {
1470         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1471         BMesh *bm = bmdm->tc->bm;
1472         BMIter iter;
1473         BMFace *f;
1474         int i;
1475
1476         i = 0;
1477         BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
1478                 poly_r->flag = BM_face_flag_to_mflag(f);
1479                 poly_r->loopstart = i;
1480                 poly_r->totloop = f->len;
1481                 poly_r->mat_nr = f->mat_nr;
1482
1483                 poly_r++;
1484                 i += f->len;
1485         }
1486 }
1487
1488 static void *emDM_getTessFaceDataArray(DerivedMesh *dm, int type)
1489 {
1490         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1491         BMesh *bm= bmdm->tc->bm;
1492         BMFace *efa;
1493         char *data, *bmdata;
1494         void *datalayer;
1495         int index /*, offset*/ /*UNUSED */, size, i;
1496
1497         datalayer = DM_get_tessface_data_layer(dm, type);
1498         if (datalayer)
1499                 return datalayer;
1500
1501         /* layers are store per face for editmesh, we convert to a tbmporary
1502          * data layer array in the derivedmesh when these are requested */
1503         if (type == CD_MTFACE || type == CD_MCOL) {
1504                 index = CustomData_get_layer_index(&bm->pdata, type);
1505
1506                 if (index != -1) {
1507                         /* offset = bm->pdata.layers[index].offset; */ /* UNUSED */
1508                         size = CustomData_sizeof(type);
1509
1510                         DM_add_tessface_layer(dm, type, CD_CALLOC, NULL);
1511                         index = CustomData_get_layer_index(&dm->faceData, type);
1512                         dm->faceData.layers[index].flag |= CD_FLAG_TEMPORARY;
1513
1514                         data = datalayer = DM_get_tessface_data_layer(dm, type);
1515                         for (i=0; i<bmdm->tc->tottri; i++, data+=size) {
1516                                 efa = bmdm->tc->looptris[i][0]->f;
1517                                 /*BMESH_TODO: need to still add tface data,
1518                                   derived from the loops.*/
1519                                 bmdata = CustomData_bmesh_get(&bm->pdata, efa->head.data, type);
1520                                 memcpy(data, bmdata, size);
1521                         }
1522                 }
1523         }
1524
1525         return datalayer;
1526 }
1527
1528 static void emDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
1529 {
1530         EditDerivedBMesh *emdm= (EditDerivedBMesh*) dm;
1531         BMVert *eve;
1532         BMIter iter;
1533         int i;
1534
1535         i= 0;
1536         BM_ITER(eve, &iter, emdm->tc->bm, BM_VERTS_OF_MESH, NULL) {
1537                 if (emdm->vertexCos) {
1538                         copy_v3_v3(cos_r[i], emdm->vertexCos[i]);
1539                 }
1540                 else {
1541                         copy_v3_v3(cos_r[i], eve->co);
1542                 }
1543
1544                 i++;
1545         }
1546 }
1547
1548 static void emDM_release(DerivedMesh *dm)
1549 {
1550         EditDerivedBMesh *bmdm= (EditDerivedBMesh *)dm;
1551
1552         if (DM_release(dm)) {
1553                 if (bmdm->vertexCos) {
1554                         MEM_freeN(bmdm->vertexCos);
1555                         MEM_freeN(bmdm->vertexNos);
1556                         MEM_freeN(bmdm->polyNos);
1557                 }
1558
1559                 MEM_freeN(bmdm);
1560         }
1561 }
1562
1563 static CustomData *bmDm_getVertDataLayout(DerivedMesh *dm)
1564 {
1565         EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm;
1566
1567         return &bmdm->tc->bm->vdata;
1568 }
1569
1570 static CustomData *bmDm_getEdgeDataLayout(DerivedMesh *dm)
1571 {
1572         EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm;
1573
1574         return &bmdm->tc->bm->edata;
1575 }
1576
1577 static CustomData *bmDm_getTessFaceDataLayout(DerivedMesh *dm)
1578 {
1579         EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm;
1580
1581         return &bmdm->dm.faceData;
1582 }
1583
1584 static CustomData *bmDm_getLoopDataLayout(DerivedMesh *dm)
1585 {
1586         EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm;
1587
1588         return &bmdm->tc->bm->ldata;
1589 }
1590
1591 static CustomData *bmDm_getPolyDataLayout(DerivedMesh *dm)
1592 {
1593         EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm;
1594
1595         return &bmdm->tc->bm->pdata;
1596 }
1597
1598
1599 DerivedMesh *getEditDerivedBMesh(
1600                 BMEditMesh *em,
1601                 Object *UNUSED(ob),
1602                 float (*vertexCos)[3])
1603 {
1604         EditDerivedBMesh *bmdm = MEM_callocN(sizeof(*bmdm), __func__);
1605         BMesh *bm = em->bm;
1606
1607         bmdm->tc = em;
1608
1609         DM_init((DerivedMesh*)bmdm, DM_TYPE_EDITBMESH, em->bm->totvert,
1610                  em->bm->totedge, em->tottri, em->bm->totloop, em->bm->totface);
1611
1612         CustomData_from_bmeshpoly(&bmdm->dm.faceData, &em->bm->pdata, &em->bm->ldata, 0);
1613
1614         bmdm->dm.getVertCos = emDM_getVertCos;
1615         bmdm->dm.getMinMax = emDM_getMinMax;
1616
1617         bmdm->dm.getVertDataLayout = bmDm_getVertDataLayout;
1618         bmdm->dm.getEdgeDataLayout = bmDm_getEdgeDataLayout;
1619         bmdm->dm.getTessFaceDataLayout = bmDm_getTessFaceDataLayout;
1620         bmdm->dm.getLoopDataLayout = bmDm_getLoopDataLayout;
1621         bmdm->dm.getPolyDataLayout = bmDm_getPolyDataLayout;
1622
1623         bmdm->dm.getNumVerts = emDM_getNumVerts;
1624         bmdm->dm.getNumEdges = emDM_getNumEdges;
1625         bmdm->dm.getNumTessFaces = emDM_getNumTessFaces;
1626         bmdm->dm.getNumLoops = emDM_getNumLoops;
1627         bmdm->dm.getNumPolys = emDM_getNumPolys;
1628
1629         bmdm->dm.getVert = emDM_getVert;
1630         bmdm->dm.getEdge = emDM_getEdge;
1631         bmdm->dm.getTessFace = emDM_getTessFace;
1632         bmdm->dm.copyVertArray = emDM_copyVertArray;
1633         bmdm->dm.copyEdgeArray = emDM_copyEdgeArray;
1634         bmdm->dm.copyTessFaceArray = emDM_copyTessFaceArray;
1635         bmdm->dm.copyLoopArray = emDM_copyLoopArray;
1636         bmdm->dm.copyPolyArray = emDM_copyPolyArray;
1637
1638         bmdm->dm.getTessFaceDataArray = emDM_getTessFaceDataArray;
1639
1640         bmdm->dm.calcNormals = emDM_calcNormals;
1641         bmdm->dm.recalcTesselation = emDM_recalcTesselation;
1642
1643         bmdm->dm.foreachMappedVert = emDM_foreachMappedVert;
1644         bmdm->dm.foreachMappedEdge = emDM_foreachMappedEdge;
1645         bmdm->dm.foreachMappedFaceCenter = emDM_foreachMappedFaceCenter;
1646
1647         bmdm->dm.drawEdges = emDM_drawEdges;
1648         bmdm->dm.drawMappedEdges = emDM_drawMappedEdges;
1649         bmdm->dm.drawMappedEdgesInterp = emDM_drawMappedEdgesInterp;
1650         bmdm->dm.drawMappedFaces = emDM_drawMappedFaces;
1651         bmdm->dm.drawMappedFacesTex = emDM_drawMappedFacesTex;
1652         bmdm->dm.drawMappedFacesGLSL = emDM_drawMappedFacesGLSL;
1653         bmdm->dm.drawMappedFacesMat = emDM_drawMappedFacesMat;
1654         bmdm->dm.drawFacesTex = emDM_drawFacesTex;
1655         bmdm->dm.drawFacesGLSL = emDM_drawFacesGLSL;
1656         bmdm->dm.drawUVEdges = emDM_drawUVEdges;
1657
1658         bmdm->dm.release = emDM_release;
1659
1660         bmdm->vertexCos = vertexCos;
1661
1662         if (CustomData_has_layer(&bm->vdata, CD_MDEFORMVERT)) {
1663                 BMIter iter;
1664                 BMVert *eve;
1665                 int i;
1666
1667                 DM_add_vert_layer(&bmdm->dm, CD_MDEFORMVERT, CD_CALLOC, NULL);
1668
1669                 eve = BM_iter_new(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
1670                 for (i=0; eve; eve=BM_iter_step(&iter), i++)
1671                         DM_set_vert_data(&bmdm->dm, i, CD_MDEFORMVERT,
1672                                                          CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MDEFORMVERT));
1673         }
1674
1675         if (vertexCos) {
1676                 BMFace *efa;
1677                 BMVert *eve;
1678                 BMIter fiter;
1679                 BMIter viter;
1680                 int i;
1681
1682                 BM_mesh_elem_index_ensure(bm, BM_VERT);
1683
1684                 bmdm->vertexNos = MEM_callocN(sizeof(*bmdm->vertexNos) * bm->totvert, "bmdm_vno");
1685                 bmdm->polyNos = MEM_mallocN(sizeof(*bmdm->polyNos)*bm->totface, "bmdm_pno");
1686
1687                 i = 0;
1688                 BM_ITER(efa, &fiter, bm, BM_FACES_OF_MESH, NULL) {
1689                         BM_elem_index_set(efa, i); /* set_inline */
1690                         BM_face_normal_update_vcos(bm, efa, bmdm->polyNos[i], vertexCos);
1691                         i++;
1692                 }
1693                 bm->elem_index_dirty &= ~BM_FACE;
1694
1695                 eve=BM_iter_new(&viter, bm, BM_VERTS_OF_MESH, NULL);
1696                 for (i=0; eve; eve=BM_iter_step(&viter), i++) {
1697                         float *no = bmdm->vertexNos[i];
1698                         BM_ITER(efa, &fiter, bm, BM_FACES_OF_VERT, eve) {
1699                                 add_v3_v3(no, bmdm->polyNos[BM_elem_index_get(efa)]);
1700                         }
1701
1702                         /* following Mesh convention; we use vertex coordinate itself
1703                          * for normal in this case */
1704                         if (normalize_v3(no)==0.0) {
1705                                 copy_v3_v3(no, vertexCos[i]);
1706                                 normalize_v3(no);
1707                         }
1708                 }
1709         }
1710
1711         return (DerivedMesh*) bmdm;
1712 }