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