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