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