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