code cleanup: white space, spelling & ';;' end of lines.
[blender.git] / source / blender / blenkernel / intern / cdderivedmesh.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) 2006 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): Ben Batt <benbatt@gmail.com>
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  *
27  * Implementation of CDDerivedMesh.
28  *
29  * BKE_cdderivedmesh.h contains the function prototypes for this file.
30  *
31  */
32
33 /** \file blender/blenkernel/intern/cdderivedmesh.c
34  *  \ingroup bke
35  */
36
37 #include "GL/glew.h"
38
39 #include "BKE_cdderivedmesh.h"
40 #include "BKE_global.h"
41 #include "BKE_mesh.h"
42 #include "BKE_paint.h"
43 #include "BKE_utildefines.h"
44 #include "BKE_tessmesh.h"
45
46 #include "BLI_scanfill.h"
47 #include "BLI_math.h"
48 #include "BLI_blenlib.h"
49 #include "BLI_edgehash.h"
50 #include "BLI_math.h"
51 #include "BLI_pbvh.h"
52 #include "BLI_array.h"
53 #include "BLI_smallhash.h"
54 #include "BLI_utildefines.h"
55
56 #include "BKE_cdderivedmesh.h"
57 #include "BKE_global.h"
58 #include "BKE_mesh.h"
59 #include "BKE_paint.h"
60
61
62 #include "DNA_mesh_types.h"
63 #include "DNA_meshdata_types.h"
64 #include "DNA_object_types.h"
65 #include "DNA_curve_types.h" /* for Curve */
66
67 #include "MEM_guardedalloc.h"
68
69 #include "GPU_buffers.h"
70 #include "GPU_draw.h"
71 #include "GPU_extensions.h"
72 #include "GPU_material.h"
73
74 #include <string.h>
75 #include <limits.h>
76 #include <math.h>
77
78 typedef struct {
79         DerivedMesh dm;
80
81         /* these point to data in the DerivedMesh custom data layers,
82            they are only here for efficiency and convenience **/
83         MVert *mvert;
84         MEdge *medge;
85         MFace *mface;
86         MLoop *mloop;
87         MPoly *mpoly;
88
89         /* Cached */
90         struct PBVH *pbvh;
91         int pbvh_draw;
92
93         /* Mesh connectivity */
94         struct ListBase *fmap;
95         struct IndexNode *fmap_mem;
96
97         struct ListBase *pmap;
98         struct IndexNode *pmap_mem;
99 } CDDerivedMesh;
100
101 /**************** DerivedMesh interface functions ****************/
102 static int cdDM_getNumVerts(DerivedMesh *dm)
103 {
104         return dm->numVertData;
105 }
106
107 static int cdDM_getNumEdges(DerivedMesh *dm)
108 {
109         return dm->numEdgeData;
110 }
111
112 static int cdDM_getNumTessFaces(DerivedMesh *dm)
113 {
114         return dm->numTessFaceData;
115 }
116
117 static int cdDM_getNumLoops(DerivedMesh *dm)
118 {
119         return dm->numLoopData;
120 }
121
122 static int cdDM_getNumPolys(DerivedMesh *dm)
123 {
124         return dm->numPolyData;
125 }
126
127 static void cdDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
128 {
129         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
130         *vert_r = cddm->mvert[index];
131 }
132
133 static void cdDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
134 {
135         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
136         *edge_r = cddm->medge[index];
137 }
138
139 static void cdDM_getTessFace(DerivedMesh *dm, int index, MFace *face_r)
140 {
141         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
142         *face_r = cddm->mface[index];
143 }
144
145 static void cdDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
146 {
147         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
148         memcpy(vert_r, cddm->mvert, sizeof(*vert_r) * dm->numVertData);
149 }
150
151 static void cdDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
152 {
153         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
154         memcpy(edge_r, cddm->medge, sizeof(*edge_r) * dm->numEdgeData);
155 }
156
157 static void cdDM_copyTessFaceArray(DerivedMesh *dm, MFace *face_r)
158 {
159         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
160         memcpy(face_r, cddm->mface, sizeof(*face_r) * dm->numTessFaceData);
161 }
162
163 static void cdDM_copyLoopArray(DerivedMesh *dm, MLoop *loop_r)
164 {
165         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
166         memcpy(loop_r, cddm->mloop, sizeof(*loop_r) * dm->numLoopData);
167 }
168
169 static void cdDM_copyPolyArray(DerivedMesh *dm, MPoly *poly_r)
170 {
171         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
172         memcpy(poly_r, cddm->mpoly, sizeof(*poly_r) * dm->numPolyData);
173 }
174
175 static void cdDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
176 {
177         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
178         int i;
179
180         if (dm->numVertData) {
181                 for (i=0; i<dm->numVertData; i++) {
182                         DO_MINMAX(cddm->mvert[i].co, min_r, max_r);
183                 }
184         } else {
185                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
186         }
187 }
188
189 static void cdDM_getVertCo(DerivedMesh *dm, int index, float co_r[3])
190 {
191         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
192
193         copy_v3_v3(co_r, cddm->mvert[index].co);
194 }
195
196 static void cdDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
197 {
198         MVert *mv = CDDM_get_verts(dm);
199         int i;
200
201         for(i = 0; i < dm->numVertData; i++, mv++)
202                 copy_v3_v3(cos_r[i], mv->co);
203 }
204
205 static void cdDM_getVertNo(DerivedMesh *dm, int index, float no_r[3])
206 {
207         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
208         normal_short_to_float_v3(no_r, cddm->mvert[index].no);
209 }
210
211 static ListBase *cdDM_getPolyMap(Object *ob, DerivedMesh *dm)
212 {
213         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
214
215         if(!cddm->pmap && ob->type == OB_MESH) {
216                 Mesh *me= ob->data;
217
218                 create_vert_poly_map(&cddm->pmap, &cddm->pmap_mem,
219                                      me->mpoly, me->mloop,
220                                      me->totvert, me->totpoly, me->totloop);
221         }
222
223         return cddm->pmap;
224 }
225
226 static ListBase *cdDM_getFaceMap(Object *ob, DerivedMesh *dm)
227 {
228         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
229
230         if(!cddm->fmap && ob->type == OB_MESH) {
231                 Mesh *me= ob->data;
232
233                 create_vert_face_map(&cddm->fmap, &cddm->fmap_mem, me->mface,
234                                      me->totvert, me->totface);
235         }
236
237         return cddm->fmap;
238 }
239
240 static int can_pbvh_draw(Object *ob, DerivedMesh *dm)
241 {
242         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
243         Mesh *me= ob->data;
244         int deformed= 0;
245
246         /* active modifiers means extra deformation, which can't be handled correct
247            on bith of PBVH and sculpt "layer" levels, so use PBVH only for internal brush
248            stuff and show final DerivedMesh so user would see actual object shape */
249         deformed|= ob->sculpt->modifiers_active;
250
251         /* as in case with modifiers, we can't synchronize deformation made against
252            PBVH and non-locked keyblock, so also use PBVH only for brushes and
253            final DM to give final result to user */
254         deformed|= ob->sculpt->kb && (ob->shapeflag&OB_SHAPE_LOCK) == 0;
255
256         if(deformed)
257                 return 0;
258
259         return cddm->mvert == me->mvert || ob->sculpt->kb;
260 }
261
262 static struct PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
263 {
264         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
265
266         if(!ob) {
267                 cddm->pbvh= NULL;
268                 return NULL;
269         }
270
271         if(!ob->sculpt)
272                 return NULL;
273         if(ob->sculpt->pbvh) {
274                 cddm->pbvh= ob->sculpt->pbvh;
275                 cddm->pbvh_draw = can_pbvh_draw(ob, dm);
276         }
277
278         /* always build pbvh from original mesh, and only use it for drawing if
279            this derivedmesh is just original mesh. it's the multires subsurf dm
280            that this is actually for, to support a pbvh on a modified mesh */
281         if(!cddm->pbvh && ob->type == OB_MESH) {
282                 SculptSession *ss= ob->sculpt;
283                 Mesh *me= ob->data;
284                 cddm->pbvh = BLI_pbvh_new();
285                 cddm->pbvh_draw = can_pbvh_draw(ob, dm);
286                 BLI_assert(!(me->mface == NULL && me->mpoly != NULL)); /* BMESH ONLY complain if mpoly is valid but not mface */
287                 BLI_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert,
288                                     me->totface, me->totvert);
289
290                 if(ss->modifiers_active && ob->derivedDeform) {
291                         DerivedMesh *deformdm= ob->derivedDeform;
292                         float (*vertCos)[3];
293                         int totvert;
294
295                         totvert= deformdm->getNumVerts(deformdm);
296                         vertCos= MEM_callocN(3*totvert*sizeof(float), "cdDM_getPBVH vertCos");
297                         deformdm->getVertCos(deformdm, vertCos);
298                         BLI_pbvh_apply_vertCos(cddm->pbvh, vertCos);
299                         MEM_freeN(vertCos);
300                 }
301         }
302
303         return cddm->pbvh;
304 }
305
306 /* update vertex normals so that drawing smooth faces works during sculpt
307    TODO: proper fix is to support the pbvh in all drawing modes */
308 static void cdDM_update_normals_from_pbvh(DerivedMesh *dm)
309 {
310         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
311         float (*face_nors)[3];
312
313         if(!cddm->pbvh || !cddm->pbvh_draw || !dm->numTessFaceData)
314                 return;
315
316         face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
317
318         BLI_pbvh_update(cddm->pbvh, PBVH_UpdateNormals, face_nors);
319 }
320
321 static void cdDM_drawVerts(DerivedMesh *dm)
322 {
323         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
324         MVert *mv = cddm->mvert;
325         int i;
326
327         if( GPU_buffer_legacy(dm) ) {
328                 glBegin(GL_POINTS);
329                 for(i = 0; i < dm->numVertData; i++, mv++)
330                         glVertex3fv(mv->co);
331                 glEnd();
332         }
333         else {  /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
334                 GPU_vertex_setup(dm);
335                 if( !GPU_buffer_legacy(dm) ) {
336                         if(dm->drawObject->tot_triangle_point)
337                                 glDrawArrays(GL_POINTS,0, dm->drawObject->tot_triangle_point);
338                         else
339                                 glDrawArrays(GL_POINTS,0, dm->drawObject->tot_loose_point);
340                 }
341                 GPU_buffer_unbind();
342         }
343 }
344
345 static void cdDM_drawUVEdges(DerivedMesh *dm)
346 {
347         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
348         MFace *mf = cddm->mface;
349         MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
350         int i;
351
352         if(mf) {
353                 if( GPU_buffer_legacy(dm) ) {
354                         glBegin(GL_LINES);
355                         for(i = 0; i < dm->numTessFaceData; i++, mf++, tf++) {
356                                 if(!(mf->flag&ME_HIDE)) {
357                                         glVertex2fv(tf->uv[0]);
358                                         glVertex2fv(tf->uv[1]);
359
360                                         glVertex2fv(tf->uv[1]);
361                                         glVertex2fv(tf->uv[2]);
362
363                                         if(!mf->v4) {
364                                                 glVertex2fv(tf->uv[2]);
365                                                 glVertex2fv(tf->uv[0]);
366                                         } else {
367                                                 glVertex2fv(tf->uv[2]);
368                                                 glVertex2fv(tf->uv[3]);
369
370                                                 glVertex2fv(tf->uv[3]);
371                                                 glVertex2fv(tf->uv[0]);
372                                         }
373                                 }
374                         }
375                         glEnd();
376                 }
377                 else {
378                         int prevstart = 0;
379                         int prevdraw = 1;
380                         int draw = 1;
381                         int curpos = 0;
382
383                         GPU_uvedge_setup(dm);
384                         if( !GPU_buffer_legacy(dm) ) {
385                                 for(i = 0; i < dm->numTessFaceData; i++, mf++) {
386                                         if(!(mf->flag&ME_HIDE)) {
387                                                 draw = 1;
388                                         } 
389                                         else {
390                                                 draw = 0;
391                                         }
392                                         if( prevdraw != draw ) {
393                                                 if( prevdraw > 0 && (curpos-prevstart) > 0) {
394                                                         glDrawArrays(GL_LINES,prevstart,curpos-prevstart);
395                                                 }
396                                                 prevstart = curpos;
397                                         }
398                                         if( mf->v4 ) {
399                                                 curpos += 8;
400                                         }
401                                         else {
402                                                 curpos += 6;
403                                         }
404                                         prevdraw = draw;
405                                 }
406                                 if( prevdraw > 0 && (curpos-prevstart) > 0 ) {
407                                         glDrawArrays(GL_LINES,prevstart,curpos-prevstart);
408                                 }
409                         }
410                         GPU_buffer_unbind();
411                 }
412         }
413 }
414
415 static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges)
416 {
417         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
418         MVert *mvert = cddm->mvert;
419         MEdge *medge = cddm->medge;
420         int i;
421         
422         if( GPU_buffer_legacy(dm) ) {
423                 DEBUG_VBO( "Using legacy code. cdDM_drawEdges\n" );
424                 glBegin(GL_LINES);
425                 for(i = 0; i < dm->numEdgeData; i++, medge++) {
426                         if((drawAllEdges || (medge->flag&ME_EDGEDRAW))
427                            && (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) {
428                                 glVertex3fv(mvert[medge->v1].co);
429                                 glVertex3fv(mvert[medge->v2].co);
430                         }
431                 }
432                 glEnd();
433         }
434         else {  /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
435                 int prevstart = 0;
436                 int prevdraw = 1;
437                 int draw = 1;
438
439                 GPU_edge_setup(dm);
440                 if( !GPU_buffer_legacy(dm) ) {
441                         for(i = 0; i < dm->numEdgeData; i++, medge++) {
442                                 if((drawAllEdges || (medge->flag&ME_EDGEDRAW))
443                                    && (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) {
444                                         draw = 1;
445                                 } 
446                                 else {
447                                         draw = 0;
448                                 }
449                                 if( prevdraw != draw ) {
450                                         if( prevdraw > 0 && (i-prevstart) > 0 ) {
451                                                 GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2  );
452                                         }
453                                         prevstart = i;
454                                 }
455                                 prevdraw = draw;
456                         }
457                         if( prevdraw > 0 && (i-prevstart) > 0 ) {
458                                 GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2  );
459                         }
460                 }
461                 GPU_buffer_unbind();
462         }
463 }
464
465 static void cdDM_drawLooseEdges(DerivedMesh *dm)
466 {
467         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
468         MVert *mvert = cddm->mvert;
469         MEdge *medge = cddm->medge;
470         int i;
471
472         if( GPU_buffer_legacy(dm) ) {
473                 DEBUG_VBO( "Using legacy code. cdDM_drawLooseEdges\n" );
474                 glBegin(GL_LINES);
475                 for(i = 0; i < dm->numEdgeData; i++, medge++) {
476                         if(medge->flag&ME_LOOSEEDGE) {
477                                 glVertex3fv(mvert[medge->v1].co);
478                                 glVertex3fv(mvert[medge->v2].co);
479                         }
480                 }
481                 glEnd();
482         }
483         else {  /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
484                 int prevstart = 0;
485                 int prevdraw = 1;
486                 int draw = 1;
487
488                 GPU_edge_setup(dm);
489                 if( !GPU_buffer_legacy(dm) ) {
490                         for(i = 0; i < dm->numEdgeData; i++, medge++) {
491                                 if(medge->flag&ME_LOOSEEDGE) {
492                                         draw = 1;
493                                 } 
494                                 else {
495                                         draw = 0;
496                                 }
497                                 if( prevdraw != draw ) {
498                                         if( prevdraw > 0 && (i-prevstart) > 0) {
499                                                 GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2  );
500                                         }
501                                         prevstart = i;
502                                 }
503                                 prevdraw = draw;
504                         }
505                         if( prevdraw > 0 && (i-prevstart) > 0 ) {
506                                 GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2  );
507                         }
508                 }
509                 GPU_buffer_unbind();
510         }
511 }
512
513 static void cdDM_drawFacesSolid(DerivedMesh *dm,
514                                 float (*partial_redraw_planes)[4],
515                                 int UNUSED(fast), int (*setMaterial)(int, void *attribs))
516 {
517         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
518         MVert *mvert = cddm->mvert;
519         MFace *mface = cddm->mface;
520         float *nors= dm->getTessFaceDataArray(dm, CD_NORMAL);
521         int a, glmode = -1, shademodel = -1, matnr = -1, drawCurrentMat = 1;
522
523 #define PASSVERT(index) {                                               \
524         if(shademodel == GL_SMOOTH) {                           \
525                 short *no = mvert[index].no;                    \
526                 glNormal3sv(no);                                                \
527         }                                                                                       \
528         glVertex3fv(mvert[index].co);   \
529 }
530
531         if(cddm->pbvh && cddm->pbvh_draw) {
532                 if(dm->numTessFaceData) {
533                         float (*face_nors)[3] = CustomData_get_layer(&dm->faceData, CD_NORMAL);
534
535                         /* should be per face */
536                         if(!setMaterial(mface->mat_nr+1, NULL))
537                                 return;
538
539                         glShadeModel((mface->flag & ME_SMOOTH)? GL_SMOOTH: GL_FLAT);
540                         BLI_pbvh_draw(cddm->pbvh, partial_redraw_planes, face_nors, (mface->flag & ME_SMOOTH));
541                         glShadeModel(GL_FLAT);
542                 }
543
544                 return;
545         }
546
547         if( GPU_buffer_legacy(dm) ) {
548                 DEBUG_VBO( "Using legacy code. cdDM_drawFacesSolid\n" );
549                 glBegin(glmode = GL_QUADS);
550                 for(a = 0; a < dm->numTessFaceData; a++, mface++) {
551                         int new_glmode, new_matnr, new_shademodel;
552
553                         new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES;
554                         new_matnr = mface->mat_nr + 1;
555                         new_shademodel = (mface->flag & ME_SMOOTH)?GL_SMOOTH:GL_FLAT;
556                         
557                         if(new_glmode != glmode || new_matnr != matnr
558                            || new_shademodel != shademodel) {
559                                 glEnd();
560
561                                 drawCurrentMat = setMaterial(matnr = new_matnr, NULL);
562
563                                 glShadeModel(shademodel = new_shademodel);
564                                 glBegin(glmode = new_glmode);
565                         } 
566                         
567                         if(drawCurrentMat) {
568                                 if(shademodel == GL_FLAT) {
569                                         if (nors) {
570                                                 glNormal3fv(nors);
571                                         }
572                                         else {
573                                                 /* TODO make this better (cache facenormals as layer?) */
574                                                 float nor[3];
575                                                 if(mface->v4) {
576                                                         normal_quad_v3( nor,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co);
577                                                 } else {
578                                                         normal_tri_v3( nor,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co);
579                                                 }
580                                                 glNormal3fv(nor);
581                                         }
582                                 }
583
584                                 PASSVERT(mface->v1);
585                                 PASSVERT(mface->v2);
586                                 PASSVERT(mface->v3);
587                                 if(mface->v4) {
588                                         PASSVERT(mface->v4);
589                                 }
590                         }
591
592                         if(nors) nors += 3;
593                 }
594                 glEnd();
595         }
596         else {  /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
597                 GPU_vertex_setup( dm );
598                 GPU_normal_setup( dm );
599                 if( !GPU_buffer_legacy(dm) ) {
600                         glShadeModel(GL_SMOOTH);
601                         for( a = 0; a < dm->drawObject->totmaterial; a++ ) {
602                                 if( setMaterial(dm->drawObject->materials[a].mat_nr+1, NULL) )
603                                         glDrawArrays(GL_TRIANGLES, dm->drawObject->materials[a].start,
604                                                      dm->drawObject->materials[a].totpoint);
605                         }
606                 }
607                 GPU_buffer_unbind( );
608         }
609
610 #undef PASSVERT
611         glShadeModel(GL_FLAT);
612 }
613
614 static void cdDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *col1, unsigned char *col2)
615 {
616         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
617         int a, glmode;
618         unsigned char *cp1, *cp2;
619         MVert *mvert = cddm->mvert;
620         MFace *mface = cddm->mface;
621
622         cp1 = col1;
623         if(col2) {
624                 cp2 = col2;
625         } else {
626                 cp2 = NULL;
627                 useTwoSided = 0;
628         }
629
630         /* there's a conflict here... twosided colors versus culling...? */
631         /* defined by history, only texture faces have culling option */
632         /* we need that as mesh option builtin, next to double sided lighting */
633         if(col2) {
634                 glEnable(GL_CULL_FACE);
635         }
636
637         cdDM_update_normals_from_pbvh(dm);
638
639         if( GPU_buffer_legacy(dm) ) {
640                 DEBUG_VBO( "Using legacy code. cdDM_drawFacesColored\n" );
641                 glShadeModel(GL_SMOOTH);
642                 glBegin(glmode = GL_QUADS);
643                 for(a = 0; a < dm->numTessFaceData; a++, mface++, cp1 += 16) {
644                         int new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES;
645
646                         if(new_glmode != glmode) {
647                                 glEnd();
648                                 glBegin(glmode = new_glmode);
649                         }
650                                 
651                         glColor3ubv(cp1+0);
652                         glVertex3fv(mvert[mface->v1].co);
653                         glColor3ubv(cp1+4);
654                         glVertex3fv(mvert[mface->v2].co);
655                         glColor3ubv(cp1+8);
656                         glVertex3fv(mvert[mface->v3].co);
657                         if(mface->v4) {
658                                 glColor3ubv(cp1+12);
659                                 glVertex3fv(mvert[mface->v4].co);
660                         }
661                                 
662                         if(useTwoSided) {
663                                 glColor3ubv(cp2+8);
664                                 glVertex3fv(mvert[mface->v3].co );
665                                 glColor3ubv(cp2+4);
666                                 glVertex3fv(mvert[mface->v2].co );
667                                 glColor3ubv(cp2+0);
668                                 glVertex3fv(mvert[mface->v1].co );
669                                 if(mface->v4) {
670                                         glColor3ubv(cp2+12);
671                                         glVertex3fv(mvert[mface->v4].co );
672                                 }
673                         }
674                         if(col2) cp2 += 16;
675                 }
676                 glEnd();
677         }
678         else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
679                 GPU_color4_upload(dm,cp1);
680                 GPU_vertex_setup(dm);
681                 GPU_color_setup(dm);
682                 if( !GPU_buffer_legacy(dm) ) {
683                         glShadeModel(GL_SMOOTH);
684                         glDrawArrays(GL_TRIANGLES, 0, dm->drawObject->tot_triangle_point);
685
686                         if( useTwoSided ) {
687                                 GPU_color4_upload(dm,cp2);
688                                 GPU_color_setup(dm);
689                                 glCullFace(GL_FRONT);
690                                 glDrawArrays(GL_TRIANGLES, 0, dm->drawObject->tot_triangle_point);
691                                 glCullFace(GL_BACK);
692                         }
693                 }
694                 GPU_buffer_unbind();
695         }
696
697         glShadeModel(GL_FLAT);
698         glDisable(GL_CULL_FACE);
699 }
700
701 static void cdDM_drawFacesTex_common(DerivedMesh *dm,
702                            int (*drawParams)(MTFace *tface, int has_mcol, int matnr),
703                            int (*drawParamsMapped)(void *userData, int index),
704                            int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
705                            void *userData) 
706 {
707         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
708         MVert *mv = cddm->mvert;
709         MFace *mf = DM_get_tessface_data_layer(dm, CD_MFACE);
710         MCol *realcol = dm->getTessFaceDataArray(dm, CD_TEXTURE_MCOL);
711         float *nors= dm->getTessFaceDataArray(dm, CD_NORMAL);
712         MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
713         int i, j, orig, *index = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
714         int startFace = 0 /*, lastFlag = 0xdeadbeef */ /* UNUSED */;
715         MCol *mcol = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL);
716         if(!mcol)
717                 mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
718
719         cdDM_update_normals_from_pbvh(dm);
720
721         if( GPU_buffer_legacy(dm) ) {
722                 DEBUG_VBO( "Using legacy code. cdDM_drawFacesTex_common\n" );
723                 for(i = 0; i < dm->numTessFaceData; i++, mf++) {
724                         MVert *mvert;
725                         int flag;
726                         unsigned char *cp = NULL;
727
728                         if(drawParams) {
729                                 flag = drawParams(tf? &tf[i]: NULL, (mcol != NULL), mf->mat_nr);
730                         }
731                         else {
732                                 if(index) {
733                                         orig = *index++;
734                                         if(orig == ORIGINDEX_NONE)              { if(nors) nors += 3; continue; }
735                                         if(drawParamsMapped) flag = drawParamsMapped(userData, orig);
736                                         else    { if(nors) nors += 3; continue; }
737                                 }
738                                 else
739                                         if(drawParamsMapped) flag = drawParamsMapped(userData, i);
740                                         else    { if(nors) nors += 3; continue; }
741                         }
742                         
743                         if(flag != 0) {
744                                 if (flag==1 && mcol)
745                                         cp= (unsigned char*) &mcol[i*4];
746
747                                 if(!(mf->flag&ME_SMOOTH)) {
748                                         if (nors) {
749                                                 glNormal3fv(nors);
750                                         }
751                                         else {
752                                                 float nor[3];
753                                                 if(mf->v4) {
754                                                         normal_quad_v3( nor,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
755                                                 } else {
756                                                         normal_tri_v3( nor,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
757                                                 }
758                                                 glNormal3fv(nor);
759                                         }
760                                 }
761
762                                 glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
763                                 if(tf) glTexCoord2fv(tf[i].uv[0]);
764                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
765                                 mvert = &mv[mf->v1];
766                                 if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
767                                 glVertex3fv(mvert->co);
768                                         
769                                 if(tf) glTexCoord2fv(tf[i].uv[1]);
770                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
771                                 mvert = &mv[mf->v2];
772                                 if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
773                                 glVertex3fv(mvert->co);
774
775                                 if(tf) glTexCoord2fv(tf[i].uv[2]);
776                                 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
777                                 mvert = &mv[mf->v3];
778                                 if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
779                                 glVertex3fv(mvert->co);
780
781                                 if(mf->v4) {
782                                         if(tf) glTexCoord2fv(tf[i].uv[3]);
783                                         if(cp) glColor3ub(cp[15], cp[14], cp[13]);
784                                         mvert = &mv[mf->v4];
785                                         if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
786                                         glVertex3fv(mvert->co);
787                                 }
788                                 glEnd();
789                         }
790                         
791                         if(nors) nors += 3;
792                 }
793         } else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
794                 MCol *col = realcol;
795                 if(!col)
796                         col = mcol;
797
798                 GPU_vertex_setup( dm );
799                 GPU_normal_setup( dm );
800                 GPU_uv_setup( dm );
801                 if( col != NULL ) {
802                         /*if( realcol && dm->drawObject->colType == CD_TEXTURE_MCOL )  {
803                                 col = 0;
804                         } else if( mcol && dm->drawObject->colType == CD_MCOL ) {
805                                 col = 0;
806                         }
807                         
808                         if( col != 0 ) {*/
809                                 unsigned char *colors = MEM_mallocN(dm->getNumTessFaces(dm)*4*3*sizeof(unsigned char), "cdDM_drawFacesTex_common");
810                                 for( i=0; i < dm->getNumTessFaces(dm); i++ ) {
811                                         for( j=0; j < 4; j++ ) {
812                                                 /* bgr -> rgb is intentional (and stupid), but how its stored internally */
813                                                 colors[i*12+j*3] = col[i*4+j].b;
814                                                 colors[i*12+j*3+1] = col[i*4+j].g;
815                                                 colors[i*12+j*3+2] = col[i*4+j].r;
816                                         }
817                                 }
818                                 GPU_color3_upload(dm,colors);
819                                 MEM_freeN(colors);
820                                 if(realcol)
821                                         dm->drawObject->colType = CD_TEXTURE_MCOL;
822                                 else if(mcol)
823                                         dm->drawObject->colType = CD_MCOL;
824                         //}
825                         GPU_color_setup( dm );
826                 }
827
828                 if( !GPU_buffer_legacy(dm) ) {
829                         int tottri = dm->drawObject->tot_triangle_point/3;
830                         int next_actualFace= dm->drawObject->triangle_to_mface[0];
831
832                         glShadeModel( GL_SMOOTH );
833                         /* lastFlag = 0; */ /* UNUSED */
834                         for(i = 0; i < tottri; i++) {
835                                 int actualFace = next_actualFace;
836                                 int flag = 1;
837                                 int flush = 0;
838
839                                 if(i != tottri-1)
840                                         next_actualFace= dm->drawObject->triangle_to_mface[i+1];
841
842                                 if(drawParams) {
843                                         flag = drawParams(tf? &tf[actualFace]: NULL, (mcol != NULL), mf[actualFace].mat_nr);
844                                 }
845                                 else {
846                                         if(index) {
847                                                 orig = index[actualFace];
848                                                 if(orig == ORIGINDEX_NONE) continue;
849                                                 if(drawParamsMapped)
850                                                         flag = drawParamsMapped(userData, orig);
851                                         }
852                                         else
853                                                 if(drawParamsMapped)
854                                                         flag = drawParamsMapped(userData, actualFace);
855                                 }
856
857                                 /* flush buffer if current triangle isn't drawable or it's last triangle */
858                                 flush= !flag || i == tottri - 1;
859
860                                 if(!flush && compareDrawOptions) {
861                                         /* also compare draw options and flush buffer if they're different
862                                            need for face selection highlight in edit mode */
863                                         flush|= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
864                                 }
865
866                                 if(flush) {
867                                         int first= startFace*3;
868                                         int count= (i-startFace+(flag ? 1 : 0))*3; /* Add one to the length if we're drawing at the end of the array */
869
870                                         if(count) {
871                                                 if (col)
872                                                         GPU_color_switch(1);
873                                                 else
874                                                         GPU_color_switch(0);
875
876                                                 glDrawArrays(GL_TRIANGLES, first, count);
877                                         }
878
879                                         startFace = i + 1;
880                                 }
881                         }
882                 }
883
884                 GPU_buffer_unbind();
885                 glShadeModel( GL_FLAT );
886         }
887 }
888
889 static void cdDM_drawFacesTex(DerivedMesh *dm,
890                            int (*setDrawOptions)(MTFace *tface, int has_mcol, int matnr),
891                            int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
892                            void *userData)
893 {
894         cdDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData);
895 }
896
897 static void cdDM_drawMappedFaces(DerivedMesh *dm,
898                         int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r),
899                         int (*setMaterial)(int, void *attribs),
900                         int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
901                         void *userData, int useColors)
902 {
903         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
904         MVert *mv = cddm->mvert;
905         MFace *mf = cddm->mface;
906         MCol *mc;
907         float *nors= DM_get_tessface_data_layer(dm, CD_NORMAL);
908         int i, orig, *index = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
909
910         mc = DM_get_tessface_data_layer(dm, CD_ID_MCOL);
911         if(!mc)
912                 mc = DM_get_tessface_data_layer(dm, CD_WEIGHT_MCOL);
913         if(!mc)
914                 mc = DM_get_tessface_data_layer(dm, CD_MCOL);
915
916         cdDM_update_normals_from_pbvh(dm);
917
918         /* back-buffer always uses legacy since VBO's would need the
919          * color array temporarily overwritten for drawing, then reset. */
920         if( GPU_buffer_legacy(dm) || G.f & G_BACKBUFSEL) {
921                 DEBUG_VBO( "Using legacy code. cdDM_drawMappedFaces\n" );
922                 for(i = 0; i < dm->numTessFaceData; i++, mf++) {
923                         int drawSmooth = (mf->flag & ME_SMOOTH);
924                         int draw= 1;
925
926                         orig= (index==NULL) ? i : *index++;
927                         
928                         if(orig == ORIGINDEX_NONE)
929                                 draw= setMaterial(mf->mat_nr + 1, NULL);
930                         else if (setDrawOptions != NULL)
931                                 draw= setDrawOptions(userData, orig, &drawSmooth);
932
933                         if(draw) {
934                                 unsigned char *cp = NULL;
935
936                                 if(useColors && mc)
937                                         cp = (unsigned char *)&mc[i * 4];
938
939                                 /* no need to set shading mode to flat because
940                                 *  normals are already used to change shading */
941                                 glShadeModel(GL_SMOOTH);
942                                 glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
943
944                                 if (!drawSmooth) {
945                                         if (nors) {
946                                                 glNormal3fv(nors);
947                                         }
948                                         else {
949                                                 float nor[3];
950                                                 if(mf->v4) {
951                                                         normal_quad_v3( nor,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
952                                                 } else {
953                                                         normal_tri_v3( nor,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
954                                                 }
955                                                 glNormal3fv(nor);
956                                         }
957
958                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
959                                         glVertex3fv(mv[mf->v1].co);
960                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
961                                         glVertex3fv(mv[mf->v2].co);
962                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
963                                         glVertex3fv(mv[mf->v3].co);
964                                         if(mf->v4) {
965                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
966                                                 glVertex3fv(mv[mf->v4].co);
967                                         }
968                                 } else {
969                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
970                                         glNormal3sv(mv[mf->v1].no);
971                                         glVertex3fv(mv[mf->v1].co);
972                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
973                                         glNormal3sv(mv[mf->v2].no);
974                                         glVertex3fv(mv[mf->v2].co);
975                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
976                                         glNormal3sv(mv[mf->v3].no);
977                                         glVertex3fv(mv[mf->v3].co);
978                                         if(mf->v4) {
979                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
980                                                 glNormal3sv(mv[mf->v4].no);
981                                                 glVertex3fv(mv[mf->v4].co);
982                                         }
983                                 }
984
985                                 glEnd();
986                         }
987                         
988                         if (nors) nors += 3;
989                 }
990         }
991         else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
992                 int prevstart = 0;
993                 GPU_vertex_setup(dm);
994                 GPU_normal_setup(dm);
995                 if( useColors && mc )
996                         GPU_color_setup(dm);
997                 if( !GPU_buffer_legacy(dm) ) {
998                         int tottri = dm->drawObject->tot_triangle_point/3;
999                         glShadeModel(GL_SMOOTH);
1000                         
1001                         if(tottri == 0) {
1002                                 /* avoid buffer problems in following code */
1003                         }
1004                         if(setDrawOptions == NULL) {
1005                                 /* just draw the entire face array */
1006                                 glDrawArrays(GL_TRIANGLES, 0, (tottri) * 3);
1007                         }
1008                         else {
1009                                 /* we need to check if the next material changes */
1010                                 int next_actualFace= dm->drawObject->triangle_to_mface[0];
1011                                 
1012                                 for( i = 0; i < tottri; i++ ) {
1013                                         //int actualFace = dm->drawObject->triangle_to_mface[i];
1014                                         int actualFace = next_actualFace;
1015                                         MFace *mface= mf + actualFace;
1016                                         int drawSmooth= (mface->flag & ME_SMOOTH);
1017                                         int draw = 1;
1018                                         int flush = 0;
1019
1020                                         if(i != tottri-1)
1021                                                 next_actualFace= dm->drawObject->triangle_to_mface[i+1];
1022
1023                                         orig= (index==NULL) ? actualFace : index[actualFace];
1024
1025                                         if(orig == ORIGINDEX_NONE)
1026                                                 draw= setMaterial(mface->mat_nr + 1, NULL);
1027                                         else if (setDrawOptions != NULL)
1028                                                 draw= setDrawOptions(userData, orig, &drawSmooth);
1029         
1030                                         /* Goal is to draw as long of a contiguous triangle
1031                                            array as possible, so draw when we hit either an
1032                                            invisible triangle or at the end of the array */
1033
1034                                         /* flush buffer if current triangle isn't drawable or it's last triangle... */
1035                                         flush= !draw || i == tottri - 1;
1036
1037                                         /* ... or when material setting is dissferent  */
1038                                         flush|= mf[actualFace].mat_nr != mf[next_actualFace].mat_nr;
1039
1040                                         if(!flush && compareDrawOptions) {
1041                                                 flush|= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
1042                                         }
1043
1044                                         if(flush) {
1045                                                 int first= prevstart*3;
1046                                                 int count= (i-prevstart+(draw ? 1 : 0))*3; /* Add one to the length if we're drawing at the end of the array */
1047
1048                                                 if(count)
1049                                                         glDrawArrays(GL_TRIANGLES, first, count);
1050
1051                                                 prevstart = i + 1;
1052                                         }
1053                                 }
1054                         }
1055
1056                         glShadeModel(GL_FLAT);
1057                 }
1058                 GPU_buffer_unbind();
1059         }
1060 }
1061
1062 static void cdDM_drawMappedFacesTex(DerivedMesh *dm,
1063                            int (*setDrawOptions)(void *userData, int index),
1064                            int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
1065                            void *userData)
1066 {
1067         cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData);
1068 }
1069
1070 static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, MVert *mvert, int a, int index, int vert, int smoothnormal)
1071 {
1072         int b;
1073
1074         /* orco texture coordinates */
1075         if(attribs->totorco) {
1076                 if(attribs->orco.glTexco)
1077                         glTexCoord3fv(attribs->orco.array[index]);
1078                 else
1079                         glVertexAttrib3fvARB(attribs->orco.glIndex, attribs->orco.array[index]);
1080         }
1081
1082         /* uv texture coordinates */
1083         for(b = 0; b < attribs->tottface; b++) {
1084                 MTFace *tf = &attribs->tface[b].array[a];
1085
1086                 if(attribs->tface[b].glTexco)
1087                         glTexCoord2fv(tf->uv[vert]);
1088                 else
1089                         glVertexAttrib2fvARB(attribs->tface[b].glIndex, tf->uv[vert]);
1090         }
1091
1092         /* vertex colors */
1093         for(b = 0; b < attribs->totmcol; b++) {
1094                 MCol *cp = &attribs->mcol[b].array[a*4 + vert];
1095                 GLubyte col[4];
1096                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1097                 glVertexAttrib4ubvARB(attribs->mcol[b].glIndex, col);
1098         }
1099
1100         /* tangent for normal mapping */
1101         if(attribs->tottang) {
1102                 float *tang = attribs->tang.array[a*4 + vert];
1103                 glVertexAttrib4fvARB(attribs->tang.glIndex, tang);
1104         }
1105
1106         /* vertex normal */
1107         if(smoothnormal)
1108                 glNormal3sv(mvert[index].no);
1109         
1110         /* vertex coordinate */
1111         glVertex3fv(mvert[index].co);
1112 }
1113
1114 static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
1115                            int (*setMaterial)(int, void *attribs),
1116                            int (*setDrawOptions)(void *userData, int index),
1117                            void *userData)
1118 {
1119         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
1120         GPUVertexAttribs gattribs;
1121         DMVertexAttribs attribs;
1122         MVert *mvert = cddm->mvert;
1123         MFace *mface = cddm->mface;
1124         /* MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */
1125         float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL);
1126         int a, b, dodraw, matnr, new_matnr;
1127         int orig, *index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1128
1129         cdDM_update_normals_from_pbvh(dm);
1130
1131         matnr = -1;
1132         dodraw = 0;
1133
1134         glShadeModel(GL_SMOOTH);
1135
1136         if( GPU_buffer_legacy(dm) || setDrawOptions != NULL ) {
1137                 DEBUG_VBO( "Using legacy code. cdDM_drawMappedFacesGLSL\n" );
1138                 memset(&attribs, 0, sizeof(attribs));
1139
1140                 glBegin(GL_QUADS);
1141
1142                 for(a = 0; a < dm->numTessFaceData; a++, mface++) {
1143                         const int smoothnormal = (mface->flag & ME_SMOOTH);
1144                         new_matnr = mface->mat_nr + 1;
1145
1146                         if(new_matnr != matnr) {
1147                                 glEnd();
1148
1149                                 dodraw = setMaterial(matnr = new_matnr, &gattribs);
1150                                 if(dodraw)
1151                                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1152
1153                                 glBegin(GL_QUADS);
1154                         }
1155
1156                         if(!dodraw) {
1157                                 continue;
1158                         }
1159                         else if(setDrawOptions) {
1160                                 orig = (index)? index[a]: a;
1161
1162                                 if(orig == ORIGINDEX_NONE) {
1163                                         /* since the material is set by setMaterial(), faces with no
1164                                          * origin can be assumed to be generated by a modifier */ 
1165                                         
1166                                         /* continue */
1167                                 }
1168                                 else if(!setDrawOptions(userData, orig))
1169                                         continue;
1170                         }
1171
1172                         if(!smoothnormal) {
1173                                 if(nors) {
1174                                         glNormal3fv(nors[a]);
1175                                 }
1176                                 else {
1177                                         /* TODO ideally a normal layer should always be available */
1178                                         float nor[3];
1179                                         if(mface->v4) {
1180                                                 normal_quad_v3( nor,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co);
1181                                         } else {
1182                                                 normal_tri_v3( nor,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co);
1183                                         }
1184                                         glNormal3fv(nor);
1185                                 }
1186                         }
1187
1188                         cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v1, 0, smoothnormal);
1189                         cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v2, 1, smoothnormal);
1190                         cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal);
1191
1192                         if(mface->v4)
1193                                 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v4, 3, smoothnormal);
1194                         else
1195                                 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal);
1196                 }
1197                 glEnd();
1198         }
1199         else {
1200                 GPUBuffer *buffer = NULL;
1201                 char *varray = NULL;
1202                 int numdata = 0, elementsize = 0, offset;
1203                 int start = 0, numfaces = 0 /* , prevdraw = 0 */ /* UNUSED */, curface = 0;
1204                 int i;
1205
1206                 MFace *mf = mface;
1207                 GPUAttrib datatypes[GPU_MAX_ATTRIB]; /* TODO, messing up when switching materials many times - [#21056]*/
1208                 memset(&attribs, 0, sizeof(attribs));
1209
1210                 GPU_vertex_setup(dm);
1211                 GPU_normal_setup(dm);
1212
1213                 if( !GPU_buffer_legacy(dm) ) {
1214                         for( i = 0; i < dm->drawObject->tot_triangle_point/3; i++ ) {
1215
1216                                 a = dm->drawObject->triangle_to_mface[i];
1217
1218                                 mface = mf + a;
1219                                 new_matnr = mface->mat_nr + 1;
1220
1221                                 if(new_matnr != matnr ) {
1222                                         numfaces = curface - start;
1223                                         if( numfaces > 0 ) {
1224
1225                                                 if( dodraw ) {
1226
1227                                                         if( numdata != 0 ) {
1228
1229                                                                 GPU_buffer_unlock(buffer);
1230
1231                                                                 GPU_interleaved_attrib_setup(buffer,datatypes,numdata);
1232                                                         }
1233
1234                                                         glDrawArrays(GL_TRIANGLES,start*3,numfaces*3);
1235
1236                                                         if( numdata != 0 ) {
1237
1238                                                                 GPU_buffer_free(buffer);
1239
1240                                                                 buffer = NULL;
1241                                                         }
1242
1243                                                 }
1244                                         }
1245                                         numdata = 0;
1246                                         start = curface;
1247                                         /* prevdraw = dodraw; */ /* UNUSED */
1248                                         dodraw = setMaterial(matnr = new_matnr, &gattribs);
1249                                         if(dodraw) {
1250                                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1251
1252                                                 if(attribs.totorco) {
1253                                                         datatypes[numdata].index = attribs.orco.glIndex;
1254                                                         datatypes[numdata].size = 3;
1255                                                         datatypes[numdata].type = GL_FLOAT;
1256                                                         numdata++;
1257                                                 }
1258                                                 for(b = 0; b < attribs.tottface; b++) {
1259                                                         datatypes[numdata].index = attribs.tface[b].glIndex;
1260                                                         datatypes[numdata].size = 2;
1261                                                         datatypes[numdata].type = GL_FLOAT;
1262                                                         numdata++;
1263                                                 }       
1264                                                 for(b = 0; b < attribs.totmcol; b++) {
1265                                                         datatypes[numdata].index = attribs.mcol[b].glIndex;
1266                                                         datatypes[numdata].size = 4;
1267                                                         datatypes[numdata].type = GL_UNSIGNED_BYTE;
1268                                                         numdata++;
1269                                                 }       
1270                                                 if(attribs.tottang) {
1271                                                         datatypes[numdata].index = attribs.tang.glIndex;
1272                                                         datatypes[numdata].size = 4;
1273                                                         datatypes[numdata].type = GL_FLOAT;
1274                                                         numdata++;
1275                                                 }
1276                                                 if( numdata != 0 ) {
1277                                                         elementsize = GPU_attrib_element_size( datatypes, numdata );
1278                                                         buffer = GPU_buffer_alloc( elementsize*dm->drawObject->tot_triangle_point);
1279                                                         if( buffer == NULL ) {
1280                                                                 GPU_buffer_unbind();
1281                                                                 dm->drawObject->legacy = 1;
1282                                                                 return;
1283                                                         }
1284                                                         varray = GPU_buffer_lock_stream(buffer);
1285                                                         if( varray == NULL ) {
1286                                                                 GPU_buffer_unbind();
1287                                                                 GPU_buffer_free(buffer);
1288                                                                 dm->drawObject->legacy = 1;
1289                                                                 return;
1290                                                         }
1291                                                 }
1292                                                 else {
1293                                                         /* if the buffer was set, dont use it again.
1294                                                          * prevdraw was assumed true but didnt run so set to false - [#21036] */
1295                                                         /* prevdraw= 0; */ /* UNUSED */
1296                                                         buffer= NULL;
1297                                                 }
1298                                         }
1299                                 }
1300
1301                                 if(dodraw && numdata != 0 ) {
1302                                         offset = 0;
1303                                         if(attribs.totorco) {
1304                                                 copy_v3_v3((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v1]);
1305                                                 copy_v3_v3((float *)&varray[elementsize*curface*3+elementsize],(float *)attribs.orco.array[mface->v2]);
1306                                                 copy_v3_v3((float *)&varray[elementsize*curface*3+elementsize*2],(float *)attribs.orco.array[mface->v3]);
1307                                                 offset += sizeof(float)*3;
1308                                         }
1309                                         for(b = 0; b < attribs.tottface; b++) {
1310                                                 MTFace *tf = &attribs.tface[b].array[a];
1311                                                 copy_v2_v2((float *)&varray[elementsize*curface*3+offset],tf->uv[0]);
1312                                                 copy_v2_v2((float *)&varray[elementsize*curface*3+offset+elementsize],tf->uv[1]);
1313
1314                                                 copy_v2_v2((float *)&varray[elementsize*curface*3+offset+elementsize*2],tf->uv[2]);
1315                                                 offset += sizeof(float)*2;
1316                                         }
1317                                         for(b = 0; b < attribs.totmcol; b++) {
1318                                                 MCol *cp = &attribs.mcol[b].array[a*4 + 0];
1319                                                 GLubyte col[4];
1320                                                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1321                                                 copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset], (char *)col);
1322                                                 cp = &attribs.mcol[b].array[a*4 + 1];
1323                                                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1324                                                 copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset+elementsize], (char *)col);
1325                                                 cp = &attribs.mcol[b].array[a*4 + 2];
1326                                                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1327                                                 copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset+elementsize*2], (char *)col);
1328                                                 offset += sizeof(unsigned char)*4;
1329                                         }       
1330                                         if(attribs.tottang) {
1331                                                 float *tang = attribs.tang.array[a*4 + 0];
1332                                                 copy_v4_v4((float *)&varray[elementsize*curface*3+offset], tang);
1333                                                 tang = attribs.tang.array[a*4 + 1];
1334                                                 copy_v4_v4((float *)&varray[elementsize*curface*3+offset+elementsize], tang);
1335                                                 tang = attribs.tang.array[a*4 + 2];
1336                                                 copy_v4_v4((float *)&varray[elementsize*curface*3+offset+elementsize*2], tang);
1337                                                 offset += sizeof(float)*4;
1338                                         }
1339                                         (void)offset;
1340                                 }
1341                                 curface++;
1342                                 if(mface->v4) {
1343                                         if(dodraw && numdata != 0 ) {
1344                                                 offset = 0;
1345                                                 if(attribs.totorco) {
1346                                                         copy_v3_v3((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v3]);
1347                                                         copy_v3_v3((float *)&varray[elementsize*curface*3+elementsize],(float *)attribs.orco.array[mface->v4]);
1348                                                         copy_v3_v3((float *)&varray[elementsize*curface*3+elementsize*2],(float *)attribs.orco.array[mface->v1]);
1349                                                         offset += sizeof(float)*3;
1350                                                 }
1351                                                 for(b = 0; b < attribs.tottface; b++) {
1352                                                         MTFace *tf = &attribs.tface[b].array[a];
1353                                                         copy_v2_v2((float *)&varray[elementsize*curface*3+offset],tf->uv[2]);
1354                                                         copy_v2_v2((float *)&varray[elementsize*curface*3+offset+elementsize],tf->uv[3]);
1355                                                         copy_v2_v2((float *)&varray[elementsize*curface*3+offset+elementsize*2],tf->uv[0]);
1356                                                         offset += sizeof(float)*2;
1357                                                 }
1358                                                 for(b = 0; b < attribs.totmcol; b++) {
1359                                                         MCol *cp = &attribs.mcol[b].array[a*4 + 2];
1360                                                         GLubyte col[4];
1361                                                         col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1362                                                         copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset], (char *)col);
1363                                                         cp = &attribs.mcol[b].array[a*4 + 3];
1364                                                         col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1365                                                         copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset+elementsize], (char *)col);
1366                                                         cp = &attribs.mcol[b].array[a*4 + 0];
1367                                                         col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1368                                                         copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset+elementsize*2], (char *)col);
1369                                                         offset += sizeof(unsigned char)*4;
1370                                                 }       
1371                                                 if(attribs.tottang) {
1372                                                         float *tang = attribs.tang.array[a*4 + 2];
1373                                                         copy_v4_v4((float *)&varray[elementsize*curface*3+offset], tang);
1374                                                         tang = attribs.tang.array[a*4 + 3];
1375                                                         copy_v4_v4((float *)&varray[elementsize*curface*3+offset+elementsize], tang);
1376                                                         tang = attribs.tang.array[a*4 + 0];
1377                                                         copy_v4_v4((float *)&varray[elementsize*curface*3+offset+elementsize*2], tang);
1378                                                         offset += sizeof(float)*4;
1379                                                 }
1380                                                 (void)offset;
1381                                         }
1382                                         curface++;
1383                                         i++;
1384                                 }
1385                         }
1386                         numfaces = curface - start;
1387                         if( numfaces > 0 ) {
1388                                 if( dodraw ) {
1389                                         if( numdata != 0 ) {
1390                                                 GPU_buffer_unlock(buffer);
1391                                                 GPU_interleaved_attrib_setup(buffer,datatypes,numdata);
1392                                         }
1393                                         glDrawArrays(GL_TRIANGLES,start*3,(curface-start)*3);
1394                                 }
1395                         }
1396                         GPU_buffer_unbind();
1397                 }
1398                 GPU_buffer_free(buffer);
1399         }
1400
1401         glShadeModel(GL_FLAT);
1402 }
1403
1404 static void cdDM_drawFacesGLSL(DerivedMesh *dm,int (*setMaterial)(int, void *attribs))
1405 {
1406         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1407 }
1408
1409 static void cdDM_drawMappedFacesMat(DerivedMesh *dm,
1410         void (*setMaterial)(void *userData, int, void *attribs),
1411         int (*setFace)(void *userData, int index), void *userData)
1412 {
1413         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
1414         GPUVertexAttribs gattribs;
1415         DMVertexAttribs attribs;
1416         MVert *mvert = cddm->mvert;
1417         MFace *mf = cddm->mface;
1418         float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL);
1419         int a, matnr, new_matnr;
1420         int orig, *index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1421
1422         cdDM_update_normals_from_pbvh(dm);
1423
1424         matnr = -1;
1425
1426         glShadeModel(GL_SMOOTH);
1427
1428         memset(&attribs, 0, sizeof(attribs));
1429
1430         glBegin(GL_QUADS);
1431
1432         for(a = 0; a < dm->numTessFaceData; a++, mf++) {
1433                 const int smoothnormal = (mf->flag & ME_SMOOTH);
1434
1435                 /* material */
1436                 new_matnr = mf->mat_nr + 1;
1437
1438                 if(new_matnr != matnr) {
1439                         glEnd();
1440
1441                         setMaterial(userData, matnr = new_matnr, &gattribs);
1442                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1443
1444                         glBegin(GL_QUADS);
1445                 }
1446
1447                 /* skipping faces */
1448                 if(setFace) {
1449                         orig = (index)? index[a]: a;
1450
1451                         if(orig != ORIGINDEX_NONE && !setFace(userData, orig))
1452                                 continue;
1453                 }
1454
1455                 /* smooth normal */
1456                 if(!smoothnormal) {
1457                         if(nors) {
1458                                 glNormal3fv(nors[a]);
1459                         }
1460                         else {
1461                                 /* TODO ideally a normal layer should always be available */
1462                                 float nor[3];
1463
1464                                 if(mf->v4)
1465                                         normal_quad_v3( nor,mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co);
1466                                 else
1467                                         normal_tri_v3( nor,mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co);
1468
1469                                 glNormal3fv(nor);
1470                         }
1471                 }
1472
1473                 /* vertices */
1474                 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v1, 0, smoothnormal);
1475                 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v2, 1, smoothnormal);
1476                 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal);
1477
1478                 if(mf->v4)
1479                         cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v4, 3, smoothnormal);
1480                 else
1481                         cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal);
1482         }
1483         glEnd();
1484
1485         glShadeModel(GL_FLAT);
1486 }
1487
1488 static void cdDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
1489 {
1490         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
1491         MVert *vert = cddm->mvert;
1492         MEdge *edge = cddm->medge;
1493         int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1494
1495         glBegin(GL_LINES);
1496         for(i = 0; i < dm->numEdgeData; i++, edge++) {
1497                 if(index) {
1498                         orig = *index++;
1499                         if(setDrawOptions && orig == ORIGINDEX_NONE) continue;
1500                 }
1501                 else
1502                         orig = i;
1503
1504                 if(!setDrawOptions || setDrawOptions(userData, orig)) {
1505                         glVertex3fv(vert[edge->v1].co);
1506                         glVertex3fv(vert[edge->v2].co);
1507                 }
1508         }
1509         glEnd();
1510 }
1511
1512 static void cdDM_foreachMappedVert(
1513                                                    DerivedMesh *dm,
1514                                                    void (*func)(void *userData, int index, float *co,
1515                                                                                 float *no_f, short *no_s),
1516                                                    void *userData)
1517 {
1518         MVert *mv = CDDM_get_verts(dm);
1519         int i, orig, *index = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
1520
1521         for(i = 0; i < dm->numVertData; i++, mv++) {
1522                 if(index) {
1523                         orig = *index++;
1524                         if(orig == ORIGINDEX_NONE) continue;
1525                         func(userData, orig, mv->co, NULL, mv->no);
1526                 }
1527                 else
1528                         func(userData, i, mv->co, NULL, mv->no);
1529         }
1530 }
1531
1532 static void cdDM_foreachMappedEdge(
1533                                                    DerivedMesh *dm,
1534                                                    void (*func)(void *userData, int index,
1535                                                                                 float *v0co, float *v1co),
1536                                                    void *userData)
1537 {
1538         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
1539         MVert *mv = cddm->mvert;
1540         MEdge *med = cddm->medge;
1541         int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1542
1543         for(i = 0; i < dm->numEdgeData; i++, med++) {
1544                 if (index) {
1545                         orig = *index++;
1546                         if(orig == ORIGINDEX_NONE) continue;
1547                         func(userData, orig, mv[med->v1].co, mv[med->v2].co);
1548                 }
1549                 else
1550                         func(userData, i, mv[med->v1].co, mv[med->v2].co);
1551         }
1552 }
1553
1554 static void cdDM_foreachMappedFaceCenter(
1555                                                    DerivedMesh *dm,
1556                                                    void (*func)(void *userData, int index,
1557                                                                                 float *cent, float *no),
1558                                                    void *userData)
1559 {
1560         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1561         MVert *mv = cddm->mvert;
1562         MPoly *mf = cddm->mpoly;
1563         MLoop *ml = cddm->mloop;
1564         int i, j, orig, *index;
1565
1566         index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
1567         mf = cddm->mpoly;
1568         for(i = 0; i < dm->numPolyData; i++, mf++) {
1569                 float cent[3];
1570                 float no[3];
1571
1572                 if (index) {
1573                         orig = *index++;
1574                         if(orig == ORIGINDEX_NONE) continue;
1575                 }
1576                 else
1577                         orig = i;
1578                 
1579                 ml = &cddm->mloop[mf->loopstart];
1580                 cent[0] = cent[1] = cent[2] = 0.0f;
1581                 for (j=0; j<mf->totloop; j++, ml++) {
1582                         add_v3_v3v3(cent, cent, mv[ml->v].co);
1583                 }
1584                 mul_v3_fl(cent, 1.0f / (float)j);
1585
1586                 ml = &cddm->mloop[mf->loopstart];
1587                 if (j > 3) {
1588                         normal_quad_v3(no, mv[ml->v].co, mv[(ml+1)->v].co,
1589                                        mv[(ml+2)->v].co, mv[(ml+3)->v].co);
1590                 } else {
1591                         normal_tri_v3(no, mv[ml->v].co, mv[(ml+1)->v].co, mv[(ml+2)->v].co);
1592                 }
1593
1594                 func(userData, orig, cent, no);
1595         }
1596
1597 }
1598
1599 void CDDM_recalc_tesselation_ex(DerivedMesh *dm, const int do_face_nor_cpy)
1600 {
1601         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1602
1603         dm->numTessFaceData = mesh_recalcTesselation(&dm->faceData, &dm->loopData, &dm->polyData,
1604                                                      cddm->mvert,
1605                                                      dm->numTessFaceData, dm->numLoopData, dm->numPolyData,
1606                                                      do_face_nor_cpy);
1607
1608         if (!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX)) {
1609                 int *polyIndex = CustomData_get_layer(&dm->faceData, CD_POLYINDEX);
1610                 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_REFERENCE, polyIndex, dm->numTessFaceData);
1611         }
1612
1613         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1614
1615         /* Tesselation recreated faceData, and the active layer indices need to get re-propagated
1616            from loops and polys to faces */
1617         CustomData_bmesh_update_active_layers(&dm->faceData, &dm->polyData, &dm->loopData);
1618 }
1619
1620 void CDDM_recalc_tesselation(DerivedMesh *dm)
1621 {
1622         CDDM_recalc_tesselation_ex(dm, TRUE);
1623 }
1624
1625 static void cdDM_free_internal(CDDerivedMesh *cddm)
1626 {
1627         if(cddm->fmap) MEM_freeN(cddm->fmap);
1628         if(cddm->fmap_mem) MEM_freeN(cddm->fmap_mem);
1629
1630         if(cddm->pmap) MEM_freeN(cddm->pmap);
1631         if(cddm->pmap_mem) MEM_freeN(cddm->pmap_mem);
1632 }
1633
1634 static void cdDM_release(DerivedMesh *dm)
1635 {
1636         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1637
1638         if (DM_release(dm)) {
1639                 cdDM_free_internal(cddm);
1640                 MEM_freeN(cddm);
1641         }
1642 }
1643
1644 int CDDM_Check(DerivedMesh *dm)
1645 {
1646         return dm && dm->getMinMax == cdDM_getMinMax;
1647 }
1648
1649 /**************** CDDM interface functions ****************/
1650 static CDDerivedMesh *cdDM_create(const char *desc)
1651 {
1652         CDDerivedMesh *cddm;
1653         DerivedMesh *dm;
1654
1655         cddm = MEM_callocN(sizeof(*cddm), desc);
1656         dm = &cddm->dm;
1657
1658         dm->getMinMax = cdDM_getMinMax;
1659
1660         dm->getNumVerts = cdDM_getNumVerts;
1661         dm->getNumEdges = cdDM_getNumEdges;
1662         dm->getNumTessFaces = cdDM_getNumTessFaces;
1663         dm->getNumLoops = cdDM_getNumLoops;
1664         dm->getNumPolys = cdDM_getNumPolys;
1665
1666         dm->getVert = cdDM_getVert;
1667         dm->getEdge = cdDM_getEdge;
1668         dm->getTessFace = cdDM_getTessFace;
1669
1670         dm->copyVertArray = cdDM_copyVertArray;
1671         dm->copyEdgeArray = cdDM_copyEdgeArray;
1672         dm->copyTessFaceArray = cdDM_copyTessFaceArray;
1673         dm->copyLoopArray = cdDM_copyLoopArray;
1674         dm->copyPolyArray = cdDM_copyPolyArray;
1675
1676         dm->getVertData = DM_get_vert_data;
1677         dm->getEdgeData = DM_get_edge_data;
1678         dm->getTessFaceData = DM_get_tessface_data;
1679         dm->getVertDataArray = DM_get_vert_data_layer;
1680         dm->getEdgeDataArray = DM_get_edge_data_layer;
1681         dm->getTessFaceDataArray = DM_get_tessface_data_layer;
1682
1683         dm->calcNormals = CDDM_calc_normals_mapping;
1684         dm->recalcTesselation = CDDM_recalc_tesselation;
1685
1686         dm->getVertCos = cdDM_getVertCos;
1687         dm->getVertCo = cdDM_getVertCo;
1688         dm->getVertNo = cdDM_getVertNo;
1689
1690         dm->getPBVH = cdDM_getPBVH;
1691         dm->getPolyMap = cdDM_getPolyMap;
1692         dm->getFaceMap = cdDM_getFaceMap;
1693
1694         dm->drawVerts = cdDM_drawVerts;
1695
1696         dm->drawUVEdges = cdDM_drawUVEdges;
1697         dm->drawEdges = cdDM_drawEdges;
1698         dm->drawLooseEdges = cdDM_drawLooseEdges;
1699         dm->drawMappedEdges = cdDM_drawMappedEdges;
1700
1701         dm->drawFacesSolid = cdDM_drawFacesSolid;
1702         dm->drawFacesColored = cdDM_drawFacesColored;
1703         dm->drawFacesTex = cdDM_drawFacesTex;
1704         dm->drawFacesGLSL = cdDM_drawFacesGLSL;
1705         dm->drawMappedFaces = cdDM_drawMappedFaces;
1706         dm->drawMappedFacesTex = cdDM_drawMappedFacesTex;
1707         dm->drawMappedFacesGLSL = cdDM_drawMappedFacesGLSL;
1708         dm->drawMappedFacesMat = cdDM_drawMappedFacesMat;
1709
1710         dm->foreachMappedVert = cdDM_foreachMappedVert;
1711         dm->foreachMappedEdge = cdDM_foreachMappedEdge;
1712         dm->foreachMappedFaceCenter = cdDM_foreachMappedFaceCenter;
1713
1714         dm->release = cdDM_release;
1715
1716         return cddm;
1717 }
1718
1719 DerivedMesh *CDDM_new(int numVerts, int numEdges, int numTessFaces, int numLoops, int numPolys)
1720 {
1721         CDDerivedMesh *cddm = cdDM_create("CDDM_new dm");
1722         DerivedMesh *dm = &cddm->dm;
1723
1724         DM_init(dm, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces, numLoops, numPolys);
1725
1726         CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
1727         CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
1728         CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numTessFaces);
1729         CustomData_add_layer(&dm->faceData, CD_POLYINDEX, CD_CALLOC, NULL, numTessFaces);
1730         CustomData_add_layer(&dm->polyData, CD_ORIGINDEX, CD_CALLOC, NULL, numPolys);
1731
1732         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
1733         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
1734         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numTessFaces);
1735         CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL, numLoops);
1736         CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL, numPolys);
1737
1738         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1739         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1740         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1741         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
1742         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
1743
1744         return dm;
1745 }
1746
1747 DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob))
1748 {
1749         CDDerivedMesh *cddm = cdDM_create("CDDM_from_mesh dm");
1750         DerivedMesh *dm = &cddm->dm;
1751         CustomDataMask mask = CD_MASK_MESH & (~CD_MASK_MDISPS);
1752         int alloctype;
1753         int *polyindex = NULL;
1754
1755         /* this does a referenced copy, with an exception for fluidsim */
1756
1757         DM_init(dm, DM_TYPE_CDDM, mesh->totvert, mesh->totedge, mesh->totface,
1758                     mesh->totloop, mesh->totpoly);
1759
1760         dm->deformedOnly = 1;
1761
1762         alloctype= CD_REFERENCE;
1763
1764         CustomData_merge(&mesh->vdata, &dm->vertData, mask, alloctype,
1765                                          mesh->totvert);
1766         CustomData_merge(&mesh->edata, &dm->edgeData, mask, alloctype,
1767                                          mesh->totedge);
1768         CustomData_merge(&mesh->fdata, &dm->faceData, mask|CD_MASK_POLYINDEX, alloctype,
1769                                          mesh->totface);
1770         CustomData_merge(&mesh->ldata, &dm->loopData, mask, alloctype,
1771                          mesh->totloop);
1772         CustomData_merge(&mesh->pdata, &dm->polyData, mask, alloctype,
1773                          mesh->totpoly);
1774
1775         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1776         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1777         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
1778         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
1779         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1780
1781         /* commented since even when CD_POLYINDEX was first added this line fails
1782          * on the default cube, (after editmode toggle too) - campbell */
1783 #if 0
1784         BLI_assert(CustomData_has_layer(&cddm->dm.faceData, CD_POLYINDEX));
1785 #endif
1786
1787         polyindex = CustomData_get_layer(&dm->faceData, CD_POLYINDEX);
1788         if (!CustomData_has_layer(&cddm->dm.faceData, CD_ORIGINDEX)) {
1789                 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_REFERENCE, polyindex, mesh->totface);
1790         }
1791
1792         return dm;
1793 }
1794
1795 DerivedMesh *CDDM_from_curve(Object *ob)
1796 {
1797         return CDDM_from_curve_customDB(ob, &ob->disp);
1798 }
1799
1800 DerivedMesh *CDDM_from_curve_customDB(Object *ob, ListBase *dispbase)
1801 {
1802         DerivedMesh *dm;
1803         CDDerivedMesh *cddm;
1804         MVert *allvert;
1805         MEdge *alledge;
1806         MLoop *allloop;
1807         MPoly *allpoly;
1808         int totvert, totedge, totloop, totpoly;
1809
1810         if (nurbs_to_mdata_customdb(ob, dispbase, &allvert, &totvert, &alledge,
1811                 &totedge, &allloop, &allpoly, &totloop, &totpoly) != 0) {
1812                 /* Error initializing mdata. This often happens when curve is empty */
1813                 return CDDM_new(0, 0, 0, 0, 0);
1814         }
1815
1816         dm = CDDM_new(totvert, totedge, 0, totloop, totpoly);
1817         dm->deformedOnly = 1;
1818
1819         cddm = (CDDerivedMesh*)dm;
1820
1821         memcpy(cddm->mvert, allvert, totvert*sizeof(MVert));
1822         memcpy(cddm->medge, alledge, totedge*sizeof(MEdge));
1823         memcpy(cddm->mloop, allloop, totloop*sizeof(MLoop));
1824         memcpy(cddm->mpoly, allpoly, totpoly*sizeof(MPoly));
1825
1826         MEM_freeN(allvert);
1827         MEM_freeN(alledge);
1828         MEM_freeN(allloop);
1829         MEM_freeN(allpoly);
1830
1831         CDDM_calc_edges(dm);
1832
1833         return dm;
1834 }
1835
1836 static void loops_to_customdata_corners(BMesh *bm, CustomData *facedata,
1837                                           int cdindex, BMLoop *l3[3],
1838                                           int numCol, int numTex)
1839 {
1840         BMLoop *l;
1841         BMFace *f = l3[0]->f;
1842         MTFace *texface;
1843         MTexPoly *texpoly;
1844         MCol *mcol;
1845         MLoopCol *mloopcol;
1846         MLoopUV *mloopuv;
1847         int i, j, hasWCol = CustomData_has_layer(&bm->ldata, CD_WEIGHT_MLOOPCOL);
1848
1849         for (i=0; i < numTex; i++) {
1850                 texface = CustomData_get_n(facedata, CD_MTFACE, cdindex, i);
1851                 texpoly = CustomData_bmesh_get_n(&bm->pdata, f->head.data, CD_MTEXPOLY, i);
1852                 
1853                 ME_MTEXFACE_CPY(texface, texpoly);
1854         
1855                 for (j=0; j<3; j++) {
1856                         l = l3[j];
1857                         mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPUV, i);
1858                         copy_v2_v2(texface->uv[j], mloopuv->uv);
1859                 }
1860         }
1861
1862         for (i=0; i < numCol; i++) {
1863                 mcol = CustomData_get_n(facedata, CD_MCOL, cdindex, i);
1864                 
1865                 for (j=0; j<3; j++) {
1866                         l = l3[j];
1867                         mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPCOL, i);
1868                         mcol[j].r = mloopcol->r;
1869                         mcol[j].g = mloopcol->g;
1870                         mcol[j].b = mloopcol->b;
1871                         mcol[j].a = mloopcol->a;
1872                 }
1873         }
1874
1875         if (hasWCol) {
1876                 mcol = CustomData_get(facedata, cdindex, CD_WEIGHT_MCOL);
1877
1878                 for (j=0; j<3; j++) {
1879                         l = l3[j];
1880                         mloopcol = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_WEIGHT_MLOOPCOL);
1881                         mcol[j].r = mloopcol->r;
1882                         mcol[j].g = mloopcol->g;
1883                         mcol[j].b = mloopcol->b;
1884                         mcol[j].a = mloopcol->a;
1885                 }
1886         }
1887 }
1888
1889 DerivedMesh *CDDM_from_BMEditMesh(BMEditMesh *em, Mesh *UNUSED(me), int use_mdisps, int use_tessface)
1890 {
1891         BMesh *bm = em->bm;
1892
1893         DerivedMesh *dm = CDDM_new(bm->totvert,
1894                                    bm->totedge,
1895                                    use_tessface ? em->tottri : 0,
1896                                    bm->totloop,
1897                                    bm->totface);
1898
1899         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1900         BMIter iter, liter;
1901         BMVert *eve;
1902         BMEdge *eed;
1903         BMFace *efa;
1904         MVert *mvert = cddm->mvert;
1905         MEdge *medge = cddm->medge;
1906         MFace *mface = cddm->mface;
1907         MLoop *mloop = cddm->mloop;
1908         MPoly *mpoly = cddm->mpoly;
1909         int numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL);
1910         int numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
1911         int *index, add_orig;
1912         int has_crease, has_edge_bweight, has_vert_bweight;
1913         CustomDataMask mask;
1914         unsigned int i, j;
1915         
1916         has_edge_bweight = CustomData_has_layer(&bm->edata, CD_BWEIGHT);
1917         has_vert_bweight = CustomData_has_layer(&bm->vdata, CD_BWEIGHT);
1918         has_crease = CustomData_has_layer(&bm->edata, CD_CREASE);
1919         
1920         dm->deformedOnly = 1;
1921         
1922         /*don't add origindex layer if one already exists*/
1923         add_orig = !CustomData_has_layer(&bm->pdata, CD_ORIGINDEX);
1924
1925         mask = use_mdisps ? CD_MASK_DERIVEDMESH|CD_MASK_MDISPS : CD_MASK_DERIVEDMESH;
1926         
1927         /*don't process shapekeys, we only feed them through the modifier stack as needed,
1928           e.g. for applying modifiers or the like*/
1929         mask &= ~CD_MASK_SHAPEKEY;
1930         CustomData_merge(&bm->vdata, &dm->vertData, mask,
1931                          CD_CALLOC, dm->numVertData);
1932         CustomData_merge(&bm->edata, &dm->edgeData, mask,
1933                          CD_CALLOC, dm->numEdgeData);
1934         CustomData_merge(&bm->ldata, &dm->loopData, mask,
1935                          CD_CALLOC, dm->numLoopData);
1936         CustomData_merge(&bm->pdata, &dm->polyData, mask,
1937                          CD_CALLOC, dm->numPolyData);
1938         
1939         /*add tesselation mface layers*/
1940         if (use_tessface) {
1941                 CustomData_from_bmeshpoly(&dm->faceData, &dm->polyData, &dm->loopData, em->tottri);
1942         }
1943
1944         index = dm->getVertDataArray(dm, CD_ORIGINDEX);
1945
1946         eve = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL);
1947         for (i=0; eve; eve=BM_iter_step(&iter), i++, index++) {
1948                 MVert *mv = &mvert[i];
1949
1950                 copy_v3_v3(mv->co, eve->co);
1951
1952                 BM_elem_index_set(eve, i); /* set_inline */
1953
1954                 normal_float_to_short_v3(mv->no, eve->no);
1955
1956                 mv->flag = BM_vert_flag_to_mflag(eve);
1957
1958                 if (has_vert_bweight)
1959                         mv->bweight = (unsigned char)(BM_elem_float_data_get(&bm->vdata, eve, CD_BWEIGHT)*255.0f);
1960
1961                 if (add_orig) *index = i;
1962
1963                 CustomData_from_bmesh_block(&bm->vdata, &dm->vertData, eve->head.data, i);
1964         }
1965         bm->elem_index_dirty &= ~BM_VERT;
1966
1967         index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
1968         eed = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, NULL);
1969         for (i=0; eed; eed=BM_iter_step(&iter), i++, index++) {
1970                 MEdge *med = &medge[i];
1971
1972                 BM_elem_index_set(eed, i); /* set_inline */
1973
1974                 med->v1 = BM_elem_index_get(eed->v1);
1975                 med->v2 = BM_elem_index_get(eed->v2);
1976
1977                 if (has_crease)
1978                         med->crease = (unsigned char)(BM_elem_float_data_get(&bm->edata, eed, CD_CREASE)*255.0f);
1979                 if (has_edge_bweight)
1980                         med->bweight = (unsigned char)(BM_elem_float_data_get(&bm->edata, eed, CD_BWEIGHT)*255.0f);
1981                 
1982                 med->flag = BM_edge_flag_to_mflag(eed);
1983
1984                 CustomData_from_bmesh_block(&bm->edata, &dm->edgeData, eed->head.data, i);
1985                 if (add_orig) *index = i;
1986         }
1987         bm->elem_index_dirty &= ~BM_EDGE;
1988
1989         /* avoid this where possiblem, takes extra memory */
1990         if (use_tessface) {
1991                 int *polyindex;
1992
1993                 BM_mesh_elem_index_ensure(bm, BM_FACE);
1994
1995                 polyindex = dm->getTessFaceDataArray(dm, CD_POLYINDEX);
1996                 index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1997                 for(i = 0; i < dm->numTessFaceData; i++, index++, polyindex++) {
1998                         MFace *mf = &mface[i];
1999                         BMLoop **l = em->looptris[i];
2000                         efa = l[0]->f;
2001
2002                         mf->v1 = BM_elem_index_get(l[0]->v);
2003                         mf->v2 = BM_elem_index_get(l[1]->v);
2004                         mf->v3 = BM_elem_index_get(l[2]->v);
2005                         mf->v4 = 0;
2006                         mf->mat_nr = efa->mat_nr;
2007                         mf->flag = BM_face_flag_to_mflag(efa);
2008
2009                         *index = add_orig ? BM_elem_index_get(efa) : *(int*)CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_ORIGINDEX);
2010                         *polyindex = BM_elem_index_get(efa);
2011
2012                         loops_to_customdata_corners(bm, &dm->faceData, i, l, numCol, numTex);
2013                         test_index_face(mf, &dm->faceData, i, 3);
2014                 }
2015         }
2016         
2017         index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
2018         j = 0;
2019         efa = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, NULL);
2020         for (i=0; efa; i++, efa=BM_iter_step(&iter), index++) {
2021                 BMLoop *l;
2022                 MPoly *mp = &mpoly[i];
2023
2024                 BM_elem_index_set(efa, i); /* set_inline */
2025
2026                 mp->totloop = efa->len;
2027                 mp->flag = BM_face_flag_to_mflag(efa);
2028                 mp->loopstart = j;
2029                 mp->mat_nr = efa->mat_nr;
2030                 
2031                 BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, efa) {
2032                         mloop->v = BM_elem_index_get(l->v);
2033                         mloop->e = BM_elem_index_get(l->e);
2034                         CustomData_from_bmesh_block(&bm->ldata, &dm->loopData, l->head.data, j);
2035
2036                         j++;
2037                         mloop++;
2038                 }
2039
2040                 CustomData_from_bmesh_block(&bm->pdata, &dm->polyData, efa->head.data, i);
2041
2042                 if (add_orig) *index = i;
2043         }
2044         bm->elem_index_dirty &= ~BM_FACE;
2045
2046         return dm;
2047 }
2048
2049 static DerivedMesh *cddm_copy_ex(DerivedMesh *source, int faces_from_tessfaces)
2050 {
2051         CDDerivedMesh *cddm = cdDM_create("CDDM_copy cddm");
2052         DerivedMesh *dm = &cddm->dm;
2053         int numVerts = source->numVertData;
2054         int numEdges = source->numEdgeData;
2055         int numTessFaces = source->numTessFaceData;
2056         int numLoops = source->numLoopData;
2057         int numPolys = source->numPolyData;
2058
2059         /* ensure these are created if they are made on demand */
2060         source->getVertDataArray(source, CD_ORIGINDEX);
2061         source->getEdgeDataArray(source, CD_ORIGINDEX);
2062         source->getTessFaceDataArray(source, CD_ORIGINDEX);
2063
2064         /* this initializes dm, and copies all non mvert/medge/mface layers */
2065         DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces,
2066                 numLoops, numPolys);
2067         dm->deformedOnly = source->deformedOnly;
2068
2069         CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts);
2070         CustomData_copy_data(&source->edgeData, &dm->edgeData, 0, 0, numEdges);
2071         CustomData_copy_data(&source->faceData, &dm->faceData, 0, 0, numTessFaces);
2072
2073         /* now add mvert/medge/mface layers */
2074         cddm->mvert = source->dupVertArray(source);
2075         cddm->medge = source->dupEdgeArray(source);
2076         cddm->mface = source->dupTessFaceArray(source);
2077
2078         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, cddm->mvert, numVerts);
2079         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, cddm->medge, numEdges);
2080         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, cddm->mface, numTessFaces);
2081         
2082         if (!faces_from_tessfaces)
2083                 DM_DupPolys(source, dm);
2084         else
2085                 CDDM_tessfaces_to_faces(dm);
2086
2087         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
2088         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
2089
2090         /* any callers that need tessface data can calculate it - campbell */
2091 #if 0
2092         /* BMESH_TODO: Find out why this is necessary (or else find a way to remove
2093            it). If it is necessary, add a comment explaining why. */
2094         CDDM_recalc_tesselation((DerivedMesh *)cddm);
2095 #endif
2096
2097         return dm;
2098 }
2099
2100 DerivedMesh *CDDM_copy(DerivedMesh *source)
2101 {
2102         return cddm_copy_ex(source, 0);
2103 }
2104
2105 DerivedMesh *CDDM_copy_from_tessface(DerivedMesh *source)
2106 {
2107         return cddm_copy_ex(source, 1);
2108 }
2109
2110 /* note, the CD_ORIGINDEX layers are all 0, so if there is a direct
2111  * relationship betwen mesh data this needs to be set by the caller. */
2112 DerivedMesh *CDDM_from_template(DerivedMesh *source,
2113                                 int numVerts, int numEdges, int numTessFaces,
2114                                 int numLoops, int numPolys)
2115 {
2116         CDDerivedMesh *cddm = cdDM_create("CDDM_from_template dest");
2117         DerivedMesh *dm = &cddm->dm;
2118
2119         /* ensure these are created if they are made on demand */
2120         source->getVertDataArray(source, CD_ORIGINDEX);
2121         source->getEdgeDataArray(source, CD_ORIGINDEX);
2122         source->getTessFaceDataArray(source, CD_ORIGINDEX);
2123
2124         /* this does a copy of all non mvert/medge/mface layers */
2125         DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces, numLoops, numPolys);
2126
2127         /* now add mvert/medge/mface layers */
2128         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
2129         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2130         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numTessFaces);
2131         CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL, numLoops);
2132         CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL, numPolys);
2133
2134         if(!CustomData_get_layer(&dm->vertData, CD_ORIGINDEX))
2135                 CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
2136         if(!CustomData_get_layer(&dm->edgeData, CD_ORIGINDEX))
2137                 CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2138         if(!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX))
2139                 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numTessFaces);
2140         if(!CustomData_get_layer(&dm->faceData, CD_POLYINDEX))
2141                 CustomData_add_layer(&dm->faceData, CD_POLYINDEX, CD_CALLOC, NULL, numTessFaces);
2142
2143         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
2144         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2145         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
2146         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
2147         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
2148
2149         return dm;
2150 }
2151
2152 void CDDM_apply_vert_coords(DerivedMesh *dm, float (*vertCoords)[3])
2153 {
2154         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2155         MVert *vert;
2156         int i;
2157
2158         /* this will just return the pointer if it wasn't a referenced layer */
2159         vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2160         cddm->mvert = vert;
2161
2162         for(i = 0; i < dm->numVertData; ++i, ++vert)
2163                 copy_v3_v3(vert->co, vertCoords[i]);
2164 }
2165
2166 void CDDM_apply_vert_normals(DerivedMesh *dm, short (*vertNormals)[3])
2167 {
2168         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2169         MVert *vert;
2170         int i;
2171
2172         /* this will just return the pointer if it wasn't a referenced layer */
2173         vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2174         cddm->mvert = vert;
2175
2176         for(i = 0; i < dm->numVertData; ++i, ++vert)
2177                 copy_v3_v3_short(vert->no, vertNormals[i]);
2178 }
2179
2180 void CDDM_calc_normals_mapping(DerivedMesh *dm)
2181 {
2182         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2183         float (*face_nors)[3] = NULL;
2184
2185         /* use this to skip calculating normals on original vert's, this may need to be changed */
2186         const short only_face_normals = CustomData_is_referenced_layer(&dm->vertData, CD_MVERT);
2187         
2188         if(dm->numVertData == 0) return;
2189
2190         /* now we skip calculating vertex normals for referenced layer,
2191          * no need to duplicate verts.
2192          * WATCH THIS, bmesh only change!,
2193          * need to take care of the side effects here - campbell */
2194 #if 0
2195         /* we don't want to overwrite any referenced layers */
2196         cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2197 #endif
2198
2199
2200         if (dm->numTessFaceData == 0) {
2201                 /* No tesselation on this mesh yet, need to calculate one.
2202                  *
2203                  * Important not to update face normals from polys since it
2204                  * interfears with assigning the new normal layer in the following code.
2205                  */
2206                 CDDM_recalc_tesselation_ex(dm, FALSE);
2207         }
2208         else {
2209                 /* A tesselation already exists, it should always have a CD_POLYINDEX */
2210                 BLI_assert(CustomData_has_layer(&dm->faceData, CD_POLYINDEX));
2211                 CustomData_free_layers(&dm->faceData, CD_NORMAL, dm->numTessFaceData);
2212         }
2213
2214
2215         face_nors = MEM_mallocN(sizeof(float)*3*dm->numTessFaceData, "face_nors");
2216         
2217         /* calculate face normals */
2218         mesh_calc_normals_mapping_ex(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm),
2219                                      dm->numLoopData, dm->numPolyData, NULL, cddm->mface, dm->numTessFaceData,
2220                                      CustomData_get_layer(&dm->faceData, CD_POLYINDEX), face_nors,
2221                                      only_face_normals);
2222         
2223         CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_ASSIGN, 
2224                              face_nors, dm->numTessFaceData);
2225
2226
2227 }
2228
2229 /* bmesh note: this matches what we have in trunk */
2230 void CDDM_calc_normals(DerivedMesh *dm)
2231 {
2232         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2233         float (*poly_nors)[3];
2234
2235         if(dm->numVertData == 0) return;
2236
2237         /* we don't want to overwrite any referenced layers */
2238         cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2239
2240         /* fill in if it exists */
2241         poly_nors = CustomData_get_layer(&dm->polyData, CD_NORMAL);
2242         if (!poly_nors) {
2243                 poly_nors = CustomData_add_layer(&dm->polyData, CD_NORMAL, CD_CALLOC, NULL, dm->numPolyData);
2244         }
2245
2246         mesh_calc_normals(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm),
2247                           dm->numLoopData, dm->numPolyData, poly_nors);
2248 }
2249
2250 void CDDM_calc_normals_tessface(DerivedMesh *dm)
2251 {
2252         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2253         float (*face_nors)[3];
2254
2255         if(dm->numVertData == 0) return;
2256
2257         /* we don't want to overwrite any referenced layers */
2258         cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2259
2260         /* fill in if it exists */
2261         face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
2262         if (!face_nors) {
2263                 face_nors = CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_CALLOC, NULL, dm->numTessFaceData);
2264         }
2265
2266         mesh_calc_normals_tessface(cddm->mvert, dm->numVertData,
2267                                                            cddm->mface, dm->numTessFaceData, face_nors);
2268 }
2269
2270 #if 1
2271 /* merge verts
2272  *
2273  * vtargetmap is a table that maps vertices to target vertices.  a value of -1
2274  * indicates a vertex is a target, and is to be kept.
2275  *
2276  * this frees dm, and returns a new one.
2277  *
2278  * this is a really horribly written function.  ger. - joeedh
2279  *
2280  * note, CDDM_recalc_tesselation has to run on the returned DM if you want to access tessfaces.
2281  */
2282 DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap)
2283 {
2284         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2285         CDDerivedMesh *cddm2 = NULL;
2286         MVert *mv, *mvert = NULL;
2287         BLI_array_declare(mvert);
2288         MEdge *med, *medge = NULL;
2289         BLI_array_declare(medge);
2290         MPoly *mp, *mpoly = NULL;
2291         BLI_array_declare(mpoly);
2292         MLoop *ml, *mloop = NULL;
2293         BLI_array_declare(mloop);
2294         EdgeHash *ehash = BLI_edgehash_new();
2295         int *newv = NULL, *newe = NULL, *newl = NULL;
2296         int *oldv = NULL, *olde = NULL, *oldl = NULL, *oldp = NULL;
2297         BLI_array_declare(oldv); BLI_array_declare(olde); BLI_array_declare(oldl); BLI_array_declare(oldp);
2298         int i, j, c, totloop, totpoly;
2299         
2300         totloop = dm->numLoopData;
2301         totpoly = dm->numPolyData;
2302         
2303         newv = MEM_callocN(sizeof(int)*dm->numVertData, "newv vtable CDDM_merge_verts");
2304         newe = MEM_callocN(sizeof(int)*dm->numEdgeData, "newv etable CDDM_merge_verts");
2305         newl = MEM_callocN(sizeof(int)*totloop, "newv ltable CDDM_merge_verts");
2306         
2307         /*fill newl with destination vertex indices*/
2308         mv = cddm->mvert;
2309         c = 0;
2310         for (i=0; i<dm->numVertData; i++, mv++) {
2311                 if (vtargetmap[i] == -1) {
2312                         BLI_array_append(oldv, i);
2313                         newv[i] = c++;
2314                         BLI_array_append(mvert, *mv);
2315                 }
2316         }
2317         
2318         /*now link target vertices to destination indices*/
2319         for (i=0; i<dm->numVertData; i++) {
2320                 if (vtargetmap[i] != -1) {
2321                         newv[i] = newv[vtargetmap[i]];
2322                 }
2323         }
2324         
2325         /*find-replace merged vertices with target vertices*/   
2326         ml = cddm->mloop;
2327         c = 0;
2328         for (i=0; i<totloop; i++, ml++) {
2329                 if (vtargetmap[ml->v] != -1) {
2330                         ml->v = vtargetmap[ml->v];
2331                 }
2332         }
2333
2334         /*now go through and fix edges and faces*/
2335         med = cddm->medge;
2336         c = 0;
2337         for (i=0; i<dm->numEdgeData; i++, med++) {
2338                 
2339                 if (LIKELY(med->v1 != med->v2)) {
2340                         const unsigned int v1 = (vtargetmap[med->v1] != -1) ? vtargetmap[med->v1] : med->v1;
2341                         const unsigned int v2 = (vtargetmap[med->v2] != -1) ? vtargetmap[med->v2] : med->v2;
2342                         void **eh_p= BLI_edgehash_lookup_p(ehash, v1, v2);
2343
2344                         if (eh_p) {
2345                                 newe[i] = GET_INT_FROM_POINTER(*eh_p);
2346                         }
2347                         else {
2348                                 BLI_array_append(olde, i);
2349                                 newe[i] = c;
2350                                 BLI_array_append(medge, *med);
2351                                 BLI_edgehash_insert(ehash, v1, v2, SET_INT_IN_POINTER(c));
2352                                 c++;
2353                         }
2354                 }
2355                 else {
2356                         newe[i] = -1;
2357                 }
2358         }
2359         
2360         mp = cddm->mpoly;
2361         for (i=0; i<totpoly; i++, mp++) {
2362                 MPoly *mp2;
2363                 
2364                 ml = cddm->mloop + mp->loopstart;
2365
2366                 c = 0;
2367                 for (j=0; j<mp->totloop; j++, ml++) {
2368                         med = cddm->medge + ml->e;
2369                         if (LIKELY(med->v1 != med->v2)) {
2370                                 newl[j+mp->loopstart] = BLI_array_count(mloop);
2371                                 BLI_array_append(oldl, j+mp->loopstart);
2372                                 BLI_array_append(mloop, *ml);
2373                                 c++;
2374                         }
2375                 }
2376
2377                 if (UNLIKELY(c == 0)) {
2378                         continue;
2379                 }
2380                 
2381                 mp2 = BLI_array_append_r(mpoly, *mp);
2382                 mp2->totloop = c;
2383                 mp2->loopstart = BLI_array_count(mloop) - c;
2384                 
2385                 BLI_array_append(oldp, i);
2386         }
2387         
2388         /*create new cddm*/     
2389         cddm2 = (CDDerivedMesh*) CDDM_from_template((DerivedMesh*)cddm, BLI_array_count(mvert), BLI_array_count(medge), 0, BLI_array_count(mloop), BLI_array_count(mpoly));
2390         
2391         /*update edge indices and copy customdata*/
2392         med = medge;
2393         for (i=0; i<cddm2->dm.numEdgeData; i++, med++) {
2394                 if (newv[med->v1] != -1)
2395                         med->v1 = newv[med->v1];
2396                 if (newv[med->v2] != -1)
2397                         med->v2 = newv[med->v2];
2398                 
2399                 CustomData_copy_data(&dm->edgeData, &cddm2->dm.edgeData, olde[i], i, 1);
2400         }
2401         
2402         /*update loop indices and copy customdata*/
2403         ml = mloop;
2404         for (i=0; i<cddm2->dm.numLoopData; i++, ml++) {
2405                 if (newe[ml->e] != -1)
2406                         ml->e = newe[ml->e];
2407                 if (newv[ml->v] != -1)
2408                         ml->v = newv[ml->v];
2409                         
2410                 CustomData_copy_data(&dm->loopData, &cddm2->dm.loopData, oldl[i], i, 1);
2411         }
2412         
2413         /*copy vertex customdata*/      
2414         mv = mvert;
2415         for (i=0; i<cddm2->dm.numVertData; i++, mv++) {
2416                 CustomData_copy_data(&dm->vertData, &cddm2->dm.vertData, oldv[i], i, 1);
2417         }
2418         
2419         /*copy poly customdata*/
2420         mp = mpoly;
2421         for (i=0; i<cddm2->dm.numPolyData; i++, mp++) {
2422                 CustomData_copy_data(&dm->polyData, &cddm2->dm.polyData, oldp[i], i, 1);
2423         }
2424         
2425         /*copy over data.  CustomData_add_layer can do this, need to look it up.*/
2426         memcpy(cddm2->mvert, mvert, sizeof(MVert)*BLI_array_count(mvert));
2427         memcpy(cddm2->medge, medge, sizeof(MEdge)*BLI_array_count(medge));
2428         memcpy(cddm2->mloop, mloop, sizeof(MLoop)*BLI_array_count(mloop));
2429         memcpy(cddm2->mpoly, mpoly, sizeof(MPoly)*BLI_array_count(mpoly));
2430         BLI_array_free(mvert); BLI_array_free(medge); BLI_array_free(mloop); BLI_array_free(mpoly);
2431         
2432         if (newv) 
2433                 MEM_freeN(newv); 
2434         if (newe)
2435                 MEM_freeN(newe); 
2436         if (newl)
2437                 MEM_freeN(newl);
2438         if (oldv) 
2439                 MEM_freeN(oldv); 
2440         if (olde) 
2441                 MEM_freeN(olde); 
2442         if (oldl) 
2443                 MEM_freeN(oldl); 
2444         if (oldp) 
2445                 MEM_freeN(oldp);
2446         if (ehash)
2447                 BLI_edgehash_free(ehash, NULL);
2448
2449         /*free old derivedmesh*/
2450         dm->needsFree = 1;
2451         dm->release(dm);
2452         
2453         return (DerivedMesh*)cddm2;
2454 }
2455 #endif
2456
2457 void CDDM_calc_edges_tessface(DerivedMesh *dm)
2458 {
2459         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2460         CustomData edgeData;
2461         EdgeHashIterator *ehi;
2462         MFace *mf = cddm->mface;
2463         MEdge *med;
2464         EdgeHash *eh = BLI_edgehash_new();
2465         int i, *index, numEdges, maxFaces = dm->numTessFaceData;
2466
2467         for (i = 0; i < maxFaces; i++, mf++) {
2468                 if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
2469                         BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
2470                 if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
2471                         BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
2472                 
2473                 if (mf->v4) {
2474                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
2475                                 BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
2476                         if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
2477                                 BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
2478                 } else {
2479                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
2480                                 BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
2481                 }
2482         }
2483
2484         numEdges = BLI_edgehash_size(eh);
2485
2486         /* write new edges into a temporary CustomData */
2487         memset(&edgeData, 0, sizeof(edgeData));
2488         CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2489         CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2490
2491         ehi = BLI_edgehashIterator_new(eh);
2492         med = CustomData_get_layer(&edgeData, CD_MEDGE);
2493         index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
2494         for(i = 0; !BLI_edgehashIterator_isDone(ehi);
2495                 BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) {
2496                 BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2);
2497
2498                 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
2499                 *index = ORIGINDEX_NONE;
2500         }
2501         BLI_edgehashIterator_free(ehi);
2502
2503         /* free old CustomData and assign new one */
2504         CustomData_free(&dm->edgeData, dm->numEdgeData);
2505         dm->edgeData = edgeData;
2506         dm->numEdgeData = numEdges;
2507
2508         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2509
2510         BLI_edgehash_free(eh, NULL);
2511 }
2512
2513 /* warning, this uses existing edges but CDDM_calc_edges_tessface() doesn't */
2514 void CDDM_calc_edges(DerivedMesh *dm)
2515 {
2516         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2517         CustomData edgeData;
2518         EdgeHashIterator *ehi;
2519         MPoly *mp = cddm->mpoly;
2520         MLoop *ml;
2521         MEdge *med;
2522         EdgeHash *eh = BLI_edgehash_new();
2523         int v1, v2;
2524         int *eindex;
2525         int i, j, *index, numEdges = cddm->dm.numEdgeData, maxFaces = dm->numPolyData;
2526
2527         eindex = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
2528
2529         med = cddm->medge;
2530         if (med) {
2531                 for (i=0; i < numEdges; i++, med++) {
2532                         BLI_edgehash_insert(eh, med->v1, med->v2, SET_INT_IN_POINTER(i+1));
2533                 }
2534         }
2535
2536         for (i=0; i < maxFaces; i++, mp++) {
2537                 ml = cddm->mloop + mp->loopstart;
2538                 for (j=0; j<mp->totloop; j++, ml++) {
2539                         v1 = ml->v;
2540                         v2 = ME_POLY_LOOP_NEXT(cddm->mloop, mp, j)->v;
2541                         if (!BLI_edgehash_haskey(eh, v1, v2)) {
2542                                 BLI_edgehash_insert(eh, v1, v2, NULL);
2543                         }
2544                 }
2545         }
2546
2547         numEdges = BLI_edgehash_size(eh);
2548
2549         /* write new edges into a temporary CustomData */
2550         memset(&edgeData, 0, sizeof(edgeData));
2551         CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2552         CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2553
2554         ehi = BLI_edgehashIterator_new(eh);
2555         med = CustomData_get_layer(&edgeData, CD_MEDGE);
2556         index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
2557         for(i = 0; !BLI_edgehashIterator_isDone(ehi);
2558             BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) {
2559                 BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2);
2560                 j = GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi));
2561
2562                 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
2563                 *index = j==0 ? ORIGINDEX_NONE : eindex[j-1];
2564
2565                 BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(i));
2566         }
2567         BLI_edgehashIterator_free(ehi);
2568
2569         /* free old CustomData and assign new one */
2570         CustomData_free(&dm->edgeData, dm->numEdgeData);
2571         dm->edgeData = edgeData;
2572         dm->numEdgeData = numEdges;
2573
2574         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2575
2576         mp = cddm->mpoly;
2577         for (i=0; i < maxFaces; i++, mp++) {
2578                 ml = cddm->mloop + mp->loopstart;
2579                 for (j=0; j<mp->totloop; j++, ml++) {
2580                         v1 = ml->v;
2581                         v2 = ME_POLY_LOOP_NEXT(cddm->mloop, mp, j)->v;
2582                         ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, v1, v2));
2583                 }
2584         }
2585
2586         BLI_edgehash_free(eh, NULL);
2587 }
2588
2589 void CDDM_lower_num_verts(DerivedMesh *dm, int numVerts)
2590 {
2591         if (numVerts < dm->numVertData)
2592                 CustomData_free_elem(&dm->vertData, numVerts, dm->numVertData-numVerts);
2593
2594         dm->numVertData = numVerts;
2595 }
2596
2597 void CDDM_lower_num_edges(DerivedMesh *dm, int numEdges)
2598 {
2599         if (numEdges < dm->numEdgeData)
2600                 CustomData_free_elem(&dm->edgeData, numEdges, dm->numEdgeData-numEdges);
2601
2602         dm->numEdgeData = numEdges;
2603 }
2604
2605 void CDDM_lower_num_tessfaces(DerivedMesh *dm, int numTessFaces)
2606 {
2607         if (numTessFaces < dm->numTessFaceData)
2608                 CustomData_free_elem(&dm->faceData, numTessFaces, dm->numTessFaceData-numTessFaces);
2609
2610         dm->numTessFaceData = numTessFaces;
2611 }
2612
2613 void CDDM_lower_num_polys(DerivedMesh *dm, int numPolys)
2614 {
2615         if (numPolys < dm->numPolyData)
2616                 CustomData_free_elem(&dm->polyData, numPolys, dm->numPolyData-numPolys);
2617
2618         dm->numPolyData = numPolys;
2619 }
2620
2621 /* mesh element access functions */
2622
2623 MVert *CDDM_get_vert(DerivedMesh *dm, int index)
2624 {
2625         return &((CDDerivedMesh*)dm)->mvert[index];
2626 }
2627
2628 MEdge *CDDM_get_edge(DerivedMesh *dm, int index)
2629 {
2630         return &((CDDerivedMesh*)dm)->medge[index];
2631 }
2632
2633 MFace *CDDM_get_tessface(DerivedMesh *dm, int index)
2634 {
2635         return &((CDDerivedMesh*)dm)->mface[index];
2636 }
2637
2638 MLoop *CDDM_get_loop(DerivedMesh *dm, int index)
2639 {
2640         return &((CDDerivedMesh*)dm)->mloop[index];
2641 }
2642
2643 MPoly *CDDM_get_poly(DerivedMesh *dm, int index)
2644 {
2645         return &((CDDerivedMesh*)dm)->mpoly[index];
2646 }
2647
2648 /* array access functions */
2649
2650 MVert *CDDM_get_verts(DerivedMesh *dm)
2651 {
2652         return ((CDDerivedMesh*)dm)->mvert;
2653 }
2654
2655 MEdge *CDDM_get_edges(DerivedMesh *dm)
2656 {
2657         return ((CDDerivedMesh*)dm)->medge;
2658 }
2659
2660 MFace *CDDM_get_tessfaces(DerivedMesh *dm)
2661 {
2662         return ((CDDerivedMesh*)dm)->mface;
2663 }
2664
2665 MLoop *CDDM_get_loops(DerivedMesh *dm)
2666 {
2667         return ((CDDerivedMesh*)dm)->mloop;
2668 }
2669
2670 MPoly *CDDM_get_polys(DerivedMesh *dm)
2671 {
2672         return ((CDDerivedMesh*)dm)->mpoly;
2673 }
2674
2675 void CDDM_tessfaces_to_faces(DerivedMesh *dm)
2676 {
2677         /*converts mfaces to mpolys/mloops*/
2678         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2679         MFace *mf;
2680         MEdge *me;
2681         EdgeHash *eh = BLI_edgehash_new();
2682         int i, totloop;
2683         
2684         /*ensure we have all the edges we need*/
2685         CDDM_calc_edges_tessface(dm);
2686
2687         /*build edge hash*/
2688         me = cddm->medge;
2689         for (i=0; i<cddm->dm.numEdgeData; i++, me++) {
2690                 BLI_edgehash_insert(eh, me->v1, me->v2, SET_INT_IN_POINTER(i));
2691         }
2692
2693         mf = cddm->mface;
2694         totloop = 0;
2695         for (i=0; i<cddm->dm.numTessFaceData; i++, mf++) {
2696                 totloop += mf->v4 ? 4 : 3;
2697         }
2698
2699         CustomData_free(&cddm->dm.polyData, cddm->dm.numPolyData);
2700         CustomData_free(&cddm->dm.loopData, cddm->dm.numLoopData);
2701         
2702         cddm->dm.numLoopData = totloop;
2703         cddm->dm.numPolyData = cddm->dm.numTessFaceData;
2704
2705         if (totloop) {
2706                 MLoop *ml;
2707                 MPoly *mp;
2708                 int l, *polyindex;
2709
2710                 cddm->mloop = MEM_callocN(sizeof(MLoop)*totloop, "cddm->mloop in CDDM_tessfaces_to_faces");
2711                 cddm->mpoly = MEM_callocN(sizeof(MPoly)*cddm->dm.numTessFaceData, "cddm->mpoly in CDDM_tessfaces_to_faces");
2712
2713                 CustomData_add_layer(&cddm->dm.loopData, CD_MLOOP, CD_ASSIGN, cddm->mloop, totloop);
2714                 CustomData_add_layer(&cddm->dm.polyData, CD_MPOLY, CD_ASSIGN, cddm->mpoly, cddm->dm.numPolyData);
2715                 CustomData_merge(&cddm->dm.faceData, &cddm->dm.polyData,
2716                         CD_MASK_ORIGINDEX, CD_DUPLICATE, cddm->dm.numTessFaceData);
2717
2718                 polyindex = CustomData_get_layer(&cddm->dm.faceData, CD_POLYINDEX);
2719
2720                 mf = cddm->mface;
2721                 mp = cddm->mpoly;
2722                 ml = cddm->mloop;
2723                 l = 0;
2724                 for (i=0; i<cddm->dm.numTessFaceData; i++, mf++, mp++) {
2725                         mp->flag = mf->flag;
2726                         mp->loopstart = l;
2727                         mp->mat_nr = mf->mat_nr;
2728                         mp->totloop = mf->v4 ? 4 : 3;
2729
2730                         ml->v = mf->v1;
2731                         ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v1, mf->v2));
2732                         ml++, l++;
2733
2734                         ml->v = mf->v2;
2735                         ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v2, mf->v3));
2736                         ml++, l++;
2737
2738                         ml->v = mf->v3;
2739                         ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v3, mf->v4?mf->v4:mf->v1));
2740                         ml++, l++;
2741
2742                         if (mf->v4) {
2743                                 ml->v = mf->v4;
2744                                 ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v4, mf->v1));
2745                                 ml++, l++;
2746                         }
2747
2748                         *polyindex = i;
2749                 }
2750         }
2751
2752         BLI_edgehash_free(eh, NULL);
2753 }
2754
2755 void CDDM_set_mvert(DerivedMesh *dm, MVert *mvert)
2756 {
2757         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2758         
2759         if (!CustomData_has_layer(&dm->vertData, CD_MVERT))
2760                 CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, mvert, dm->numVertData);
2761                                 
2762         cddm->mvert = mvert;
2763 }
2764
2765 void CDDM_set_medge(DerivedMesh *dm, MEdge *medge)
2766 {
2767         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2768
2769         if (!CustomData_has_layer(&dm->edgeData, CD_MEDGE))
2770                 CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, medge, dm->numEdgeData);
2771
2772         cddm->medge = medge;
2773 }
2774
2775 void CDDM_set_mface(DerivedMesh *dm, MFace *mface)
2776 {
2777         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2778
2779         if (!CustomData_has_layer(&dm->faceData, CD_MFACE))
2780                 CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, mface, dm->numTessFaceData);
2781
2782         cddm->mface = mface;
2783 }