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