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