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