2964914de4b6a2cd47098b6e0da0c6dd58cee3e8
[blender.git] / source / blender / blenkernel / intern / editderivedbmesh.c
1 /**
2  * $Id: editderivedbmesh.c 18571 2009-01-19 06:04:57Z joeedh $
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Tbmple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2005 Blender Foundation.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #include <string.h>
31
32 #ifdef HAVE_CONFIG_H
33 #include <config.h>
34 #endif
35
36 #include "PIL_time.h"
37
38 #include "MEM_guardedalloc.h"
39
40 #include "DNA_effect_types.h"
41 #include "DNA_mesh_types.h"
42 #include "DNA_key_types.h"
43 #include "DNA_meshdata_types.h"
44 #include "DNA_modifier_types.h"
45 #include "DNA_object_types.h"
46 #include "DNA_object_force.h"
47 #include "DNA_object_fluidsim.h" // N_T
48 #include "DNA_scene_types.h" // N_T
49 #include "DNA_texture_types.h"
50 #include "DNA_view3d_types.h"
51 #include "DNA_screen_types.h"
52 #include "DNA_space_types.h"
53 #include "DNA_particle_types.h"
54
55 #include "BLI_arithb.h"
56 #include "BLI_blenlib.h"
57 #include "BLI_editVert.h"
58 #include "BLI_edgehash.h"
59 #include "BLI_linklist.h"
60 #include "BLI_memarena.h"
61 #include "BLI_scanfill.h"
62 #include "BLI_ghash.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_utildefines.h"
80 #include "BKE_particle.h"
81 #include "BKE_tessmesh.h"
82
83 #include "BLO_sys_types.h" // for intptr_t support
84
85 #include "BIF_gl.h"
86 #include "BIF_glutil.h"
87
88 #include "GPU_draw.h"
89 #include "GPU_extensions.h"
90 #include "GPU_material.h"
91
92 #include "bmesh.h"
93
94 BMEditMesh *BMEdit_Create(BMesh *bm)
95 {
96         BMEditMesh *tm = MEM_callocN(sizeof(BMEditMesh), "tm");
97         
98         tm->bm = bm;
99
100         BMEdit_RecalcTesselation(tm);
101
102         return tm;
103 }
104
105 BMEditMesh *BMEdit_Copy(BMEditMesh *tm)
106 {
107         BMEditMesh *tm2 = MEM_callocN(sizeof(BMEditMesh), "tm2");
108         *tm2 = *tm;
109         
110         tm2->derivedCage = tm2->derivedFinal = NULL;
111         
112         tm2->looptris = NULL;
113         tm2->bm = BM_Copy_Mesh(tm->bm);
114         BMEdit_RecalcTesselation(tm2);
115
116         tm2->vert_index = NULL;
117         tm2->edge_index = NULL;
118         tm2->face_index = NULL;
119
120         return tm2;
121 }
122
123 static void BMEdit_RecalcTesselation_intern(BMEditMesh *tm)
124 {
125         BMesh *bm = tm->bm;
126         BMLoop **looptris = NULL;
127         V_DYNDECLARE(looptris);
128         BMIter iter, liter;
129         BMFace *f;
130         BMLoop *l;
131         int i = 0, j;
132         
133         if (tm->looptris) MEM_freeN(tm->looptris);
134
135         f = BMIter_New(&iter, bm, BM_FACES_OF_MESH, NULL);
136         for ( ; f; f=BMIter_Step(&iter)) {
137                 /*don't consider two-edged faces*/
138                 if (f->len < 3) continue;
139                 
140                 if (f->len <= 4) {
141                         /*triangle fan for quads.  should be recoded to
142                           just add one tri for tris, and two for quads,
143                           but this code works for now too.*/
144                         l = BMIter_New(&liter, bm, BM_LOOPS_OF_FACE, f);
145                         for (; l; l=BMIter_Step(&liter)) {
146                                 if (l == f->loopbase) continue;
147                                 if ((BMLoop*)l->head.next == f->loopbase) continue;
148
149                                 V_GROW(looptris);
150                                 V_GROW(looptris);
151                                 V_GROW(looptris);
152
153                                 looptris[i*3] = l;
154                                 looptris[i*3+1] = (BMLoop*)l->head.next;
155                                 looptris[i*3+2] = f->loopbase;
156
157                                 i += 1;
158                         }
159                 } else {
160                         /*scanfill time*/
161                         EditVert *v, *lastv=NULL, *firstv=NULL;
162                         EditEdge *e;
163                         EditFace *efa;
164
165                         l = BMIter_New(&liter, bm, BM_LOOPS_OF_FACE, f);
166                         for (j=0; l; l=BMIter_Step(&liter), j++) {
167                                 /*mark order*/
168                                 l->head.eflag2 = j;
169
170                                 v = BLI_addfillvert(l->v->co);
171                                 v->tmp.p = l;
172                                 
173                                 if (lastv) {
174                                         e = BLI_addfilledge(lastv, v);
175                                 }
176
177                                 lastv = v;
178                                 if (firstv==NULL) firstv = v;
179                         }
180
181                         /*complete the loop*/
182                         BLI_addfilledge(firstv, v);
183
184                         BLI_edgefill(0, 0);
185                         
186                         for (efa = fillfacebase.first; efa; efa=efa->next) {
187                                 V_GROW(looptris);
188                                 V_GROW(looptris);
189                                 V_GROW(looptris);
190                                 
191                                 looptris[i*3] = efa->v1->tmp.p;
192                                 looptris[i*3+1] = efa->v2->tmp.p;
193                                 looptris[i*3+2] = efa->v3->tmp.p;
194
195                                 if (looptris[i*3]->head.eflag2 > looptris[i*3+1]->head.eflag2);
196                                         SWAP(BMLoop*, looptris[i*3], looptris[i*3+1]);
197                                 if (looptris[i*3+1]->head.eflag2 > looptris[i*3+2]->head.eflag2);
198                                         SWAP(BMLoop*, looptris[i*3+1], looptris[i*3+2]);
199                                 if (looptris[i*3]->head.eflag2 > looptris[i*3+1]->head.eflag2);
200                                         SWAP(BMLoop*, looptris[i*3], looptris[i*3+1]);
201
202                                 i += 1;
203                         }
204                         BLI_end_edgefill();
205                 }
206         }
207
208         tm->tottri = i;
209         tm->looptris = looptris;
210 }
211
212 void BMEdit_RecalcTesselation(BMEditMesh *tm)
213 {
214         BMEdit_RecalcTesselation_intern(tm);
215
216         if (tm->derivedFinal && tm->derivedFinal == tm->derivedCage) {
217                 if (tm->derivedFinal->recalcTesselation) 
218                         tm->derivedFinal->recalcTesselation(tm->derivedFinal);
219         } else if (tm->derivedFinal) {
220                 if (tm->derivedCage->recalcTesselation) 
221                         tm->derivedCage->recalcTesselation(tm->derivedCage);
222                 if (tm->derivedFinal->recalcTesselation) 
223                         tm->derivedFinal->recalcTesselation(tm->derivedFinal);
224         }
225 }
226
227 /*does not free the BMEditMesh struct itself*/
228 void BMEdit_Free(BMEditMesh *em)
229 {
230         if(em->derivedFinal) {
231                 if (em->derivedFinal!=em->derivedCage) {
232                         em->derivedFinal->needsFree= 1;
233                         em->derivedFinal->release(em->derivedFinal);
234                 }
235                 em->derivedFinal= NULL;
236         }
237         if(em->derivedCage) {
238                 em->derivedCage->needsFree= 1;
239                 em->derivedCage->release(em->derivedCage);
240                 em->derivedCage= NULL;
241         }
242
243         em->retopo_paint_data= NULL;
244
245         if (em->looptris) MEM_freeN(em->looptris);
246
247         if (em->vert_index) MEM_freeN(em->vert_index);
248         if (em->edge_index) MEM_freeN(em->edge_index);
249         if (em->face_index) MEM_freeN(em->face_index);
250
251         BM_Free_Mesh(em->bm);
252 }
253
254
255 /*
256 ok, basic design:
257
258 the bmesh derivedmesh exposes the mesh as triangles.  it stores pointers
259 to three loops per triangle.  the derivedmesh stores a cache of tesselations
260 for each face.  this cache will smartly update as needed (though at first
261 it'll simply be more brute force).  keeping track of face/edge counts may
262 be a small problbm.
263
264 this won't be the most efficient thing, considering that internal edges and
265 faces of tesselations are exposed.  looking up an edge by index in particular
266 is likely to be a little slow.
267 */
268
269 typedef struct EditDerivedBMesh {
270         DerivedMesh dm;
271
272         Object *ob;
273         BMEditMesh *tc;
274
275         float (*vertexCos)[3];
276         float (*vertexNos)[3];
277         float (*faceNos)[3];
278
279         /*lookup caches; these are rebuilt on dm->RecalcTesselation()
280           (or when the derivedmesh is created, of course)*/
281         GHash *vhash, *ehash, *fhash;
282         BMVert **vtable;
283         BMEdge **etable;
284         BMFace **ftable;
285
286         /*private variables, for number of verts/edges/faces
287           within the above hash/table members*/
288         int tv, te, tf;
289 } EditDerivedBMesh;
290
291 static void bmdm_recalc_lookups(EditDerivedBMesh *bmdm)
292 {
293         BMIter iter;
294         BMHeader *h;
295         int a, i, iters[3] = {BM_VERTS_OF_MESH, BM_EDGES_OF_MESH, BM_FACES_OF_MESH};
296         
297         bmdm->tv = bmdm->tc->bm->totvert;
298         bmdm->te = bmdm->tc->bm->totedge;
299         bmdm->tf = bmdm->tc->bm->totface;
300
301         if (bmdm->vhash) BLI_ghash_free(bmdm->vhash, NULL, NULL);
302         if (bmdm->ehash) BLI_ghash_free(bmdm->ehash, NULL, NULL);
303         if (bmdm->fhash) BLI_ghash_free(bmdm->fhash, NULL, NULL);
304
305         bmdm->vhash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
306         bmdm->ehash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
307         bmdm->fhash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
308         
309         if (bmdm->vtable) MEM_freeN(bmdm->vtable);
310         if (bmdm->etable) MEM_freeN(bmdm->etable);
311         if (bmdm->ftable) MEM_freeN(bmdm->ftable);
312         
313         bmdm->vtable = MEM_mallocN(sizeof(void**)*bmdm->tc->bm->totvert, "bmdm->vtable");
314         bmdm->etable = MEM_mallocN(sizeof(void**)*bmdm->tc->bm->totedge, "bmdm->etable");
315         bmdm->ftable = MEM_mallocN(sizeof(void**)*bmdm->tc->bm->totface, "bmdm->ftable");
316         
317         for (a=0; a<3; a++) {
318                 h = BMIter_New(&iter, bmdm->tc->bm, iters[a], NULL);
319                 for (i=0; h; h=BMIter_Step(&iter), i++) {
320                         switch (a) {
321                                 case 0:
322                                         bmdm->vtable[i] = (BMVert*) h;
323                                         BLI_ghash_insert(bmdm->vhash, h, SET_INT_IN_POINTER(i));
324                                         break;
325                                 case 1:
326                                         bmdm->etable[i] = (BMEdge*) h;
327                                         BLI_ghash_insert(bmdm->ehash, h, SET_INT_IN_POINTER(i));
328                                         break;
329                                 case 2:
330                                         bmdm->ftable[i] = (BMFace*) h;
331                                         BLI_ghash_insert(bmdm->fhash, h, SET_INT_IN_POINTER(i));
332                                         break;
333
334                         }
335                 }
336         }
337 }
338
339 static void bmDM_recalcTesselation(DerivedMesh *dm)
340 {
341         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
342
343         BMEdit_RecalcTesselation_intern(bmdm->tc);
344         bmdm_recalc_lookups(bmdm);
345 }
346
347 static void bmDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData)
348 {
349         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
350         BMVert *eve;
351         BMIter iter;
352         int i;
353         
354         eve = BMIter_New(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
355         for (i=0; eve; i++, eve=BMIter_Step(&iter)) {
356                 if (bmdm->vertexCos) {
357                         func(userData, i, bmdm->vertexCos[i], bmdm->vertexNos[i], NULL);
358                 } else {
359                         func(userData, i, eve->co, eve->no, NULL);
360                 }
361         }
362 }
363 static void bmDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData)
364 {
365         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
366         BMEdge *eed;
367         BMIter iter;
368         int i;
369         
370         if (bmdm->vertexCos) {
371                 BMVert *eve;
372                 BMIter viter;
373
374                 eve = BMIter_New(&viter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
375                 for (i=0; eve; eve=BMIter_Step(&viter), i++) {
376                         BMINDEX_SET(eve, i);
377                 }
378
379                 eed = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
380                 for(i=0; eed; i++,eed=BMIter_Step(&iter))
381                         func(userData, i, 
382                              bmdm->vertexCos[BMINDEX_GET(eve)], 
383                              bmdm->vertexCos[BMINDEX_GET(eve)]);
384         } else {
385                 eed = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
386                 for(i=0; eed; i++,eed=BMIter_Step(&iter))
387                         func(userData, i, eed->v1->co, eed->v2->co);
388         }
389
390 }
391
392 static void bmDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) 
393 {
394         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
395         BMEdge *eed;
396         BMIter iter;
397         int i;
398         
399         if (bmdm->vertexCos) {
400                 BMVert *eve;
401                 BMIter viter;
402
403                 eve = BMIter_New(&viter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
404                 for (i=0; eve; eve=BMIter_Step(&viter)) {
405                         BMINDEX_SET(eve, i);
406                 }
407
408                 glBegin(GL_LINES);
409                 eed = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
410                 for(i=0; eed; i++,eed=BMIter_Step(&iter)) {
411                         if(!setDrawOptions || setDrawOptions(userData, i)) {
412                                 glVertex3fv(bmdm->vertexCos[BMINDEX_GET(eed->v1)]);
413                                 glVertex3fv(bmdm->vertexCos[BMINDEX_GET(eed->v2)]);
414                         }
415                 }
416                 glEnd();
417
418         } else {
419                 glBegin(GL_LINES);
420                 eed = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
421                 for(i=0; eed; i++,eed=BMIter_Step(&iter)) {
422                         if(!setDrawOptions || setDrawOptions(userData, i)) {
423                                 glVertex3fv(eed->v1->co);
424                                 glVertex3fv(eed->v2->co);
425                         }
426                 }
427                 glEnd();
428         }
429 }
430
431 static void bmDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
432 {
433         bmDM_drawMappedEdges(dm, NULL, NULL);
434 }
435
436 static void bmDM_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) 
437 {
438         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
439         BMEdge *eed;
440         BMIter iter;
441         int i;
442
443         if (bmdm->vertexCos) {
444                 BMVert *eve;
445
446                 eve = BMIter_New(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
447                 for (i=0; eve; eve=BMIter_Step(&iter), i++)
448                         BMINDEX_SET(eve, i);
449
450                 glBegin(GL_LINES);
451                 eed = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
452                 for(i=0; eed; i++,eed=BMIter_Step(&iter)) {
453                         if(!setDrawOptions || setDrawOptions(userData, i)) {
454                                 setDrawInterpOptions(userData, i, 0.0);
455                                 glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(eed->v1)]);
456                                 setDrawInterpOptions(userData, i, 1.0);
457                                 glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(eed->v2)]);
458                         }
459                 }
460                 glEnd();
461         } else {
462                 glBegin(GL_LINES);
463                 eed = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
464                 for(i=0; eed; i++,eed=BMIter_Step(&iter)) {
465                         if(!setDrawOptions || setDrawOptions(userData, i)) {
466                                 setDrawInterpOptions(userData, i, 0.0);
467                                 glVertex3fv(eed->v1->co);
468                                 setDrawInterpOptions(userData, i, 1.0);
469                                 glVertex3fv(eed->v2->co);
470                         }
471                 }
472                 glEnd();
473         }
474 }
475
476 static void bmDM_drawUVEdges(DerivedMesh *dm)
477 {
478 #if 0
479         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
480         BMFace *efa;
481         MTFace *tf;
482
483         glBegin(GL_LINES);
484         for(efa= bmdm->tc->bm->faces.first; efa; efa= efa->next) {
485                 tf = CustomData_bm_get(&bmdm->tc->bm->pdata, efa->data, CD_MTFACE);
486
487                 if(tf && !(efa->h)) {
488                         glVertex2fv(tf->uv[0]);
489                         glVertex2fv(tf->uv[1]);
490
491                         glVertex2fv(tf->uv[1]);
492                         glVertex2fv(tf->uv[2]);
493
494                         if (!efa->v4) {
495                                 glVertex2fv(tf->uv[2]);
496                                 glVertex2fv(tf->uv[0]);
497                         } else {
498                                 glVertex2fv(tf->uv[2]);
499                                 glVertex2fv(tf->uv[3]);
500                                 glVertex2fv(tf->uv[3]);
501                                 glVertex2fv(tf->uv[0]);
502                         }
503                 }
504         }
505         glEnd();
506 #endif
507 }
508
509 static void bmDM__calcFaceCent(BMesh *bm, BMFace *efa, float cent[3],
510                                float (*vertexCos)[3])
511 {
512         BMIter iter;
513         BMLoop *l;
514         int tot = 0;
515         
516         cent[0] = cent[1] = cent[2] = 0.0f;
517         
518         /*simple (and stupid) median (average) based method :/ */
519
520         l = BMIter_New(&iter, bm, BM_LOOPS_OF_FACE, efa);
521         for (; l; l=BMIter_Step(&iter)) {
522                 VECADD(cent, cent, l->v->co);
523                 tot++;
524         }
525
526         if (tot==0) return;
527         VECMUL(cent, 1.0f/(float)tot);
528 }
529
530 static void bmDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData)
531 {
532         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
533         BMVert *eve;
534         BMFace *efa;
535         BMIter iter;
536         float cent[3];
537         int i;
538
539         if (bmdm->vertexCos) {
540                 eve = BMIter_New(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
541                 for (i=0; eve; eve=BMIter_Step(&iter));
542                         BMINDEX_SET(eve, i);
543         }
544
545         efa = BMIter_New(&iter, bmdm->tc->bm, BM_FACES_OF_MESH, NULL);
546         for (i=0; efa; efa=BMIter_Step(&iter), i++) {
547                 bmDM__calcFaceCent(bmdm->tc->bm, efa, cent, bmdm->vertexCos);
548                 func(userData, i, cent, bmdm->vertexCos?bmdm->faceNos[i]:efa->no);
549         }
550 }
551
552 static void bmDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors)
553 {
554         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
555         BMFace *efa;
556         BMIter iter;
557         int i, draw;
558
559         if (bmdm->vertexCos) {
560                 BMVert *eve;
561                 
562                 eve = BMIter_New(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
563                 for (i=0; eve; eve=BMIter_Step(&iter))
564                         BMINDEX_SET(eve, i);
565
566                 efa = BMIter_New(&iter, bmdm->tc->bm, BM_FACES_OF_MESH, NULL);
567                 for (i=0; efa; efa=BMIter_Step(&iter), i++)
568                         BMINDEX_SET(efa, i);
569
570                 for (i=0; i<bmdm->tc->tottri; i++) {
571                         BMLoop **l = bmdm->tc->looptris[i];
572                         int drawSmooth;
573                         
574                         drawSmooth = (efa->head.flag & BM_SMOOTH);
575                         efa = l[0]->f;
576
577                         draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, BMINDEX_GET(efa), &drawSmooth);
578                         if(draw) {
579                                 if (draw==2) { /* enabled with stipple */
580                                         glEnable(GL_POLYGON_STIPPLE);
581                                         glPolygonStipple(stipple_quarttone);
582                                 }
583                                 
584                                 glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
585
586                                 glBegin(GL_TRIANGLES);
587
588                                 if (!drawSmooth) {
589                                         glNormal3fv(efa->no);
590                                         glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(l[0]->v)]);
591                                         glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(l[1]->v)]);
592                                         glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(l[2]->v)]);
593                                 } else {
594                                         glNormal3fv(bmdm->vertexNos[(int) BMINDEX_GET(l[0]->v)]);
595                                         glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(l[0]->v)]);
596                                         glNormal3fv(bmdm->vertexNos[(int) BMINDEX_GET(l[1]->v)]);
597                                         glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(l[1]->v)]);
598                                         glNormal3fv(bmdm->vertexNos[(int) BMINDEX_GET(l[2]->v)]);
599                                         glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(l[2]->v)]);
600                                 }
601                                 glEnd();
602
603                                 if (draw==2)
604                                         glDisable(GL_POLYGON_STIPPLE);
605                         }
606                 }
607         } else {
608                 efa = BMIter_New(&iter, bmdm->tc->bm, BM_FACES_OF_MESH, NULL);
609                 for (i=0; efa; efa=BMIter_Step(&iter), i++)
610                         BMINDEX_SET(efa, i);
611
612                 for (i=0; i<bmdm->tc->tottri; i++) {
613                         BMLoop **l = bmdm->tc->looptris[i];
614                         int drawSmooth;
615
616                         efa = l[0]->f;
617
618                         drawSmooth = (efa->head.flag & BM_SMOOTH);
619                         
620                         draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, BMINDEX_GET(efa), &drawSmooth);
621                         if(draw) {
622                                 if (draw==2) { /* enabled with stipple */
623                                         glEnable(GL_POLYGON_STIPPLE);
624                                         glPolygonStipple(stipple_quarttone);
625                                 }
626                                 glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
627                                 
628                                 glBegin(GL_TRIANGLES);
629                                 if (!drawSmooth) {
630                                         glNormal3fv(efa->no);
631                                         glVertex3fv(l[0]->v->co);
632                                         glVertex3fv(l[1]->v->co);
633                                         glVertex3fv(l[2]->v->co);
634                                 } else {
635                                         glNormal3fv(l[0]->v->no);
636                                         glVertex3fv(l[0]->v->co);
637                                         glNormal3fv(l[1]->v->no);
638                                         glVertex3fv(l[1]->v->co);
639                                         glNormal3fv(l[2]->v->no);
640                                         glVertex3fv(l[2]->v->co);
641                                 }
642                                 glEnd();
643                                 
644                                 if (draw==2)
645                                         glDisable(GL_POLYGON_STIPPLE);
646                         }
647                 }
648         }
649 }
650
651 static void bmDM_drawFacesTex_common(DerivedMesh *dm,
652                int (*drawParams)(MTFace *tface, MCol *mcol, int matnr),
653                int (*drawParamsMapped)(void *userData, int index),
654                void *userData) 
655 {
656 #if 0
657         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
658         BMesh *bm= bmdm->tc->bm;
659         float (*vertexCos)[3]= bmdm->vertexCos;
660         float (*vertexNos)[3]= bmdm->vertexNos;
661         BMFace *efa;
662         BMIter iter;
663         int i;
664
665         /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
666         glShadeModel(GL_SMOOTH);
667         
668         if (vertexCos) {
669                 BMVert *eve;
670
671                 for (i=0,eve=bm->verts.first; eve; eve= eve->next)
672                         BMINDEX_SET(eve, i++);
673
674                 for (i=0,efa= bm->faces.first; efa; i++,efa= efa->next) {
675                         MTFace *tf= CustomData_bm_get(&bm->pdata, efa->data, CD_MTFACE);
676                         MCol *mcol= CustomData_bm_get(&bm->pdata, efa->data, CD_MCOL);
677                         unsigned char *cp= NULL;
678                         int drawSmooth= (efa->flag & ME_SMOOTH);
679                         int flag;
680
681                         if(drawParams)
682                                 flag= drawParams(tf, mcol, efa->mat_nr);
683                         else if(drawParamsMapped)
684                                 flag= drawParamsMapped(userData, i);
685                         else
686                                 flag= 1;
687
688                         if(flag != 0) { /* flag 0 == the face is hidden or invisible */
689                                 
690                                 /* we always want smooth here since otherwise vertex colors dont interpolate */
691                                 if (mcol) {
692                                         if (flag==1) {
693                                                 cp= (unsigned char*)mcol;
694                                         }
695                                 } else {
696                                         glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
697                                 } 
698                                 
699                                 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
700                                 if (!drawSmooth) {
701                                         glNormal3fv(bmdm->faceNos[i]);
702
703                                         if(tf) glTexCoord2fv(tf->uv[0]);
704                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
705                                         glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
706
707                                         if(tf) glTexCoord2fv(tf->uv[1]);
708                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
709                                         glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
710
711                                         if(tf) glTexCoord2fv(tf->uv[2]);
712                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
713                                         glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
714
715                                         if(efa->v4) {
716                                                 if(tf) glTexCoord2fv(tf->uv[3]);
717                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
718                                                 glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
719                                         }
720                                 } else {
721                                         if(tf) glTexCoord2fv(tf->uv[0]);
722                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
723                                         glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
724                                         glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
725
726                                         if(tf) glTexCoord2fv(tf->uv[1]);
727                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
728                                         glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
729                                         glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
730
731                                         if(tf) glTexCoord2fv(tf->uv[2]);
732                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
733                                         glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
734                                         glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
735
736                                         if(efa->v4) {
737                                                 if(tf) glTexCoord2fv(tf->uv[3]);
738                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
739                                                 glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
740                                                 glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
741                                         }
742                                 }
743                                 glEnd();
744                         }
745                 }
746         } else {
747                 for (i=0,efa= bm->faces.first; efa; i++,efa= efa->next) {
748                         MTFace *tf= CustomData_bm_get(&bm->pdata, efa->data, CD_MTFACE);
749                         MCol *mcol= CustomData_bm_get(&bm->pdata, efa->data, CD_MCOL);
750                         unsigned char *cp= NULL;
751                         int drawSmooth= (efa->flag & ME_SMOOTH);
752                         int flag;
753
754                         if(drawParams)
755                                 flag= drawParams(tf, mcol, efa->mat_nr);
756                         else if(drawParamsMapped)
757                                 flag= drawParamsMapped(userData, i);
758                         else
759                                 flag= 1;
760
761                         if(flag != 0) { /* flag 0 == the face is hidden or invisible */
762                                 /* we always want smooth here since otherwise vertex colors dont interpolate */
763                                 if (mcol) {
764                                         if (flag==1) {
765                                                 cp= (unsigned char*)mcol;
766                                         }
767                                 } else {
768                                         glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
769                                 } 
770
771                                 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
772                                 if (!drawSmooth) {
773                                         glNormal3fv(efa->n);
774
775                                         if(tf) glTexCoord2fv(tf->uv[0]);
776                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
777                                         glVertex3fv(efa->v1->co);
778
779                                         if(tf) glTexCoord2fv(tf->uv[1]);
780                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
781                                         glVertex3fv(efa->v2->co);
782
783                                         if(tf) glTexCoord2fv(tf->uv[2]);
784                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
785                                         glVertex3fv(efa->v3->co);
786
787                                         if(efa->v4) {
788                                                 if(tf) glTexCoord2fv(tf->uv[3]);
789                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
790                                                 glVertex3fv(efa->v4->co);
791                                         }
792                                 } else {
793                                         if(tf) glTexCoord2fv(tf->uv[0]);
794                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
795                                         glNormal3fv(efa->v1->no);
796                                         glVertex3fv(efa->v1->co);
797
798                                         if(tf) glTexCoord2fv(tf->uv[1]);
799                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
800                                         glNormal3fv(efa->v2->no);
801                                         glVertex3fv(efa->v2->co);
802
803                                         if(tf) glTexCoord2fv(tf->uv[2]);
804                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
805                                         glNormal3fv(efa->v3->no);
806                                         glVertex3fv(efa->v3->co);
807
808                                         if(efa->v4) {
809                                                 if(tf) glTexCoord2fv(tf->uv[3]);
810                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
811                                                 glNormal3fv(efa->v4->no);
812                                                 glVertex3fv(efa->v4->co);
813                                         }
814                                 }
815                                 glEnd();
816                         }
817                 }
818         }
819 #endif
820 }
821
822 static void bmDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr))
823 {
824         bmDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
825 }
826
827 static void bmDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
828 {
829         bmDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
830 }
831
832 static void bmDM_drawMappedFacesGLSL(DerivedMesh *dm,
833                int (*setMaterial)(int, void *attribs),
834                int (*setDrawOptions)(void *userData, int index), void *userData) 
835 {
836 #if 0
837         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
838         BMesh *bm= bmdm->tc->bm;
839         float (*vertexCos)[3]= bmdm->vertexCos;
840         float (*vertexNos)[3]= bmdm->vertexNos;
841         BMVert *eve;
842         BMFace *efa;
843         DMVertexAttribs attribs;
844         GPUVertexAttribs gattribs;
845         MTFace *tf;
846         int transp, new_transp, orig_transp, tfoffset;
847         int i, b, matnr, new_matnr, dodraw, layer;
848
849         dodraw = 0;
850         matnr = -1;
851
852         transp = GPU_get_material_blend_mode();
853         orig_transp = transp;
854         layer = CustomData_get_layer_index(&bm->pdata, CD_MTFACE);
855         tfoffset = (layer == -1)? -1: bm->pdata.layers[layer].offset;
856
857         memset(&attribs, 0, sizeof(attribs));
858
859         /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
860         glShadeModel(GL_SMOOTH);
861
862         for (i=0,eve=bm->verts.first; eve; eve= eve->next)
863                 BMINDEX_SET(eve, i++);
864
865 #define PASSATTRIB(efa, eve, vert) {                                                                                    \
866         if(attribs.totorco) {                                                                                                           \
867                 float *orco = attribs.orco.array[BMINDEX_GET(eve)];                                                     \
868                 glVertexAttrib3fvARB(attribs.orco.glIndex, orco);                                               \
869         }                                                                                                                                                       \
870         for(b = 0; b < attribs.tottface; b++) {                                                                         \
871                 MTFace *_tf = (MTFace*)((char*)efa->data + attribs.tface[b].bmOffset);  \
872                 glVertexAttrib2fvARB(attribs.tface[b].glIndex, _tf->uv[vert]);                  \
873         }                                                                                                                                                       \
874         for(b = 0; b < attribs.totmcol; b++) {                                                                          \
875                 MCol *cp = (MCol*)((char*)efa->data + attribs.mcol[b].bmOffset);                \
876                 GLubyte col[4];                                                                                                                 \
877                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;                             \
878                 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col);                                    \
879         }                                                                                                                                                       \
880         if(attribs.tottang) {                                                                                                           \
881                 float *tang = attribs.tang.array[i*4 + vert];                                                   \
882                 glVertexAttrib3fvARB(attribs.tang.glIndex, tang);                                               \
883         }                                                                                                                                                       \
884 }
885
886         for (i=0,efa= bm->faces.first; efa; i++,efa= efa->next) {
887                 int drawSmooth= (efa->flag & ME_SMOOTH);
888
889                 if(setDrawOptions && !setDrawOptions(userData, i))
890                         continue;
891
892                 new_matnr = efa->mat_nr + 1;
893                 if(new_matnr != matnr) {
894                         dodraw = setMaterial(matnr = new_matnr, &gattribs);
895                         if(dodraw)
896                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
897                 }
898
899                 if(tfoffset != -1) {
900                         tf = (MTFace*)((char*)efa->data)+tfoffset;
901                         new_transp = tf->transp;
902
903                         if(new_transp != transp) {
904                                 if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
905                                         GPU_set_material_blend_mode(orig_transp);
906                                 else
907                                         GPU_set_material_blend_mode(new_transp);
908                                 transp = new_transp;
909                         }
910                 }
911
912                 if(dodraw) {
913                         glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
914                         if (!drawSmooth) {
915                                 if(vertexCos) glNormal3fv(bmdm->faceNos[i]);
916                                 else glNormal3fv(efa->n);
917
918                                 PASSATTRIB(efa, efa->v1, 0);
919                                 if(vertexCos) glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
920                                 else glVertex3fv(efa->v1->co);
921
922                                 PASSATTRIB(efa, efa->v2, 1);
923                                 if(vertexCos) glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
924                                 else glVertex3fv(efa->v2->co);
925
926                                 PASSATTRIB(efa, efa->v3, 2);
927                                 if(vertexCos) glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
928                                 else glVertex3fv(efa->v3->co);
929
930                                 if(efa->v4) {
931                                         PASSATTRIB(efa, efa->v4, 3);
932                                         if(vertexCos) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
933                                         else glVertex3fv(efa->v4->co);
934                                 }
935                         } else {
936                                 PASSATTRIB(efa, efa->v1, 0);
937                                 if(vertexCos) {
938                                         glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
939                                         glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
940                                 }
941                                 else {
942                                         glNormal3fv(efa->v1->no);
943                                         glVertex3fv(efa->v1->co);
944                                 }
945
946                                 PASSATTRIB(efa, efa->v2, 1);
947                                 if(vertexCos) {
948                                         glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
949                                         glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
950                                 }
951                                 else {
952                                         glNormal3fv(efa->v2->no);
953                                         glVertex3fv(efa->v2->co);
954                                 }
955
956                                 PASSATTRIB(efa, efa->v3, 2);
957                                 if(vertexCos) {
958                                         glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
959                                         glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
960                                 }
961                                 else {
962                                         glNormal3fv(efa->v3->no);
963                                         glVertex3fv(efa->v3->co);
964                                 }
965
966                                 if(efa->v4) {
967                                         PASSATTRIB(efa, efa->v4, 3);
968                                         if(vertexCos) {
969                                                 glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
970                                                 glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
971                                         }
972                                         else {
973                                                 glNormal3fv(efa->v4->no);
974                                                 glVertex3fv(efa->v4->co);
975                                         }
976                                 }
977                         }
978                         glEnd();
979                 }
980         }
981 #endif
982 }
983
984 static void bmDM_drawFacesGLSL(DerivedMesh *dm,
985                int (*setMaterial)(int, void *attribs))
986 {
987         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
988 }
989
990 static void bmDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
991 {
992         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
993         BMVert *eve;
994         BMIter iter;
995         int i;
996
997         if (bmdm->tc->bm->verts.first) {
998                 eve = BMIter_New(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
999                 for (i=0; eve; eve=BMIter_Step(&iter), i++) {
1000                         if (bmdm->vertexCos) {
1001                                 DO_MINMAX(bmdm->vertexCos[i], min_r, max_r);
1002                         } else {
1003                                 DO_MINMAX(eve->co, min_r, max_r);
1004                         }
1005                 }
1006         } else {
1007                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
1008         }
1009 }
1010 static int bmDM_getNumVerts(DerivedMesh *dm)
1011 {
1012         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1013
1014         return bmdm->tc->bm->totvert;
1015 }
1016
1017 static int bmDM_getNumEdges(DerivedMesh *dm)
1018 {
1019         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1020
1021         return bmdm->tc->bm->totedge;
1022 }
1023
1024 static int bmDM_getNumTessFaces(DerivedMesh *dm)
1025 {
1026         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1027         
1028         return bmdm->tc->tottri;
1029 }
1030
1031 static int bmDM_getNumFaces(DerivedMesh *dm)
1032 {
1033         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1034         
1035         return bmdm->tc->bm->totface;
1036 }
1037
1038 static int bmvert_to_mvert(BMVert *ev, MVert *vert_r)
1039 {
1040         VECCOPY(vert_r->co, ev->co);
1041
1042         vert_r->no[0] = (short)(ev->no[0] * 32767.0f);
1043         vert_r->no[1] = (short)(ev->no[1] * 32767.0f);
1044         vert_r->no[2] = (short)(ev->no[2] * 32767.0f);
1045
1046         /* TODO what to do with vert_r->flag and vert_r->mat_nr? */
1047         vert_r->flag = BMFlags_To_MEFlags(ev);
1048         vert_r->mat_nr = 0;
1049         vert_r->bweight = (unsigned char) (ev->bweight*255.0f);
1050 }
1051
1052 static void bmDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
1053 {
1054         BMVert *ev;
1055         BMIter iter;
1056         int i;
1057
1058         if (index < 0 || index >= ((EditDerivedBMesh *)dm)->tv) {
1059                 printf("error in bmDM_getVert.\n");
1060                 return;
1061         }
1062
1063         ev = ((EditDerivedBMesh *)dm)->vtable[index];
1064         bmvert_to_mvert(ev, vert_r);
1065 }
1066
1067 static void bmDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
1068 {
1069         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1070         BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
1071         BMEdge *e;
1072         BMVert *ev, *v1, *v2;
1073         BMIter iter;
1074         int i;
1075
1076         if (index < 0 || index >= ((EditDerivedBMesh *)dm)->te) {
1077                 printf("error in bmDM_getEdge.\n");
1078                 return;
1079         }
1080
1081         e = bmdm->etable[index];
1082
1083         edge_r->crease = (unsigned char) (e->crease*255.0f);
1084         edge_r->bweight = (unsigned char) (e->bweight*255.0f);
1085         /* TODO what to do with edge_r->flag? */
1086         edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER;
1087         edge_r->flag |= BMFlags_To_MEFlags(e);
1088 #if 0
1089         /* this needs setup of f2 field */
1090         if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE;
1091 #endif
1092         
1093         edge_r->v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(bmdm->vhash, e->v1));
1094         edge_r->v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(bmdm->vhash, e->v2));
1095 }
1096
1097 static void bmDM_getTessFace(DerivedMesh *dm, int index, MFace *face_r)
1098 {
1099         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1100         BMesh *bm = bmdm->tc->bm;
1101         BMFace *ef;
1102         BMIter iter;
1103         BMLoop **l;
1104         int i;
1105         
1106         if (index < 0 || index >= ((EditDerivedBMesh *)dm)->tf) {
1107                 printf("error in bmDM_getTessFace.\n");
1108                 return;
1109         }
1110
1111         l = ((EditDerivedBMesh *)dm)->tc->looptris[index];
1112
1113         ef = l[0]->f;
1114
1115         face_r->mat_nr = (unsigned char) ef->mat_nr;
1116         face_r->flag = BMFlags_To_MEFlags(ef);
1117
1118         face_r->v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(bmdm->vhash, l[0]->v));
1119         face_r->v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(bmdm->vhash, l[1]->v));
1120         face_r->v3 = GET_INT_FROM_POINTER(BLI_ghash_lookup(bmdm->vhash, l[2]->v));
1121         face_r->v4 = 0;
1122
1123         test_index_face(face_r, NULL, 0, 3);
1124 }
1125
1126 static void bmDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
1127 {
1128         BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
1129         BMVert *ev;
1130         BMIter iter;
1131
1132         ev = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
1133         for( ; ev; ev = BMIter_Step(&iter), ++vert_r) {
1134                 VECCOPY(vert_r->co, ev->co);
1135
1136                 vert_r->no[0] = (short) (ev->no[0] * 32767.0);
1137                 vert_r->no[1] = (short) (ev->no[1] * 32767.0);
1138                 vert_r->no[2] = (short) (ev->no[2] * 32767.0);
1139
1140                 /* TODO what to do with vert_r->flag and vert_r->mat_nr? */
1141                 vert_r->mat_nr = 0;
1142                 vert_r->flag = BMFlags_To_MEFlags(ev);
1143                 vert_r->bweight = (unsigned char) (ev->bweight*255.0f);
1144         }
1145 }
1146
1147 static void bmDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
1148 {
1149         BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
1150         BMEdge *ee;
1151         BMIter iter;
1152         BMVert *ev;
1153         int i;
1154
1155         /* store vertex indices in tmp union */
1156         ev = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
1157         for (i=0; ev; ev=BMIter_Step(&iter), i++)
1158                 BMINDEX_SET(ev, i);
1159
1160         ee = BMIter_New(&iter, bm, BM_EDGES_OF_MESH, NULL);
1161         for( ; ee; ee=BMIter_Step(&iter)) {
1162                 edge_r->crease = (unsigned char) (ee->crease*255.0f);
1163                 edge_r->bweight = (unsigned char) (ee->bweight*255.0f);
1164                 /* TODO what to do with edge_r->flag? */
1165                 edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER;
1166                 if (ee->head.flag & BM_SEAM) edge_r->flag |= ME_SEAM;
1167                 if (ee->head.flag & BM_SHARP) edge_r->flag |= ME_SHARP;
1168 #if 0
1169                 /* this needs setup of f2 field */
1170                 if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE;
1171 #endif
1172
1173                 edge_r->v1 = (int)BMINDEX_GET(ee->v1);
1174                 edge_r->v2 = (int)BMINDEX_GET(ee->v2);
1175         }
1176 }
1177
1178 static void bmDM_copyFaceArray(DerivedMesh *dm, MFace *face_r)
1179 {
1180         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1181         BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
1182         BMFace *ef;
1183         BMVert *ev;
1184         BMIter iter;
1185         BMLoop **l;
1186         int i;
1187
1188         /* store vertexes indices in tmp union */
1189         ev = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
1190         for (i=0; ev; ev=BMIter_Step(&iter), i++)
1191                 BMINDEX_SET(ev, i);
1192
1193         for (i=0; i<bmdm->tc->tottri; i++) {
1194                 l = bmdm->tc->looptris[i];
1195                 ef = l[0]->f;
1196
1197                 face_r->mat_nr = (unsigned char) ef->mat_nr;
1198
1199                 /*HACK/TODO: need to convert this*/
1200                 face_r->flag = ef->head.flag;
1201
1202                 face_r->v1 = BMINDEX_GET(l[0]->v);
1203                 face_r->v2 = BMINDEX_GET(l[1]->v);
1204                 face_r->v3 = BMINDEX_GET(l[2]->v);
1205                 face_r->v4 = 0;
1206
1207                 test_index_face(face_r, NULL, 0, 3);
1208         }
1209 }
1210
1211 static void *bmDM_getFaceDataArray(DerivedMesh *dm, int type)
1212 {
1213         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1214         BMesh *bm= bmdm->tc->bm;
1215         BMFace *efa;
1216         char *data, *bmdata;
1217         void *datalayer;
1218         int index, offset, size, i;
1219
1220         datalayer = DM_get_face_data_layer(dm, type);
1221         if(datalayer)
1222                 return datalayer;
1223
1224         /* layers are store per face for editmesh, we convert to a tbmporary
1225          * data layer array in the derivedmesh when these are requested */
1226         if(type == CD_MTFACE || type == CD_MCOL) {
1227                 index = CustomData_get_layer_index(&bm->pdata, type);
1228
1229                 if(index != -1) {
1230                         offset = bm->pdata.layers[index].offset;
1231                         size = CustomData_sizeof(type);
1232
1233                         DM_add_face_layer(dm, type, CD_CALLOC, NULL);
1234                         index = CustomData_get_layer_index(&dm->faceData, type);
1235                         dm->faceData.layers[index].flag |= CD_FLAG_TEMPORARY;
1236
1237                         data = datalayer = DM_get_face_data_layer(dm, type);
1238                         for (i=0; i<bmdm->tc->tottri; i++, data+=size) {
1239                                 efa = bmdm->tc->looptris[i][0]->f;
1240                                 /*BMESH_TODO: need to still add tface data,
1241                                   derived from the loops.*/
1242                                 bmdata = CustomData_bmesh_get(&bm->pdata, efa->head.data, type);
1243                                 memcpy(data, bmdata, size);
1244                         }
1245                 }
1246         }
1247
1248         return datalayer;
1249 }
1250
1251 typedef struct bmDM_loopIter {
1252         DMLoopIter head;
1253
1254         BMFace *f;
1255         BMLoop *l, *nextl;
1256         BMIter iter;
1257         BMesh *bm;
1258 } bmDM_loopIter;
1259
1260 typedef struct bmDM_faceIter {
1261         DMFaceIter head;
1262
1263         BMFace *f, *nextf;
1264         BMIter iter;
1265         BMesh *bm;
1266
1267         bmDM_loopIter loopiter;
1268 } bmDM_faceIter;
1269
1270 void bmDM_faceIterStep(void *self)
1271 {
1272         bmDM_faceIter *iter = self;
1273         
1274         iter->f = iter->nextf;
1275
1276         iter->head.mat_nr = iter->f->mat_nr;
1277         iter->head.flags = BMFlags_To_MEFlags(iter->f);
1278         iter->head.index++;
1279
1280         iter->nextf = BMIter_Step(&iter->iter);
1281
1282         if (!iter->nextf) iter->head.done = 1;
1283 }
1284
1285 void *bmDM_getFaceCDData(void *self, int type, int layer)
1286 {
1287         bmDM_faceIter *iter = self;
1288
1289         if (layer == -1) 
1290                 return CustomData_bmesh_get(&iter->bm->pdata, iter->f->head.data, type);
1291         else return CustomData_bmesh_get_n(&iter->bm->pdata, iter->f->head.data, type, layer);
1292 }
1293
1294 void bmDM_loopIterStep(void *self)
1295 {
1296         bmDM_loopIter *iter = self;
1297
1298         iter->l = iter->nextl;
1299
1300         bmvert_to_mvert(iter->l->v, &iter->head.v);
1301         iter->head.index++;
1302         iter->head.vindex = BMINDEX_GET(iter->l->v);
1303         iter->head.eindex = BMINDEX_GET(iter->l->e);
1304
1305         iter->nextl = BMIter_Step(&iter->iter);
1306
1307         if (!iter->nextl) iter->head.done = 1;
1308 }
1309
1310 void *bmDM_getLoopCDData(void *self, int type, int layer)
1311 {
1312         bmDM_loopIter *iter = self;
1313
1314         if (layer == -1) 
1315                 return CustomData_bmesh_get(&iter->bm->ldata, iter->l->head.data, type);
1316         else return CustomData_bmesh_get_n(&iter->bm->ldata, iter->l->head.data, type, layer);
1317 }
1318
1319 void *bmDM_getVertCDData(void *self, int type, int layer)
1320 {
1321         bmDM_loopIter *iter = self;
1322
1323         if (layer == -1) 
1324                 return CustomData_bmesh_get(&iter->bm->vdata, iter->l->v->head.data, type);
1325         else return CustomData_bmesh_get_n(&iter->bm->vdata, iter->l->v->head.data, type, layer);
1326 }
1327
1328 void bmDM_iterFree(void *self)
1329 {
1330         MEM_freeN(self);
1331 }
1332
1333 void bmDM_nulliterFree(void *self)
1334 {
1335 }
1336
1337 DMLoopIter *bmDM_newLoopsIter(void *faceiter)
1338 {
1339         bmDM_faceIter *fiter = faceiter;
1340         bmDM_loopIter *iter = &fiter->loopiter;
1341
1342         memset(&fiter->loopiter, 0, sizeof(bmDM_loopIter));
1343
1344         iter->bm = fiter->bm;
1345         iter->f = fiter->f;
1346         iter->nextl = BMIter_New(&iter->iter, iter->bm, BM_LOOPS_OF_FACE, iter->f);
1347
1348         iter->head.step = bmDM_loopIterStep;
1349         iter->head.getLoopCDData = bmDM_getLoopCDData;
1350         iter->head.getVertCDData = bmDM_getVertCDData;
1351
1352         bmvert_to_mvert(iter->nextl->v, &iter->head.v);
1353         iter->head.vindex = BMINDEX_GET(iter->nextl->v);
1354         iter->head.eindex = BMINDEX_GET(iter->nextl->e);
1355
1356         return (DMLoopIter*) iter;
1357 }
1358
1359 static DMFaceIter *bmDM_getFaceIter(void *dm)
1360 {
1361         EditDerivedBMesh *bmdm= dm;
1362         bmDM_faceIter *iter = MEM_callocN(sizeof(bmDM_faceIter), "bmDM_faceIter");
1363         BMIter biter;
1364         BMVert *v;
1365         BMEdge *e;
1366         int i;
1367
1368         iter->bm = bmdm->tc->bm;
1369         iter->f = iter->nextf = BMIter_New(&iter->iter, iter->bm, BM_FACES_OF_MESH, NULL);
1370         
1371         iter->head.step = bmDM_faceIterStep;
1372         iter->head.free = bmDM_iterFree;
1373         iter->head.getCDData = bmDM_getFaceCDData;
1374         iter->head.getLoopsIter = bmDM_newLoopsIter;
1375         
1376         iter->head.mat_nr = iter->f->mat_nr;
1377         iter->head.flags = BMFlags_To_MEFlags(iter->f);
1378
1379         /*set up vert/edge indices*/
1380         i = 0;
1381         BM_ITER(v, &biter, iter->bm, BM_VERTS_OF_MESH, NULL) {
1382                 BMINDEX_SET(v, i);
1383                 i++;
1384         }
1385
1386         i = 0;
1387         BM_ITER(e, &biter, iter->bm, BM_EDGES_OF_MESH, NULL) {
1388                 BMINDEX_SET(e, i);
1389                 i++;
1390         }
1391
1392         return (DMFaceIter*) iter;
1393 }
1394
1395 static void bmDM_release(void *dm)
1396 {
1397         EditDerivedBMesh *bmdm= dm;
1398
1399         if (DM_release(dm)) {
1400                 if (bmdm->vertexCos) {
1401                         MEM_freeN(bmdm->vertexCos);
1402                         MEM_freeN(bmdm->vertexNos);
1403                         MEM_freeN(bmdm->faceNos);
1404                 }
1405                 
1406                 MEM_freeN(bmdm);
1407         }
1408 }
1409
1410 DerivedMesh *getEditDerivedBMesh(BMEditMesh *em, Object *ob,
1411                                            float (*vertexCos)[3])
1412 {
1413         EditDerivedBMesh *bmdm = MEM_callocN(sizeof(*bmdm), "bmdm");
1414         BMesh *bm = em->bm;
1415
1416         bmdm->tc = em;
1417
1418         DM_init((DerivedMesh*)bmdm, em->bm->totvert, em->bm->totedge, em->tottri,
1419                  em->bm->totloop, em->bm->totface);
1420
1421         bmdm->dm.getMinMax = bmDM_getMinMax;
1422
1423         bmdm->dm.getNumVerts = bmDM_getNumVerts;
1424         bmdm->dm.getNumEdges = bmDM_getNumEdges;
1425         bmdm->dm.getNumTessFaces = bmDM_getNumTessFaces;
1426         bmdm->dm.getNumFaces = bmDM_getNumFaces;
1427
1428         bmdm->dm.getVert = bmDM_getVert;
1429         bmdm->dm.getEdge = bmDM_getEdge;
1430         bmdm->dm.getTessFace = bmDM_getTessFace;
1431         bmdm->dm.copyVertArray = bmDM_copyVertArray;
1432         bmdm->dm.copyEdgeArray = bmDM_copyEdgeArray;
1433         bmdm->dm.copyTessFaceArray = bmDM_copyFaceArray;
1434         bmdm->dm.getTessFaceDataArray = bmDM_getFaceDataArray;
1435
1436         bmdm->dm.newFaceIter = bmDM_getFaceIter;
1437         bmdm->dm.recalcTesselation = bmDM_recalcTesselation;
1438
1439         bmdm->dm.foreachMappedVert = bmDM_foreachMappedVert;
1440         bmdm->dm.foreachMappedEdge = bmDM_foreachMappedEdge;
1441         bmdm->dm.foreachMappedFaceCenter = bmDM_foreachMappedFaceCenter;
1442
1443         bmdm->dm.drawEdges = bmDM_drawEdges;
1444         bmdm->dm.drawMappedEdges = bmDM_drawMappedEdges;
1445         bmdm->dm.drawMappedEdgesInterp = bmDM_drawMappedEdgesInterp;
1446         bmdm->dm.drawMappedFaces = bmDM_drawMappedFaces;
1447         bmdm->dm.drawMappedFacesTex = bmDM_drawMappedFacesTex;
1448         bmdm->dm.drawMappedFacesGLSL = bmDM_drawMappedFacesGLSL;
1449         bmdm->dm.drawFacesTex = bmDM_drawFacesTex;
1450         bmdm->dm.drawFacesGLSL = bmDM_drawFacesGLSL;
1451         bmdm->dm.drawUVEdges = bmDM_drawUVEdges;
1452
1453         bmdm->dm.release = bmDM_release;
1454         
1455         bmdm->vertexCos = vertexCos;
1456
1457         if(CustomData_has_layer(&bm->vdata, CD_MDEFORMVERT)) {
1458                 BMIter iter;
1459                 BMVert *eve;
1460                 int i;
1461
1462                 DM_add_vert_layer(&bmdm->dm, CD_MDEFORMVERT, CD_CALLOC, NULL);
1463                 
1464                 eve = BMIter_New(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
1465                 for (i=0; eve; eve=BMIter_Step(&iter), i++)
1466                         DM_set_vert_data(&bmdm->dm, i, CD_MDEFORMVERT,
1467                                          CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MDEFORMVERT));
1468         }
1469
1470         if(vertexCos) {
1471                 BMVert *eve;
1472                 BMIter iter;
1473                 int totface = bm->totface;
1474                 int i;
1475                 
1476                 eve=BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
1477                 for (i=0; eve; eve=BMIter_Step(&iter), i++)
1478                         BMINDEX_SET(eve, i);
1479
1480                 bmdm->vertexNos = MEM_callocN(sizeof(*bmdm->vertexNos)*i, "bmdm_vno");
1481                 bmdm->faceNos = MEM_mallocN(sizeof(*bmdm->faceNos)*totface, "bmdm_vno");
1482
1483                 for (i=0; i<bmdm->tc->tottri; i++) {
1484                         BMLoop **l = bmdm->tc->looptris[i];
1485                         float *v1 = vertexCos[(int) BMINDEX_GET(l[0]->v)];
1486                         float *v2 = vertexCos[(int) BMINDEX_GET(l[1]->v)];
1487                         float *v3 = vertexCos[(int) BMINDEX_GET(l[2]->v)];
1488                         float *no = bmdm->faceNos[i];
1489                         
1490                         CalcNormFloat(v1, v2, v3, no);
1491                         VecAddf(bmdm->vertexNos[BMINDEX_GET(l[0]->v)], bmdm->vertexNos[BMINDEX_GET(l[0]->v)], no);
1492                         VecAddf(bmdm->vertexNos[BMINDEX_GET(l[1]->v)], bmdm->vertexNos[BMINDEX_GET(l[1]->v)], no);
1493                         VecAddf(bmdm->vertexNos[BMINDEX_GET(l[2]->v)], bmdm->vertexNos[BMINDEX_GET(l[2]->v)], no);
1494                 }
1495
1496                 eve=BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
1497                 for (i=0; eve; eve=BMIter_Step(&iter), i++) {
1498                         float *no = bmdm->vertexNos[i];
1499                         /* following Mesh convention; we use vertex coordinate itself
1500                          * for normal in this case */
1501                         if (Normalize(no)==0.0) {
1502                                 VECCOPY(no, vertexCos[i]);
1503                                 Normalize(no);
1504                         }
1505                 }
1506         }
1507
1508         bmdm_recalc_lookups(bmdm);
1509
1510         return (DerivedMesh*) bmdm;
1511 }