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