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