style cleanup: line length and ensure some macros error when not ending with ';'
[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,     \
1001                                                                CD_MLOOPUV, b);                  \
1002                         glVertexAttrib2fvARB(attribs.tface[b].gl_index, _luv->uv);              \
1003                 }                                                                           \
1004                 for (b = 0; b < attribs.totmcol; b++) {                                     \
1005                         MLoopCol *_cp = CustomData_bmesh_get_n(&bm->ldata, loop->head.data,     \
1006                                                                CD_MLOOPCOL, b);                 \
1007                         GLubyte _col[4];                                                        \
1008                         _col[0] = _cp->b; _col[1] = _cp->g; _col[2] = _cp->r; _col[3] = _cp->a; \
1009                         glVertexAttrib4ubvARB(attribs.mcol[b].gl_index, _col);                  \
1010                 }                                                                           \
1011                 if (attribs.tottang) {                                                      \
1012                         float *tang = attribs.tang.array[i * 4 + vert];                         \
1013                         glVertexAttrib3fvARB(attribs.tang.gl_index, tang);                      \
1014                 }                                                                           \
1015         } (void)0
1016
1017
1018         for (i = 0, ltri = em->looptris[0]; i < em->tottri; i++, ltri += 3) {
1019                 int drawSmooth;
1020
1021                 efa = ltri[0]->f;
1022                 drawSmooth = BM_elem_flag_test(efa, BM_ELEM_SMOOTH);
1023
1024                 if (setDrawOptions && (setDrawOptions(userData, BM_elem_index_get(efa)) == DM_DRAW_OPTION_SKIP))
1025                         continue;
1026
1027                 new_matnr = efa->mat_nr + 1;
1028                 if (new_matnr != matnr) {
1029                         dodraw = setMaterial(matnr = new_matnr, &gattribs);
1030                         if (dodraw)
1031                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1032                 }
1033
1034                 if (dodraw) {
1035                         glBegin(GL_TRIANGLES);
1036                         if (!drawSmooth) {
1037                                 if (vertexCos) glNormal3fv(bmdm->polyNos[BM_elem_index_get(efa)]);
1038                                 else glNormal3fv(efa->no);
1039
1040                                 PASSATTRIB(ltri[0], ltri[0]->v, 0);
1041                                 if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
1042                                 else glVertex3fv(ltri[0]->v->co);
1043
1044                                 PASSATTRIB(ltri[1], ltri[1]->v, 1);
1045                                 if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
1046                                 else glVertex3fv(ltri[1]->v->co);
1047
1048                                 PASSATTRIB(ltri[2], ltri[2]->v, 2);
1049                                 if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
1050                                 else glVertex3fv(ltri[2]->v->co);
1051                         }
1052                         else {
1053                                 PASSATTRIB(ltri[0], ltri[0]->v, 0);
1054                                 if (vertexCos) {
1055                                         glNormal3fv(vertexNos[BM_elem_index_get(ltri[0]->v)]);
1056                                         glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
1057                                 }
1058                                 else {
1059                                         glNormal3fv(ltri[0]->v->no);
1060                                         glVertex3fv(ltri[0]->v->co);
1061                                 }
1062
1063                                 PASSATTRIB(ltri[1], ltri[1]->v, 1);
1064                                 if (vertexCos) {
1065                                         glNormal3fv(vertexNos[BM_elem_index_get(ltri[1]->v)]);
1066                                         glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
1067                                 }
1068                                 else {
1069                                         glNormal3fv(ltri[1]->v->no);
1070                                         glVertex3fv(ltri[1]->v->co);
1071                                 }
1072
1073                                 PASSATTRIB(ltri[2], ltri[2]->v, 2);
1074                                 if (vertexCos) {
1075                                         glNormal3fv(vertexNos[BM_elem_index_get(ltri[2]->v)]);
1076                                         glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
1077                                 }
1078                                 else {
1079                                         glNormal3fv(ltri[2]->v->no);
1080                                         glVertex3fv(ltri[2]->v->co);
1081                                 }
1082                         }
1083                         glEnd();
1084                 }
1085         }
1086 #undef PASSATTRIB
1087 }
1088
1089 static void emDM_drawFacesGLSL(DerivedMesh *dm,
1090                                int (*setMaterial)(int, void *attribs))
1091 {
1092         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1093 }
1094
1095 static void emDM_drawMappedFacesMat(DerivedMesh *dm,
1096                                     void (*setMaterial)(void *userData, int, void *attribs),
1097                                     int (*setFace)(void *userData, int index), void *userData)
1098 {
1099         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1100         BMesh *bm = bmdm->tc->bm;
1101         BMEditMesh *em = bmdm->tc;
1102         float (*vertexCos)[3] = bmdm->vertexCos;
1103         float (*vertexNos)[3] = bmdm->vertexNos;
1104         BMFace *efa;
1105         BMLoop **ltri;
1106         DMVertexAttribs attribs = {{{0}}};
1107         GPUVertexAttribs gattribs;
1108         int i, b, matnr, new_matnr;
1109
1110         matnr = -1;
1111
1112         /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
1113         glShadeModel(GL_SMOOTH);
1114
1115         BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE);
1116
1117 #define PASSATTRIB(loop, eve, vert) {                                               \
1118                 if (attribs.totorco) {                                                      \
1119                         float *orco = attribs.orco.array[BM_elem_index_get(eve)];               \
1120                         if (attribs.orco.gl_texco)                                              \
1121                                 glTexCoord3fv(orco);                                                \
1122                         else                                                                    \
1123                                 glVertexAttrib3fvARB(attribs.orco.gl_index, orco);                  \
1124                 }                                                                           \
1125                 for (b = 0; b < attribs.tottface; b++) {                                    \
1126                         MLoopUV *_luv = CustomData_bmesh_get_n(&bm->ldata, loop->head.data,     \
1127                                                                CD_MLOOPUV, b);                  \
1128                         if (attribs.tface[b].gl_texco)                                          \
1129                                 glTexCoord2fv(_luv->uv);                                            \
1130                         else                                                                    \
1131                                 glVertexAttrib2fvARB(attribs.tface[b].gl_index, _luv->uv);          \
1132                 }                                                                           \
1133                 for (b = 0; b < attribs.totmcol; b++) {                                     \
1134                         MLoopCol *_cp = CustomData_bmesh_get_n(&bm->ldata, loop->head.data,     \
1135                                                                CD_MLOOPCOL, b);                 \
1136                         GLubyte _col[4];                                                        \
1137                         _col[0] = _cp->b; _col[1] = _cp->g; _col[2] = _cp->r; _col[3] = _cp->a; \
1138                         glVertexAttrib4ubvARB(attribs.mcol[b].gl_index, _col);                  \
1139                 }                                                                           \
1140                 if (attribs.tottang) {                                                      \
1141                         float *tang = attribs.tang.array[i * 4 + vert];                         \
1142                         glVertexAttrib4fvARB(attribs.tang.gl_index, tang);                      \
1143                 }                                                                           \
1144         } (void)0
1145
1146         for (i = 0, ltri = em->looptris[0]; i < em->tottri; i++, ltri += 3) {
1147                 int drawSmooth;
1148
1149                 efa = ltri[0]->f;
1150                 drawSmooth = BM_elem_flag_test(efa, BM_ELEM_SMOOTH);
1151
1152                 /* face hiding */
1153                 if (setFace && !setFace(userData, BM_elem_index_get(efa)))
1154                         continue;
1155
1156                 /* material */
1157                 new_matnr = efa->mat_nr + 1;
1158                 if (new_matnr != matnr) {
1159                         setMaterial(userData, matnr = new_matnr, &gattribs);
1160                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1161                 }
1162
1163                 /* face */
1164                 glBegin(GL_TRIANGLES);
1165                 if (!drawSmooth) {
1166                         if (vertexCos) glNormal3fv(bmdm->polyNos[BM_elem_index_get(efa)]);
1167                         else glNormal3fv(efa->no);
1168
1169                         PASSATTRIB(ltri[0], ltri[0]->v, 0);
1170                         if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
1171                         else glVertex3fv(ltri[0]->v->co);
1172
1173                         PASSATTRIB(ltri[1], ltri[1]->v, 1);
1174                         if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
1175                         else glVertex3fv(ltri[1]->v->co);
1176
1177                         PASSATTRIB(ltri[2], ltri[2]->v, 2);
1178                         if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
1179                         else glVertex3fv(ltri[2]->v->co);
1180
1181                 }
1182                 else {
1183                         PASSATTRIB(ltri[0], ltri[0]->v, 0);
1184                         if (vertexCos) {
1185                                 glNormal3fv(vertexNos[BM_elem_index_get(ltri[0]->v)]);
1186                                 glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
1187                         }
1188                         else {
1189                                 glNormal3fv(ltri[0]->v->no);
1190                                 glVertex3fv(ltri[0]->v->co);
1191                         }
1192
1193                         PASSATTRIB(ltri[1], ltri[1]->v, 1);
1194                         if (vertexCos) {
1195                                 glNormal3fv(vertexNos[BM_elem_index_get(ltri[1]->v)]);
1196                                 glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
1197                         }
1198                         else {
1199                                 glNormal3fv(ltri[1]->v->no);
1200                                 glVertex3fv(ltri[1]->v->co);
1201                         }
1202
1203                         PASSATTRIB(ltri[2], ltri[2]->v, 2);
1204                         if (vertexCos) {
1205                                 glNormal3fv(vertexNos[BM_elem_index_get(ltri[2]->v)]);
1206                                 glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
1207                         }
1208                         else {
1209                                 glNormal3fv(ltri[2]->v->no);
1210                                 glVertex3fv(ltri[2]->v->co);
1211                         }
1212                 }
1213                 glEnd();
1214         }
1215 #undef PASSATTRIB
1216 }
1217
1218 static void emDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
1219 {
1220         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1221         BMVert *eve;
1222         BMIter iter;
1223         int i;
1224
1225         if (bmdm->tc->bm->totvert) {
1226                 if (bmdm->vertexCos) {
1227                         BM_ITER_MESH_INDEX (eve, &iter, bmdm->tc->bm, BM_VERTS_OF_MESH, i) {
1228                                 minmax_v3v3_v3(min_r, max_r, bmdm->vertexCos[i]);
1229                         }
1230                 }
1231                 else {
1232                         BM_ITER_MESH (eve, &iter, bmdm->tc->bm, BM_VERTS_OF_MESH) {
1233                                 minmax_v3v3_v3(min_r, max_r, eve->co);
1234                         }
1235                 }
1236         }
1237         else {
1238                 zero_v3(min_r);
1239                 zero_v3(max_r);
1240         }
1241 }
1242 static int emDM_getNumVerts(DerivedMesh *dm)
1243 {
1244         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1245
1246         return bmdm->tc->bm->totvert;
1247 }
1248
1249 static int emDM_getNumEdges(DerivedMesh *dm)
1250 {
1251         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1252
1253         return bmdm->tc->bm->totedge;
1254 }
1255
1256 static int emDM_getNumTessFaces(DerivedMesh *dm)
1257 {
1258         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1259
1260         return bmdm->tc->tottri;
1261 }
1262
1263 static int emDM_getNumLoops(DerivedMesh *dm)
1264 {
1265         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1266
1267         return bmdm->tc->bm->totloop;
1268 }
1269
1270 static int emDM_getNumPolys(DerivedMesh *dm)
1271 {
1272         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1273
1274         return bmdm->tc->bm->totface;
1275 }
1276
1277 static int bmvert_to_mvert(BMesh *bm, BMVert *ev, MVert *vert_r)
1278 {
1279         copy_v3_v3(vert_r->co, ev->co);
1280
1281         normal_float_to_short_v3(vert_r->no, ev->no);
1282
1283         vert_r->flag = BM_vert_flag_to_mflag(ev);
1284
1285         if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
1286                 vert_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->vdata, ev, CD_BWEIGHT) * 255.0f);
1287         }
1288
1289         return 1;
1290 }
1291
1292 static void emDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
1293 {
1294         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1295         BMVert *ev;
1296
1297         if (index < 0 || index >= bmdm->tv) {
1298                 printf("error in emDM_getVert.\n");
1299                 return;
1300         }
1301
1302         // ev = EDBM_vert_at_index(bmdm->tc, index);
1303         ev = BM_vert_at_index(bmdm->tc->bm, index); /* warning, does list loop, _not_ ideal */
1304
1305         bmvert_to_mvert(bmdm->tc->bm, ev, vert_r);
1306         if (bmdm->vertexCos)
1307                 copy_v3_v3(vert_r->co, bmdm->vertexCos[index]);
1308 }
1309
1310 static void emDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
1311 {
1312         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1313         BMesh *bm = bmdm->tc->bm;
1314         BMEdge *e;
1315
1316         if (index < 0 || index >= bmdm->te) {
1317                 printf("error in emDM_getEdge.\n");
1318                 return;
1319         }
1320
1321         // e = EDBM_edge_at_index(bmdm->tc, index);
1322         e = BM_edge_at_index(bmdm->tc->bm, index); /* warning, does list loop, _not_ ideal */
1323
1324         if (CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
1325                 edge_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->edata, e, CD_BWEIGHT) * 255.0f);
1326         }
1327
1328         if (CustomData_has_layer(&bm->edata, CD_CREASE)) {
1329                 edge_r->crease = (unsigned char) (BM_elem_float_data_get(&bm->edata, e, CD_CREASE) * 255.0f);
1330         }
1331
1332         edge_r->flag = BM_edge_flag_to_mflag(e);
1333
1334         edge_r->v1 = BM_elem_index_get(e->v1);
1335         edge_r->v2 = BM_elem_index_get(e->v2);
1336 }
1337
1338 static void emDM_getTessFace(DerivedMesh *dm, int index, MFace *face_r)
1339 {
1340         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1341         BMFace *ef;
1342         BMLoop **l;
1343
1344         if (index < 0 || index >= bmdm->tf) {
1345                 printf("error in emDM_getTessFace.\n");
1346                 return;
1347         }
1348
1349         l = bmdm->tc->looptris[index];
1350
1351         ef = l[0]->f;
1352
1353         face_r->mat_nr = (unsigned char) ef->mat_nr;
1354         face_r->flag = BM_face_flag_to_mflag(ef);
1355
1356         face_r->v1 = BM_elem_index_get(l[0]->v);
1357         face_r->v2 = BM_elem_index_get(l[1]->v);
1358         face_r->v3 = BM_elem_index_get(l[2]->v);
1359         face_r->v4 = 0;
1360
1361         test_index_face(face_r, NULL, 0, 3);
1362 }
1363
1364 static void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
1365 {
1366         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1367         BMesh *bm = bmdm->tc->bm;
1368         BMVert *eve;
1369         BMIter iter;
1370         const int has_bweight = CustomData_has_layer(&bm->vdata, CD_BWEIGHT);
1371
1372         if (bmdm->vertexCos) {
1373                 int i;
1374
1375                 BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
1376                         copy_v3_v3(vert_r->co, bmdm->vertexCos[i]);
1377                         normal_float_to_short_v3(vert_r->no, eve->no);
1378                         vert_r->flag = BM_vert_flag_to_mflag(eve);
1379
1380                         if (has_bweight) {
1381                                 vert_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->vdata, eve, CD_BWEIGHT) * 255.0f);
1382                         }
1383                         vert_r++;
1384                 }
1385         }
1386         else {
1387                 BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
1388                         copy_v3_v3(vert_r->co, eve->co);
1389                         normal_float_to_short_v3(vert_r->no, eve->no);
1390                         vert_r->flag = BM_vert_flag_to_mflag(eve);
1391
1392                         if (has_bweight) {
1393                                 vert_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->vdata, eve, CD_BWEIGHT) * 255.0f);
1394                         }
1395                         vert_r++;
1396                 }
1397         }
1398 }
1399
1400 static void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
1401 {
1402         BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
1403         BMEdge *eed;
1404         BMIter iter;
1405         const int has_bweight = CustomData_has_layer(&bm->edata, CD_BWEIGHT);
1406         const int has_crease = CustomData_has_layer(&bm->edata, CD_CREASE);
1407
1408         BM_mesh_elem_index_ensure(bm, BM_VERT);
1409
1410         BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
1411                 if (has_bweight) {
1412                         edge_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->edata, eed, CD_BWEIGHT) * 255.0f);
1413                 }
1414
1415                 if (has_crease) {
1416                         edge_r->crease = (unsigned char) (BM_elem_float_data_get(&bm->edata, eed, CD_CREASE) * 255.0f);
1417                 }
1418
1419                 edge_r->flag = BM_edge_flag_to_mflag(eed);
1420
1421                 edge_r->v1 = BM_elem_index_get(eed->v1);
1422                 edge_r->v2 = BM_elem_index_get(eed->v2);
1423
1424                 edge_r++;
1425         }
1426 }
1427
1428 static void emDM_copyTessFaceArray(DerivedMesh *dm, MFace *face_r)
1429 {
1430         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1431         BMesh *bm = bmdm->tc->bm;
1432         BMFace *ef;
1433         BMLoop **l;
1434         int i;
1435
1436         BM_mesh_elem_index_ensure(bm, BM_VERT);
1437
1438         for (i = 0; i < bmdm->tc->tottri; i++, face_r++) {
1439                 l = bmdm->tc->looptris[i];
1440                 ef = l[0]->f;
1441
1442                 face_r->mat_nr = (unsigned char) ef->mat_nr;
1443
1444                 face_r->flag = BM_face_flag_to_mflag(ef);
1445
1446                 face_r->v1 = BM_elem_index_get(l[0]->v);
1447                 face_r->v2 = BM_elem_index_get(l[1]->v);
1448                 face_r->v3 = BM_elem_index_get(l[2]->v);
1449                 face_r->v4 = 0;
1450
1451                 test_index_face(face_r, NULL, 0, 3);
1452         }
1453 }
1454
1455 static void emDM_copyLoopArray(DerivedMesh *dm, MLoop *loop_r)
1456 {
1457         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1458         BMesh *bm = bmdm->tc->bm;
1459         BMIter iter, liter;
1460         BMFace *efa;
1461         BMLoop *l;
1462
1463         BM_mesh_elem_index_ensure(bm, BM_VERT | BM_EDGE);
1464
1465         BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
1466                 BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
1467                         loop_r->v = BM_elem_index_get(l->v);
1468                         loop_r->e = BM_elem_index_get(l->e);
1469                         loop_r++;
1470                 }
1471         }
1472 }
1473
1474 static void emDM_copyPolyArray(DerivedMesh *dm, MPoly *poly_r)
1475 {
1476         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1477         BMesh *bm = bmdm->tc->bm;
1478         BMIter iter;
1479         BMFace *efa;
1480         int i;
1481
1482         i = 0;
1483         BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
1484                 poly_r->flag = BM_face_flag_to_mflag(efa);
1485                 poly_r->loopstart = i;
1486                 poly_r->totloop = efa->len;
1487                 poly_r->mat_nr = efa->mat_nr;
1488
1489                 poly_r++;
1490                 i += efa->len;
1491         }
1492 }
1493
1494 static void *emDM_getTessFaceDataArray(DerivedMesh *dm, int type)
1495 {
1496         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1497         BMesh *bm = bmdm->tc->bm;
1498         void *datalayer;
1499
1500         datalayer = DM_get_tessface_data_layer(dm, type);
1501         if (datalayer)
1502                 return datalayer;
1503
1504         /* layers are store per face for editmesh, we convert to a temporary
1505          * data layer array in the derivedmesh when these are requested */
1506         if (type == CD_MTFACE || type == CD_MCOL) {
1507                 const int type_from = (type == CD_MTFACE) ? CD_MTEXPOLY : CD_MLOOPCOL;
1508                 int index;
1509                 char *data, *bmdata;
1510                 index = CustomData_get_layer_index(&bm->pdata, type_from);
1511
1512                 if (index != -1) {
1513                         /* offset = bm->pdata.layers[index].offset; */ /* UNUSED */
1514                         const int size = CustomData_sizeof(type);
1515                         int i, j;
1516
1517                         DM_add_tessface_layer(dm, type, CD_CALLOC, NULL);
1518                         index = CustomData_get_layer_index(&dm->faceData, type);
1519                         dm->faceData.layers[index].flag |= CD_FLAG_TEMPORARY;
1520
1521                         data = datalayer = DM_get_tessface_data_layer(dm, type);
1522
1523                         if (type == CD_MTFACE) {
1524                                 for (i = 0; i < bmdm->tc->tottri; i++, data += size) {
1525                                         BMFace *efa = bmdm->tc->looptris[i][0]->f;
1526                                         bmdata = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY);
1527                                         ME_MTEXFACE_CPY(((MTFace *)data), ((MTexPoly *)bmdata));
1528                                         for (j = 0; j < 3; j++) {
1529                                                 bmdata = CustomData_bmesh_get(&bm->ldata, bmdm->tc->looptris[i][j]->head.data, CD_MLOOPUV);
1530                                                 copy_v2_v2(((MTFace *)data)->uv[j], ((MLoopUV *)bmdata)->uv);
1531                                         }
1532                                 }
1533                         }
1534                         else {
1535                                 for (i = 0; i < bmdm->tc->tottri; i++, data += size) {
1536                                         for (j = 0; j < 3; j++) {
1537                                                 bmdata = CustomData_bmesh_get(&bm->ldata, bmdm->tc->looptris[i][j]->head.data, CD_MLOOPCOL);
1538                                                 MESH_MLOOPCOL_TO_MCOL(((MLoopCol *)bmdata), (((MCol *)data) + j));
1539                                         }
1540                                 }
1541                         }
1542                 }
1543         }
1544
1545         return datalayer;
1546 }
1547
1548 static void emDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
1549 {
1550         EditDerivedBMesh *emdm = (EditDerivedBMesh *)dm;
1551         BMVert *eve;
1552         BMIter iter;
1553         int i;
1554
1555         if (emdm->vertexCos) {
1556                 BM_ITER_MESH_INDEX (eve, &iter, emdm->tc->bm, BM_VERTS_OF_MESH, i) {
1557                         copy_v3_v3(cos_r[i], emdm->vertexCos[i]);
1558                 }
1559         }
1560         else {
1561                 BM_ITER_MESH_INDEX (eve, &iter, emdm->tc->bm, BM_VERTS_OF_MESH, i) {
1562                         copy_v3_v3(cos_r[i], eve->co);
1563                 }
1564         }
1565 }
1566
1567 static void emDM_release(DerivedMesh *dm)
1568 {
1569         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1570
1571         if (DM_release(dm)) {
1572                 if (bmdm->vertexCos) {
1573                         MEM_freeN(bmdm->vertexCos);
1574                         MEM_freeN(bmdm->vertexNos);
1575                         MEM_freeN(bmdm->polyNos);
1576                 }
1577
1578                 MEM_freeN(bmdm);
1579         }
1580 }
1581
1582 static CustomData *bmDm_getVertDataLayout(DerivedMesh *dm)
1583 {
1584         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1585
1586         return &bmdm->tc->bm->vdata;
1587 }
1588
1589 static CustomData *bmDm_getEdgeDataLayout(DerivedMesh *dm)
1590 {
1591         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1592
1593         return &bmdm->tc->bm->edata;
1594 }
1595
1596 static CustomData *bmDm_getTessFaceDataLayout(DerivedMesh *dm)
1597 {
1598         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1599
1600         return &bmdm->dm.faceData;
1601 }
1602
1603 static CustomData *bmDm_getLoopDataLayout(DerivedMesh *dm)
1604 {
1605         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1606
1607         return &bmdm->tc->bm->ldata;
1608 }
1609
1610 static CustomData *bmDm_getPolyDataLayout(DerivedMesh *dm)
1611 {
1612         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1613
1614         return &bmdm->tc->bm->pdata;
1615 }
1616
1617
1618 DerivedMesh *getEditDerivedBMesh(BMEditMesh *em,
1619                                  Object *UNUSED(ob),
1620                                  float (*vertexCos)[3])
1621 {
1622         EditDerivedBMesh *bmdm = MEM_callocN(sizeof(*bmdm), __func__);
1623         BMesh *bm = em->bm;
1624
1625         bmdm->tc = em;
1626
1627         DM_init((DerivedMesh *)bmdm, DM_TYPE_EDITBMESH, em->bm->totvert,
1628                 em->bm->totedge, em->tottri, em->bm->totloop, em->bm->totface);
1629
1630         bmdm->dm.getVertCos = emDM_getVertCos;
1631         bmdm->dm.getMinMax = emDM_getMinMax;
1632
1633         bmdm->dm.getVertDataLayout = bmDm_getVertDataLayout;
1634         bmdm->dm.getEdgeDataLayout = bmDm_getEdgeDataLayout;
1635         bmdm->dm.getTessFaceDataLayout = bmDm_getTessFaceDataLayout;
1636         bmdm->dm.getLoopDataLayout = bmDm_getLoopDataLayout;
1637         bmdm->dm.getPolyDataLayout = bmDm_getPolyDataLayout;
1638
1639         bmdm->dm.getNumVerts = emDM_getNumVerts;
1640         bmdm->dm.getNumEdges = emDM_getNumEdges;
1641         bmdm->dm.getNumTessFaces = emDM_getNumTessFaces;
1642         bmdm->dm.getNumLoops = emDM_getNumLoops;
1643         bmdm->dm.getNumPolys = emDM_getNumPolys;
1644
1645         bmdm->dm.getVert = emDM_getVert;
1646         bmdm->dm.getEdge = emDM_getEdge;
1647         bmdm->dm.getTessFace = emDM_getTessFace;
1648         bmdm->dm.copyVertArray = emDM_copyVertArray;
1649         bmdm->dm.copyEdgeArray = emDM_copyEdgeArray;
1650         bmdm->dm.copyTessFaceArray = emDM_copyTessFaceArray;
1651         bmdm->dm.copyLoopArray = emDM_copyLoopArray;
1652         bmdm->dm.copyPolyArray = emDM_copyPolyArray;
1653
1654         bmdm->dm.getTessFaceDataArray = emDM_getTessFaceDataArray;
1655
1656         bmdm->dm.calcNormals = emDM_calcNormals;
1657         bmdm->dm.recalcTessellation = emDM_recalcTessellation;
1658
1659         bmdm->dm.foreachMappedVert = emDM_foreachMappedVert;
1660         bmdm->dm.foreachMappedEdge = emDM_foreachMappedEdge;
1661         bmdm->dm.foreachMappedFaceCenter = emDM_foreachMappedFaceCenter;
1662
1663         bmdm->dm.drawEdges = emDM_drawEdges;
1664         bmdm->dm.drawMappedEdges = emDM_drawMappedEdges;
1665         bmdm->dm.drawMappedEdgesInterp = emDM_drawMappedEdgesInterp;
1666         bmdm->dm.drawMappedFaces = emDM_drawMappedFaces;
1667         bmdm->dm.drawMappedFacesTex = emDM_drawMappedFacesTex;
1668         bmdm->dm.drawMappedFacesGLSL = emDM_drawMappedFacesGLSL;
1669         bmdm->dm.drawMappedFacesMat = emDM_drawMappedFacesMat;
1670         bmdm->dm.drawFacesTex = emDM_drawFacesTex;
1671         bmdm->dm.drawFacesGLSL = emDM_drawFacesGLSL;
1672         bmdm->dm.drawUVEdges = emDM_drawUVEdges;
1673
1674         bmdm->dm.release = emDM_release;
1675
1676         bmdm->vertexCos = vertexCos;
1677
1678         if (CustomData_has_layer(&bm->vdata, CD_MDEFORMVERT)) {
1679                 BMIter iter;
1680                 BMVert *eve;
1681                 int i;
1682
1683                 DM_add_vert_layer(&bmdm->dm, CD_MDEFORMVERT, CD_CALLOC, NULL);
1684
1685                 BM_ITER_MESH_INDEX (eve, &iter, bmdm->tc->bm, BM_VERTS_OF_MESH, i) {
1686                         DM_set_vert_data(&bmdm->dm, i, CD_MDEFORMVERT,
1687                                          CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MDEFORMVERT));
1688                 }
1689         }
1690
1691         if (vertexCos) {
1692                 BMFace *efa;
1693                 BMVert *eve;
1694                 BMIter fiter;
1695                 BMIter viter;
1696                 int i;
1697
1698                 BM_mesh_elem_index_ensure(bm, BM_VERT);
1699
1700                 bmdm->vertexNos = MEM_callocN(sizeof(*bmdm->vertexNos) * bm->totvert, "bmdm_vno");
1701                 bmdm->polyNos = MEM_mallocN(sizeof(*bmdm->polyNos) * bm->totface, "bmdm_pno");
1702
1703                 BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) {
1704                         BM_elem_index_set(efa, i); /* set_inline */
1705                         BM_face_normal_update_vcos(bm, efa, bmdm->polyNos[i], (float const (*)[3])vertexCos);
1706                 }
1707                 bm->elem_index_dirty &= ~BM_FACE;
1708
1709                 BM_ITER_MESH_INDEX (eve, &viter, bm, BM_VERTS_OF_MESH, i) {
1710                         float *no = bmdm->vertexNos[i];
1711                         BM_ITER_ELEM (efa, &fiter, eve, BM_FACES_OF_VERT) {
1712                                 add_v3_v3(no, bmdm->polyNos[BM_elem_index_get(efa)]);
1713                         }
1714
1715                         /* following Mesh convention; we use vertex coordinate itself
1716                          * for normal in this case */
1717                         if (normalize_v3(no) == 0.0f) {
1718                                 copy_v3_v3(no, vertexCos[i]);
1719                                 normalize_v3(no);
1720                         }
1721                 }
1722         }
1723
1724         return (DerivedMesh *)bmdm;
1725 }
1726
1727 /**
1728  * \brief Return the BMEditMesh for a given object
1729  *
1730  * \note this function assumes this is a mesh object,
1731  * don't add NULL data check here. caller must do that
1732  */
1733 BMEditMesh *BMEdit_FromObject(Object *ob)
1734 {
1735         BLI_assert(ob->type == OB_MESH);
1736         return ((Mesh *)ob->data)->edit_btmesh;
1737 }