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