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