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