svn merge ^/trunk/blender -r44213:44235 --- fixes bmesh shading bug [#30125]
[blender.git] / source / blender / blenkernel / intern / editderivedmesh.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2005 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/blenkernel/intern/editderivedmesh.c
29  *  \ingroup bke
30  */
31
32 #include <string.h>
33 #include <limits.h>
34 #include <math.h>
35
36 #include "GL/glew.h"
37
38 #include "BLI_utildefines.h"
39 #include "BLI_blenlib.h"
40 #include "BLI_edgehash.h"
41 #include "BLI_editVert.h"
42 #include "BLI_math.h"
43 #include "BLI_pbvh.h"
44
45 #include "BKE_cdderivedmesh.h"
46 #include "BKE_global.h"
47 #include "BKE_mesh.h"
48 #include "BKE_paint.h"
49
50
51 #include "DNA_meshdata_types.h"
52 #include "DNA_object_types.h"
53 #include "DNA_curve_types.h" /* for Curve */
54
55 #include "MEM_guardedalloc.h"
56
57 #include "GPU_buffers.h"
58 #include "GPU_draw.h"
59 #include "GPU_extensions.h"
60 #include "GPU_material.h"
61
62 /* bmesh */
63 #include "BKE_tessmesh.h"
64 #include "BLI_array.h"
65 #include "BLI_scanfill.h"
66
67 #include "bmesh.h"
68 /* end bmesh */
69
70 extern GLubyte stipple_quarttone[128]; /* glutil.c, bad level data */
71
72
73 BMEditMesh *BMEdit_Create(BMesh *bm, int do_tesselate)
74 {
75         BMEditMesh *tm = MEM_callocN(sizeof(BMEditMesh), __func__);
76
77         tm->bm = bm;
78         if (do_tesselate) {
79                 BMEdit_RecalcTesselation(tm);
80         }
81
82         return tm;
83 }
84
85 BMEditMesh *BMEdit_Copy(BMEditMesh *tm)
86 {
87         BMEditMesh *tm2 = MEM_callocN(sizeof(BMEditMesh), __func__);
88         *tm2 = *tm;
89
90         tm2->derivedCage = tm2->derivedFinal = NULL;
91
92         tm2->bm = BM_mesh_copy(tm->bm);
93
94         /*The tesselation is NOT calculated on the copy here,
95           because currently all the callers of this function use
96           it to make a backup copy of the BMEditMesh to restore
97           it in the case of errors in an operation. For perf
98           reasons, in that case it makes more sense to do the
99           tesselation only when/if that copy ends up getting
100           used.*/
101         tm2->looptris = NULL;
102
103         tm2->vert_index = NULL;
104         tm2->edge_index = NULL;
105         tm2->face_index = NULL;
106
107         return tm2;
108 }
109
110 static void BMEdit_RecalcTesselation_intern(BMEditMesh *tm)
111 {
112         /* use this to avoid locking pthread for _every_ polygon
113          * and calling the fill function */
114 #define USE_TESSFACE_SPEEDUP
115
116         BMesh *bm = tm->bm;
117         BMLoop *(*looptris)[3]= NULL;
118         BLI_array_declare(looptris);
119         BMIter iter, liter;
120         BMFace *f;
121         BMLoop *l;
122         int i = 0, j;
123
124 #if 0
125         /* note, we could be clever and re-use this array but would need to ensure
126          * its realloced at some point, for now just free it */
127         if (tm->looptris) MEM_freeN(tm->looptris);
128
129         /* Use tm->tottri when set, this means no reallocs while transforming,
130          * (unless scanfill fails), otherwise... */
131         /* allocate the length of totfaces, avoid many small reallocs,
132          * if all faces are tri's it will be correct, quads == 2x allocs */
133         BLI_array_reserve(looptris, (tm->tottri && tm->tottri < bm->totface * 3) ? tm->tottri : bm->totface);
134 #else
135
136         /* this means no reallocs for quad dominant models, for */
137         if ( (tm->looptris != NULL) &&
138              (tm->tottri != 0) &&
139              /* (totrti <= bm->totface * 2) would be fine for all quads,
140                   * but incase there are some ngons, still re-use the array */
141              (tm->tottri <= bm->totface * 3))
142         {
143                 looptris = tm->looptris;
144         }
145         else {
146                 if (tm->looptris) MEM_freeN(tm->looptris);
147                 BLI_array_reserve(looptris, bm->totface);
148         }
149
150 #endif
151
152         f = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, NULL);
153         for ( ; f; f=BM_iter_step(&iter)) {
154                 /*don't consider two-edged faces*/
155                 if (f->len < 3) {
156                         /* do nothing */
157                 }
158
159 #ifdef USE_TESSFACE_SPEEDUP
160
161                 /* no need to ensure the loop order, we know its ok */
162
163                 else if (f->len == 3) {
164                         BLI_array_growone(looptris);
165                         l = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, f);
166                         for (j=0; l; l=BM_iter_step(&liter), j++) {
167                                 looptris[i][j] = l;
168                         }
169                         i += 1;
170                 }
171                 else if (f->len == 4) {
172                         BMLoop *ltmp[4];
173                         BLI_array_growitems(looptris, 2);
174
175                         l = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, f);
176                         for (j=0; l; l=BM_iter_step(&liter), j++) {
177                                 ltmp[j] = l;
178                         }
179
180                         looptris[i][0] = ltmp[0];
181                         looptris[i][1] = ltmp[1];
182                         looptris[i][2] = ltmp[2];
183                         i += 1;
184
185                         looptris[i][0] = ltmp[0];
186                         looptris[i][1] = ltmp[2];
187                         looptris[i][2] = ltmp[3];
188                         i += 1;
189                 }
190
191 #endif /* USE_TESSFACE_SPEEDUP */
192
193                 else {
194                         EditVert *v, *lastv=NULL, *firstv=NULL;
195                         EditEdge *e;
196                         EditFace *efa;
197                         int totfilltri;
198
199                         BLI_begin_edgefill();
200                         /*scanfill time*/
201                         l = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, f);
202                         for (j=0; l; l=BM_iter_step(&liter), j++) {
203                                 /*mark order*/
204                                 BM_elem_index_set(l, j); /* set_loop */
205
206                                 v = BLI_addfillvert(l->v->co);
207                                 v->tmp.p = l;
208
209                                 if (lastv) {
210                                         e = BLI_addfilledge(lastv, v);
211                                 }
212
213                                 lastv = v;
214                                 if (firstv==NULL) firstv = v;
215                         }
216
217                         /*complete the loop*/
218                         BLI_addfilledge(firstv, v);
219
220                         totfilltri = BLI_edgefill(2);
221                         BLI_array_growitems(looptris, totfilltri);
222
223                         for (efa = fillfacebase.first; efa; efa=efa->next) {
224                                 BMLoop *l1= efa->v1->tmp.p;
225                                 BMLoop *l2= efa->v2->tmp.p;
226                                 BMLoop *l3= efa->v3->tmp.p;
227
228                                 if (BM_elem_index_get(l1) > BM_elem_index_get(l2)) { SWAP(BMLoop*, l1, l2); }
229                                 if (BM_elem_index_get(l2) > BM_elem_index_get(l3)) { SWAP(BMLoop*, l2, l3); }
230                                 if (BM_elem_index_get(l1) > BM_elem_index_get(l2)) { SWAP(BMLoop*, l1, l2); }
231
232                                 looptris[i][0] = l1;
233                                 looptris[i][1] = l2;
234                                 looptris[i][2] = l3;
235                                 i += 1;
236                         }
237
238                         BLI_end_edgefill();
239                 }
240         }
241
242         tm->tottri = i;
243         tm->looptris = looptris;
244
245 #undef USE_TESSFACE_SPEEDUP
246
247 }
248
249 void BMEdit_RecalcTesselation(BMEditMesh *em)
250 {
251         BMEdit_RecalcTesselation_intern(em);
252
253         /* commented because editbmesh_build_data() ensures we get tessfaces */
254 #if 0
255         if (em->derivedFinal && em->derivedFinal == em->derivedCage) {
256                 if (em->derivedFinal->recalcTesselation)
257                         em->derivedFinal->recalcTesselation(em->derivedFinal);
258         }
259         else if (em->derivedFinal) {
260                 if (em->derivedCage->recalcTesselation)
261                         em->derivedCage->recalcTesselation(em->derivedCage);
262                 if (em->derivedFinal->recalcTesselation)
263                         em->derivedFinal->recalcTesselation(em->derivedFinal);
264         }
265 #endif
266 }
267
268 void BMEdit_UpdateLinkedCustomData(BMEditMesh *em)
269 {
270         BMesh *bm = em->bm;
271         int act;
272
273         if (CustomData_has_layer(&bm->pdata, CD_MTEXPOLY)) {
274                 act = CustomData_get_active_layer(&bm->pdata, CD_MTEXPOLY);
275                 CustomData_set_layer_active(&bm->ldata, CD_MLOOPUV, act);
276
277                 act = CustomData_get_render_layer(&bm->pdata, CD_MTEXPOLY);
278                 CustomData_set_layer_render(&bm->ldata, CD_MLOOPUV, act);
279
280                 act = CustomData_get_clone_layer(&bm->pdata, CD_MTEXPOLY);
281                 CustomData_set_layer_clone(&bm->ldata, CD_MLOOPUV, act);
282
283                 act = CustomData_get_stencil_layer(&bm->pdata, CD_MTEXPOLY);
284                 CustomData_set_layer_stencil(&bm->ldata, CD_MLOOPUV, act);
285         }
286 }
287
288 /*does not free the BMEditMesh struct itself*/
289 void BMEdit_Free(BMEditMesh *em)
290 {
291         if (em->derivedFinal) {
292                 if (em->derivedFinal!=em->derivedCage) {
293                         em->derivedFinal->needsFree= 1;
294                         em->derivedFinal->release(em->derivedFinal);
295                 }
296                 em->derivedFinal= NULL;
297         }
298         if (em->derivedCage) {
299                 em->derivedCage->needsFree= 1;
300                 em->derivedCage->release(em->derivedCage);
301                 em->derivedCage= NULL;
302         }
303
304         if (em->looptris) MEM_freeN(em->looptris);
305
306         if (em->vert_index) MEM_freeN(em->vert_index);
307         if (em->edge_index) MEM_freeN(em->edge_index);
308         if (em->face_index) MEM_freeN(em->face_index);
309
310         if (em->bm)
311                 BM_mesh_free(em->bm);
312 }
313
314 /*
315 ok, basic design:
316
317 the bmesh derivedmesh exposes the mesh as triangles.  it stores pointers
318 to three loops per triangle.  the derivedmesh stores a cache of tesselations
319 for each face.  this cache will smartly update as needed (though at first
320 it'll simply be more brute force).  keeping track of face/edge counts may
321 be a small problbm.
322
323 this won't be the most efficient thing, considering that internal edges and
324 faces of tesselations are exposed.  looking up an edge by index in particular
325 is likely to be a little slow.
326 */
327
328 typedef struct EditDerivedBMesh {
329         DerivedMesh dm;
330
331         Object *ob;
332         BMEditMesh *tc;
333
334         float (*vertexCos)[3];
335         float (*vertexNos)[3];
336         float (*polyNos)[3];
337
338         /* private variables, for number of verts/edges/faces
339          * within the above hash/table members*/
340         int tv, te, tf;
341 } EditDerivedBMesh;
342
343 static void emDM_calcNormals(DerivedMesh *UNUSED(dm))
344 {
345         /* Nothing to do: normals are already calculated and stored on the
346            BMVerts and BMFaces */
347 }
348
349 static void emDM_recalcTesselation(DerivedMesh *UNUSED(dm))
350 {
351         /* do nothing */
352 }
353
354 static void emDM_foreachMappedVert(
355                 DerivedMesh *dm,
356                 void (*func)(void *userData, int index, float *co, float *no_f, short *no_s),
357                 void *userData)
358 {
359         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
360         BMVert *eve;
361         BMIter iter;
362         int i;
363
364         eve = BM_iter_new(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
365         for (i=0; eve; i++, eve=BM_iter_step(&iter)) {
366                 if (bmdm->vertexCos) {
367                         func(userData, i, bmdm->vertexCos[i], bmdm->vertexNos[i], NULL);
368                 }
369                 else {
370                         func(userData, i, eve->co, eve->no, NULL);
371                 }
372         }
373 }
374 static void emDM_foreachMappedEdge(
375                 DerivedMesh *dm,
376                 void (*func)(void *userData, int index, float *v0co, float *v1co),
377                 void *userData)
378 {
379         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
380         BMEdge *eed;
381         BMIter iter;
382         int i;
383
384         if (bmdm->vertexCos) {
385
386                 BM_mesh_elem_index_ensure(bmdm->tc->bm, BM_VERT);
387
388                 eed = BM_iter_new(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
389                 for (i=0; eed; i++,eed=BM_iter_step(&iter))
390                         func(userData, i,
391                                  bmdm->vertexCos[BM_elem_index_get(eed->v1)],
392                                  bmdm->vertexCos[BM_elem_index_get(eed->v2)]);
393         }
394         else {
395                 eed = BM_iter_new(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
396                 for (i=0; eed; i++,eed=BM_iter_step(&iter))
397                         func(userData, i, eed->v1->co, eed->v2->co);
398         }
399 }
400
401 static void emDM_drawMappedEdges(
402                 DerivedMesh *dm,
403                 int (*setDrawOptions)(void *userData, int index),
404                 void *userData)
405 {
406         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
407         BMEdge *eed;
408         BMIter iter;
409         int i;
410
411         if (bmdm->vertexCos) {
412
413                 BM_mesh_elem_index_ensure(bmdm->tc->bm, BM_VERT);
414
415                 glBegin(GL_LINES);
416                 eed = BM_iter_new(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
417                 for (i=0; eed; i++,eed=BM_iter_step(&iter)) {
418                         if (!setDrawOptions || setDrawOptions(userData, i)) {
419                                 glVertex3fv(bmdm->vertexCos[BM_elem_index_get(eed->v1)]);
420                                 glVertex3fv(bmdm->vertexCos[BM_elem_index_get(eed->v2)]);
421                         }
422                 }
423                 glEnd();
424         }
425         else {
426                 glBegin(GL_LINES);
427                 eed = BM_iter_new(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
428                 for (i=0; eed; i++,eed=BM_iter_step(&iter)) {
429                         if (!setDrawOptions || setDrawOptions(userData, i)) {
430                                 glVertex3fv(eed->v1->co);
431                                 glVertex3fv(eed->v2->co);
432                         }
433                 }
434                 glEnd();
435         }
436 }
437 static void emDM_drawEdges(
438                 DerivedMesh *dm,
439                 int UNUSED(drawLooseEdges),
440                 int UNUSED(drawAllEdges))
441 {
442         emDM_drawMappedEdges(dm, NULL, NULL);
443 }
444
445 static void emDM_drawMappedEdgesInterp(
446                 DerivedMesh *dm,
447                 int (*setDrawOptions)(void *userData, int index),
448                 void (*setDrawInterpOptions)(void *userData, int index, float t),
449                 void *userData)
450 {
451         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
452         BMEdge *eed;
453         BMIter iter;
454         int i;
455
456         if (bmdm->vertexCos) {
457
458                 BM_mesh_elem_index_ensure(bmdm->tc->bm, BM_VERT);
459
460                 glBegin(GL_LINES);
461                 eed = BM_iter_new(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
462                 for (i=0; eed; i++,eed=BM_iter_step(&iter)) {
463                         if (!setDrawOptions || setDrawOptions(userData, i)) {
464                                 setDrawInterpOptions(userData, i, 0.0);
465                                 glVertex3fv(bmdm->vertexCos[BM_elem_index_get(eed->v1)]);
466                                 setDrawInterpOptions(userData, i, 1.0);
467                                 glVertex3fv(bmdm->vertexCos[BM_elem_index_get(eed->v2)]);
468                         }
469                 }
470                 glEnd();
471         }
472         else {
473                 glBegin(GL_LINES);
474                 eed = BM_iter_new(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
475                 for (i=0; eed; i++,eed=BM_iter_step(&iter)) {
476                         if (!setDrawOptions || setDrawOptions(userData, i)) {
477                                 setDrawInterpOptions(userData, i, 0.0);
478                                 glVertex3fv(eed->v1->co);
479                                 setDrawInterpOptions(userData, i, 1.0);
480                                 glVertex3fv(eed->v2->co);
481                         }
482                 }
483                 glEnd();
484         }
485 }
486
487 static void emDM_drawUVEdges(DerivedMesh *dm)
488 {
489         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
490         BMEditMesh *em = bmdm->tc;
491         BMFace *efa;
492         BMIter iter;
493
494         glBegin(GL_LINES);
495         BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
496                 BMIter liter;
497                 BMLoop *l;
498                 MLoopUV *lastluv = NULL, *firstluv = NULL;
499
500                 if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN))
501                         continue;
502
503                 BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
504                         MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
505
506                         if (luv) {
507                                 if (lastluv)
508                                         glVertex2fv(luv->uv);
509                                 glVertex2fv(luv->uv);
510
511                                 lastluv = luv;
512                                 if (!firstluv)
513                                         firstluv = luv;
514                         }
515                 }
516
517                 if (lastluv) {
518                         glVertex2fv(lastluv->uv);
519                         glVertex2fv(firstluv->uv);
520                 }
521         }
522         glEnd();
523 }
524
525 static void emDM__calcFaceCent(BMesh *bm, BMFace *efa, float cent[3], float (*vertexCos)[3])
526 {
527         BMIter iter;
528         BMLoop *l;
529         int tot = 0;
530
531         zero_v3(cent);
532
533         /*simple (and stupid) median (average) based method :/ */
534
535         if (vertexCos) {
536                 l = BM_iter_new(&iter, bm, BM_LOOPS_OF_FACE, efa);
537                 for (; l; l=BM_iter_step(&iter)) {
538                         add_v3_v3(cent, vertexCos[BM_elem_index_get(l->v)]);
539                         tot++;
540                 }
541         }
542         else {
543                 l = BM_iter_new(&iter, bm, BM_LOOPS_OF_FACE, efa);
544                 for (; l; l=BM_iter_step(&iter)) {
545                         add_v3_v3(cent, l->v->co);
546                         tot++;
547                 }
548         }
549
550         if (tot==0) return;
551         mul_v3_fl(cent, 1.0f/(float)tot);
552 }
553
554 static void emDM_foreachMappedFaceCenter(
555                 DerivedMesh *dm,
556                 void (*func)(void *userData, int index, float *co, float *no),
557                 void *userData)
558 {
559         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
560         float (*polyNos)[3] = NULL;
561         BMFace *efa;
562         BMIter iter;
563         float cent[3];
564         int i;
565
566         /* ensure for face center calculation */
567         if (bmdm->vertexCos) {
568                 BM_mesh_elem_index_ensure(bmdm->tc->bm, BM_VERT);
569                 polyNos = bmdm->polyNos;
570
571                 BLI_assert(polyNos != NULL);
572         }
573
574         efa = BM_iter_new(&iter, bmdm->tc->bm, BM_FACES_OF_MESH, NULL);
575         for (i=0; efa; efa=BM_iter_step(&iter), i++) {
576                 emDM__calcFaceCent(bmdm->tc->bm, efa, cent, bmdm->vertexCos);
577                 func(userData, i, cent, polyNos ? polyNos[i] : efa->no);
578         }
579 }
580
581 static void emDM_drawMappedFaces(
582                 DerivedMesh *dm,
583                 int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r),
584                 int (*setMaterial)(int, void *attribs),
585                 int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
586                 void *userData, int UNUSED(useColors))
587 {
588         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
589         BMFace *efa;
590         struct BMLoop *(*looptris)[3]= bmdm->tc->looptris;
591         const int tottri= bmdm->tc->tottri;
592         const int lasttri= tottri - 1; /* compare agasint this a lot */
593         int i, draw, flush;
594         const int skip_normals= !glIsEnabled(GL_LIGHTING); /* could be passed as an arg */
595
596         /* GL_ZERO is used to detect if drawing has started or not */
597         GLenum poly_prev= GL_ZERO;
598         GLenum shade_prev= GL_ZERO;
599
600         (void)setMaterial; /* UNUSED */
601
602         /* currently unused -- each original face is handled separately */
603         (void)compareDrawOptions;
604
605         if (bmdm->vertexCos) {
606                 /* add direct access */
607                 float (*vertexCos)[3]= bmdm->vertexCos;
608                 float (*vertexNos)[3]= bmdm->vertexNos;
609                 float (*polyNos)[3]=   bmdm->polyNos;
610                 // int *triPolyMap= bmdm->triPolyMap;
611
612                 BM_mesh_elem_index_ensure(bmdm->tc->bm, BM_VERT | BM_FACE);
613
614                 for (i=0; i < tottri; i++) {
615                         BMLoop **l = looptris[i];
616                         int drawSmooth;
617
618                         efa = l[0]->f;
619                         drawSmooth= BM_elem_flag_test(efa, BM_ELEM_SMOOTH);
620
621                         draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, BM_elem_index_get(efa), &drawSmooth);
622                         if (draw) {
623                                 const GLenum poly_type= GL_TRIANGLES; /* BMESH NOTE, this is odd but keep it for now to match trunk */
624                                 if (draw==2) { /* enabled with stipple */
625
626                                         if (poly_prev != GL_ZERO) glEnd();
627                                         poly_prev= GL_ZERO; /* force glBegin */
628
629                                         glEnable(GL_POLYGON_STIPPLE);
630                                         glPolygonStipple(stipple_quarttone);
631                                 }
632
633                                 if (skip_normals) {
634                                         if (poly_type != poly_prev) {
635                                                 if (poly_prev != GL_ZERO) glEnd();
636                                                 glBegin((poly_prev= poly_type)); /* BMesh: will always be GL_TRIANGLES */
637                                         }
638                                         glVertex3fv(vertexCos[BM_elem_index_get(l[0]->v)]);
639                                         glVertex3fv(vertexCos[BM_elem_index_get(l[1]->v)]);
640                                         glVertex3fv(vertexCos[BM_elem_index_get(l[2]->v)]);
641                                 }
642                                 else {
643                                         const GLenum shade_type= drawSmooth ? GL_SMOOTH : GL_FLAT;
644                                         if (shade_type != shade_prev) {
645                                                 if (poly_prev != GL_ZERO) glEnd();
646                                                 glShadeModel((shade_prev= shade_type)); /* same as below but switch shading */
647                                                 glBegin((poly_prev= poly_type)); /* BMesh: will always be GL_TRIANGLES */
648                                         }
649                                         if (poly_type != poly_prev) {
650                                                 if (poly_prev != GL_ZERO) glEnd();
651                                                 glBegin((poly_prev= poly_type)); /* BMesh: will always be GL_TRIANGLES */
652                                         }
653
654                                         if (!drawSmooth) {
655                                                 glNormal3fv(polyNos[BM_elem_index_get(efa)]);
656                                                 glVertex3fv(vertexCos[BM_elem_index_get(l[0]->v)]);
657                                                 glVertex3fv(vertexCos[BM_elem_index_get(l[1]->v)]);
658                                                 glVertex3fv(vertexCos[BM_elem_index_get(l[2]->v)]);
659                                         }
660                                         else {
661                                                 glNormal3fv(vertexNos[BM_elem_index_get(l[0]->v)]);
662                                                 glVertex3fv(vertexCos[BM_elem_index_get(l[0]->v)]);
663                                                 glNormal3fv(vertexNos[BM_elem_index_get(l[1]->v)]);
664                                                 glVertex3fv(vertexCos[BM_elem_index_get(l[1]->v)]);
665                                                 glNormal3fv(vertexNos[BM_elem_index_get(l[2]->v)]);
666                                                 glVertex3fv(vertexCos[BM_elem_index_get(l[2]->v)]);
667                                         }
668                                 }
669
670                                 flush= (draw==2);
671                                 if (!skip_normals && !flush && (i != lasttri))
672                                         flush|= efa->mat_nr != looptris[i + 1][0]->f->mat_nr; /* TODO, make this neater */
673
674                                 if (flush) {
675                                         glEnd();
676                                         poly_prev= GL_ZERO; /* force glBegin */
677
678                                         glDisable(GL_POLYGON_STIPPLE);
679                                 }
680                         }
681                 }
682         }
683         else {
684                 BM_mesh_elem_index_ensure(bmdm->tc->bm, BM_FACE);
685
686                 for (i=0; i < tottri; i++) {
687                         BMLoop **l = looptris[i];
688                         int drawSmooth;
689
690                         efa = l[0]->f;
691                         drawSmooth= BM_elem_flag_test(efa, BM_ELEM_SMOOTH);
692
693                         draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, BM_elem_index_get(efa), &drawSmooth);
694                         if (draw) {
695                                 const GLenum poly_type= GL_TRIANGLES; /* BMESH NOTE, this is odd but keep it for now to match trunk */
696                                 if (draw==2) { /* enabled with stipple */
697
698                                         if (poly_prev != GL_ZERO) glEnd();
699                                         poly_prev= GL_ZERO; /* force glBegin */
700
701                                         glEnable(GL_POLYGON_STIPPLE);
702                                         glPolygonStipple(stipple_quarttone);
703                                 }
704
705                                 if (skip_normals) {
706                                         if (poly_type != poly_prev) {
707                                                 if (poly_prev != GL_ZERO) glEnd();
708                                                 glBegin((poly_prev= poly_type)); /* BMesh: will always be GL_TRIANGLES */
709                                         }
710                                         glVertex3fv(l[0]->v->co);
711                                         glVertex3fv(l[1]->v->co);
712                                         glVertex3fv(l[2]->v->co);
713                                 }
714                                 else {
715                                         const GLenum shade_type= drawSmooth ? GL_SMOOTH : GL_FLAT;
716                                         if (shade_type != shade_prev) {
717                                                 if (poly_prev != GL_ZERO) glEnd();
718                                                 glShadeModel((shade_prev= shade_type)); /* same as below but switch shading */
719                                                 glBegin((poly_prev= poly_type)); /* BMesh: will always be GL_TRIANGLES */
720                                         }
721                                         if (poly_type != poly_prev) {
722                                                 if (poly_prev != GL_ZERO) glEnd();
723                                                 glBegin((poly_prev= poly_type)); /* BMesh: will always be GL_TRIANGLES */
724                                         }
725
726                                         if (!drawSmooth) {
727                                                 glNormal3fv(efa->no);
728                                                 glVertex3fv(l[0]->v->co);
729                                                 glVertex3fv(l[1]->v->co);
730                                                 glVertex3fv(l[2]->v->co);
731                                         }
732                                         else {
733                                                 glNormal3fv(l[0]->v->no);
734                                                 glVertex3fv(l[0]->v->co);
735                                                 glNormal3fv(l[1]->v->no);
736                                                 glVertex3fv(l[1]->v->co);
737                                                 glNormal3fv(l[2]->v->no);
738                                                 glVertex3fv(l[2]->v->co);
739                                         }
740                                 }
741
742                                 flush= (draw==2);
743                                 if (!skip_normals && !flush && (i != lasttri)) {
744                                         flush|= efa->mat_nr != looptris[i + 1][0]->f->mat_nr; /* TODO, make this neater */
745                                 }
746
747                                 if (flush) {
748                                         glEnd();
749                                         poly_prev= GL_ZERO; /* force glBegin */
750
751                                         glDisable(GL_POLYGON_STIPPLE);
752                                 }
753                         }
754                 }
755         }
756
757         /* if non zero we know a face was rendered */
758         if (poly_prev != GL_ZERO) glEnd();
759 }
760
761 static void bmdm_get_tri_tex(BMesh *bm, BMLoop **ls, MLoopUV *luv[3], MLoopCol *lcol[3],
762                                  int has_uv, int has_col)
763 {
764         if (has_uv) {
765                 luv[0] = CustomData_bmesh_get(&bm->ldata, ls[0]->head.data, CD_MLOOPUV);
766                 luv[1] = CustomData_bmesh_get(&bm->ldata, ls[1]->head.data, CD_MLOOPUV);
767                 luv[2] = CustomData_bmesh_get(&bm->ldata, ls[2]->head.data, CD_MLOOPUV);
768         }
769
770         if (has_col) {
771                 lcol[0] = CustomData_bmesh_get(&bm->ldata, ls[0]->head.data, CD_MLOOPCOL);
772                 lcol[1] = CustomData_bmesh_get(&bm->ldata, ls[1]->head.data, CD_MLOOPCOL);
773                 lcol[2] = CustomData_bmesh_get(&bm->ldata, ls[2]->head.data, CD_MLOOPCOL);
774         }
775
776
777 }
778
779 static void emDM_drawFacesTex_common(
780                 DerivedMesh *dm,
781                 int (*drawParams)(MTFace *tface, int has_vcol, int matnr),
782                 int (*drawParamsMapped)(void *userData, int index),
783                 int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
784                 void *userData)
785 {
786         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
787         BMEditMesh *em = bmdm->tc;
788         BMesh *bm= bmdm->tc->bm;
789         float (*vertexCos)[3]= bmdm->vertexCos;
790         float (*vertexNos)[3]= bmdm->vertexNos;
791         BMFace *efa;
792         MLoopUV *luv[3], dummyluv = {{0}};
793         MLoopCol *lcol[3], dummylcol = {0};
794         int i, has_vcol = CustomData_has_layer(&bm->ldata, CD_MLOOPCOL);
795         int has_uv = CustomData_has_layer(&bm->pdata, CD_MTEXPOLY);
796
797         (void) compareDrawOptions;
798
799         luv[0] = luv[1] = luv[2] = &dummyluv;
800         lcol[0] = lcol[1] = lcol[2] = &dummylcol;
801
802         dummylcol.a = dummylcol.r = dummylcol.g = dummylcol.b = 255;
803
804         /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
805         glShadeModel(GL_SMOOTH);
806
807         BM_mesh_elem_index_ensure(bm, BM_FACE);
808
809         if (vertexCos) {
810                 BM_mesh_elem_index_ensure(bm, BM_VERT);
811
812                 glBegin(GL_TRIANGLES);
813                 for (i=0; i<em->tottri; i++) {
814                         BMLoop **ls = em->looptris[i];
815                         MTexPoly *tp= has_uv ? CustomData_bmesh_get(&bm->pdata, ls[0]->f->head.data, CD_MTEXPOLY) : NULL;
816                         MTFace mtf = {{{0}}};
817                         /*unsigned char *cp= NULL;*/ /*UNUSED*/
818                         int drawSmooth= BM_elem_flag_test(ls[0]->f, BM_ELEM_SMOOTH);
819                         int flag;
820
821                         efa = ls[0]->f;
822
823                         if (has_uv) {
824                                 ME_MTEXFACE_CPY(&mtf, tp);
825                         }
826
827                         if (drawParams)
828                                 flag= drawParams(&mtf, has_vcol, efa->mat_nr);
829                         else if (drawParamsMapped)
830                                 flag= drawParamsMapped(userData, BM_elem_index_get(efa));
831                         else
832                                 flag= 1;
833
834                         if (flag != 0) { /* flag 0 == the face is hidden or invisible */
835
836                                 if (!drawSmooth) {
837                                         glNormal3fv(bmdm->polyNos[BM_elem_index_get(efa)]);
838
839                                         bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol);
840
841                                         glTexCoord2fv(luv[0]->uv);
842                                         glColor3ub(lcol[0]->b, lcol[0]->g, lcol[0]->r);
843                                         glVertex3fv(vertexCos[BM_elem_index_get(ls[0]->v)]);
844
845                                         glTexCoord2fv(luv[1]->uv);
846                                         glColor3ub(lcol[1]->b, lcol[1]->g, lcol[1]->r);
847                                         glVertex3fv(vertexCos[BM_elem_index_get(ls[1]->v)]);
848
849                                         glTexCoord2fv(luv[2]->uv);
850                                         glColor3ub(lcol[2]->b, lcol[2]->g, lcol[2]->r);
851                                         glVertex3fv(vertexCos[BM_elem_index_get(ls[2]->v)]);
852                                 }
853                                 else {
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                                         glNormal3fv(vertexNos[BM_elem_index_get(ls[0]->v)]);
859                                         glVertex3fv(vertexCos[BM_elem_index_get(ls[0]->v)]);
860
861                                         glTexCoord2fv(luv[1]->uv);
862                                         glColor3ub(lcol[1]->b, lcol[1]->g, lcol[1]->r);
863                                         glNormal3fv(vertexNos[BM_elem_index_get(ls[1]->v)]);
864                                         glVertex3fv(vertexCos[BM_elem_index_get(ls[1]->v)]);
865
866                                         glTexCoord2fv(luv[2]->uv);
867                                         glColor3ub(lcol[2]->b, lcol[2]->g, lcol[2]->r);
868                                         glNormal3fv(vertexNos[BM_elem_index_get(ls[2]->v)]);
869                                         glVertex3fv(vertexCos[BM_elem_index_get(ls[2]->v)]);
870                                 }
871                         }
872                 }
873                 glEnd();
874         }
875         else {
876                 BM_mesh_elem_index_ensure(bm, BM_VERT);
877
878                 for (i=0; i<em->tottri; i++) {
879                         BMLoop **ls = em->looptris[i];
880                         MTexPoly *tp= has_uv ? CustomData_bmesh_get(&bm->pdata, ls[0]->f->head.data, CD_MTEXPOLY) : NULL;
881                         MTFace mtf = {{{0}}};
882                         /*unsigned char *cp= NULL;*/ /*UNUSED*/
883                         int drawSmooth= BM_elem_flag_test(ls[0]->f, BM_ELEM_SMOOTH);
884                         int flag;
885
886                         efa = ls[0]->f;
887
888                         if (has_uv) {
889                                 ME_MTEXFACE_CPY(&mtf, tp);
890                         }
891
892                         if (drawParams)
893                                 flag= drawParams(&mtf, has_vcol, efa->mat_nr);
894                         else if (drawParamsMapped)
895                                 flag= drawParamsMapped(userData, BM_elem_index_get(efa));
896                         else
897                                 flag= 1;
898
899                         if (flag != 0) { /* flag 0 == the face is hidden or invisible */
900
901                                 glBegin(GL_TRIANGLES);
902                                 if (!drawSmooth) {
903                                         glNormal3fv(efa->no);
904
905                                         bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol);
906
907                                         if (luv[0])
908                                                 glTexCoord2fv(luv[0]->uv);
909                                         if (lcol[0])
910                                                 glColor3ub(lcol[0]->b, lcol[0]->g, lcol[0]->r);
911                                         else glColor3ub(0, 0, 0);
912                                         glVertex3fv(ls[0]->v->co);
913
914                                         if (luv[1])
915                                                 glTexCoord2fv(luv[1]->uv);
916                                         if (lcol[1])
917                                                 glColor3ub(lcol[1]->b, lcol[1]->g, lcol[1]->r);
918                                         else glColor3ub(0, 0, 0);
919                                         glVertex3fv(ls[1]->v->co);
920
921                                         if (luv[2])
922                                                 glTexCoord2fv(luv[2]->uv);
923                                         if (lcol[2])
924                                                 glColor3ub(lcol[2]->b, lcol[2]->g, lcol[2]->r);
925                                         else glColor3ub(0, 0, 0);
926                                         glVertex3fv(ls[2]->v->co);
927                                 }
928                                 else {
929                                         bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol);
930
931                                         if (luv[0])
932                                                 glTexCoord2fv(luv[0]->uv);
933                                         if (lcol[0])
934                                                 glColor3ub(lcol[0]->b, lcol[0]->g, lcol[0]->r);
935                                         else glColor3ub(0, 0, 0);
936                                         glNormal3fv(ls[0]->v->no);
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                                         glNormal3fv(ls[1]->v->no);
945                                         glVertex3fv(ls[1]->v->co);
946
947                                         if (luv[2])
948                                                 glTexCoord2fv(luv[2]->uv);
949                                         if (lcol[2])
950                                                 glColor3ub(lcol[2]->b, lcol[2]->g, lcol[2]->r);
951                                         else glColor3ub(0, 0, 0);
952                                         glNormal3fv(ls[2]->v->no);
953                                         glVertex3fv(ls[2]->v->co);
954                                 }
955                                 glEnd();
956                         }
957                 }
958         }
959
960         glShadeModel(GL_FLAT);
961 }
962
963 static void emDM_drawFacesTex(
964                 DerivedMesh *dm,
965                 int (*setDrawOptions)(MTFace *tface, int has_vcol, int matnr),
966                 int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
967                 void *userData)
968 {
969         emDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData);
970 }
971
972 static void emDM_drawMappedFacesTex(
973                 DerivedMesh *dm,
974                 int (*setDrawOptions)(void *userData, int index),
975                 int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
976                 void *userData)
977 {
978         emDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData);
979 }
980
981 static void emDM_drawMappedFacesGLSL(
982                 DerivedMesh *dm,
983                 int (*setMaterial)(int, void *attribs),
984                 int (*setDrawOptions)(void *userData, int index),
985                 void *userData)
986 {
987         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
988         BMesh *bm= bmdm->tc->bm;
989         BMEditMesh *em = bmdm->tc;
990         float (*vertexCos)[3]= bmdm->vertexCos;
991         float (*vertexNos)[3]= bmdm->vertexNos;
992         BMFace *efa;
993         BMLoop **ltri;
994         DMVertexAttribs attribs;
995         GPUVertexAttribs gattribs;
996
997         int i, b, matnr, new_matnr, dodraw;
998
999         dodraw = 0;
1000         matnr = -1;
1001
1002         memset(&attribs, 0, sizeof(attribs));
1003
1004         /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
1005         glShadeModel(GL_SMOOTH);
1006         BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE);
1007
1008 #define PASSATTRIB(loop, eve, vert) {                                                                                   \
1009         if (attribs.totorco) {                                                                                                          \
1010                 float *orco = attribs.orco.array[BM_elem_index_get(eve)];                                               \
1011                 glVertexAttrib3fvARB(attribs.orco.glIndex, orco);                                               \
1012         }                                                                                                                                                       \
1013         for (b = 0; b < attribs.tottface; b++) {                                                                        \
1014                 MLoopUV *_luv = CustomData_bmesh_get_n(&bm->ldata, loop->head.data, CD_MLOOPUV, b);\
1015                 glVertexAttrib2fvARB(attribs.tface[b].glIndex, _luv->uv);                               \
1016         }                                                                                                                                                       \
1017         for (b = 0; b < attribs.totmcol; b++) {                                                                         \
1018                 MLoopCol *_cp = CustomData_bmesh_get_n(&bm->ldata, loop->head.data, CD_MLOOPCOL, b);\
1019                 GLubyte _col[4];                                                                                                                \
1020                 _col[0]= _cp->b; _col[1]= _cp->g; _col[2]= _cp->r; _col[3]= _cp->a;             \
1021                 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, _col);                                   \
1022         }                                                                                                                                                       \
1023         if (attribs.tottang) {                                                                                                          \
1024                 float *tang = attribs.tang.array[i*4 + vert];                                                   \
1025                 glVertexAttrib3fvARB(attribs.tang.glIndex, tang);                                               \
1026         }                                                                                                                                                       \
1027         }
1028
1029
1030         for (i=0, ltri=em->looptris[0]; i<em->tottri; i++, ltri += 3) {
1031                 int drawSmooth;
1032
1033                 efa = ltri[0]->f;
1034                 drawSmooth= BM_elem_flag_test(efa, BM_ELEM_SMOOTH);
1035
1036                 if (setDrawOptions && !setDrawOptions(userData, BM_elem_index_get(efa)))
1037                         continue;
1038
1039                 new_matnr = efa->mat_nr + 1;
1040                 if (new_matnr != matnr) {
1041                         dodraw = setMaterial(matnr = new_matnr, &gattribs);
1042                         if (dodraw)
1043                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1044                 }
1045
1046                 if (dodraw) {
1047                         glBegin(GL_TRIANGLES);
1048                         if (!drawSmooth) {
1049                                 if (vertexCos) glNormal3fv(bmdm->polyNos[BM_elem_index_get(efa)]);
1050                                 else glNormal3fv(efa->no);
1051
1052                                 PASSATTRIB(ltri[0], ltri[0]->v, 0);
1053                                 if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
1054                                 else glVertex3fv(ltri[0]->v->co);
1055
1056                                 PASSATTRIB(ltri[1], ltri[1]->v, 1);
1057                                 if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
1058                                 else glVertex3fv(ltri[1]->v->co);
1059
1060                                 PASSATTRIB(ltri[2], ltri[2]->v, 2);
1061                                 if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
1062                                 else glVertex3fv(ltri[2]->v->co);
1063                         }
1064                         else {
1065                                 PASSATTRIB(ltri[0], ltri[0]->v, 0);
1066                                 if (vertexCos) {
1067                                         glNormal3fv(vertexNos[BM_elem_index_get(ltri[0]->v)]);
1068                                         glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
1069                                 }
1070                                 else {
1071                                         glNormal3fv(ltri[0]->v->no);
1072                                         glVertex3fv(ltri[0]->v->co);
1073                                 }
1074
1075                                 PASSATTRIB(ltri[1], ltri[1]->v, 1);
1076                                 if (vertexCos) {
1077                                         glNormal3fv(vertexNos[BM_elem_index_get(ltri[1]->v)]);
1078                                         glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
1079                                 }
1080                                 else {
1081                                         glNormal3fv(ltri[1]->v->no);
1082                                         glVertex3fv(ltri[1]->v->co);
1083                                 }
1084
1085                                 PASSATTRIB(ltri[2], ltri[2]->v, 2);
1086                                 if (vertexCos) {
1087                                         glNormal3fv(vertexNos[BM_elem_index_get(ltri[2]->v)]);
1088                                         glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
1089                                 }
1090                                 else {
1091                                         glNormal3fv(ltri[2]->v->no);
1092                                         glVertex3fv(ltri[2]->v->co);
1093                                 }
1094                         }
1095                         glEnd();
1096                 }
1097         }
1098 #undef PASSATTRIB
1099 }
1100
1101 static void emDM_drawFacesGLSL(
1102                 DerivedMesh *dm,
1103                 int (*setMaterial)(int, void *attribs))
1104 {
1105         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1106 }
1107
1108 static void emDM_drawMappedFacesMat(
1109                 DerivedMesh *dm,
1110                 void (*setMaterial)(void *userData, int, void *attribs),
1111                 int (*setFace)(void *userData, int index), void *userData)
1112 {
1113         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1114         BMesh *bm= bmdm->tc->bm;
1115         BMEditMesh *em = bmdm->tc;
1116         float (*vertexCos)[3]= bmdm->vertexCos;
1117         float (*vertexNos)[3]= bmdm->vertexNos;
1118         BMFace *efa;
1119         BMLoop **ltri;
1120         DMVertexAttribs attribs= {{{0}}};
1121         GPUVertexAttribs gattribs;
1122         int i, b, matnr, new_matnr;
1123
1124         matnr = -1;
1125
1126         /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
1127         glShadeModel(GL_SMOOTH);
1128
1129         BM_mesh_elem_index_ensure(bm, BM_VERT);
1130
1131 #define PASSATTRIB(loop, eve, vert) {                                                                                   \
1132         if (attribs.totorco) {                                                                                                          \
1133                 float *orco = attribs.orco.array[BM_elem_index_get(eve)];                                               \
1134                 glVertexAttrib3fvARB(attribs.orco.glIndex, orco);                                               \
1135         }                                                                                                                                                       \
1136         for (b = 0; b < attribs.tottface; b++) {                                                                        \
1137                 MLoopUV *_luv = CustomData_bmesh_get_n(&bm->ldata, loop->head.data, CD_MLOOPUV, b);\
1138                 glVertexAttrib2fvARB(attribs.tface[b].glIndex, _luv->uv);                               \
1139         }                                                                                                                                                       \
1140         for (b = 0; b < attribs.totmcol; b++) {                                                                         \
1141                 MLoopCol *_cp = CustomData_bmesh_get_n(&bm->ldata, loop->head.data, CD_MLOOPCOL, b);\
1142                 GLubyte _col[4];                                                                                                                \
1143                 _col[0]= _cp->b; _col[1]= _cp->g; _col[2]= _cp->r; _col[3]= _cp->a;             \
1144                 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, _col);                                   \
1145         }                                                                                                                                                       \
1146         if (attribs.tottang) {                                                                                                          \
1147                 float *tang = attribs.tang.array[i*4 + vert];                                                   \
1148                 glVertexAttrib4fvARB(attribs.tang.glIndex, tang);                                               \
1149         }                                                                                                                                                       \
1150 }
1151
1152         for (i=0, ltri=em->looptris[0]; i<em->tottri; i++, ltri += 3) {
1153                 int drawSmooth;
1154
1155                 efa = ltri[0]->f;
1156                 drawSmooth = BM_elem_flag_test(efa, BM_ELEM_SMOOTH);
1157
1158                 /* face hiding */
1159                 if (setFace && !setFace(userData, BM_elem_index_get(efa)))
1160                         continue;
1161
1162                 /* material */
1163                 new_matnr = efa->mat_nr + 1;
1164                 if (new_matnr != matnr) {
1165                         setMaterial(userData, matnr = new_matnr, &gattribs);
1166                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1167                 }
1168
1169                 /* face */
1170                 glBegin(GL_TRIANGLES);
1171                 if (!drawSmooth) {
1172                         if (vertexCos) glNormal3fv(bmdm->polyNos[BM_elem_index_get(efa)]);
1173                         else glNormal3fv(efa->no);
1174
1175                         PASSATTRIB(ltri[0], ltri[0]->v, 0);
1176                         if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
1177                         else glVertex3fv(ltri[0]->v->co);
1178
1179                         PASSATTRIB(ltri[1], ltri[1]->v, 1);
1180                         if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
1181                         else glVertex3fv(ltri[1]->v->co);
1182
1183                         PASSATTRIB(ltri[2], ltri[2]->v, 2);
1184                         if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
1185                         else glVertex3fv(ltri[2]->v->co);
1186
1187                 }
1188                 else {
1189                         PASSATTRIB(ltri[0], ltri[0]->v, 0);
1190                         if (vertexCos) {
1191                                 glNormal3fv(vertexNos[BM_elem_index_get(ltri[0]->v)]);
1192                                 glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
1193                         }
1194                         else {
1195                                 glNormal3fv(ltri[0]->v->no);
1196                                 glVertex3fv(ltri[0]->v->co);
1197                         }
1198
1199                         PASSATTRIB(ltri[1], ltri[1]->v, 1);
1200                         if (vertexCos) {
1201                                 glNormal3fv(vertexNos[BM_elem_index_get(ltri[1]->v)]);
1202                                 glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
1203                         }
1204                         else {
1205                                 glNormal3fv(ltri[1]->v->no);
1206                                 glVertex3fv(ltri[1]->v->co);
1207                         }
1208
1209                         PASSATTRIB(ltri[2], ltri[2]->v, 2);
1210                         if (vertexCos) {
1211                                 glNormal3fv(vertexNos[BM_elem_index_get(ltri[2]->v)]);
1212                                 glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
1213                         }
1214                         else {
1215                                 glNormal3fv(ltri[2]->v->no);
1216                                 glVertex3fv(ltri[2]->v->co);
1217                         }
1218                 }
1219                 glEnd();
1220         }
1221 #undef PASSATTRIB
1222 }
1223
1224 static void emDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
1225 {
1226         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1227         BMVert *eve;
1228         BMIter iter;
1229         int i;
1230
1231         if (bmdm->tc->bm->totvert) {
1232                 eve = BM_iter_new(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
1233                 for (i=0; eve; eve=BM_iter_step(&iter), i++) {
1234                         if (bmdm->vertexCos) {
1235                                 DO_MINMAX(bmdm->vertexCos[i], min_r, max_r);
1236                         }
1237                         else {
1238                                 DO_MINMAX(eve->co, min_r, max_r);
1239                         }
1240                 }
1241         }
1242         else {
1243                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
1244         }
1245 }
1246 static int emDM_getNumVerts(DerivedMesh *dm)
1247 {
1248         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1249
1250         return bmdm->tc->bm->totvert;
1251 }
1252
1253 static int emDM_getNumEdges(DerivedMesh *dm)
1254 {
1255         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1256
1257         return bmdm->tc->bm->totedge;
1258 }
1259
1260 static int emDM_getNumTessFaces(DerivedMesh *dm)
1261 {
1262         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1263
1264         return bmdm->tc->tottri;
1265 }
1266
1267 static int emDM_getNumLoops(DerivedMesh *dm)
1268 {
1269         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1270
1271         return bmdm->tc->bm->totloop;
1272 }
1273
1274 static int emDM_getNumPolys(DerivedMesh *dm)
1275 {
1276         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1277
1278         return bmdm->tc->bm->totface;
1279 }
1280
1281 static int bmvert_to_mvert(BMesh *bm, BMVert *ev, MVert *vert_r)
1282 {
1283         copy_v3_v3(vert_r->co, ev->co);
1284
1285         normal_float_to_short_v3(vert_r->no, ev->no);
1286
1287         vert_r->flag = BM_vert_flag_to_mflag(ev);
1288
1289         if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
1290                 vert_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->vdata, ev, CD_BWEIGHT)*255.0f);
1291         }
1292
1293         return 1;
1294 }
1295
1296 static void emDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
1297 {
1298         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1299         BMVert *ev;
1300
1301         if (index < 0 || index >= bmdm->tv) {
1302                 printf("error in emDM_getVert.\n");
1303                 return;
1304         }
1305
1306         // ev = EDBM_get_vert_for_index(bmdm->tc, index);
1307         ev = BM_vert_at_index(bmdm->tc->bm, index); /* warning, does list loop, _not_ ideal */
1308
1309         bmvert_to_mvert(bmdm->tc->bm, ev, vert_r);
1310 }
1311
1312 static void emDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
1313 {
1314         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1315         BMesh *bm = bmdm->tc->bm;
1316         BMEdge *e;
1317
1318         if (index < 0 || index >= bmdm->te) {
1319                 printf("error in emDM_getEdge.\n");
1320                 return;
1321         }
1322
1323         // e = EDBM_get_edge_for_index(bmdm->tc, index);
1324         e = BM_edge_at_index(bmdm->tc->bm, index); /* warning, does list loop, _not_ ideal */
1325
1326         if (CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
1327                 edge_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->edata, e, CD_BWEIGHT)*255.0f);
1328         }
1329
1330         if (CustomData_has_layer(&bm->edata, CD_CREASE)) {
1331                 edge_r->crease = (unsigned char) (BM_elem_float_data_get(&bm->edata, e, CD_CREASE)*255.0f);
1332         }
1333
1334         edge_r->flag = BM_edge_flag_to_mflag(e);
1335
1336         edge_r->v1 = BM_elem_index_get(e->v1);
1337         edge_r->v2 = BM_elem_index_get(e->v2);
1338 }
1339
1340 static void emDM_getTessFace(DerivedMesh *dm, int index, MFace *face_r)
1341 {
1342         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1343         BMFace *ef;
1344         BMLoop **l;
1345
1346         if (index < 0 || index >= bmdm->tf) {
1347                 printf("error in emDM_getTessFace.\n");
1348                 return;
1349         }
1350
1351         l = bmdm->tc->looptris[index];
1352
1353         ef = l[0]->f;
1354
1355         face_r->mat_nr = (unsigned char) ef->mat_nr;
1356         face_r->flag = BM_face_flag_to_mflag(ef);
1357
1358         face_r->v1 = BM_elem_index_get(l[0]->v);
1359         face_r->v2 = BM_elem_index_get(l[1]->v);
1360         face_r->v3 = BM_elem_index_get(l[2]->v);
1361         face_r->v4 = 0;
1362
1363         test_index_face(face_r, NULL, 0, 3);
1364 }
1365
1366 static void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
1367 {
1368         BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
1369         BMVert *ev;
1370         BMIter iter;
1371
1372         ev = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL);
1373         for ( ; ev; ev = BM_iter_step(&iter), ++vert_r) {
1374                 copy_v3_v3(vert_r->co, ev->co);
1375
1376                 normal_float_to_short_v3(vert_r->no, ev->no);
1377
1378                 vert_r->flag = BM_vert_flag_to_mflag(ev);
1379
1380                 if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
1381                         vert_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->vdata, ev, CD_BWEIGHT)*255.0f);
1382                 }
1383         }
1384 }
1385
1386 static void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
1387 {
1388         BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
1389         BMEdge *ee;
1390         BMIter iter;
1391         int has_bweight = CustomData_has_layer(&bm->edata, CD_BWEIGHT);
1392         int has_crease = CustomData_has_layer(&bm->edata, CD_CREASE);
1393
1394         BM_mesh_elem_index_ensure(bm, BM_VERT);
1395
1396         ee = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, NULL);
1397         for ( ; ee; ee=BM_iter_step(&iter), edge_r++) {
1398                 if (has_bweight) {
1399                         edge_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->edata, ee, CD_BWEIGHT)*255.0f);
1400                 }
1401
1402                 if (has_crease) {
1403                         edge_r->crease = (unsigned char) (BM_elem_float_data_get(&bm->edata, ee, CD_CREASE)*255.0f);
1404                 }
1405
1406                 edge_r->flag = BM_edge_flag_to_mflag(ee);
1407
1408                 edge_r->v1 = BM_elem_index_get(ee->v1);
1409                 edge_r->v2 = BM_elem_index_get(ee->v2);
1410         }
1411 }
1412
1413 static void emDM_copyTessFaceArray(DerivedMesh *dm, MFace *face_r)
1414 {
1415         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1416         BMesh *bm = bmdm->tc->bm;
1417         BMFace *ef;
1418         BMLoop **l;
1419         int i;
1420
1421         BM_mesh_elem_index_ensure(bm, BM_VERT);
1422
1423         for (i=0; i<bmdm->tc->tottri; i++, face_r++) {
1424                 l = bmdm->tc->looptris[i];
1425                 ef = l[0]->f;
1426
1427                 face_r->mat_nr = (unsigned char) ef->mat_nr;
1428
1429                 face_r->flag = BM_face_flag_to_mflag(ef);
1430
1431                 face_r->v1 = BM_elem_index_get(l[0]->v);
1432                 face_r->v2 = BM_elem_index_get(l[1]->v);
1433                 face_r->v3 = BM_elem_index_get(l[2]->v);
1434                 face_r->v4 = 0;
1435
1436                 test_index_face(face_r, NULL, 0, 3);
1437         }
1438 }
1439
1440
1441 static void emDM_copyLoopArray(DerivedMesh *dm, MLoop *loop_r)
1442 {
1443         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1444         BMesh *bm = bmdm->tc->bm;
1445         BMIter iter, liter;
1446         BMFace *f;
1447         BMLoop *l;
1448
1449         BM_mesh_elem_index_ensure(bm, BM_VERT | BM_EDGE);
1450
1451         BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
1452                 BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) {
1453                         loop_r->v = BM_elem_index_get(l->v);
1454                         loop_r->e = BM_elem_index_get(l->e);
1455                         loop_r++;
1456                 }
1457         }
1458 }
1459
1460 static void emDM_copyPolyArray(DerivedMesh *dm, MPoly *poly_r)
1461 {
1462         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1463         BMesh *bm = bmdm->tc->bm;
1464         BMIter iter;
1465         BMFace *f;
1466         int i;
1467
1468         i = 0;
1469         BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
1470                 poly_r->flag = BM_face_flag_to_mflag(f);
1471                 poly_r->loopstart = i;
1472                 poly_r->totloop = f->len;
1473                 poly_r->mat_nr = f->mat_nr;
1474
1475                 poly_r++;
1476                 i += f->len;
1477         }
1478 }
1479
1480 static void *emDM_getTessFaceDataArray(DerivedMesh *dm, int type)
1481 {
1482         EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1483         BMesh *bm= bmdm->tc->bm;
1484         BMFace *efa;
1485         char *data, *bmdata;
1486         void *datalayer;
1487         int index /*, offset*/ /*UNUSED */, size, i;
1488
1489         datalayer = DM_get_tessface_data_layer(dm, type);
1490         if (datalayer)
1491                 return datalayer;
1492
1493         /* layers are store per face for editmesh, we convert to a tbmporary
1494          * data layer array in the derivedmesh when these are requested */
1495         if (type == CD_MTFACE || type == CD_MCOL) {
1496                 index = CustomData_get_layer_index(&bm->pdata, type);
1497
1498                 if (index != -1) {
1499                         /* offset = bm->pdata.layers[index].offset; */ /* UNUSED */
1500                         size = CustomData_sizeof(type);
1501
1502                         DM_add_tessface_layer(dm, type, CD_CALLOC, NULL);
1503                         index = CustomData_get_layer_index(&dm->faceData, type);
1504                         dm->faceData.layers[index].flag |= CD_FLAG_TEMPORARY;
1505
1506                         data = datalayer = DM_get_tessface_data_layer(dm, type);
1507                         for (i=0; i<bmdm->tc->tottri; i++, data+=size) {
1508                                 efa = bmdm->tc->looptris[i][0]->f;
1509                                 /*BMESH_TODO: need to still add tface data,
1510                                   derived from the loops.*/
1511                                 bmdata = CustomData_bmesh_get(&bm->pdata, efa->head.data, type);
1512                                 memcpy(data, bmdata, size);
1513                         }
1514                 }
1515         }
1516
1517         return datalayer;
1518 }
1519
1520 static void emDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
1521 {
1522         EditDerivedBMesh *emdm= (EditDerivedBMesh*) dm;
1523         BMVert *eve;
1524         BMIter iter;
1525         int i;
1526
1527         i= 0;
1528         BM_ITER(eve, &iter, emdm->tc->bm, BM_VERTS_OF_MESH, NULL) {
1529                 if (emdm->vertexCos) {
1530                         copy_v3_v3(cos_r[i], emdm->vertexCos[i]);
1531                 }
1532                 else {
1533                         copy_v3_v3(cos_r[i], eve->co);
1534                 }
1535
1536                 i++;
1537         }
1538 }
1539
1540 static void emDM_release(DerivedMesh *dm)
1541 {
1542         EditDerivedBMesh *bmdm= (EditDerivedBMesh *)dm;
1543
1544         if (DM_release(dm)) {
1545                 if (bmdm->vertexCos) {
1546                         MEM_freeN(bmdm->vertexCos);
1547                         MEM_freeN(bmdm->vertexNos);
1548                         MEM_freeN(bmdm->polyNos);
1549                 }
1550
1551                 MEM_freeN(bmdm);
1552         }
1553 }
1554
1555 static CustomData *bmDm_getVertDataLayout(DerivedMesh *dm)
1556 {
1557         EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm;
1558
1559         return &bmdm->tc->bm->vdata;
1560 }
1561
1562 static CustomData *bmDm_getEdgeDataLayout(DerivedMesh *dm)
1563 {
1564         EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm;
1565
1566         return &bmdm->tc->bm->edata;
1567 }
1568
1569 static CustomData *bmDm_getTessFaceDataLayout(DerivedMesh *dm)
1570 {
1571         EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm;
1572
1573         return &bmdm->dm.faceData;
1574 }
1575
1576 static CustomData *bmDm_getLoopDataLayout(DerivedMesh *dm)
1577 {
1578         EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm;
1579
1580         return &bmdm->tc->bm->ldata;
1581 }
1582
1583 static CustomData *bmDm_getPolyDataLayout(DerivedMesh *dm)
1584 {
1585         EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm;
1586
1587         return &bmdm->tc->bm->pdata;
1588 }
1589
1590
1591 DerivedMesh *getEditDerivedBMesh(
1592                 BMEditMesh *em,
1593                 Object *UNUSED(ob),
1594                 float (*vertexCos)[3])
1595 {
1596         EditDerivedBMesh *bmdm = MEM_callocN(sizeof(*bmdm), __func__);
1597         BMesh *bm = em->bm;
1598
1599         bmdm->tc = em;
1600
1601         DM_init((DerivedMesh*)bmdm, DM_TYPE_EDITBMESH, em->bm->totvert,
1602                  em->bm->totedge, em->tottri, em->bm->totloop, em->bm->totface);
1603
1604         CustomData_from_bmeshpoly(&bmdm->dm.faceData, &em->bm->pdata, &em->bm->ldata, 0);
1605
1606         bmdm->dm.getVertCos = emDM_getVertCos;
1607         bmdm->dm.getMinMax = emDM_getMinMax;
1608
1609         bmdm->dm.getVertDataLayout = bmDm_getVertDataLayout;
1610         bmdm->dm.getEdgeDataLayout = bmDm_getEdgeDataLayout;
1611         bmdm->dm.getTessFaceDataLayout = bmDm_getTessFaceDataLayout;
1612         bmdm->dm.getLoopDataLayout = bmDm_getLoopDataLayout;
1613         bmdm->dm.getPolyDataLayout = bmDm_getPolyDataLayout;
1614
1615         bmdm->dm.getNumVerts = emDM_getNumVerts;
1616         bmdm->dm.getNumEdges = emDM_getNumEdges;
1617         bmdm->dm.getNumTessFaces = emDM_getNumTessFaces;
1618         bmdm->dm.getNumLoops = emDM_getNumLoops;
1619         bmdm->dm.getNumPolys = emDM_getNumPolys;
1620
1621         bmdm->dm.getVert = emDM_getVert;
1622         bmdm->dm.getEdge = emDM_getEdge;
1623         bmdm->dm.getTessFace = emDM_getTessFace;
1624         bmdm->dm.copyVertArray = emDM_copyVertArray;
1625         bmdm->dm.copyEdgeArray = emDM_copyEdgeArray;
1626         bmdm->dm.copyTessFaceArray = emDM_copyTessFaceArray;
1627         bmdm->dm.copyLoopArray = emDM_copyLoopArray;
1628         bmdm->dm.copyPolyArray = emDM_copyPolyArray;
1629
1630         bmdm->dm.getTessFaceDataArray = emDM_getTessFaceDataArray;
1631
1632         bmdm->dm.calcNormals = emDM_calcNormals;
1633         bmdm->dm.recalcTesselation = emDM_recalcTesselation;
1634
1635         bmdm->dm.foreachMappedVert = emDM_foreachMappedVert;
1636         bmdm->dm.foreachMappedEdge = emDM_foreachMappedEdge;
1637         bmdm->dm.foreachMappedFaceCenter = emDM_foreachMappedFaceCenter;
1638
1639         bmdm->dm.drawEdges = emDM_drawEdges;
1640         bmdm->dm.drawMappedEdges = emDM_drawMappedEdges;
1641         bmdm->dm.drawMappedEdgesInterp = emDM_drawMappedEdgesInterp;
1642         bmdm->dm.drawMappedFaces = emDM_drawMappedFaces;
1643         bmdm->dm.drawMappedFacesTex = emDM_drawMappedFacesTex;
1644         bmdm->dm.drawMappedFacesGLSL = emDM_drawMappedFacesGLSL;
1645         bmdm->dm.drawMappedFacesMat = emDM_drawMappedFacesMat;
1646         bmdm->dm.drawFacesTex = emDM_drawFacesTex;
1647         bmdm->dm.drawFacesGLSL = emDM_drawFacesGLSL;
1648         bmdm->dm.drawUVEdges = emDM_drawUVEdges;
1649
1650         bmdm->dm.release = emDM_release;
1651
1652         bmdm->vertexCos = vertexCos;
1653
1654         if (CustomData_has_layer(&bm->vdata, CD_MDEFORMVERT)) {
1655                 BMIter iter;
1656                 BMVert *eve;
1657                 int i;
1658
1659                 DM_add_vert_layer(&bmdm->dm, CD_MDEFORMVERT, CD_CALLOC, NULL);
1660
1661                 eve = BM_iter_new(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
1662                 for (i=0; eve; eve=BM_iter_step(&iter), i++)
1663                         DM_set_vert_data(&bmdm->dm, i, CD_MDEFORMVERT,
1664                                                          CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MDEFORMVERT));
1665         }
1666
1667         if (vertexCos) {
1668                 BMFace *efa;
1669                 BMVert *eve;
1670                 BMIter fiter;
1671                 BMIter viter;
1672                 int i;
1673
1674                 BM_mesh_elem_index_ensure(bm, BM_VERT);
1675
1676                 bmdm->vertexNos = MEM_callocN(sizeof(*bmdm->vertexNos) * bm->totvert, "bmdm_vno");
1677                 bmdm->polyNos = MEM_mallocN(sizeof(*bmdm->polyNos)*bm->totface, "bmdm_pno");
1678
1679                 i = 0;
1680                 BM_ITER(efa, &fiter, bm, BM_FACES_OF_MESH, NULL) {
1681                         BM_elem_index_set(efa, i); /* set_inline */
1682                         BM_face_normal_update_vcos(bm, efa, bmdm->polyNos[i], vertexCos);
1683                         i++;
1684                 }
1685                 bm->elem_index_dirty &= ~BM_FACE;
1686
1687                 eve=BM_iter_new(&viter, bm, BM_VERTS_OF_MESH, NULL);
1688                 for (i=0; eve; eve=BM_iter_step(&viter), i++) {
1689                         float *no = bmdm->vertexNos[i];
1690                         BM_ITER(efa, &fiter, bm, BM_FACES_OF_VERT, eve) {
1691                                 add_v3_v3(no, bmdm->polyNos[BM_elem_index_get(efa)]);
1692                         }
1693
1694                         /* following Mesh convention; we use vertex coordinate itself
1695                          * for normal in this case */
1696                         if (normalize_v3(no)==0.0) {
1697                                 copy_v3_v3(no, vertexCos[i]);
1698                                 normalize_v3(no);
1699                         }
1700                 }
1701         }
1702
1703         return (DerivedMesh*) bmdm;
1704 }