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