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