svn merge ^/trunk/blender -r40872:40890
[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                                                 if(poly_prev != GL_ZERO) glEnd();
664                                                 glShadeModel((shade_prev= shade_type)); /* same as below but switch shading */
665                                                 glBegin((poly_prev= poly_type)); /* BMesh: will always be GL_TRIANGLES */
666                                         }
667                                         if(poly_type != poly_prev) {
668                                                 if(poly_prev != GL_ZERO) glEnd();
669                                                 glBegin((poly_prev= poly_type)); /* BMesh: will always be GL_TRIANGLES */
670                                         }
671
672                                         if (!drawSmooth) {
673                                                 glNormal3fv(faceNos[i]);
674                                                 glVertex3fv(vertexCos[(int) BM_GetIndex(l[0]->v)]);
675                                                 glVertex3fv(vertexCos[(int) BM_GetIndex(l[1]->v)]);
676                                                 glVertex3fv(vertexCos[(int) BM_GetIndex(l[2]->v)]);
677                                         } else {
678                                                 glNormal3fv(vertexNos[(int) BM_GetIndex(l[0]->v)]);
679                                                 glVertex3fv(vertexCos[(int) BM_GetIndex(l[0]->v)]);
680                                                 glNormal3fv(vertexNos[(int) BM_GetIndex(l[1]->v)]);
681                                                 glVertex3fv(vertexCos[(int) BM_GetIndex(l[1]->v)]);
682                                                 glNormal3fv(vertexNos[(int) BM_GetIndex(l[2]->v)]);
683                                                 glVertex3fv(vertexCos[(int) BM_GetIndex(l[2]->v)]);
684                                         }
685                                 }
686
687                                 if (draw==2) {
688                                         glEnd();
689                                         poly_prev= GL_ZERO; /* force glBegin */
690
691                                         glDisable(GL_POLYGON_STIPPLE);
692                                 }
693                         }
694                 }
695         } else {
696                 efa = BMIter_New(&iter, bmdm->tc->bm, BM_FACES_OF_MESH, NULL);
697                 for (i=0; efa; efa=BMIter_Step(&iter), i++)
698                         BM_SetIndex(efa, i);
699
700                 for (i=0; i<bmdm->tc->tottri; i++) {
701                         BMLoop **l = bmdm->tc->looptris[i];
702                         int drawSmooth;
703
704                         efa = l[0]->f;
705                         drawSmooth = (efa->head.flag & BM_SMOOTH);
706                         
707                         draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, BM_GetIndex(efa), &drawSmooth);
708                         if(draw) {
709                                 const GLenum poly_type= GL_TRIANGLES; /* BMESH NOTE, this is odd but keep it for now to match trunk */
710                                 if (draw==2) { /* enabled with stipple */
711
712                                         if(poly_prev != GL_ZERO) glEnd();
713                                         poly_prev= GL_ZERO; /* force glBegin */
714
715                                         glEnable(GL_POLYGON_STIPPLE);
716                                         glPolygonStipple(stipple_quarttone);
717                                 }
718                                 
719                                 if(skip_normals) {
720                                         if(poly_type != poly_prev) {
721                                                 if(poly_prev != GL_ZERO) glEnd();
722                                                 glBegin((poly_prev= poly_type)); /* BMesh: will always be GL_TRIANGLES */
723                                         }
724                                         glVertex3fv(l[0]->v->co);
725                                         glVertex3fv(l[1]->v->co);
726                                         glVertex3fv(l[2]->v->co);
727                                 }
728                                 else {
729                                         const GLenum shade_type= drawSmooth ? GL_SMOOTH : GL_FLAT;
730                                         if (shade_type != shade_prev) {
731                                                 if(poly_prev != GL_ZERO) glEnd();
732                                                 glShadeModel((shade_prev= shade_type)); /* same as below but switch shading */
733                                                 glBegin((poly_prev= poly_type)); /* BMesh: will always be GL_TRIANGLES */
734                                         }
735                                         if(poly_type != poly_prev) {
736                                                 if(poly_prev != GL_ZERO) glEnd();
737                                                 glBegin((poly_prev= poly_type)); /* BMesh: will always be GL_TRIANGLES */
738                                         }
739
740                                         if (!drawSmooth) {
741                                                 glNormal3fv(efa->no);
742                                                 glVertex3fv(l[0]->v->co);
743                                                 glVertex3fv(l[1]->v->co);
744                                                 glVertex3fv(l[2]->v->co);
745                                         } else {
746                                                 glNormal3fv(l[0]->v->no);
747                                                 glVertex3fv(l[0]->v->co);
748                                                 glNormal3fv(l[1]->v->no);
749                                                 glVertex3fv(l[1]->v->co);
750                                                 glNormal3fv(l[2]->v->no);
751                                                 glVertex3fv(l[2]->v->co);
752                                         }
753                                 }
754                                 if (draw==2) {
755                                         glEnd();
756                                         poly_prev= GL_ZERO; /* force glBegin */
757
758                                         glDisable(GL_POLYGON_STIPPLE);
759                                 }
760                         }
761                 }
762         }
763
764         /* if non zero we know a face was rendered */
765         if(poly_prev != GL_ZERO) glEnd();
766 }
767
768 static void bmdm_get_tri_tex(BMesh *bm, BMLoop **ls, MLoopUV *luv[3], MLoopCol *lcol[3], 
769                              int has_uv, int has_col)
770 {
771         if (has_uv) { 
772                 luv[0] = CustomData_bmesh_get(&bm->ldata, ls[0]->head.data, CD_MLOOPUV);
773                 luv[1] = CustomData_bmesh_get(&bm->ldata, ls[1]->head.data, CD_MLOOPUV);
774                 luv[2] = CustomData_bmesh_get(&bm->ldata, ls[2]->head.data, CD_MLOOPUV);
775         }
776
777         if (has_col) {
778                 lcol[0] = CustomData_bmesh_get(&bm->ldata, ls[0]->head.data, CD_MLOOPCOL);
779                 lcol[1] = CustomData_bmesh_get(&bm->ldata, ls[1]->head.data, CD_MLOOPCOL);
780                 lcol[2] = CustomData_bmesh_get(&bm->ldata, ls[2]->head.data, CD_MLOOPCOL);
781         }
782
783
784 }
785
786 static void bmDM_drawFacesTex_common(DerivedMesh *dm,
787                int (*drawParams)(MTFace *tface, int has_vcol, int matnr),
788                int (*drawParamsMapped)(void *userData, int index),
789                void *userData) 
790 {
791         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
792         BMEditMesh *em = bmdm->tc;
793         BMesh *bm= bmdm->tc->bm;
794         float (*vertexCos)[3]= bmdm->vertexCos;
795         float (*vertexNos)[3]= bmdm->vertexNos;
796         BMFace *efa;
797         BMVert *eve;
798         BMIter iter;
799         MLoopUV *luv[3], dummyluv = {{0}};
800         MLoopCol *lcol[3], dummylcol = {0};
801         int i, has_vcol = CustomData_has_layer(&bm->ldata, CD_MLOOPCOL);
802         int has_uv = CustomData_has_layer(&bm->pdata, CD_MTEXPOLY);
803         
804         luv[0] = luv[1] = luv[2] = &dummyluv;
805         lcol[0] = lcol[1] = lcol[2] = &dummylcol;
806
807         dummylcol.a = dummylcol.r = dummylcol.g = dummylcol.b = 255;
808
809         /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
810         glShadeModel(GL_SMOOTH);
811         
812         i = 0;
813         BM_ITER(efa, &iter, bm, BM_FACES_OF_MESH, NULL)
814                 BM_SetIndex(efa, i++);
815
816         if (vertexCos) {
817                 i = 0;
818                 BM_ITER(eve, &iter, bm, BM_VERTS_OF_MESH, NULL)
819                         BM_SetIndex(eve, i++);
820                                 
821                 glBegin(GL_TRIANGLES);
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                                 if (!drawSmooth) {
856                                         glNormal3fv(bmdm->faceNos[i]);
857                                         
858                                         bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol);
859                                         
860                                         glTexCoord2fv(luv[0]->uv);
861                                         glColor3ub(lcol[0]->b, lcol[0]->g, lcol[0]->r);
862                                         glVertex3fv(vertexCos[BM_GetIndex(ls[0]->v)]);
863
864                                         glTexCoord2fv(luv[1]->uv);
865                                         glColor3ub(lcol[1]->b, lcol[1]->g, lcol[1]->r);
866                                         glVertex3fv(vertexCos[BM_GetIndex(ls[1]->v)]);
867
868                                         glTexCoord2fv(luv[2]->uv);
869                                         glColor3ub(lcol[2]->b, lcol[2]->g, lcol[2]->r);
870                                         glVertex3fv(vertexCos[BM_GetIndex(ls[2]->v)]);
871                                 } else {
872                                         bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol);
873                                         
874                                         glTexCoord2fv(luv[0]->uv);
875                                         glColor3ub(lcol[0]->b, lcol[0]->g, lcol[0]->r);
876                                         glNormal3fv(vertexNos[BM_GetIndex(ls[0]->v)]);
877                                         glVertex3fv(vertexCos[BM_GetIndex(ls[0]->v)]);
878
879                                         glTexCoord2fv(luv[1]->uv);
880                                         glColor3ub(lcol[1]->b, lcol[1]->g, lcol[1]->r);
881                                         glNormal3fv(vertexNos[BM_GetIndex(ls[1]->v)]);
882                                         glVertex3fv(vertexCos[BM_GetIndex(ls[1]->v)]);
883
884                                         glTexCoord2fv(luv[2]->uv);
885                                         glColor3ub(lcol[2]->b, lcol[2]->g, lcol[2]->r);
886                                         glNormal3fv(vertexNos[BM_GetIndex(ls[2]->v)]);
887                                         glVertex3fv(vertexCos[BM_GetIndex(ls[2]->v)]);
888                                 }
889                         }
890                 }
891                 glEnd();
892         } else {
893                 i = 0;
894                 BM_ITER(eve, &iter, bm, BM_VERTS_OF_MESH, NULL)
895                         BM_SetIndex(eve, i++);
896                                 
897                 for (i=0; i<em->tottri; i++) {
898                         BMLoop **ls = em->looptris[i];
899                         MTexPoly *tp= CustomData_bmesh_get(&bm->pdata, ls[0]->f->head.data, CD_MTEXPOLY);
900                         MTFace mtf = {{{0}}};
901                         /*unsigned char *cp= NULL;*/ /*UNUSED*/
902                         int drawSmooth= BM_TestHFlag(ls[0]->f, BM_SMOOTH);
903                         int flag;
904
905                         efa = ls[0]->f;
906                         
907                         if (has_uv) {
908                                 mtf.flag = tp->flag;
909                                 mtf.tpage = tp->tpage;
910                                 mtf.transp = tp->transp;
911                                 mtf.mode = tp->mode;
912                                 mtf.tile = tp->tile;
913                                 mtf.unwrap = tp->unwrap;
914                         }
915
916                         if(drawParams)
917                                 flag= drawParams(&mtf, has_vcol, efa->mat_nr);
918                         else if(drawParamsMapped)
919                                 flag= drawParamsMapped(userData, BM_GetIndex(efa));
920                         else
921                                 flag= 1;
922
923                         if(flag != 0) { /* flag 0 == the face is hidden or invisible */
924                                 
925                                 /* we always want smooth here since otherwise vertex colors dont interpolate */
926                                 if (!has_vcol) {
927                                         glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
928                                 } 
929                                 
930                                 glBegin(GL_TRIANGLES);
931                                 if (!drawSmooth) {
932                                         glNormal3fv(efa->no);
933                                         
934                                         bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol);
935                                         
936                                         if (luv[0])
937                                                 glTexCoord2fv(luv[0]->uv);
938                                         if (lcol[0])
939                                                 glColor3ub(lcol[0]->b, lcol[0]->g, lcol[0]->r);
940                                         else glColor3ub(0, 0, 0);
941                                         glVertex3fv(ls[0]->v->co);
942
943                                         if (luv[1])
944                                                 glTexCoord2fv(luv[1]->uv);
945                                         if (lcol[1])
946                                                 glColor3ub(lcol[1]->b, lcol[1]->g, lcol[1]->r);
947                                         else glColor3ub(0, 0, 0);
948                                         glVertex3fv(ls[1]->v->co);
949
950                                         if (luv[2])
951                                                 glTexCoord2fv(luv[2]->uv);
952                                         if (lcol[2])
953                                                 glColor3ub(lcol[2]->b, lcol[2]->g, lcol[2]->r);
954                                         else glColor3ub(0, 0, 0);
955                                         glVertex3fv(ls[2]->v->co);
956                                 } else {
957                                         bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol);
958                                         
959                                         if (luv[0])
960                                                 glTexCoord2fv(luv[0]->uv);
961                                         if (lcol[0])
962                                                 glColor3ub(lcol[0]->b, lcol[0]->g, lcol[0]->r);
963                                         else glColor3ub(0, 0, 0);
964                                         glNormal3fv(ls[0]->v->no);
965                                         glVertex3fv(ls[0]->v->co);
966
967                                         if (luv[1])
968                                                 glTexCoord2fv(luv[1]->uv);
969                                         if (lcol[1])
970                                                 glColor3ub(lcol[1]->b, lcol[1]->g, lcol[1]->r);
971                                         else glColor3ub(0, 0, 0);
972                                         glNormal3fv(ls[1]->v->no);
973                                         glVertex3fv(ls[1]->v->co);
974
975                                         if (luv[2])
976                                                 glTexCoord2fv(luv[2]->uv);
977                                         if (lcol[2])
978                                                 glColor3ub(lcol[2]->b, lcol[2]->g, lcol[2]->r);
979                                         else glColor3ub(0, 0, 0);
980                                         glNormal3fv(ls[2]->v->no);
981                                         glVertex3fv(ls[2]->v->co);
982                                 }
983                                 glEnd();
984                         }
985                 }
986         }
987 }
988
989 static void bmDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, int has_vcol, int matnr))
990 {
991         bmDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
992 }
993
994 static void bmDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
995 {
996         bmDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
997 }
998
999 static void bmDM_drawMappedFacesGLSL(DerivedMesh *dm,
1000                int (*setMaterial)(int, void *attribs),
1001                int (*setDrawOptions)(void *userData, int index), void *userData)
1002 {
1003 #if 0
1004         (void)dm;
1005         (void)setMaterial;
1006         (void)setDrawOptions;
1007         (void)userData;
1008 #else /*BMESH_TODO*/
1009
1010         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1011         BMesh *bm= bmdm->tc->bm;
1012         BMEditMesh *em = bmdm->tc;
1013         float (*vertexCos)[3]= bmdm->vertexCos;
1014         float (*vertexNos)[3]= bmdm->vertexNos;
1015         BMVert *eve;
1016         BMFace *efa;
1017         BMIter iter;
1018         BMLoop **ltri;
1019         DMVertexAttribs attribs;
1020         GPUVertexAttribs gattribs;
1021
1022         int i, b, matnr, new_matnr, dodraw;
1023
1024         dodraw = 0;
1025         matnr = -1;
1026
1027         memset(&attribs, 0, sizeof(attribs));
1028
1029         /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
1030         glShadeModel(GL_SMOOTH);
1031         BM_ITER_INDEX(eve, &iter, bm, BM_VERTS_OF_MESH, NULL, i) {
1032                  BM_SetIndex(eve, i);
1033         }
1034
1035 #define PASSATTRIB(loop, eve, vert) {                                                                                   \
1036         if(attribs.totorco) {                                                                                                           \
1037                 float *orco = attribs.orco.array[BM_GetIndex(eve)];                                             \
1038                 glVertexAttrib3fvARB(attribs.orco.glIndex, orco);                                               \
1039         }                                                                                                                                                       \
1040         for(b = 0; b < attribs.tottface; b++) {                                                                         \
1041                 MLoopUV *_luv = CustomData_bmesh_get_n(&bm->ldata, loop->head.data, CD_MLOOPUV, b);\
1042                 glVertexAttrib2fvARB(attribs.tface[b].glIndex, _luv->uv);                               \
1043         }                                                                                                                                                       \
1044         for(b = 0; b < attribs.totmcol; b++) {                                                                          \
1045                 MLoopCol *_cp = CustomData_bmesh_get_n(&bm->ldata, loop->head.data, CD_MLOOPCOL, b);\
1046                 GLubyte _col[4];                                                                                                                \
1047                 _col[0]= _cp->b; _col[1]= _cp->g; _col[2]= _cp->r; _col[3]= _cp->a;             \
1048                 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, _col);                                   \
1049         }                                                                                                                                                       \
1050         if(attribs.tottang) {                                                                                                           \
1051                 float *tang = attribs.tang.array[i*4 + vert];                                                   \
1052                 glVertexAttrib3fvARB(attribs.tang.glIndex, tang);                                               \
1053         }                                                                                                                                                       \
1054         }
1055         
1056         BM_ITER_INDEX(efa, &iter, bm, BM_FACES_OF_MESH, NULL, i) {
1057                 BM_SetIndex(efa, i);
1058         }
1059         
1060         for (i=0, ltri=em->looptris[0]; i<em->tottri; i++, ltri += 3) {
1061                 int drawSmooth;
1062
1063                 efa = ltri[0]->f;
1064                 drawSmooth= BM_TestHFlag(efa, BM_SMOOTH);
1065                 
1066                 if(setDrawOptions && !setDrawOptions(userData, BM_GetIndex(efa)))
1067                         continue;
1068
1069                 new_matnr = efa->mat_nr + 1;
1070                 if(new_matnr != matnr) {
1071                         dodraw = setMaterial(matnr = new_matnr, &gattribs);
1072                         if(dodraw)
1073                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1074                 }
1075
1076                 if(dodraw) {
1077                         glBegin(GL_TRIANGLES);
1078                         if (!drawSmooth) {
1079                                 if(vertexCos) glNormal3fv(bmdm->faceNos[i]);
1080                                 else glNormal3fv(efa->no);
1081
1082                                 PASSATTRIB(ltri[0], ltri[0]->v, 0);
1083                                 if(vertexCos) glVertex3fv(vertexCos[BM_GetIndex(ltri[0]->v)]);
1084                                 else glVertex3fv(ltri[0]->v->co);
1085
1086                                 PASSATTRIB(ltri[1], ltri[1]->v, 1);
1087                                 if(vertexCos) glVertex3fv(vertexCos[BM_GetIndex(ltri[1]->v)]);
1088                                 else glVertex3fv(ltri[1]->v->co);
1089
1090                                 PASSATTRIB(ltri[2], ltri[2]->v, 2);
1091                                 if(vertexCos) glVertex3fv(vertexCos[BM_GetIndex(ltri[2]->v)]);
1092                                 else glVertex3fv(ltri[2]->v->co);
1093                         } else {
1094                                 PASSATTRIB(ltri[0], ltri[0]->v, 0);
1095                                 if(vertexCos) {
1096                                         glNormal3fv(vertexNos[BM_GetIndex(ltri[0]->v)]);
1097                                         glVertex3fv(vertexCos[BM_GetIndex(ltri[0]->v)]);
1098                                 }
1099                                 else {
1100                                         glNormal3fv(ltri[0]->v->no);
1101                                         glVertex3fv(ltri[0]->v->co);
1102                                 }
1103
1104                                 PASSATTRIB(ltri[1], ltri[1]->v, 1);
1105                                 if(vertexCos) {
1106                                         glNormal3fv(vertexNos[BM_GetIndex(ltri[1]->v)]);
1107                                         glVertex3fv(vertexCos[BM_GetIndex(ltri[1]->v)]);
1108                                 }
1109                                 else {
1110                                         glNormal3fv(ltri[1]->v->no);
1111                                         glVertex3fv(ltri[1]->v->co);
1112                                 }
1113
1114                                 PASSATTRIB(ltri[2], ltri[2]->v, 2);
1115                                 if(vertexCos) {
1116                                         glNormal3fv(vertexNos[BM_GetIndex(ltri[2]->v)]);
1117                                         glVertex3fv(vertexCos[BM_GetIndex(ltri[2]->v)]);
1118                                 }
1119                                 else {
1120                                         glNormal3fv(ltri[2]->v->no);
1121                                         glVertex3fv(ltri[2]->v->co);
1122                                 }
1123                         }
1124                         glEnd();
1125                 }
1126         }
1127 #endif
1128 }
1129
1130 static void bmDM_drawFacesGLSL(DerivedMesh *dm,
1131                int (*setMaterial)(int, void *attribs))
1132 {
1133         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1134 }
1135
1136 static void bmDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
1137 {
1138         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1139         BMVert *eve;
1140         BMIter iter;
1141         int i;
1142
1143         if (bmdm->tc->bm->totvert) {
1144                 eve = BMIter_New(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
1145                 for (i=0; eve; eve=BMIter_Step(&iter), i++) {
1146                         if (bmdm->vertexCos) {
1147                                 DO_MINMAX(bmdm->vertexCos[i], min_r, max_r);
1148                         } else {
1149                                 DO_MINMAX(eve->co, min_r, max_r);
1150                         }
1151                 }
1152         } else {
1153                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
1154         }
1155 }
1156 static int bmDM_getNumVerts(DerivedMesh *dm)
1157 {
1158         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1159
1160         return bmdm->tc->bm->totvert;
1161 }
1162
1163 static int bmDM_getNumEdges(DerivedMesh *dm)
1164 {
1165         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1166
1167         return bmdm->tc->bm->totedge;
1168 }
1169
1170 static int bmDM_getNumTessFaces(DerivedMesh *dm)
1171 {
1172         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1173         
1174         return bmdm->tc->tottri;
1175 }
1176
1177 static int bmDM_getNumFaces(DerivedMesh *dm)
1178 {
1179         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1180         
1181         return bmdm->tc->bm->totface;
1182 }
1183
1184 static int bmvert_to_mvert(BMesh *bm, BMVert *ev, MVert *vert_r)
1185 {
1186         copy_v3_v3(vert_r->co, ev->co);
1187
1188         vert_r->no[0] = (short)(ev->no[0] * 32767.0f);
1189         vert_r->no[1] = (short)(ev->no[1] * 32767.0f);
1190         vert_r->no[2] = (short)(ev->no[2] * 32767.0f);
1191
1192         vert_r->flag = BMFlags_To_MEFlags(ev);
1193
1194         if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
1195                 vert_r->bweight = (unsigned char) (BM_GetCDf(&bm->vdata, ev, CD_BWEIGHT)*255.0f);
1196         }
1197
1198         return 1;
1199 }
1200
1201 static void bmDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
1202 {
1203         BMVert *ev;
1204
1205         if (index < 0 || index >= ((EditDerivedBMesh *)dm)->tv) {
1206                 printf("error in bmDM_getVert.\n");
1207                 return;
1208         }
1209
1210         ev = ((EditDerivedBMesh *)dm)->vtable[index];
1211         bmvert_to_mvert(((EditDerivedBMesh *)dm)->tc->bm, ev, vert_r);
1212 }
1213
1214 static void bmDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
1215 {
1216         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1217         BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
1218         BMEdge *e;
1219
1220         if (index < 0 || index >= ((EditDerivedBMesh *)dm)->te) {
1221                 printf("error in bmDM_getEdge.\n");
1222                 return;
1223         }
1224
1225         e = bmdm->etable[index];
1226
1227         if (CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
1228                 edge_r->bweight = (unsigned char) (BM_GetCDf(&bm->edata, e, CD_BWEIGHT)*255.0f);
1229         }
1230
1231         if (CustomData_has_layer(&bm->edata, CD_CREASE)) {
1232                 edge_r->crease = (unsigned char) (BM_GetCDf(&bm->edata, e, CD_CREASE)*255.0f);
1233         }
1234
1235         edge_r->flag = BMFlags_To_MEFlags(e);
1236         
1237         edge_r->v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(bmdm->vhash, e->v1));
1238         edge_r->v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(bmdm->vhash, e->v2));
1239 }
1240
1241 static void bmDM_getTessFace(DerivedMesh *dm, int index, MFace *face_r)
1242 {
1243         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1244         BMFace *ef;
1245         BMLoop **l;
1246         
1247         if (index < 0 || index >= ((EditDerivedBMesh *)dm)->tf) {
1248                 printf("error in bmDM_getTessFace.\n");
1249                 return;
1250         }
1251
1252         l = ((EditDerivedBMesh *)dm)->tc->looptris[index];
1253
1254         ef = l[0]->f;
1255
1256         face_r->mat_nr = (unsigned char) ef->mat_nr;
1257         face_r->flag = BMFlags_To_MEFlags(ef);
1258
1259         face_r->v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(bmdm->vhash, l[0]->v));
1260         face_r->v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(bmdm->vhash, l[1]->v));
1261         face_r->v3 = GET_INT_FROM_POINTER(BLI_ghash_lookup(bmdm->vhash, l[2]->v));
1262         face_r->v4 = 0;
1263
1264         test_index_face(face_r, NULL, 0, 3);
1265 }
1266
1267 static void bmDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
1268 {
1269         BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
1270         BMVert *ev;
1271         BMIter iter;
1272
1273         ev = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
1274         for( ; ev; ev = BMIter_Step(&iter), ++vert_r) {
1275                 copy_v3_v3(vert_r->co, ev->co);
1276
1277                 vert_r->no[0] = (short) (ev->no[0] * 32767.0);
1278                 vert_r->no[1] = (short) (ev->no[1] * 32767.0);
1279                 vert_r->no[2] = (short) (ev->no[2] * 32767.0);
1280
1281                 vert_r->flag = BMFlags_To_MEFlags(ev);
1282
1283                 if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
1284                         vert_r->bweight = (unsigned char) (BM_GetCDf(&bm->vdata, ev, CD_BWEIGHT)*255.0f);
1285                 }
1286         }
1287 }
1288
1289 static void bmDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
1290 {
1291         BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
1292         BMEdge *ee;
1293         BMIter iter;
1294         BMVert *ev;
1295         int has_bweight = CustomData_has_layer(&bm->edata, CD_BWEIGHT);
1296         int i, has_crease = CustomData_has_layer(&bm->edata, CD_CREASE);
1297
1298         /* store vertex indices in tmp union */
1299         ev = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
1300         for (i=0; ev; ev=BMIter_Step(&iter), i++)
1301                 BM_SetIndex(ev, i);
1302
1303         ee = BMIter_New(&iter, bm, BM_EDGES_OF_MESH, NULL);
1304         for( ; ee; ee=BMIter_Step(&iter), edge_r++) {
1305                 if (has_bweight) {
1306                         edge_r->bweight = (unsigned char) (BM_GetCDf(&bm->edata, ee, CD_BWEIGHT)*255.0f);
1307                 }
1308
1309                 if (has_crease) {
1310                         edge_r->crease = (unsigned char) (BM_GetCDf(&bm->edata, ee, CD_CREASE)*255.0f);
1311                 }
1312
1313                 edge_r->flag = BMFlags_To_MEFlags(ee);
1314
1315                 edge_r->v1 = (int)BM_GetIndex(ee->v1);
1316                 edge_r->v2 = (int)BM_GetIndex(ee->v2);
1317         }
1318 }
1319
1320 static void bmDM_copyFaceArray(DerivedMesh *dm, MFace *face_r)
1321 {
1322         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1323         BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
1324         BMFace *ef;
1325         BMVert *ev;
1326         BMIter iter;
1327         BMLoop **l;
1328         int i;
1329
1330         /* store vertexes indices in tmp union */
1331         i = 0;
1332         BM_ITER(ev, &iter, bm, BM_VERTS_OF_MESH, NULL)
1333                 BM_SetIndex(ev, i++);
1334
1335         for (i=0; i<bmdm->tc->tottri; i++, face_r++) {
1336                 l = bmdm->tc->looptris[i];
1337                 ef = l[0]->f;
1338
1339                 face_r->mat_nr = (unsigned char) ef->mat_nr;
1340
1341                 face_r->flag = BMFlags_To_MEFlags(ef);
1342
1343                 face_r->v1 = BM_GetIndex(l[0]->v);
1344                 face_r->v2 = BM_GetIndex(l[1]->v);
1345                 face_r->v3 = BM_GetIndex(l[2]->v);
1346                 face_r->v4 = 0;
1347
1348                 test_index_face(face_r, NULL, 0, 3);
1349         }
1350 }
1351
1352
1353 static void bmDM_copyLoopArray(DerivedMesh *dm, MLoop *loop_r)
1354 {
1355         /* EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm; */ /* UNUSED */
1356         BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
1357         BMIter iter, liter;
1358         BMVert *v;
1359         BMFace *f;
1360         BMLoop *l;
1361         BMEdge *e;
1362         int i;
1363
1364         i = 0;
1365         BM_ITER(v, &iter, bm, BM_VERTS_OF_MESH, NULL) {
1366                 BM_SetIndex(v, i++);
1367         }
1368
1369         i = 0;
1370         BM_ITER(e, &iter, bm, BM_EDGES_OF_MESH, NULL) {
1371                 BM_SetIndex(e, i++);
1372         }
1373
1374         BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
1375                 BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) {
1376                         loop_r->v = BM_GetIndex(l->v);
1377                         loop_r->e = BM_GetIndex(l->e);
1378                         loop_r++;
1379                 }
1380         }
1381 }
1382
1383 static void bmDM_copyPolyArray(DerivedMesh *dm, MPoly *poly_r)
1384 {
1385         /* EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm; */ /* UNUSED */
1386         BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
1387         BMIter iter;
1388         BMFace *f;
1389         int i;
1390
1391         i = 0;
1392         BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
1393                 poly_r->flag = BMFlags_To_MEFlags(f);
1394                 poly_r->loopstart = i;
1395                 poly_r->totloop = f->len;
1396                 poly_r->mat_nr = f->mat_nr;
1397
1398                 poly_r++;
1399                 i += f->len;
1400         }
1401 }
1402
1403 static void *bmDM_getFaceDataArray(DerivedMesh *dm, int type)
1404 {
1405         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1406         BMesh *bm= bmdm->tc->bm;
1407         BMFace *efa;
1408         char *data, *bmdata;
1409         void *datalayer;
1410         int index /*, offset*/ /*UNUSED */, size, i;
1411
1412         datalayer = DM_get_tessface_data_layer(dm, type);
1413         if(datalayer)
1414                 return datalayer;
1415
1416         /* layers are store per face for editmesh, we convert to a tbmporary
1417          * data layer array in the derivedmesh when these are requested */
1418         if(type == CD_MTFACE || type == CD_MCOL) {
1419                 index = CustomData_get_layer_index(&bm->pdata, type);
1420
1421                 if(index != -1) {
1422                         /* offset = bm->pdata.layers[index].offset; */ /* UNUSED */
1423                         size = CustomData_sizeof(type);
1424
1425                         DM_add_tessface_layer(dm, type, CD_CALLOC, NULL);
1426                         index = CustomData_get_layer_index(&dm->faceData, type);
1427                         dm->faceData.layers[index].flag |= CD_FLAG_TEMPORARY;
1428
1429                         data = datalayer = DM_get_tessface_data_layer(dm, type);
1430                         for (i=0; i<bmdm->tc->tottri; i++, data+=size) {
1431                                 efa = bmdm->tc->looptris[i][0]->f;
1432                                 /*BMESH_TODO: need to still add tface data,
1433                                   derived from the loops.*/
1434                                 bmdata = CustomData_bmesh_get(&bm->pdata, efa->head.data, type);
1435                                 memcpy(data, bmdata, size);
1436                         }
1437                 }
1438         }
1439
1440         return datalayer;
1441 }
1442
1443 static void bmDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
1444 {
1445         EditDerivedBMesh *emdm= (EditDerivedBMesh*) dm;
1446         BMVert *eve;
1447         BMIter iter;
1448         int i;
1449
1450         i= 0;
1451         BM_ITER(eve, &iter, emdm->tc->bm, BM_VERTS_OF_MESH, NULL) {
1452                 if (emdm->vertexCos) {
1453                         copy_v3_v3(cos_r[i], emdm->vertexCos[i]);
1454                 } else {
1455                         copy_v3_v3(cos_r[i], eve->co);
1456                 }
1457                 
1458                 i++;
1459         }
1460 }
1461
1462 static void bmDM_release(DerivedMesh *dm)
1463 {
1464         EditDerivedBMesh *bmdm= (EditDerivedBMesh *)dm;
1465
1466         if (DM_release(dm)) {
1467                 if (bmdm->vertexCos) {
1468                         MEM_freeN(bmdm->vertexCos);
1469                         MEM_freeN(bmdm->vertexNos);
1470                         MEM_freeN(bmdm->faceNos);
1471                 }
1472                 
1473                 if (bmdm->fhash) BLI_ghash_free(bmdm->fhash, NULL, NULL);
1474                 if (bmdm->ehash) BLI_ghash_free(bmdm->ehash, NULL, NULL);
1475                 if (bmdm->vhash) BLI_ghash_free(bmdm->vhash, NULL, NULL);
1476
1477                 if (bmdm->vtable) MEM_freeN(bmdm->vtable);
1478                 if (bmdm->etable) MEM_freeN(bmdm->etable);
1479                 if (bmdm->ftable) MEM_freeN(bmdm->ftable);
1480                 
1481                 MEM_freeN(bmdm);
1482         }
1483 }
1484
1485 static CustomData *bmDm_getVertDataLayout(DerivedMesh *dm)
1486 {
1487         EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm;
1488
1489         return &bmdm->tc->bm->vdata;
1490 }
1491
1492 static CustomData *bmDm_getEdgeDataLayout(DerivedMesh *dm)
1493 {
1494         EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm;
1495
1496         return &bmdm->tc->bm->edata;
1497 }
1498
1499 static CustomData *bmDm_getTessFaceDataLayout(DerivedMesh *dm)
1500 {
1501         EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm;
1502
1503         return &bmdm->dm.faceData;
1504 }
1505
1506 static CustomData *bmDm_getLoopDataLayout(DerivedMesh *dm)
1507 {
1508         EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm;
1509
1510         return &bmdm->tc->bm->ldata;
1511 }
1512
1513 static CustomData *bmDm_getFaceDataLayout(DerivedMesh *dm)
1514 {
1515         EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm;
1516
1517         return &bmdm->tc->bm->pdata;
1518 }
1519
1520
1521 DerivedMesh *getEditDerivedBMesh(BMEditMesh *em, Object *UNUSED(ob),
1522                                            float (*vertexCos)[3])
1523 {
1524         EditDerivedBMesh *bmdm = MEM_callocN(sizeof(*bmdm), __func__);
1525         BMesh *bm = em->bm;
1526         
1527         bmdm->tc = em;
1528
1529         DM_init((DerivedMesh*)bmdm, DM_TYPE_EDITBMESH, em->bm->totvert, 
1530                  em->bm->totedge, em->tottri, em->bm->totloop, em->bm->totface);
1531         
1532         CustomData_from_bmeshpoly(&bmdm->dm.faceData, &em->bm->pdata, &em->bm->ldata, 0);
1533         
1534         bmdm->dm.numVertData = bm->totvert;
1535         bmdm->dm.numEdgeData = bm->totedge;
1536         bmdm->dm.numFaceData = em->tottri;
1537         bmdm->dm.numLoopData = bm->totloop;
1538         bmdm->dm.numPolyData = bm->totface;
1539         
1540         bmdm->dm.getVertCos = bmDM_getVertCos;
1541         bmdm->dm.getMinMax = bmDM_getMinMax;
1542
1543         bmdm->dm.getVertDataLayout = bmDm_getVertDataLayout;
1544         bmdm->dm.getEdgeDataLayout = bmDm_getEdgeDataLayout;
1545         bmdm->dm.getTessFaceDataLayout = bmDm_getTessFaceDataLayout;
1546         bmdm->dm.getLoopDataLayout = bmDm_getLoopDataLayout;
1547         bmdm->dm.getFaceDataLayout = bmDm_getFaceDataLayout;
1548
1549         bmdm->dm.getNumVerts = bmDM_getNumVerts;
1550         bmdm->dm.getNumEdges = bmDM_getNumEdges;
1551         bmdm->dm.getNumTessFaces = bmDM_getNumTessFaces;
1552         bmdm->dm.getNumFaces = bmDM_getNumFaces;
1553
1554         bmdm->dm.getVert = bmDM_getVert;
1555         bmdm->dm.getEdge = bmDM_getEdge;
1556         bmdm->dm.getTessFace = bmDM_getTessFace;
1557         bmdm->dm.copyVertArray = bmDM_copyVertArray;
1558         bmdm->dm.copyEdgeArray = bmDM_copyEdgeArray;
1559         bmdm->dm.copyTessFaceArray = bmDM_copyFaceArray;
1560         bmdm->dm.copyLoopArray = bmDM_copyLoopArray;
1561         bmdm->dm.copyPolyArray = bmDM_copyPolyArray;
1562
1563         bmdm->dm.getTessFaceDataArray = bmDM_getFaceDataArray;
1564
1565         bmdm->dm.recalcTesselation = bmDM_recalcTesselation;
1566
1567         bmdm->dm.foreachMappedVert = bmDM_foreachMappedVert;
1568         bmdm->dm.foreachMappedEdge = bmDM_foreachMappedEdge;
1569         bmdm->dm.foreachMappedFaceCenter = bmDM_foreachMappedFaceCenter;
1570
1571         bmdm->dm.drawEdges = bmDM_drawEdges;
1572         bmdm->dm.drawMappedEdges = bmDM_drawMappedEdges;
1573         bmdm->dm.drawMappedEdgesInterp = bmDM_drawMappedEdgesInterp;
1574         bmdm->dm.drawMappedFaces = bmDM_drawMappedFaces;
1575         bmdm->dm.drawMappedFacesTex = bmDM_drawMappedFacesTex;
1576         bmdm->dm.drawMappedFacesGLSL = bmDM_drawMappedFacesGLSL;
1577         bmdm->dm.drawFacesTex = bmDM_drawFacesTex;
1578         bmdm->dm.drawFacesGLSL = bmDM_drawFacesGLSL;
1579         bmdm->dm.drawUVEdges = bmDM_drawUVEdges;
1580
1581         bmdm->dm.release = bmDM_release;
1582         
1583         bmdm->vertexCos = vertexCos;
1584
1585         if(CustomData_has_layer(&bm->vdata, CD_MDEFORMVERT)) {
1586                 BMIter iter;
1587                 BMVert *eve;
1588                 int i;
1589
1590                 DM_add_vert_layer(&bmdm->dm, CD_MDEFORMVERT, CD_CALLOC, NULL);
1591                 
1592                 eve = BMIter_New(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
1593                 for (i=0; eve; eve=BMIter_Step(&iter), i++)
1594                         DM_set_vert_data(&bmdm->dm, i, CD_MDEFORMVERT,
1595                                          CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MDEFORMVERT));
1596         }
1597
1598         if(vertexCos) {
1599                 BMVert *eve;
1600                 BMIter iter;
1601                 int totface = bmdm->tc->tottri;
1602                 int i;
1603                 
1604                 eve=BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
1605                 for (i=0; eve; eve=BMIter_Step(&iter), i++)
1606                         BM_SetIndex(eve, i);
1607
1608                 bmdm->vertexNos = MEM_callocN(sizeof(*bmdm->vertexNos)*i, "bmdm_vno");
1609                 bmdm->faceNos = MEM_mallocN(sizeof(*bmdm->faceNos)*totface, "bmdm_vno");
1610
1611                 for (i=0; i<bmdm->tc->tottri; i++) {
1612                         BMLoop **l = bmdm->tc->looptris[i];
1613                         float *v1 = vertexCos[(int) BM_GetIndex(l[0]->v)];
1614                         float *v2 = vertexCos[(int) BM_GetIndex(l[1]->v)];
1615                         float *v3 = vertexCos[(int) BM_GetIndex(l[2]->v)];
1616                         float *no = bmdm->faceNos[i];
1617                         
1618                         normal_tri_v3( no,v1, v2, v3);
1619                         add_v3_v3v3(bmdm->vertexNos[BM_GetIndex(l[0]->v)], bmdm->vertexNos[BM_GetIndex(l[0]->v)], no);
1620                         add_v3_v3v3(bmdm->vertexNos[BM_GetIndex(l[1]->v)], bmdm->vertexNos[BM_GetIndex(l[1]->v)], no);
1621                         add_v3_v3v3(bmdm->vertexNos[BM_GetIndex(l[2]->v)], bmdm->vertexNos[BM_GetIndex(l[2]->v)], no);
1622                 }
1623
1624                 eve=BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
1625                 for (i=0; eve; eve=BMIter_Step(&iter), i++) {
1626                         float *no = bmdm->vertexNos[i];
1627                         /* following Mesh convention; we use vertex coordinate itself
1628                          * for normal in this case */
1629                         if (normalize_v3(no)==0.0) {
1630                                 copy_v3_v3(no, vertexCos[i]);
1631                                 normalize_v3(no);
1632                         }
1633                 }
1634         }
1635
1636         //bmdm_recalc_lookups(bmdm);
1637
1638         return (DerivedMesh*) bmdm;
1639 }