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