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