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