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