Code cleanup: remove some PBVH material code that isn't needed anymore.
[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), int (*setMaterial)(int, void *attribs))
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                            int (*drawParams)(MTFace *tface, int has_mcol, int matnr),
604                            int (*drawParamsMapped)(void *userData, int index),
605                            int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
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                            int (*setDrawOptions)(MTFace *tface, int has_mcol, int matnr),
792                            int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
793                            void *userData)
794 {
795         cdDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData);
796 }
797
798 static void cdDM_drawMappedFaces(DerivedMesh *dm,
799                         int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r),
800                         int (*setMaterial)(int, void *attribs),
801                         int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
802                         void *userData, int useColors)
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 i, orig, *index = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
810
811         mc = DM_get_tessface_data_layer(dm, CD_ID_MCOL);
812         if(!mc)
813                 mc = DM_get_tessface_data_layer(dm, CD_WEIGHT_MCOL);
814         if(!mc)
815                 mc = DM_get_tessface_data_layer(dm, CD_MCOL);
816
817         cdDM_update_normals_from_pbvh(dm);
818
819         /* back-buffer always uses legacy since VBO's would need the
820          * color array temporarily overwritten for drawing, then reset. */
821         if( GPU_buffer_legacy(dm) || G.f & G_BACKBUFSEL) {
822                 DEBUG_VBO( "Using legacy code. cdDM_drawMappedFaces\n" );
823                 for(i = 0; i < dm->numTessFaceData; i++, mf++) {
824                         int drawSmooth = (mf->flag & ME_SMOOTH);
825                         int draw= 1;
826
827                         orig= (index==NULL) ? i : *index++;
828                         
829                         if(orig == ORIGINDEX_NONE)
830                                 draw= setMaterial(mf->mat_nr + 1, NULL);
831                         else if (setDrawOptions != NULL)
832                                 draw= setDrawOptions(userData, orig, &drawSmooth);
833
834                         if(draw) {
835                                 unsigned char *cp = NULL;
836
837                                 if(useColors && mc)
838                                         cp = (unsigned char *)&mc[i * 4];
839
840                                 /* no need to set shading mode to flat because
841                                 *  normals are already used to change shading */
842                                 glShadeModel(GL_SMOOTH);
843                                 glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
844
845                                 if (!drawSmooth) {
846                                         if (nors) {
847                                                 glNormal3fv(nors);
848                                         }
849                                         else {
850                                                 float nor[3];
851                                                 if(mf->v4) {
852                                                         normal_quad_v3( nor,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
853                                                 } else {
854                                                         normal_tri_v3( nor,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
855                                                 }
856                                                 glNormal3fv(nor);
857                                         }
858
859                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
860                                         glVertex3fv(mv[mf->v1].co);
861                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
862                                         glVertex3fv(mv[mf->v2].co);
863                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
864                                         glVertex3fv(mv[mf->v3].co);
865                                         if(mf->v4) {
866                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
867                                                 glVertex3fv(mv[mf->v4].co);
868                                         }
869                                 } else {
870                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
871                                         glNormal3sv(mv[mf->v1].no);
872                                         glVertex3fv(mv[mf->v1].co);
873                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
874                                         glNormal3sv(mv[mf->v2].no);
875                                         glVertex3fv(mv[mf->v2].co);
876                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
877                                         glNormal3sv(mv[mf->v3].no);
878                                         glVertex3fv(mv[mf->v3].co);
879                                         if(mf->v4) {
880                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
881                                                 glNormal3sv(mv[mf->v4].no);
882                                                 glVertex3fv(mv[mf->v4].co);
883                                         }
884                                 }
885
886                                 glEnd();
887                         }
888                         
889                         if (nors) nors += 3;
890                 }
891         }
892         else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
893                 int prevstart = 0;
894                 GPU_vertex_setup(dm);
895                 GPU_normal_setup(dm);
896                 if( useColors && mc )
897                         GPU_color_setup(dm);
898                 if( !GPU_buffer_legacy(dm) ) {
899                         int tottri = dm->drawObject->tot_triangle_point/3;
900                         glShadeModel(GL_SMOOTH);
901                         
902                         if(tottri == 0) {
903                                 /* avoid buffer problems in following code */
904                         }
905                         if(setDrawOptions == NULL) {
906                                 /* just draw the entire face array */
907                                 glDrawArrays(GL_TRIANGLES, 0, (tottri) * 3);
908                         }
909                         else {
910                                 /* we need to check if the next material changes */
911                                 int next_actualFace= dm->drawObject->triangle_to_mface[0];
912                                 
913                                 for( i = 0; i < tottri; i++ ) {
914                                         //int actualFace = dm->drawObject->triangle_to_mface[i];
915                                         int actualFace = next_actualFace;
916                                         MFace *mface= mf + actualFace;
917                                         int drawSmooth= (mface->flag & ME_SMOOTH);
918                                         int draw = 1;
919                                         int flush = 0;
920
921                                         if(i != tottri-1)
922                                                 next_actualFace= dm->drawObject->triangle_to_mface[i+1];
923
924                                         orig= (index==NULL) ? actualFace : index[actualFace];
925
926                                         if(orig == ORIGINDEX_NONE)
927                                                 draw= setMaterial(mface->mat_nr + 1, NULL);
928                                         else if (setDrawOptions != NULL)
929                                                 draw= setDrawOptions(userData, orig, &drawSmooth);
930         
931                                         /* Goal is to draw as long of a contiguous triangle
932                                            array as possible, so draw when we hit either an
933                                            invisible triangle or at the end of the array */
934
935                                         /* flush buffer if current triangle isn't drawable or it's last triangle... */
936                                         flush= !draw || i == tottri - 1;
937
938                                         /* ... or when material setting is dissferent  */
939                                         flush|= mf[actualFace].mat_nr != mf[next_actualFace].mat_nr;
940
941                                         if(!flush && compareDrawOptions) {
942                                                 flush|= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
943                                         }
944
945                                         if(flush) {
946                                                 int first= prevstart*3;
947                                                 int count= (i-prevstart+(draw ? 1 : 0))*3; /* Add one to the length if we're drawing at the end of the array */
948
949                                                 if(count)
950                                                         glDrawArrays(GL_TRIANGLES, first, count);
951
952                                                 prevstart = i + 1;
953                                         }
954                                 }
955                         }
956
957                         glShadeModel(GL_FLAT);
958                 }
959                 GPU_buffer_unbind();
960         }
961 }
962
963 static void cdDM_drawMappedFacesTex(DerivedMesh *dm,
964                            int (*setDrawOptions)(void *userData, int index),
965                            int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
966                            void *userData)
967 {
968         cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData);
969 }
970
971 static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, MVert *mvert, int a, int index, int vert, int smoothnormal)
972 {
973         int b;
974
975         /* orco texture coordinates */
976         if(attribs->totorco) {
977                 if(attribs->orco.glTexco)
978                         glTexCoord3fv(attribs->orco.array[index]);
979                 else
980                         glVertexAttrib3fvARB(attribs->orco.glIndex, attribs->orco.array[index]);
981         }
982
983         /* uv texture coordinates */
984         for(b = 0; b < attribs->tottface; b++) {
985                 MTFace *tf = &attribs->tface[b].array[a];
986
987                 if(attribs->tface[b].glTexco)
988                         glTexCoord2fv(tf->uv[vert]);
989                 else
990                         glVertexAttrib2fvARB(attribs->tface[b].glIndex, tf->uv[vert]);
991         }
992
993         /* vertex colors */
994         for(b = 0; b < attribs->totmcol; b++) {
995                 MCol *cp = &attribs->mcol[b].array[a*4 + vert];
996                 GLubyte col[4];
997                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
998                 glVertexAttrib4ubvARB(attribs->mcol[b].glIndex, col);
999         }
1000
1001         /* tangent for normal mapping */
1002         if(attribs->tottang) {
1003                 float *tang = attribs->tang.array[a*4 + vert];
1004                 glVertexAttrib4fvARB(attribs->tang.glIndex, tang);
1005         }
1006
1007         /* vertex normal */
1008         if(smoothnormal)
1009                 glNormal3sv(mvert[index].no);
1010         
1011         /* vertex coordinate */
1012         glVertex3fv(mvert[index].co);
1013 }
1014
1015 static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
1016                            int (*setMaterial)(int, void *attribs),
1017                            int (*setDrawOptions)(void *userData, int index),
1018                            void *userData)
1019 {
1020         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
1021         GPUVertexAttribs gattribs;
1022         DMVertexAttribs attribs;
1023         MVert *mvert = cddm->mvert;
1024         MFace *mface = cddm->mface;
1025         /* MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */
1026         float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL);
1027         int a, b, dodraw, matnr, new_matnr;
1028         int orig, *index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1029
1030         cdDM_update_normals_from_pbvh(dm);
1031
1032         matnr = -1;
1033         dodraw = 0;
1034
1035         glShadeModel(GL_SMOOTH);
1036
1037         if( GPU_buffer_legacy(dm) || setDrawOptions != NULL ) {
1038                 DEBUG_VBO( "Using legacy code. cdDM_drawMappedFacesGLSL\n" );
1039                 memset(&attribs, 0, sizeof(attribs));
1040
1041                 glBegin(GL_QUADS);
1042
1043                 for(a = 0; a < dm->numTessFaceData; a++, mface++) {
1044                         const int smoothnormal = (mface->flag & ME_SMOOTH);
1045                         new_matnr = mface->mat_nr + 1;
1046
1047                         if(new_matnr != matnr) {
1048                                 glEnd();
1049
1050                                 dodraw = setMaterial(matnr = new_matnr, &gattribs);
1051                                 if(dodraw)
1052                                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1053
1054                                 glBegin(GL_QUADS);
1055                         }
1056
1057                         if(!dodraw) {
1058                                 continue;
1059                         }
1060                         else if(setDrawOptions) {
1061                                 orig = (index)? index[a]: a;
1062
1063                                 if(orig == ORIGINDEX_NONE) {
1064                                         /* since the material is set by setMaterial(), faces with no
1065                                          * origin can be assumed to be generated by a modifier */ 
1066                                         
1067                                         /* continue */
1068                                 }
1069                                 else if(!setDrawOptions(userData, orig))
1070                                         continue;
1071                         }
1072
1073                         if(!smoothnormal) {
1074                                 if(nors) {
1075                                         glNormal3fv(nors[a]);
1076                                 }
1077                                 else {
1078                                         /* TODO ideally a normal layer should always be available */
1079                                         float nor[3];
1080                                         if(mface->v4) {
1081                                                 normal_quad_v3( nor,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co);
1082                                         } else {
1083                                                 normal_tri_v3( nor,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co);
1084                                         }
1085                                         glNormal3fv(nor);
1086                                 }
1087                         }
1088
1089                         cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v1, 0, smoothnormal);
1090                         cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v2, 1, smoothnormal);
1091                         cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal);
1092
1093                         if(mface->v4)
1094                                 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v4, 3, smoothnormal);
1095                         else
1096                                 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal);
1097                 }
1098                 glEnd();
1099         }
1100         else {
1101                 GPUBuffer *buffer = NULL;
1102                 char *varray = NULL;
1103                 int numdata = 0, elementsize = 0, offset;
1104                 int start = 0, numfaces = 0 /* , prevdraw = 0 */ /* UNUSED */, curface = 0;
1105                 int i;
1106
1107                 MFace *mf = mface;
1108                 GPUAttrib datatypes[GPU_MAX_ATTRIB]; /* TODO, messing up when switching materials many times - [#21056]*/
1109                 memset(&attribs, 0, sizeof(attribs));
1110
1111                 GPU_vertex_setup(dm);
1112                 GPU_normal_setup(dm);
1113
1114                 if( !GPU_buffer_legacy(dm) ) {
1115                         for( i = 0; i < dm->drawObject->tot_triangle_point/3; i++ ) {
1116
1117                                 a = dm->drawObject->triangle_to_mface[i];
1118
1119                                 mface = mf + a;
1120                                 new_matnr = mface->mat_nr + 1;
1121
1122                                 if(new_matnr != matnr ) {
1123                                         numfaces = curface - start;
1124                                         if( numfaces > 0 ) {
1125
1126                                                 if( dodraw ) {
1127
1128                                                         if( numdata != 0 ) {
1129
1130                                                                 GPU_buffer_unlock(buffer);
1131
1132                                                                 GPU_interleaved_attrib_setup(buffer,datatypes,numdata);
1133                                                         }
1134
1135                                                         glDrawArrays(GL_TRIANGLES,start*3,numfaces*3);
1136
1137                                                         if( numdata != 0 ) {
1138
1139                                                                 GPU_buffer_free(buffer);
1140
1141                                                                 buffer = NULL;
1142                                                         }
1143
1144                                                 }
1145                                         }
1146                                         numdata = 0;
1147                                         start = curface;
1148                                         /* prevdraw = dodraw; */ /* UNUSED */
1149                                         dodraw = setMaterial(matnr = new_matnr, &gattribs);
1150                                         if(dodraw) {
1151                                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1152
1153                                                 if(attribs.totorco) {
1154                                                         datatypes[numdata].index = attribs.orco.glIndex;
1155                                                         datatypes[numdata].size = 3;
1156                                                         datatypes[numdata].type = GL_FLOAT;
1157                                                         numdata++;
1158                                                 }
1159                                                 for(b = 0; b < attribs.tottface; b++) {
1160                                                         datatypes[numdata].index = attribs.tface[b].glIndex;
1161                                                         datatypes[numdata].size = 2;
1162                                                         datatypes[numdata].type = GL_FLOAT;
1163                                                         numdata++;
1164                                                 }       
1165                                                 for(b = 0; b < attribs.totmcol; b++) {
1166                                                         datatypes[numdata].index = attribs.mcol[b].glIndex;
1167                                                         datatypes[numdata].size = 4;
1168                                                         datatypes[numdata].type = GL_UNSIGNED_BYTE;
1169                                                         numdata++;
1170                                                 }       
1171                                                 if(attribs.tottang) {
1172                                                         datatypes[numdata].index = attribs.tang.glIndex;
1173                                                         datatypes[numdata].size = 4;
1174                                                         datatypes[numdata].type = GL_FLOAT;
1175                                                         numdata++;
1176                                                 }
1177                                                 if( numdata != 0 ) {
1178                                                         elementsize = GPU_attrib_element_size( datatypes, numdata );
1179                                                         buffer = GPU_buffer_alloc( elementsize*dm->drawObject->tot_triangle_point);
1180                                                         if( buffer == NULL ) {
1181                                                                 GPU_buffer_unbind();
1182                                                                 dm->drawObject->legacy = 1;
1183                                                                 return;
1184                                                         }
1185                                                         varray = GPU_buffer_lock_stream(buffer);
1186                                                         if( varray == NULL ) {
1187                                                                 GPU_buffer_unbind();
1188                                                                 GPU_buffer_free(buffer);
1189                                                                 dm->drawObject->legacy = 1;
1190                                                                 return;
1191                                                         }
1192                                                 }
1193                                                 else {
1194                                                         /* if the buffer was set, dont use it again.
1195                                                          * prevdraw was assumed true but didnt run so set to false - [#21036] */
1196                                                         /* prevdraw= 0; */ /* UNUSED */
1197                                                         buffer= NULL;
1198                                                 }
1199                                         }
1200                                 }
1201
1202                                 if(dodraw && numdata != 0 ) {
1203                                         offset = 0;
1204                                         if(attribs.totorco) {
1205                                                 copy_v3_v3((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v1]);
1206                                                 copy_v3_v3((float *)&varray[elementsize*curface*3+elementsize],(float *)attribs.orco.array[mface->v2]);
1207                                                 copy_v3_v3((float *)&varray[elementsize*curface*3+elementsize*2],(float *)attribs.orco.array[mface->v3]);
1208                                                 offset += sizeof(float)*3;
1209                                         }
1210                                         for(b = 0; b < attribs.tottface; b++) {
1211                                                 MTFace *tf = &attribs.tface[b].array[a];
1212                                                 copy_v2_v2((float *)&varray[elementsize*curface*3+offset],tf->uv[0]);
1213                                                 copy_v2_v2((float *)&varray[elementsize*curface*3+offset+elementsize],tf->uv[1]);
1214
1215                                                 copy_v2_v2((float *)&varray[elementsize*curface*3+offset+elementsize*2],tf->uv[2]);
1216                                                 offset += sizeof(float)*2;
1217                                         }
1218                                         for(b = 0; b < attribs.totmcol; b++) {
1219                                                 MCol *cp = &attribs.mcol[b].array[a*4 + 0];
1220                                                 GLubyte col[4];
1221                                                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1222                                                 copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset], (char *)col);
1223                                                 cp = &attribs.mcol[b].array[a*4 + 1];
1224                                                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1225                                                 copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset+elementsize], (char *)col);
1226                                                 cp = &attribs.mcol[b].array[a*4 + 2];
1227                                                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1228                                                 copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset+elementsize*2], (char *)col);
1229                                                 offset += sizeof(unsigned char)*4;
1230                                         }       
1231                                         if(attribs.tottang) {
1232                                                 float *tang = attribs.tang.array[a*4 + 0];
1233                                                 copy_v4_v4((float *)&varray[elementsize*curface*3+offset], tang);
1234                                                 tang = attribs.tang.array[a*4 + 1];
1235                                                 copy_v4_v4((float *)&varray[elementsize*curface*3+offset+elementsize], tang);
1236                                                 tang = attribs.tang.array[a*4 + 2];
1237                                                 copy_v4_v4((float *)&varray[elementsize*curface*3+offset+elementsize*2], tang);
1238                                                 offset += sizeof(float)*4;
1239                                         }
1240                                         (void)offset;
1241                                 }
1242                                 curface++;
1243                                 if(mface->v4) {
1244                                         if(dodraw && numdata != 0 ) {
1245                                                 offset = 0;
1246                                                 if(attribs.totorco) {
1247                                                         copy_v3_v3((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v3]);
1248                                                         copy_v3_v3((float *)&varray[elementsize*curface*3+elementsize],(float *)attribs.orco.array[mface->v4]);
1249                                                         copy_v3_v3((float *)&varray[elementsize*curface*3+elementsize*2],(float *)attribs.orco.array[mface->v1]);
1250                                                         offset += sizeof(float)*3;
1251                                                 }
1252                                                 for(b = 0; b < attribs.tottface; b++) {
1253                                                         MTFace *tf = &attribs.tface[b].array[a];
1254                                                         copy_v2_v2((float *)&varray[elementsize*curface*3+offset],tf->uv[2]);
1255                                                         copy_v2_v2((float *)&varray[elementsize*curface*3+offset+elementsize],tf->uv[3]);
1256                                                         copy_v2_v2((float *)&varray[elementsize*curface*3+offset+elementsize*2],tf->uv[0]);
1257                                                         offset += sizeof(float)*2;
1258                                                 }
1259                                                 for(b = 0; b < attribs.totmcol; b++) {
1260                                                         MCol *cp = &attribs.mcol[b].array[a*4 + 2];
1261                                                         GLubyte col[4];
1262                                                         col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1263                                                         copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset], (char *)col);
1264                                                         cp = &attribs.mcol[b].array[a*4 + 3];
1265                                                         col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1266                                                         copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset+elementsize], (char *)col);
1267                                                         cp = &attribs.mcol[b].array[a*4 + 0];
1268                                                         col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1269                                                         copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset+elementsize*2], (char *)col);
1270                                                         offset += sizeof(unsigned char)*4;
1271                                                 }       
1272                                                 if(attribs.tottang) {
1273                                                         float *tang = attribs.tang.array[a*4 + 2];
1274                                                         copy_v4_v4((float *)&varray[elementsize*curface*3+offset], tang);
1275                                                         tang = attribs.tang.array[a*4 + 3];
1276                                                         copy_v4_v4((float *)&varray[elementsize*curface*3+offset+elementsize], tang);
1277                                                         tang = attribs.tang.array[a*4 + 0];
1278                                                         copy_v4_v4((float *)&varray[elementsize*curface*3+offset+elementsize*2], tang);
1279                                                         offset += sizeof(float)*4;
1280                                                 }
1281                                                 (void)offset;
1282                                         }
1283                                         curface++;
1284                                         i++;
1285                                 }
1286                         }
1287                         numfaces = curface - start;
1288                         if( numfaces > 0 ) {
1289                                 if( dodraw ) {
1290                                         if( numdata != 0 ) {
1291                                                 GPU_buffer_unlock(buffer);
1292                                                 GPU_interleaved_attrib_setup(buffer,datatypes,numdata);
1293                                         }
1294                                         glDrawArrays(GL_TRIANGLES,start*3,(curface-start)*3);
1295                                 }
1296                         }
1297                         GPU_buffer_unbind();
1298                 }
1299                 GPU_buffer_free(buffer);
1300         }
1301
1302         glShadeModel(GL_FLAT);
1303 }
1304
1305 static void cdDM_drawFacesGLSL(DerivedMesh *dm,int (*setMaterial)(int, void *attribs))
1306 {
1307         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1308 }
1309
1310 static void cdDM_drawMappedFacesMat(DerivedMesh *dm,
1311         void (*setMaterial)(void *userData, int, void *attribs),
1312         int (*setFace)(void *userData, int index), void *userData)
1313 {
1314         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
1315         GPUVertexAttribs gattribs;
1316         DMVertexAttribs attribs;
1317         MVert *mvert = cddm->mvert;
1318         MFace *mf = cddm->mface;
1319         float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL);
1320         int a, matnr, new_matnr;
1321         int orig, *index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1322
1323         cdDM_update_normals_from_pbvh(dm);
1324
1325         matnr = -1;
1326
1327         glShadeModel(GL_SMOOTH);
1328
1329         memset(&attribs, 0, sizeof(attribs));
1330
1331         glBegin(GL_QUADS);
1332
1333         for(a = 0; a < dm->numTessFaceData; a++, mf++) {
1334                 const int smoothnormal = (mf->flag & ME_SMOOTH);
1335
1336                 /* material */
1337                 new_matnr = mf->mat_nr + 1;
1338
1339                 if(new_matnr != matnr) {
1340                         glEnd();
1341
1342                         setMaterial(userData, matnr = new_matnr, &gattribs);
1343                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1344
1345                         glBegin(GL_QUADS);
1346                 }
1347
1348                 /* skipping faces */
1349                 if(setFace) {
1350                         orig = (index)? index[a]: a;
1351
1352                         if(orig != ORIGINDEX_NONE && !setFace(userData, orig))
1353                                 continue;
1354                 }
1355
1356                 /* smooth normal */
1357                 if(!smoothnormal) {
1358                         if(nors) {
1359                                 glNormal3fv(nors[a]);
1360                         }
1361                         else {
1362                                 /* TODO ideally a normal layer should always be available */
1363                                 float nor[3];
1364
1365                                 if(mf->v4)
1366                                         normal_quad_v3( nor,mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co);
1367                                 else
1368                                         normal_tri_v3( nor,mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co);
1369
1370                                 glNormal3fv(nor);
1371                         }
1372                 }
1373
1374                 /* vertices */
1375                 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v1, 0, smoothnormal);
1376                 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v2, 1, smoothnormal);
1377                 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal);
1378
1379                 if(mf->v4)
1380                         cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v4, 3, smoothnormal);
1381                 else
1382                         cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal);
1383         }
1384         glEnd();
1385
1386         glShadeModel(GL_FLAT);
1387 }
1388
1389 static void cdDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
1390 {
1391         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
1392         MVert *vert = cddm->mvert;
1393         MEdge *edge = cddm->medge;
1394         int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1395
1396         glBegin(GL_LINES);
1397         for(i = 0; i < dm->numEdgeData; i++, edge++) {
1398                 if(index) {
1399                         orig = *index++;
1400                         if(setDrawOptions && orig == ORIGINDEX_NONE) continue;
1401                 }
1402                 else
1403                         orig = i;
1404
1405                 if(!setDrawOptions || setDrawOptions(userData, orig)) {
1406                         glVertex3fv(vert[edge->v1].co);
1407                         glVertex3fv(vert[edge->v2].co);
1408                 }
1409         }
1410         glEnd();
1411 }
1412
1413 static void cdDM_foreachMappedVert(
1414                                                    DerivedMesh *dm,
1415                                                    void (*func)(void *userData, int index, float *co,
1416                                                                                 float *no_f, short *no_s),
1417                                                    void *userData)
1418 {
1419         MVert *mv = CDDM_get_verts(dm);
1420         int i, orig, *index = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
1421
1422         for(i = 0; i < dm->numVertData; i++, mv++) {
1423                 if(index) {
1424                         orig = *index++;
1425                         if(orig == ORIGINDEX_NONE) continue;
1426                         func(userData, orig, mv->co, NULL, mv->no);
1427                 }
1428                 else
1429                         func(userData, i, mv->co, NULL, mv->no);
1430         }
1431 }
1432
1433 static void cdDM_foreachMappedEdge(
1434                                                    DerivedMesh *dm,
1435                                                    void (*func)(void *userData, int index,
1436                                                                                 float *v0co, float *v1co),
1437                                                    void *userData)
1438 {
1439         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
1440         MVert *mv = cddm->mvert;
1441         MEdge *med = cddm->medge;
1442         int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1443
1444         for(i = 0; i < dm->numEdgeData; i++, med++) {
1445                 if (index) {
1446                         orig = *index++;
1447                         if(orig == ORIGINDEX_NONE) continue;
1448                         func(userData, orig, mv[med->v1].co, mv[med->v2].co);
1449                 }
1450                 else
1451                         func(userData, i, mv[med->v1].co, mv[med->v2].co);
1452         }
1453 }
1454
1455 static void cdDM_foreachMappedFaceCenter(
1456                                                    DerivedMesh *dm,
1457                                                    void (*func)(void *userData, int index,
1458                                                                                 float *cent, float *no),
1459                                                    void *userData)
1460 {
1461         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1462         MVert *mv = cddm->mvert;
1463         MPoly *mf = cddm->mpoly;
1464         MLoop *ml = cddm->mloop;
1465         int i, j, orig, *index;
1466
1467         index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
1468         mf = cddm->mpoly;
1469         for(i = 0; i < dm->numPolyData; i++, mf++) {
1470                 float cent[3];
1471                 float no[3];
1472
1473                 if (index) {
1474                         orig = *index++;
1475                         if(orig == ORIGINDEX_NONE) continue;
1476                 }
1477                 else
1478                         orig = i;
1479                 
1480                 ml = &cddm->mloop[mf->loopstart];
1481                 cent[0] = cent[1] = cent[2] = 0.0f;
1482                 for (j=0; j<mf->totloop; j++, ml++) {
1483                         add_v3_v3v3(cent, cent, mv[ml->v].co);
1484                 }
1485                 mul_v3_fl(cent, 1.0f / (float)j);
1486
1487                 ml = &cddm->mloop[mf->loopstart];
1488                 if (j > 3) {
1489                         normal_quad_v3(no, mv[ml->v].co, mv[(ml+1)->v].co,
1490                                        mv[(ml+2)->v].co, mv[(ml+3)->v].co);
1491                 } else {
1492                         normal_tri_v3(no, mv[ml->v].co, mv[(ml+1)->v].co, mv[(ml+2)->v].co);
1493                 }
1494
1495                 func(userData, orig, cent, no);
1496         }
1497
1498 }
1499
1500 void CDDM_recalc_tessellation_ex(DerivedMesh *dm, const int do_face_nor_cpy)
1501 {
1502         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1503
1504         dm->numTessFaceData = mesh_recalcTessellation(&dm->faceData, &dm->loopData, &dm->polyData,
1505                                                      cddm->mvert,
1506                                                      dm->numTessFaceData, dm->numLoopData, dm->numPolyData,
1507                                                      do_face_nor_cpy);
1508
1509         if (!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX)) {
1510                 int *polyIndex = CustomData_get_layer(&dm->faceData, CD_POLYINDEX);
1511                 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_REFERENCE, polyIndex, dm->numTessFaceData);
1512         }
1513
1514         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1515
1516         /* Tessellation recreated faceData, and the active layer indices need to get re-propagated
1517            from loops and polys to faces */
1518         CustomData_bmesh_update_active_layers(&dm->faceData, &dm->polyData, &dm->loopData);
1519 }
1520
1521 void CDDM_recalc_tessellation(DerivedMesh *dm)
1522 {
1523         CDDM_recalc_tessellation_ex(dm, TRUE);
1524 }
1525
1526 static void cdDM_free_internal(CDDerivedMesh *cddm)
1527 {
1528         if(cddm->fmap) MEM_freeN(cddm->fmap);
1529         if(cddm->fmap_mem) MEM_freeN(cddm->fmap_mem);
1530
1531         if(cddm->pmap) MEM_freeN(cddm->pmap);
1532         if(cddm->pmap_mem) MEM_freeN(cddm->pmap_mem);
1533 }
1534
1535 static void cdDM_release(DerivedMesh *dm)
1536 {
1537         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1538
1539         if (DM_release(dm)) {
1540                 cdDM_free_internal(cddm);
1541                 MEM_freeN(cddm);
1542         }
1543 }
1544
1545 int CDDM_Check(DerivedMesh *dm)
1546 {
1547         return dm && dm->getMinMax == cdDM_getMinMax;
1548 }
1549
1550 /**************** CDDM interface functions ****************/
1551 static CDDerivedMesh *cdDM_create(const char *desc)
1552 {
1553         CDDerivedMesh *cddm;
1554         DerivedMesh *dm;
1555
1556         cddm = MEM_callocN(sizeof(*cddm), desc);
1557         dm = &cddm->dm;
1558
1559         dm->getMinMax = cdDM_getMinMax;
1560
1561         dm->getNumVerts = cdDM_getNumVerts;
1562         dm->getNumEdges = cdDM_getNumEdges;
1563         dm->getNumTessFaces = cdDM_getNumTessFaces;
1564         dm->getNumLoops = cdDM_getNumLoops;
1565         dm->getNumPolys = cdDM_getNumPolys;
1566
1567         dm->getVert = cdDM_getVert;
1568         dm->getEdge = cdDM_getEdge;
1569         dm->getTessFace = cdDM_getTessFace;
1570
1571         dm->copyVertArray = cdDM_copyVertArray;
1572         dm->copyEdgeArray = cdDM_copyEdgeArray;
1573         dm->copyTessFaceArray = cdDM_copyTessFaceArray;
1574         dm->copyLoopArray = cdDM_copyLoopArray;
1575         dm->copyPolyArray = cdDM_copyPolyArray;
1576
1577         dm->getVertData = DM_get_vert_data;
1578         dm->getEdgeData = DM_get_edge_data;
1579         dm->getTessFaceData = DM_get_tessface_data;
1580         dm->getVertDataArray = DM_get_vert_data_layer;
1581         dm->getEdgeDataArray = DM_get_edge_data_layer;
1582         dm->getTessFaceDataArray = DM_get_tessface_data_layer;
1583
1584         dm->calcNormals = CDDM_calc_normals_mapping;
1585         dm->recalcTessellation = CDDM_recalc_tessellation;
1586
1587         dm->getVertCos = cdDM_getVertCos;
1588         dm->getVertCo = cdDM_getVertCo;
1589         dm->getVertNo = cdDM_getVertNo;
1590
1591         dm->getPBVH = cdDM_getPBVH;
1592         dm->getPolyMap = cdDM_getPolyMap;
1593
1594         dm->drawVerts = cdDM_drawVerts;
1595
1596         dm->drawUVEdges = cdDM_drawUVEdges;
1597         dm->drawEdges = cdDM_drawEdges;
1598         dm->drawLooseEdges = cdDM_drawLooseEdges;
1599         dm->drawMappedEdges = cdDM_drawMappedEdges;
1600
1601         dm->drawFacesSolid = cdDM_drawFacesSolid;
1602         dm->drawFacesTex = cdDM_drawFacesTex;
1603         dm->drawFacesGLSL = cdDM_drawFacesGLSL;
1604         dm->drawMappedFaces = cdDM_drawMappedFaces;
1605         dm->drawMappedFacesTex = cdDM_drawMappedFacesTex;
1606         dm->drawMappedFacesGLSL = cdDM_drawMappedFacesGLSL;
1607         dm->drawMappedFacesMat = cdDM_drawMappedFacesMat;
1608
1609         dm->foreachMappedVert = cdDM_foreachMappedVert;
1610         dm->foreachMappedEdge = cdDM_foreachMappedEdge;
1611         dm->foreachMappedFaceCenter = cdDM_foreachMappedFaceCenter;
1612
1613         dm->release = cdDM_release;
1614
1615         return cddm;
1616 }
1617
1618 DerivedMesh *CDDM_new(int numVerts, int numEdges, int numTessFaces, int numLoops, int numPolys)
1619 {
1620         CDDerivedMesh *cddm = cdDM_create("CDDM_new dm");
1621         DerivedMesh *dm = &cddm->dm;
1622
1623         DM_init(dm, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces, numLoops, numPolys);
1624
1625         CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
1626         CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
1627         CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numTessFaces);
1628         CustomData_add_layer(&dm->faceData, CD_POLYINDEX, CD_CALLOC, NULL, numTessFaces);
1629         CustomData_add_layer(&dm->polyData, CD_ORIGINDEX, CD_CALLOC, NULL, numPolys);
1630
1631         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
1632         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
1633         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numTessFaces);
1634         CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL, numLoops);
1635         CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL, numPolys);
1636
1637         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1638         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1639         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1640         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
1641         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
1642
1643         return dm;
1644 }
1645
1646 DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob))
1647 {
1648         CDDerivedMesh *cddm = cdDM_create("CDDM_from_mesh dm");
1649         DerivedMesh *dm = &cddm->dm;
1650         CustomDataMask mask = CD_MASK_MESH & (~CD_MASK_MDISPS);
1651         int alloctype;
1652         int *polyindex = NULL;
1653
1654         /* this does a referenced copy, with an exception for fluidsim */
1655
1656         DM_init(dm, DM_TYPE_CDDM, mesh->totvert, mesh->totedge, mesh->totface,
1657                     mesh->totloop, mesh->totpoly);
1658
1659         dm->deformedOnly = 1;
1660
1661         alloctype= CD_REFERENCE;
1662
1663         CustomData_merge(&mesh->vdata, &dm->vertData, mask, alloctype,
1664                                          mesh->totvert);
1665         CustomData_merge(&mesh->edata, &dm->edgeData, mask, alloctype,
1666                                          mesh->totedge);
1667         CustomData_merge(&mesh->fdata, &dm->faceData, mask|CD_MASK_POLYINDEX, alloctype,
1668                                          mesh->totface);
1669         CustomData_merge(&mesh->ldata, &dm->loopData, mask, alloctype,
1670                          mesh->totloop);
1671         CustomData_merge(&mesh->pdata, &dm->polyData, mask, alloctype,
1672                          mesh->totpoly);
1673
1674         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1675         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1676         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
1677         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
1678         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1679
1680         /* commented since even when CD_POLYINDEX was first added this line fails
1681          * on the default cube, (after editmode toggle too) - campbell */
1682 #if 0
1683         BLI_assert(CustomData_has_layer(&cddm->dm.faceData, CD_POLYINDEX));
1684 #endif
1685
1686         polyindex = CustomData_get_layer(&dm->faceData, CD_POLYINDEX);
1687         if (!CustomData_has_layer(&cddm->dm.faceData, CD_ORIGINDEX)) {
1688                 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_REFERENCE, polyindex, mesh->totface);
1689         }
1690
1691         return dm;
1692 }
1693
1694 DerivedMesh *CDDM_from_curve(Object *ob)
1695 {
1696         return CDDM_from_curve_customDB(ob, &ob->disp);
1697 }
1698
1699 DerivedMesh *CDDM_from_curve_customDB(Object *ob, ListBase *dispbase)
1700 {
1701         DerivedMesh *dm;
1702         CDDerivedMesh *cddm;
1703         MVert *allvert;
1704         MEdge *alledge;
1705         MLoop *allloop;
1706         MPoly *allpoly;
1707         int totvert, totedge, totloop, totpoly;
1708
1709         if (nurbs_to_mdata_customdb(ob, dispbase, &allvert, &totvert, &alledge,
1710                 &totedge, &allloop, &allpoly, &totloop, &totpoly) != 0) {
1711                 /* Error initializing mdata. This often happens when curve is empty */
1712                 return CDDM_new(0, 0, 0, 0, 0);
1713         }
1714
1715         dm = CDDM_new(totvert, totedge, 0, totloop, totpoly);
1716         dm->deformedOnly = 1;
1717
1718         cddm = (CDDerivedMesh*)dm;
1719
1720         memcpy(cddm->mvert, allvert, totvert*sizeof(MVert));
1721         memcpy(cddm->medge, alledge, totedge*sizeof(MEdge));
1722         memcpy(cddm->mloop, allloop, totloop*sizeof(MLoop));
1723         memcpy(cddm->mpoly, allpoly, totpoly*sizeof(MPoly));
1724
1725         MEM_freeN(allvert);
1726         MEM_freeN(alledge);
1727         MEM_freeN(allloop);
1728         MEM_freeN(allpoly);
1729
1730         CDDM_calc_edges(dm);
1731
1732         return dm;
1733 }
1734
1735 static void loops_to_customdata_corners(BMesh *bm, CustomData *facedata,
1736                                           int cdindex, BMLoop *l3[3],
1737                                           int numCol, int numTex)
1738 {
1739         BMLoop *l;
1740         BMFace *f = l3[0]->f;
1741         MTFace *texface;
1742         MTexPoly *texpoly;
1743         MCol *mcol;
1744         MLoopCol *mloopcol;
1745         MLoopUV *mloopuv;
1746         int i, j, hasWCol = CustomData_has_layer(&bm->ldata, CD_WEIGHT_MLOOPCOL);
1747
1748         for (i=0; i < numTex; i++) {
1749                 texface = CustomData_get_n(facedata, CD_MTFACE, cdindex, i);
1750                 texpoly = CustomData_bmesh_get_n(&bm->pdata, f->head.data, CD_MTEXPOLY, i);
1751                 
1752                 ME_MTEXFACE_CPY(texface, texpoly);
1753         
1754                 for (j=0; j<3; j++) {
1755                         l = l3[j];
1756                         mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPUV, i);
1757                         copy_v2_v2(texface->uv[j], mloopuv->uv);
1758                 }
1759         }
1760
1761         for (i=0; i < numCol; i++) {
1762                 mcol = CustomData_get_n(facedata, CD_MCOL, cdindex, i);
1763                 
1764                 for (j=0; j<3; j++) {
1765                         l = l3[j];
1766                         mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPCOL, i);
1767                         mcol[j].r = mloopcol->r;
1768                         mcol[j].g = mloopcol->g;
1769                         mcol[j].b = mloopcol->b;
1770                         mcol[j].a = mloopcol->a;
1771                 }
1772         }
1773
1774         if (hasWCol) {
1775                 mcol = CustomData_get(facedata, cdindex, CD_WEIGHT_MCOL);
1776
1777                 for (j=0; j<3; j++) {
1778                         l = l3[j];
1779                         mloopcol = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_WEIGHT_MLOOPCOL);
1780                         mcol[j].r = mloopcol->r;
1781                         mcol[j].g = mloopcol->g;
1782                         mcol[j].b = mloopcol->b;
1783                         mcol[j].a = mloopcol->a;
1784                 }
1785         }
1786 }
1787
1788 DerivedMesh *CDDM_from_BMEditMesh(BMEditMesh *em, Mesh *UNUSED(me), int use_mdisps, int use_tessface)
1789 {
1790         BMesh *bm = em->bm;
1791
1792         DerivedMesh *dm = CDDM_new(bm->totvert,
1793                                    bm->totedge,
1794                                    use_tessface ? em->tottri : 0,
1795                                    bm->totloop,
1796                                    bm->totface);
1797
1798         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1799         BMIter iter, liter;
1800         BMVert *eve;
1801         BMEdge *eed;
1802         BMFace *efa;
1803         MVert *mvert = cddm->mvert;
1804         MEdge *medge = cddm->medge;
1805         MFace *mface = cddm->mface;
1806         MLoop *mloop = cddm->mloop;
1807         MPoly *mpoly = cddm->mpoly;
1808         int numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL);
1809         int numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
1810         int *index, add_orig;
1811         int has_crease, has_edge_bweight, has_vert_bweight;
1812         CustomDataMask mask;
1813         unsigned int i, j;
1814         
1815         has_edge_bweight = CustomData_has_layer(&bm->edata, CD_BWEIGHT);
1816         has_vert_bweight = CustomData_has_layer(&bm->vdata, CD_BWEIGHT);
1817         has_crease = CustomData_has_layer(&bm->edata, CD_CREASE);
1818         
1819         dm->deformedOnly = 1;
1820         
1821         /*don't add origindex layer if one already exists*/
1822         add_orig = !CustomData_has_layer(&bm->pdata, CD_ORIGINDEX);
1823
1824         mask = use_mdisps ? CD_MASK_DERIVEDMESH|CD_MASK_MDISPS : CD_MASK_DERIVEDMESH;
1825         
1826         /*don't process shapekeys, we only feed them through the modifier stack as needed,
1827           e.g. for applying modifiers or the like*/
1828         mask &= ~CD_MASK_SHAPEKEY;
1829         CustomData_merge(&bm->vdata, &dm->vertData, mask,
1830                          CD_CALLOC, dm->numVertData);
1831         CustomData_merge(&bm->edata, &dm->edgeData, mask,
1832                          CD_CALLOC, dm->numEdgeData);
1833         CustomData_merge(&bm->ldata, &dm->loopData, mask,
1834                          CD_CALLOC, dm->numLoopData);
1835         CustomData_merge(&bm->pdata, &dm->polyData, mask,
1836                          CD_CALLOC, dm->numPolyData);
1837         
1838         /*add tessellation mface layers*/
1839         if (use_tessface) {
1840                 CustomData_from_bmeshpoly(&dm->faceData, &dm->polyData, &dm->loopData, em->tottri);
1841         }
1842
1843         index = dm->getVertDataArray(dm, CD_ORIGINDEX);
1844
1845         eve = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL);
1846         for (i=0; eve; eve=BM_iter_step(&iter), i++, index++) {
1847                 MVert *mv = &mvert[i];
1848
1849                 copy_v3_v3(mv->co, eve->co);
1850
1851                 BM_elem_index_set(eve, i); /* set_inline */
1852
1853                 normal_float_to_short_v3(mv->no, eve->no);
1854
1855                 mv->flag = BM_vert_flag_to_mflag(eve);
1856
1857                 if (has_vert_bweight)
1858                         mv->bweight = (unsigned char)(BM_elem_float_data_get(&bm->vdata, eve, CD_BWEIGHT)*255.0f);
1859
1860                 if (add_orig) *index = i;
1861
1862                 CustomData_from_bmesh_block(&bm->vdata, &dm->vertData, eve->head.data, i);
1863         }
1864         bm->elem_index_dirty &= ~BM_VERT;
1865
1866         index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
1867         eed = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, NULL);
1868         for (i=0; eed; eed=BM_iter_step(&iter), i++, index++) {
1869                 MEdge *med = &medge[i];
1870
1871                 BM_elem_index_set(eed, i); /* set_inline */
1872
1873                 med->v1 = BM_elem_index_get(eed->v1);
1874                 med->v2 = BM_elem_index_get(eed->v2);
1875
1876                 if (has_crease)
1877                         med->crease = (unsigned char)(BM_elem_float_data_get(&bm->edata, eed, CD_CREASE)*255.0f);
1878                 if (has_edge_bweight)
1879                         med->bweight = (unsigned char)(BM_elem_float_data_get(&bm->edata, eed, CD_BWEIGHT)*255.0f);
1880                 
1881                 med->flag = BM_edge_flag_to_mflag(eed);
1882
1883                 CustomData_from_bmesh_block(&bm->edata, &dm->edgeData, eed->head.data, i);
1884                 if (add_orig) *index = i;
1885         }
1886         bm->elem_index_dirty &= ~BM_EDGE;
1887
1888         /* avoid this where possiblem, takes extra memory */
1889         if (use_tessface) {
1890                 int *polyindex;
1891
1892                 BM_mesh_elem_index_ensure(bm, BM_FACE);
1893
1894                 polyindex = dm->getTessFaceDataArray(dm, CD_POLYINDEX);
1895                 index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1896                 for(i = 0; i < dm->numTessFaceData; i++, index++, polyindex++) {
1897                         MFace *mf = &mface[i];
1898                         BMLoop **l = em->looptris[i];
1899                         efa = l[0]->f;
1900
1901                         mf->v1 = BM_elem_index_get(l[0]->v);
1902                         mf->v2 = BM_elem_index_get(l[1]->v);
1903                         mf->v3 = BM_elem_index_get(l[2]->v);
1904                         mf->v4 = 0;
1905                         mf->mat_nr = efa->mat_nr;
1906                         mf->flag = BM_face_flag_to_mflag(efa);
1907
1908                         *index = add_orig ? BM_elem_index_get(efa) : *(int*)CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_ORIGINDEX);
1909                         *polyindex = BM_elem_index_get(efa);
1910
1911                         loops_to_customdata_corners(bm, &dm->faceData, i, l, numCol, numTex);
1912                         test_index_face(mf, &dm->faceData, i, 3);
1913                 }
1914         }
1915         
1916         index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
1917         j = 0;
1918         efa = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, NULL);
1919         for (i=0; efa; i++, efa=BM_iter_step(&iter), index++) {
1920                 BMLoop *l;
1921                 MPoly *mp = &mpoly[i];
1922
1923                 BM_elem_index_set(efa, i); /* set_inline */
1924
1925                 mp->totloop = efa->len;
1926                 mp->flag = BM_face_flag_to_mflag(efa);
1927                 mp->loopstart = j;
1928                 mp->mat_nr = efa->mat_nr;
1929                 
1930                 BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, efa) {
1931                         mloop->v = BM_elem_index_get(l->v);
1932                         mloop->e = BM_elem_index_get(l->e);
1933                         CustomData_from_bmesh_block(&bm->ldata, &dm->loopData, l->head.data, j);
1934
1935                         j++;
1936                         mloop++;
1937                 }
1938
1939                 CustomData_from_bmesh_block(&bm->pdata, &dm->polyData, efa->head.data, i);
1940
1941                 if (add_orig) *index = i;
1942         }
1943         bm->elem_index_dirty &= ~BM_FACE;
1944
1945         return dm;
1946 }
1947
1948 static DerivedMesh *cddm_copy_ex(DerivedMesh *source, int faces_from_tessfaces)
1949 {
1950         CDDerivedMesh *cddm = cdDM_create("CDDM_copy cddm");
1951         DerivedMesh *dm = &cddm->dm;
1952         int numVerts = source->numVertData;
1953         int numEdges = source->numEdgeData;
1954         int numTessFaces = source->numTessFaceData;
1955         int numLoops = source->numLoopData;
1956         int numPolys = source->numPolyData;
1957
1958         /* ensure these are created if they are made on demand */
1959         source->getVertDataArray(source, CD_ORIGINDEX);
1960         source->getEdgeDataArray(source, CD_ORIGINDEX);
1961         source->getTessFaceDataArray(source, CD_ORIGINDEX);
1962
1963         /* this initializes dm, and copies all non mvert/medge/mface layers */
1964         DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces,
1965                 numLoops, numPolys);
1966         dm->deformedOnly = source->deformedOnly;
1967
1968         CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts);
1969         CustomData_copy_data(&source->edgeData, &dm->edgeData, 0, 0, numEdges);
1970         CustomData_copy_data(&source->faceData, &dm->faceData, 0, 0, numTessFaces);
1971
1972         /* now add mvert/medge/mface layers */
1973         cddm->mvert = source->dupVertArray(source);
1974         cddm->medge = source->dupEdgeArray(source);
1975         cddm->mface = source->dupTessFaceArray(source);
1976
1977         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, cddm->mvert, numVerts);
1978         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, cddm->medge, numEdges);
1979         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, cddm->mface, numTessFaces);
1980         
1981         if (!faces_from_tessfaces)
1982                 DM_DupPolys(source, dm);
1983         else
1984                 CDDM_tessfaces_to_faces(dm);
1985
1986         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
1987         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
1988
1989         /* any callers that need tessface data can calculate it - campbell */
1990 #if 0
1991         /* BMESH_TODO: Find out why this is necessary (or else find a way to remove
1992            it). If it is necessary, add a comment explaining why. */
1993         CDDM_recalc_tessellation((DerivedMesh *)cddm);
1994 #endif
1995
1996         return dm;
1997 }
1998
1999 DerivedMesh *CDDM_copy(DerivedMesh *source)
2000 {
2001         return cddm_copy_ex(source, 0);
2002 }
2003
2004 DerivedMesh *CDDM_copy_from_tessface(DerivedMesh *source)
2005 {
2006         return cddm_copy_ex(source, 1);
2007 }
2008
2009 /* note, the CD_ORIGINDEX layers are all 0, so if there is a direct
2010  * relationship between mesh data this needs to be set by the caller. */
2011 DerivedMesh *CDDM_from_template(DerivedMesh *source,
2012                                 int numVerts, int numEdges, int numTessFaces,
2013                                 int numLoops, int numPolys)
2014 {
2015         CDDerivedMesh *cddm = cdDM_create("CDDM_from_template dest");
2016         DerivedMesh *dm = &cddm->dm;
2017
2018         /* ensure these are created if they are made on demand */
2019         source->getVertDataArray(source, CD_ORIGINDEX);
2020         source->getEdgeDataArray(source, CD_ORIGINDEX);
2021         source->getTessFaceDataArray(source, CD_ORIGINDEX);
2022
2023         /* this does a copy of all non mvert/medge/mface layers */
2024         DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces, numLoops, numPolys);
2025
2026         /* now add mvert/medge/mface layers */
2027         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
2028         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2029         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numTessFaces);
2030         CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL, numLoops);
2031         CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL, numPolys);
2032
2033         if(!CustomData_get_layer(&dm->vertData, CD_ORIGINDEX))
2034                 CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
2035         if(!CustomData_get_layer(&dm->edgeData, CD_ORIGINDEX))
2036                 CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2037         if(!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX))
2038                 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numTessFaces);
2039         if(!CustomData_get_layer(&dm->faceData, CD_POLYINDEX))
2040                 CustomData_add_layer(&dm->faceData, CD_POLYINDEX, CD_CALLOC, NULL, numTessFaces);
2041
2042         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
2043         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2044         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
2045         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
2046         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
2047
2048         return dm;
2049 }
2050
2051 void CDDM_apply_vert_coords(DerivedMesh *dm, float (*vertCoords)[3])
2052 {
2053         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2054         MVert *vert;
2055         int i;
2056
2057         /* this will just return the pointer if it wasn't a referenced layer */
2058         vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2059         cddm->mvert = vert;
2060
2061         for(i = 0; i < dm->numVertData; ++i, ++vert)
2062                 copy_v3_v3(vert->co, vertCoords[i]);
2063 }
2064
2065 void CDDM_apply_vert_normals(DerivedMesh *dm, short (*vertNormals)[3])
2066 {
2067         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2068         MVert *vert;
2069         int i;
2070
2071         /* this will just return the pointer if it wasn't a referenced layer */
2072         vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2073         cddm->mvert = vert;
2074
2075         for(i = 0; i < dm->numVertData; ++i, ++vert)
2076                 copy_v3_v3_short(vert->no, vertNormals[i]);
2077 }
2078
2079 void CDDM_calc_normals_mapping(DerivedMesh *dm)
2080 {
2081         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2082         float (*face_nors)[3] = NULL;
2083
2084         /* use this to skip calculating normals on original vert's, this may need to be changed */
2085         const short only_face_normals = CustomData_is_referenced_layer(&dm->vertData, CD_MVERT);
2086         
2087         if(dm->numVertData == 0) return;
2088
2089         /* now we skip calculating vertex normals for referenced layer,
2090          * no need to duplicate verts.
2091          * WATCH THIS, bmesh only change!,
2092          * need to take care of the side effects here - campbell */
2093 #if 0
2094         /* we don't want to overwrite any referenced layers */
2095         cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2096 #endif
2097
2098
2099         if (dm->numTessFaceData == 0) {
2100                 /* No tessellation on this mesh yet, need to calculate one.
2101                  *
2102                  * Important not to update face normals from polys since it
2103                  * interfears with assigning the new normal layer in the following code.
2104                  */
2105                 CDDM_recalc_tessellation_ex(dm, FALSE);
2106         }
2107         else {
2108                 /* A tessellation already exists, it should always have a CD_POLYINDEX */
2109                 BLI_assert(CustomData_has_layer(&dm->faceData, CD_POLYINDEX));
2110                 CustomData_free_layers(&dm->faceData, CD_NORMAL, dm->numTessFaceData);
2111         }
2112
2113
2114         face_nors = MEM_mallocN(sizeof(float)*3*dm->numTessFaceData, "face_nors");
2115         
2116         /* calculate face normals */
2117         mesh_calc_normals_mapping_ex(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm),
2118                                      dm->numLoopData, dm->numPolyData, NULL, cddm->mface, dm->numTessFaceData,
2119                                      CustomData_get_layer(&dm->faceData, CD_POLYINDEX), face_nors,
2120                                      only_face_normals);
2121         
2122         CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_ASSIGN, 
2123                              face_nors, dm->numTessFaceData);
2124
2125
2126 }
2127
2128 /* bmesh note: this matches what we have in trunk */
2129 void CDDM_calc_normals(DerivedMesh *dm)
2130 {
2131         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2132         float (*poly_nors)[3];
2133
2134         if(dm->numVertData == 0) return;
2135
2136         /* we don't want to overwrite any referenced layers */
2137         cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2138
2139         /* fill in if it exists */
2140         poly_nors = CustomData_get_layer(&dm->polyData, CD_NORMAL);
2141         if (!poly_nors) {
2142                 poly_nors = CustomData_add_layer(&dm->polyData, CD_NORMAL, CD_CALLOC, NULL, dm->numPolyData);
2143         }
2144
2145         mesh_calc_normals(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm),
2146                           dm->numLoopData, dm->numPolyData, poly_nors);
2147 }
2148
2149 void CDDM_calc_normals_tessface(DerivedMesh *dm)
2150 {
2151         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2152         float (*face_nors)[3];
2153
2154         if(dm->numVertData == 0) return;
2155
2156         /* we don't want to overwrite any referenced layers */
2157         cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2158
2159         /* fill in if it exists */
2160         face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
2161         if (!face_nors) {
2162                 face_nors = CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_CALLOC, NULL, dm->numTessFaceData);
2163         }
2164
2165         mesh_calc_normals_tessface(cddm->mvert, dm->numVertData,
2166                                                            cddm->mface, dm->numTessFaceData, face_nors);
2167 }
2168
2169 #if 1
2170 /* merge verts
2171  *
2172  * vtargetmap is a table that maps vertices to target vertices.  a value of -1
2173  * indicates a vertex is a target, and is to be kept.
2174  *
2175  * this frees dm, and returns a new one.
2176  *
2177  * this is a really horribly written function.  ger. - joeedh
2178  *
2179  * note, CDDM_recalc_tessellation has to run on the returned DM if you want to access tessfaces.
2180  */
2181 DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap)
2182 {
2183         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2184         CDDerivedMesh *cddm2 = NULL;
2185         MVert *mv, *mvert = NULL;
2186         BLI_array_declare(mvert);
2187         MEdge *med, *medge = NULL;
2188         BLI_array_declare(medge);
2189         MPoly *mp, *mpoly = NULL;
2190         BLI_array_declare(mpoly);
2191         MLoop *ml, *mloop = NULL;
2192         BLI_array_declare(mloop);
2193         EdgeHash *ehash = BLI_edgehash_new();
2194         int *newv = NULL, *newe = NULL, *newl = NULL;
2195         int *oldv = NULL, *olde = NULL, *oldl = NULL, *oldp = NULL;
2196         BLI_array_declare(oldv); BLI_array_declare(olde); BLI_array_declare(oldl); BLI_array_declare(oldp);
2197         int i, j, c, totloop, totpoly;
2198         
2199         totloop = dm->numLoopData;
2200         totpoly = dm->numPolyData;
2201         
2202         newv = MEM_callocN(sizeof(int)*dm->numVertData, "newv vtable CDDM_merge_verts");
2203         newe = MEM_callocN(sizeof(int)*dm->numEdgeData, "newv etable CDDM_merge_verts");
2204         newl = MEM_callocN(sizeof(int)*totloop, "newv ltable CDDM_merge_verts");
2205         
2206         /*fill newl with destination vertex indices*/
2207         mv = cddm->mvert;
2208         c = 0;
2209         for (i=0; i<dm->numVertData; i++, mv++) {
2210                 if (vtargetmap[i] == -1) {
2211                         BLI_array_append(oldv, i);
2212                         newv[i] = c++;
2213                         BLI_array_append(mvert, *mv);
2214                 }
2215         }
2216         
2217         /*now link target vertices to destination indices*/
2218         for (i=0; i<dm->numVertData; i++) {
2219                 if (vtargetmap[i] != -1) {
2220                         newv[i] = newv[vtargetmap[i]];
2221                 }
2222         }
2223         
2224         /*find-replace merged vertices with target vertices*/   
2225         ml = cddm->mloop;
2226         c = 0;
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 }