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