merge with trunk at r27259 and commit of a patch by anthony jones to fix msvc (though...
[blender-staging.git] / source / blender / blenkernel / intern / cdderivedmesh.c
1  /*
2 * $Id$
3 *
4 * ***** BEGIN GPL LICENSE BLOCK *****
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software  Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 *
20 * The Original Code is Copyright (C) 2006 Blender Foundation.
21 * All rights reserved.
22 *
23 * The Original Code is: all of this file.
24 *
25 * Contributor(s): Ben Batt <benbatt@gmail.com>
26 *
27 * ***** END GPL LICENSE BLOCK *****
28 *
29 * Implementation of CDDerivedMesh.
30 *
31 * BKE_cdderivedmesh.h contains the function prototypes for this file.
32 *
33 */ 
34
35 /* TODO maybe BIF_gl.h should include string.h? */
36 #include <string.h>
37 #include "BIF_gl.h"
38
39 #include "BKE_cdderivedmesh.h"
40 #include "BKE_customdata.h"
41 #include "BKE_DerivedMesh.h"
42 #include "BKE_displist.h"
43 #include "BKE_global.h"
44 #include "BKE_mesh.h"
45 #include "BKE_multires.h"
46 #include "BKE_utildefines.h"
47 #include "BKE_tessmesh.h"
48
49 #include "BLI_editVert.h"
50 #include "BLI_scanfill.h"
51 #include "BLI_math.h"
52 #include "BLI_blenlib.h"
53 #include "BLI_edgehash.h"
54 #include "BLI_editVert.h"
55 #include "BLI_pbvh.h"
56
57 #include "DNA_mesh_types.h"
58 #include "DNA_meshdata_types.h"
59 #include "DNA_modifier_types.h"
60 #include "DNA_object_fluidsim.h"
61 #include "DNA_object_types.h"
62 #include "DNA_scene_types.h"
63
64 #include "MEM_guardedalloc.h"
65
66 #include "gpu_buffers.h"
67 #include "GPU_draw.h"
68 #include "GPU_extensions.h"
69 #include "GPU_material.h"
70
71 #include <string.h>
72 #include <limits.h>
73 #include <math.h>
74
75 typedef struct {
76         DerivedMesh dm;
77
78         /* these point to data in the DerivedMesh custom data layers,
79            they are only here for efficiency and convenience **/
80         MVert *mvert;
81         MEdge *medge;
82         MFace *mface;
83         MLoop *mloop;
84         MPoly *mpoly;
85
86         /* Cached */
87         struct PBVH *pbvh;
88         /* Mesh connectivity */
89         struct ListBase *fmap;
90         struct IndexNode *fmap_mem;
91 } CDDerivedMesh;
92
93 DMFaceIter *cdDM_newFaceIter(DerivedMesh *source);
94
95 /**************** DerivedMesh interface functions ****************/
96 static int cdDM_getNumVerts(DerivedMesh *dm)
97 {
98         return dm->numVertData;
99 }
100
101 static int cdDM_getNumEdges(DerivedMesh *dm)
102 {
103         return dm->numEdgeData;
104 }
105
106 static int cdDM_getNumTessFaces(DerivedMesh *dm)
107 {
108         return dm->numFaceData;
109 }
110
111 static int cdDM_getNumFaces(DerivedMesh *dm)
112 {
113         return dm->numPolyData;
114 }
115
116 static void cdDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
117 {
118         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
119         *vert_r = cddm->mvert[index];
120 }
121
122 static void cdDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
123 {
124         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
125         *edge_r = cddm->medge[index];
126 }
127
128 static void cdDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
129 {
130         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
131         *face_r = cddm->mface[index];
132 }
133
134 static void cdDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
135 {
136         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
137         memcpy(vert_r, cddm->mvert, sizeof(*vert_r) * dm->numVertData);
138 }
139
140 static void cdDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
141 {
142         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
143         memcpy(edge_r, cddm->medge, sizeof(*edge_r) * dm->numEdgeData);
144 }
145
146 static void cdDM_copyFaceArray(DerivedMesh *dm, MFace *face_r)
147 {
148         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
149         memcpy(face_r, cddm->mface, sizeof(*face_r) * dm->numFaceData);
150 }
151
152 static void cdDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
153 {
154         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
155         int i;
156
157         if (dm->numVertData) {
158                 for (i=0; i<dm->numVertData; i++) {
159                         DO_MINMAX(cddm->mvert[i].co, min_r, max_r);
160                 }
161         } else {
162                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
163         }
164 }
165
166 static void cdDM_getVertCo(DerivedMesh *dm, int index, float co_r[3])
167 {
168         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
169
170         VECCOPY(co_r, cddm->mvert[index].co);
171 }
172
173 static void cdDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
174 {
175         MVert *mv = CDDM_get_verts(dm);
176         int i;
177
178         for(i = 0; i < dm->numVertData; i++, mv++)
179                 VECCOPY(cos_r[i], mv->co);
180 }
181
182 static void cdDM_getVertNo(DerivedMesh *dm, int index, float no_r[3])
183 {
184         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
185         short *no = cddm->mvert[index].no;
186
187         no_r[0] = no[0]/32767.f;
188         no_r[1] = no[1]/32767.f;
189         no_r[2] = no[2]/32767.f;
190 }
191
192 static ListBase *cdDM_getFaceMap(Object *ob, DerivedMesh *dm)
193 {
194         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
195
196         if(!cddm->fmap && ob->type == OB_MESH) {
197                 Mesh *me= ob->data;
198
199                 create_vert_face_map(&cddm->fmap, &cddm->fmap_mem, me->mface,
200                                      me->totvert, me->totface);
201         }
202
203         return cddm->fmap;
204 }
205
206 static struct PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
207 {
208         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
209
210         if(!cddm->pbvh && ob->type == OB_MESH) {
211                 Mesh *me= ob->data;
212
213                 cddm->pbvh = BLI_pbvh_new();
214                 BLI_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert,
215                                me->totface, me->totvert);
216         }
217
218         return cddm->pbvh;
219 }
220
221 static void cdDM_drawVerts(DerivedMesh *dm)
222 {
223         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
224         MVert *mv = cddm->mvert;
225         int i;
226
227         if( GPU_buffer_legacy(dm) ) {
228                 glBegin(GL_POINTS);
229                 for(i = 0; i < dm->numVertData; i++, mv++)
230                         glVertex3fv(mv->co);
231                 glEnd();
232         }
233         else {  /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
234                 GPU_vertex_setup(dm);
235                 if( !GPU_buffer_legacy(dm) ) {
236                         glDrawArrays(GL_POINTS,0,dm->drawObject->nelements);
237                 }
238                 GPU_buffer_unbind();
239         }
240 }
241
242 static void cdDM_drawUVEdges(DerivedMesh *dm)
243 {
244         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
245         MFace *mf = cddm->mface;
246         MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
247         int i;
248
249         if(mf) {
250                 if( GPU_buffer_legacy(dm) ) {
251                         glBegin(GL_LINES);
252                         for(i = 0; i < dm->numFaceData; i++, mf++, tf++) {
253                                 if(!(mf->flag&ME_HIDE)) {
254                                         glVertex2fv(tf->uv[0]);
255                                         glVertex2fv(tf->uv[1]);
256
257                                         glVertex2fv(tf->uv[1]);
258                                         glVertex2fv(tf->uv[2]);
259
260                                         if(!mf->v4) {
261                                                 glVertex2fv(tf->uv[2]);
262                                                 glVertex2fv(tf->uv[0]);
263                                         } else {
264                                                 glVertex2fv(tf->uv[2]);
265                                                 glVertex2fv(tf->uv[3]);
266
267                                                 glVertex2fv(tf->uv[3]);
268                                                 glVertex2fv(tf->uv[0]);
269                                         }
270                                 }
271                         }
272                         glEnd();
273                 }
274                 else {
275                         int prevstart = 0;
276                         int prevdraw = 1;
277                         int draw = 1;
278                         int curpos = 0;
279
280                         GPU_uvedge_setup(dm);
281                         if( !GPU_buffer_legacy(dm) ) {
282                                 for(i = 0; i < dm->numFaceData; i++, mf++) {
283                                         if(mf->flag&ME_LOOSEEDGE) {
284                                                 draw = 1;
285                                         } 
286                                         else {
287                                                 draw = 0;
288                                         }
289                                         if( prevdraw != draw ) {
290                                                 if( prevdraw > 0 && (curpos-prevstart) > 0) {
291                                                         glDrawArrays(GL_LINES,prevstart,curpos-prevstart);
292                                                 }
293                                                 prevstart = curpos;
294                                         }
295                                         if( mf->v4 ) {
296                                                 curpos += 8;
297                                         }
298                                         else {
299                                                 curpos += 6;
300                                         }
301                                         prevdraw = draw;
302                                 }
303                                 if( prevdraw > 0 && (curpos-prevstart) > 0 ) {
304                                         glDrawArrays(GL_LINES,prevstart,curpos-prevstart);
305                                 }
306                         }
307                         GPU_buffer_unbind();
308                 }
309         }
310 }
311
312 static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
313 {
314         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
315         MVert *mvert = cddm->mvert;
316         MEdge *medge = cddm->medge;
317         int i;
318         
319         if( GPU_buffer_legacy(dm) ) {
320                 DEBUG_VBO( "Using legacy code. cdDM_drawEdges\n" );
321                 glBegin(GL_LINES);
322                 for(i = 0; i < dm->numEdgeData; i++, medge++) {
323                         if((medge->flag&ME_EDGEDRAW)
324                            && (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) {
325                                 glVertex3fv(mvert[medge->v1].co);
326                                 glVertex3fv(mvert[medge->v2].co);
327                         }
328                 }
329                 glEnd();
330         }
331         else {  /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
332                 int prevstart = 0;
333                 int prevdraw = 1;
334                 int draw = 1;
335
336                 GPU_edge_setup(dm);
337                 if( !GPU_buffer_legacy(dm) ) {
338                         for(i = 0; i < dm->numEdgeData; i++, medge++) {
339                                 if((medge->flag&ME_EDGEDRAW)
340                                    && (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) {
341                                         draw = 1;
342                                 } 
343                                 else {
344                                         draw = 0;
345                                 }
346                                 if( prevdraw != draw ) {
347                                         if( prevdraw > 0 && (i-prevstart) > 0 ) {
348                                                 GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2  );
349                                         }
350                                         prevstart = i;
351                                 }
352                                 prevdraw = draw;
353                         }
354                         if( prevdraw > 0 && (i-prevstart) > 0 ) {
355                                 GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2  );
356                         }
357                 }
358                 GPU_buffer_unbind();
359         }
360 }
361
362 static void cdDM_drawLooseEdges(DerivedMesh *dm)
363 {
364         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
365         MVert *mvert = cddm->mvert;
366         MEdge *medge = cddm->medge;
367         int i;
368
369         if( GPU_buffer_legacy(dm) ) {
370                 DEBUG_VBO( "Using legacy code. cdDM_drawLooseEdges\n" );
371                 glBegin(GL_LINES);
372                 for(i = 0; i < dm->numEdgeData; i++, medge++) {
373                         if(medge->flag&ME_LOOSEEDGE) {
374                                 glVertex3fv(mvert[medge->v1].co);
375                                 glVertex3fv(mvert[medge->v2].co);
376                         }
377                 }
378                 glEnd();
379         }
380         else {  /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
381                 int prevstart = 0;
382                 int prevdraw = 1;
383                 int draw = 1;
384
385                 GPU_edge_setup(dm);
386                 if( !GPU_buffer_legacy(dm) ) {
387                         for(i = 0; i < dm->numEdgeData; i++, medge++) {
388                                 if(medge->flag&ME_LOOSEEDGE) {
389                                         draw = 1;
390                                 } 
391                                 else {
392                                         draw = 0;
393                                 }
394                                 if( prevdraw != draw ) {
395                                         if( prevdraw > 0 && (i-prevstart) > 0) {
396                                                 GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2  );
397                                         }
398                                         prevstart = i;
399                                 }
400                                 prevdraw = draw;
401                         }
402                         if( prevdraw > 0 && (i-prevstart) > 0 ) {
403                                 GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2  );
404                         }
405                 }
406                 GPU_buffer_unbind();
407         }
408 }
409
410 static void cdDM_drawFacesSolid(DerivedMesh *dm,
411                                 float (*partial_redraw_planes)[4],
412                                 int fast, int (*setMaterial)(int, void *attribs))
413 {
414         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
415         MVert *mvert = cddm->mvert;
416         MFace *mface = cddm->mface;
417         float *nors= dm->getTessFaceDataArray(dm, CD_NORMAL);
418         int a, glmode = -1, shademodel = -1, matnr = -1, drawCurrentMat = 1;
419
420 #define PASSVERT(index) {                                               \
421         if(shademodel == GL_SMOOTH) {                           \
422                 short *no = mvert[index].no;                    \
423                 glNormal3sv(no);                                                \
424         }                                                                                       \
425         glVertex3fv(mvert[index].co);   \
426 }
427
428         if(cddm->pbvh) {
429                 if(dm->numFaceData) {
430                         float (*face_nors)[3] = CustomData_get_layer(&dm->faceData, CD_NORMAL);
431
432                         /* should be per face */
433                         if(!setMaterial(mface->mat_nr+1, NULL))
434                                 return;
435
436                         glShadeModel((mface->flag & ME_SMOOTH)? GL_SMOOTH: GL_FLAT);
437                         BLI_pbvh_draw(cddm->pbvh, partial_redraw_planes, face_nors);
438                         glShadeModel(GL_FLAT);
439                 }
440
441                 return;
442         }
443
444         if( GPU_buffer_legacy(dm) ) {
445                 DEBUG_VBO( "Using legacy code. cdDM_drawFacesSolid\n" );
446                 glBegin(glmode = GL_QUADS);
447                 for(a = 0; a < dm->numFaceData; a++, mface++) {
448                         int new_glmode, new_matnr, new_shademodel;
449
450                         new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES;
451                         new_matnr = mface->mat_nr + 1;
452                         new_shademodel = (mface->flag & ME_SMOOTH)?GL_SMOOTH:GL_FLAT;
453                         
454                         if(new_glmode != glmode || new_matnr != matnr
455                            || new_shademodel != shademodel) {
456                                 glEnd();
457
458                                 drawCurrentMat = setMaterial(matnr = new_matnr, NULL);
459
460                                 glShadeModel(shademodel = new_shademodel);
461                                 glBegin(glmode = new_glmode);
462                         } 
463                         
464                         if(drawCurrentMat) {
465                                 if(shademodel == GL_FLAT) {
466                                         if (nors) {
467                                                 glNormal3fv(nors);
468                                         }
469                                         else {
470                                                 /* TODO make this better (cache facenormals as layer?) */
471                                                 float nor[3];
472                                                 if(mface->v4) {
473                                                         normal_quad_v3( nor,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co);
474                                                 } else {
475                                                         normal_tri_v3( nor,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co);
476                                                 }
477                                                 glNormal3fv(nor);
478                                         }
479                                 }
480
481                                 PASSVERT(mface->v1);
482                                 PASSVERT(mface->v2);
483                                 PASSVERT(mface->v3);
484                                 if(mface->v4) {
485                                         PASSVERT(mface->v4);
486                                 }
487                         }
488
489                         if(nors) nors += 3;
490                 }
491                 glEnd();
492         }
493         else {  /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
494                 GPU_vertex_setup( dm );
495                 GPU_normal_setup( dm );
496                 if( !GPU_buffer_legacy(dm) ) {
497                         glShadeModel(GL_SMOOTH);
498                         for( a = 0; a < dm->drawObject->nmaterials; a++ ) {
499                                 if( setMaterial(dm->drawObject->materials[a].mat_nr+1, NULL) )
500                                         glDrawArrays(GL_TRIANGLES, dm->drawObject->materials[a].start, dm->drawObject->materials[a].end-dm->drawObject->materials[a].start);
501                         }
502                 }
503                 GPU_buffer_unbind( );
504         }
505
506 #undef PASSVERT
507         glShadeModel(GL_FLAT);
508 }
509
510 static void cdDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *col1, unsigned char *col2)
511 {
512         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
513         int a, glmode;
514         unsigned char *cp1, *cp2;
515         MVert *mvert = cddm->mvert;
516         MFace *mface = cddm->mface;
517
518         cp1 = col1;
519         if(col2) {
520                 cp2 = col2;
521         } else {
522                 cp2 = NULL;
523                 useTwoSided = 0;
524         }
525
526         /* there's a conflict here... twosided colors versus culling...? */
527         /* defined by history, only texture faces have culling option */
528         /* we need that as mesh option builtin, next to double sided lighting */
529         if(col1 && col2)
530                 glEnable(GL_CULL_FACE);
531
532         if( GPU_buffer_legacy(dm) ) {
533                 DEBUG_VBO( "Using legacy code. cdDM_drawFacesColored\n" );
534                 glShadeModel(GL_SMOOTH);
535                 glBegin(glmode = GL_QUADS);
536                 for(a = 0; a < dm->numFaceData; a++, mface++, cp1 += 16) {
537                         int new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES;
538
539                         if(new_glmode != glmode) {
540                                 glEnd();
541                                 glBegin(glmode = new_glmode);
542                         }
543                                 
544                         glColor3ub(cp1[0], cp1[1], cp1[2]);
545                         glVertex3fv(mvert[mface->v1].co);
546                         glColor3ub(cp1[4], cp1[5], cp1[6]);
547                         glVertex3fv(mvert[mface->v2].co);
548                         glColor3ub(cp1[8], cp1[9], cp1[10]);
549                         glVertex3fv(mvert[mface->v3].co);
550                         if(mface->v4) {
551                                 glColor3ub(cp1[12], cp1[13], cp1[14]);
552                                 glVertex3fv(mvert[mface->v4].co);
553                         }
554                                 
555                         if(useTwoSided) {
556                                 glColor3ub(cp2[8], cp2[9], cp2[10]);
557                                 glVertex3fv(mvert[mface->v3].co );
558                                 glColor3ub(cp2[4], cp2[5], cp2[6]);
559                                 glVertex3fv(mvert[mface->v2].co );
560                                 glColor3ub(cp2[0], cp2[1], cp2[2]);
561                                 glVertex3fv(mvert[mface->v1].co );
562                                 if(mface->v4) {
563                                         glColor3ub(cp2[12], cp2[13], cp2[14]);
564                                         glVertex3fv(mvert[mface->v4].co );
565                                 }
566                         }
567                         if(col2) cp2 += 16;
568                 }
569                 glEnd();
570         }
571         else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
572                 GPU_color4_upload(dm,cp1);
573                 GPU_vertex_setup(dm);
574                 GPU_color_setup(dm);
575                 if( !GPU_buffer_legacy(dm) ) {
576                         glShadeModel(GL_SMOOTH);
577                         glDrawArrays(GL_TRIANGLES, 0, dm->drawObject->nelements);
578
579                         if( useTwoSided ) {
580                                 GPU_color4_upload(dm,cp2);
581                                 GPU_color_setup(dm);
582                                 glCullFace(GL_FRONT);
583                                 glDrawArrays(GL_TRIANGLES, 0, dm->drawObject->nelements);
584                                 glCullFace(GL_BACK);
585                         }
586                 }
587                 GPU_buffer_unbind();
588         }
589
590         glShadeModel(GL_FLAT);
591         glDisable(GL_CULL_FACE);
592 }
593
594 static void cdDM_drawFacesTex_common(DerivedMesh *dm,
595                int (*drawParams)(MTFace *tface, int has_vcol, int matnr),
596                int (*drawParamsMapped)(void *userData, int index),
597                void *userData) 
598 {
599         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
600         MVert *mv = cddm->mvert;
601         MFace *mf = DM_get_tessface_data_layer(dm, CD_MFACE);
602         MCol *realcol = dm->getTessFaceDataArray(dm, CD_TEXTURE_MCOL);
603         float *nors= dm->getTessFaceDataArray(dm, CD_NORMAL);
604         MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
605         int i, j, orig, *index = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
606         int startFace = 0, lastFlag = 0xdeadbeef;
607         MCol *mcol = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL);
608         if(!mcol)
609                 mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
610
611         if( GPU_buffer_legacy(dm) ) {
612                 DEBUG_VBO( "Using legacy code. cdDM_drawFacesTex_common\n" );
613                 for(i = 0; i < dm->numFaceData; i++, mf++) {
614                         MVert *mvert;
615                         int flag;
616                         unsigned char *cp = NULL;
617
618                         if(drawParams) {
619                                 flag = drawParams(tf? &tf[i]: NULL, mcol!=NULL, mf->mat_nr);
620                         }
621                         else {
622                                 if(index) {
623                                         orig = *index++;
624                                         if(orig == ORIGINDEX_NONE)              { if(nors) nors += 3; continue; }
625                                         if(drawParamsMapped) flag = drawParamsMapped(userData, orig);
626                                         else    { if(nors) nors += 3; continue; }
627                                 }
628                                 else
629                                         if(drawParamsMapped) flag = drawParamsMapped(userData, i);
630                                         else    { if(nors) nors += 3; continue; }
631                         }
632                         
633                         if(flag != 0) {
634                                 if (flag==1 && mcol)
635                                         cp= (unsigned char*) &mcol[i*4];
636
637                                 if(!(mf->flag&ME_SMOOTH)) {
638                                         if (nors) {
639                                                 glNormal3fv(nors);
640                                         }
641                                         else {
642                                                 float nor[3];
643                                                 if(mf->v4) {
644                                                         normal_quad_v3( nor,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
645                                                 } else {
646                                                         normal_tri_v3( nor,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
647                                                 }
648                                                 glNormal3fv(nor);
649                                         }
650                                 }
651
652                                 glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
653                                 if(tf) glTexCoord2fv(tf[i].uv[0]);
654                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
655                                 mvert = &mv[mf->v1];
656                                 if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
657                                 glVertex3fv(mvert->co);
658                                         
659                                 if(tf) glTexCoord2fv(tf[i].uv[1]);
660                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
661                                 mvert = &mv[mf->v2];
662                                 if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
663                                 glVertex3fv(mvert->co);
664
665                                 if(tf) glTexCoord2fv(tf[i].uv[2]);
666                                 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
667                                 mvert = &mv[mf->v3];
668                                 if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
669                                 glVertex3fv(mvert->co);
670
671                                 if(mf->v4) {
672                                         if(tf) glTexCoord2fv(tf[i].uv[3]);
673                                         if(cp) glColor3ub(cp[15], cp[14], cp[13]);
674                                         mvert = &mv[mf->v4];
675                                         if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
676                                         glVertex3fv(mvert->co);
677                                 }
678                                 glEnd();
679                         }
680                         
681                         if(nors) nors += 3;
682                 }
683         } else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
684                 MCol *col = realcol;
685                 if(!col)
686                         col = mcol;
687
688                 GPU_vertex_setup( dm );
689                 GPU_normal_setup( dm );
690                 GPU_uv_setup( dm );
691                 if( col != 0 ) {
692                         /*if( realcol && dm->drawObject->colType == CD_TEXTURE_MCOL )  {
693                                 col = 0;
694                         } else if( mcol && dm->drawObject->colType == CD_MCOL ) {
695                                 col = 0;
696                         }
697                         
698                         if( col != 0 ) {*/
699                                 unsigned char *colors = MEM_mallocN(dm->getNumTessFaces(dm)*4*3*sizeof(unsigned char), "cdDM_drawFacesTex_common");
700                                 for( i=0; i < dm->getNumTessFaces(dm); i++ ) {
701                                         for( j=0; j < 4; j++ ) {
702                                                 colors[i*12+j*3] = col[i*4+j].r;
703                                                 colors[i*12+j*3+1] = col[i*4+j].g;
704                                                 colors[i*12+j*3+2] = col[i*4+j].b;
705                                         }
706                                 }
707                                 GPU_color3_upload(dm,colors);
708                                 MEM_freeN(colors);
709                                 if(realcol)
710                                         dm->drawObject->colType = CD_TEXTURE_MCOL;
711                                 else if(mcol)
712                                         dm->drawObject->colType = CD_MCOL;
713                         //}
714                         GPU_color_setup( dm );
715                 }
716
717                 if( !GPU_buffer_legacy(dm) ) {
718                         glShadeModel( GL_SMOOTH );
719                         for(i = 0; i < dm->drawObject->nelements/3; i++) {
720                                 int actualFace = dm->drawObject->faceRemap[i];
721                                 int flag = 1;
722
723                                 if(drawParams) {
724                                         flag = drawParams(tf? &tf[actualFace]: NULL, mcol!=NULL, mf[actualFace].mat_nr);
725                                 }
726                                 else {
727                                         if(index) {
728                                                 orig = index[actualFace];
729                                                 if(drawParamsMapped)
730                                                         flag = drawParamsMapped(userData, orig);
731                                         }
732                                         else
733                                                 if(drawParamsMapped)
734                                                         flag = drawParamsMapped(userData, actualFace);
735                                 }
736                                 if( flag != lastFlag ) {
737                                         if( startFace < i ) {
738                                                 if( lastFlag != 0 ) { /* if the flag is 0 it means the face is hidden or invisible */
739                                                         if (lastFlag==1 && mcol)
740                                                                 GPU_color_switch(1);
741                                                         else
742                                                                 GPU_color_switch(0);
743                                                         glDrawArrays(GL_TRIANGLES,startFace*3,(i-startFace)*3);
744                                                 }
745                                         }
746                                         lastFlag = flag;
747                                         startFace = i;
748                                 }
749                         }
750                         if( startFace < dm->drawObject->nelements/3 ) {
751                                 if( lastFlag != 0 ) { /* if the flag is 0 it means the face is hidden or invisible */
752                                         if (lastFlag==1 && mcol)
753                                                 GPU_color_switch(1);
754                                         else
755                                                 GPU_color_switch(0);
756                                         glDrawArrays(GL_TRIANGLES,startFace*3,dm->drawObject->nelements-startFace*3);
757                                 }
758                         }
759                 }
760
761                 GPU_buffer_unbind();
762                 glShadeModel( GL_FLAT );
763         }
764 }
765
766 static void cdDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, int has_vcol, int matnr))
767 {
768         cdDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
769 }
770
771 static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors)
772 {
773         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
774         MVert *mv = cddm->mvert;
775         MFace *mf = cddm->mface;
776         MCol *mc;
777         float *nors= dm->getTessFaceDataArray(dm, CD_NORMAL);
778         int i, orig, *index = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
779
780         mc = DM_get_tessface_data_layer(dm, CD_ID_MCOL);
781         if(!mc)
782                 mc = DM_get_tessface_data_layer(dm, CD_WEIGHT_MCOL);
783         if(!mc)
784                 mc = DM_get_tessface_data_layer(dm, CD_MCOL);
785
786         /* back-buffer always uses legacy since VBO's would need the
787          * color array temporarily overwritten for drawing, then reset. */
788         if( GPU_buffer_legacy(dm) || G.f & G_BACKBUFSEL) {
789                 DEBUG_VBO( "Using legacy code. cdDM_drawMappedFaces\n" );
790                 for(i = 0; i < dm->numFaceData; i++, mf++) {
791                         int drawSmooth = (mf->flag & ME_SMOOTH);
792
793                         if(index) {
794                                 orig = *index++;
795                                 if(setDrawOptions && orig == ORIGINDEX_NONE)
796                                         { if(nors) nors += 3; continue; }
797                         }
798                         else
799                                 orig = i;
800
801                         if(!setDrawOptions || setDrawOptions(userData, orig, &drawSmooth)) {
802                                 unsigned char *cp = NULL;
803
804                                 if(useColors && mc)
805                                         cp = (unsigned char *)&mc[i * 4];
806
807                                 glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
808                                 glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
809
810                                 if (!drawSmooth) {
811                                         if (nors) {
812                                                 glNormal3fv(nors);
813                                         }
814                                         else {
815                                                 float nor[3];
816                                                 if(mf->v4) {
817                                                         normal_quad_v3( nor,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
818                                                 } else {
819                                                         normal_tri_v3( nor,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
820                                                 }
821                                                 glNormal3fv(nor);
822                                         }
823
824                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
825                                         glVertex3fv(mv[mf->v1].co);
826                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
827                                         glVertex3fv(mv[mf->v2].co);
828                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
829                                         glVertex3fv(mv[mf->v3].co);
830                                         if(mf->v4) {
831                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
832                                                 glVertex3fv(mv[mf->v4].co);
833                                         }
834                                 } else {
835                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
836                                         glNormal3sv(mv[mf->v1].no);
837                                         glVertex3fv(mv[mf->v1].co);
838                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
839                                         glNormal3sv(mv[mf->v2].no);
840                                         glVertex3fv(mv[mf->v2].co);
841                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
842                                         glNormal3sv(mv[mf->v3].no);
843                                         glVertex3fv(mv[mf->v3].co);
844                                         if(mf->v4) {
845                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
846                                                 glNormal3sv(mv[mf->v4].no);
847                                                 glVertex3fv(mv[mf->v4].co);
848                                         }
849                                 }
850
851                                 glEnd();
852                         }
853                         
854                         if (nors) nors += 3;
855                 }
856         }
857         else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
858                 int state = 1;
859                 int prevstate = 1;
860                 int prevstart = 0;
861                 GPU_vertex_setup(dm);
862                 GPU_normal_setup(dm);
863                 if( useColors && mc )
864                         GPU_color_setup(dm);
865                 if( !GPU_buffer_legacy(dm) ) {
866                         glShadeModel(GL_SMOOTH);
867                         for( i = 0; i < dm->drawObject->nelements/3; i++ ) {
868                                 int actualFace = dm->drawObject->faceRemap[i];
869                                 int drawSmooth = (mf[actualFace].flag & ME_SMOOTH);
870                                 int dontdraw = 0;
871                                 if(index) {
872                                         orig = index[actualFace];
873                                         if(setDrawOptions && orig == ORIGINDEX_NONE)
874                                                 dontdraw = 1;
875                                 }
876                                 else
877                                         orig = actualFace;
878                                 if( dontdraw ) {
879                                         state = 0;
880                                 }
881                                 else {
882                                         if(!setDrawOptions || setDrawOptions(userData, orig, &drawSmooth)) {
883                                                 state = 1;
884                                         }
885                                         else {
886                                                 state = 0;
887                                         }
888                                 }
889                                 if( prevstate != state && prevstate == 1 ) {
890                                         if( i-prevstart > 0 ) {
891                                                 glDrawArrays(GL_TRIANGLES,prevstart*3,(i-prevstart)*3);
892                                         }
893                                         prevstart = i;
894                                 }
895                                 prevstate = state;
896                         }
897                         if(state==1) {
898                                 glDrawArrays(GL_TRIANGLES,prevstart*3,dm->drawObject->nelements-prevstart*3);
899                         }
900                         glShadeModel(GL_FLAT);
901                 }
902                 GPU_buffer_unbind();
903         }
904 }
905
906 static void cdDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
907 {
908         cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
909 }
910
911 static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs), int (*setDrawOptions)(void *userData, int index), void *userData)
912 {
913         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
914         GPUVertexAttribs gattribs;
915         DMVertexAttribs attribs;
916         MVert *mvert = cddm->mvert;
917         MFace *mface = cddm->mface;
918         MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE);
919         float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL);
920         int a, b, dodraw, smoothnormal, matnr, new_matnr;
921         int transp, new_transp, orig_transp;
922         int orig, *index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
923
924         matnr = -1;
925         smoothnormal = 0;
926         dodraw = 0;
927         transp = GPU_get_material_blend_mode();
928         orig_transp = transp;
929
930         glShadeModel(GL_SMOOTH);
931
932         if( GPU_buffer_legacy(dm) || setDrawOptions != 0 ) {
933                 DEBUG_VBO( "Using legacy code. cdDM_drawMappedFacesGLSL\n" );
934                 memset(&attribs, 0, sizeof(attribs));
935
936                 glBegin(GL_QUADS);
937
938                 for(a = 0; a < dm->numFaceData; a++, mface++) {
939                         new_matnr = mface->mat_nr + 1;
940
941                         if(new_matnr != matnr) {
942                                 glEnd();
943
944                                 dodraw = setMaterial(matnr = new_matnr, &gattribs);
945                                 if(dodraw)
946                                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
947
948                                 glBegin(GL_QUADS);
949                         }
950
951                         if(!dodraw) {
952                                 continue;
953                         }
954                         else if(setDrawOptions) {
955                                 orig = (index)? index[a]: a;
956
957                                 if(orig == ORIGINDEX_NONE)
958                                         continue;
959                                 else if(!setDrawOptions(userData, orig))
960                                         continue;
961                         }
962
963                         if(tf) {
964                                 new_transp = tf[a].transp;
965
966                                 if(new_transp != transp) {
967                                         glEnd();
968
969                                         if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
970                                                 GPU_set_material_blend_mode(orig_transp);
971                                         else
972                                                 GPU_set_material_blend_mode(new_transp);
973                                         transp = new_transp;
974
975                                         glBegin(GL_QUADS);
976                                 }
977                         }
978
979                         smoothnormal = (mface->flag & ME_SMOOTH);
980
981                         if(!smoothnormal) {
982                                 if(nors) {
983                                         glNormal3fv(nors[a]);
984                                 }
985                                 else {
986                                         /* TODO ideally a normal layer should always be available */
987                                         float nor[3];
988                                         if(mface->v4) {
989                                                 normal_quad_v3( nor,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co);
990                                         } else {
991                                                 normal_tri_v3( nor,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co);
992                                         }
993                                         glNormal3fv(nor);
994                                 }
995                         }
996
997 #define PASSVERT(index, vert) {                                                                                                 \
998                 if(attribs.totorco)                                                                                                                     \
999                         glVertexAttrib3fvARB(attribs.orco.glIndex, attribs.orco.array[index]);  \
1000                 for(b = 0; b < attribs.tottface; b++) {                                                                         \
1001                         MTFace *tf = &attribs.tface[b].array[a];                                                                \
1002                         glVertexAttrib2fvARB(attribs.tface[b].glIndex, tf->uv[vert]);                   \
1003                 }                                                                                                                                                       \
1004                 for(b = 0; b < attribs.totmcol; b++) {                                                                          \
1005                         MCol *cp = &attribs.mcol[b].array[a*4 + vert];                                                  \
1006                         GLubyte col[4];                                                                                                                 \
1007                         col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;                             \
1008                         glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col);                                    \
1009                 }                                                                                                                                                       \
1010                 if(attribs.tottang) {                                                                                                           \
1011                         float *tang = attribs.tang.array[a*4 + vert];                                                   \
1012                         glVertexAttrib3fvARB(attribs.tang.glIndex, tang);                                               \
1013                 }                                                                                                                                                       \
1014                 if(smoothnormal)                                                                                                                        \
1015                         glNormal3sv(mvert[index].no);                                                                                   \
1016                 glVertex3fv(mvert[index].co);                                                                                           \
1017         }
1018
1019                         PASSVERT(mface->v1, 0);
1020                         PASSVERT(mface->v2, 1);
1021                         PASSVERT(mface->v3, 2);
1022                         if(mface->v4)
1023                                 PASSVERT(mface->v4, 3)
1024                         else
1025                                 PASSVERT(mface->v3, 2)
1026
1027 #undef PASSVERT
1028                 }
1029                 glEnd();
1030         }
1031         else {
1032                 GPUBuffer *buffer = 0;
1033                 char *varray = 0;
1034                 int numdata = 0, elementsize = 0, offset;
1035                 int start = 0, numfaces = 0, prevdraw = 0, curface = 0;
1036                 int i;
1037
1038                 MFace *mf = mface;
1039                 GPUAttrib datatypes[GPU_MAX_ATTRIB]; /* TODO, messing up when switching materials many times - [#21056]*/
1040                 memset(&attribs, 0, sizeof(attribs));
1041
1042                 GPU_vertex_setup(dm);
1043                 GPU_normal_setup(dm);
1044
1045                 if( !GPU_buffer_legacy(dm) ) {
1046                         for( i = 0; i < dm->drawObject->nelements/3; i++ ) {
1047
1048                                 a = dm->drawObject->faceRemap[i];
1049
1050                                 mface = mf + a;
1051                                 new_matnr = mface->mat_nr + 1;
1052
1053                                 if(new_matnr != matnr ) {
1054                                         numfaces = curface - start;
1055                                         if( numfaces > 0 ) {
1056
1057                                                 if( dodraw ) {
1058
1059                                                         if( numdata != 0 ) {
1060
1061                                                                 GPU_buffer_unlock(buffer);
1062
1063                                                                 GPU_interleaved_attrib_setup(buffer,datatypes,numdata);
1064                                                         }
1065
1066                                                         glDrawArrays(GL_TRIANGLES,start*3,numfaces*3);
1067
1068                                                         if( numdata != 0 ) {
1069
1070                                                                 GPU_buffer_free(buffer,0);
1071
1072                                                                 buffer = 0;
1073                                                         }
1074
1075                                                 }
1076                                         }
1077                                         numdata = 0;
1078                                         start = curface;
1079                                         prevdraw = dodraw;
1080                                         dodraw = setMaterial(matnr = new_matnr, &gattribs);
1081                                         if(dodraw) {
1082                                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1083
1084                                                 if(attribs.totorco) {
1085                                                         datatypes[numdata].index = attribs.orco.glIndex;
1086                                                         datatypes[numdata].size = 3;
1087                                                         datatypes[numdata].type = GL_FLOAT;
1088                                                         numdata++;
1089                                                 }
1090                                                 for(b = 0; b < attribs.tottface; b++) {
1091                                                         datatypes[numdata].index = attribs.tface[b].glIndex;
1092                                                         datatypes[numdata].size = 2;
1093                                                         datatypes[numdata].type = GL_FLOAT;
1094                                                         numdata++;
1095                                                 }       
1096                                                 for(b = 0; b < attribs.totmcol; b++) {
1097                                                         datatypes[numdata].index = attribs.mcol[b].glIndex;
1098                                                         datatypes[numdata].size = 4;
1099                                                         datatypes[numdata].type = GL_UNSIGNED_BYTE;
1100                                                         numdata++;
1101                                                 }       
1102                                                 if(attribs.tottang) {
1103                                                         datatypes[numdata].index = attribs.tang.glIndex;
1104                                                         datatypes[numdata].size = 3;
1105                                                         datatypes[numdata].type = GL_FLOAT;
1106                                                         numdata++;
1107                                                 }
1108                                                 if( numdata != 0 ) {
1109                                                         elementsize = GPU_attrib_element_size( datatypes, numdata );
1110                                                         buffer = GPU_buffer_alloc( elementsize*dm->drawObject->nelements, 0 );
1111                                                         if( buffer == 0 ) {
1112                                                                 GPU_buffer_unbind();
1113                                                                 dm->drawObject->legacy = 1;
1114                                                                 return;
1115                                                         }
1116                                                         varray = GPU_buffer_lock_stream(buffer);
1117                                                         if( varray == 0 ) {
1118                                                                 GPU_buffer_unbind();
1119                                                                 GPU_buffer_free(buffer, 0);
1120                                                                 dm->drawObject->legacy = 1;
1121                                                                 return;
1122                                                         }
1123                                                 }
1124                                                 else {
1125                                                         /* if the buffer was set, dont use it again.
1126                                                          * prevdraw was assumed true but didnt run so set to false - [#21036] */
1127                                                         prevdraw= 0;
1128                                                         buffer= NULL;
1129                                                 }
1130                                         }
1131                                 }
1132                                 if(!dodraw) {
1133                                         continue;
1134                                 }
1135
1136                                 if(tf) {
1137                                         new_transp = tf[a].transp;
1138
1139                                         if(new_transp != transp) {
1140                                                 numfaces = curface - start;
1141                                                 if( numfaces > 0 ) {
1142                                                         if( dodraw ) {
1143                                                                 if( numdata != 0 ) {
1144                                                                         GPU_buffer_unlock(buffer);
1145                                                                         GPU_interleaved_attrib_setup(buffer,datatypes,numdata);
1146                                                                 }
1147                                                                 glDrawArrays(GL_TRIANGLES,start*3,(curface-start)*3);
1148                                                                 if( numdata != 0 ) {
1149                                                                         varray = GPU_buffer_lock_stream(buffer);
1150                                                                 }
1151                                                         }
1152                                                 }
1153                                                 start = curface;
1154
1155                                                 if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
1156                                                         GPU_set_material_blend_mode(orig_transp);
1157                                                 else
1158                                                         GPU_set_material_blend_mode(new_transp);
1159                                                 transp = new_transp;
1160                                         }
1161                                 }
1162                                 
1163                                 if( numdata != 0 ) {
1164                                         offset = 0;
1165                                         if(attribs.totorco) {
1166                                                 VECCOPY((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v1]);
1167                                                 VECCOPY((float *)&varray[elementsize*curface*3+elementsize],(float *)attribs.orco.array[mface->v2]);
1168                                                 VECCOPY((float *)&varray[elementsize*curface*3+elementsize*2],(float *)attribs.orco.array[mface->v3]);
1169                                                 offset += sizeof(float)*3;
1170                                         }
1171                                         for(b = 0; b < attribs.tottface; b++) {
1172                                                 MTFace *tf = &attribs.tface[b].array[a];
1173                                                 VECCOPY2D((float *)&varray[elementsize*curface*3+offset],tf->uv[0]);
1174                                                 VECCOPY2D((float *)&varray[elementsize*curface*3+offset+elementsize],tf->uv[1]);
1175
1176                                                 VECCOPY2D((float *)&varray[elementsize*curface*3+offset+elementsize*2],tf->uv[2]);
1177                                                 offset += sizeof(float)*2;
1178                                         }
1179                                         for(b = 0; b < attribs.totmcol; b++) {
1180                                                 MCol *cp = &attribs.mcol[b].array[a*4 + 0];
1181                                                 GLubyte col[4];
1182                                                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1183                                                 QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset], col);
1184                                                 cp = &attribs.mcol[b].array[a*4 + 1];
1185                                                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1186                                                 QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset+elementsize], col);
1187                                                 cp = &attribs.mcol[b].array[a*4 + 2];
1188                                                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1189                                                 QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset+elementsize*2], col);
1190                                                 offset += sizeof(unsigned char)*4;
1191                                         }       
1192                                         if(attribs.tottang) {
1193                                                 float *tang = attribs.tang.array[a*4 + 0];
1194                                                 VECCOPY((float *)&varray[elementsize*curface*3+offset], tang);
1195                                                 tang = attribs.tang.array[a*4 + 1];
1196                                                 VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize], tang);
1197                                                 tang = attribs.tang.array[a*4 + 2];
1198                                                 VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize*2], tang);
1199                                                 offset += sizeof(float)*3;
1200                                         }
1201                                 }
1202                                 curface++;
1203                                 if(mface->v4) {
1204                                         if( numdata != 0 ) {
1205                                                 offset = 0;
1206                                                 if(attribs.totorco) {
1207                                                         VECCOPY((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v3]);
1208                                                         VECCOPY((float *)&varray[elementsize*curface*3+elementsize],(float *)attribs.orco.array[mface->v4]);
1209                                                         VECCOPY((float *)&varray[elementsize*curface*3+elementsize*2],(float *)attribs.orco.array[mface->v1]);
1210                                                         offset += sizeof(float)*3;
1211                                                 }
1212                                                 for(b = 0; b < attribs.tottface; b++) {
1213                                                         MTFace *tf = &attribs.tface[b].array[a];
1214                                                         VECCOPY2D((float *)&varray[elementsize*curface*3+offset],tf->uv[2]);
1215                                                         VECCOPY2D((float *)&varray[elementsize*curface*3+offset+elementsize],tf->uv[3]);
1216                                                         VECCOPY2D((float *)&varray[elementsize*curface*3+offset+elementsize*2],tf->uv[0]);
1217                                                         offset += sizeof(float)*2;
1218                                                 }
1219                                                 for(b = 0; b < attribs.totmcol; b++) {
1220                                                         MCol *cp = &attribs.mcol[b].array[a*4 + 2];
1221                                                         GLubyte col[4];
1222                                                         col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1223                                                         QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset], col);
1224                                                         cp = &attribs.mcol[b].array[a*4 + 3];
1225                                                         col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1226                                                         QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset+elementsize], col);
1227                                                         cp = &attribs.mcol[b].array[a*4 + 0];
1228                                                         col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1229                                                         QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset+elementsize*2], col);
1230                                                         offset += sizeof(unsigned char)*4;
1231                                                 }       
1232                                                 if(attribs.tottang) {
1233                                                         float *tang = attribs.tang.array[a*4 + 2];
1234                                                         VECCOPY((float *)&varray[elementsize*curface*3+offset], tang);
1235                                                         tang = attribs.tang.array[a*4 + 3];
1236                                                         VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize], tang);
1237                                                         tang = attribs.tang.array[a*4 + 0];
1238                                                         VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize*2], tang);
1239                                                         offset += sizeof(float)*3;
1240                                                 }
1241                                         }
1242                                         curface++;
1243                                         i++;
1244                                 }
1245                         }
1246                         numfaces = curface - start;
1247                         if( numfaces > 0 ) {
1248                                 if( dodraw ) {
1249                                         if( numdata != 0 ) {
1250                                                 GPU_buffer_unlock(buffer);
1251                                                 GPU_interleaved_attrib_setup(buffer,datatypes,numdata);
1252                                         }
1253                                         glDrawArrays(GL_TRIANGLES,start*3,(curface-start)*3);
1254                                 }
1255                         }
1256                         GPU_buffer_unbind();
1257                 }
1258                 GPU_buffer_free( buffer, 0 );
1259         }
1260
1261         glShadeModel(GL_FLAT);
1262 }
1263
1264 static void cdDM_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs))
1265 {
1266         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1267 }
1268
1269 static void cdDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
1270 {
1271         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
1272         MVert *vert = cddm->mvert;
1273         MEdge *edge = cddm->medge;
1274         int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1275
1276         glBegin(GL_LINES);
1277         for(i = 0; i < dm->numEdgeData; i++, edge++) {
1278                 if(index) {
1279                         orig = *index++;
1280                         if(setDrawOptions && orig == ORIGINDEX_NONE) continue;
1281                 }
1282                 else
1283                         orig = i;
1284
1285                 if(!setDrawOptions || setDrawOptions(userData, orig)) {
1286                         glVertex3fv(vert[edge->v1].co);
1287                         glVertex3fv(vert[edge->v2].co);
1288                 }
1289         }
1290         glEnd();
1291 }
1292
1293 static void cdDM_foreachMappedVert(
1294                            DerivedMesh *dm,
1295                            void (*func)(void *userData, int index, float *co,
1296                                         float *no_f, short *no_s),
1297                            void *userData)
1298 {
1299         MVert *mv = CDDM_get_verts(dm);
1300         int i, orig, *index = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
1301
1302         for(i = 0; i < dm->numVertData; i++, mv++) {
1303                 if(index) {
1304                         orig = *index++;
1305                         if(orig == ORIGINDEX_NONE) continue;
1306                         func(userData, orig, mv->co, NULL, mv->no);
1307                 }
1308                 else
1309                         func(userData, i, mv->co, NULL, mv->no);
1310         }
1311 }
1312
1313 static void cdDM_foreachMappedEdge(
1314                            DerivedMesh *dm,
1315                            void (*func)(void *userData, int index,
1316                                         float *v0co, float *v1co),
1317                            void *userData)
1318 {
1319         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
1320         MVert *mv = cddm->mvert;
1321         MEdge *med = cddm->medge;
1322         int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1323
1324         for(i = 0; i < dm->numEdgeData; i++, med++) {
1325                 if (index) {
1326                         orig = *index++;
1327                         if(orig == ORIGINDEX_NONE) continue;
1328                         func(userData, orig, mv[med->v1].co, mv[med->v2].co);
1329                 }
1330                 else
1331                         func(userData, i, mv[med->v1].co, mv[med->v2].co);
1332         }
1333 }
1334
1335 static void cdDM_foreachMappedFaceCenter(
1336                            DerivedMesh *dm,
1337                            void (*func)(void *userData, int index,
1338                                         float *cent, float *no),
1339                            void *userData)
1340 {
1341         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1342         MVert *mv = cddm->mvert;
1343         MPoly *mf = cddm->mpoly;
1344         MLoop *ml = cddm->mloop;
1345         int i, j, orig, *index;
1346         int maxf=0;
1347
1348         index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
1349         mf = cddm->mpoly;
1350         for(i = 0; i < dm->numPolyData; i++, mf++) {
1351                 float cent[3];
1352                 float no[3];
1353
1354                 if (index) {
1355                         orig = *index++;
1356                         if(orig == ORIGINDEX_NONE) continue;
1357                 } else
1358                         orig = i;
1359                 
1360                 ml = &cddm->mloop[mf->loopstart];
1361                 cent[0] = cent[1] = cent[2] = 0.0f;
1362                 for (j=0; j<mf->totloop; j++, ml++) {
1363                         add_v3_v3v3(cent, cent, mv[ml->v].co);
1364                 }
1365                 mul_v3_fl(cent, 1.0f / (float)j);
1366
1367                 ml = &cddm->mloop[mf->loopstart];
1368                 if (j > 3) {
1369                         normal_quad_v3(no, mv[ml->v].co, mv[(ml+1)->v].co,
1370                                        mv[(ml+2)->v].co, mv[(ml+3)->v].co);
1371                 } else {
1372                         normal_tri_v3(no, mv[ml->v].co, mv[(ml+1)->v].co,
1373                                        mv[(ml+2)->v].co);
1374                 }
1375
1376                 func(userData, orig, cent, no);
1377         }
1378
1379 }
1380
1381 static void cdDM_recalcTesselation(DerivedMesh *dm)
1382 {
1383         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1384
1385         dm->numFaceData = mesh_recalcTesselation(&dm->faceData, &dm->loopData, 
1386                 &dm->polyData, cddm->mvert, dm->numFaceData, dm->numLoopData, 
1387                 dm->numPolyData, 1, 0);
1388         
1389         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1390 }
1391
1392 /*ignores original poly origindex layer*/
1393 static void cdDM_recalcTesselation2(DerivedMesh *dm)
1394 {
1395         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1396
1397         dm->numFaceData = mesh_recalcTesselation(&dm->faceData, &dm->loopData, 
1398                 &dm->polyData, cddm->mvert, dm->numFaceData, dm->numLoopData, 
1399                 dm->numPolyData, 0, 0);
1400         
1401         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1402 }
1403
1404 static void cdDM_free_internal(CDDerivedMesh *cddm)
1405 {
1406         if(cddm->pbvh) BLI_pbvh_free(cddm->pbvh);
1407         if(cddm->fmap) MEM_freeN(cddm->fmap);
1408         if(cddm->fmap_mem) MEM_freeN(cddm->fmap_mem);
1409 }
1410
1411 static void cdDM_release(DerivedMesh *dm)
1412 {
1413         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1414
1415         if (DM_release(dm)) {
1416                 cdDM_free_internal(cddm);
1417                 MEM_freeN(cddm);
1418         }
1419 }
1420
1421 int CDDM_Check(DerivedMesh *dm)
1422 {
1423         return dm && dm->getMinMax == cdDM_getMinMax;
1424 }
1425
1426 /**************** CDDM interface functions ****************/
1427 static CDDerivedMesh *cdDM_create(const char *desc)
1428 {
1429         CDDerivedMesh *cddm;
1430         DerivedMesh *dm;
1431
1432         cddm = MEM_callocN(sizeof(*cddm), desc);
1433         dm = &cddm->dm;
1434
1435         dm->getMinMax = cdDM_getMinMax;
1436
1437         dm->getNumVerts = cdDM_getNumVerts;
1438         dm->getNumEdges = cdDM_getNumEdges;
1439         dm->getNumTessFaces = cdDM_getNumTessFaces;
1440         dm->getNumFaces = cdDM_getNumFaces;
1441
1442         dm->newFaceIter = cdDM_newFaceIter;
1443
1444         dm->getVert = cdDM_getVert;
1445         dm->getEdge = cdDM_getEdge;
1446         dm->getTessFace = cdDM_getFace;
1447         dm->copyVertArray = cdDM_copyVertArray;
1448         dm->copyEdgeArray = cdDM_copyEdgeArray;
1449         dm->copyTessFaceArray = cdDM_copyFaceArray;
1450         dm->getVertData = DM_get_vert_data;
1451         dm->getEdgeData = DM_get_edge_data;
1452         dm->getTessFaceData = DM_get_face_data;
1453         dm->getVertDataArray = DM_get_vert_data_layer;
1454         dm->getEdgeDataArray = DM_get_edge_data_layer;
1455         dm->getTessFaceDataArray = DM_get_tessface_data_layer;
1456         
1457         //doesn't work yet for all cases
1458         //dm->recalcTesselation = cdDM_recalcTesselation;
1459
1460         dm->getVertCos = cdDM_getVertCos;
1461         dm->getVertCo = cdDM_getVertCo;
1462         dm->getVertNo = cdDM_getVertNo;
1463
1464         dm->getPBVH = cdDM_getPBVH;
1465         dm->getFaceMap = cdDM_getFaceMap;
1466
1467         dm->drawVerts = cdDM_drawVerts;
1468
1469         dm->drawUVEdges = cdDM_drawUVEdges;
1470         dm->drawEdges = cdDM_drawEdges;
1471         dm->drawLooseEdges = cdDM_drawLooseEdges;
1472         dm->drawMappedEdges = cdDM_drawMappedEdges;
1473
1474         dm->drawFacesSolid = cdDM_drawFacesSolid;
1475         dm->drawFacesColored = cdDM_drawFacesColored;
1476         dm->drawFacesTex = cdDM_drawFacesTex;
1477         dm->drawFacesGLSL = cdDM_drawFacesGLSL;
1478         dm->drawMappedFaces = cdDM_drawMappedFaces;
1479         dm->drawMappedFacesTex = cdDM_drawMappedFacesTex;
1480         dm->drawMappedFacesGLSL = cdDM_drawMappedFacesGLSL;
1481
1482         dm->foreachMappedVert = cdDM_foreachMappedVert;
1483         dm->foreachMappedEdge = cdDM_foreachMappedEdge;
1484         dm->foreachMappedFaceCenter = cdDM_foreachMappedFaceCenter;
1485
1486         dm->release = cdDM_release;
1487
1488         return cddm;
1489 }
1490
1491 DerivedMesh *CDDM_new(int numVerts, int numEdges, int numFaces, int numLoops, int numPolys)
1492 {
1493         CDDerivedMesh *cddm = cdDM_create("CDDM_new dm");
1494         DerivedMesh *dm = &cddm->dm;
1495
1496         DM_init(dm, DM_TYPE_CDDM, numVerts, numEdges, numFaces, numLoops, numPolys);
1497
1498         CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
1499         CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
1500         CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numFaces);
1501         CustomData_add_layer(&dm->polyData, CD_ORIGINDEX, CD_CALLOC, NULL, numPolys);
1502
1503         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
1504         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
1505         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numFaces);
1506         CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL, numLoops);
1507         CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL, numPolys);
1508
1509         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1510         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1511         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1512         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
1513         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
1514
1515         return dm;
1516 }
1517
1518 DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *ob)
1519 {
1520         CDDerivedMesh *cddm = cdDM_create("CDDM_from_mesh dm");
1521         DerivedMesh *dm = &cddm->dm;
1522         CustomDataMask mask = CD_MASK_MESH & (~CD_MASK_MDISPS);
1523         int alloctype;
1524
1525         /* this does a referenced copy, with an exception for fluidsim */
1526
1527         DM_init(dm, DM_TYPE_CDDM, mesh->totvert, mesh->totedge, mesh->totface,
1528                     mesh->totloop, mesh->totpoly);
1529
1530         dm->deformedOnly = 1;
1531
1532         alloctype= CD_REFERENCE;
1533
1534         CustomData_merge(&mesh->vdata, &dm->vertData, mask, alloctype,
1535                          mesh->totvert);
1536         CustomData_merge(&mesh->edata, &dm->edgeData, mask, alloctype,
1537                          mesh->totedge);
1538         CustomData_merge(&mesh->fdata, &dm->faceData, mask|CD_MASK_ORIGINDEX, alloctype,
1539                          mesh->totface);
1540         CustomData_merge(&mesh->ldata, &dm->loopData, mask, alloctype,
1541                          mesh->totloop);
1542         CustomData_merge(&mesh->pdata, &dm->polyData, mask, alloctype,
1543                          mesh->totpoly);
1544
1545         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1546         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1547         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
1548         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
1549         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1550
1551         if (!CustomData_has_layer(&cddm->dm.faceData, CD_ORIGINDEX))
1552                 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totface);
1553
1554         return dm;
1555 }
1556
1557 DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
1558 {
1559         DerivedMesh *dm = CDDM_new(BLI_countlist(&em->verts),
1560                                    BLI_countlist(&em->edges),
1561                                    BLI_countlist(&em->faces), 0, 0);
1562         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1563         EditVert *eve;
1564         EditEdge *eed;
1565         EditFace *efa;
1566         MVert *mvert = cddm->mvert;
1567         MEdge *medge = cddm->medge;
1568         MFace *mface = cddm->mface;
1569         int i, *index;
1570
1571         dm->deformedOnly = 1;
1572
1573         CustomData_merge(&em->vdata, &dm->vertData, CD_MASK_DERIVEDMESH,
1574                          CD_CALLOC, dm->numVertData);
1575         /* CustomData_merge(&em->edata, &dm->edgeData, CD_MASK_DERIVEDMESH,
1576                          CD_CALLOC, dm->numEdgeData); */
1577         CustomData_merge(&em->fdata, &dm->faceData, CD_MASK_DERIVEDMESH,
1578                          CD_CALLOC, dm->numFaceData);
1579         CustomData_merge(&em->fdata, &dm->faceData, CD_MASK_DERIVEDMESH,
1580                          CD_CALLOC, dm->numFaceData);
1581
1582         /* set eve->hash to vert index */
1583         for(i = 0, eve = em->verts.first; eve; eve = eve->next, ++i)
1584                 eve->tmp.l = i;
1585
1586         /* Need to be able to mark loose edges */
1587         for(eed = em->edges.first; eed; eed = eed->next) {
1588                 eed->f2 = 0;
1589         }
1590         for(efa = em->faces.first; efa; efa = efa->next) {
1591                 efa->e1->f2 = 1;
1592                 efa->e2->f2 = 1;
1593                 efa->e3->f2 = 1;
1594                 if(efa->e4) efa->e4->f2 = 1;
1595         }
1596
1597         index = dm->getVertDataArray(dm, CD_ORIGINDEX);
1598         for(i = 0, eve = em->verts.first; i < dm->numVertData;
1599             i++, eve = eve->next, index++) {
1600                 MVert *mv = &mvert[i];
1601
1602                 VECCOPY(mv->co, eve->co);
1603
1604                 mv->no[0] = eve->no[0] * 32767.0;
1605                 mv->no[1] = eve->no[1] * 32767.0;
1606                 mv->no[2] = eve->no[2] * 32767.0;
1607                 mv->bweight = (unsigned char) (eve->bweight * 255.0f);
1608
1609                 mv->mat_nr = 0;
1610                 mv->flag = 0;
1611
1612                 *index = i;
1613
1614                 CustomData_from_em_block(&em->vdata, &dm->vertData, eve->data, i);
1615         }
1616
1617         index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
1618         for(i = 0, eed = em->edges.first; i < dm->numEdgeData;
1619             i++, eed = eed->next, index++) {
1620                 MEdge *med = &medge[i];
1621
1622                 med->v1 = eed->v1->tmp.l;
1623                 med->v2 = eed->v2->tmp.l;
1624                 med->crease = (unsigned char) (eed->crease * 255.0f);
1625                 med->bweight = (unsigned char) (eed->bweight * 255.0f);
1626                 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
1627                 
1628                 if(eed->seam) med->flag |= ME_SEAM;
1629                 if(eed->sharp) med->flag |= ME_SHARP;
1630                 if(!eed->f2) med->flag |= ME_LOOSEEDGE;
1631
1632                 *index = i;
1633
1634                 /* CustomData_from_em_block(&em->edata, &dm->edgeData, eed->data, i); */
1635         }
1636
1637         index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1638         for(i = 0, efa = em->faces.first; i < dm->numFaceData;
1639             i++, efa = efa->next, index++) {
1640                 MFace *mf = &mface[i];
1641
1642                 mf->v1 = efa->v1->tmp.l;
1643                 mf->v2 = efa->v2->tmp.l;
1644                 mf->v3 = efa->v3->tmp.l;
1645                 mf->v4 = efa->v4 ? efa->v4->tmp.l : 0;
1646                 mf->mat_nr = efa->mat_nr;
1647                 mf->flag = efa->flag;
1648
1649                 *index = i;
1650
1651                 CustomData_from_em_block(&em->fdata, &dm->faceData, efa->data, i);
1652                 test_index_face(mf, &dm->faceData, i, efa->v4?4:3);
1653         }
1654
1655         return dm;
1656 }
1657
1658
1659 static void loops_to_customdata_corners(BMesh *bm, CustomData *facedata,
1660                                       int cdindex, BMLoop *l3[3],
1661                                       int numCol, int numTex)
1662 {
1663         BMLoop *l;
1664         BMFace *f = l3[0]->f;
1665         MTFace *texface;
1666         MTexPoly *texpoly;
1667         MCol *mcol;
1668         MLoopCol *mloopcol;
1669         MLoopUV *mloopuv;
1670         int i, j, hasWCol = CustomData_has_layer(&bm->ldata, CD_WEIGHT_MLOOPCOL);
1671
1672         for(i=0; i < numTex; i++){
1673                 texface = CustomData_get_n(facedata, CD_MTFACE, cdindex, i);
1674                 texpoly = CustomData_bmesh_get_n(&bm->pdata, f->head.data, CD_MTEXPOLY, i);
1675                 
1676                 texface->tpage = texpoly->tpage;
1677                 texface->flag = texpoly->flag;
1678                 texface->transp = texpoly->transp;
1679                 texface->mode = texpoly->mode;
1680                 texface->tile = texpoly->tile;
1681                 texface->unwrap = texpoly->unwrap;
1682         
1683                 for (j=0; j<3; j++) {
1684                         l = l3[j];
1685                         mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPUV, i);
1686                         texface->uv[j][0] = mloopuv->uv[0];
1687                         texface->uv[j][1] = mloopuv->uv[1];
1688                 }
1689         }
1690
1691         for(i=0; i < numCol; i++){
1692                 mcol = CustomData_get_n(facedata, CD_MCOL, cdindex, i);
1693                 
1694                 for (j=0; j<3; j++) {
1695                         l = l3[j];
1696                         mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPCOL, i);
1697                         mcol[j].r = mloopcol->r;
1698                         mcol[j].g = mloopcol->g;
1699                         mcol[j].b = mloopcol->b;
1700                         mcol[j].a = mloopcol->a;
1701                 }
1702         }
1703
1704         if (hasWCol) {
1705                 mcol = CustomData_get(facedata, cdindex, CD_WEIGHT_MCOL);
1706
1707                 for (j=0; j<3; j++) {
1708                         l = l3[j];
1709                         mloopcol = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_WEIGHT_MLOOPCOL);
1710                         mcol[j].r = mloopcol->r;
1711                         mcol[j].g = mloopcol->g;
1712                         mcol[j].b = mloopcol->b;
1713                         mcol[j].a = mloopcol->a;
1714                 }
1715         }
1716 }
1717
1718 DerivedMesh *CDDM_from_BMEditMesh(BMEditMesh *em, Mesh *me)
1719 {
1720         DerivedMesh *dm = CDDM_new(em->bm->totvert, em->bm->totedge, 
1721                                em->tottri, em->bm->totloop, em->bm->totface);
1722         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1723         BMesh *bm = em->bm;
1724         BMIter iter, liter;
1725         BMVert *eve;
1726         BMEdge *eed;
1727         BMFace *efa;
1728         MVert *mvert = cddm->mvert;
1729         MEdge *medge = cddm->medge;
1730         MFace *mface = cddm->mface;
1731         MLoop *mloop = cddm->mloop;
1732         MPoly *mpoly = cddm->mpoly;
1733         int numCol = CustomData_number_of_layers(&em->bm->ldata, CD_MLOOPCOL);
1734         int numTex = CustomData_number_of_layers(&em->bm->pdata, CD_MTEXPOLY);
1735         int i, j, *index, add_orig;
1736
1737         dm->deformedOnly = 1;
1738         
1739         /*don't add origindex layer if one already exists*/
1740         add_orig = !CustomData_has_layer(&em->bm->pdata, CD_ORIGINDEX);
1741
1742         CustomData_merge(&em->bm->vdata, &dm->vertData, CD_MASK_DERIVEDMESH,
1743                          CD_CALLOC, dm->numVertData);
1744         CustomData_merge(&em->bm->edata, &dm->edgeData, CD_MASK_DERIVEDMESH,
1745                          CD_CALLOC, dm->numEdgeData);
1746         CustomData_merge(&em->bm->pdata, &dm->faceData, CD_MASK_DERIVEDMESH,
1747                          CD_CALLOC, dm->numFaceData);
1748         CustomData_merge(&em->bm->ldata, &dm->loopData, CD_MASK_DERIVEDMESH,
1749                          CD_CALLOC, dm->numLoopData);
1750         CustomData_merge(&em->bm->pdata, &dm->polyData, CD_MASK_DERIVEDMESH,
1751                          CD_CALLOC, dm->numPolyData);
1752         
1753         /*add tesselation mface layers*/
1754         CustomData_from_bmeshpoly(&dm->faceData, &dm->polyData, &dm->loopData, em->tottri);
1755
1756         /* set vert index */
1757         eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
1758         for (i=0; eve; eve=BMIter_Step(&iter), i++)
1759                 BMINDEX_SET(eve, i);
1760
1761         index = dm->getVertDataArray(dm, CD_ORIGINDEX);
1762
1763         eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
1764         for (i=0; eve; eve=BMIter_Step(&iter), i++, index++) {
1765                 MVert *mv = &mvert[i];
1766
1767                 VECCOPY(mv->co, eve->co);
1768
1769                 BMINDEX_SET(eve, i);
1770
1771                 mv->no[0] = eve->no[0] * 32767.0;
1772                 mv->no[1] = eve->no[1] * 32767.0;
1773                 mv->no[2] = eve->no[2] * 32767.0;
1774                 mv->bweight = (unsigned char) (eve->bweight * 255.0f);
1775
1776                 mv->mat_nr = 0;
1777                 mv->flag = BMFlags_To_MEFlags(eve);
1778
1779                 if (add_orig) *index = i;
1780
1781                 CustomData_from_bmesh_block(&bm->vdata, &dm->vertData, eve->head.data, i);
1782         }
1783
1784         index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
1785         eed = BMIter_New(&iter, bm, BM_EDGES_OF_MESH, NULL);
1786         for (i=0; eed; eed=BMIter_Step(&iter), i++, index++) {
1787                 MEdge *med = &medge[i];
1788
1789                 BMINDEX_SET(eed, i);
1790
1791                 med->v1 = BMINDEX_GET(eed->v1);
1792                 med->v2 = BMINDEX_GET(eed->v2);
1793                 med->crease = (unsigned char) (eed->crease * 255.0f);
1794                 med->bweight = (unsigned char) (eed->bweight * 255.0f);
1795                 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
1796                 
1797                 med->flag = BMFlags_To_MEFlags(eed);
1798
1799                 CustomData_from_bmesh_block(&bm->edata, &dm->edgeData, eed->head.data, i);
1800                 if (add_orig) *index = i;
1801         }
1802
1803         efa = BMIter_New(&iter, bm, BM_FACES_OF_MESH, NULL);
1804         for (i=0; efa; i++, efa=BMIter_Step(&iter)) {
1805                 BMINDEX_SET(efa, i);
1806         }
1807
1808         index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1809         for(i = 0; i < dm->numFaceData; i++, index++) {
1810                 MFace *mf = &mface[i];
1811                 BMLoop **l = em->looptris[i];
1812                 efa = l[0]->f;
1813
1814                 mf->v1 = BMINDEX_GET(l[0]->v);
1815                 mf->v2 = BMINDEX_GET(l[1]->v);
1816                 mf->v3 = BMINDEX_GET(l[2]->v);
1817                 mf->v4 = 0;
1818                 mf->mat_nr = efa->mat_nr;
1819                 mf->flag = BMFlags_To_MEFlags(efa);
1820                 
1821                 *index = add_orig ? BMINDEX_GET(efa) : *(int*)CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_ORIGINDEX);
1822
1823                 loops_to_customdata_corners(bm, &dm->faceData, i, l, numCol, numTex);
1824                 test_index_face(mf, &dm->faceData, i, 3);
1825         }
1826         
1827         index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
1828         j = 0;
1829         efa = BMIter_New(&iter, bm, BM_FACES_OF_MESH, NULL);
1830         for (i=0; efa; i++, efa=BMIter_Step(&iter), index++) {
1831                 BMLoop *l;
1832                 MPoly *mp = &mpoly[i];
1833
1834                 mp->totloop = efa->len;
1835                 mp->flag = BMFlags_To_MEFlags(efa);
1836                 mp->loopstart = j;
1837                 mp->mat_nr = efa->mat_nr;
1838                 
1839                 BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, efa) {
1840                         mloop->v = BMINDEX_GET(l->v);
1841                         mloop->e = BMINDEX_GET(l->e);
1842                         CustomData_from_bmesh_block(&bm->ldata, &dm->loopData, l->head.data, j);
1843
1844                         j++;
1845                         mloop++;
1846                 }
1847
1848                 CustomData_from_bmesh_block(&bm->pdata, &dm->polyData, efa->head.data, i);
1849
1850                 if (add_orig) *index = i;
1851         }
1852
1853         return dm;
1854 }
1855
1856 typedef struct CDDM_LoopIter {
1857         DMLoopIter head;
1858         CDDerivedMesh *cddm;
1859         int len, i;
1860 } CDDM_LoopIter;
1861
1862 typedef struct CDDM_FaceIter {
1863         DMFaceIter head;
1864         CDDerivedMesh *cddm;
1865         CDDM_LoopIter liter;
1866 } CDDM_FaceIter;
1867
1868 void cddm_freeiter(void *self)
1869 {
1870         MEM_freeN(self);
1871 }
1872
1873 void cddm_stepiter(void *self)
1874 {
1875         CDDM_FaceIter *iter = self;
1876         MPoly *mp;
1877         
1878         mp = iter->cddm->mpoly + iter->head.index;
1879         mp->flag = iter->head.flags;
1880         mp->mat_nr = iter->head.mat_nr;
1881
1882         iter->head.index++;
1883         if (iter->head.index >= iter->cddm->dm.numPolyData) {
1884                 iter->head.done = 1;
1885                 return;
1886         }
1887
1888         mp = iter->cddm->mpoly + iter->head.index;
1889
1890         iter->head.flags = mp->flag;
1891         iter->head.mat_nr = mp->mat_nr;
1892         iter->head.len = mp->totloop;
1893 }
1894
1895 void *cddm_faceiter_getcddata(void *self, int type, int layer)
1896 {
1897         CDDM_FaceIter *iter = self;
1898
1899         if (layer == -1) return CustomData_get(&iter->cddm->dm.polyData, 
1900                                                iter->head.index, type);
1901         else return CustomData_get_n(&iter->cddm->dm.polyData, type, 
1902                                     iter->head.index, layer);
1903 }
1904
1905 void *cddm_loopiter_getcddata(void *self, int type, int layer)
1906 {
1907         CDDM_LoopIter *iter = self;
1908
1909         if (layer == -1) return CustomData_get(&iter->cddm->dm.loopData, 
1910                                                iter->head.index, type);
1911         else return CustomData_get_n(&iter->cddm->dm.loopData, type, 
1912                                      iter->head.index, layer);
1913 }
1914
1915 void *cddm_loopiter_getvertcddata(void *self, int type, int layer)
1916 {
1917         CDDM_LoopIter *iter = self;
1918
1919         if (layer == -1) return CustomData_get(&iter->cddm->dm.vertData, 
1920                                                iter->cddm->mloop[iter->head.vindex].v,
1921                                                type);
1922         else return CustomData_get_n(&iter->cddm->dm.vertData, type, 
1923                                      iter->cddm->mloop[iter->head.vindex].v, layer);
1924 }
1925
1926 DMLoopIter *cddmiter_get_loopiter(void *self)
1927 {
1928         CDDM_FaceIter *iter = self;
1929         CDDM_LoopIter *liter = &iter->liter;
1930         MPoly *mp = iter->cddm->mpoly + iter->head.index;
1931
1932         liter->i = -1;
1933         liter->len = iter->head.len;
1934         liter->head.index = mp->loopstart-1;
1935         liter->head.done = 0;
1936
1937         liter->head.step(liter);
1938
1939         return (DMLoopIter*) liter;
1940 }
1941
1942 void cddm_loopiter_step(void *self)
1943 {
1944         CDDM_LoopIter *liter = self;
1945         MLoop *ml;
1946
1947         liter->i++;
1948         liter->head.index++;
1949
1950         if (liter->i == liter->len) {
1951                 liter->head.done = 1;
1952                 return;
1953         }
1954
1955         ml = liter->cddm->mloop + liter->head.index;
1956
1957         liter->head.eindex = ml->e;
1958         liter->head.v = liter->cddm->mvert[ml->v];
1959         liter->head.vindex = ml->v;
1960 }
1961
1962 DMFaceIter *cdDM_newFaceIter(DerivedMesh *source)
1963 {
1964         CDDerivedMesh *cddm = (CDDerivedMesh*) source;
1965         CDDM_FaceIter *iter = MEM_callocN(sizeof(CDDM_FaceIter), "DMFaceIter from cddm");
1966
1967         iter->head.free = cddm_freeiter;
1968         iter->head.step = cddm_stepiter;
1969         iter->head.getCDData = cddm_faceiter_getcddata;
1970         iter->head.getLoopsIter = cddmiter_get_loopiter;
1971
1972         iter->liter.head.step = cddm_loopiter_step;
1973         iter->liter.head.getLoopCDData = cddm_loopiter_getcddata;
1974         iter->liter.head.getVertCDData = cddm_loopiter_getvertcddata;
1975         iter->liter.cddm = cddm;
1976
1977         iter->cddm = cddm;
1978
1979         if (source->numFaceData) {
1980                 iter->head.index = -1;
1981                 iter->head.step(iter);
1982         } else {
1983                 iter->head.done = 1;
1984         }
1985
1986         return (DMFaceIter*) iter;
1987 }
1988
1989 DerivedMesh *CDDM_copy(DerivedMesh *source, int faces_from_tessfaces)
1990 {
1991         CDDerivedMesh *cddm = cdDM_create("CDDM_copy cddm");
1992         DerivedMesh *dm = &cddm->dm;
1993         int numVerts = source->numVertData;
1994         int numEdges = source->numEdgeData;
1995         int numFaces = source->numFaceData;
1996         int numLoops = source->numLoopData;
1997         int numPolys = source->numPolyData;
1998
1999         /* ensure these are created if they are made on demand */
2000         source->getVertDataArray(source, CD_ORIGINDEX);
2001         source->getEdgeDataArray(source, CD_ORIGINDEX);
2002         source->getTessFaceDataArray(source, CD_ORIGINDEX);
2003
2004         /* this initializes dm, and copies all non mvert/medge/mface layers */
2005         DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numFaces,
2006                 numLoops, numPolys);
2007         dm->deformedOnly = source->deformedOnly;
2008
2009         CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts);
2010         CustomData_copy_data(&source->edgeData, &dm->edgeData, 0, 0, numEdges);
2011         CustomData_copy_data(&source->faceData, &dm->faceData, 0, 0, numFaces);
2012
2013         /* now add mvert/medge/mface layers */
2014         cddm->mvert = source->dupVertArray(source);
2015         cddm->medge = source->dupEdgeArray(source);
2016         cddm->mface = source->dupTessFaceArray(source);
2017
2018         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, cddm->mvert, numVerts);
2019         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, cddm->medge, numEdges);
2020         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, cddm->mface, numFaces);
2021         
2022         if (!faces_from_tessfaces)
2023                 DM_DupPolys(source, dm);
2024         else
2025                 CDDM_tessfaces_to_faces(dm);
2026
2027         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
2028         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
2029
2030         return dm;
2031 }
2032
2033 DerivedMesh *CDDM_from_template(DerivedMesh *source,
2034                                 int numVerts, int numEdges, int numFaces,
2035                                 int numLoops, int numPolys)
2036 {
2037         CDDerivedMesh *cddm = cdDM_create("CDDM_from_template dest");
2038         DerivedMesh *dm = &cddm->dm;
2039
2040         /* this does a copy of all non mvert/medge/mface layers */
2041         DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numFaces, numLoops, numPolys);
2042
2043         /* now add mvert/medge/mface layers */
2044         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
2045         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2046         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numFaces);
2047         CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL, numLoops);
2048         CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL, numPolys);
2049
2050         if(!CustomData_get_layer(&dm->vertData, CD_ORIGINDEX))
2051                 CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
2052         if(!CustomData_get_layer(&dm->edgeData, CD_ORIGINDEX))
2053                 CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2054         if(!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX))
2055                 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numFaces);
2056
2057         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
2058         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2059         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
2060         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
2061         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
2062
2063         return dm;
2064 }
2065
2066 void CDDM_apply_vert_coords(DerivedMesh *dm, float (*vertCoords)[3])
2067 {
2068         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2069         MVert *vert;
2070         int i;
2071
2072         /* this will just return the pointer if it wasn't a referenced layer */
2073         vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
2074         cddm->mvert = vert;
2075
2076         for(i = 0; i < dm->numVertData; ++i, ++vert)
2077                 VECCOPY(vert->co, vertCoords[i]);
2078 }
2079
2080 void CDDM_apply_vert_normals(DerivedMesh *dm, short (*vertNormals)[3])
2081 {
2082         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2083         MVert *vert;
2084         int i;
2085
2086         /* this will just return the pointer if it wasn't a referenced layer */
2087         vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
2088         cddm->mvert = vert;
2089
2090         for(i = 0; i < dm->numVertData; ++i, ++vert)
2091                 VECCOPY(vert->no, vertNormals[i]);
2092 }
2093
2094 void CDDM_calc_normals(DerivedMesh *dm)
2095 {
2096         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2097         float (*temp_nors)[3];
2098         float (*face_nors)[3];
2099         float (*vert_nors)[3];
2100         int i, j, *origIndex;
2101         int numVerts = dm->numVertData;
2102         int numFaces = dm->numFaceData;
2103         MFace *mf;
2104         MPoly *mp;
2105         MVert *mv;
2106         MLoop *ml;
2107
2108         if(numVerts == 0) return;
2109
2110         if (CustomData_has_layer(&dm->faceData, CD_NORMAL))
2111                 CustomData_free_layer(&dm->faceData, CD_NORMAL, dm->numFaceData, 0);
2112
2113         /*recalc tesselation to ensure we have valid origindex values
2114           for mface->mpoly lookups.*/
2115         cdDM_recalcTesselation2(dm);
2116
2117         numFaces = dm->numFaceData;
2118
2119         /*first go through and calculate normals for all the polys*/
2120         temp_nors = MEM_callocN(sizeof(float)*3*dm->numPolyData, "temp_nors cdderivedmesh.c");
2121         vert_nors = MEM_callocN(sizeof(float)*3*dm->numVertData, "vert_nors cdderivedmesh.c");
2122         
2123         mp = cddm->mpoly;
2124         for (i=0; i<dm->numPolyData; i++, mp++) {
2125                 mesh_calc_poly_normal(mp, cddm->mloop+mp->loopstart, cddm->mvert, temp_nors[i]);
2126
2127                 ml = cddm->mloop + mp->loopstart;
2128                 for (j=0; j<mp->totloop; j++, ml++) {
2129                         VECADD(vert_nors[ml->v], vert_nors[ml->v], temp_nors[i]);
2130                 }
2131         }
2132
2133         face_nors = MEM_callocN(sizeof(float)*3*dm->numFaceData, "face_nors cdderivedmesh.c");
2134         origIndex = CustomData_get_layer(&dm->faceData, CD_ORIGINDEX);
2135
2136         mf = cddm->mface;
2137         for (i=0; i<dm->numFaceData; i++, mf++, origIndex++) {
2138                 VECCOPY(face_nors[i], temp_nors[*origIndex]);
2139         }
2140
2141         mv = cddm->mvert;
2142         for (i=0; i<dm->numVertData; i++, mv++) {
2143                 float *no = vert_nors[i];
2144                 
2145                 if (normalize_v3(no) == 0.0) {
2146                         VECCOPY(no, mv->co);
2147                         if (normalize_v3(no) == 0.0) {
2148                                 no[0] = 0.0f;
2149                                 no[1] = 0.0f;
2150                                 no[2] = 1.0f;
2151                         }
2152                 }
2153
2154                 mv->no[0] = (short)(no[0] * 32767.0f);
2155                 mv->no[1] = (short)(no[1] * 32767.0f);
2156                 mv->no[2] = (short)(no[2] * 32767.0f);
2157         }
2158
2159         MEM_freeN(temp_nors);
2160         MEM_freeN(vert_nors);
2161
2162         /*this restores original poly origindex -> tessface origindex mapping,
2163           instead of the poly index -> tessface origindex one we generated
2164           with cdDM_recalcTesselation2*/
2165         cdDM_recalcTesselation(dm);
2166         CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_ASSIGN, 
2167                 face_nors, dm->numFaceData);
2168 }
2169
2170 void CDDM_calc_edges(DerivedMesh *dm)
2171 {
2172         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2173         CustomData edgeData;
2174         EdgeHashIterator *ehi;
2175         MFace *mf = cddm->mface;
2176         MEdge *med;
2177         EdgeHash *eh = BLI_edgehash_new();
2178         int i, *index, numEdges, maxFaces = dm->numFaceData;
2179
2180         for (i = 0; i < maxFaces; i++, mf++) {
2181                 if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
2182                         BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
2183                 if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
2184                         BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
2185                 
2186                 if (mf->v4) {
2187                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
2188                                 BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
2189                         if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
2190                                 BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
2191                 } else {
2192                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
2193                                 BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
2194                 }
2195         }
2196
2197         numEdges = BLI_edgehash_size(eh);
2198
2199         /* write new edges into a temporary CustomData */
2200         memset(&edgeData, 0, sizeof(edgeData));
2201         CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2202         CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2203
2204         ehi = BLI_edgehashIterator_new(eh);
2205         med = CustomData_get_layer(&edgeData, CD_MEDGE);
2206         index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
2207         for(i = 0; !BLI_edgehashIterator_isDone(ehi);
2208             BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) {
2209                 BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2);
2210
2211                 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
2212                 *index = ORIGINDEX_NONE;
2213         }
2214         BLI_edgehashIterator_free(ehi);
2215
2216         /* free old CustomData and assign new one */
2217         CustomData_free(&dm->edgeData, dm->numEdgeData);
2218         dm->edgeData = edgeData;
2219         dm->numEdgeData = numEdges;
2220
2221         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2222
2223         BLI_edgehash_free(eh, NULL);
2224 }
2225
2226
2227 void CDDM_calc_edges_poly(DerivedMesh *dm)
2228 {
2229         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2230         CustomData edgeData;
2231         EdgeHashIterator *ehi;
2232         MPoly *mp = cddm->mpoly;
2233         MLoop *ml;
2234         MEdge *med;
2235         EdgeHash *eh = BLI_edgehash_new();
2236         int v1, v2;
2237         int *eindex;
2238         int i, j, k, *index, numEdges = cddm->dm.numEdgeData, maxFaces = dm->numPolyData;
2239
2240         eindex = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
2241
2242         med = cddm->medge;
2243         if (med) {
2244                 for (i=0; i < numEdges; i++, med++) {
2245                         BLI_edgehash_insert(eh, med->v1, med->v2, SET_INT_IN_POINTER(i+1));
2246                 }
2247         }
2248
2249         for (i=0; i < maxFaces; i++, mp++) {
2250                 ml = cddm->mloop + mp->loopstart;
2251                 for (j=0; j<mp->totloop; j++, ml++) {
2252                         v1 = ml->v;
2253                         v2 = (cddm->mloop + mp->loopstart + ((j+1)%mp->totloop))->v;
2254                         if (!BLI_edgehash_haskey(eh, v1, v2)) {
2255                                 BLI_edgehash_insert(eh, v1, v2, NULL);
2256                         }
2257                 }
2258         }
2259
2260         k = numEdges;
2261         numEdges = BLI_edgehash_size(eh);
2262
2263         /* write new edges into a temporary CustomData */
2264         memset(&edgeData, 0, sizeof(edgeData));
2265         CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2266         CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2267
2268         ehi = BLI_edgehashIterator_new(eh);
2269         med = CustomData_get_layer(&edgeData, CD_MEDGE);
2270         index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
2271         for(i = 0; !BLI_edgehashIterator_isDone(ehi);
2272             BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) {
2273                 BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2);
2274                 j = GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi));
2275
2276                 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
2277                 *index = j==0 ? ORIGINDEX_NONE : eindex[j-1];
2278
2279                 BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(i));
2280         }
2281         BLI_edgehashIterator_free(ehi);
2282
2283         /* free old CustomData and assign new one */
2284         CustomData_free(&dm->edgeData, dm->numEdgeData);
2285         dm->edgeData = edgeData;
2286         dm->numEdgeData = numEdges;
2287
2288         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2289
2290         mp = cddm->mpoly;
2291         for (i=0; i < maxFaces; i++, mp++) {
2292                 ml = cddm->mloop + mp->loopstart;
2293                 for (j=0; j<mp->totloop; j++, ml++) {
2294                         v1 = ml->v;
2295                         v2 = (cddm->mloop + mp->loopstart + ((j+1)%mp->totloop))->v;
2296                         ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, v1, v2));
2297                 }
2298         }
2299
2300         BLI_edgehash_free(eh, NULL);
2301 }
2302
2303 void CDDM_lower_num_verts(DerivedMesh *dm, int numVerts)
2304 {
2305         if (numVerts < dm->numVertData)
2306                 CustomData_free_elem(&dm->vertData, numVerts, dm->numVertData-numVerts);
2307
2308         dm->numVertData = numVerts;
2309 }
2310
2311 void CDDM_lower_num_edges(DerivedMesh *dm, int numEdges)
2312 {
2313         if (numEdges < dm->numEdgeData)
2314                 CustomData_free_elem(&dm->edgeData, numEdges, dm->numEdgeData-numEdges);
2315
2316         dm->numEdgeData = numEdges;
2317 }
2318
2319 void CDDM_lower_num_faces(DerivedMesh *dm, int numFaces)
2320 {
2321         if (numFaces < dm->numFaceData)
2322                 CustomData_free_elem(&dm->faceData, numFaces, dm->numFaceData-numFaces);
2323
2324         dm->numFaceData = numFaces;
2325 }
2326
2327 MVert *CDDM_get_vert(DerivedMesh *dm, int index)
2328 {
2329         return &((CDDerivedMesh*)dm)->mvert[index];
2330 }
2331
2332 MEdge *CDDM_get_edge(DerivedMesh *dm, int index)
2333 {
2334         return &((CDDerivedMesh*)dm)->medge[index];
2335 }
2336
2337 MFace *CDDM_get_tessface(DerivedMesh *dm, int index)
2338 {
2339         return &((CDDerivedMesh*)dm)->mface[index];
2340 }
2341
2342 MVert *CDDM_get_verts(DerivedMesh *dm)
2343 {
2344         return ((CDDerivedMesh*)dm)->mvert;
2345 }
2346
2347 MEdge *CDDM_get_edges(DerivedMesh *dm)
2348 {
2349         return ((CDDerivedMesh*)dm)->medge;
2350 }
2351
2352 MFace *CDDM_get_tessfaces(DerivedMesh *dm)
2353 {
2354         return ((CDDerivedMesh*)dm)->mface;
2355 }
2356
2357 void CDDM_tessfaces_to_faces(DerivedMesh *dm)
2358 {
2359         /*converts mfaces to mpolys/mloops*/
2360         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2361         MFace *mf;
2362         MEdge *me;
2363         MLoop *ml;
2364         MPoly *mp;
2365         EdgeHash *eh = BLI_edgehash_new();
2366         int i, l, totloop, *index1, *index2;
2367         
2368         /*ensure we have all the edges we need*/
2369         CDDM_calc_edges(dm);
2370
2371         /*build edge hash*/
2372         me = cddm->medge;
2373         for (i=0; i<cddm->dm.numEdgeData; i++, me++) {
2374                 BLI_edgehash_insert(eh, me->v1, me->v2, SET_INT_IN_POINTER(i));
2375         }
2376
2377         mf = cddm->mface;
2378         totloop = 0;
2379         for (i=0; i<cddm->dm.numFaceData; i++, mf++) {
2380                 totloop += mf->v4 ? 4 : 3;
2381         }
2382
2383         CustomData_free(&cddm->dm.polyData, cddm->dm.numPolyData);
2384         CustomData_free(&cddm->dm.loopData, cddm->dm.numLoopData);
2385         
2386         cddm->dm.numLoopData = totloop;
2387         cddm->dm.numPolyData = cddm->dm.numFaceData;
2388
2389         if (!totloop) return;
2390
2391         cddm->mloop = MEM_callocN(sizeof(MLoop)*totloop, "cddm->mloop in CDDM_tessfaces_to_faces");
2392         cddm->mpoly = MEM_callocN(sizeof(MPoly)*cddm->dm.numFaceData, "cddm->mpoly in CDDM_tessfaces_to_faces");
2393         
2394         CustomData_add_layer(&cddm->dm.loopData, CD_MLOOP, CD_ASSIGN, cddm->mloop, totloop);
2395         CustomData_add_layer(&cddm->dm.polyData, CD_MPOLY, CD_ASSIGN, cddm->mpoly, cddm->dm.numPolyData);
2396         CustomData_merge(&cddm->dm.faceData, &cddm->dm.polyData, 
2397                 CD_MASK_ORIGINDEX, CD_DUPLICATE, cddm->dm.numFaceData);
2398
2399         index1 = CustomData_get_layer(&cddm->dm.faceData, CD_ORIGINDEX);
2400         index2 = CustomData_get_layer(&cddm->dm.polyData, CD_ORIGINDEX);
2401
2402         mf = cddm->mface;
2403         mp = cddm->mpoly;
2404         ml = cddm->mloop;
2405         l = 0;
2406         for (i=0; i<cddm->dm.numFaceData; i++, mf++, mp++) {
2407                 mp->flag = mf->flag;
2408                 mp->loopstart = l;
2409                 mp->mat_nr = mf->mat_nr;
2410                 mp->totloop = mf->v4 ? 4 : 3;
2411                 
2412                 ml->v = mf->v1;
2413                 ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v1, mf->v2));
2414                 ml++, l++;
2415
2416                 ml->v = mf->v2;
2417                 ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v2, mf->v3));
2418                 ml++, l++;
2419
2420                 ml->v = mf->v3;
2421                 ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v3, mf->v4?mf->v4:mf->v1));
2422                 ml++, l++;
2423
2424                 if (mf->v4) {
2425                         ml->v = mf->v4;
2426                         ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v4, mf->v1));
2427                         ml++, l++;
2428                 }
2429
2430         }
2431
2432         BLI_edgehash_free(eh, NULL);
2433 }
2434
2435 void CDDM_set_mvert(DerivedMesh *dm, MVert *mvert)
2436 {
2437         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2438
2439         cddm->mvert = mvert;
2440 }
2441
2442 void CDDM_set_medge(DerivedMesh *dm, MEdge *medge)
2443 {
2444         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2445
2446         cddm->medge = medge;
2447 }
2448
2449 void CDDM_set_mface(DerivedMesh *dm, MFace *mface)
2450 {
2451         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2452
2453         cddm->mface = mface;
2454 }