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