first pass at the uv code. uv editor now mostly uses new bmesh structures for uvs.
[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         if (bmdm->tc->bm->totvert)
314                 bmdm->vtable = MEM_mallocN(sizeof(void**)*bmdm->tc->bm->totvert, "bmdm->vtable");
315         else bmdm->vtable = NULL;
316
317         if (bmdm->tc->bm->totedge)
318                 bmdm->etable = MEM_mallocN(sizeof(void**)*bmdm->tc->bm->totedge, "bmdm->etable");
319         else bmdm->etable = NULL;
320         
321         if (bmdm->tc->bm->totface)
322                 bmdm->ftable = MEM_mallocN(sizeof(void**)*bmdm->tc->bm->totface, "bmdm->ftable");
323         else bmdm->ftable = NULL;
324         
325         for (a=0; a<3; a++) {
326                 h = BMIter_New(&iter, bmdm->tc->bm, iters[a], NULL);
327                 for (i=0; h; h=BMIter_Step(&iter), i++) {
328                         switch (a) {
329                                 case 0:
330                                         bmdm->vtable[i] = (BMVert*) h;
331                                         BLI_ghash_insert(bmdm->vhash, h, SET_INT_IN_POINTER(i));
332                                         break;
333                                 case 1:
334                                         bmdm->etable[i] = (BMEdge*) h;
335                                         BLI_ghash_insert(bmdm->ehash, h, SET_INT_IN_POINTER(i));
336                                         break;
337                                 case 2:
338                                         bmdm->ftable[i] = (BMFace*) h;
339                                         BLI_ghash_insert(bmdm->fhash, h, SET_INT_IN_POINTER(i));
340                                         break;
341
342                         }
343                 }
344         }
345 }
346
347 static void bmDM_recalcTesselation(DerivedMesh *dm)
348 {
349         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
350
351         bmdm_recalc_lookups(bmdm);
352 }
353
354 static void bmDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData)
355 {
356         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
357         BMVert *eve;
358         BMIter iter;
359         int i;
360         
361         eve = BMIter_New(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
362         for (i=0; eve; i++, eve=BMIter_Step(&iter)) {
363                 if (bmdm->vertexCos) {
364                         func(userData, i, bmdm->vertexCos[i], bmdm->vertexNos[i], NULL);
365                 } else {
366                         func(userData, i, eve->co, eve->no, NULL);
367                 }
368         }
369 }
370 static void bmDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData)
371 {
372         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
373         BMEdge *eed;
374         BMIter iter;
375         int i;
376         
377         if (bmdm->vertexCos) {
378                 BMVert *eve;
379                 BMIter viter;
380
381                 eve = BMIter_New(&viter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
382                 for (i=0; eve; eve=BMIter_Step(&viter), i++) {
383                         BMINDEX_SET(eve, i);
384                 }
385
386                 eed = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
387                 for(i=0; eed; i++,eed=BMIter_Step(&iter))
388                         func(userData, i, 
389                              bmdm->vertexCos[BMINDEX_GET(eve)], 
390                              bmdm->vertexCos[BMINDEX_GET(eve)]);
391         } else {
392                 eed = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
393                 for(i=0; eed; i++,eed=BMIter_Step(&iter))
394                         func(userData, i, eed->v1->co, eed->v2->co);
395         }
396
397 }
398
399 static void bmDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) 
400 {
401         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
402         BMEdge *eed;
403         BMIter iter;
404         int i;
405         
406         if (bmdm->vertexCos) {
407                 BMVert *eve;
408                 BMIter viter;
409
410                 eve = BMIter_New(&viter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
411                 for (i=0; eve; eve=BMIter_Step(&viter)) {
412                         BMINDEX_SET(eve, i);
413                 }
414
415                 glBegin(GL_LINES);
416                 eed = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
417                 for(i=0; eed; i++,eed=BMIter_Step(&iter)) {
418                         if(!setDrawOptions || setDrawOptions(userData, i)) {
419                                 glVertex3fv(bmdm->vertexCos[BMINDEX_GET(eed->v1)]);
420                                 glVertex3fv(bmdm->vertexCos[BMINDEX_GET(eed->v2)]);
421                         }
422                 }
423                 glEnd();
424
425         } else {
426                 glBegin(GL_LINES);
427                 eed = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
428                 for(i=0; eed; i++,eed=BMIter_Step(&iter)) {
429                         if(!setDrawOptions || setDrawOptions(userData, i)) {
430                                 glVertex3fv(eed->v1->co);
431                                 glVertex3fv(eed->v2->co);
432                         }
433                 }
434                 glEnd();
435         }
436 }
437
438 static void bmDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
439 {
440         bmDM_drawMappedEdges(dm, NULL, NULL);
441 }
442
443 static void bmDM_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) 
444 {
445         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
446         BMEdge *eed;
447         BMIter iter;
448         int i;
449
450         if (bmdm->vertexCos) {
451                 BMVert *eve;
452
453                 eve = BMIter_New(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
454                 for (i=0; eve; eve=BMIter_Step(&iter), i++)
455                         BMINDEX_SET(eve, i);
456
457                 glBegin(GL_LINES);
458                 eed = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
459                 for(i=0; eed; i++,eed=BMIter_Step(&iter)) {
460                         if(!setDrawOptions || setDrawOptions(userData, i)) {
461                                 setDrawInterpOptions(userData, i, 0.0);
462                                 glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(eed->v1)]);
463                                 setDrawInterpOptions(userData, i, 1.0);
464                                 glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(eed->v2)]);
465                         }
466                 }
467                 glEnd();
468         } else {
469                 glBegin(GL_LINES);
470                 eed = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
471                 for(i=0; eed; i++,eed=BMIter_Step(&iter)) {
472                         if(!setDrawOptions || setDrawOptions(userData, i)) {
473                                 setDrawInterpOptions(userData, i, 0.0);
474                                 glVertex3fv(eed->v1->co);
475                                 setDrawInterpOptions(userData, i, 1.0);
476                                 glVertex3fv(eed->v2->co);
477                         }
478                 }
479                 glEnd();
480         }
481 }
482
483 static void bmDM_drawUVEdges(DerivedMesh *dm)
484 {
485 #if 0
486         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
487         BMFace *efa;
488         MTFace *tf;
489
490         glBegin(GL_LINES);
491         for(efa= bmdm->tc->bm->faces.first; efa; efa= efa->next) {
492                 tf = CustomData_bm_get(&bmdm->tc->bm->pdata, efa->data, CD_MTFACE);
493
494                 if(tf && !(efa->h)) {
495                         glVertex2fv(tf->uv[0]);
496                         glVertex2fv(tf->uv[1]);
497
498                         glVertex2fv(tf->uv[1]);
499                         glVertex2fv(tf->uv[2]);
500
501                         if (!efa->v4) {
502                                 glVertex2fv(tf->uv[2]);
503                                 glVertex2fv(tf->uv[0]);
504                         } else {
505                                 glVertex2fv(tf->uv[2]);
506                                 glVertex2fv(tf->uv[3]);
507                                 glVertex2fv(tf->uv[3]);
508                                 glVertex2fv(tf->uv[0]);
509                         }
510                 }
511         }
512         glEnd();
513 #endif
514 }
515
516 static void bmDM__calcFaceCent(BMesh *bm, BMFace *efa, float cent[3],
517                                float (*vertexCos)[3])
518 {
519         BMIter iter;
520         BMLoop *l;
521         int tot = 0;
522         
523         cent[0] = cent[1] = cent[2] = 0.0f;
524         
525         /*simple (and stupid) median (average) based method :/ */
526
527         l = BMIter_New(&iter, bm, BM_LOOPS_OF_FACE, efa);
528         for (; l; l=BMIter_Step(&iter)) {
529                 VECADD(cent, cent, l->v->co);
530                 tot++;
531         }
532
533         if (tot==0) return;
534         VECMUL(cent, 1.0f/(float)tot);
535 }
536
537 static void bmDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData)
538 {
539         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
540         BMVert *eve;
541         BMFace *efa;
542         BMIter iter;
543         float cent[3];
544         int i;
545
546         if (bmdm->vertexCos) {
547                 eve = BMIter_New(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
548                 for (i=0; eve; eve=BMIter_Step(&iter));
549                         BMINDEX_SET(eve, i);
550         }
551
552         efa = BMIter_New(&iter, bmdm->tc->bm, BM_FACES_OF_MESH, NULL);
553         for (i=0; efa; efa=BMIter_Step(&iter), i++) {
554                 bmDM__calcFaceCent(bmdm->tc->bm, efa, cent, bmdm->vertexCos);
555                 func(userData, i, cent, bmdm->vertexCos?bmdm->faceNos[i]:efa->no);
556         }
557 }
558
559 static void bmDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors)
560 {
561         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
562         BMFace *efa;
563         BMIter iter;
564         int i, draw;
565
566         if (bmdm->vertexCos) {
567                 BMVert *eve;
568                 
569                 eve = BMIter_New(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
570                 for (i=0; eve; eve=BMIter_Step(&iter))
571                         BMINDEX_SET(eve, i);
572
573                 efa = BMIter_New(&iter, bmdm->tc->bm, BM_FACES_OF_MESH, NULL);
574                 for (i=0; efa; efa=BMIter_Step(&iter), i++)
575                         BMINDEX_SET(efa, i);
576
577                 for (i=0; i<bmdm->tc->tottri; i++) {
578                         BMLoop **l = bmdm->tc->looptris[i];
579                         int drawSmooth;
580                         
581                         drawSmooth = (efa->head.flag & BM_SMOOTH);
582                         efa = l[0]->f;
583
584                         draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, BMINDEX_GET(efa), &drawSmooth);
585                         if(draw) {
586                                 if (draw==2) { /* enabled with stipple */
587                                         glEnable(GL_POLYGON_STIPPLE);
588                                         glPolygonStipple(stipple_quarttone);
589                                 }
590                                 
591                                 glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
592
593                                 glBegin(GL_TRIANGLES);
594
595                                 if (!drawSmooth) {
596                                         glNormal3fv(efa->no);
597                                         glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(l[0]->v)]);
598                                         glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(l[1]->v)]);
599                                         glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(l[2]->v)]);
600                                 } else {
601                                         glNormal3fv(bmdm->vertexNos[(int) BMINDEX_GET(l[0]->v)]);
602                                         glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(l[0]->v)]);
603                                         glNormal3fv(bmdm->vertexNos[(int) BMINDEX_GET(l[1]->v)]);
604                                         glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(l[1]->v)]);
605                                         glNormal3fv(bmdm->vertexNos[(int) BMINDEX_GET(l[2]->v)]);
606                                         glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(l[2]->v)]);
607                                 }
608                                 glEnd();
609
610                                 if (draw==2)
611                                         glDisable(GL_POLYGON_STIPPLE);
612                         }
613                 }
614         } else {
615                 efa = BMIter_New(&iter, bmdm->tc->bm, BM_FACES_OF_MESH, NULL);
616                 for (i=0; efa; efa=BMIter_Step(&iter), i++)
617                         BMINDEX_SET(efa, i);
618
619                 for (i=0; i<bmdm->tc->tottri; i++) {
620                         BMLoop **l = bmdm->tc->looptris[i];
621                         int drawSmooth;
622
623                         efa = l[0]->f;
624
625                         drawSmooth = (efa->head.flag & BM_SMOOTH);
626                         
627                         draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, BMINDEX_GET(efa), &drawSmooth);
628                         if(draw) {
629                                 if (draw==2) { /* enabled with stipple */
630                                         glEnable(GL_POLYGON_STIPPLE);
631                                         glPolygonStipple(stipple_quarttone);
632                                 }
633                                 glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
634                                 
635                                 glBegin(GL_TRIANGLES);
636                                 if (!drawSmooth) {
637                                         glNormal3fv(efa->no);
638                                         glVertex3fv(l[0]->v->co);
639                                         glVertex3fv(l[1]->v->co);
640                                         glVertex3fv(l[2]->v->co);
641                                 } else {
642                                         glNormal3fv(l[0]->v->no);
643                                         glVertex3fv(l[0]->v->co);
644                                         glNormal3fv(l[1]->v->no);
645                                         glVertex3fv(l[1]->v->co);
646                                         glNormal3fv(l[2]->v->no);
647                                         glVertex3fv(l[2]->v->co);
648                                 }
649                                 glEnd();
650                                 
651                                 if (draw==2)
652                                         glDisable(GL_POLYGON_STIPPLE);
653                         }
654                 }
655         }
656 }
657
658 static void bmDM_drawFacesTex_common(DerivedMesh *dm,
659                int (*drawParams)(MTFace *tface, MCol *mcol, int matnr),
660                int (*drawParamsMapped)(void *userData, int index),
661                void *userData) 
662 {
663 #if 0
664         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
665         BMesh *bm= bmdm->tc->bm;
666         float (*vertexCos)[3]= bmdm->vertexCos;
667         float (*vertexNos)[3]= bmdm->vertexNos;
668         BMFace *efa;
669         BMIter iter;
670         int i;
671
672         /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
673         glShadeModel(GL_SMOOTH);
674         
675         if (vertexCos) {
676                 BMVert *eve;
677
678                 for (i=0,eve=bm->verts.first; eve; eve= eve->next)
679                         BMINDEX_SET(eve, i++);
680
681                 for (i=0,efa= bm->faces.first; efa; i++,efa= efa->next) {
682                         MTFace *tf= CustomData_bm_get(&bm->pdata, efa->data, CD_MTFACE);
683                         MCol *mcol= CustomData_bm_get(&bm->pdata, efa->data, CD_MCOL);
684                         unsigned char *cp= NULL;
685                         int drawSmooth= (efa->flag & ME_SMOOTH);
686                         int flag;
687
688                         if(drawParams)
689                                 flag= drawParams(tf, mcol, efa->mat_nr);
690                         else if(drawParamsMapped)
691                                 flag= drawParamsMapped(userData, i);
692                         else
693                                 flag= 1;
694
695                         if(flag != 0) { /* flag 0 == the face is hidden or invisible */
696                                 
697                                 /* we always want smooth here since otherwise vertex colors dont interpolate */
698                                 if (mcol) {
699                                         if (flag==1) {
700                                                 cp= (unsigned char*)mcol;
701                                         }
702                                 } else {
703                                         glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
704                                 } 
705                                 
706                                 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
707                                 if (!drawSmooth) {
708                                         glNormal3fv(bmdm->faceNos[i]);
709
710                                         if(tf) glTexCoord2fv(tf->uv[0]);
711                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
712                                         glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
713
714                                         if(tf) glTexCoord2fv(tf->uv[1]);
715                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
716                                         glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
717
718                                         if(tf) glTexCoord2fv(tf->uv[2]);
719                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
720                                         glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
721
722                                         if(efa->v4) {
723                                                 if(tf) glTexCoord2fv(tf->uv[3]);
724                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
725                                                 glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
726                                         }
727                                 } else {
728                                         if(tf) glTexCoord2fv(tf->uv[0]);
729                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
730                                         glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
731                                         glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
732
733                                         if(tf) glTexCoord2fv(tf->uv[1]);
734                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
735                                         glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
736                                         glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
737
738                                         if(tf) glTexCoord2fv(tf->uv[2]);
739                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
740                                         glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
741                                         glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
742
743                                         if(efa->v4) {
744                                                 if(tf) glTexCoord2fv(tf->uv[3]);
745                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
746                                                 glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
747                                                 glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
748                                         }
749                                 }
750                                 glEnd();
751                         }
752                 }
753         } else {
754                 for (i=0,efa= bm->faces.first; efa; i++,efa= efa->next) {
755                         MTFace *tf= CustomData_bm_get(&bm->pdata, efa->data, CD_MTFACE);
756                         MCol *mcol= CustomData_bm_get(&bm->pdata, efa->data, CD_MCOL);
757                         unsigned char *cp= NULL;
758                         int drawSmooth= (efa->flag & ME_SMOOTH);
759                         int flag;
760
761                         if(drawParams)
762                                 flag= drawParams(tf, mcol, efa->mat_nr);
763                         else if(drawParamsMapped)
764                                 flag= drawParamsMapped(userData, i);
765                         else
766                                 flag= 1;
767
768                         if(flag != 0) { /* flag 0 == the face is hidden or invisible */
769                                 /* we always want smooth here since otherwise vertex colors dont interpolate */
770                                 if (mcol) {
771                                         if (flag==1) {
772                                                 cp= (unsigned char*)mcol;
773                                         }
774                                 } else {
775                                         glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
776                                 } 
777
778                                 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
779                                 if (!drawSmooth) {
780                                         glNormal3fv(efa->n);
781
782                                         if(tf) glTexCoord2fv(tf->uv[0]);
783                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
784                                         glVertex3fv(efa->v1->co);
785
786                                         if(tf) glTexCoord2fv(tf->uv[1]);
787                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
788                                         glVertex3fv(efa->v2->co);
789
790                                         if(tf) glTexCoord2fv(tf->uv[2]);
791                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
792                                         glVertex3fv(efa->v3->co);
793
794                                         if(efa->v4) {
795                                                 if(tf) glTexCoord2fv(tf->uv[3]);
796                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
797                                                 glVertex3fv(efa->v4->co);
798                                         }
799                                 } else {
800                                         if(tf) glTexCoord2fv(tf->uv[0]);
801                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
802                                         glNormal3fv(efa->v1->no);
803                                         glVertex3fv(efa->v1->co);
804
805                                         if(tf) glTexCoord2fv(tf->uv[1]);
806                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
807                                         glNormal3fv(efa->v2->no);
808                                         glVertex3fv(efa->v2->co);
809
810                                         if(tf) glTexCoord2fv(tf->uv[2]);
811                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
812                                         glNormal3fv(efa->v3->no);
813                                         glVertex3fv(efa->v3->co);
814
815                                         if(efa->v4) {
816                                                 if(tf) glTexCoord2fv(tf->uv[3]);
817                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
818                                                 glNormal3fv(efa->v4->no);
819                                                 glVertex3fv(efa->v4->co);
820                                         }
821                                 }
822                                 glEnd();
823                         }
824                 }
825         }
826 #endif
827 }
828
829 static void bmDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr))
830 {
831         bmDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
832 }
833
834 static void bmDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
835 {
836         bmDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
837 }
838
839 static void bmDM_drawMappedFacesGLSL(DerivedMesh *dm,
840                int (*setMaterial)(int, void *attribs),
841                int (*setDrawOptions)(void *userData, int index), void *userData) 
842 {
843 #if 0
844         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
845         BMesh *bm= bmdm->tc->bm;
846         float (*vertexCos)[3]= bmdm->vertexCos;
847         float (*vertexNos)[3]= bmdm->vertexNos;
848         BMVert *eve;
849         BMFace *efa;
850         DMVertexAttribs attribs;
851         GPUVertexAttribs gattribs;
852         MTFace *tf;
853         int transp, new_transp, orig_transp, tfoffset;
854         int i, b, matnr, new_matnr, dodraw, layer;
855
856         dodraw = 0;
857         matnr = -1;
858
859         transp = GPU_get_material_blend_mode();
860         orig_transp = transp;
861         layer = CustomData_get_layer_index(&bm->pdata, CD_MTFACE);
862         tfoffset = (layer == -1)? -1: bm->pdata.layers[layer].offset;
863
864         memset(&attribs, 0, sizeof(attribs));
865
866         /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
867         glShadeModel(GL_SMOOTH);
868
869         for (i=0,eve=bm->verts.first; eve; eve= eve->next)
870                 BMINDEX_SET(eve, i++);
871
872 #define PASSATTRIB(efa, eve, vert) {                                                                                    \
873         if(attribs.totorco) {                                                                                                           \
874                 float *orco = attribs.orco.array[BMINDEX_GET(eve)];                                                     \
875                 glVertexAttrib3fvARB(attribs.orco.glIndex, orco);                                               \
876         }                                                                                                                                                       \
877         for(b = 0; b < attribs.tottface; b++) {                                                                         \
878                 MTFace *_tf = (MTFace*)((char*)efa->data + attribs.tface[b].bmOffset);  \
879                 glVertexAttrib2fvARB(attribs.tface[b].glIndex, _tf->uv[vert]);                  \
880         }                                                                                                                                                       \
881         for(b = 0; b < attribs.totmcol; b++) {                                                                          \
882                 MCol *cp = (MCol*)((char*)efa->data + attribs.mcol[b].bmOffset);                \
883                 GLubyte col[4];                                                                                                                 \
884                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;                             \
885                 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col);                                    \
886         }                                                                                                                                                       \
887         if(attribs.tottang) {                                                                                                           \
888                 float *tang = attribs.tang.array[i*4 + vert];                                                   \
889                 glVertexAttrib3fvARB(attribs.tang.glIndex, tang);                                               \
890         }                                                                                                                                                       \
891 }
892
893         for (i=0,efa= bm->faces.first; efa; i++,efa= efa->next) {
894                 int drawSmooth= (efa->flag & ME_SMOOTH);
895
896                 if(setDrawOptions && !setDrawOptions(userData, i))
897                         continue;
898
899                 new_matnr = efa->mat_nr + 1;
900                 if(new_matnr != matnr) {
901                         dodraw = setMaterial(matnr = new_matnr, &gattribs);
902                         if(dodraw)
903                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
904                 }
905
906                 if(tfoffset != -1) {
907                         tf = (MTFace*)((char*)efa->data)+tfoffset;
908                         new_transp = tf->transp;
909
910                         if(new_transp != transp) {
911                                 if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
912                                         GPU_set_material_blend_mode(orig_transp);
913                                 else
914                                         GPU_set_material_blend_mode(new_transp);
915                                 transp = new_transp;
916                         }
917                 }
918
919                 if(dodraw) {
920                         glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
921                         if (!drawSmooth) {
922                                 if(vertexCos) glNormal3fv(bmdm->faceNos[i]);
923                                 else glNormal3fv(efa->n);
924
925                                 PASSATTRIB(efa, efa->v1, 0);
926                                 if(vertexCos) glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
927                                 else glVertex3fv(efa->v1->co);
928
929                                 PASSATTRIB(efa, efa->v2, 1);
930                                 if(vertexCos) glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
931                                 else glVertex3fv(efa->v2->co);
932
933                                 PASSATTRIB(efa, efa->v3, 2);
934                                 if(vertexCos) glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
935                                 else glVertex3fv(efa->v3->co);
936
937                                 if(efa->v4) {
938                                         PASSATTRIB(efa, efa->v4, 3);
939                                         if(vertexCos) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
940                                         else glVertex3fv(efa->v4->co);
941                                 }
942                         } else {
943                                 PASSATTRIB(efa, efa->v1, 0);
944                                 if(vertexCos) {
945                                         glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
946                                         glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
947                                 }
948                                 else {
949                                         glNormal3fv(efa->v1->no);
950                                         glVertex3fv(efa->v1->co);
951                                 }
952
953                                 PASSATTRIB(efa, efa->v2, 1);
954                                 if(vertexCos) {
955                                         glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
956                                         glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
957                                 }
958                                 else {
959                                         glNormal3fv(efa->v2->no);
960                                         glVertex3fv(efa->v2->co);
961                                 }
962
963                                 PASSATTRIB(efa, efa->v3, 2);
964                                 if(vertexCos) {
965                                         glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
966                                         glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
967                                 }
968                                 else {
969                                         glNormal3fv(efa->v3->no);
970                                         glVertex3fv(efa->v3->co);
971                                 }
972
973                                 if(efa->v4) {
974                                         PASSATTRIB(efa, efa->v4, 3);
975                                         if(vertexCos) {
976                                                 glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
977                                                 glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
978                                         }
979                                         else {
980                                                 glNormal3fv(efa->v4->no);
981                                                 glVertex3fv(efa->v4->co);
982                                         }
983                                 }
984                         }
985                         glEnd();
986                 }
987         }
988 #endif
989 }
990
991 static void bmDM_drawFacesGLSL(DerivedMesh *dm,
992                int (*setMaterial)(int, void *attribs))
993 {
994         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
995 }
996
997 static void bmDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
998 {
999         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1000         BMVert *eve;
1001         BMIter iter;
1002         int i;
1003
1004         if (bmdm->tc->bm->verts.first) {
1005                 eve = BMIter_New(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
1006                 for (i=0; eve; eve=BMIter_Step(&iter), i++) {
1007                         if (bmdm->vertexCos) {
1008                                 DO_MINMAX(bmdm->vertexCos[i], min_r, max_r);
1009                         } else {
1010                                 DO_MINMAX(eve->co, min_r, max_r);
1011                         }
1012                 }
1013         } else {
1014                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
1015         }
1016 }
1017 static int bmDM_getNumVerts(DerivedMesh *dm)
1018 {
1019         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1020
1021         return bmdm->tc->bm->totvert;
1022 }
1023
1024 static int bmDM_getNumEdges(DerivedMesh *dm)
1025 {
1026         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1027
1028         return bmdm->tc->bm->totedge;
1029 }
1030
1031 static int bmDM_getNumTessFaces(DerivedMesh *dm)
1032 {
1033         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1034         
1035         return bmdm->tc->tottri;
1036 }
1037
1038 static int bmDM_getNumFaces(DerivedMesh *dm)
1039 {
1040         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1041         
1042         return bmdm->tc->bm->totface;
1043 }
1044
1045 static int bmvert_to_mvert(BMVert *ev, MVert *vert_r)
1046 {
1047         VECCOPY(vert_r->co, ev->co);
1048
1049         vert_r->no[0] = (short)(ev->no[0] * 32767.0f);
1050         vert_r->no[1] = (short)(ev->no[1] * 32767.0f);
1051         vert_r->no[2] = (short)(ev->no[2] * 32767.0f);
1052
1053         /* TODO what to do with vert_r->flag and vert_r->mat_nr? */
1054         vert_r->flag = BMFlags_To_MEFlags(ev);
1055         vert_r->mat_nr = 0;
1056         vert_r->bweight = (unsigned char) (ev->bweight*255.0f);
1057 }
1058
1059 static void bmDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
1060 {
1061         BMVert *ev;
1062         BMIter iter;
1063         int i;
1064
1065         if (index < 0 || index >= ((EditDerivedBMesh *)dm)->tv) {
1066                 printf("error in bmDM_getVert.\n");
1067                 return;
1068         }
1069
1070         ev = ((EditDerivedBMesh *)dm)->vtable[index];
1071         bmvert_to_mvert(ev, vert_r);
1072 }
1073
1074 static void bmDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
1075 {
1076         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1077         BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
1078         BMEdge *e;
1079         BMVert *ev, *v1, *v2;
1080         BMIter iter;
1081         int i;
1082
1083         if (index < 0 || index >= ((EditDerivedBMesh *)dm)->te) {
1084                 printf("error in bmDM_getEdge.\n");
1085                 return;
1086         }
1087
1088         e = bmdm->etable[index];
1089
1090         edge_r->crease = (unsigned char) (e->crease*255.0f);
1091         edge_r->bweight = (unsigned char) (e->bweight*255.0f);
1092         /* TODO what to do with edge_r->flag? */
1093         edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER;
1094         edge_r->flag |= BMFlags_To_MEFlags(e);
1095 #if 0
1096         /* this needs setup of f2 field */
1097         if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE;
1098 #endif
1099         
1100         edge_r->v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(bmdm->vhash, e->v1));
1101         edge_r->v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(bmdm->vhash, e->v2));
1102 }
1103
1104 static void bmDM_getTessFace(DerivedMesh *dm, int index, MFace *face_r)
1105 {
1106         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1107         BMesh *bm = bmdm->tc->bm;
1108         BMFace *ef;
1109         BMIter iter;
1110         BMLoop **l;
1111         int i;
1112         
1113         if (index < 0 || index >= ((EditDerivedBMesh *)dm)->tf) {
1114                 printf("error in bmDM_getTessFace.\n");
1115                 return;
1116         }
1117
1118         l = ((EditDerivedBMesh *)dm)->tc->looptris[index];
1119
1120         ef = l[0]->f;
1121
1122         face_r->mat_nr = (unsigned char) ef->mat_nr;
1123         face_r->flag = BMFlags_To_MEFlags(ef);
1124
1125         face_r->v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(bmdm->vhash, l[0]->v));
1126         face_r->v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(bmdm->vhash, l[1]->v));
1127         face_r->v3 = GET_INT_FROM_POINTER(BLI_ghash_lookup(bmdm->vhash, l[2]->v));
1128         face_r->v4 = 0;
1129
1130         test_index_face(face_r, NULL, 0, 3);
1131 }
1132
1133 static void bmDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
1134 {
1135         BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
1136         BMVert *ev;
1137         BMIter iter;
1138
1139         ev = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
1140         for( ; ev; ev = BMIter_Step(&iter), ++vert_r) {
1141                 VECCOPY(vert_r->co, ev->co);
1142
1143                 vert_r->no[0] = (short) (ev->no[0] * 32767.0);
1144                 vert_r->no[1] = (short) (ev->no[1] * 32767.0);
1145                 vert_r->no[2] = (short) (ev->no[2] * 32767.0);
1146
1147                 /* TODO what to do with vert_r->flag and vert_r->mat_nr? */
1148                 vert_r->mat_nr = 0;
1149                 vert_r->flag = BMFlags_To_MEFlags(ev);
1150                 vert_r->bweight = (unsigned char) (ev->bweight*255.0f);
1151         }
1152 }
1153
1154 static void bmDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
1155 {
1156         BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
1157         BMEdge *ee;
1158         BMIter iter;
1159         BMVert *ev;
1160         int i;
1161
1162         /* store vertex indices in tmp union */
1163         ev = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
1164         for (i=0; ev; ev=BMIter_Step(&iter), i++)
1165                 BMINDEX_SET(ev, i);
1166
1167         ee = BMIter_New(&iter, bm, BM_EDGES_OF_MESH, NULL);
1168         for( ; ee; ee=BMIter_Step(&iter)) {
1169                 edge_r->crease = (unsigned char) (ee->crease*255.0f);
1170                 edge_r->bweight = (unsigned char) (ee->bweight*255.0f);
1171                 /* TODO what to do with edge_r->flag? */
1172                 edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER;
1173                 if (ee->head.flag & BM_SEAM) edge_r->flag |= ME_SEAM;
1174                 if (ee->head.flag & BM_SHARP) edge_r->flag |= ME_SHARP;
1175 #if 0
1176                 /* this needs setup of f2 field */
1177                 if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE;
1178 #endif
1179
1180                 edge_r->v1 = (int)BMINDEX_GET(ee->v1);
1181                 edge_r->v2 = (int)BMINDEX_GET(ee->v2);
1182         }
1183 }
1184
1185 static void bmDM_copyFaceArray(DerivedMesh *dm, MFace *face_r)
1186 {
1187         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1188         BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
1189         BMFace *ef;
1190         BMVert *ev;
1191         BMIter iter;
1192         BMLoop **l;
1193         int i;
1194
1195         /* store vertexes indices in tmp union */
1196         ev = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
1197         for (i=0; ev; ev=BMIter_Step(&iter), i++)
1198                 BMINDEX_SET(ev, i);
1199
1200         for (i=0; i<bmdm->tc->tottri; i++) {
1201                 l = bmdm->tc->looptris[i];
1202                 ef = l[0]->f;
1203
1204                 face_r->mat_nr = (unsigned char) ef->mat_nr;
1205
1206                 /*HACK/TODO: need to convert this*/
1207                 face_r->flag = ef->head.flag;
1208
1209                 face_r->v1 = BMINDEX_GET(l[0]->v);
1210                 face_r->v2 = BMINDEX_GET(l[1]->v);
1211                 face_r->v3 = BMINDEX_GET(l[2]->v);
1212                 face_r->v4 = 0;
1213
1214                 test_index_face(face_r, NULL, 0, 3);
1215         }
1216 }
1217
1218 static void *bmDM_getFaceDataArray(DerivedMesh *dm, int type)
1219 {
1220         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1221         BMesh *bm= bmdm->tc->bm;
1222         BMFace *efa;
1223         char *data, *bmdata;
1224         void *datalayer;
1225         int index, offset, size, i;
1226
1227         datalayer = DM_get_face_data_layer(dm, type);
1228         if(datalayer)
1229                 return datalayer;
1230
1231         /* layers are store per face for editmesh, we convert to a tbmporary
1232          * data layer array in the derivedmesh when these are requested */
1233         if(type == CD_MTFACE || type == CD_MCOL) {
1234                 index = CustomData_get_layer_index(&bm->pdata, type);
1235
1236                 if(index != -1) {
1237                         offset = bm->pdata.layers[index].offset;
1238                         size = CustomData_sizeof(type);
1239
1240                         DM_add_face_layer(dm, type, CD_CALLOC, NULL);
1241                         index = CustomData_get_layer_index(&dm->faceData, type);
1242                         dm->faceData.layers[index].flag |= CD_FLAG_TEMPORARY;
1243
1244                         data = datalayer = DM_get_face_data_layer(dm, type);
1245                         for (i=0; i<bmdm->tc->tottri; i++, data+=size) {
1246                                 efa = bmdm->tc->looptris[i][0]->f;
1247                                 /*BMESH_TODO: need to still add tface data,
1248                                   derived from the loops.*/
1249                                 bmdata = CustomData_bmesh_get(&bm->pdata, efa->head.data, type);
1250                                 memcpy(data, bmdata, size);
1251                         }
1252                 }
1253         }
1254
1255         return datalayer;
1256 }
1257
1258 typedef struct bmDM_loopIter {
1259         DMLoopIter head;
1260
1261         BMFace *f;
1262         BMLoop *l, *nextl;
1263         BMIter iter;
1264         BMesh *bm;
1265 } bmDM_loopIter;
1266
1267 typedef struct bmDM_faceIter {
1268         DMFaceIter head;
1269
1270         BMFace *f, *nextf;
1271         BMIter iter;
1272         BMesh *bm;
1273
1274         bmDM_loopIter loopiter;
1275 } bmDM_faceIter;
1276
1277 void bmDM_faceIterStep(void *self)
1278 {
1279         bmDM_faceIter *iter = self;
1280         
1281         iter->f = iter->nextf;
1282
1283         iter->head.mat_nr = iter->f->mat_nr;
1284         iter->head.flags = BMFlags_To_MEFlags(iter->f);
1285         iter->head.index++;
1286
1287         iter->nextf = BMIter_Step(&iter->iter);
1288
1289         if (!iter->nextf) iter->head.done = 1;
1290 }
1291
1292 void *bmDM_getFaceCDData(void *self, int type, int layer)
1293 {
1294         bmDM_faceIter *iter = self;
1295
1296         if (layer == -1) 
1297                 return CustomData_bmesh_get(&iter->bm->pdata, iter->f->head.data, type);
1298         else return CustomData_bmesh_get_n(&iter->bm->pdata, iter->f->head.data, type, layer);
1299 }
1300
1301 void bmDM_loopIterStep(void *self)
1302 {
1303         bmDM_loopIter *iter = self;
1304
1305         iter->l = iter->nextl;
1306
1307         bmvert_to_mvert(iter->l->v, &iter->head.v);
1308         iter->head.index++;
1309         iter->head.vindex = BMINDEX_GET(iter->l->v);
1310         iter->head.eindex = BMINDEX_GET(iter->l->e);
1311
1312         iter->nextl = BMIter_Step(&iter->iter);
1313
1314         if (!iter->nextl) iter->head.done = 1;
1315 }
1316
1317 void *bmDM_getLoopCDData(void *self, int type, int layer)
1318 {
1319         bmDM_loopIter *iter = self;
1320
1321         if (layer == -1) 
1322                 return CustomData_bmesh_get(&iter->bm->ldata, iter->l->head.data, type);
1323         else return CustomData_bmesh_get_n(&iter->bm->ldata, iter->l->head.data, type, layer);
1324 }
1325
1326 void *bmDM_getVertCDData(void *self, int type, int layer)
1327 {
1328         bmDM_loopIter *iter = self;
1329
1330         if (layer == -1) 
1331                 return CustomData_bmesh_get(&iter->bm->vdata, iter->l->v->head.data, type);
1332         else return CustomData_bmesh_get_n(&iter->bm->vdata, iter->l->v->head.data, type, layer);
1333 }
1334
1335 void bmDM_iterFree(void *self)
1336 {
1337         MEM_freeN(self);
1338 }
1339
1340 void bmDM_nulliterFree(void *self)
1341 {
1342 }
1343
1344 DMLoopIter *bmDM_newLoopsIter(void *faceiter)
1345 {
1346         bmDM_faceIter *fiter = faceiter;
1347         bmDM_loopIter *iter = &fiter->loopiter;
1348
1349         memset(&fiter->loopiter, 0, sizeof(bmDM_loopIter));
1350
1351         iter->bm = fiter->bm;
1352         iter->f = fiter->f;
1353         iter->nextl = BMIter_New(&iter->iter, iter->bm, BM_LOOPS_OF_FACE, iter->f);
1354
1355         iter->head.step = bmDM_loopIterStep;
1356         iter->head.getLoopCDData = bmDM_getLoopCDData;
1357         iter->head.getVertCDData = bmDM_getVertCDData;
1358
1359         bmvert_to_mvert(iter->nextl->v, &iter->head.v);
1360         iter->head.vindex = BMINDEX_GET(iter->nextl->v);
1361         iter->head.eindex = BMINDEX_GET(iter->nextl->e);
1362
1363         return (DMLoopIter*) iter;
1364 }
1365
1366 static DMFaceIter *bmDM_getFaceIter(void *dm)
1367 {
1368         EditDerivedBMesh *bmdm= dm;
1369         bmDM_faceIter *iter = MEM_callocN(sizeof(bmDM_faceIter), "bmDM_faceIter");
1370         BMIter biter;
1371         BMVert *v;
1372         BMEdge *e;
1373         int i;
1374
1375         iter->bm = bmdm->tc->bm;
1376         iter->f = iter->nextf = BMIter_New(&iter->iter, iter->bm, BM_FACES_OF_MESH, NULL);
1377         
1378         iter->head.step = bmDM_faceIterStep;
1379         iter->head.free = bmDM_iterFree;
1380         iter->head.getCDData = bmDM_getFaceCDData;
1381         iter->head.getLoopsIter = bmDM_newLoopsIter;
1382         
1383         iter->head.mat_nr = iter->f->mat_nr;
1384         iter->head.flags = BMFlags_To_MEFlags(iter->f);
1385
1386         /*set up vert/edge indices*/
1387         i = 0;
1388         BM_ITER(v, &biter, iter->bm, BM_VERTS_OF_MESH, NULL) {
1389                 BMINDEX_SET(v, i);
1390                 i++;
1391         }
1392
1393         i = 0;
1394         BM_ITER(e, &biter, iter->bm, BM_EDGES_OF_MESH, NULL) {
1395                 BMINDEX_SET(e, i);
1396                 i++;
1397         }
1398
1399         return (DMFaceIter*) iter;
1400 }
1401
1402 static void bmDM_release(void *dm)
1403 {
1404         EditDerivedBMesh *bmdm= dm;
1405
1406         if (DM_release(dm)) {
1407                 if (bmdm->vertexCos) {
1408                         MEM_freeN(bmdm->vertexCos);
1409                         MEM_freeN(bmdm->vertexNos);
1410                         MEM_freeN(bmdm->faceNos);
1411                 }
1412                 
1413                 BLI_ghash_free(bmdm->fhash, NULL, NULL);
1414                 BLI_ghash_free(bmdm->ehash, NULL, NULL);
1415                 BLI_ghash_free(bmdm->vhash, NULL, NULL);
1416
1417                 if (bmdm->vtable) MEM_freeN(bmdm->vtable);
1418                 if (bmdm->etable) MEM_freeN(bmdm->etable);
1419                 if (bmdm->ftable) MEM_freeN(bmdm->ftable);
1420                 
1421                 MEM_freeN(bmdm);
1422         }
1423 }
1424
1425 DerivedMesh *getEditDerivedBMesh(BMEditMesh *em, Object *ob,
1426                                            float (*vertexCos)[3])
1427 {
1428         EditDerivedBMesh *bmdm = MEM_callocN(sizeof(*bmdm), "bmdm");
1429         BMesh *bm = em->bm;
1430
1431         bmdm->tc = em;
1432
1433         DM_init((DerivedMesh*)bmdm, em->bm->totvert, em->bm->totedge, em->tottri,
1434                  em->bm->totloop, em->bm->totface);
1435
1436         bmdm->dm.getMinMax = bmDM_getMinMax;
1437
1438         bmdm->dm.getNumVerts = bmDM_getNumVerts;
1439         bmdm->dm.getNumEdges = bmDM_getNumEdges;
1440         bmdm->dm.getNumTessFaces = bmDM_getNumTessFaces;
1441         bmdm->dm.getNumFaces = bmDM_getNumFaces;
1442
1443         bmdm->dm.getVert = bmDM_getVert;
1444         bmdm->dm.getEdge = bmDM_getEdge;
1445         bmdm->dm.getTessFace = bmDM_getTessFace;
1446         bmdm->dm.copyVertArray = bmDM_copyVertArray;
1447         bmdm->dm.copyEdgeArray = bmDM_copyEdgeArray;
1448         bmdm->dm.copyTessFaceArray = bmDM_copyFaceArray;
1449         bmdm->dm.getTessFaceDataArray = bmDM_getFaceDataArray;
1450
1451         bmdm->dm.newFaceIter = bmDM_getFaceIter;
1452         bmdm->dm.recalcTesselation = bmDM_recalcTesselation;
1453
1454         bmdm->dm.foreachMappedVert = bmDM_foreachMappedVert;
1455         bmdm->dm.foreachMappedEdge = bmDM_foreachMappedEdge;
1456         bmdm->dm.foreachMappedFaceCenter = bmDM_foreachMappedFaceCenter;
1457
1458         bmdm->dm.drawEdges = bmDM_drawEdges;
1459         bmdm->dm.drawMappedEdges = bmDM_drawMappedEdges;
1460         bmdm->dm.drawMappedEdgesInterp = bmDM_drawMappedEdgesInterp;
1461         bmdm->dm.drawMappedFaces = bmDM_drawMappedFaces;
1462         bmdm->dm.drawMappedFacesTex = bmDM_drawMappedFacesTex;
1463         bmdm->dm.drawMappedFacesGLSL = bmDM_drawMappedFacesGLSL;
1464         bmdm->dm.drawFacesTex = bmDM_drawFacesTex;
1465         bmdm->dm.drawFacesGLSL = bmDM_drawFacesGLSL;
1466         bmdm->dm.drawUVEdges = bmDM_drawUVEdges;
1467
1468         bmdm->dm.release = bmDM_release;
1469         
1470         bmdm->vertexCos = vertexCos;
1471
1472         if(CustomData_has_layer(&bm->vdata, CD_MDEFORMVERT)) {
1473                 BMIter iter;
1474                 BMVert *eve;
1475                 int i;
1476
1477                 DM_add_vert_layer(&bmdm->dm, CD_MDEFORMVERT, CD_CALLOC, NULL);
1478                 
1479                 eve = BMIter_New(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
1480                 for (i=0; eve; eve=BMIter_Step(&iter), i++)
1481                         DM_set_vert_data(&bmdm->dm, i, CD_MDEFORMVERT,
1482                                          CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MDEFORMVERT));
1483         }
1484
1485         if(vertexCos) {
1486                 BMVert *eve;
1487                 BMIter iter;
1488                 int totface = bm->totface;
1489                 int i;
1490                 
1491                 eve=BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
1492                 for (i=0; eve; eve=BMIter_Step(&iter), i++)
1493                         BMINDEX_SET(eve, i);
1494
1495                 bmdm->vertexNos = MEM_callocN(sizeof(*bmdm->vertexNos)*i, "bmdm_vno");
1496                 bmdm->faceNos = MEM_mallocN(sizeof(*bmdm->faceNos)*totface, "bmdm_vno");
1497
1498                 for (i=0; i<bmdm->tc->tottri; i++) {
1499                         BMLoop **l = bmdm->tc->looptris[i];
1500                         float *v1 = vertexCos[(int) BMINDEX_GET(l[0]->v)];
1501                         float *v2 = vertexCos[(int) BMINDEX_GET(l[1]->v)];
1502                         float *v3 = vertexCos[(int) BMINDEX_GET(l[2]->v)];
1503                         float *no = bmdm->faceNos[i];
1504                         
1505                         CalcNormFloat(v1, v2, v3, no);
1506                         VecAddf(bmdm->vertexNos[BMINDEX_GET(l[0]->v)], bmdm->vertexNos[BMINDEX_GET(l[0]->v)], no);
1507                         VecAddf(bmdm->vertexNos[BMINDEX_GET(l[1]->v)], bmdm->vertexNos[BMINDEX_GET(l[1]->v)], no);
1508                         VecAddf(bmdm->vertexNos[BMINDEX_GET(l[2]->v)], bmdm->vertexNos[BMINDEX_GET(l[2]->v)], no);
1509                 }
1510
1511                 eve=BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
1512                 for (i=0; eve; eve=BMIter_Step(&iter), i++) {
1513                         float *no = bmdm->vertexNos[i];
1514                         /* following Mesh convention; we use vertex coordinate itself
1515                          * for normal in this case */
1516                         if (Normalize(no)==0.0) {
1517                                 VECCOPY(no, vertexCos[i]);
1518                                 Normalize(no);
1519                         }
1520                 }
1521         }
1522
1523         bmdm_recalc_lookups(bmdm);
1524
1525         return (DerivedMesh*) bmdm;
1526 }