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