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