svn merge -r39765:39781 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                         int (*compareDrawOptions)(void *userData, int cur_index, int next_index))
879 {
880         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
881         MVert *mv = cddm->mvert;
882         MFace *mf = cddm->mface;
883         MCol *mc;
884         float *nors= DM_get_tessface_data_layer(dm, CD_NORMAL);
885         int i, orig, *index = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
886
887         mc = DM_get_tessface_data_layer(dm, CD_ID_MCOL);
888         if(!mc)
889                 mc = DM_get_tessface_data_layer(dm, CD_WEIGHT_MCOL);
890         if(!mc)
891                 mc = DM_get_tessface_data_layer(dm, CD_MCOL);
892
893         cdDM_update_normals_from_pbvh(dm);
894
895         /* back-buffer always uses legacy since VBO's would need the
896          * color array temporarily overwritten for drawing, then reset. */
897         if( GPU_buffer_legacy(dm) || G.f & G_BACKBUFSEL) {
898                 DEBUG_VBO( "Using legacy code. cdDM_drawMappedFaces\n" );
899                 for(i = 0; i < dm->numFaceData; i++, mf++) {
900                         int drawSmooth = (mf->flag & ME_SMOOTH);
901                         int draw= 1;
902
903                         orig= (index==NULL) ? i : *index++;
904                         
905                         if(orig == ORIGINDEX_NONE)
906                                 draw= setMaterial(mf->mat_nr + 1, NULL);
907                         else if (setDrawOptions != NULL)
908                                 draw= setDrawOptions(userData, orig, &drawSmooth);
909
910                         if(draw) {
911                                 unsigned char *cp = NULL;
912
913                                 if(useColors && mc)
914                                         cp = (unsigned char *)&mc[i * 4];
915
916                                 glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
917                                 glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
918
919                                 if (!drawSmooth) {
920                                         if (nors) {
921                                                 glNormal3fv(nors);
922                                         }
923                                         else {
924                                                 float nor[3];
925                                                 if(mf->v4) {
926                                                         normal_quad_v3( nor,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
927                                                 } else {
928                                                         normal_tri_v3( nor,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
929                                                 }
930                                                 glNormal3fv(nor);
931                                         }
932
933                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
934                                         glVertex3fv(mv[mf->v1].co);
935                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
936                                         glVertex3fv(mv[mf->v2].co);
937                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
938                                         glVertex3fv(mv[mf->v3].co);
939                                         if(mf->v4) {
940                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
941                                                 glVertex3fv(mv[mf->v4].co);
942                                         }
943                                 } else {
944                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
945                                         glNormal3sv(mv[mf->v1].no);
946                                         glVertex3fv(mv[mf->v1].co);
947                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
948                                         glNormal3sv(mv[mf->v2].no);
949                                         glVertex3fv(mv[mf->v2].co);
950                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
951                                         glNormal3sv(mv[mf->v3].no);
952                                         glVertex3fv(mv[mf->v3].co);
953                                         if(mf->v4) {
954                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
955                                                 glNormal3sv(mv[mf->v4].no);
956                                                 glVertex3fv(mv[mf->v4].co);
957                                         }
958                                 }
959
960                                 glEnd();
961                         } /*else {
962                                 printf("eek in cddm draw mapped faces!\n");
963                         }*/
964                         
965                         if (nors) nors += 3;
966                 }
967         }
968         else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
969                 int prevstart = 0;
970                 GPU_vertex_setup(dm);
971                 GPU_normal_setup(dm);
972                 if( useColors && mc )
973                         GPU_color_setup(dm);
974                 if( !GPU_buffer_legacy(dm) ) {
975                         int tottri = dm->drawObject->tot_triangle_point/3;
976                         glShadeModel(GL_SMOOTH);
977                         
978                         if(tottri == 0) {
979                                 /* avoid buffer problems in following code */
980                         }
981                         if(setDrawOptions == NULL) {
982                                 /* just draw the entire face array */
983                                 glDrawArrays(GL_TRIANGLES, 0, (tottri-1) * 3);
984                         }
985                         else {
986                                 /* we need to check if the next material changes */
987                                 int next_actualFace= dm->drawObject->triangle_to_mface[0];
988                                 
989                                 for( i = 0; i < tottri; i++ ) {
990                                         //int actualFace = dm->drawObject->triangle_to_mface[i];
991                                         int actualFace = next_actualFace;
992                                         MFace *mface= mf + actualFace;
993                                         int drawSmooth= (mface->flag & ME_SMOOTH);
994                                         int draw = 1;
995                                         int flush = 0;
996
997                                         if(i != tottri-1)
998                                                 next_actualFace= dm->drawObject->triangle_to_mface[i+1];
999
1000                                         orig= (index==NULL) ? actualFace : index[actualFace];
1001
1002                                         if(orig == ORIGINDEX_NONE)
1003                                                 draw= setMaterial(mface->mat_nr + 1, NULL);
1004                                         else if (setDrawOptions != NULL)
1005                                                 draw= setDrawOptions(userData, orig, &drawSmooth);
1006         
1007                                         /* Goal is to draw as long of a contiguous triangle
1008                                            array as possible, so draw when we hit either an
1009                                            invisible triangle or at the end of the array */
1010
1011                                         /* flush buffer if current triangle isn't drawable or it's last triangle... */
1012                                         flush= !draw || i == tottri - 1;
1013
1014                                         /* ... or when material setting is dissferent  */
1015                                         flush|= mf[actualFace].mat_nr != mf[next_actualFace].mat_nr;
1016
1017                                         if(!flush && compareDrawOptions) {
1018                                                 int next_orig= (index==NULL) ? next_actualFace : index[next_actualFace];
1019
1020                                                 /* also compare draw options and flush buffer if they're different
1021                                                    need for face selection highlight in edit mode */
1022                                                 flush|= compareDrawOptions(userData, orig, next_orig) == 0;
1023                                         }
1024
1025                                         if(flush) {
1026                                                 int first= prevstart*3;
1027                                                 int count= (i-prevstart+(draw ? 1 : 0))*3; /* Add one to the length if we're drawing at the end of the array */
1028
1029                                                 if(count)
1030                                                         glDrawArrays(GL_TRIANGLES, first, count);
1031
1032                                                 prevstart = i + 1;
1033                                         }
1034                                 }
1035                         }
1036
1037                         glShadeModel(GL_FLAT);
1038                 }
1039                 GPU_buffer_unbind();
1040         }
1041 }
1042
1043 static void cdDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
1044 {
1045         cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
1046 }
1047
1048
1049 static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, MVert *mvert, int a, int index, int vert, int smoothnormal)
1050 {
1051         int b;
1052
1053         /* orco texture coordinates */
1054         if(attribs->totorco) {
1055                 if(attribs->orco.glTexco)
1056                         glTexCoord3fv(attribs->orco.array[index]);
1057                 else
1058                         glVertexAttrib3fvARB(attribs->orco.glIndex, attribs->orco.array[index]);
1059         }
1060
1061         /* uv texture coordinates */
1062         for(b = 0; b < attribs->tottface; b++) {
1063                 MTFace *tf = &attribs->tface[b].array[a];
1064
1065                 if(attribs->tface[b].glTexco)
1066                         glTexCoord2fv(tf->uv[vert]);
1067                 else
1068                         glVertexAttrib2fvARB(attribs->tface[b].glIndex, tf->uv[vert]);
1069         }
1070
1071         /* vertex colors */
1072         for(b = 0; b < attribs->totmcol; b++) {
1073                 MCol *cp = &attribs->mcol[b].array[a*4 + vert];
1074                 GLubyte col[4];
1075                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1076                 glVertexAttrib4ubvARB(attribs->mcol[b].glIndex, col);
1077         }
1078
1079         /* tangent for normal mapping */
1080         if(attribs->tottang) {
1081                 float *tang = attribs->tang.array[a*4 + vert];
1082                 glVertexAttrib4fvARB(attribs->tang.glIndex, tang);
1083         }
1084
1085         /* vertex normal */
1086         if(smoothnormal)
1087                 glNormal3sv(mvert[index].no);
1088
1089         /* vertex coordinate */
1090         glVertex3fv(mvert[index].co);
1091 }
1092
1093
1094 static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs), int (*setDrawOptions)(void *userData, int index), void *userData)
1095 {
1096         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
1097         GPUVertexAttribs gattribs;
1098         DMVertexAttribs attribs;
1099         MVert *mvert = cddm->mvert;
1100         MFace *mface = cddm->mface;
1101         MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE);
1102         float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL);
1103         int a, b, dodraw, matnr, new_matnr;
1104         int transp, new_transp, orig_transp;
1105         int orig, *index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1106
1107         cdDM_update_normals_from_pbvh(dm);
1108
1109         matnr = -1;
1110         dodraw = 0;
1111         transp = GPU_get_material_blend_mode();
1112         orig_transp = transp;
1113
1114         glShadeModel(GL_SMOOTH);
1115
1116         if( GPU_buffer_legacy(dm) || setDrawOptions != NULL ) {
1117                 DEBUG_VBO( "Using legacy code. cdDM_drawMappedFacesGLSL\n" );
1118                 memset(&attribs, 0, sizeof(attribs));
1119
1120                 glBegin(GL_QUADS);
1121
1122                 for(a = 0; a < dm->numFaceData; a++, mface++) {
1123                         const int smoothnormal = (mface->flag & ME_SMOOTH);
1124                         new_matnr = mface->mat_nr + 1;
1125
1126                         if(new_matnr != matnr) {
1127                                 glEnd();
1128
1129                                 dodraw = setMaterial(matnr = new_matnr, &gattribs);
1130                                 if(dodraw)
1131                                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1132
1133                                 glBegin(GL_QUADS);
1134                         }
1135
1136                         if(!dodraw) {
1137                                 continue;
1138                         }
1139                         else if(setDrawOptions) {
1140                                 orig = (index)? index[a]: a;
1141
1142                                 if(orig == ORIGINDEX_NONE) {
1143                                         /* since the material is set by setMaterial(), faces with no
1144                                          * origin can be assumed to be generated by a modifier */ 
1145                                         
1146                                         /* continue */
1147                                 }
1148                                 else if(!setDrawOptions(userData, orig))
1149                                         continue;
1150                         }
1151
1152                         if(tf) {
1153                                 new_transp = tf[a].transp;
1154
1155                                 if(new_transp != transp) {
1156                                         glEnd();
1157
1158                                         if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
1159                                                 GPU_set_material_blend_mode(orig_transp);
1160                                         else
1161                                                 GPU_set_material_blend_mode(new_transp);
1162                                         transp = new_transp;
1163
1164                                         glBegin(GL_QUADS);
1165                                 }
1166                         }
1167
1168                         if(!smoothnormal) {
1169                                 if(nors) {
1170                                         glNormal3fv(nors[a]);
1171                                 }
1172                                 else {
1173                                         /* TODO ideally a normal layer should always be available */
1174                                         float nor[3];
1175                                         if(mface->v4) {
1176                                                 normal_quad_v3( nor,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co);
1177                                         } else {
1178                                                 normal_tri_v3( nor,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co);
1179                                         }
1180                                         glNormal3fv(nor);
1181                                 }
1182                         }
1183
1184                         cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v1, 0, smoothnormal);
1185                         cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v2, 1, smoothnormal);
1186                         cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal);
1187                         if(mface->v4)
1188                                 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v4, 3, smoothnormal);
1189                         else
1190                                 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal);
1191
1192                 }
1193                 glEnd();
1194         }
1195         else {
1196                 GPUBuffer *buffer = NULL;
1197                 char *varray = NULL;
1198                 int numdata = 0, elementsize = 0, offset;
1199                 int start = 0, numfaces = 0, prevdraw = 0, curface = 0;
1200                 int i;
1201
1202                 MFace *mf = mface;
1203                 GPUAttrib datatypes[GPU_MAX_ATTRIB]; /* TODO, messing up when switching materials many times - [#21056]*/
1204                 memset(&attribs, 0, sizeof(attribs));
1205
1206                 GPU_vertex_setup(dm);
1207                 GPU_normal_setup(dm);
1208
1209                 if( !GPU_buffer_legacy(dm) ) {
1210                         for( i = 0; i < dm->drawObject->tot_triangle_point/3; i++ ) {
1211
1212                                 a = dm->drawObject->triangle_to_mface[i];
1213
1214                                 mface = mf + a;
1215                                 new_matnr = mface->mat_nr + 1;
1216
1217                                 if(new_matnr != matnr ) {
1218                                         numfaces = curface - start;
1219                                         if( numfaces > 0 ) {
1220
1221                                                 if( dodraw ) {
1222
1223                                                         if( numdata != 0 ) {
1224
1225                                                                 GPU_buffer_unlock(buffer);
1226
1227                                                                 GPU_interleaved_attrib_setup(buffer,datatypes,numdata);
1228                                                         }
1229
1230                                                         glDrawArrays(GL_TRIANGLES,start*3,numfaces*3);
1231
1232                                                         if( numdata != 0 ) {
1233
1234                                                                 GPU_buffer_free(buffer);
1235
1236                                                                 buffer = NULL;
1237                                                         }
1238
1239                                                 }
1240                                         }
1241                                         numdata = 0;
1242                                         start = curface;
1243                                         prevdraw = dodraw;
1244                                         dodraw = setMaterial(matnr = new_matnr, &gattribs);
1245                                         if(dodraw) {
1246                                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1247
1248                                                 if(attribs.totorco) {
1249                                                         datatypes[numdata].index = attribs.orco.glIndex;
1250                                                         datatypes[numdata].size = 3;
1251                                                         datatypes[numdata].type = GL_FLOAT;
1252                                                         numdata++;
1253                                                 }
1254                                                 for(b = 0; b < attribs.tottface; b++) {
1255                                                         datatypes[numdata].index = attribs.tface[b].glIndex;
1256                                                         datatypes[numdata].size = 2;
1257                                                         datatypes[numdata].type = GL_FLOAT;
1258                                                         numdata++;
1259                                                 }       
1260                                                 for(b = 0; b < attribs.totmcol; b++) {
1261                                                         datatypes[numdata].index = attribs.mcol[b].glIndex;
1262                                                         datatypes[numdata].size = 4;
1263                                                         datatypes[numdata].type = GL_UNSIGNED_BYTE;
1264                                                         numdata++;
1265                                                 }       
1266                                                 if(attribs.tottang) {
1267                                                         datatypes[numdata].index = attribs.tang.glIndex;
1268                                                         datatypes[numdata].size = 4;
1269                                                         datatypes[numdata].type = GL_FLOAT;
1270                                                         numdata++;
1271                                                 }
1272                                                 if( numdata != 0 ) {
1273                                                         elementsize = GPU_attrib_element_size( datatypes, numdata );
1274                                                         buffer = GPU_buffer_alloc( elementsize*dm->drawObject->tot_triangle_point);
1275                                                         if( buffer == NULL ) {
1276                                                                 GPU_buffer_unbind();
1277                                                                 dm->drawObject->legacy = 1;
1278                                                                 return;
1279                                                         }
1280                                                         varray = GPU_buffer_lock_stream(buffer);
1281                                                         if( varray == NULL ) {
1282                                                                 GPU_buffer_unbind();
1283                                                                 GPU_buffer_free(buffer);
1284                                                                 dm->drawObject->legacy = 1;
1285                                                                 return;
1286                                                         }
1287                                                 }
1288                                                 else {
1289                                                         /* if the buffer was set, dont use it again.
1290                                                          * prevdraw was assumed true but didnt run so set to false - [#21036] */
1291                                                         prevdraw= 0;
1292                                                         buffer= NULL;
1293                                                 }
1294                                         }
1295                                 }
1296                                 if(!dodraw) {
1297                                         continue;
1298                                 }
1299
1300                                 if(tf) {
1301                                         new_transp = tf[a].transp;
1302
1303                                         if(new_transp != transp) {
1304                                                 numfaces = curface - start;
1305                                                 if( numfaces > 0 ) {
1306                                                         if( dodraw ) {
1307                                                                 if( numdata != 0 ) {
1308                                                                         GPU_buffer_unlock(buffer);
1309                                                                         GPU_interleaved_attrib_setup(buffer,datatypes,numdata);
1310                                                                 }
1311                                                                 glDrawArrays(GL_TRIANGLES,start*3,(curface-start)*3);
1312                                                                 if( numdata != 0 ) {
1313                                                                         varray = GPU_buffer_lock_stream(buffer);
1314                                                                 }
1315                                                         }
1316                                                 }
1317                                                 start = curface;
1318
1319                                                 if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
1320                                                         GPU_set_material_blend_mode(orig_transp);
1321                                                 else
1322                                                         GPU_set_material_blend_mode(new_transp);
1323                                                 transp = new_transp;
1324                                         }
1325                                 }
1326                                 
1327                                 if( numdata != 0 ) {
1328                                         offset = 0;
1329                                         if(attribs.totorco) {
1330                                                 VECCOPY((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v1]);
1331                                                 VECCOPY((float *)&varray[elementsize*curface*3+elementsize],(float *)attribs.orco.array[mface->v2]);
1332                                                 VECCOPY((float *)&varray[elementsize*curface*3+elementsize*2],(float *)attribs.orco.array[mface->v3]);
1333                                                 offset += sizeof(float)*3;
1334                                         }
1335                                         for(b = 0; b < attribs.tottface; b++) {
1336                                                 MTFace *tf = &attribs.tface[b].array[a];
1337                                                 VECCOPY2D((float *)&varray[elementsize*curface*3+offset],tf->uv[0]);
1338                                                 VECCOPY2D((float *)&varray[elementsize*curface*3+offset+elementsize],tf->uv[1]);
1339
1340                                                 VECCOPY2D((float *)&varray[elementsize*curface*3+offset+elementsize*2],tf->uv[2]);
1341                                                 offset += sizeof(float)*2;
1342                                         }
1343                                         for(b = 0; b < attribs.totmcol; b++) {
1344                                                 MCol *cp = &attribs.mcol[b].array[a*4 + 0];
1345                                                 GLubyte col[4];
1346                                                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1347                                                 QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset], col);
1348                                                 cp = &attribs.mcol[b].array[a*4 + 1];
1349                                                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1350                                                 QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset+elementsize], col);
1351                                                 cp = &attribs.mcol[b].array[a*4 + 2];
1352                                                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1353                                                 QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset+elementsize*2], col);
1354                                                 offset += sizeof(unsigned char)*4;
1355                                         }       
1356                                         if(attribs.tottang) {
1357                                                 float *tang = attribs.tang.array[a*4 + 0];
1358                                                 QUATCOPY((float *)&varray[elementsize*curface*3+offset], tang);
1359                                                 tang = attribs.tang.array[a*4 + 1];
1360                                                 QUATCOPY((float *)&varray[elementsize*curface*3+offset+elementsize], tang);
1361                                                 tang = attribs.tang.array[a*4 + 2];
1362                                                 QUATCOPY((float *)&varray[elementsize*curface*3+offset+elementsize*2], tang);
1363                                                 offset += sizeof(float)*4;
1364                                         }
1365                                         (void)offset;
1366                                 }
1367                                 curface++;
1368                                 if(mface->v4) {
1369                                         if( numdata != 0 ) {
1370                                                 offset = 0;
1371                                                 if(attribs.totorco) {
1372                                                         VECCOPY((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v3]);
1373                                                         VECCOPY((float *)&varray[elementsize*curface*3+elementsize],(float *)attribs.orco.array[mface->v4]);
1374                                                         VECCOPY((float *)&varray[elementsize*curface*3+elementsize*2],(float *)attribs.orco.array[mface->v1]);
1375                                                         offset += sizeof(float)*3;
1376                                                 }
1377                                                 for(b = 0; b < attribs.tottface; b++) {
1378                                                         MTFace *tf = &attribs.tface[b].array[a];
1379                                                         VECCOPY2D((float *)&varray[elementsize*curface*3+offset],tf->uv[2]);
1380                                                         VECCOPY2D((float *)&varray[elementsize*curface*3+offset+elementsize],tf->uv[3]);
1381                                                         VECCOPY2D((float *)&varray[elementsize*curface*3+offset+elementsize*2],tf->uv[0]);
1382                                                         offset += sizeof(float)*2;
1383                                                 }
1384                                                 for(b = 0; b < attribs.totmcol; b++) {
1385                                                         MCol *cp = &attribs.mcol[b].array[a*4 + 2];
1386                                                         GLubyte col[4];
1387                                                         col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1388                                                         QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset], col);
1389                                                         cp = &attribs.mcol[b].array[a*4 + 3];
1390                                                         col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1391                                                         QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset+elementsize], col);
1392                                                         cp = &attribs.mcol[b].array[a*4 + 0];
1393                                                         col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1394                                                         QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset+elementsize*2], col);
1395                                                         offset += sizeof(unsigned char)*4;
1396                                                 }       
1397                                                 if(attribs.tottang) {
1398                                                         float *tang = attribs.tang.array[a*4 + 2];
1399                                                         QUATCOPY((float *)&varray[elementsize*curface*3+offset], tang);
1400                                                         tang = attribs.tang.array[a*4 + 3];
1401                                                         QUATCOPY((float *)&varray[elementsize*curface*3+offset+elementsize], tang);
1402                                                         tang = attribs.tang.array[a*4 + 0];
1403                                                         QUATCOPY((float *)&varray[elementsize*curface*3+offset+elementsize*2], tang);
1404                                                         offset += sizeof(float)*4;
1405                                                 }
1406                                                 (void)offset;
1407                                         }
1408                                         curface++;
1409                                         i++;
1410                                 }
1411                         }
1412                         numfaces = curface - start;
1413                         if( numfaces > 0 ) {
1414                                 if( dodraw ) {
1415                                         if( numdata != 0 ) {
1416                                                 GPU_buffer_unlock(buffer);
1417                                                 GPU_interleaved_attrib_setup(buffer,datatypes,numdata);
1418                                         }
1419                                         glDrawArrays(GL_TRIANGLES,start*3,(curface-start)*3);
1420                                 }
1421                         }
1422                         GPU_buffer_unbind();
1423                 }
1424                 GPU_buffer_free(buffer);
1425         }
1426
1427         glShadeModel(GL_FLAT);
1428 }
1429
1430 static void cdDM_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs))
1431 {
1432         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1433 }
1434
1435 static void cdDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
1436 {
1437         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
1438         MVert *vert = cddm->mvert;
1439         MEdge *edge = cddm->medge;
1440         int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1441
1442         glBegin(GL_LINES);
1443         for(i = 0; i < dm->numEdgeData; i++, edge++) {
1444                 if(index) {
1445                         orig = *index++;
1446                         if(setDrawOptions && orig == ORIGINDEX_NONE) continue;
1447                 }
1448                 else
1449                         orig = i;
1450
1451                 if(!setDrawOptions || setDrawOptions(userData, orig)) {
1452                         glVertex3fv(vert[edge->v1].co);
1453                         glVertex3fv(vert[edge->v2].co);
1454                 }
1455         }
1456         glEnd();
1457 }
1458
1459 static void cdDM_foreachMappedVert(
1460                                                    DerivedMesh *dm,
1461                                                    void (*func)(void *userData, int index, float *co,
1462                                                                                 float *no_f, short *no_s),
1463                                                    void *userData)
1464 {
1465         MVert *mv = CDDM_get_verts(dm);
1466         int i, orig, *index = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
1467
1468         for(i = 0; i < dm->numVertData; i++, mv++) {
1469                 if(index) {
1470                         orig = *index++;
1471                         if(orig == ORIGINDEX_NONE) continue;
1472                         func(userData, orig, mv->co, NULL, mv->no);
1473                 }
1474                 else
1475                         func(userData, i, mv->co, NULL, mv->no);
1476         }
1477 }
1478
1479 static void cdDM_foreachMappedEdge(
1480                                                    DerivedMesh *dm,
1481                                                    void (*func)(void *userData, int index,
1482                                                                                 float *v0co, float *v1co),
1483                                                    void *userData)
1484 {
1485         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
1486         MVert *mv = cddm->mvert;
1487         MEdge *med = cddm->medge;
1488         int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1489
1490         for(i = 0; i < dm->numEdgeData; i++, med++) {
1491                 if (index) {
1492                         orig = *index++;
1493                         if(orig == ORIGINDEX_NONE) continue;
1494                         func(userData, orig, mv[med->v1].co, mv[med->v2].co);
1495                 }
1496                 else
1497                         func(userData, i, mv[med->v1].co, mv[med->v2].co);
1498         }
1499 }
1500
1501 static void cdDM_foreachMappedFaceCenter(
1502                                                    DerivedMesh *dm,
1503                                                    void (*func)(void *userData, int index,
1504                                                                                 float *cent, float *no),
1505                                                    void *userData)
1506 {
1507         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1508         MVert *mv = cddm->mvert;
1509         MPoly *mf = cddm->mpoly;
1510         MLoop *ml = cddm->mloop;
1511         int i, j, orig, *index;
1512
1513         index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
1514         mf = cddm->mpoly;
1515         for(i = 0; i < dm->numPolyData; i++, mf++) {
1516                 float cent[3];
1517                 float no[3];
1518
1519                 if (index) {
1520                         orig = *index++;
1521                         if(orig == ORIGINDEX_NONE) continue;
1522                 } else
1523                         orig = i;
1524                 
1525                 ml = &cddm->mloop[mf->loopstart];
1526                 cent[0] = cent[1] = cent[2] = 0.0f;
1527                 for (j=0; j<mf->totloop; j++, ml++) {
1528                         add_v3_v3v3(cent, cent, mv[ml->v].co);
1529                 }
1530                 mul_v3_fl(cent, 1.0f / (float)j);
1531
1532                 ml = &cddm->mloop[mf->loopstart];
1533                 if (j > 3) {
1534                         normal_quad_v3(no, mv[ml->v].co, mv[(ml+1)->v].co,
1535                                        mv[(ml+2)->v].co, mv[(ml+3)->v].co);
1536                 } else {
1537                         normal_tri_v3(no, mv[ml->v].co, mv[(ml+1)->v].co,
1538                                        mv[(ml+2)->v].co);
1539                 }
1540
1541                 func(userData, orig, cent, no);
1542         }
1543
1544 }
1545
1546 static void cdDM_recalcTesselation(DerivedMesh *dm)
1547 {
1548         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1549
1550         dm->numFaceData = mesh_recalcTesselation(&dm->faceData, &dm->loopData, 
1551                 &dm->polyData, cddm->mvert, dm->numFaceData, dm->numLoopData, 
1552                 dm->numPolyData, 1, 0);
1553         
1554         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1555 }
1556
1557 /*ignores original poly origindex layer*/
1558 static void cdDM_recalcTesselation2(DerivedMesh *dm)
1559 {
1560         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1561
1562         dm->numFaceData = mesh_recalcTesselation(&dm->faceData, &dm->loopData, 
1563                 &dm->polyData, cddm->mvert, dm->numFaceData, dm->numLoopData, 
1564                 dm->numPolyData, 0, 0);
1565         
1566         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1567 }
1568
1569 void CDDM_recalc_tesselation(DerivedMesh *dm, int orig_use_polyorig)
1570 {
1571         if (orig_use_polyorig)
1572                 cdDM_recalcTesselation(dm);
1573         else
1574                 cdDM_recalcTesselation2(dm);
1575 }
1576
1577 static void cdDM_free_internal(CDDerivedMesh *cddm)
1578 {
1579         if(cddm->fmap) MEM_freeN(cddm->fmap);
1580         if(cddm->fmap_mem) MEM_freeN(cddm->fmap_mem);
1581 }
1582
1583 static void cdDM_release(DerivedMesh *dm)
1584 {
1585         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1586
1587         if (DM_release(dm)) {
1588                 cdDM_free_internal(cddm);
1589                 MEM_freeN(cddm);
1590         }
1591 }
1592
1593 int CDDM_Check(DerivedMesh *dm)
1594 {
1595         return dm && dm->getMinMax == cdDM_getMinMax;
1596 }
1597
1598 /**************** CDDM interface functions ****************/
1599 static CDDerivedMesh *cdDM_create(const char *desc)
1600 {
1601         CDDerivedMesh *cddm;
1602         DerivedMesh *dm;
1603
1604         cddm = MEM_callocN(sizeof(*cddm), desc);
1605         dm = &cddm->dm;
1606
1607         dm->getMinMax = cdDM_getMinMax;
1608
1609         dm->getNumVerts = cdDM_getNumVerts;
1610         dm->getNumEdges = cdDM_getNumEdges;
1611         dm->getNumTessFaces = cdDM_getNumTessFaces;
1612         dm->getNumFaces = cdDM_getNumFaces;
1613
1614         dm->getVert = cdDM_getVert;
1615         dm->getEdge = cdDM_getEdge;
1616         dm->getTessFace = cdDM_getFace;
1617         dm->copyVertArray = cdDM_copyVertArray;
1618         dm->copyEdgeArray = cdDM_copyEdgeArray;
1619         dm->copyTessFaceArray = cdDM_copyFaceArray;
1620         dm->copyLoopArray = cdDM_copyLoopArray;
1621         dm->copyPolyArray = cdDM_copyPolyArray;
1622         dm->getVertData = DM_get_vert_data;
1623         dm->getEdgeData = DM_get_edge_data;
1624         dm->getTessFaceData = DM_get_face_data;
1625         dm->getVertDataArray = DM_get_vert_data_layer;
1626         dm->getEdgeDataArray = DM_get_edge_data_layer;
1627         dm->getTessFaceDataArray = DM_get_tessface_data_layer;
1628         
1629         //doesn't work yet for all cases
1630         //dm->recalcTesselation = cdDM_recalcTesselation;
1631
1632         dm->getVertCos = cdDM_getVertCos;
1633         dm->getVertCo = cdDM_getVertCo;
1634         dm->getVertNo = cdDM_getVertNo;
1635
1636         dm->getPBVH = cdDM_getPBVH;
1637         dm->getFaceMap = cdDM_getFaceMap;
1638
1639         dm->drawVerts = cdDM_drawVerts;
1640
1641         dm->drawUVEdges = cdDM_drawUVEdges;
1642         dm->drawEdges = cdDM_drawEdges;
1643         dm->drawLooseEdges = cdDM_drawLooseEdges;
1644         dm->drawMappedEdges = cdDM_drawMappedEdges;
1645
1646         dm->drawFacesSolid = cdDM_drawFacesSolid;
1647         dm->drawFacesColored = cdDM_drawFacesColored;
1648         dm->drawFacesTex = cdDM_drawFacesTex;
1649         dm->drawFacesGLSL = cdDM_drawFacesGLSL;
1650         dm->drawMappedFaces = cdDM_drawMappedFaces;
1651         dm->drawMappedFacesTex = cdDM_drawMappedFacesTex;
1652         dm->drawMappedFacesGLSL = cdDM_drawMappedFacesGLSL;
1653
1654         dm->foreachMappedVert = cdDM_foreachMappedVert;
1655         dm->foreachMappedEdge = cdDM_foreachMappedEdge;
1656         dm->foreachMappedFaceCenter = cdDM_foreachMappedFaceCenter;
1657
1658         dm->release = cdDM_release;
1659
1660         return cddm;
1661 }
1662
1663 DerivedMesh *CDDM_new(int numVerts, int numEdges, int numFaces, int numLoops, int numPolys)
1664 {
1665         CDDerivedMesh *cddm = cdDM_create("CDDM_new dm");
1666         DerivedMesh *dm = &cddm->dm;
1667
1668         DM_init(dm, DM_TYPE_CDDM, numVerts, numEdges, numFaces, numLoops, numPolys);
1669
1670         CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
1671         CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
1672         CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numFaces);
1673         CustomData_add_layer(&dm->polyData, CD_ORIGINDEX, CD_CALLOC, NULL, numPolys);
1674
1675         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
1676         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
1677         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numFaces);
1678         CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL, numLoops);
1679         CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL, numPolys);
1680
1681         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1682         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1683         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1684         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
1685         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
1686
1687         return dm;
1688 }
1689
1690 DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob))
1691 {
1692         CDDerivedMesh *cddm = cdDM_create("CDDM_from_mesh dm");
1693         DerivedMesh *dm = &cddm->dm;
1694         CustomDataMask mask = CD_MASK_MESH & (~CD_MASK_MDISPS);
1695         int alloctype;
1696
1697         /* this does a referenced copy, with an exception for fluidsim */
1698
1699         DM_init(dm, DM_TYPE_CDDM, mesh->totvert, mesh->totedge, mesh->totface,
1700                     mesh->totloop, mesh->totpoly);
1701
1702         dm->deformedOnly = 1;
1703
1704         alloctype= CD_REFERENCE;
1705
1706         CustomData_merge(&mesh->vdata, &dm->vertData, mask, alloctype,
1707                                          mesh->totvert);
1708         CustomData_merge(&mesh->edata, &dm->edgeData, mask, alloctype,
1709                                          mesh->totedge);
1710         CustomData_merge(&mesh->fdata, &dm->faceData, mask|CD_MASK_ORIGINDEX, alloctype,
1711                                          mesh->totface);
1712         CustomData_merge(&mesh->ldata, &dm->loopData, mask, alloctype,
1713                          mesh->totloop);
1714         CustomData_merge(&mesh->pdata, &dm->polyData, mask, alloctype,
1715                          mesh->totpoly);
1716
1717         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1718         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1719         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
1720         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
1721         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1722
1723         if (!CustomData_has_layer(&cddm->dm.faceData, CD_ORIGINDEX))
1724                 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totface);
1725
1726         return dm;
1727 }
1728
1729 static DerivedMesh *disabled__CDDM_from_editmesh(EditMesh *em, Mesh *UNUSED(me))
1730 {
1731         DerivedMesh *dm = CDDM_new(BLI_countlist(&em->verts),
1732                                    BLI_countlist(&em->edges),
1733                                    BLI_countlist(&em->faces), 0, 0);
1734         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1735         EditVert *eve;
1736         EditEdge *eed;
1737         EditFace *efa;
1738         MVert *mvert = cddm->mvert;
1739         MEdge *medge = cddm->medge;
1740         MFace *mface = cddm->mface;
1741         int i, *index;
1742
1743         dm->deformedOnly = 1;
1744
1745         CustomData_merge(&em->vdata, &dm->vertData, CD_MASK_DERIVEDMESH,
1746                                          CD_CALLOC, dm->numVertData);
1747         /* CustomData_merge(&em->edata, &dm->edgeData, CD_MASK_DERIVEDMESH,
1748                                          CD_CALLOC, dm->numEdgeData); */
1749         CustomData_merge(&em->fdata, &dm->faceData, CD_MASK_DERIVEDMESH,
1750                                          CD_CALLOC, dm->numFaceData);
1751         CustomData_merge(&em->fdata, &dm->faceData, CD_MASK_DERIVEDMESH,
1752                          CD_CALLOC, dm->numFaceData);
1753
1754         /* set eve->hash to vert index */
1755         for(i = 0, eve = em->verts.first; eve; eve = eve->next, ++i)
1756                 eve->tmp.l = i;
1757
1758         /* Need to be able to mark loose edges */
1759         for(eed = em->edges.first; eed; eed = eed->next) {
1760                 eed->f2 = 0;
1761         }
1762         for(efa = em->faces.first; efa; efa = efa->next) {
1763                 efa->e1->f2 = 1;
1764                 efa->e2->f2 = 1;
1765                 efa->e3->f2 = 1;
1766                 if(efa->e4) efa->e4->f2 = 1;
1767         }
1768
1769         index = dm->getVertDataArray(dm, CD_ORIGINDEX);
1770         for(i = 0, eve = em->verts.first; i < dm->numVertData;
1771                 i++, eve = eve->next, index++) {
1772                 MVert *mv = &mvert[i];
1773
1774                 VECCOPY(mv->co, eve->co);
1775
1776                 normal_float_to_short_v3(mv->no, eve->no);
1777                 mv->bweight = (unsigned char) (eve->bweight * 255.0f);
1778
1779                 mv->flag = 0;
1780
1781                 *index = i;
1782
1783                 CustomData_from_em_block(&em->vdata, &dm->vertData, eve->data, i);
1784         }
1785
1786         index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
1787         for(i = 0, eed = em->edges.first; i < dm->numEdgeData;
1788                 i++, eed = eed->next, index++) {
1789                 MEdge *med = &medge[i];
1790
1791                 med->v1 = eed->v1->tmp.l;
1792                 med->v2 = eed->v2->tmp.l;
1793                 med->crease = (unsigned char) (eed->crease * 255.0f);
1794                 med->bweight = (unsigned char) (eed->bweight * 255.0f);
1795                 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
1796                 
1797                 if(eed->seam) med->flag |= ME_SEAM;
1798                 if(eed->sharp) med->flag |= ME_SHARP;
1799                 if(!eed->f2) med->flag |= ME_LOOSEEDGE;
1800
1801                 *index = i;
1802
1803                 /* CustomData_from_em_block(&em->edata, &dm->edgeData, eed->data, i); */
1804         }
1805
1806         index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1807         for(i = 0, efa = em->faces.first; i < dm->numFaceData;
1808                 i++, efa = efa->next, index++) {
1809                 MFace *mf = &mface[i];
1810
1811                 mf->v1 = efa->v1->tmp.l;
1812                 mf->v2 = efa->v2->tmp.l;
1813                 mf->v3 = efa->v3->tmp.l;
1814                 mf->v4 = efa->v4 ? efa->v4->tmp.l : 0;
1815                 mf->mat_nr = efa->mat_nr;
1816                 mf->flag = efa->flag;
1817
1818                 *index = i;
1819
1820                 CustomData_from_em_block(&em->fdata, &dm->faceData, efa->data, i);
1821                 test_index_face(mf, &dm->faceData, i, efa->v4?4:3);
1822         }
1823
1824         return dm;
1825 }
1826
1827 DerivedMesh *CDDM_from_curve(Object *ob)
1828 {
1829         return CDDM_from_curve_customDB(ob, &ob->disp);
1830 }
1831
1832 DerivedMesh *CDDM_from_curve_customDB(Object *ob, ListBase *dispbase)
1833 {
1834         DerivedMesh *dm;
1835         CDDerivedMesh *cddm;
1836         MVert *allvert;
1837         MEdge *alledge;
1838         MFace *allface;
1839         MLoop *allloop;
1840         MPoly *allpoly;
1841         int totvert, totedge, totface, totloop, totpoly;
1842
1843         if (nurbs_to_mdata_customdb(ob, dispbase, &allvert, &totvert, &alledge,
1844                 &totedge, &allface, &allloop, &allpoly, &totface, &totloop, &totpoly) != 0) {
1845                 /* Error initializing mdata. This often happens when curve is empty */
1846                 return CDDM_new(0, 0, 0, 0, 0);
1847         }
1848
1849         dm = CDDM_new(totvert, totedge, totface, totloop, totpoly);
1850         dm->deformedOnly = 1;
1851
1852         cddm = (CDDerivedMesh*)dm;
1853
1854         memcpy(cddm->mvert, allvert, totvert*sizeof(MVert));
1855         memcpy(cddm->medge, alledge, totedge*sizeof(MEdge));
1856         memcpy(cddm->mface, allface, totface*sizeof(MFace));
1857         memcpy(cddm->mloop, allloop, totloop*sizeof(MLoop));
1858         memcpy(cddm->mpoly, allpoly, totpoly*sizeof(MPoly));
1859
1860         MEM_freeN(allvert);
1861         MEM_freeN(alledge);
1862         MEM_freeN(allface);
1863         MEM_freeN(allloop);
1864         MEM_freeN(allpoly);
1865
1866         return dm;
1867 }
1868
1869 static void loops_to_customdata_corners(BMesh *bm, CustomData *facedata,
1870                                           int cdindex, BMLoop *l3[3],
1871                                           int numCol, int numTex)
1872 {
1873         BMLoop *l;
1874         BMFace *f = l3[0]->f;
1875         MTFace *texface;
1876         MTexPoly *texpoly;
1877         MCol *mcol;
1878         MLoopCol *mloopcol;
1879         MLoopUV *mloopuv;
1880         int i, j, hasWCol = CustomData_has_layer(&bm->ldata, CD_WEIGHT_MLOOPCOL);
1881
1882         for(i=0; i < numTex; i++){
1883                 texface = CustomData_get_n(facedata, CD_MTFACE, cdindex, i);
1884                 texpoly = CustomData_bmesh_get_n(&bm->pdata, f->head.data, CD_MTEXPOLY, i);
1885                 
1886                 texface->tpage = texpoly->tpage;
1887                 texface->flag = texpoly->flag;
1888                 texface->transp = texpoly->transp;
1889                 texface->mode = texpoly->mode;
1890                 texface->tile = texpoly->tile;
1891                 texface->unwrap = texpoly->unwrap;
1892         
1893                 for (j=0; j<3; j++) {
1894                         l = l3[j];
1895                         mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPUV, i);
1896                         texface->uv[j][0] = mloopuv->uv[0];
1897                         texface->uv[j][1] = mloopuv->uv[1];
1898                 }
1899         }
1900
1901         for(i=0; i < numCol; i++){
1902                 mcol = CustomData_get_n(facedata, CD_MCOL, cdindex, i);
1903                 
1904                 for (j=0; j<3; j++) {
1905                         l = l3[j];
1906                         mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPCOL, i);
1907                         mcol[j].r = mloopcol->r;
1908                         mcol[j].g = mloopcol->g;
1909                         mcol[j].b = mloopcol->b;
1910                         mcol[j].a = mloopcol->a;
1911                 }
1912         }
1913
1914         if (hasWCol) {
1915                 mcol = CustomData_get(facedata, cdindex, CD_WEIGHT_MCOL);
1916
1917                 for (j=0; j<3; j++) {
1918                         l = l3[j];
1919                         mloopcol = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_WEIGHT_MLOOPCOL);
1920                         mcol[j].r = mloopcol->r;
1921                         mcol[j].g = mloopcol->g;
1922                         mcol[j].b = mloopcol->b;
1923                         mcol[j].a = mloopcol->a;
1924                 }
1925         }
1926 }
1927
1928 DerivedMesh *CDDM_from_BMEditMesh(BMEditMesh *em, Mesh *UNUSED(me), int use_mdisps)
1929 {
1930         DerivedMesh *dm = CDDM_new(em->bm->totvert, em->bm->totedge, 
1931                                em->tottri, em->bm->totloop, em->bm->totface);
1932         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1933         BMesh *bm = em->bm;
1934         BMIter iter, liter;
1935         BMVert *eve;
1936         BMEdge *eed;
1937         BMFace *efa;
1938         MVert *mvert = cddm->mvert;
1939         MEdge *medge = cddm->medge;
1940         MFace *mface = cddm->mface;
1941         MLoop *mloop = cddm->mloop;
1942         MPoly *mpoly = cddm->mpoly;
1943         int numCol = CustomData_number_of_layers(&em->bm->ldata, CD_MLOOPCOL);
1944         int numTex = CustomData_number_of_layers(&em->bm->pdata, CD_MTEXPOLY);
1945         int i, j, *index, add_orig;
1946         int has_crease, has_edge_bweight, has_vert_bweight;
1947         int flag;
1948         
1949         has_edge_bweight = CustomData_has_layer(&em->bm->edata, CD_BWEIGHT);
1950         has_vert_bweight = CustomData_has_layer(&em->bm->vdata, CD_BWEIGHT);
1951         has_crease = CustomData_has_layer(&em->bm->edata, CD_CREASE);
1952         
1953         dm->deformedOnly = 1;
1954         
1955         /*don't add origindex layer if one already exists*/
1956         add_orig = !CustomData_has_layer(&em->bm->pdata, CD_ORIGINDEX);
1957
1958         flag = use_mdisps ? CD_MASK_DERIVEDMESH|CD_MASK_MDISPS : CD_MASK_DERIVEDMESH;
1959         
1960         /*don't process shapekeys, we only feed them through the modifier stack as needed,
1961       e.g. for applying modifiers or the like*/
1962         flag &= ~CD_SHAPEKEY;
1963         CustomData_merge(&em->bm->vdata, &dm->vertData, flag,
1964                          CD_CALLOC, dm->numVertData);
1965         CustomData_merge(&em->bm->edata, &dm->edgeData, flag,
1966                          CD_CALLOC, dm->numEdgeData);
1967         CustomData_merge(&em->bm->ldata, &dm->loopData, flag,
1968                          CD_CALLOC, dm->numLoopData);
1969         CustomData_merge(&em->bm->pdata, &dm->polyData, flag,
1970                          CD_CALLOC, dm->numPolyData);
1971         
1972         /*add tesselation mface layers*/
1973         CustomData_from_bmeshpoly(&dm->faceData, &dm->polyData, &dm->loopData, em->tottri);
1974
1975         /* set vert index */
1976         eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
1977         for (i=0; eve; eve=BMIter_Step(&iter), i++)
1978                 BM_SetIndex(eve, i);
1979
1980         index = dm->getVertDataArray(dm, CD_ORIGINDEX);
1981
1982         eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
1983         for (i=0; eve; eve=BMIter_Step(&iter), i++, index++) {
1984                 MVert *mv = &mvert[i];
1985
1986                 VECCOPY(mv->co, eve->co);
1987
1988                 BM_SetIndex(eve, i);
1989
1990                 mv->no[0] = eve->no[0] * 32767.0;
1991                 mv->no[1] = eve->no[1] * 32767.0;
1992                 mv->no[2] = eve->no[2] * 32767.0;
1993
1994                 mv->flag = BMFlags_To_MEFlags(eve);
1995
1996                 if (has_vert_bweight)
1997                         mv->bweight = (unsigned char)(BM_GetCDf(&bm->vdata, eve, CD_BWEIGHT)*255.0f);
1998
1999                 if (add_orig) *index = i;
2000
2001                 CustomData_from_bmesh_block(&bm->vdata, &dm->vertData, eve->head.data, i);
2002         }
2003
2004         index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
2005         eed = BMIter_New(&iter, bm, BM_EDGES_OF_MESH, NULL);
2006         for (i=0; eed; eed=BMIter_Step(&iter), i++, index++) {
2007                 MEdge *med = &medge[i];
2008
2009                 BM_SetIndex(eed, i);
2010
2011                 med->v1 = BM_GetIndex(eed->v1);
2012                 med->v2 = BM_GetIndex(eed->v2);
2013                 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
2014
2015                 if (has_crease)
2016                         med->crease = (unsigned char)(BM_GetCDf(&bm->edata, eed, CD_CREASE)*255.0f);
2017                 if (has_edge_bweight)
2018                         med->bweight = (unsigned char)(BM_GetCDf(&bm->edata, eed, CD_BWEIGHT)*255.0f);
2019                 
2020                 med->flag = BMFlags_To_MEFlags(eed);
2021
2022                 CustomData_from_bmesh_block(&bm->edata, &dm->edgeData, eed->head.data, i);
2023                 if (add_orig) *index = i;
2024         }
2025
2026         efa = BMIter_New(&iter, bm, BM_FACES_OF_MESH, NULL);
2027         for (i=0; efa; i++, efa=BMIter_Step(&iter)) {
2028                 BM_SetIndex(efa, i);
2029         }
2030
2031         index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
2032         for(i = 0; i < dm->numFaceData; i++, index++) {
2033                 MFace *mf = &mface[i];
2034                 BMLoop **l = em->looptris[i];
2035                 efa = l[0]->f;
2036
2037                 mf->v1 = BM_GetIndex(l[0]->v);
2038                 mf->v2 = BM_GetIndex(l[1]->v);
2039                 mf->v3 = BM_GetIndex(l[2]->v);
2040                 mf->v4 = 0;
2041                 mf->mat_nr = efa->mat_nr;
2042                 mf->flag = BMFlags_To_MEFlags(efa);
2043                 
2044                 *index = add_orig ? BM_GetIndex(efa) : *(int*)CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_ORIGINDEX);
2045
2046                 loops_to_customdata_corners(bm, &dm->faceData, i, l, numCol, numTex);
2047                 test_index_face(mf, &dm->faceData, i, 3);
2048         }
2049         
2050         index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
2051         j = 0;
2052         efa = BMIter_New(&iter, bm, BM_FACES_OF_MESH, NULL);
2053         for (i=0; efa; i++, efa=BMIter_Step(&iter), index++) {
2054                 BMLoop *l;
2055                 MPoly *mp = &mpoly[i];
2056
2057                 mp->totloop = efa->len;
2058                 mp->flag = BMFlags_To_MEFlags(efa);
2059                 mp->loopstart = j;
2060                 mp->mat_nr = efa->mat_nr;
2061                 
2062                 BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, efa) {
2063                         mloop->v = BM_GetIndex(l->v);
2064                         mloop->e = BM_GetIndex(l->e);
2065                         CustomData_from_bmesh_block(&bm->ldata, &dm->loopData, l->head.data, j);
2066
2067                         j++;
2068                         mloop++;
2069                 }
2070
2071                 CustomData_from_bmesh_block(&bm->pdata, &dm->polyData, efa->head.data, i);
2072
2073                 if (add_orig) *index = i;
2074         }
2075
2076         return dm;
2077 }
2078
2079 DerivedMesh *CDDM_copy(DerivedMesh *source, int faces_from_tessfaces)
2080 {
2081         CDDerivedMesh *cddm = cdDM_create("CDDM_copy cddm");
2082         DerivedMesh *dm = &cddm->dm;
2083         int numVerts = source->numVertData;
2084         int numEdges = source->numEdgeData;
2085         int numFaces = source->numFaceData;
2086         int numLoops = source->numLoopData;
2087         int numPolys = source->numPolyData;
2088
2089         /* ensure these are created if they are made on demand */
2090         source->getVertDataArray(source, CD_ORIGINDEX);
2091         source->getEdgeDataArray(source, CD_ORIGINDEX);
2092         source->getTessFaceDataArray(source, CD_ORIGINDEX);
2093
2094         /* this initializes dm, and copies all non mvert/medge/mface layers */
2095         DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numFaces,
2096                 numLoops, numPolys);
2097         dm->deformedOnly = source->deformedOnly;
2098
2099         CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts);
2100         CustomData_copy_data(&source->edgeData, &dm->edgeData, 0, 0, numEdges);
2101         CustomData_copy_data(&source->faceData, &dm->faceData, 0, 0, numFaces);
2102
2103         /* now add mvert/medge/mface layers */
2104         cddm->mvert = source->dupVertArray(source);
2105         cddm->medge = source->dupEdgeArray(source);
2106         cddm->mface = source->dupTessFaceArray(source);
2107
2108         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, cddm->mvert, numVerts);
2109         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, cddm->medge, numEdges);
2110         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, cddm->mface, numFaces);
2111         
2112         if (!faces_from_tessfaces)
2113                 DM_DupPolys(source, dm);
2114         else
2115                 CDDM_tessfaces_to_faces(dm);
2116
2117         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
2118         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
2119         
2120         cdDM_recalcTesselation((DerivedMesh *)cddm);
2121         
2122         return dm;
2123 }
2124
2125 /* note, the CD_ORIGINDEX layers are all 0, so if there is a direct
2126  * relationship betwen mesh data this needs to be set by the caller. */
2127 DerivedMesh *CDDM_from_template(DerivedMesh *source,
2128                                 int numVerts, int numEdges, int numFaces,
2129                                                                 int numLoops, int numPolys)
2130 {
2131         CDDerivedMesh *cddm = cdDM_create("CDDM_from_template dest");
2132         DerivedMesh *dm = &cddm->dm;
2133
2134         /* ensure these are created if they are made on demand */
2135         source->getVertDataArray(source, CD_ORIGINDEX);
2136         source->getEdgeDataArray(source, CD_ORIGINDEX);
2137         source->getTessFaceDataArray(source, CD_ORIGINDEX);
2138
2139         /* this does a copy of all non mvert/medge/mface layers */
2140         DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numFaces, numLoops, numPolys);
2141
2142         /* now add mvert/medge/mface layers */
2143         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
2144         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2145         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numFaces);
2146         CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL, numLoops);
2147         CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL, numPolys);
2148
2149         if(!CustomData_get_layer(&dm->vertData, CD_ORIGINDEX))
2150                 CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
2151         if(!CustomData_get_layer(&dm->edgeData, CD_ORIGINDEX))
2152                 CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2153         if(!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX))
2154                 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numFaces);
2155
2156         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
2157         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2158         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
2159         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
2160         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
2161
2162         return dm;
2163 }
2164
2165 void CDDM_apply_vert_coords(DerivedMesh *dm, float (*vertCoords)[3])
2166 {
2167         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2168         MVert *vert;
2169         int i;
2170
2171         /* this will just return the pointer if it wasn't a referenced layer */
2172         vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
2173         cddm->mvert = vert;
2174
2175         for(i = 0; i < dm->numVertData; ++i, ++vert)
2176                 VECCOPY(vert->co, vertCoords[i]);
2177 }
2178
2179 void CDDM_apply_vert_normals(DerivedMesh *dm, short (*vertNormals)[3])
2180 {
2181         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2182         MVert *vert;
2183         int i;
2184
2185         /* this will just return the pointer if it wasn't a referenced layer */
2186         vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
2187         cddm->mvert = vert;
2188
2189         for(i = 0; i < dm->numVertData; ++i, ++vert)
2190                 VECCOPY(vert->no, vertNormals[i]);
2191 }
2192
2193 void CDDM_calc_normals(DerivedMesh *dm)
2194 {
2195         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2196         float (*face_nors)[3] = NULL;
2197         
2198         if(dm->numVertData == 0) return;
2199
2200         /* we don't want to overwrite any referenced layers */
2201         cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
2202         
2203         /*set tesselation origindex values to map to poly indices, rather then poly
2204           poly origindex values*/
2205         cdDM_recalcTesselation2(dm);
2206         
2207         face_nors = MEM_mallocN(sizeof(float)*3*dm->numFaceData, "face_nors");
2208         
2209         /* calculate face normals */
2210         mesh_calc_normals(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm), 
2211                                           dm->numLoopData, dm->numPolyData, NULL, cddm->mface, dm->numFaceData, 
2212                                           CustomData_get_layer(&dm->faceData, CD_ORIGINDEX), face_nors);
2213         
2214         /*restore tesselation origindex indices to poly origindex indices*/
2215         cdDM_recalcTesselation(dm);
2216
2217         CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_ASSIGN, 
2218                 face_nors, dm->numFaceData);
2219 }
2220
2221 #if 1
2222 /*merge verts
2223  
2224   vtargetmap is a table that maps vertices to target vertices.  a value of -1
2225   indicates a vertex is a target, and is to be kept.
2226   
2227   this frees dm, and returns a new one.
2228   
2229   this is a really horribly written function.  ger. - joeedh
2230
2231  */
2232 DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, int *vtargetmap)
2233 {
2234         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2235         CDDerivedMesh *cddm2 = NULL;
2236         MVert *mv, *mvert = NULL;
2237         BLI_array_declare(mvert);
2238         MEdge *me, *medge = NULL;
2239         BLI_array_declare(medge);
2240         MPoly *mp, *mpoly = NULL;
2241         BLI_array_declare(mpoly);
2242         MLoop *ml, *mloop = NULL;
2243         BLI_array_declare(mloop);
2244         EdgeHash *ehash = BLI_edgehash_new();
2245         int *newv = NULL, *newe = NULL, *newl = NULL;
2246         int *oldv = NULL, *olde = NULL, *oldl = NULL, *oldp = NULL;
2247         BLI_array_declare(oldv); BLI_array_declare(olde); BLI_array_declare(oldl); BLI_array_declare(oldp);
2248         int i, j, c, totloop, totpoly;
2249         
2250         totloop = dm->numLoopData;
2251         totpoly = dm->numPolyData;
2252         
2253         newv = MEM_callocN(sizeof(int)*dm->numVertData, "newv vtable CDDM_merge_verts");
2254         newe = MEM_callocN(sizeof(int)*dm->numEdgeData, "newv etable CDDM_merge_verts");
2255         newl = MEM_callocN(sizeof(int)*totloop, "newv ltable CDDM_merge_verts");
2256         
2257         /*fill newl with destination vertex indices*/
2258         mv = cddm->mvert;
2259         c = 0;
2260         for (i=0; i<dm->numVertData; i++, mv++) {
2261                 if (vtargetmap[i] == -1) {
2262                         BLI_array_append(oldv, i);
2263                         newv[i] = c++;
2264                         BLI_array_append(mvert, *mv);
2265                 }
2266         }
2267         
2268         /*now link target vertices to destination indices*/
2269         for (i=0; i<dm->numVertData; i++) {
2270                 if (vtargetmap[i] != -1) {
2271                         newv[i] = newv[vtargetmap[i]];
2272                 }
2273         }
2274         
2275         /*find-replace merged vertices with target vertices*/   
2276         ml = cddm->mloop;
2277         c = 0;
2278         for (i=0; i<totloop; i++, ml++) {
2279                 if (ml->v == -1)
2280                         continue;
2281                 
2282                 if (vtargetmap[ml->v] != -1)
2283                         ml->v = vtargetmap[ml->v];
2284         }
2285         
2286         /*now go through and fix edges and faces*/
2287         me = cddm->medge;
2288         c = 0;
2289         for (i=0; i<dm->numEdgeData; i++, me++) {
2290                 int v1, v2;
2291                 
2292                 if (me->v1 == me->v2) {
2293                         newe[i] = -1;
2294                         continue;
2295                 }
2296                 
2297                 if (vtargetmap[me->v1] != -1)
2298                         v1 = vtargetmap[me->v1];
2299                 else
2300                         v1 = me->v1;
2301                 
2302                 if (vtargetmap[me->v2] != -1)
2303                         v2 = vtargetmap[me->v2];
2304                 else
2305                         v2 = me->v2;
2306                 
2307                 if (BLI_edgehash_haskey(ehash, v1, v2)) {
2308                         newe[i] = GET_INT_FROM_POINTER(BLI_edgehash_lookup(ehash, v1, v2));
2309                 } else {
2310                         BLI_array_append(olde, i);
2311                         newe[i] = c;
2312                         BLI_array_append(medge, *me);
2313                         BLI_edgehash_insert(ehash, v1, v2, SET_INT_IN_POINTER(c));
2314                         c++;
2315                 }
2316         }
2317         
2318         mp = cddm->mpoly;
2319         for (i=0; i<totpoly; i++, mp++) {
2320                 MPoly *mp2;
2321                 
2322                 ml = cddm->mloop + mp->loopstart;
2323                 
2324                 c = 0;
2325                 for (j=0; j<mp->totloop; j++, ml++) {
2326                         if (ml->v == -1)
2327                                 continue;
2328                         
2329                         me = cddm->medge + ml->e;
2330                         if (me->v1 != me->v2) {
2331                                 BLI_array_append(oldl, j+mp->loopstart);
2332                                 BLI_array_append(mloop, *ml);
2333                                 newl[j+mp->loopstart] = BLI_array_count(mloop)-1;
2334                                 c++;
2335                         }
2336                 }
2337                 
2338                 if (!c)
2339                         continue;
2340                 
2341                 mp2 = BLI_array_append(mpoly, *mp);
2342                 mp2->totloop = c;
2343                 mp2->loopstart = BLI_array_count(mloop) - c;
2344                 
2345                 BLI_array_append(oldp, i);
2346         }
2347         
2348         /*create new cddm*/     
2349         cddm2 = (CDDerivedMesh*) CDDM_from_template((DerivedMesh*)cddm, BLI_array_count(mvert), BLI_array_count(medge), 0, BLI_array_count(mloop), BLI_array_count(mpoly));
2350         
2351         /*update edge indices and copy customdata*/
2352         me = medge;
2353         for (i=0; i<cddm2->dm.numEdgeData; i++, me++) {
2354                 if (newv[me->v1] != -1)
2355                         me->v1 = newv[me->v1];
2356                 if (newv[me->v2] != -1)
2357                         me->v2 = newv[me->v2];
2358                 
2359                 CustomData_copy_data(&dm->edgeData, &cddm2->dm.edgeData, olde[i], i, 1);
2360         }
2361         
2362         /*update loop indices and copy customdata*/
2363         ml = mloop;
2364         for (i=0; i<cddm2->dm.numLoopData; i++, ml++) {
2365                 if (newe[ml->e] != -1)
2366                         ml->e = newe[ml->e];
2367                 if (newv[ml->v] != -1)
2368                         ml->v = newv[ml->v];
2369                         
2370                 CustomData_copy_data(&dm->loopData, &cddm2->dm.loopData, oldl[i], i, 1);
2371         }
2372         
2373         /*copy vertex customdata*/      
2374         mv = mvert;
2375         for (i=0; i<cddm2->dm.numVertData; i++, mv++) {
2376                 CustomData_copy_data(&dm->vertData, &cddm2->dm.vertData, oldv[i], i, 1);
2377         }
2378         
2379         /*copy poly customdata*/
2380         mp = mpoly;
2381         for (i=0; i<cddm2->dm.numPolyData; i++, mp++) {
2382                 CustomData_copy_data(&dm->polyData, &cddm2->dm.polyData, oldp[i], i, 1);
2383         }
2384         
2385         /*copy over data.  CustomData_add_layer can do this, need to look it up.*/
2386         memcpy(cddm2->mvert, mvert, sizeof(MVert)*BLI_array_count(mvert));
2387         memcpy(cddm2->medge, medge, sizeof(MEdge)*BLI_array_count(medge));
2388         memcpy(cddm2->mloop, mloop, sizeof(MLoop)*BLI_array_count(mloop));
2389         memcpy(cddm2->mpoly, mpoly, sizeof(MPoly)*BLI_array_count(mpoly));
2390         BLI_array_free(mvert); BLI_array_free(medge); BLI_array_free(mloop); BLI_array_free(mpoly);
2391
2392         CDDM_recalc_tesselation((DerivedMesh*)cddm2, 1);
2393         
2394         if (newv) 
2395                 MEM_freeN(newv); 
2396         if (newe)
2397                 MEM_freeN(newe); 
2398         if (newl)
2399                 MEM_freeN(newl);
2400         if (oldv) 
2401                 MEM_freeN(oldv); 
2402         if (olde) 
2403                 MEM_freeN(olde); 
2404         if (oldl) 
2405                 MEM_freeN(oldl); 
2406         if (oldp) 
2407                 MEM_freeN(oldp);
2408         if (ehash)
2409                 BLI_edgehash_free(ehash, NULL);
2410
2411         /*free old derivedmesh*/
2412         dm->needsFree = 1;
2413         dm->release(dm);
2414         
2415         return (DerivedMesh*)cddm2;
2416 }
2417 #endif
2418
2419 void CDDM_calc_edges(DerivedMesh *dm)
2420 {
2421         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2422         CustomData edgeData;
2423         EdgeHashIterator *ehi;
2424         MFace *mf = cddm->mface;
2425         MEdge *med;
2426         EdgeHash *eh = BLI_edgehash_new();
2427         int i, *index, numEdges, maxFaces = dm->numFaceData;
2428
2429         for (i = 0; i < maxFaces; i++, mf++) {
2430                 if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
2431                         BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
2432                 if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
2433                         BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
2434                 
2435                 if (mf->v4) {
2436                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
2437                                 BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
2438                         if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
2439                                 BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
2440                 } else {
2441                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
2442                                 BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
2443                 }
2444         }
2445
2446         numEdges = BLI_edgehash_size(eh);
2447
2448         /* write new edges into a temporary CustomData */
2449         memset(&edgeData, 0, sizeof(edgeData));
2450         CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2451         CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2452
2453         ehi = BLI_edgehashIterator_new(eh);
2454         med = CustomData_get_layer(&edgeData, CD_MEDGE);
2455         index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
2456         for(i = 0; !BLI_edgehashIterator_isDone(ehi);
2457                 BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) {
2458                 BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2);
2459
2460                 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
2461                 *index = ORIGINDEX_NONE;
2462         }
2463         BLI_edgehashIterator_free(ehi);
2464
2465         /* free old CustomData and assign new one */
2466         CustomData_free(&dm->edgeData, dm->numEdgeData);
2467         dm->edgeData = edgeData;
2468         dm->numEdgeData = numEdges;
2469
2470         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2471
2472         BLI_edgehash_free(eh, NULL);
2473 }
2474
2475
2476 void CDDM_calc_edges_poly(DerivedMesh *dm)
2477 {
2478         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2479         CustomData edgeData;
2480         EdgeHashIterator *ehi;
2481         MPoly *mp = cddm->mpoly;
2482         MLoop *ml;
2483         MEdge *med;
2484         EdgeHash *eh = BLI_edgehash_new();
2485         int v1, v2;
2486         int *eindex;
2487         int i, j, k, *index, numEdges = cddm->dm.numEdgeData, maxFaces = dm->numPolyData;
2488
2489         eindex = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
2490
2491         med = cddm->medge;
2492         if (med) {
2493                 for (i=0; i < numEdges; i++, med++) {
2494                         BLI_edgehash_insert(eh, med->v1, med->v2, SET_INT_IN_POINTER(i+1));
2495                 }
2496         }
2497
2498         for (i=0; i < maxFaces; i++, mp++) {
2499                 ml = cddm->mloop + mp->loopstart;
2500                 for (j=0; j<mp->totloop; j++, ml++) {
2501                         v1 = ml->v;
2502                         v2 = (cddm->mloop + mp->loopstart + ((j+1)%mp->totloop))->v;
2503                         if (!BLI_edgehash_haskey(eh, v1, v2)) {
2504                                 BLI_edgehash_insert(eh, v1, v2, NULL);
2505                         }
2506                 }
2507         }
2508
2509         k = numEdges;
2510         numEdges = BLI_edgehash_size(eh);
2511
2512         /* write new edges into a temporary CustomData */
2513         memset(&edgeData, 0, sizeof(edgeData));
2514         CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2515         CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2516
2517         ehi = BLI_edgehashIterator_new(eh);
2518         med = CustomData_get_layer(&edgeData, CD_MEDGE);
2519         index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
2520         for(i = 0; !BLI_edgehashIterator_isDone(ehi);
2521             BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) {
2522                 BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2);
2523                 j = GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi));
2524
2525                 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
2526                 *index = j==0 ? ORIGINDEX_NONE : eindex[j-1];
2527
2528                 BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(i));
2529         }
2530         BLI_edgehashIterator_free(ehi);
2531
2532         /* free old CustomData and assign new one */
2533         CustomData_free(&dm->edgeData, dm->numEdgeData);
2534         dm->edgeData = edgeData;
2535         dm->numEdgeData = numEdges;
2536
2537         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2538
2539         mp = cddm->mpoly;
2540         for (i=0; i < maxFaces; i++, mp++) {
2541                 ml = cddm->mloop + mp->loopstart;
2542                 for (j=0; j<mp->totloop; j++, ml++) {
2543                         v1 = ml->v;
2544                         v2 = (cddm->mloop + mp->loopstart + ((j+1)%mp->totloop))->v;
2545                         ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, v1, v2));
2546                 }
2547         }
2548
2549         BLI_edgehash_free(eh, NULL);
2550 }
2551
2552 void CDDM_lower_num_verts(DerivedMesh *dm, int numVerts)
2553 {
2554         if (numVerts < dm->numVertData)
2555                 CustomData_free_elem(&dm->vertData, numVerts, dm->numVertData-numVerts);
2556
2557         dm->numVertData = numVerts;
2558 }
2559
2560 void CDDM_lower_num_edges(DerivedMesh *dm, int numEdges)
2561 {
2562         if (numEdges < dm->numEdgeData)
2563                 CustomData_free_elem(&dm->edgeData, numEdges, dm->numEdgeData-numEdges);
2564
2565         dm->numEdgeData = numEdges;
2566 }
2567
2568 void CDDM_lower_num_faces(DerivedMesh *dm, int numFaces)
2569 {
2570         if (numFaces < dm->numFaceData)
2571                 CustomData_free_elem(&dm->faceData, numFaces, dm->numFaceData-numFaces);
2572
2573         dm->numFaceData = numFaces;
2574 }
2575
2576 MVert *CDDM_get_vert(DerivedMesh *dm, int index)
2577 {
2578         return &((CDDerivedMesh*)dm)->mvert[index];
2579 }
2580
2581 MEdge *CDDM_get_edge(DerivedMesh *dm, int index)
2582 {
2583         return &((CDDerivedMesh*)dm)->medge[index];
2584 }
2585
2586 MFace *CDDM_get_tessface(DerivedMesh *dm, int index)
2587 {
2588         return &((CDDerivedMesh*)dm)->mface[index];
2589 }
2590
2591 MVert *CDDM_get_verts(DerivedMesh *dm)
2592 {
2593         return ((CDDerivedMesh*)dm)->mvert;
2594 }
2595
2596 MEdge *CDDM_get_edges(DerivedMesh *dm)
2597 {
2598         return ((CDDerivedMesh*)dm)->medge;
2599 }
2600
2601 MFace *CDDM_get_tessfaces(DerivedMesh *dm)
2602 {
2603         return ((CDDerivedMesh*)dm)->mface;
2604 }
2605
2606 MLoop *CDDM_get_loops(DerivedMesh *dm)
2607 {
2608         return ((CDDerivedMesh*)dm)->mloop;
2609 }
2610
2611 MPoly *CDDM_get_polys(DerivedMesh *dm)
2612 {
2613         return ((CDDerivedMesh*)dm)->mpoly;
2614 }
2615
2616 void CDDM_tessfaces_to_faces(DerivedMesh *dm)
2617 {
2618         /*converts mfaces to mpolys/mloops*/
2619         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2620         MFace *mf;
2621         MEdge *me;
2622         MLoop *ml;
2623         MPoly *mp;
2624         EdgeHash *eh = BLI_edgehash_new();
2625         int i, l, totloop, *index1, *index2;
2626         
2627         /*ensure we have all the edges we need*/
2628         CDDM_calc_edges(dm);
2629
2630         /*build edge hash*/
2631         me = cddm->medge;
2632         for (i=0; i<cddm->dm.numEdgeData; i++, me++) {
2633                 BLI_edgehash_insert(eh, me->v1, me->v2, SET_INT_IN_POINTER(i));
2634         }
2635
2636         mf = cddm->mface;
2637         totloop = 0;
2638         for (i=0; i<cddm->dm.numFaceData; i++, mf++) {
2639                 totloop += mf->v4 ? 4 : 3;
2640         }
2641
2642         CustomData_free(&cddm->dm.polyData, cddm->dm.numPolyData);
2643         CustomData_free(&cddm->dm.loopData, cddm->dm.numLoopData);
2644         
2645         cddm->dm.numLoopData = totloop;
2646         cddm->dm.numPolyData = cddm->dm.numFaceData;
2647
2648         if (!totloop) return;
2649
2650         cddm->mloop = MEM_callocN(sizeof(MLoop)*totloop, "cddm->mloop in CDDM_tessfaces_to_faces");
2651         cddm->mpoly = MEM_callocN(sizeof(MPoly)*cddm->dm.numFaceData, "cddm->mpoly in CDDM_tessfaces_to_faces");
2652         
2653         CustomData_add_layer(&cddm->dm.loopData, CD_MLOOP, CD_ASSIGN, cddm->mloop, totloop);
2654         CustomData_add_layer(&cddm->dm.polyData, CD_MPOLY, CD_ASSIGN, cddm->mpoly, cddm->dm.numPolyData);
2655         CustomData_merge(&cddm->dm.faceData, &cddm->dm.polyData, 
2656                 CD_MASK_ORIGINDEX, CD_DUPLICATE, cddm->dm.numFaceData);
2657
2658         index1 = CustomData_get_layer(&cddm->dm.faceData, CD_ORIGINDEX);
2659         index2 = CustomData_get_layer(&cddm->dm.polyData, CD_ORIGINDEX);
2660
2661         mf = cddm->mface;
2662         mp = cddm->mpoly;
2663         ml = cddm->mloop;
2664         l = 0;
2665         for (i=0; i<cddm->dm.numFaceData; i++, mf++, mp++) {
2666                 mp->flag = mf->flag;
2667                 mp->loopstart = l;
2668                 mp->mat_nr = mf->mat_nr;
2669                 mp->totloop = mf->v4 ? 4 : 3;
2670                 
2671                 ml->v = mf->v1;
2672                 ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v1, mf->v2));
2673                 ml++, l++;
2674
2675                 ml->v = mf->v2;
2676                 ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v2, mf->v3));
2677                 ml++, l++;
2678
2679                 ml->v = mf->v3;
2680                 ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v3, mf->v4?mf->v4:mf->v1));
2681                 ml++, l++;
2682
2683                 if (mf->v4) {
2684                         ml->v = mf->v4;
2685                         ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v4, mf->v1));
2686                         ml++, l++;
2687                 }
2688
2689         }
2690
2691         BLI_edgehash_free(eh, NULL);
2692 }
2693
2694 void CDDM_set_mvert(DerivedMesh *dm, MVert *mvert)
2695 {
2696         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2697         
2698         if (!CustomData_has_layer(&dm->vertData, CD_MVERT))
2699                 CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, mvert, dm->numVertData);
2700                                 
2701         cddm->mvert = mvert;
2702 }
2703
2704 void CDDM_set_medge(DerivedMesh *dm, MEdge *medge)
2705 {
2706         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2707
2708         if (!CustomData_has_layer(&dm->edgeData, CD_MEDGE))
2709                 CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, medge, dm->numEdgeData);
2710
2711         cddm->medge = medge;
2712 }
2713
2714 void CDDM_set_mface(DerivedMesh *dm, MFace *mface)
2715 {
2716         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2717
2718         if (!CustomData_has_layer(&dm->faceData, CD_MFACE))
2719                 CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, mface, dm->numFaceData);
2720
2721         cddm->mface = mface;
2722 }