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