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