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