Fix a bug in CustomData_duplicate_referenced_layer(_named) functions: MEM_dupallocN...
[blender.git] / source / blender / blenkernel / intern / cdderivedmesh.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software  Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2006 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): Ben Batt <benbatt@gmail.com>
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  *
27  * Implementation of CDDerivedMesh.
28  *
29  * BKE_cdderivedmesh.h contains the function prototypes for this file.
30  *
31  */
32
33 /** \file blender/blenkernel/intern/cdderivedmesh.c
34  *  \ingroup bke
35  */
36
37 #include "GL/glew.h"
38
39 #include "BLI_blenlib.h"
40 #include "BLI_edgehash.h"
41 #include "BLI_editVert.h"
42 #include "BLI_math.h"
43 #include "BLI_pbvh.h"
44 #include "BLI_utildefines.h"
45
46 #include "BKE_cdderivedmesh.h"
47 #include "BKE_global.h"
48 #include "BKE_mesh.h"
49 #include "BKE_paint.h"
50
51
52 #include "DNA_meshdata_types.h"
53 #include "DNA_object_types.h"
54 #include "DNA_curve_types.h" /* for Curve */
55
56 #include "MEM_guardedalloc.h"
57
58 #include "GPU_buffers.h"
59 #include "GPU_draw.h"
60 #include "GPU_extensions.h"
61 #include "GPU_material.h"
62
63 #include <string.h>
64 #include <limits.h>
65 #include <math.h>
66
67 typedef struct {
68         DerivedMesh dm;
69
70         /* these point to data in the DerivedMesh custom data layers,
71            they are only here for efficiency and convenience **/
72         MVert *mvert;
73         MEdge *medge;
74         MFace *mface;
75
76         /* Cached */
77         struct PBVH *pbvh;
78         int pbvh_draw;
79
80         /* Mesh connectivity */
81         struct ListBase *fmap;
82         struct IndexNode *fmap_mem;
83 } CDDerivedMesh;
84
85 /**************** DerivedMesh interface functions ****************/
86 static int cdDM_getNumVerts(DerivedMesh *dm)
87 {
88         return dm->numVertData;
89 }
90
91 static int cdDM_getNumEdges(DerivedMesh *dm)
92 {
93         return dm->numEdgeData;
94 }
95
96 static int cdDM_getNumFaces(DerivedMesh *dm)
97 {
98         return dm->numFaceData;
99 }
100
101 static void cdDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
102 {
103         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
104         *vert_r = cddm->mvert[index];
105 }
106
107 static void cdDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
108 {
109         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
110         *edge_r = cddm->medge[index];
111 }
112
113 static void cdDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
114 {
115         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
116         *face_r = cddm->mface[index];
117 }
118
119 static void cdDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
120 {
121         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
122         memcpy(vert_r, cddm->mvert, sizeof(*vert_r) * dm->numVertData);
123 }
124
125 static void cdDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
126 {
127         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
128         memcpy(edge_r, cddm->medge, sizeof(*edge_r) * dm->numEdgeData);
129 }
130
131 static void cdDM_copyFaceArray(DerivedMesh *dm, MFace *face_r)
132 {
133         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
134         memcpy(face_r, cddm->mface, sizeof(*face_r) * dm->numFaceData);
135 }
136
137 static void cdDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
138 {
139         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
140         int i;
141
142         if (dm->numVertData) {
143                 for (i=0; i<dm->numVertData; i++) {
144                         DO_MINMAX(cddm->mvert[i].co, min_r, max_r);
145                 }
146         } else {
147                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
148         }
149 }
150
151 static void cdDM_getVertCo(DerivedMesh *dm, int index, float co_r[3])
152 {
153         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
154
155         copy_v3_v3(co_r, cddm->mvert[index].co);
156 }
157
158 static void cdDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
159 {
160         MVert *mv = CDDM_get_verts(dm);
161         int i;
162
163         for(i = 0; i < dm->numVertData; i++, mv++)
164                 copy_v3_v3(cos_r[i], mv->co);
165 }
166
167 static void cdDM_getVertNo(DerivedMesh *dm, int index, float no_r[3])
168 {
169         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
170         normal_short_to_float_v3(no_r, cddm->mvert[index].no);
171 }
172
173 static ListBase *cdDM_getFaceMap(Object *ob, DerivedMesh *dm)
174 {
175         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
176
177         if(!cddm->fmap && ob->type == OB_MESH) {
178                 Mesh *me= ob->data;
179
180                 create_vert_face_map(&cddm->fmap, &cddm->fmap_mem, me->mface,
181                                          me->totvert, me->totface);
182         }
183
184         return cddm->fmap;
185 }
186
187 static int can_pbvh_draw(Object *ob, DerivedMesh *dm)
188 {
189         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
190         Mesh *me= ob->data;
191         int deformed= 0;
192
193         /* active modifiers means extra deformation, which can't be handled correct
194            on bith of PBVH and sculpt "layer" levels, so use PBVH only for internal brush
195            stuff and show final DerivedMesh so user would see actual object shape */
196         deformed|= ob->sculpt->modifiers_active;
197
198         /* as in case with modifiers, we can't synchronize deformation made against
199            PBVH and non-locked keyblock, so also use PBVH only for brushes and
200            final DM to give final result to user */
201         deformed|= ob->sculpt->kb && (ob->shapeflag&OB_SHAPE_LOCK) == 0;
202
203         if(deformed)
204                 return 0;
205
206         return (cddm->mvert == me->mvert) || ob->sculpt->kb;
207 }
208
209 static struct PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
210 {
211         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
212
213         if(!ob) {
214                 cddm->pbvh= NULL;
215                 return NULL;
216         }
217
218         if(!ob->sculpt)
219                 return NULL;
220         if(ob->sculpt->pbvh) {
221                 cddm->pbvh= ob->sculpt->pbvh;
222                 cddm->pbvh_draw = can_pbvh_draw(ob, dm);
223         }
224
225         /* always build pbvh from original mesh, and only use it for drawing if
226            this derivedmesh is just original mesh. it's the multires subsurf dm
227            that this is actually for, to support a pbvh on a modified mesh */
228         if(!cddm->pbvh && ob->type == OB_MESH) {
229                 SculptSession *ss= ob->sculpt;
230                 Mesh *me= ob->data;
231                 cddm->pbvh = BLI_pbvh_new();
232                 cddm->pbvh_draw = can_pbvh_draw(ob, dm);
233                 BLI_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert,
234                                     me->totface, me->totvert);
235
236                 if(ss->modifiers_active && ob->derivedDeform) {
237                         DerivedMesh *deformdm= ob->derivedDeform;
238                         float (*vertCos)[3];
239                         int totvert;
240
241                         totvert= deformdm->getNumVerts(deformdm);
242                         vertCos= MEM_callocN(3*totvert*sizeof(float), "cdDM_getPBVH vertCos");
243                         deformdm->getVertCos(deformdm, vertCos);
244                         BLI_pbvh_apply_vertCos(cddm->pbvh, vertCos);
245                         MEM_freeN(vertCos);
246                 }
247         }
248
249         return cddm->pbvh;
250 }
251
252 /* update vertex normals so that drawing smooth faces works during sculpt
253    TODO: proper fix is to support the pbvh in all drawing modes */
254 static void cdDM_update_normals_from_pbvh(DerivedMesh *dm)
255 {
256         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
257         float (*face_nors)[3];
258
259         if(!cddm->pbvh || !cddm->pbvh_draw || !dm->numFaceData)
260                 return;
261
262         face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
263
264         BLI_pbvh_update(cddm->pbvh, PBVH_UpdateNormals, face_nors);
265 }
266
267 static void cdDM_drawVerts(DerivedMesh *dm)
268 {
269         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
270         MVert *mv = cddm->mvert;
271         int i;
272
273         if( GPU_buffer_legacy(dm) ) {
274                 glBegin(GL_POINTS);
275                 for(i = 0; i < dm->numVertData; i++, mv++)
276                         glVertex3fv(mv->co);
277                 glEnd();
278         }
279         else {  /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
280                 GPU_vertex_setup(dm);
281                 if( !GPU_buffer_legacy(dm) ) {
282                         if(dm->drawObject->tot_triangle_point)
283                                 glDrawArrays(GL_POINTS,0, dm->drawObject->tot_triangle_point);
284                         else
285                                 glDrawArrays(GL_POINTS,0, dm->drawObject->tot_loose_point);
286                 }
287                 GPU_buffer_unbind();
288         }
289 }
290
291 static void cdDM_drawUVEdges(DerivedMesh *dm)
292 {
293         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
294         MFace *mf = cddm->mface;
295         MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
296         int i;
297
298         if(mf) {
299                 if( GPU_buffer_legacy(dm) ) {
300                         glBegin(GL_LINES);
301                         for(i = 0; i < dm->numFaceData; i++, mf++, tf++) {
302                                 if(!(mf->flag&ME_HIDE)) {
303                                         glVertex2fv(tf->uv[0]);
304                                         glVertex2fv(tf->uv[1]);
305
306                                         glVertex2fv(tf->uv[1]);
307                                         glVertex2fv(tf->uv[2]);
308
309                                         if(!mf->v4) {
310                                                 glVertex2fv(tf->uv[2]);
311                                                 glVertex2fv(tf->uv[0]);
312                                         } else {
313                                                 glVertex2fv(tf->uv[2]);
314                                                 glVertex2fv(tf->uv[3]);
315
316                                                 glVertex2fv(tf->uv[3]);
317                                                 glVertex2fv(tf->uv[0]);
318                                         }
319                                 }
320                         }
321                         glEnd();
322                 }
323                 else {
324                         int prevstart = 0;
325                         int prevdraw = 1;
326                         int draw = 1;
327                         int curpos = 0;
328
329                         GPU_uvedge_setup(dm);
330                         if( !GPU_buffer_legacy(dm) ) {
331                                 for(i = 0; i < dm->numFaceData; i++, mf++) {
332                                         if(!(mf->flag&ME_HIDE)) {
333                                                 draw = 1;
334                                         } 
335                                         else {
336                                                 draw = 0;
337                                         }
338                                         if( prevdraw != draw ) {
339                                                 if( prevdraw > 0 && (curpos-prevstart) > 0) {
340                                                         glDrawArrays(GL_LINES,prevstart,curpos-prevstart);
341                                                 }
342                                                 prevstart = curpos;
343                                         }
344                                         if( mf->v4 ) {
345                                                 curpos += 8;
346                                         }
347                                         else {
348                                                 curpos += 6;
349                                         }
350                                         prevdraw = draw;
351                                 }
352                                 if( prevdraw > 0 && (curpos-prevstart) > 0 ) {
353                                         glDrawArrays(GL_LINES,prevstart,curpos-prevstart);
354                                 }
355                         }
356                         GPU_buffer_unbind();
357                 }
358         }
359 }
360
361 static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges)
362 {
363         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
364         MVert *mvert = cddm->mvert;
365         MEdge *medge = cddm->medge;
366         int i;
367         
368         if( GPU_buffer_legacy(dm) ) {
369                 DEBUG_VBO( "Using legacy code. cdDM_drawEdges\n" );
370                 glBegin(GL_LINES);
371                 for(i = 0; i < dm->numEdgeData; i++, medge++) {
372                         if((drawAllEdges || (medge->flag&ME_EDGEDRAW))
373                            && (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) {
374                                 glVertex3fv(mvert[medge->v1].co);
375                                 glVertex3fv(mvert[medge->v2].co);
376                         }
377                 }
378                 glEnd();
379         }
380         else {  /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
381                 int prevstart = 0;
382                 int prevdraw = 1;
383                 int draw = 1;
384
385                 GPU_edge_setup(dm);
386                 if( !GPU_buffer_legacy(dm) ) {
387                         for(i = 0; i < dm->numEdgeData; i++, medge++) {
388                                 if((drawAllEdges || (medge->flag&ME_EDGEDRAW))
389                                    && (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) {
390                                         draw = 1;
391                                 } 
392                                 else {
393                                         draw = 0;
394                                 }
395                                 if( prevdraw != draw ) {
396                                         if( prevdraw > 0 && (i-prevstart) > 0 ) {
397                                                 GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2  );
398                                         }
399                                         prevstart = i;
400                                 }
401                                 prevdraw = draw;
402                         }
403                         if( prevdraw > 0 && (i-prevstart) > 0 ) {
404                                 GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2  );
405                         }
406                 }
407                 GPU_buffer_unbind();
408         }
409 }
410
411 static void cdDM_drawLooseEdges(DerivedMesh *dm)
412 {
413         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
414         MVert *mvert = cddm->mvert;
415         MEdge *medge = cddm->medge;
416         int i;
417
418         if( GPU_buffer_legacy(dm) ) {
419                 DEBUG_VBO( "Using legacy code. cdDM_drawLooseEdges\n" );
420                 glBegin(GL_LINES);
421                 for(i = 0; i < dm->numEdgeData; i++, medge++) {
422                         if(medge->flag&ME_LOOSEEDGE) {
423                                 glVertex3fv(mvert[medge->v1].co);
424                                 glVertex3fv(mvert[medge->v2].co);
425                         }
426                 }
427                 glEnd();
428         }
429         else {  /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
430                 int prevstart = 0;
431                 int prevdraw = 1;
432                 int draw = 1;
433
434                 GPU_edge_setup(dm);
435                 if( !GPU_buffer_legacy(dm) ) {
436                         for(i = 0; i < dm->numEdgeData; i++, medge++) {
437                                 if(medge->flag&ME_LOOSEEDGE) {
438                                         draw = 1;
439                                 } 
440                                 else {
441                                         draw = 0;
442                                 }
443                                 if( prevdraw != draw ) {
444                                         if( prevdraw > 0 && (i-prevstart) > 0) {
445                                                 GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2  );
446                                         }
447                                         prevstart = i;
448                                 }
449                                 prevdraw = draw;
450                         }
451                         if( prevdraw > 0 && (i-prevstart) > 0 ) {
452                                 GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2  );
453                         }
454                 }
455                 GPU_buffer_unbind();
456         }
457 }
458
459 static void cdDM_drawFacesSolid(DerivedMesh *dm,
460                                 float (*partial_redraw_planes)[4],
461                                 int UNUSED(fast), int (*setMaterial)(int, void *attribs))
462 {
463         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
464         MVert *mvert = cddm->mvert;
465         MFace *mface = cddm->mface;
466         float *nors= dm->getFaceDataArray(dm, CD_NORMAL);
467         int a, glmode = -1, shademodel = -1, matnr = -1, drawCurrentMat = 1;
468
469 #define PASSVERT(index) {                                               \
470         if(shademodel == GL_SMOOTH) {                           \
471                 short *no = mvert[index].no;                    \
472                 glNormal3sv(no);                                                \
473         }                                                                                       \
474         glVertex3fv(mvert[index].co);   \
475 }
476
477         if(cddm->pbvh && cddm->pbvh_draw) {
478                 if(dm->numFaceData) {
479                         float (*face_nors)[3] = CustomData_get_layer(&dm->faceData, CD_NORMAL);
480
481                         /* should be per face */
482                         if(!setMaterial(mface->mat_nr+1, NULL))
483                                 return;
484
485                         glShadeModel((mface->flag & ME_SMOOTH)? GL_SMOOTH: GL_FLAT);
486                         BLI_pbvh_draw(cddm->pbvh, partial_redraw_planes, face_nors, (mface->flag & ME_SMOOTH));
487                         glShadeModel(GL_FLAT);
488                 }
489
490                 return;
491         }
492
493         if( GPU_buffer_legacy(dm) ) {
494                 DEBUG_VBO( "Using legacy code. cdDM_drawFacesSolid\n" );
495                 glBegin(glmode = GL_QUADS);
496                 for(a = 0; a < dm->numFaceData; a++, mface++) {
497                         int new_glmode, new_matnr, new_shademodel;
498
499                         new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES;
500                         new_matnr = mface->mat_nr + 1;
501                         new_shademodel = (mface->flag & ME_SMOOTH)?GL_SMOOTH:GL_FLAT;
502                         
503                         if(new_glmode != glmode || new_matnr != matnr
504                            || new_shademodel != shademodel) {
505                                 glEnd();
506
507                                 drawCurrentMat = setMaterial(matnr = new_matnr, NULL);
508
509                                 glShadeModel(shademodel = new_shademodel);
510                                 glBegin(glmode = new_glmode);
511                         } 
512                         
513                         if(drawCurrentMat) {
514                                 if(shademodel == GL_FLAT) {
515                                         if (nors) {
516                                                 glNormal3fv(nors);
517                                         }
518                                         else {
519                                                 /* TODO make this better (cache facenormals as layer?) */
520                                                 float nor[3];
521                                                 if(mface->v4) {
522                                                         normal_quad_v3( nor,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co);
523                                                 } else {
524                                                         normal_tri_v3( nor,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co);
525                                                 }
526                                                 glNormal3fv(nor);
527                                         }
528                                 }
529
530                                 PASSVERT(mface->v1);
531                                 PASSVERT(mface->v2);
532                                 PASSVERT(mface->v3);
533                                 if(mface->v4) {
534                                         PASSVERT(mface->v4);
535                                 }
536                         }
537
538                         if(nors) nors += 3;
539                 }
540                 glEnd();
541         }
542         else {  /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
543                 GPU_vertex_setup( dm );
544                 GPU_normal_setup( dm );
545                 if( !GPU_buffer_legacy(dm) ) {
546                         glShadeModel(GL_SMOOTH);
547                         for( a = 0; a < dm->drawObject->totmaterial; a++ ) {
548                                 if( setMaterial(dm->drawObject->materials[a].mat_nr+1, NULL) )
549                                         glDrawArrays(GL_TRIANGLES, dm->drawObject->materials[a].start,
550                                                      dm->drawObject->materials[a].totpoint);
551                         }
552                 }
553                 GPU_buffer_unbind( );
554         }
555
556 #undef PASSVERT
557         glShadeModel(GL_FLAT);
558 }
559
560 static void cdDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *col1, unsigned char *col2)
561 {
562         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
563         int a, glmode;
564         unsigned char *cp1, *cp2;
565         MVert *mvert = cddm->mvert;
566         MFace *mface = cddm->mface;
567
568         cp1 = col1;
569         if(col2) {
570                 cp2 = col2;
571         } else {
572                 cp2 = NULL;
573                 useTwoSided = 0;
574         }
575
576         /* there's a conflict here... twosided colors versus culling...? */
577         /* defined by history, only texture faces have culling option */
578         /* we need that as mesh option builtin, next to double sided lighting */
579         if(col2) {
580                 glEnable(GL_CULL_FACE);
581         }
582
583         cdDM_update_normals_from_pbvh(dm);
584
585         if( GPU_buffer_legacy(dm) ) {
586                 DEBUG_VBO( "Using legacy code. cdDM_drawFacesColored\n" );
587                 glShadeModel(GL_SMOOTH);
588                 glBegin(glmode = GL_QUADS);
589                 for(a = 0; a < dm->numFaceData; a++, mface++, cp1 += 16) {
590                         int new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES;
591
592                         if(new_glmode != glmode) {
593                                 glEnd();
594                                 glBegin(glmode = new_glmode);
595                         }
596                                 
597                         glColor3ubv(cp1+0);
598                         glVertex3fv(mvert[mface->v1].co);
599                         glColor3ubv(cp1+4);
600                         glVertex3fv(mvert[mface->v2].co);
601                         glColor3ubv(cp1+8);
602                         glVertex3fv(mvert[mface->v3].co);
603                         if(mface->v4) {
604                                 glColor3ubv(cp1+12);
605                                 glVertex3fv(mvert[mface->v4].co);
606                         }
607                                 
608                         if(useTwoSided) {
609                                 glColor3ubv(cp2+8);
610                                 glVertex3fv(mvert[mface->v3].co );
611                                 glColor3ubv(cp2+4);
612                                 glVertex3fv(mvert[mface->v2].co );
613                                 glColor3ubv(cp2+0);
614                                 glVertex3fv(mvert[mface->v1].co );
615                                 if(mface->v4) {
616                                         glColor3ubv(cp2+12);
617                                         glVertex3fv(mvert[mface->v4].co );
618                                 }
619                         }
620                         if(col2) cp2 += 16;
621                 }
622                 glEnd();
623         }
624         else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
625                 GPU_color4_upload(dm,cp1);
626                 GPU_vertex_setup(dm);
627                 GPU_color_setup(dm);
628                 if( !GPU_buffer_legacy(dm) ) {
629                         glShadeModel(GL_SMOOTH);
630                         glDrawArrays(GL_TRIANGLES, 0, dm->drawObject->tot_triangle_point);
631
632                         if( useTwoSided ) {
633                                 GPU_color4_upload(dm,cp2);
634                                 GPU_color_setup(dm);
635                                 glCullFace(GL_FRONT);
636                                 glDrawArrays(GL_TRIANGLES, 0, dm->drawObject->tot_triangle_point);
637                                 glCullFace(GL_BACK);
638                         }
639                 }
640                 GPU_buffer_unbind();
641         }
642
643         glShadeModel(GL_FLAT);
644         glDisable(GL_CULL_FACE);
645 }
646
647 static void cdDM_drawFacesTex_common(DerivedMesh *dm,
648                            int (*drawParams)(MTFace *tface, int has_mcol, int matnr),
649                            int (*drawParamsMapped)(void *userData, int index),
650                            int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
651                            void *userData) 
652 {
653         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
654         MVert *mv = cddm->mvert;
655         MFace *mf = DM_get_face_data_layer(dm, CD_MFACE);
656         MCol *realcol = dm->getFaceDataArray(dm, CD_TEXTURE_MCOL);
657         float *nors= dm->getFaceDataArray(dm, CD_NORMAL);
658         MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
659         int i, j, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
660         int startFace = 0 /*, lastFlag = 0xdeadbeef */ /* UNUSED */;
661         MCol *mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL);
662         if(!mcol)
663                 mcol = dm->getFaceDataArray(dm, CD_MCOL);
664
665         cdDM_update_normals_from_pbvh(dm);
666
667         if( GPU_buffer_legacy(dm) ) {
668                 DEBUG_VBO( "Using legacy code. cdDM_drawFacesTex_common\n" );
669                 for(i = 0; i < dm->numFaceData; i++, mf++) {
670                         MVert *mvert;
671                         int flag;
672                         unsigned char *cp = NULL;
673
674                         if(drawParams) {
675                                 flag = drawParams(tf? &tf[i]: NULL, (mcol != NULL), mf->mat_nr);
676                         }
677                         else {
678                                 if(index) {
679                                         orig = *index++;
680                                         if(orig == ORIGINDEX_NONE)              { if(nors) nors += 3; continue; }
681                                         if(drawParamsMapped) flag = drawParamsMapped(userData, orig);
682                                         else    { if(nors) nors += 3; continue; }
683                                 }
684                                 else
685                                         if(drawParamsMapped) flag = drawParamsMapped(userData, i);
686                                         else    { if(nors) nors += 3; continue; }
687                         }
688                         
689                         if(flag != 0) {
690                                 if (flag==1 && mcol)
691                                         cp= (unsigned char*) &mcol[i*4];
692
693                                 if(!(mf->flag&ME_SMOOTH)) {
694                                         if (nors) {
695                                                 glNormal3fv(nors);
696                                         }
697                                         else {
698                                                 float nor[3];
699                                                 if(mf->v4) {
700                                                         normal_quad_v3( nor,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
701                                                 } else {
702                                                         normal_tri_v3( nor,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
703                                                 }
704                                                 glNormal3fv(nor);
705                                         }
706                                 }
707
708                                 glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
709                                 if(tf) glTexCoord2fv(tf[i].uv[0]);
710                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
711                                 mvert = &mv[mf->v1];
712                                 if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
713                                 glVertex3fv(mvert->co);
714                                         
715                                 if(tf) glTexCoord2fv(tf[i].uv[1]);
716                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
717                                 mvert = &mv[mf->v2];
718                                 if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
719                                 glVertex3fv(mvert->co);
720
721                                 if(tf) glTexCoord2fv(tf[i].uv[2]);
722                                 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
723                                 mvert = &mv[mf->v3];
724                                 if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
725                                 glVertex3fv(mvert->co);
726
727                                 if(mf->v4) {
728                                         if(tf) glTexCoord2fv(tf[i].uv[3]);
729                                         if(cp) glColor3ub(cp[15], cp[14], cp[13]);
730                                         mvert = &mv[mf->v4];
731                                         if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
732                                         glVertex3fv(mvert->co);
733                                 }
734                                 glEnd();
735                         }
736                         
737                         if(nors) nors += 3;
738                 }
739         } else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
740                 MCol *col = realcol;
741                 if(!col)
742                         col = mcol;
743
744                 GPU_vertex_setup( dm );
745                 GPU_normal_setup( dm );
746                 GPU_uv_setup( dm );
747                 if( col != NULL ) {
748                         /*if( realcol && dm->drawObject->colType == CD_TEXTURE_MCOL )  {
749                                 col = 0;
750                         } else if( mcol && dm->drawObject->colType == CD_MCOL ) {
751                                 col = 0;
752                         }
753                         
754                         if( col != 0 ) {*/
755                                 unsigned char *colors = MEM_mallocN(dm->getNumFaces(dm)*4*3*sizeof(unsigned char), "cdDM_drawFacesTex_common");
756                                 for( i=0; i < dm->getNumFaces(dm); i++ ) {
757                                         for( j=0; j < 4; j++ ) {
758                                                 /* bgr -> rgb is intentional (and stupid), but how its stored internally */
759                                                 colors[i*12+j*3] = col[i*4+j].b;
760                                                 colors[i*12+j*3+1] = col[i*4+j].g;
761                                                 colors[i*12+j*3+2] = col[i*4+j].r;
762                                         }
763                                 }
764                                 GPU_color3_upload(dm,colors);
765                                 MEM_freeN(colors);
766                                 if(realcol)
767                                         dm->drawObject->colType = CD_TEXTURE_MCOL;
768                                 else if(mcol)
769                                         dm->drawObject->colType = CD_MCOL;
770                         //}
771                         GPU_color_setup( dm );
772                 }
773
774                 if( !GPU_buffer_legacy(dm) ) {
775                         int tottri = dm->drawObject->tot_triangle_point/3;
776                         int next_actualFace= dm->drawObject->triangle_to_mface[0];
777
778                         glShadeModel( GL_SMOOTH );
779                         /* lastFlag = 0; */ /* UNUSED */
780                         for(i = 0; i < tottri; i++) {
781                                 int actualFace = next_actualFace;
782                                 int flag = 1;
783                                 int flush = 0;
784
785                                 if(i != tottri-1)
786                                         next_actualFace= dm->drawObject->triangle_to_mface[i+1];
787
788                                 if(drawParams) {
789                                         flag = drawParams(tf? &tf[actualFace]: NULL, (mcol != NULL), mf[actualFace].mat_nr);
790                                 }
791                                 else {
792                                         if(index) {
793                                                 orig = index[actualFace];
794                                                 if(orig == ORIGINDEX_NONE) continue;
795                                                 if(drawParamsMapped)
796                                                         flag = drawParamsMapped(userData, orig);
797                                         }
798                                         else
799                                                 if(drawParamsMapped)
800                                                         flag = drawParamsMapped(userData, actualFace);
801                                 }
802
803                                 /* flush buffer if current triangle isn't drawable or it's last triangle */
804                                 flush= !flag || i == tottri - 1;
805
806                                 if(!flush && compareDrawOptions) {
807                                         /* also compare draw options and flush buffer if they're different
808                                            need for face selection highlight in edit mode */
809                                         flush|= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
810                                 }
811
812                                 if(flush) {
813                                         int first= startFace*3;
814                                         int count= (i-startFace+(flag ? 1 : 0))*3; /* Add one to the length if we're drawing at the end of the array */
815
816                                         if(count) {
817                                                 if (col)
818                                                         GPU_color_switch(1);
819                                                 else
820                                                         GPU_color_switch(0);
821
822                                                 glDrawArrays(GL_TRIANGLES, first, count);
823                                         }
824
825                                         startFace = i + 1;
826                                 }
827                         }
828                 }
829
830                 GPU_buffer_unbind();
831                 glShadeModel( GL_FLAT );
832         }
833 }
834
835 static void cdDM_drawFacesTex(DerivedMesh *dm,
836                            int (*setDrawOptions)(MTFace *tface, int has_mcol, int matnr),
837                            int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
838                            void *userData)
839 {
840         cdDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData);
841 }
842
843 static void cdDM_drawMappedFaces(DerivedMesh *dm,
844                         int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r),
845                         int (*setMaterial)(int, void *attribs),
846                         int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
847                         void *userData, int useColors)
848 {
849         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
850         MVert *mv = cddm->mvert;
851         MFace *mf = cddm->mface;
852         MCol *mc;
853         float *nors= dm->getFaceDataArray(dm, CD_NORMAL);
854         int i, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
855
856         mc = DM_get_face_data_layer(dm, CD_ID_MCOL);
857         if(!mc)
858                 mc = DM_get_face_data_layer(dm, CD_WEIGHT_MCOL);
859         if(!mc)
860                 mc = DM_get_face_data_layer(dm, CD_MCOL);
861
862         cdDM_update_normals_from_pbvh(dm);
863
864         /* back-buffer always uses legacy since VBO's would need the
865          * color array temporarily overwritten for drawing, then reset. */
866         if( GPU_buffer_legacy(dm) || G.f & G_BACKBUFSEL) {
867                 DEBUG_VBO( "Using legacy code. cdDM_drawMappedFaces\n" );
868                 for(i = 0; i < dm->numFaceData; i++, mf++) {
869                         int drawSmooth = (mf->flag & ME_SMOOTH);
870                         int draw= 1;
871
872                         orig= (index==NULL) ? i : *index++;
873                         
874                         if(orig == ORIGINDEX_NONE)
875                                 draw= setMaterial(mf->mat_nr + 1, NULL);
876                         else if (setDrawOptions != NULL)
877                                 draw= setDrawOptions(userData, orig, &drawSmooth);
878
879                         if(draw) {
880                                 unsigned char *cp = NULL;
881
882                                 if(useColors && mc)
883                                         cp = (unsigned char *)&mc[i * 4];
884
885                                 /* no need to set shading mode to flat because
886                                 *  normals are already used to change shading */
887                                 glShadeModel(GL_SMOOTH);
888                                 glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
889
890                                 if (!drawSmooth) {
891                                         if (nors) {
892                                                 glNormal3fv(nors);
893                                         }
894                                         else {
895                                                 float nor[3];
896                                                 if(mf->v4) {
897                                                         normal_quad_v3( nor,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
898                                                 } else {
899                                                         normal_tri_v3( nor,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
900                                                 }
901                                                 glNormal3fv(nor);
902                                         }
903
904                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
905                                         glVertex3fv(mv[mf->v1].co);
906                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
907                                         glVertex3fv(mv[mf->v2].co);
908                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
909                                         glVertex3fv(mv[mf->v3].co);
910                                         if(mf->v4) {
911                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
912                                                 glVertex3fv(mv[mf->v4].co);
913                                         }
914                                 } else {
915                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
916                                         glNormal3sv(mv[mf->v1].no);
917                                         glVertex3fv(mv[mf->v1].co);
918                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
919                                         glNormal3sv(mv[mf->v2].no);
920                                         glVertex3fv(mv[mf->v2].co);
921                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
922                                         glNormal3sv(mv[mf->v3].no);
923                                         glVertex3fv(mv[mf->v3].co);
924                                         if(mf->v4) {
925                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
926                                                 glNormal3sv(mv[mf->v4].no);
927                                                 glVertex3fv(mv[mf->v4].co);
928                                         }
929                                 }
930
931                                 glEnd();
932                         }
933                         
934                         if (nors) nors += 3;
935                 }
936         }
937         else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
938                 int prevstart = 0;
939                 GPU_vertex_setup(dm);
940                 GPU_normal_setup(dm);
941                 if( useColors && mc )
942                         GPU_color_setup(dm);
943                 if( !GPU_buffer_legacy(dm) ) {
944                         int tottri = dm->drawObject->tot_triangle_point/3;
945                         glShadeModel(GL_SMOOTH);
946                         
947                         if(tottri == 0) {
948                                 /* avoid buffer problems in following code */
949                         }
950                         if(setDrawOptions == NULL) {
951                                 /* just draw the entire face array */
952                                 glDrawArrays(GL_TRIANGLES, 0, (tottri) * 3);
953                         }
954                         else {
955                                 /* we need to check if the next material changes */
956                                 int next_actualFace= dm->drawObject->triangle_to_mface[0];
957                                 
958                                 for( i = 0; i < tottri; i++ ) {
959                                         //int actualFace = dm->drawObject->triangle_to_mface[i];
960                                         int actualFace = next_actualFace;
961                                         MFace *mface= mf + actualFace;
962                                         int drawSmooth= (mface->flag & ME_SMOOTH);
963                                         int draw = 1;
964                                         int flush = 0;
965
966                                         if(i != tottri-1)
967                                                 next_actualFace= dm->drawObject->triangle_to_mface[i+1];
968
969                                         orig= (index==NULL) ? actualFace : index[actualFace];
970
971                                         if(orig == ORIGINDEX_NONE)
972                                                 draw= setMaterial(mface->mat_nr + 1, NULL);
973                                         else if (setDrawOptions != NULL)
974                                                 draw= setDrawOptions(userData, orig, &drawSmooth);
975         
976                                         /* Goal is to draw as long of a contiguous triangle
977                                            array as possible, so draw when we hit either an
978                                            invisible triangle or at the end of the array */
979
980                                         /* flush buffer if current triangle isn't drawable or it's last triangle... */
981                                         flush= !draw || i == tottri - 1;
982
983                                         /* ... or when material setting is dissferent  */
984                                         flush|= mf[actualFace].mat_nr != mf[next_actualFace].mat_nr;
985
986                                         if(!flush && compareDrawOptions) {
987                                                 flush|= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
988                                         }
989
990                                         if(flush) {
991                                                 int first= prevstart*3;
992                                                 int count= (i-prevstart+(draw ? 1 : 0))*3; /* Add one to the length if we're drawing at the end of the array */
993
994                                                 if(count)
995                                                         glDrawArrays(GL_TRIANGLES, first, count);
996
997                                                 prevstart = i + 1;
998                                         }
999                                 }
1000                         }
1001
1002                         glShadeModel(GL_FLAT);
1003                 }
1004                 GPU_buffer_unbind();
1005         }
1006 }
1007
1008 static void cdDM_drawMappedFacesTex(DerivedMesh *dm,
1009                            int (*setDrawOptions)(void *userData, int index),
1010                            int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
1011                            void *userData)
1012 {
1013         cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData);
1014 }
1015
1016 static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, MVert *mvert, int a, int index, int vert, int smoothnormal)
1017 {
1018         int b;
1019
1020         /* orco texture coordinates */
1021         if(attribs->totorco) {
1022                 if(attribs->orco.glTexco)
1023                         glTexCoord3fv(attribs->orco.array[index]);
1024                 else
1025                         glVertexAttrib3fvARB(attribs->orco.glIndex, attribs->orco.array[index]);
1026         }
1027
1028         /* uv texture coordinates */
1029         for(b = 0; b < attribs->tottface; b++) {
1030                 MTFace *tf = &attribs->tface[b].array[a];
1031
1032                 if(attribs->tface[b].glTexco)
1033                         glTexCoord2fv(tf->uv[vert]);
1034                 else
1035                         glVertexAttrib2fvARB(attribs->tface[b].glIndex, tf->uv[vert]);
1036         }
1037
1038         /* vertex colors */
1039         for(b = 0; b < attribs->totmcol; b++) {
1040                 MCol *cp = &attribs->mcol[b].array[a*4 + vert];
1041                 GLubyte col[4];
1042                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1043                 glVertexAttrib4ubvARB(attribs->mcol[b].glIndex, col);
1044         }
1045
1046         /* tangent for normal mapping */
1047         if(attribs->tottang) {
1048                 float *tang = attribs->tang.array[a*4 + vert];
1049                 glVertexAttrib4fvARB(attribs->tang.glIndex, tang);
1050         }
1051
1052         /* vertex normal */
1053         if(smoothnormal)
1054                 glNormal3sv(mvert[index].no);
1055         
1056         /* vertex coordinate */
1057         glVertex3fv(mvert[index].co);
1058 }
1059
1060 static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
1061                            int (*setMaterial)(int, void *attribs),
1062                            int (*setDrawOptions)(void *userData, int index),
1063                            void *userData)
1064 {
1065         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
1066         GPUVertexAttribs gattribs;
1067         DMVertexAttribs attribs;
1068         MVert *mvert = cddm->mvert;
1069         MFace *mface = cddm->mface;
1070         /* MTFace *tf = dm->getFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */
1071         float (*nors)[3] = dm->getFaceDataArray(dm, CD_NORMAL);
1072         int a, b, dodraw, matnr, new_matnr;
1073         int orig, *index = dm->getFaceDataArray(dm, CD_ORIGINDEX);
1074
1075         cdDM_update_normals_from_pbvh(dm);
1076
1077         matnr = -1;
1078         dodraw = 0;
1079
1080         glShadeModel(GL_SMOOTH);
1081
1082         if( GPU_buffer_legacy(dm) || setDrawOptions != NULL ) {
1083                 DEBUG_VBO( "Using legacy code. cdDM_drawMappedFacesGLSL\n" );
1084                 memset(&attribs, 0, sizeof(attribs));
1085
1086                 glBegin(GL_QUADS);
1087
1088                 for(a = 0; a < dm->numFaceData; a++, mface++) {
1089                         const int smoothnormal = (mface->flag & ME_SMOOTH);
1090                         new_matnr = mface->mat_nr + 1;
1091
1092                         if(new_matnr != matnr) {
1093                                 glEnd();
1094
1095                                 dodraw = setMaterial(matnr = new_matnr, &gattribs);
1096                                 if(dodraw)
1097                                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1098
1099                                 glBegin(GL_QUADS);
1100                         }
1101
1102                         if(!dodraw) {
1103                                 continue;
1104                         }
1105                         else if(setDrawOptions) {
1106                                 orig = (index)? index[a]: a;
1107
1108                                 if(orig == ORIGINDEX_NONE) {
1109                                         /* since the material is set by setMaterial(), faces with no
1110                                          * origin can be assumed to be generated by a modifier */ 
1111                                         
1112                                         /* continue */
1113                                 }
1114                                 else if(!setDrawOptions(userData, orig))
1115                                         continue;
1116                         }
1117
1118                         if(!smoothnormal) {
1119                                 if(nors) {
1120                                         glNormal3fv(nors[a]);
1121                                 }
1122                                 else {
1123                                         /* TODO ideally a normal layer should always be available */
1124                                         float nor[3];
1125                                         if(mface->v4) {
1126                                                 normal_quad_v3( nor,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co);
1127                                         } else {
1128                                                 normal_tri_v3( nor,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co);
1129                                         }
1130                                         glNormal3fv(nor);
1131                                 }
1132                         }
1133
1134                         cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v1, 0, smoothnormal);
1135                         cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v2, 1, smoothnormal);
1136                         cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal);
1137
1138                         if(mface->v4)
1139                                 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v4, 3, smoothnormal);
1140                         else
1141                                 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal);
1142                 }
1143                 glEnd();
1144         }
1145         else {
1146                 GPUBuffer *buffer = NULL;
1147                 char *varray = NULL;
1148                 int numdata = 0, elementsize = 0, offset;
1149                 int start = 0, numfaces = 0 /* , prevdraw = 0 */ /* UNUSED */, curface = 0;
1150                 int i;
1151
1152                 MFace *mf = mface;
1153                 GPUAttrib datatypes[GPU_MAX_ATTRIB]; /* TODO, messing up when switching materials many times - [#21056]*/
1154                 memset(&attribs, 0, sizeof(attribs));
1155
1156                 GPU_vertex_setup(dm);
1157                 GPU_normal_setup(dm);
1158
1159                 if( !GPU_buffer_legacy(dm) ) {
1160                         for( i = 0; i < dm->drawObject->tot_triangle_point/3; i++ ) {
1161
1162                                 a = dm->drawObject->triangle_to_mface[i];
1163
1164                                 mface = mf + a;
1165                                 new_matnr = mface->mat_nr + 1;
1166
1167                                 if(new_matnr != matnr ) {
1168                                         numfaces = curface - start;
1169                                         if( numfaces > 0 ) {
1170
1171                                                 if( dodraw ) {
1172
1173                                                         if( numdata != 0 ) {
1174
1175                                                                 GPU_buffer_unlock(buffer);
1176
1177                                                                 GPU_interleaved_attrib_setup(buffer,datatypes,numdata);
1178                                                         }
1179
1180                                                         glDrawArrays(GL_TRIANGLES,start*3,numfaces*3);
1181
1182                                                         if( numdata != 0 ) {
1183
1184                                                                 GPU_buffer_free(buffer);
1185
1186                                                                 buffer = NULL;
1187                                                         }
1188
1189                                                 }
1190                                         }
1191                                         numdata = 0;
1192                                         start = curface;
1193                                         /* prevdraw = dodraw; */ /* UNUSED */
1194                                         dodraw = setMaterial(matnr = new_matnr, &gattribs);
1195                                         if(dodraw) {
1196                                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1197
1198                                                 if(attribs.totorco) {
1199                                                         datatypes[numdata].index = attribs.orco.glIndex;
1200                                                         datatypes[numdata].size = 3;
1201                                                         datatypes[numdata].type = GL_FLOAT;
1202                                                         numdata++;
1203                                                 }
1204                                                 for(b = 0; b < attribs.tottface; b++) {
1205                                                         datatypes[numdata].index = attribs.tface[b].glIndex;
1206                                                         datatypes[numdata].size = 2;
1207                                                         datatypes[numdata].type = GL_FLOAT;
1208                                                         numdata++;
1209                                                 }       
1210                                                 for(b = 0; b < attribs.totmcol; b++) {
1211                                                         datatypes[numdata].index = attribs.mcol[b].glIndex;
1212                                                         datatypes[numdata].size = 4;
1213                                                         datatypes[numdata].type = GL_UNSIGNED_BYTE;
1214                                                         numdata++;
1215                                                 }       
1216                                                 if(attribs.tottang) {
1217                                                         datatypes[numdata].index = attribs.tang.glIndex;
1218                                                         datatypes[numdata].size = 4;
1219                                                         datatypes[numdata].type = GL_FLOAT;
1220                                                         numdata++;
1221                                                 }
1222                                                 if( numdata != 0 ) {
1223                                                         elementsize = GPU_attrib_element_size( datatypes, numdata );
1224                                                         buffer = GPU_buffer_alloc( elementsize*dm->drawObject->tot_triangle_point);
1225                                                         if( buffer == NULL ) {
1226                                                                 GPU_buffer_unbind();
1227                                                                 dm->drawObject->legacy = 1;
1228                                                                 return;
1229                                                         }
1230                                                         varray = GPU_buffer_lock_stream(buffer);
1231                                                         if( varray == NULL ) {
1232                                                                 GPU_buffer_unbind();
1233                                                                 GPU_buffer_free(buffer);
1234                                                                 dm->drawObject->legacy = 1;
1235                                                                 return;
1236                                                         }
1237                                                 }
1238                                                 else {
1239                                                         /* if the buffer was set, dont use it again.
1240                                                          * prevdraw was assumed true but didnt run so set to false - [#21036] */
1241                                                         /* prevdraw= 0; */ /* UNUSED */
1242                                                         buffer= NULL;
1243                                                 }
1244                                         }
1245                                 }
1246
1247                                 if(dodraw && numdata != 0 ) {
1248                                         offset = 0;
1249                                         if(attribs.totorco) {
1250                                                 copy_v3_v3((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v1]);
1251                                                 copy_v3_v3((float *)&varray[elementsize*curface*3+elementsize],(float *)attribs.orco.array[mface->v2]);
1252                                                 copy_v3_v3((float *)&varray[elementsize*curface*3+elementsize*2],(float *)attribs.orco.array[mface->v3]);
1253                                                 offset += sizeof(float)*3;
1254                                         }
1255                                         for(b = 0; b < attribs.tottface; b++) {
1256                                                 MTFace *tf = &attribs.tface[b].array[a];
1257                                                 copy_v2_v2((float *)&varray[elementsize*curface*3+offset],tf->uv[0]);
1258                                                 copy_v2_v2((float *)&varray[elementsize*curface*3+offset+elementsize],tf->uv[1]);
1259
1260                                                 copy_v2_v2((float *)&varray[elementsize*curface*3+offset+elementsize*2],tf->uv[2]);
1261                                                 offset += sizeof(float)*2;
1262                                         }
1263                                         for(b = 0; b < attribs.totmcol; b++) {
1264                                                 MCol *cp = &attribs.mcol[b].array[a*4 + 0];
1265                                                 GLubyte col[4];
1266                                                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1267                                                 copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset], (char *)col);
1268                                                 cp = &attribs.mcol[b].array[a*4 + 1];
1269                                                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1270                                                 copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset+elementsize], (char *)col);
1271                                                 cp = &attribs.mcol[b].array[a*4 + 2];
1272                                                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1273                                                 copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset+elementsize*2], (char *)col);
1274                                                 offset += sizeof(unsigned char)*4;
1275                                         }       
1276                                         if(attribs.tottang) {
1277                                                 float *tang = attribs.tang.array[a*4 + 0];
1278                                                 copy_v4_v4((float *)&varray[elementsize*curface*3+offset], tang);
1279                                                 tang = attribs.tang.array[a*4 + 1];
1280                                                 copy_v4_v4((float *)&varray[elementsize*curface*3+offset+elementsize], tang);
1281                                                 tang = attribs.tang.array[a*4 + 2];
1282                                                 copy_v4_v4((float *)&varray[elementsize*curface*3+offset+elementsize*2], tang);
1283                                                 offset += sizeof(float)*4;
1284                                         }
1285                                         (void)offset;
1286                                 }
1287                                 curface++;
1288                                 if(mface->v4) {
1289                                         if(dodraw && numdata != 0 ) {
1290                                                 offset = 0;
1291                                                 if(attribs.totorco) {
1292                                                         copy_v3_v3((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v3]);
1293                                                         copy_v3_v3((float *)&varray[elementsize*curface*3+elementsize],(float *)attribs.orco.array[mface->v4]);
1294                                                         copy_v3_v3((float *)&varray[elementsize*curface*3+elementsize*2],(float *)attribs.orco.array[mface->v1]);
1295                                                         offset += sizeof(float)*3;
1296                                                 }
1297                                                 for(b = 0; b < attribs.tottface; b++) {
1298                                                         MTFace *tf = &attribs.tface[b].array[a];
1299                                                         copy_v2_v2((float *)&varray[elementsize*curface*3+offset],tf->uv[2]);
1300                                                         copy_v2_v2((float *)&varray[elementsize*curface*3+offset+elementsize],tf->uv[3]);
1301                                                         copy_v2_v2((float *)&varray[elementsize*curface*3+offset+elementsize*2],tf->uv[0]);
1302                                                         offset += sizeof(float)*2;
1303                                                 }
1304                                                 for(b = 0; b < attribs.totmcol; b++) {
1305                                                         MCol *cp = &attribs.mcol[b].array[a*4 + 2];
1306                                                         GLubyte col[4];
1307                                                         col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1308                                                         copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset], (char *)col);
1309                                                         cp = &attribs.mcol[b].array[a*4 + 3];
1310                                                         col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1311                                                         copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset+elementsize], (char *)col);
1312                                                         cp = &attribs.mcol[b].array[a*4 + 0];
1313                                                         col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1314                                                         copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset+elementsize*2], (char *)col);
1315                                                         offset += sizeof(unsigned char)*4;
1316                                                 }       
1317                                                 if(attribs.tottang) {
1318                                                         float *tang = attribs.tang.array[a*4 + 2];
1319                                                         copy_v4_v4((float *)&varray[elementsize*curface*3+offset], tang);
1320                                                         tang = attribs.tang.array[a*4 + 3];
1321                                                         copy_v4_v4((float *)&varray[elementsize*curface*3+offset+elementsize], tang);
1322                                                         tang = attribs.tang.array[a*4 + 0];
1323                                                         copy_v4_v4((float *)&varray[elementsize*curface*3+offset+elementsize*2], tang);
1324                                                         offset += sizeof(float)*4;
1325                                                 }
1326                                                 (void)offset;
1327                                         }
1328                                         curface++;
1329                                         i++;
1330                                 }
1331                         }
1332                         numfaces = curface - start;
1333                         if( numfaces > 0 ) {
1334                                 if( dodraw ) {
1335                                         if( numdata != 0 ) {
1336                                                 GPU_buffer_unlock(buffer);
1337                                                 GPU_interleaved_attrib_setup(buffer,datatypes,numdata);
1338                                         }
1339                                         glDrawArrays(GL_TRIANGLES,start*3,(curface-start)*3);
1340                                 }
1341                         }
1342                         GPU_buffer_unbind();
1343                 }
1344                 GPU_buffer_free(buffer);
1345         }
1346
1347         glShadeModel(GL_FLAT);
1348 }
1349
1350 static void cdDM_drawFacesGLSL(DerivedMesh *dm,int (*setMaterial)(int, void *attribs))
1351 {
1352         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1353 }
1354
1355 static void cdDM_drawMappedFacesMat(DerivedMesh *dm,
1356         void (*setMaterial)(void *userData, int, void *attribs),
1357         int (*setFace)(void *userData, int index), void *userData)
1358 {
1359         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
1360         GPUVertexAttribs gattribs;
1361         DMVertexAttribs attribs;
1362         MVert *mvert = cddm->mvert;
1363         MFace *mf = cddm->mface;
1364         float (*nors)[3] = dm->getFaceDataArray(dm, CD_NORMAL);
1365         int a, matnr, new_matnr;
1366         int orig, *index = dm->getFaceDataArray(dm, CD_ORIGINDEX);
1367
1368         cdDM_update_normals_from_pbvh(dm);
1369
1370         matnr = -1;
1371
1372         glShadeModel(GL_SMOOTH);
1373
1374         memset(&attribs, 0, sizeof(attribs));
1375
1376         glBegin(GL_QUADS);
1377
1378         for(a = 0; a < dm->numFaceData; a++, mf++) {
1379                 const int smoothnormal = (mf->flag & ME_SMOOTH);
1380
1381                 /* material */
1382                 new_matnr = mf->mat_nr + 1;
1383
1384                 if(new_matnr != matnr) {
1385                         glEnd();
1386
1387                         setMaterial(userData, matnr = new_matnr, &gattribs);
1388                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1389
1390                         glBegin(GL_QUADS);
1391                 }
1392
1393                 /* skipping faces */
1394                 if(setFace) {
1395                         orig = (index)? index[a]: a;
1396
1397                         if(orig != ORIGINDEX_NONE && !setFace(userData, orig))
1398                                 continue;
1399                 }
1400
1401                 /* smooth normal */
1402                 if(!smoothnormal) {
1403                         if(nors) {
1404                                 glNormal3fv(nors[a]);
1405                         }
1406                         else {
1407                                 /* TODO ideally a normal layer should always be available */
1408                                 float nor[3];
1409
1410                                 if(mf->v4)
1411                                         normal_quad_v3( nor,mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co);
1412                                 else
1413                                         normal_tri_v3( nor,mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co);
1414
1415                                 glNormal3fv(nor);
1416                         }
1417                 }
1418
1419                 /* vertices */
1420                 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v1, 0, smoothnormal);
1421                 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v2, 1, smoothnormal);
1422                 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal);
1423
1424                 if(mf->v4)
1425                         cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v4, 3, smoothnormal);
1426                 else
1427                         cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal);
1428         }
1429         glEnd();
1430
1431         glShadeModel(GL_FLAT);
1432 }
1433
1434 static void cdDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
1435 {
1436         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
1437         MVert *vert = cddm->mvert;
1438         MEdge *edge = cddm->medge;
1439         int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1440
1441         glBegin(GL_LINES);
1442         for(i = 0; i < dm->numEdgeData; i++, edge++) {
1443                 if(index) {
1444                         orig = *index++;
1445                         if(setDrawOptions && orig == ORIGINDEX_NONE) continue;
1446                 }
1447                 else
1448                         orig = i;
1449
1450                 if(!setDrawOptions || setDrawOptions(userData, orig)) {
1451                         glVertex3fv(vert[edge->v1].co);
1452                         glVertex3fv(vert[edge->v2].co);
1453                 }
1454         }
1455         glEnd();
1456 }
1457
1458 static void cdDM_foreachMappedVert(
1459                                                    DerivedMesh *dm,
1460                                                    void (*func)(void *userData, int index, float *co,
1461                                                                                 float *no_f, short *no_s),
1462                                                    void *userData)
1463 {
1464         MVert *mv = CDDM_get_verts(dm);
1465         int i, orig, *index = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
1466
1467         for(i = 0; i < dm->numVertData; i++, mv++) {
1468                 if(index) {
1469                         orig = *index++;
1470                         if(orig == ORIGINDEX_NONE) continue;
1471                         func(userData, orig, mv->co, NULL, mv->no);
1472                 }
1473                 else
1474                         func(userData, i, mv->co, NULL, mv->no);
1475         }
1476 }
1477
1478 static void cdDM_foreachMappedEdge(
1479                                                    DerivedMesh *dm,
1480                                                    void (*func)(void *userData, int index,
1481                                                                                 float *v0co, float *v1co),
1482                                                    void *userData)
1483 {
1484         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
1485         MVert *mv = cddm->mvert;
1486         MEdge *med = cddm->medge;
1487         int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1488
1489         for(i = 0; i < dm->numEdgeData; i++, med++) {
1490                 if (index) {
1491                         orig = *index++;
1492                         if(orig == ORIGINDEX_NONE) continue;
1493                         func(userData, orig, mv[med->v1].co, mv[med->v2].co);
1494                 }
1495                 else
1496                         func(userData, i, mv[med->v1].co, mv[med->v2].co);
1497         }
1498 }
1499
1500 static void cdDM_foreachMappedFaceCenter(
1501                                                    DerivedMesh *dm,
1502                                                    void (*func)(void *userData, int index,
1503                                                                                 float *cent, float *no),
1504                                                    void *userData)
1505 {
1506         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1507         MVert *mv = cddm->mvert;
1508         MFace *mf = cddm->mface;
1509         int i, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
1510
1511         for(i = 0; i < dm->numFaceData; i++, mf++) {
1512                 float cent[3];
1513                 float no[3];
1514
1515                 if (index) {
1516                         orig = *index++;
1517                         if(orig == ORIGINDEX_NONE) continue;
1518                 }
1519                 else
1520                         orig = i;
1521
1522                 copy_v3_v3(cent, mv[mf->v1].co);
1523                 add_v3_v3(cent, mv[mf->v2].co);
1524                 add_v3_v3(cent, mv[mf->v3].co);
1525
1526                 if (mf->v4) {
1527                         normal_quad_v3( no,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
1528                         add_v3_v3(cent, mv[mf->v4].co);
1529                         mul_v3_fl(cent, 0.25f);
1530                 } else {
1531                         normal_tri_v3( no,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
1532                         mul_v3_fl(cent, 0.33333333333f);
1533                 }
1534
1535                 func(userData, orig, cent, no);
1536         }
1537 }
1538
1539 static void cdDM_free_internal(CDDerivedMesh *cddm)
1540 {
1541         if(cddm->fmap) MEM_freeN(cddm->fmap);
1542         if(cddm->fmap_mem) MEM_freeN(cddm->fmap_mem);
1543 }
1544
1545 static void cdDM_release(DerivedMesh *dm)
1546 {
1547         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1548
1549         if (DM_release(dm)) {
1550                 cdDM_free_internal(cddm);
1551                 MEM_freeN(cddm);
1552         }
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->getNumFaces = cdDM_getNumFaces;
1568         dm->getNumEdges = cdDM_getNumEdges;
1569
1570         dm->getVert = cdDM_getVert;
1571         dm->getEdge = cdDM_getEdge;
1572         dm->getFace = cdDM_getFace;
1573         dm->copyVertArray = cdDM_copyVertArray;
1574         dm->copyEdgeArray = cdDM_copyEdgeArray;
1575         dm->copyFaceArray = cdDM_copyFaceArray;
1576         dm->getVertData = DM_get_vert_data;
1577         dm->getEdgeData = DM_get_edge_data;
1578         dm->getFaceData = DM_get_face_data;
1579         dm->getVertDataArray = DM_get_vert_data_layer;
1580         dm->getEdgeDataArray = DM_get_edge_data_layer;
1581         dm->getFaceDataArray = DM_get_face_data_layer;
1582
1583         dm->getVertCos = cdDM_getVertCos;
1584         dm->getVertCo = cdDM_getVertCo;
1585         dm->getVertNo = cdDM_getVertNo;
1586
1587         dm->getPBVH = cdDM_getPBVH;
1588         dm->getFaceMap = cdDM_getFaceMap;
1589
1590         dm->drawVerts = cdDM_drawVerts;
1591
1592         dm->drawUVEdges = cdDM_drawUVEdges;
1593         dm->drawEdges = cdDM_drawEdges;
1594         dm->drawLooseEdges = cdDM_drawLooseEdges;
1595         dm->drawMappedEdges = cdDM_drawMappedEdges;
1596
1597         dm->drawFacesSolid = cdDM_drawFacesSolid;
1598         dm->drawFacesColored = cdDM_drawFacesColored;
1599         dm->drawFacesTex = cdDM_drawFacesTex;
1600         dm->drawFacesGLSL = cdDM_drawFacesGLSL;
1601         dm->drawMappedFaces = cdDM_drawMappedFaces;
1602         dm->drawMappedFacesTex = cdDM_drawMappedFacesTex;
1603         dm->drawMappedFacesGLSL = cdDM_drawMappedFacesGLSL;
1604         dm->drawMappedFacesMat = cdDM_drawMappedFacesMat;
1605
1606         dm->foreachMappedVert = cdDM_foreachMappedVert;
1607         dm->foreachMappedEdge = cdDM_foreachMappedEdge;
1608         dm->foreachMappedFaceCenter = cdDM_foreachMappedFaceCenter;
1609
1610         dm->release = cdDM_release;
1611
1612         return cddm;
1613 }
1614
1615 DerivedMesh *CDDM_new(int numVerts, int numEdges, int numFaces)
1616 {
1617         CDDerivedMesh *cddm = cdDM_create("CDDM_new dm");
1618         DerivedMesh *dm = &cddm->dm;
1619
1620         DM_init(dm, DM_TYPE_CDDM, numVerts, numEdges, numFaces);
1621
1622         CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
1623         CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
1624         CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numFaces);
1625
1626         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
1627         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
1628         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numFaces);
1629
1630         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1631         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1632         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1633
1634         return dm;
1635 }
1636
1637 DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob))
1638 {
1639         CDDerivedMesh *cddm = cdDM_create("CDDM_from_mesh dm");
1640         DerivedMesh *dm = &cddm->dm;
1641         CustomDataMask mask = CD_MASK_MESH & (~CD_MASK_MDISPS);
1642         int alloctype;
1643
1644         /* this does a referenced copy, with an exception for fluidsim */
1645
1646         DM_init(dm, DM_TYPE_CDDM, mesh->totvert, mesh->totedge, mesh->totface);
1647
1648         dm->deformedOnly = 1;
1649
1650         alloctype= CD_REFERENCE;
1651
1652         CustomData_merge(&mesh->vdata, &dm->vertData, mask, alloctype,
1653                                          mesh->totvert);
1654         CustomData_merge(&mesh->edata, &dm->edgeData, mask, alloctype,
1655                                          mesh->totedge);
1656         CustomData_merge(&mesh->fdata, &dm->faceData, mask, alloctype,
1657                                          mesh->totface);
1658
1659         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1660         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1661         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1662
1663         return dm;
1664 }
1665
1666 DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *UNUSED(me))
1667 {
1668         DerivedMesh *dm = CDDM_new(BLI_countlist(&em->verts),
1669                                                            BLI_countlist(&em->edges),
1670                                                            BLI_countlist(&em->faces));
1671         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1672         EditVert *eve;
1673         EditEdge *eed;
1674         EditFace *efa;
1675         MVert *mvert = cddm->mvert;
1676         MEdge *medge = cddm->medge;
1677         MFace *mface = cddm->mface;
1678         int i, *index;
1679
1680         dm->deformedOnly = 1;
1681
1682         CustomData_merge(&em->vdata, &dm->vertData, CD_MASK_DERIVEDMESH,
1683                                          CD_CALLOC, dm->numVertData);
1684         /* CustomData_merge(&em->edata, &dm->edgeData, CD_MASK_DERIVEDMESH,
1685                                          CD_CALLOC, dm->numEdgeData); */
1686         CustomData_merge(&em->fdata, &dm->faceData, CD_MASK_DERIVEDMESH,
1687                                          CD_CALLOC, dm->numFaceData);
1688
1689         /* set eve->hash to vert index */
1690         for(i = 0, eve = em->verts.first; eve; eve = eve->next, ++i)
1691                 eve->tmp.l = i;
1692
1693         /* Need to be able to mark loose edges */
1694         for(eed = em->edges.first; eed; eed = eed->next) {
1695                 eed->f2 = 0;
1696         }
1697         for(efa = em->faces.first; efa; efa = efa->next) {
1698                 efa->e1->f2 = 1;
1699                 efa->e2->f2 = 1;
1700                 efa->e3->f2 = 1;
1701                 if(efa->e4) efa->e4->f2 = 1;
1702         }
1703
1704         index = dm->getVertDataArray(dm, CD_ORIGINDEX);
1705         for(i = 0, eve = em->verts.first; i < dm->numVertData;
1706                 i++, eve = eve->next, index++) {
1707                 MVert *mv = &mvert[i];
1708
1709                 copy_v3_v3(mv->co, eve->co);
1710
1711                 normal_float_to_short_v3(mv->no, eve->no);
1712                 mv->bweight = (unsigned char) (eve->bweight * 255.0f);
1713
1714                 mv->flag = 0;
1715
1716                 *index = i;
1717
1718                 CustomData_from_em_block(&em->vdata, &dm->vertData, eve->data, i);
1719         }
1720
1721         index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
1722         for(i = 0, eed = em->edges.first; i < dm->numEdgeData;
1723                 i++, eed = eed->next, index++) {
1724                 MEdge *med = &medge[i];
1725
1726                 med->v1 = eed->v1->tmp.l;
1727                 med->v2 = eed->v2->tmp.l;
1728                 med->crease = (unsigned char) (eed->crease * 255.0f);
1729                 med->bweight = (unsigned char) (eed->bweight * 255.0f);
1730                 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
1731                 
1732                 if(eed->seam) med->flag |= ME_SEAM;
1733                 if(eed->sharp) med->flag |= ME_SHARP;
1734                 if(!eed->f2) med->flag |= ME_LOOSEEDGE;
1735
1736                 *index = i;
1737
1738                 /* CustomData_from_em_block(&em->edata, &dm->edgeData, eed->data, i); */
1739         }
1740
1741         index = dm->getFaceDataArray(dm, CD_ORIGINDEX);
1742         for(i = 0, efa = em->faces.first; i < dm->numFaceData;
1743                 i++, efa = efa->next, index++) {
1744                 MFace *mf = &mface[i];
1745
1746                 mf->v1 = efa->v1->tmp.l;
1747                 mf->v2 = efa->v2->tmp.l;
1748                 mf->v3 = efa->v3->tmp.l;
1749                 mf->v4 = efa->v4 ? efa->v4->tmp.l : 0;
1750                 mf->mat_nr = efa->mat_nr;
1751                 mf->flag = efa->flag;
1752
1753                 *index = i;
1754
1755                 CustomData_from_em_block(&em->fdata, &dm->faceData, efa->data, i);
1756                 test_index_face(mf, &dm->faceData, i, efa->v4?4:3);
1757         }
1758
1759         return dm;
1760 }
1761
1762 DerivedMesh *CDDM_from_curve(Object *ob)
1763 {
1764         return CDDM_from_curve_customDB(ob, &ob->disp);
1765 }
1766
1767 DerivedMesh *CDDM_from_curve_customDB(Object *ob, ListBase *dispbase)
1768 {
1769         DerivedMesh *dm;
1770         CDDerivedMesh *cddm;
1771         MVert *allvert;
1772         MEdge *alledge;
1773         MFace *allface;
1774         int totvert, totedge, totface;
1775
1776         if (nurbs_to_mdata_customdb(ob, dispbase, &allvert, &totvert, &alledge,
1777                 &totedge, &allface, &totface) != 0) {
1778                 /* Error initializing mdata. This often happens when curve is empty */
1779                 return CDDM_new(0, 0, 0);
1780         }
1781
1782         dm = CDDM_new(totvert, totedge, totface);
1783         dm->deformedOnly = 1;
1784
1785         cddm = (CDDerivedMesh*)dm;
1786
1787         memcpy(cddm->mvert, allvert, totvert*sizeof(MVert));
1788         memcpy(cddm->medge, alledge, totedge*sizeof(MEdge));
1789         memcpy(cddm->mface, allface, totface*sizeof(MFace));
1790
1791         MEM_freeN(allvert);
1792         MEM_freeN(alledge);
1793         MEM_freeN(allface);
1794
1795         return dm;
1796 }
1797
1798 DerivedMesh *CDDM_copy(DerivedMesh *source)
1799 {
1800         CDDerivedMesh *cddm = cdDM_create("CDDM_copy cddm");
1801         DerivedMesh *dm = &cddm->dm;
1802         int numVerts = source->numVertData;
1803         int numEdges = source->numEdgeData;
1804         int numFaces = source->numFaceData;
1805
1806         /* ensure these are created if they are made on demand */
1807         source->getVertDataArray(source, CD_ORIGINDEX);
1808         source->getEdgeDataArray(source, CD_ORIGINDEX);
1809         source->getFaceDataArray(source, CD_ORIGINDEX);
1810
1811         /* this initializes dm, and copies all non mvert/medge/mface layers */
1812         DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numFaces);
1813         dm->deformedOnly = source->deformedOnly;
1814
1815         CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts);
1816         CustomData_copy_data(&source->edgeData, &dm->edgeData, 0, 0, numEdges);
1817         CustomData_copy_data(&source->faceData, &dm->faceData, 0, 0, numFaces);
1818
1819         /* now add mvert/medge/mface layers */
1820         cddm->mvert = source->dupVertArray(source);
1821         cddm->medge = source->dupEdgeArray(source);
1822         cddm->mface = source->dupFaceArray(source);
1823
1824         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, cddm->mvert, numVerts);
1825         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, cddm->medge, numEdges);
1826         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, cddm->mface, numFaces);
1827
1828         return dm;
1829 }
1830
1831 /* note, the CD_ORIGINDEX layers are all 0, so if there is a direct
1832  * relationship betwen mesh data this needs to be set by the caller. */
1833 DerivedMesh *CDDM_from_template(DerivedMesh *source,
1834                                                                 int numVerts, int numEdges, int numFaces)
1835 {
1836         CDDerivedMesh *cddm = cdDM_create("CDDM_from_template dest");
1837         DerivedMesh *dm = &cddm->dm;
1838
1839         /* ensure these are created if they are made on demand */
1840         source->getVertDataArray(source, CD_ORIGINDEX);
1841         source->getEdgeDataArray(source, CD_ORIGINDEX);
1842         source->getFaceDataArray(source, CD_ORIGINDEX);
1843
1844         /* this does a copy of all non mvert/medge/mface layers */
1845         DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numFaces);
1846
1847         /* now add mvert/medge/mface layers */
1848         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
1849         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
1850         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numFaces);
1851
1852         if(!CustomData_get_layer(&dm->vertData, CD_ORIGINDEX))
1853                 CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
1854         if(!CustomData_get_layer(&dm->edgeData, CD_ORIGINDEX))
1855                 CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
1856         if(!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX))
1857                 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numFaces);
1858
1859         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1860         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1861         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1862
1863         return dm;
1864 }
1865
1866 void CDDM_apply_vert_coords(DerivedMesh *dm, float (*vertCoords)[3])
1867 {
1868         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1869         MVert *vert;
1870         int i;
1871
1872         /* this will just return the pointer if it wasn't a referenced layer */
1873         vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
1874         cddm->mvert = vert;
1875
1876         for(i = 0; i < dm->numVertData; ++i, ++vert)
1877                 copy_v3_v3(vert->co, vertCoords[i]);
1878 }
1879
1880 void CDDM_apply_vert_normals(DerivedMesh *dm, short (*vertNormals)[3])
1881 {
1882         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1883         MVert *vert;
1884         int i;
1885
1886         /* this will just return the pointer if it wasn't a referenced layer */
1887         vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
1888         cddm->mvert = vert;
1889
1890         for(i = 0; i < dm->numVertData; ++i, ++vert)
1891                 copy_v3_v3_short(vert->no, vertNormals[i]);
1892 }
1893
1894 void CDDM_calc_normals(DerivedMesh *dm)
1895 {
1896         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1897         float (*face_nors)[3];
1898
1899         if(dm->numVertData == 0) return;
1900
1901         /* we don't want to overwrite any referenced layers */
1902         cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
1903
1904         /* make a face normal layer if not present */
1905         face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
1906         if(!face_nors)
1907                 face_nors = CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_CALLOC,
1908                                                                                  NULL, dm->numFaceData);
1909
1910         /* calculate face normals */
1911         mesh_calc_normals(cddm->mvert, dm->numVertData, CDDM_get_faces(dm), dm->numFaceData, face_nors);
1912 }
1913
1914 void CDDM_calc_edges(DerivedMesh *dm)
1915 {
1916         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1917         CustomData edgeData;
1918         EdgeHashIterator *ehi;
1919         MFace *mf = cddm->mface;
1920         MEdge *med;
1921         EdgeHash *eh = BLI_edgehash_new();
1922         int i, *index, numEdges, maxFaces = dm->numFaceData;
1923
1924         for (i = 0; i < maxFaces; i++, mf++) {
1925                 if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
1926                         BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
1927                 if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
1928                         BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
1929                 
1930                 if (mf->v4) {
1931                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
1932                                 BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
1933                         if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
1934                                 BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
1935                 } else {
1936                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
1937                                 BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
1938                 }
1939         }
1940
1941         numEdges = BLI_edgehash_size(eh);
1942
1943         /* write new edges into a temporary CustomData */
1944         memset(&edgeData, 0, sizeof(edgeData));
1945         CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
1946         CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
1947
1948         ehi = BLI_edgehashIterator_new(eh);
1949         med = CustomData_get_layer(&edgeData, CD_MEDGE);
1950         index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
1951         for(i = 0; !BLI_edgehashIterator_isDone(ehi);
1952                 BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) {
1953                 BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2);
1954
1955                 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
1956                 *index = ORIGINDEX_NONE;
1957         }
1958         BLI_edgehashIterator_free(ehi);
1959
1960         /* free old CustomData and assign new one */
1961         CustomData_free(&dm->edgeData, dm->numEdgeData);
1962         dm->edgeData = edgeData;
1963         dm->numEdgeData = numEdges;
1964
1965         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1966
1967         BLI_edgehash_free(eh, NULL);
1968 }
1969
1970 void CDDM_lower_num_verts(DerivedMesh *dm, int numVerts)
1971 {
1972         if (numVerts < dm->numVertData)
1973                 CustomData_free_elem(&dm->vertData, numVerts, dm->numVertData-numVerts);
1974
1975         dm->numVertData = numVerts;
1976 }
1977
1978 void CDDM_lower_num_edges(DerivedMesh *dm, int numEdges)
1979 {
1980         if (numEdges < dm->numEdgeData)
1981                 CustomData_free_elem(&dm->edgeData, numEdges, dm->numEdgeData-numEdges);
1982
1983         dm->numEdgeData = numEdges;
1984 }
1985
1986 void CDDM_lower_num_faces(DerivedMesh *dm, int numFaces)
1987 {
1988         if (numFaces < dm->numFaceData)
1989                 CustomData_free_elem(&dm->faceData, numFaces, dm->numFaceData-numFaces);
1990
1991         dm->numFaceData = numFaces;
1992 }
1993
1994 MVert *CDDM_get_vert(DerivedMesh *dm, int index)
1995 {
1996         return &((CDDerivedMesh*)dm)->mvert[index];
1997 }
1998
1999 MEdge *CDDM_get_edge(DerivedMesh *dm, int index)
2000 {
2001         return &((CDDerivedMesh*)dm)->medge[index];
2002 }
2003
2004 MFace *CDDM_get_face(DerivedMesh *dm, int index)
2005 {
2006         return &((CDDerivedMesh*)dm)->mface[index];
2007 }
2008
2009 MVert *CDDM_get_verts(DerivedMesh *dm)
2010 {
2011         return ((CDDerivedMesh*)dm)->mvert;
2012 }
2013
2014 MEdge *CDDM_get_edges(DerivedMesh *dm)
2015 {
2016         return ((CDDerivedMesh*)dm)->medge;
2017 }
2018
2019 MFace *CDDM_get_faces(DerivedMesh *dm)
2020 {
2021         return ((CDDerivedMesh*)dm)->mface;
2022 }
2023