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