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