Code Cleanup: remove non existing function declarations.
[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), int (*setMaterial)(int, void *attribs))
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                         /* should be per face */
529                         if(!setMaterial(mface->mat_nr+1, NULL))
530                                 return;
531
532                         glShadeModel((mface->flag & ME_SMOOTH)? GL_SMOOTH: GL_FLAT);
533                         BLI_pbvh_draw(cddm->pbvh, partial_redraw_planes, face_nors, (mface->flag & ME_SMOOTH));
534                         glShadeModel(GL_FLAT);
535                 }
536
537                 return;
538         }
539
540         if( GPU_buffer_legacy(dm) ) {
541                 DEBUG_VBO( "Using legacy code. cdDM_drawFacesSolid\n" );
542                 glBegin(glmode = GL_QUADS);
543                 for(a = 0; a < dm->numTessFaceData; a++, mface++) {
544                         int new_glmode, new_matnr, new_shademodel;
545
546                         new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES;
547                         new_matnr = mface->mat_nr + 1;
548                         new_shademodel = (mface->flag & ME_SMOOTH)?GL_SMOOTH:GL_FLAT;
549                         
550                         if(new_glmode != glmode || new_matnr != matnr
551                            || new_shademodel != shademodel) {
552                                 glEnd();
553
554                                 drawCurrentMat = setMaterial(matnr = new_matnr, NULL);
555
556                                 glShadeModel(shademodel = new_shademodel);
557                                 glBegin(glmode = new_glmode);
558                         } 
559                         
560                         if(drawCurrentMat) {
561                                 if(shademodel == GL_FLAT) {
562                                         if (nors) {
563                                                 glNormal3fv(nors);
564                                         }
565                                         else {
566                                                 /* TODO make this better (cache facenormals as layer?) */
567                                                 float nor[3];
568                                                 if(mface->v4) {
569                                                         normal_quad_v3( nor,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co);
570                                                 } else {
571                                                         normal_tri_v3( nor,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co);
572                                                 }
573                                                 glNormal3fv(nor);
574                                         }
575                                 }
576
577                                 PASSVERT(mface->v1);
578                                 PASSVERT(mface->v2);
579                                 PASSVERT(mface->v3);
580                                 if(mface->v4) {
581                                         PASSVERT(mface->v4);
582                                 }
583                         }
584
585                         if(nors) nors += 3;
586                 }
587                 glEnd();
588         }
589         else {  /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
590                 GPU_vertex_setup( dm );
591                 GPU_normal_setup( dm );
592                 if( !GPU_buffer_legacy(dm) ) {
593                         glShadeModel(GL_SMOOTH);
594                         for( a = 0; a < dm->drawObject->totmaterial; a++ ) {
595                                 if( setMaterial(dm->drawObject->materials[a].mat_nr+1, NULL) )
596                                         glDrawArrays(GL_TRIANGLES, dm->drawObject->materials[a].start,
597                                                      dm->drawObject->materials[a].totpoint);
598                         }
599                 }
600                 GPU_buffer_unbind( );
601         }
602
603 #undef PASSVERT
604         glShadeModel(GL_FLAT);
605 }
606
607 static void cdDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *col1, unsigned char *col2)
608 {
609         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
610         int a, glmode;
611         unsigned char *cp1, *cp2;
612         MVert *mvert = cddm->mvert;
613         MFace *mface = cddm->mface;
614
615         cp1 = col1;
616         if(col2) {
617                 cp2 = col2;
618         } else {
619                 cp2 = NULL;
620                 useTwoSided = 0;
621         }
622
623         /* there's a conflict here... twosided colors versus culling...? */
624         /* defined by history, only texture faces have culling option */
625         /* we need that as mesh option builtin, next to double sided lighting */
626         if(col2) {
627                 glEnable(GL_CULL_FACE);
628         }
629
630         cdDM_update_normals_from_pbvh(dm);
631
632         if( GPU_buffer_legacy(dm) ) {
633                 DEBUG_VBO( "Using legacy code. cdDM_drawFacesColored\n" );
634                 glShadeModel(GL_SMOOTH);
635                 glBegin(glmode = GL_QUADS);
636                 for(a = 0; a < dm->numTessFaceData; a++, mface++, cp1 += 16) {
637                         int new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES;
638
639                         if(new_glmode != glmode) {
640                                 glEnd();
641                                 glBegin(glmode = new_glmode);
642                         }
643                                 
644                         glColor3ubv(cp1+0);
645                         glVertex3fv(mvert[mface->v1].co);
646                         glColor3ubv(cp1+4);
647                         glVertex3fv(mvert[mface->v2].co);
648                         glColor3ubv(cp1+8);
649                         glVertex3fv(mvert[mface->v3].co);
650                         if(mface->v4) {
651                                 glColor3ubv(cp1+12);
652                                 glVertex3fv(mvert[mface->v4].co);
653                         }
654                                 
655                         if(useTwoSided) {
656                                 glColor3ubv(cp2+8);
657                                 glVertex3fv(mvert[mface->v3].co );
658                                 glColor3ubv(cp2+4);
659                                 glVertex3fv(mvert[mface->v2].co );
660                                 glColor3ubv(cp2+0);
661                                 glVertex3fv(mvert[mface->v1].co );
662                                 if(mface->v4) {
663                                         glColor3ubv(cp2+12);
664                                         glVertex3fv(mvert[mface->v4].co );
665                                 }
666                         }
667                         if(col2) cp2 += 16;
668                 }
669                 glEnd();
670         }
671         else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
672                 GPU_color4_upload(dm,cp1);
673                 GPU_vertex_setup(dm);
674                 GPU_color_setup(dm);
675                 if( !GPU_buffer_legacy(dm) ) {
676                         glShadeModel(GL_SMOOTH);
677                         glDrawArrays(GL_TRIANGLES, 0, dm->drawObject->tot_triangle_point);
678
679                         if( useTwoSided ) {
680                                 GPU_color4_upload(dm,cp2);
681                                 GPU_color_setup(dm);
682                                 glCullFace(GL_FRONT);
683                                 glDrawArrays(GL_TRIANGLES, 0, dm->drawObject->tot_triangle_point);
684                                 glCullFace(GL_BACK);
685                         }
686                 }
687                 GPU_buffer_unbind();
688         }
689
690         glShadeModel(GL_FLAT);
691         glDisable(GL_CULL_FACE);
692 }
693
694 static void cdDM_drawFacesTex_common(DerivedMesh *dm,
695                            int (*drawParams)(MTFace *tface, int has_mcol, int matnr),
696                            int (*drawParamsMapped)(void *userData, int index),
697                            int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
698                            void *userData) 
699 {
700         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
701         MVert *mv = cddm->mvert;
702         MFace *mf = DM_get_tessface_data_layer(dm, CD_MFACE);
703         MCol *realcol = dm->getTessFaceDataArray(dm, CD_TEXTURE_MCOL);
704         float *nors= dm->getTessFaceDataArray(dm, CD_NORMAL);
705         MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
706         int i, j, orig, *index = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
707         int startFace = 0 /*, lastFlag = 0xdeadbeef */ /* UNUSED */;
708         MCol *mcol = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL);
709         if(!mcol)
710                 mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
711
712         cdDM_update_normals_from_pbvh(dm);
713
714         if( GPU_buffer_legacy(dm) ) {
715                 DEBUG_VBO( "Using legacy code. cdDM_drawFacesTex_common\n" );
716                 for(i = 0; i < dm->numTessFaceData; i++, mf++) {
717                         MVert *mvert;
718                         int flag;
719                         unsigned char *cp = NULL;
720
721                         if(drawParams) {
722                                 flag = drawParams(tf? &tf[i]: NULL, (mcol != NULL), mf->mat_nr);
723                         }
724                         else {
725                                 if(index) {
726                                         orig = *index++;
727                                         if(orig == ORIGINDEX_NONE)              { if(nors) nors += 3; continue; }
728                                         if(drawParamsMapped) flag = drawParamsMapped(userData, orig);
729                                         else    { if(nors) nors += 3; continue; }
730                                 }
731                                 else
732                                         if(drawParamsMapped) flag = drawParamsMapped(userData, i);
733                                         else    { if(nors) nors += 3; continue; }
734                         }
735                         
736                         if(flag != 0) {
737                                 if (flag==1 && mcol)
738                                         cp= (unsigned char*) &mcol[i*4];
739
740                                 if(!(mf->flag&ME_SMOOTH)) {
741                                         if (nors) {
742                                                 glNormal3fv(nors);
743                                         }
744                                         else {
745                                                 float nor[3];
746                                                 if(mf->v4) {
747                                                         normal_quad_v3( nor,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
748                                                 } else {
749                                                         normal_tri_v3( nor,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
750                                                 }
751                                                 glNormal3fv(nor);
752                                         }
753                                 }
754
755                                 glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
756                                 if(tf) glTexCoord2fv(tf[i].uv[0]);
757                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
758                                 mvert = &mv[mf->v1];
759                                 if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
760                                 glVertex3fv(mvert->co);
761                                         
762                                 if(tf) glTexCoord2fv(tf[i].uv[1]);
763                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
764                                 mvert = &mv[mf->v2];
765                                 if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
766                                 glVertex3fv(mvert->co);
767
768                                 if(tf) glTexCoord2fv(tf[i].uv[2]);
769                                 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
770                                 mvert = &mv[mf->v3];
771                                 if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
772                                 glVertex3fv(mvert->co);
773
774                                 if(mf->v4) {
775                                         if(tf) glTexCoord2fv(tf[i].uv[3]);
776                                         if(cp) glColor3ub(cp[15], cp[14], cp[13]);
777                                         mvert = &mv[mf->v4];
778                                         if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
779                                         glVertex3fv(mvert->co);
780                                 }
781                                 glEnd();
782                         }
783                         
784                         if(nors) nors += 3;
785                 }
786         } else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
787                 MCol *col = realcol;
788                 if(!col)
789                         col = mcol;
790
791                 GPU_vertex_setup( dm );
792                 GPU_normal_setup( dm );
793                 GPU_uv_setup( dm );
794                 if( col != NULL ) {
795                         /*if( realcol && dm->drawObject->colType == CD_TEXTURE_MCOL ) {
796                                 col = 0;
797                         } else if( mcol && dm->drawObject->colType == CD_MCOL ) {
798                                 col = 0;
799                         }
800                         
801                         if( col != 0 ) {*/
802                                 unsigned char *colors = MEM_mallocN(dm->getNumTessFaces(dm)*4*3*sizeof(unsigned char), "cdDM_drawFacesTex_common");
803                                 for( i=0; i < dm->getNumTessFaces(dm); i++ ) {
804                                         for( j=0; j < 4; j++ ) {
805                                                 /* bgr -> rgb is intentional (and stupid), but how its stored internally */
806                                                 colors[i*12+j*3] = col[i*4+j].b;
807                                                 colors[i*12+j*3+1] = col[i*4+j].g;
808                                                 colors[i*12+j*3+2] = col[i*4+j].r;
809                                         }
810                                 }
811                                 GPU_color3_upload(dm,colors);
812                                 MEM_freeN(colors);
813                                 if(realcol)
814                                         dm->drawObject->colType = CD_TEXTURE_MCOL;
815                                 else if(mcol)
816                                         dm->drawObject->colType = CD_MCOL;
817                         //}
818                         GPU_color_setup( dm );
819                 }
820
821                 if( !GPU_buffer_legacy(dm) ) {
822                         int tottri = dm->drawObject->tot_triangle_point/3;
823                         int next_actualFace= dm->drawObject->triangle_to_mface[0];
824
825                         glShadeModel( GL_SMOOTH );
826                         /* lastFlag = 0; */ /* UNUSED */
827                         for(i = 0; i < tottri; i++) {
828                                 int actualFace = next_actualFace;
829                                 int flag = 1;
830                                 int flush = 0;
831
832                                 if(i != tottri-1)
833                                         next_actualFace= dm->drawObject->triangle_to_mface[i+1];
834
835                                 if(drawParams) {
836                                         flag = drawParams(tf? &tf[actualFace]: NULL, (mcol != NULL), mf[actualFace].mat_nr);
837                                 }
838                                 else {
839                                         if(index) {
840                                                 orig = index[actualFace];
841                                                 if(orig == ORIGINDEX_NONE) continue;
842                                                 if(drawParamsMapped)
843                                                         flag = drawParamsMapped(userData, orig);
844                                         }
845                                         else
846                                                 if(drawParamsMapped)
847                                                         flag = drawParamsMapped(userData, actualFace);
848                                 }
849
850                                 /* flush buffer if current triangle isn't drawable or it's last triangle */
851                                 flush= !flag || i == tottri - 1;
852
853                                 if(!flush && compareDrawOptions) {
854                                         /* also compare draw options and flush buffer if they're different
855                                            need for face selection highlight in edit mode */
856                                         flush|= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
857                                 }
858
859                                 if(flush) {
860                                         int first= startFace*3;
861                                         int count= (i-startFace+(flag ? 1 : 0))*3; /* Add one to the length if we're drawing at the end of the array */
862
863                                         if(count) {
864                                                 if (col)
865                                                         GPU_color_switch(1);
866                                                 else
867                                                         GPU_color_switch(0);
868
869                                                 glDrawArrays(GL_TRIANGLES, first, count);
870                                         }
871
872                                         startFace = i + 1;
873                                 }
874                         }
875                 }
876
877                 GPU_buffer_unbind();
878                 glShadeModel( GL_FLAT );
879         }
880 }
881
882 static void cdDM_drawFacesTex(DerivedMesh *dm,
883                            int (*setDrawOptions)(MTFace *tface, int has_mcol, int matnr),
884                            int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
885                            void *userData)
886 {
887         cdDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData);
888 }
889
890 static void cdDM_drawMappedFaces(DerivedMesh *dm,
891                         int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r),
892                         int (*setMaterial)(int, void *attribs),
893                         int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
894                         void *userData, int useColors)
895 {
896         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
897         MVert *mv = cddm->mvert;
898         MFace *mf = cddm->mface;
899         MCol *mc;
900         float *nors= DM_get_tessface_data_layer(dm, CD_NORMAL);
901         int i, orig, *index = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
902
903         mc = DM_get_tessface_data_layer(dm, CD_ID_MCOL);
904         if(!mc)
905                 mc = DM_get_tessface_data_layer(dm, CD_WEIGHT_MCOL);
906         if(!mc)
907                 mc = DM_get_tessface_data_layer(dm, CD_MCOL);
908
909         cdDM_update_normals_from_pbvh(dm);
910
911         /* back-buffer always uses legacy since VBO's would need the
912          * color array temporarily overwritten for drawing, then reset. */
913         if( GPU_buffer_legacy(dm) || G.f & G_BACKBUFSEL) {
914                 DEBUG_VBO( "Using legacy code. cdDM_drawMappedFaces\n" );
915                 for(i = 0; i < dm->numTessFaceData; i++, mf++) {
916                         int drawSmooth = (mf->flag & ME_SMOOTH);
917                         int draw= 1;
918
919                         orig= (index==NULL) ? i : *index++;
920                         
921                         if(orig == ORIGINDEX_NONE)
922                                 draw= setMaterial(mf->mat_nr + 1, NULL);
923                         else if (setDrawOptions != NULL)
924                                 draw= setDrawOptions(userData, orig, &drawSmooth);
925
926                         if(draw) {
927                                 unsigned char *cp = NULL;
928
929                                 if(useColors && mc)
930                                         cp = (unsigned char *)&mc[i * 4];
931
932                                 /* no need to set shading mode to flat because
933                                 *  normals are already used to change shading */
934                                 glShadeModel(GL_SMOOTH);
935                                 glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
936
937                                 if (!drawSmooth) {
938                                         if (nors) {
939                                                 glNormal3fv(nors);
940                                         }
941                                         else {
942                                                 float nor[3];
943                                                 if(mf->v4) {
944                                                         normal_quad_v3( nor,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
945                                                 } else {
946                                                         normal_tri_v3( nor,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
947                                                 }
948                                                 glNormal3fv(nor);
949                                         }
950
951                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
952                                         glVertex3fv(mv[mf->v1].co);
953                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
954                                         glVertex3fv(mv[mf->v2].co);
955                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
956                                         glVertex3fv(mv[mf->v3].co);
957                                         if(mf->v4) {
958                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
959                                                 glVertex3fv(mv[mf->v4].co);
960                                         }
961                                 } else {
962                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
963                                         glNormal3sv(mv[mf->v1].no);
964                                         glVertex3fv(mv[mf->v1].co);
965                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
966                                         glNormal3sv(mv[mf->v2].no);
967                                         glVertex3fv(mv[mf->v2].co);
968                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
969                                         glNormal3sv(mv[mf->v3].no);
970                                         glVertex3fv(mv[mf->v3].co);
971                                         if(mf->v4) {
972                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
973                                                 glNormal3sv(mv[mf->v4].no);
974                                                 glVertex3fv(mv[mf->v4].co);
975                                         }
976                                 }
977
978                                 glEnd();
979                         }
980                         
981                         if (nors) nors += 3;
982                 }
983         }
984         else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
985                 int prevstart = 0;
986                 GPU_vertex_setup(dm);
987                 GPU_normal_setup(dm);
988                 if( useColors && mc )
989                         GPU_color_setup(dm);
990                 if( !GPU_buffer_legacy(dm) ) {
991                         int tottri = dm->drawObject->tot_triangle_point/3;
992                         glShadeModel(GL_SMOOTH);
993                         
994                         if(tottri == 0) {
995                                 /* avoid buffer problems in following code */
996                         }
997                         if(setDrawOptions == NULL) {
998                                 /* just draw the entire face array */
999                                 glDrawArrays(GL_TRIANGLES, 0, (tottri) * 3);
1000                         }
1001                         else {
1002                                 /* we need to check if the next material changes */
1003                                 int next_actualFace= dm->drawObject->triangle_to_mface[0];
1004                                 
1005                                 for( i = 0; i < tottri; i++ ) {
1006                                         //int actualFace = dm->drawObject->triangle_to_mface[i];
1007                                         int actualFace = next_actualFace;
1008                                         MFace *mface= mf + actualFace;
1009                                         int drawSmooth= (mface->flag & ME_SMOOTH);
1010                                         int draw = 1;
1011                                         int flush = 0;
1012
1013                                         if(i != tottri-1)
1014                                                 next_actualFace= dm->drawObject->triangle_to_mface[i+1];
1015
1016                                         orig= (index==NULL) ? actualFace : index[actualFace];
1017
1018                                         if(orig == ORIGINDEX_NONE)
1019                                                 draw= setMaterial(mface->mat_nr + 1, NULL);
1020                                         else if (setDrawOptions != NULL)
1021                                                 draw= setDrawOptions(userData, orig, &drawSmooth);
1022         
1023                                         /* Goal is to draw as long of a contiguous triangle
1024                                            array as possible, so draw when we hit either an
1025                                            invisible triangle or at the end of the array */
1026
1027                                         /* flush buffer if current triangle isn't drawable or it's last triangle... */
1028                                         flush= !draw || i == tottri - 1;
1029
1030                                         /* ... or when material setting is dissferent  */
1031                                         flush|= mf[actualFace].mat_nr != mf[next_actualFace].mat_nr;
1032
1033                                         if(!flush && compareDrawOptions) {
1034                                                 flush|= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
1035                                         }
1036
1037                                         if(flush) {
1038                                                 int first= prevstart*3;
1039                                                 int count= (i-prevstart+(draw ? 1 : 0))*3; /* Add one to the length if we're drawing at the end of the array */
1040
1041                                                 if(count)
1042                                                         glDrawArrays(GL_TRIANGLES, first, count);
1043
1044                                                 prevstart = i + 1;
1045                                         }
1046                                 }
1047                         }
1048
1049                         glShadeModel(GL_FLAT);
1050                 }
1051                 GPU_buffer_unbind();
1052         }
1053 }
1054
1055 static void cdDM_drawMappedFacesTex(DerivedMesh *dm,
1056                            int (*setDrawOptions)(void *userData, int index),
1057                            int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
1058                            void *userData)
1059 {
1060         cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData);
1061 }
1062
1063 static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, MVert *mvert, int a, int index, int vert, int smoothnormal)
1064 {
1065         int b;
1066
1067         /* orco texture coordinates */
1068         if(attribs->totorco) {
1069                 if(attribs->orco.glTexco)
1070                         glTexCoord3fv(attribs->orco.array[index]);
1071                 else
1072                         glVertexAttrib3fvARB(attribs->orco.glIndex, attribs->orco.array[index]);
1073         }
1074
1075         /* uv texture coordinates */
1076         for(b = 0; b < attribs->tottface; b++) {
1077                 MTFace *tf = &attribs->tface[b].array[a];
1078
1079                 if(attribs->tface[b].glTexco)
1080                         glTexCoord2fv(tf->uv[vert]);
1081                 else
1082                         glVertexAttrib2fvARB(attribs->tface[b].glIndex, tf->uv[vert]);
1083         }
1084
1085         /* vertex colors */
1086         for(b = 0; b < attribs->totmcol; b++) {
1087                 MCol *cp = &attribs->mcol[b].array[a*4 + vert];
1088                 GLubyte col[4];
1089                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1090                 glVertexAttrib4ubvARB(attribs->mcol[b].glIndex, col);
1091         }
1092
1093         /* tangent for normal mapping */
1094         if(attribs->tottang) {
1095                 float *tang = attribs->tang.array[a*4 + vert];
1096                 glVertexAttrib4fvARB(attribs->tang.glIndex, tang);
1097         }
1098
1099         /* vertex normal */
1100         if(smoothnormal)
1101                 glNormal3sv(mvert[index].no);
1102         
1103         /* vertex coordinate */
1104         glVertex3fv(mvert[index].co);
1105 }
1106
1107 static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
1108                            int (*setMaterial)(int, void *attribs),
1109                            int (*setDrawOptions)(void *userData, int index),
1110                            void *userData)
1111 {
1112         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
1113         GPUVertexAttribs gattribs;
1114         DMVertexAttribs attribs;
1115         MVert *mvert = cddm->mvert;
1116         MFace *mface = cddm->mface;
1117         /* MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */
1118         float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL);
1119         int a, b, dodraw, matnr, new_matnr;
1120         int orig, *index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1121
1122         cdDM_update_normals_from_pbvh(dm);
1123
1124         matnr = -1;
1125         dodraw = 0;
1126
1127         glShadeModel(GL_SMOOTH);
1128
1129         if( GPU_buffer_legacy(dm) || setDrawOptions != NULL ) {
1130                 DEBUG_VBO( "Using legacy code. cdDM_drawMappedFacesGLSL\n" );
1131                 memset(&attribs, 0, sizeof(attribs));
1132
1133                 glBegin(GL_QUADS);
1134
1135                 for(a = 0; a < dm->numTessFaceData; a++, mface++) {
1136                         const int smoothnormal = (mface->flag & ME_SMOOTH);
1137                         new_matnr = mface->mat_nr + 1;
1138
1139                         if(new_matnr != matnr) {
1140                                 glEnd();
1141
1142                                 dodraw = setMaterial(matnr = new_matnr, &gattribs);
1143                                 if(dodraw)
1144                                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1145
1146                                 glBegin(GL_QUADS);
1147                         }
1148
1149                         if(!dodraw) {
1150                                 continue;
1151                         }
1152                         else if(setDrawOptions) {
1153                                 orig = (index)? index[a]: a;
1154
1155                                 if(orig == ORIGINDEX_NONE) {
1156                                         /* since the material is set by setMaterial(), faces with no
1157                                          * origin can be assumed to be generated by a modifier */ 
1158                                         
1159                                         /* continue */
1160                                 }
1161                                 else if(!setDrawOptions(userData, orig))
1162                                         continue;
1163                         }
1164
1165                         if(!smoothnormal) {
1166                                 if(nors) {
1167                                         glNormal3fv(nors[a]);
1168                                 }
1169                                 else {
1170                                         /* TODO ideally a normal layer should always be available */
1171                                         float nor[3];
1172                                         if(mface->v4) {
1173                                                 normal_quad_v3( nor,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co);
1174                                         } else {
1175                                                 normal_tri_v3( nor,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co);
1176                                         }
1177                                         glNormal3fv(nor);
1178                                 }
1179                         }
1180
1181                         cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v1, 0, smoothnormal);
1182                         cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v2, 1, smoothnormal);
1183                         cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal);
1184
1185                         if(mface->v4)
1186                                 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v4, 3, smoothnormal);
1187                         else
1188                                 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal);
1189                 }
1190                 glEnd();
1191         }
1192         else {
1193                 GPUBuffer *buffer = NULL;
1194                 char *varray = NULL;
1195                 int numdata = 0, elementsize = 0, offset;
1196                 int start = 0, numfaces = 0 /* , prevdraw = 0 */ /* UNUSED */, curface = 0;
1197                 int i;
1198
1199                 MFace *mf = mface;
1200                 GPUAttrib datatypes[GPU_MAX_ATTRIB]; /* TODO, messing up when switching materials many times - [#21056]*/
1201                 memset(&attribs, 0, sizeof(attribs));
1202
1203                 GPU_vertex_setup(dm);
1204                 GPU_normal_setup(dm);
1205
1206                 if( !GPU_buffer_legacy(dm) ) {
1207                         for( i = 0; i < dm->drawObject->tot_triangle_point/3; i++ ) {
1208
1209                                 a = dm->drawObject->triangle_to_mface[i];
1210
1211                                 mface = mf + a;
1212                                 new_matnr = mface->mat_nr + 1;
1213
1214                                 if(new_matnr != matnr ) {
1215                                         numfaces = curface - start;
1216                                         if( numfaces > 0 ) {
1217
1218                                                 if( dodraw ) {
1219
1220                                                         if( numdata != 0 ) {
1221
1222                                                                 GPU_buffer_unlock(buffer);
1223
1224                                                                 GPU_interleaved_attrib_setup(buffer,datatypes,numdata);
1225                                                         }
1226
1227                                                         glDrawArrays(GL_TRIANGLES,start*3,numfaces*3);
1228
1229                                                         if( numdata != 0 ) {
1230
1231                                                                 GPU_buffer_free(buffer);
1232
1233                                                                 buffer = NULL;
1234                                                         }
1235
1236                                                 }
1237                                         }
1238                                         numdata = 0;
1239                                         start = curface;
1240                                         /* prevdraw = dodraw; */ /* UNUSED */
1241                                         dodraw = setMaterial(matnr = new_matnr, &gattribs);
1242                                         if(dodraw) {
1243                                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1244
1245                                                 if(attribs.totorco) {
1246                                                         datatypes[numdata].index = attribs.orco.glIndex;
1247                                                         datatypes[numdata].size = 3;
1248                                                         datatypes[numdata].type = GL_FLOAT;
1249                                                         numdata++;
1250                                                 }
1251                                                 for(b = 0; b < attribs.tottface; b++) {
1252                                                         datatypes[numdata].index = attribs.tface[b].glIndex;
1253                                                         datatypes[numdata].size = 2;
1254                                                         datatypes[numdata].type = GL_FLOAT;
1255                                                         numdata++;
1256                                                 }       
1257                                                 for(b = 0; b < attribs.totmcol; b++) {
1258                                                         datatypes[numdata].index = attribs.mcol[b].glIndex;
1259                                                         datatypes[numdata].size = 4;
1260                                                         datatypes[numdata].type = GL_UNSIGNED_BYTE;
1261                                                         numdata++;
1262                                                 }       
1263                                                 if(attribs.tottang) {
1264                                                         datatypes[numdata].index = attribs.tang.glIndex;
1265                                                         datatypes[numdata].size = 4;
1266                                                         datatypes[numdata].type = GL_FLOAT;
1267                                                         numdata++;
1268                                                 }
1269                                                 if( numdata != 0 ) {
1270                                                         elementsize = GPU_attrib_element_size( datatypes, numdata );
1271                                                         buffer = GPU_buffer_alloc( elementsize*dm->drawObject->tot_triangle_point);
1272                                                         if( buffer == NULL ) {
1273                                                                 GPU_buffer_unbind();
1274                                                                 dm->drawObject->legacy = 1;
1275                                                                 return;
1276                                                         }
1277                                                         varray = GPU_buffer_lock_stream(buffer);
1278                                                         if( varray == NULL ) {
1279                                                                 GPU_buffer_unbind();
1280                                                                 GPU_buffer_free(buffer);
1281                                                                 dm->drawObject->legacy = 1;
1282                                                                 return;
1283                                                         }
1284                                                 }
1285                                                 else {
1286                                                         /* if the buffer was set, dont use it again.
1287                                                          * prevdraw was assumed true but didnt run so set to false - [#21036] */
1288                                                         /* prevdraw= 0; */ /* UNUSED */
1289                                                         buffer= NULL;
1290                                                 }
1291                                         }
1292                                 }
1293
1294                                 if(dodraw && numdata != 0 ) {
1295                                         offset = 0;
1296                                         if(attribs.totorco) {
1297                                                 copy_v3_v3((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v1]);
1298                                                 copy_v3_v3((float *)&varray[elementsize*curface*3+elementsize],(float *)attribs.orco.array[mface->v2]);
1299                                                 copy_v3_v3((float *)&varray[elementsize*curface*3+elementsize*2],(float *)attribs.orco.array[mface->v3]);
1300                                                 offset += sizeof(float)*3;
1301                                         }
1302                                         for(b = 0; b < attribs.tottface; b++) {
1303                                                 MTFace *tf = &attribs.tface[b].array[a];
1304                                                 copy_v2_v2((float *)&varray[elementsize*curface*3+offset],tf->uv[0]);
1305                                                 copy_v2_v2((float *)&varray[elementsize*curface*3+offset+elementsize],tf->uv[1]);
1306
1307                                                 copy_v2_v2((float *)&varray[elementsize*curface*3+offset+elementsize*2],tf->uv[2]);
1308                                                 offset += sizeof(float)*2;
1309                                         }
1310                                         for(b = 0; b < attribs.totmcol; b++) {
1311                                                 MCol *cp = &attribs.mcol[b].array[a*4 + 0];
1312                                                 GLubyte col[4];
1313                                                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1314                                                 copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset], (char *)col);
1315                                                 cp = &attribs.mcol[b].array[a*4 + 1];
1316                                                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1317                                                 copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset+elementsize], (char *)col);
1318                                                 cp = &attribs.mcol[b].array[a*4 + 2];
1319                                                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1320                                                 copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset+elementsize*2], (char *)col);
1321                                                 offset += sizeof(unsigned char)*4;
1322                                         }       
1323                                         if(attribs.tottang) {
1324                                                 float *tang = attribs.tang.array[a*4 + 0];
1325                                                 copy_v4_v4((float *)&varray[elementsize*curface*3+offset], tang);
1326                                                 tang = attribs.tang.array[a*4 + 1];
1327                                                 copy_v4_v4((float *)&varray[elementsize*curface*3+offset+elementsize], tang);
1328                                                 tang = attribs.tang.array[a*4 + 2];
1329                                                 copy_v4_v4((float *)&varray[elementsize*curface*3+offset+elementsize*2], tang);
1330                                                 offset += sizeof(float)*4;
1331                                         }
1332                                         (void)offset;
1333                                 }
1334                                 curface++;
1335                                 if(mface->v4) {
1336                                         if(dodraw && numdata != 0 ) {
1337                                                 offset = 0;
1338                                                 if(attribs.totorco) {
1339                                                         copy_v3_v3((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v3]);
1340                                                         copy_v3_v3((float *)&varray[elementsize*curface*3+elementsize],(float *)attribs.orco.array[mface->v4]);
1341                                                         copy_v3_v3((float *)&varray[elementsize*curface*3+elementsize*2],(float *)attribs.orco.array[mface->v1]);
1342                                                         offset += sizeof(float)*3;
1343                                                 }
1344                                                 for(b = 0; b < attribs.tottface; b++) {
1345                                                         MTFace *tf = &attribs.tface[b].array[a];
1346                                                         copy_v2_v2((float *)&varray[elementsize*curface*3+offset],tf->uv[2]);
1347                                                         copy_v2_v2((float *)&varray[elementsize*curface*3+offset+elementsize],tf->uv[3]);
1348                                                         copy_v2_v2((float *)&varray[elementsize*curface*3+offset+elementsize*2],tf->uv[0]);
1349                                                         offset += sizeof(float)*2;
1350                                                 }
1351                                                 for(b = 0; b < attribs.totmcol; b++) {
1352                                                         MCol *cp = &attribs.mcol[b].array[a*4 + 2];
1353                                                         GLubyte col[4];
1354                                                         col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1355                                                         copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset], (char *)col);
1356                                                         cp = &attribs.mcol[b].array[a*4 + 3];
1357                                                         col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1358                                                         copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset+elementsize], (char *)col);
1359                                                         cp = &attribs.mcol[b].array[a*4 + 0];
1360                                                         col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1361                                                         copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset+elementsize*2], (char *)col);
1362                                                         offset += sizeof(unsigned char)*4;
1363                                                 }       
1364                                                 if(attribs.tottang) {
1365                                                         float *tang = attribs.tang.array[a*4 + 2];
1366                                                         copy_v4_v4((float *)&varray[elementsize*curface*3+offset], tang);
1367                                                         tang = attribs.tang.array[a*4 + 3];
1368                                                         copy_v4_v4((float *)&varray[elementsize*curface*3+offset+elementsize], tang);
1369                                                         tang = attribs.tang.array[a*4 + 0];
1370                                                         copy_v4_v4((float *)&varray[elementsize*curface*3+offset+elementsize*2], tang);
1371                                                         offset += sizeof(float)*4;
1372                                                 }
1373                                                 (void)offset;
1374                                         }
1375                                         curface++;
1376                                         i++;
1377                                 }
1378                         }
1379                         numfaces = curface - start;
1380                         if( numfaces > 0 ) {
1381                                 if( dodraw ) {
1382                                         if( numdata != 0 ) {
1383                                                 GPU_buffer_unlock(buffer);
1384                                                 GPU_interleaved_attrib_setup(buffer,datatypes,numdata);
1385                                         }
1386                                         glDrawArrays(GL_TRIANGLES,start*3,(curface-start)*3);
1387                                 }
1388                         }
1389                         GPU_buffer_unbind();
1390                 }
1391                 GPU_buffer_free(buffer);
1392         }
1393
1394         glShadeModel(GL_FLAT);
1395 }
1396
1397 static void cdDM_drawFacesGLSL(DerivedMesh *dm,int (*setMaterial)(int, void *attribs))
1398 {
1399         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1400 }
1401
1402 static void cdDM_drawMappedFacesMat(DerivedMesh *dm,
1403         void (*setMaterial)(void *userData, int, void *attribs),
1404         int (*setFace)(void *userData, int index), void *userData)
1405 {
1406         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
1407         GPUVertexAttribs gattribs;
1408         DMVertexAttribs attribs;
1409         MVert *mvert = cddm->mvert;
1410         MFace *mf = cddm->mface;
1411         float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL);
1412         int a, matnr, new_matnr;
1413         int orig, *index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1414
1415         cdDM_update_normals_from_pbvh(dm);
1416
1417         matnr = -1;
1418
1419         glShadeModel(GL_SMOOTH);
1420
1421         memset(&attribs, 0, sizeof(attribs));
1422
1423         glBegin(GL_QUADS);
1424
1425         for(a = 0; a < dm->numTessFaceData; a++, mf++) {
1426                 const int smoothnormal = (mf->flag & ME_SMOOTH);
1427
1428                 /* material */
1429                 new_matnr = mf->mat_nr + 1;
1430
1431                 if(new_matnr != matnr) {
1432                         glEnd();
1433
1434                         setMaterial(userData, matnr = new_matnr, &gattribs);
1435                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1436
1437                         glBegin(GL_QUADS);
1438                 }
1439
1440                 /* skipping faces */
1441                 if(setFace) {
1442                         orig = (index)? index[a]: a;
1443
1444                         if(orig != ORIGINDEX_NONE && !setFace(userData, orig))
1445                                 continue;
1446                 }
1447
1448                 /* smooth normal */
1449                 if(!smoothnormal) {
1450                         if(nors) {
1451                                 glNormal3fv(nors[a]);
1452                         }
1453                         else {
1454                                 /* TODO ideally a normal layer should always be available */
1455                                 float nor[3];
1456
1457                                 if(mf->v4)
1458                                         normal_quad_v3( nor,mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co);
1459                                 else
1460                                         normal_tri_v3( nor,mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co);
1461
1462                                 glNormal3fv(nor);
1463                         }
1464                 }
1465
1466                 /* vertices */
1467                 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v1, 0, smoothnormal);
1468                 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v2, 1, smoothnormal);
1469                 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal);
1470
1471                 if(mf->v4)
1472                         cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v4, 3, smoothnormal);
1473                 else
1474                         cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal);
1475         }
1476         glEnd();
1477
1478         glShadeModel(GL_FLAT);
1479 }
1480
1481 static void cdDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
1482 {
1483         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
1484         MVert *vert = cddm->mvert;
1485         MEdge *edge = cddm->medge;
1486         int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1487
1488         glBegin(GL_LINES);
1489         for(i = 0; i < dm->numEdgeData; i++, edge++) {
1490                 if(index) {
1491                         orig = *index++;
1492                         if(setDrawOptions && orig == ORIGINDEX_NONE) continue;
1493                 }
1494                 else
1495                         orig = i;
1496
1497                 if(!setDrawOptions || setDrawOptions(userData, orig)) {
1498                         glVertex3fv(vert[edge->v1].co);
1499                         glVertex3fv(vert[edge->v2].co);
1500                 }
1501         }
1502         glEnd();
1503 }
1504
1505 static void cdDM_foreachMappedVert(
1506                                                    DerivedMesh *dm,
1507                                                    void (*func)(void *userData, int index, float *co,
1508                                                                                 float *no_f, short *no_s),
1509                                                    void *userData)
1510 {
1511         MVert *mv = CDDM_get_verts(dm);
1512         int i, orig, *index = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
1513
1514         for(i = 0; i < dm->numVertData; i++, mv++) {
1515                 if(index) {
1516                         orig = *index++;
1517                         if(orig == ORIGINDEX_NONE) continue;
1518                         func(userData, orig, mv->co, NULL, mv->no);
1519                 }
1520                 else
1521                         func(userData, i, mv->co, NULL, mv->no);
1522         }
1523 }
1524
1525 static void cdDM_foreachMappedEdge(
1526                                                    DerivedMesh *dm,
1527                                                    void (*func)(void *userData, int index,
1528                                                                                 float *v0co, float *v1co),
1529                                                    void *userData)
1530 {
1531         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
1532         MVert *mv = cddm->mvert;
1533         MEdge *med = cddm->medge;
1534         int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1535
1536         for(i = 0; i < dm->numEdgeData; i++, med++) {
1537                 if (index) {
1538                         orig = *index++;
1539                         if(orig == ORIGINDEX_NONE) continue;
1540                         func(userData, orig, mv[med->v1].co, mv[med->v2].co);
1541                 }
1542                 else
1543                         func(userData, i, mv[med->v1].co, mv[med->v2].co);
1544         }
1545 }
1546
1547 static void cdDM_foreachMappedFaceCenter(
1548                                                    DerivedMesh *dm,
1549                                                    void (*func)(void *userData, int index,
1550                                                                                 float *cent, float *no),
1551                                                    void *userData)
1552 {
1553         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1554         MVert *mv = cddm->mvert;
1555         MPoly *mf = cddm->mpoly;
1556         MLoop *ml = cddm->mloop;
1557         int i, j, orig, *index;
1558
1559         index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
1560         mf = cddm->mpoly;
1561         for(i = 0; i < dm->numPolyData; i++, mf++) {
1562                 float cent[3];
1563                 float no[3];
1564
1565                 if (index) {
1566                         orig = *index++;
1567                         if(orig == ORIGINDEX_NONE) continue;
1568                 }
1569                 else
1570                         orig = i;
1571                 
1572                 ml = &cddm->mloop[mf->loopstart];
1573                 cent[0] = cent[1] = cent[2] = 0.0f;
1574                 for (j=0; j<mf->totloop; j++, ml++) {
1575                         add_v3_v3v3(cent, cent, mv[ml->v].co);
1576                 }
1577                 mul_v3_fl(cent, 1.0f / (float)j);
1578
1579                 ml = &cddm->mloop[mf->loopstart];
1580                 if (j > 3) {
1581                         normal_quad_v3(no, mv[ml->v].co, mv[(ml+1)->v].co,
1582                                        mv[(ml+2)->v].co, mv[(ml+3)->v].co);
1583                 } else {
1584                         normal_tri_v3(no, mv[ml->v].co, mv[(ml+1)->v].co, mv[(ml+2)->v].co);
1585                 }
1586
1587                 func(userData, orig, cent, no);
1588         }
1589
1590 }
1591
1592 void CDDM_recalc_tesselation_ex(DerivedMesh *dm, const int do_face_nor_cpy)
1593 {
1594         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1595
1596         dm->numTessFaceData = mesh_recalcTesselation(&dm->faceData, &dm->loopData, &dm->polyData,
1597                                                      cddm->mvert,
1598                                                      dm->numTessFaceData, dm->numLoopData, dm->numPolyData,
1599                                                      do_face_nor_cpy);
1600
1601         if (!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX)) {
1602                 int *polyIndex = CustomData_get_layer(&dm->faceData, CD_POLYINDEX);
1603                 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_REFERENCE, polyIndex, dm->numTessFaceData);
1604         }
1605
1606         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1607
1608         /* Tesselation recreated faceData, and the active layer indices need to get re-propagated
1609            from loops and polys to faces */
1610         CustomData_bmesh_update_active_layers(&dm->faceData, &dm->polyData, &dm->loopData);
1611 }
1612
1613 void CDDM_recalc_tesselation(DerivedMesh *dm)
1614 {
1615         CDDM_recalc_tesselation_ex(dm, TRUE);
1616 }
1617
1618 static void cdDM_free_internal(CDDerivedMesh *cddm)
1619 {
1620         if(cddm->fmap) MEM_freeN(cddm->fmap);
1621         if(cddm->fmap_mem) MEM_freeN(cddm->fmap_mem);
1622
1623         if(cddm->pmap) MEM_freeN(cddm->pmap);
1624         if(cddm->pmap_mem) MEM_freeN(cddm->pmap_mem);
1625 }
1626
1627 static void cdDM_release(DerivedMesh *dm)
1628 {
1629         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1630
1631         if (DM_release(dm)) {
1632                 cdDM_free_internal(cddm);
1633                 MEM_freeN(cddm);
1634         }
1635 }
1636
1637 int CDDM_Check(DerivedMesh *dm)
1638 {
1639         return dm && dm->getMinMax == cdDM_getMinMax;
1640 }
1641
1642 /**************** CDDM interface functions ****************/
1643 static CDDerivedMesh *cdDM_create(const char *desc)
1644 {
1645         CDDerivedMesh *cddm;
1646         DerivedMesh *dm;
1647
1648         cddm = MEM_callocN(sizeof(*cddm), desc);
1649         dm = &cddm->dm;
1650
1651         dm->getMinMax = cdDM_getMinMax;
1652
1653         dm->getNumVerts = cdDM_getNumVerts;
1654         dm->getNumEdges = cdDM_getNumEdges;
1655         dm->getNumTessFaces = cdDM_getNumTessFaces;
1656         dm->getNumLoops = cdDM_getNumLoops;
1657         dm->getNumPolys = cdDM_getNumPolys;
1658
1659         dm->getVert = cdDM_getVert;
1660         dm->getEdge = cdDM_getEdge;
1661         dm->getTessFace = cdDM_getTessFace;
1662
1663         dm->copyVertArray = cdDM_copyVertArray;
1664         dm->copyEdgeArray = cdDM_copyEdgeArray;
1665         dm->copyTessFaceArray = cdDM_copyTessFaceArray;
1666         dm->copyLoopArray = cdDM_copyLoopArray;
1667         dm->copyPolyArray = cdDM_copyPolyArray;
1668
1669         dm->getVertData = DM_get_vert_data;
1670         dm->getEdgeData = DM_get_edge_data;
1671         dm->getTessFaceData = DM_get_tessface_data;
1672         dm->getVertDataArray = DM_get_vert_data_layer;
1673         dm->getEdgeDataArray = DM_get_edge_data_layer;
1674         dm->getTessFaceDataArray = DM_get_tessface_data_layer;
1675
1676         dm->calcNormals = CDDM_calc_normals_mapping;
1677         dm->recalcTesselation = CDDM_recalc_tesselation;
1678
1679         dm->getVertCos = cdDM_getVertCos;
1680         dm->getVertCo = cdDM_getVertCo;
1681         dm->getVertNo = cdDM_getVertNo;
1682
1683         dm->getPBVH = cdDM_getPBVH;
1684         dm->getPolyMap = cdDM_getPolyMap;
1685
1686         dm->drawVerts = cdDM_drawVerts;
1687
1688         dm->drawUVEdges = cdDM_drawUVEdges;
1689         dm->drawEdges = cdDM_drawEdges;
1690         dm->drawLooseEdges = cdDM_drawLooseEdges;
1691         dm->drawMappedEdges = cdDM_drawMappedEdges;
1692
1693         dm->drawFacesSolid = cdDM_drawFacesSolid;
1694         dm->drawFacesColored = cdDM_drawFacesColored;
1695         dm->drawFacesTex = cdDM_drawFacesTex;
1696         dm->drawFacesGLSL = cdDM_drawFacesGLSL;
1697         dm->drawMappedFaces = cdDM_drawMappedFaces;
1698         dm->drawMappedFacesTex = cdDM_drawMappedFacesTex;
1699         dm->drawMappedFacesGLSL = cdDM_drawMappedFacesGLSL;
1700         dm->drawMappedFacesMat = cdDM_drawMappedFacesMat;
1701
1702         dm->foreachMappedVert = cdDM_foreachMappedVert;
1703         dm->foreachMappedEdge = cdDM_foreachMappedEdge;
1704         dm->foreachMappedFaceCenter = cdDM_foreachMappedFaceCenter;
1705
1706         dm->release = cdDM_release;
1707
1708         return cddm;
1709 }
1710
1711 DerivedMesh *CDDM_new(int numVerts, int numEdges, int numTessFaces, int numLoops, int numPolys)
1712 {
1713         CDDerivedMesh *cddm = cdDM_create("CDDM_new dm");
1714         DerivedMesh *dm = &cddm->dm;
1715
1716         DM_init(dm, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces, numLoops, numPolys);
1717
1718         CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
1719         CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
1720         CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numTessFaces);
1721         CustomData_add_layer(&dm->faceData, CD_POLYINDEX, CD_CALLOC, NULL, numTessFaces);
1722         CustomData_add_layer(&dm->polyData, CD_ORIGINDEX, CD_CALLOC, NULL, numPolys);
1723
1724         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
1725         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
1726         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numTessFaces);
1727         CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL, numLoops);
1728         CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL, numPolys);
1729
1730         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1731         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1732         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1733         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
1734         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
1735
1736         return dm;
1737 }
1738
1739 DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob))
1740 {
1741         CDDerivedMesh *cddm = cdDM_create("CDDM_from_mesh dm");
1742         DerivedMesh *dm = &cddm->dm;
1743         CustomDataMask mask = CD_MASK_MESH & (~CD_MASK_MDISPS);
1744         int alloctype;
1745         int *polyindex = NULL;
1746
1747         /* this does a referenced copy, with an exception for fluidsim */
1748
1749         DM_init(dm, DM_TYPE_CDDM, mesh->totvert, mesh->totedge, mesh->totface,
1750                     mesh->totloop, mesh->totpoly);
1751
1752         dm->deformedOnly = 1;
1753
1754         alloctype= CD_REFERENCE;
1755
1756         CustomData_merge(&mesh->vdata, &dm->vertData, mask, alloctype,
1757                                          mesh->totvert);
1758         CustomData_merge(&mesh->edata, &dm->edgeData, mask, alloctype,
1759                                          mesh->totedge);
1760         CustomData_merge(&mesh->fdata, &dm->faceData, mask|CD_MASK_POLYINDEX, alloctype,
1761                                          mesh->totface);
1762         CustomData_merge(&mesh->ldata, &dm->loopData, mask, alloctype,
1763                          mesh->totloop);
1764         CustomData_merge(&mesh->pdata, &dm->polyData, mask, alloctype,
1765                          mesh->totpoly);
1766
1767         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1768         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1769         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
1770         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
1771         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1772
1773         /* commented since even when CD_POLYINDEX was first added this line fails
1774          * on the default cube, (after editmode toggle too) - campbell */
1775 #if 0
1776         BLI_assert(CustomData_has_layer(&cddm->dm.faceData, CD_POLYINDEX));
1777 #endif
1778
1779         polyindex = CustomData_get_layer(&dm->faceData, CD_POLYINDEX);
1780         if (!CustomData_has_layer(&cddm->dm.faceData, CD_ORIGINDEX)) {
1781                 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_REFERENCE, polyindex, mesh->totface);
1782         }
1783
1784         return dm;
1785 }
1786
1787 DerivedMesh *CDDM_from_curve(Object *ob)
1788 {
1789         return CDDM_from_curve_customDB(ob, &ob->disp);
1790 }
1791
1792 DerivedMesh *CDDM_from_curve_customDB(Object *ob, ListBase *dispbase)
1793 {
1794         DerivedMesh *dm;
1795         CDDerivedMesh *cddm;
1796         MVert *allvert;
1797         MEdge *alledge;
1798         MLoop *allloop;
1799         MPoly *allpoly;
1800         int totvert, totedge, totloop, totpoly;
1801
1802         if (nurbs_to_mdata_customdb(ob, dispbase, &allvert, &totvert, &alledge,
1803                 &totedge, &allloop, &allpoly, &totloop, &totpoly) != 0) {
1804                 /* Error initializing mdata. This often happens when curve is empty */
1805                 return CDDM_new(0, 0, 0, 0, 0);
1806         }
1807
1808         dm = CDDM_new(totvert, totedge, 0, totloop, totpoly);
1809         dm->deformedOnly = 1;
1810
1811         cddm = (CDDerivedMesh*)dm;
1812
1813         memcpy(cddm->mvert, allvert, totvert*sizeof(MVert));
1814         memcpy(cddm->medge, alledge, totedge*sizeof(MEdge));
1815         memcpy(cddm->mloop, allloop, totloop*sizeof(MLoop));
1816         memcpy(cddm->mpoly, allpoly, totpoly*sizeof(MPoly));
1817
1818         MEM_freeN(allvert);
1819         MEM_freeN(alledge);
1820         MEM_freeN(allloop);
1821         MEM_freeN(allpoly);
1822
1823         CDDM_calc_edges(dm);
1824
1825         return dm;
1826 }
1827
1828 static void loops_to_customdata_corners(BMesh *bm, CustomData *facedata,
1829                                           int cdindex, BMLoop *l3[3],
1830                                           int numCol, int numTex)
1831 {
1832         BMLoop *l;
1833         BMFace *f = l3[0]->f;
1834         MTFace *texface;
1835         MTexPoly *texpoly;
1836         MCol *mcol;
1837         MLoopCol *mloopcol;
1838         MLoopUV *mloopuv;
1839         int i, j, hasWCol = CustomData_has_layer(&bm->ldata, CD_WEIGHT_MLOOPCOL);
1840
1841         for (i=0; i < numTex; i++) {
1842                 texface = CustomData_get_n(facedata, CD_MTFACE, cdindex, i);
1843                 texpoly = CustomData_bmesh_get_n(&bm->pdata, f->head.data, CD_MTEXPOLY, i);
1844                 
1845                 ME_MTEXFACE_CPY(texface, texpoly);
1846         
1847                 for (j=0; j<3; j++) {
1848                         l = l3[j];
1849                         mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPUV, i);
1850                         copy_v2_v2(texface->uv[j], mloopuv->uv);
1851                 }
1852         }
1853
1854         for (i=0; i < numCol; i++) {
1855                 mcol = CustomData_get_n(facedata, CD_MCOL, cdindex, i);
1856                 
1857                 for (j=0; j<3; j++) {
1858                         l = l3[j];
1859                         mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPCOL, i);
1860                         mcol[j].r = mloopcol->r;
1861                         mcol[j].g = mloopcol->g;
1862                         mcol[j].b = mloopcol->b;
1863                         mcol[j].a = mloopcol->a;
1864                 }
1865         }
1866
1867         if (hasWCol) {
1868                 mcol = CustomData_get(facedata, cdindex, CD_WEIGHT_MCOL);
1869
1870                 for (j=0; j<3; j++) {
1871                         l = l3[j];
1872                         mloopcol = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_WEIGHT_MLOOPCOL);
1873                         mcol[j].r = mloopcol->r;
1874                         mcol[j].g = mloopcol->g;
1875                         mcol[j].b = mloopcol->b;
1876                         mcol[j].a = mloopcol->a;
1877                 }
1878         }
1879 }
1880
1881 DerivedMesh *CDDM_from_BMEditMesh(BMEditMesh *em, Mesh *UNUSED(me), int use_mdisps, int use_tessface)
1882 {
1883         BMesh *bm = em->bm;
1884
1885         DerivedMesh *dm = CDDM_new(bm->totvert,
1886                                    bm->totedge,
1887                                    use_tessface ? em->tottri : 0,
1888                                    bm->totloop,
1889                                    bm->totface);
1890
1891         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1892         BMIter iter, liter;
1893         BMVert *eve;
1894         BMEdge *eed;
1895         BMFace *efa;
1896         MVert *mvert = cddm->mvert;
1897         MEdge *medge = cddm->medge;
1898         MFace *mface = cddm->mface;
1899         MLoop *mloop = cddm->mloop;
1900         MPoly *mpoly = cddm->mpoly;
1901         int numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL);
1902         int numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
1903         int *index, add_orig;
1904         int has_crease, has_edge_bweight, has_vert_bweight;
1905         CustomDataMask mask;
1906         unsigned int i, j;
1907         
1908         has_edge_bweight = CustomData_has_layer(&bm->edata, CD_BWEIGHT);
1909         has_vert_bweight = CustomData_has_layer(&bm->vdata, CD_BWEIGHT);
1910         has_crease = CustomData_has_layer(&bm->edata, CD_CREASE);
1911         
1912         dm->deformedOnly = 1;
1913         
1914         /*don't add origindex layer if one already exists*/
1915         add_orig = !CustomData_has_layer(&bm->pdata, CD_ORIGINDEX);
1916
1917         mask = use_mdisps ? CD_MASK_DERIVEDMESH|CD_MASK_MDISPS : CD_MASK_DERIVEDMESH;
1918         
1919         /*don't process shapekeys, we only feed them through the modifier stack as needed,
1920           e.g. for applying modifiers or the like*/
1921         mask &= ~CD_MASK_SHAPEKEY;
1922         CustomData_merge(&bm->vdata, &dm->vertData, mask,
1923                          CD_CALLOC, dm->numVertData);
1924         CustomData_merge(&bm->edata, &dm->edgeData, mask,
1925                          CD_CALLOC, dm->numEdgeData);
1926         CustomData_merge(&bm->ldata, &dm->loopData, mask,
1927                          CD_CALLOC, dm->numLoopData);
1928         CustomData_merge(&bm->pdata, &dm->polyData, mask,
1929                          CD_CALLOC, dm->numPolyData);
1930         
1931         /*add tesselation mface layers*/
1932         if (use_tessface) {
1933                 CustomData_from_bmeshpoly(&dm->faceData, &dm->polyData, &dm->loopData, em->tottri);
1934         }
1935
1936         index = dm->getVertDataArray(dm, CD_ORIGINDEX);
1937
1938         eve = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL);
1939         for (i=0; eve; eve=BM_iter_step(&iter), i++, index++) {
1940                 MVert *mv = &mvert[i];
1941
1942                 copy_v3_v3(mv->co, eve->co);
1943
1944                 BM_elem_index_set(eve, i); /* set_inline */
1945
1946                 normal_float_to_short_v3(mv->no, eve->no);
1947
1948                 mv->flag = BM_vert_flag_to_mflag(eve);
1949
1950                 if (has_vert_bweight)
1951                         mv->bweight = (unsigned char)(BM_elem_float_data_get(&bm->vdata, eve, CD_BWEIGHT)*255.0f);
1952
1953                 if (add_orig) *index = i;
1954
1955                 CustomData_from_bmesh_block(&bm->vdata, &dm->vertData, eve->head.data, i);
1956         }
1957         bm->elem_index_dirty &= ~BM_VERT;
1958
1959         index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
1960         eed = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, NULL);
1961         for (i=0; eed; eed=BM_iter_step(&iter), i++, index++) {
1962                 MEdge *med = &medge[i];
1963
1964                 BM_elem_index_set(eed, i); /* set_inline */
1965
1966                 med->v1 = BM_elem_index_get(eed->v1);
1967                 med->v2 = BM_elem_index_get(eed->v2);
1968
1969                 if (has_crease)
1970                         med->crease = (unsigned char)(BM_elem_float_data_get(&bm->edata, eed, CD_CREASE)*255.0f);
1971                 if (has_edge_bweight)
1972                         med->bweight = (unsigned char)(BM_elem_float_data_get(&bm->edata, eed, CD_BWEIGHT)*255.0f);
1973                 
1974                 med->flag = BM_edge_flag_to_mflag(eed);
1975
1976                 CustomData_from_bmesh_block(&bm->edata, &dm->edgeData, eed->head.data, i);
1977                 if (add_orig) *index = i;
1978         }
1979         bm->elem_index_dirty &= ~BM_EDGE;
1980
1981         /* avoid this where possiblem, takes extra memory */
1982         if (use_tessface) {
1983                 int *polyindex;
1984
1985                 BM_mesh_elem_index_ensure(bm, BM_FACE);
1986
1987                 polyindex = dm->getTessFaceDataArray(dm, CD_POLYINDEX);
1988                 index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1989                 for(i = 0; i < dm->numTessFaceData; i++, index++, polyindex++) {
1990                         MFace *mf = &mface[i];
1991                         BMLoop **l = em->looptris[i];
1992                         efa = l[0]->f;
1993
1994                         mf->v1 = BM_elem_index_get(l[0]->v);
1995                         mf->v2 = BM_elem_index_get(l[1]->v);
1996                         mf->v3 = BM_elem_index_get(l[2]->v);
1997                         mf->v4 = 0;
1998                         mf->mat_nr = efa->mat_nr;
1999                         mf->flag = BM_face_flag_to_mflag(efa);
2000
2001                         *index = add_orig ? BM_elem_index_get(efa) : *(int*)CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_ORIGINDEX);
2002                         *polyindex = BM_elem_index_get(efa);
2003
2004                         loops_to_customdata_corners(bm, &dm->faceData, i, l, numCol, numTex);
2005                         test_index_face(mf, &dm->faceData, i, 3);
2006                 }
2007         }
2008         
2009         index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
2010         j = 0;
2011         efa = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, NULL);
2012         for (i=0; efa; i++, efa=BM_iter_step(&iter), index++) {
2013                 BMLoop *l;
2014                 MPoly *mp = &mpoly[i];
2015
2016                 BM_elem_index_set(efa, i); /* set_inline */
2017
2018                 mp->totloop = efa->len;
2019                 mp->flag = BM_face_flag_to_mflag(efa);
2020                 mp->loopstart = j;
2021                 mp->mat_nr = efa->mat_nr;
2022                 
2023                 BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, efa) {
2024                         mloop->v = BM_elem_index_get(l->v);
2025                         mloop->e = BM_elem_index_get(l->e);
2026                         CustomData_from_bmesh_block(&bm->ldata, &dm->loopData, l->head.data, j);
2027
2028                         j++;
2029                         mloop++;
2030                 }
2031
2032                 CustomData_from_bmesh_block(&bm->pdata, &dm->polyData, efa->head.data, i);
2033
2034                 if (add_orig) *index = i;
2035         }
2036         bm->elem_index_dirty &= ~BM_FACE;
2037
2038         return dm;
2039 }
2040
2041 static DerivedMesh *cddm_copy_ex(DerivedMesh *source, int faces_from_tessfaces)
2042 {
2043         CDDerivedMesh *cddm = cdDM_create("CDDM_copy cddm");
2044         DerivedMesh *dm = &cddm->dm;
2045         int numVerts = source->numVertData;
2046         int numEdges = source->numEdgeData;
2047         int numTessFaces = source->numTessFaceData;
2048         int numLoops = source->numLoopData;
2049         int numPolys = source->numPolyData;
2050
2051         /* ensure these are created if they are made on demand */
2052         source->getVertDataArray(source, CD_ORIGINDEX);
2053         source->getEdgeDataArray(source, CD_ORIGINDEX);
2054         source->getTessFaceDataArray(source, CD_ORIGINDEX);
2055
2056         /* this initializes dm, and copies all non mvert/medge/mface layers */
2057         DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces,
2058                 numLoops, numPolys);
2059         dm->deformedOnly = source->deformedOnly;
2060
2061         CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts);
2062         CustomData_copy_data(&source->edgeData, &dm->edgeData, 0, 0, numEdges);
2063         CustomData_copy_data(&source->faceData, &dm->faceData, 0, 0, numTessFaces);
2064
2065         /* now add mvert/medge/mface layers */
2066         cddm->mvert = source->dupVertArray(source);
2067         cddm->medge = source->dupEdgeArray(source);
2068         cddm->mface = source->dupTessFaceArray(source);
2069
2070         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, cddm->mvert, numVerts);
2071         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, cddm->medge, numEdges);
2072         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, cddm->mface, numTessFaces);
2073         
2074         if (!faces_from_tessfaces)
2075                 DM_DupPolys(source, dm);
2076         else
2077                 CDDM_tessfaces_to_faces(dm);
2078
2079         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
2080         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
2081
2082         /* any callers that need tessface data can calculate it - campbell */
2083 #if 0
2084         /* BMESH_TODO: Find out why this is necessary (or else find a way to remove
2085            it). If it is necessary, add a comment explaining why. */
2086         CDDM_recalc_tesselation((DerivedMesh *)cddm);
2087 #endif
2088
2089         return dm;
2090 }
2091
2092 DerivedMesh *CDDM_copy(DerivedMesh *source)
2093 {
2094         return cddm_copy_ex(source, 0);
2095 }
2096
2097 DerivedMesh *CDDM_copy_from_tessface(DerivedMesh *source)
2098 {
2099         return cddm_copy_ex(source, 1);
2100 }
2101
2102 /* note, the CD_ORIGINDEX layers are all 0, so if there is a direct
2103  * relationship betwen mesh data this needs to be set by the caller. */
2104 DerivedMesh *CDDM_from_template(DerivedMesh *source,
2105                                 int numVerts, int numEdges, int numTessFaces,
2106                                 int numLoops, int numPolys)
2107 {
2108         CDDerivedMesh *cddm = cdDM_create("CDDM_from_template dest");
2109         DerivedMesh *dm = &cddm->dm;
2110
2111         /* ensure these are created if they are made on demand */
2112         source->getVertDataArray(source, CD_ORIGINDEX);
2113         source->getEdgeDataArray(source, CD_ORIGINDEX);
2114         source->getTessFaceDataArray(source, CD_ORIGINDEX);
2115
2116         /* this does a copy of all non mvert/medge/mface layers */
2117         DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces, numLoops, numPolys);
2118
2119         /* now add mvert/medge/mface layers */
2120         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
2121         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2122         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numTessFaces);
2123         CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL, numLoops);
2124         CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL, numPolys);
2125
2126         if(!CustomData_get_layer(&dm->vertData, CD_ORIGINDEX))
2127                 CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
2128         if(!CustomData_get_layer(&dm->edgeData, CD_ORIGINDEX))
2129                 CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2130         if(!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX))
2131                 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numTessFaces);
2132         if(!CustomData_get_layer(&dm->faceData, CD_POLYINDEX))
2133                 CustomData_add_layer(&dm->faceData, CD_POLYINDEX, CD_CALLOC, NULL, numTessFaces);
2134
2135         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
2136         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2137         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
2138         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
2139         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
2140
2141         return dm;
2142 }
2143
2144 void CDDM_apply_vert_coords(DerivedMesh *dm, float (*vertCoords)[3])
2145 {
2146         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2147         MVert *vert;
2148         int i;
2149
2150         /* this will just return the pointer if it wasn't a referenced layer */
2151         vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2152         cddm->mvert = vert;
2153
2154         for(i = 0; i < dm->numVertData; ++i, ++vert)
2155                 copy_v3_v3(vert->co, vertCoords[i]);
2156 }
2157
2158 void CDDM_apply_vert_normals(DerivedMesh *dm, short (*vertNormals)[3])
2159 {
2160         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2161         MVert *vert;
2162         int i;
2163
2164         /* this will just return the pointer if it wasn't a referenced layer */
2165         vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2166         cddm->mvert = vert;
2167
2168         for(i = 0; i < dm->numVertData; ++i, ++vert)
2169                 copy_v3_v3_short(vert->no, vertNormals[i]);
2170 }
2171
2172 void CDDM_calc_normals_mapping(DerivedMesh *dm)
2173 {
2174         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2175         float (*face_nors)[3] = NULL;
2176
2177         /* use this to skip calculating normals on original vert's, this may need to be changed */
2178         const short only_face_normals = CustomData_is_referenced_layer(&dm->vertData, CD_MVERT);
2179         
2180         if(dm->numVertData == 0) return;
2181
2182         /* now we skip calculating vertex normals for referenced layer,
2183          * no need to duplicate verts.
2184          * WATCH THIS, bmesh only change!,
2185          * need to take care of the side effects here - campbell */
2186 #if 0
2187         /* we don't want to overwrite any referenced layers */
2188         cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2189 #endif
2190
2191
2192         if (dm->numTessFaceData == 0) {
2193                 /* No tesselation on this mesh yet, need to calculate one.
2194                  *
2195                  * Important not to update face normals from polys since it
2196                  * interfears with assigning the new normal layer in the following code.
2197                  */
2198                 CDDM_recalc_tesselation_ex(dm, FALSE);
2199         }
2200         else {
2201                 /* A tesselation already exists, it should always have a CD_POLYINDEX */
2202                 BLI_assert(CustomData_has_layer(&dm->faceData, CD_POLYINDEX));
2203                 CustomData_free_layers(&dm->faceData, CD_NORMAL, dm->numTessFaceData);
2204         }
2205
2206
2207         face_nors = MEM_mallocN(sizeof(float)*3*dm->numTessFaceData, "face_nors");
2208         
2209         /* calculate face normals */
2210         mesh_calc_normals_mapping_ex(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm),
2211                                      dm->numLoopData, dm->numPolyData, NULL, cddm->mface, dm->numTessFaceData,
2212                                      CustomData_get_layer(&dm->faceData, CD_POLYINDEX), face_nors,
2213                                      only_face_normals);
2214         
2215         CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_ASSIGN, 
2216                              face_nors, dm->numTessFaceData);
2217
2218
2219 }
2220
2221 /* bmesh note: this matches what we have in trunk */
2222 void CDDM_calc_normals(DerivedMesh *dm)
2223 {
2224         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2225         float (*poly_nors)[3];
2226
2227         if(dm->numVertData == 0) return;
2228
2229         /* we don't want to overwrite any referenced layers */
2230         cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2231
2232         /* fill in if it exists */
2233         poly_nors = CustomData_get_layer(&dm->polyData, CD_NORMAL);
2234         if (!poly_nors) {
2235                 poly_nors = CustomData_add_layer(&dm->polyData, CD_NORMAL, CD_CALLOC, NULL, dm->numPolyData);
2236         }
2237
2238         mesh_calc_normals(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm),
2239                           dm->numLoopData, dm->numPolyData, poly_nors);
2240 }
2241
2242 void CDDM_calc_normals_tessface(DerivedMesh *dm)
2243 {
2244         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2245         float (*face_nors)[3];
2246
2247         if(dm->numVertData == 0) return;
2248
2249         /* we don't want to overwrite any referenced layers */
2250         cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2251
2252         /* fill in if it exists */
2253         face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
2254         if (!face_nors) {
2255                 face_nors = CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_CALLOC, NULL, dm->numTessFaceData);
2256         }
2257
2258         mesh_calc_normals_tessface(cddm->mvert, dm->numVertData,
2259                                                            cddm->mface, dm->numTessFaceData, face_nors);
2260 }
2261
2262 #if 1
2263 /* merge verts
2264  *
2265  * vtargetmap is a table that maps vertices to target vertices.  a value of -1
2266  * indicates a vertex is a target, and is to be kept.
2267  *
2268  * this frees dm, and returns a new one.
2269  *
2270  * this is a really horribly written function.  ger. - joeedh
2271  *
2272  * note, CDDM_recalc_tesselation has to run on the returned DM if you want to access tessfaces.
2273  */
2274 DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap)
2275 {
2276         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2277         CDDerivedMesh *cddm2 = NULL;
2278         MVert *mv, *mvert = NULL;
2279         BLI_array_declare(mvert);
2280         MEdge *med, *medge = NULL;
2281         BLI_array_declare(medge);
2282         MPoly *mp, *mpoly = NULL;
2283         BLI_array_declare(mpoly);
2284         MLoop *ml, *mloop = NULL;
2285         BLI_array_declare(mloop);
2286         EdgeHash *ehash = BLI_edgehash_new();
2287         int *newv = NULL, *newe = NULL, *newl = NULL;
2288         int *oldv = NULL, *olde = NULL, *oldl = NULL, *oldp = NULL;
2289         BLI_array_declare(oldv); BLI_array_declare(olde); BLI_array_declare(oldl); BLI_array_declare(oldp);
2290         int i, j, c, totloop, totpoly;
2291         
2292         totloop = dm->numLoopData;
2293         totpoly = dm->numPolyData;
2294         
2295         newv = MEM_callocN(sizeof(int)*dm->numVertData, "newv vtable CDDM_merge_verts");
2296         newe = MEM_callocN(sizeof(int)*dm->numEdgeData, "newv etable CDDM_merge_verts");
2297         newl = MEM_callocN(sizeof(int)*totloop, "newv ltable CDDM_merge_verts");
2298         
2299         /*fill newl with destination vertex indices*/
2300         mv = cddm->mvert;
2301         c = 0;
2302         for (i=0; i<dm->numVertData; i++, mv++) {
2303                 if (vtargetmap[i] == -1) {
2304                         BLI_array_append(oldv, i);
2305                         newv[i] = c++;
2306                         BLI_array_append(mvert, *mv);
2307                 }
2308         }
2309         
2310         /*now link target vertices to destination indices*/
2311         for (i=0; i<dm->numVertData; i++) {
2312                 if (vtargetmap[i] != -1) {
2313                         newv[i] = newv[vtargetmap[i]];
2314                 }
2315         }
2316         
2317         /*find-replace merged vertices with target vertices*/   
2318         ml = cddm->mloop;
2319         c = 0;
2320         for (i=0; i<totloop; i++, ml++) {
2321                 if (vtargetmap[ml->v] != -1) {
2322                         ml->v = vtargetmap[ml->v];
2323                 }
2324         }
2325
2326         /*now go through and fix edges and faces*/
2327         med = cddm->medge;
2328         c = 0;
2329         for (i=0; i<dm->numEdgeData; i++, med++) {
2330                 
2331                 if (LIKELY(med->v1 != med->v2)) {
2332                         const unsigned int v1 = (vtargetmap[med->v1] != -1) ? vtargetmap[med->v1] : med->v1;
2333                         const unsigned int v2 = (vtargetmap[med->v2] != -1) ? vtargetmap[med->v2] : med->v2;
2334                         void **eh_p= BLI_edgehash_lookup_p(ehash, v1, v2);
2335
2336                         if (eh_p) {
2337                                 newe[i] = GET_INT_FROM_POINTER(*eh_p);
2338                         }
2339                         else {
2340                                 BLI_array_append(olde, i);
2341                                 newe[i] = c;
2342                                 BLI_array_append(medge, *med);
2343                                 BLI_edgehash_insert(ehash, v1, v2, SET_INT_IN_POINTER(c));
2344                                 c++;
2345                         }
2346                 }
2347                 else {
2348                         newe[i] = -1;
2349                 }
2350         }
2351         
2352         mp = cddm->mpoly;
2353         for (i=0; i<totpoly; i++, mp++) {
2354                 MPoly *mp2;
2355                 
2356                 ml = cddm->mloop + mp->loopstart;
2357
2358                 c = 0;
2359                 for (j=0; j<mp->totloop; j++, ml++) {
2360                         med = cddm->medge + ml->e;
2361                         if (LIKELY(med->v1 != med->v2)) {
2362                                 newl[j+mp->loopstart] = BLI_array_count(mloop);
2363                                 BLI_array_append(oldl, j+mp->loopstart);
2364                                 BLI_array_append(mloop, *ml);
2365                                 c++;
2366                         }
2367                 }
2368
2369                 if (UNLIKELY(c == 0)) {
2370                         continue;
2371                 }
2372                 
2373                 mp2 = BLI_array_append_r(mpoly, *mp);
2374                 mp2->totloop = c;
2375                 mp2->loopstart = BLI_array_count(mloop) - c;
2376                 
2377                 BLI_array_append(oldp, i);
2378         }
2379         
2380         /*create new cddm*/     
2381         cddm2 = (CDDerivedMesh*) CDDM_from_template((DerivedMesh*)cddm, BLI_array_count(mvert), BLI_array_count(medge), 0, BLI_array_count(mloop), BLI_array_count(mpoly));
2382         
2383         /*update edge indices and copy customdata*/
2384         med = medge;
2385         for (i=0; i<cddm2->dm.numEdgeData; i++, med++) {
2386                 if (newv[med->v1] != -1)
2387                         med->v1 = newv[med->v1];
2388                 if (newv[med->v2] != -1)
2389                         med->v2 = newv[med->v2];
2390                 
2391                 CustomData_copy_data(&dm->edgeData, &cddm2->dm.edgeData, olde[i], i, 1);
2392         }
2393         
2394         /*update loop indices and copy customdata*/
2395         ml = mloop;
2396         for (i=0; i<cddm2->dm.numLoopData; i++, ml++) {
2397                 if (newe[ml->e] != -1)
2398                         ml->e = newe[ml->e];
2399                 if (newv[ml->v] != -1)
2400                         ml->v = newv[ml->v];
2401                         
2402                 CustomData_copy_data(&dm->loopData, &cddm2->dm.loopData, oldl[i], i, 1);
2403         }
2404         
2405         /*copy vertex customdata*/      
2406         mv = mvert;
2407         for (i=0; i<cddm2->dm.numVertData; i++, mv++) {
2408                 CustomData_copy_data(&dm->vertData, &cddm2->dm.vertData, oldv[i], i, 1);
2409         }
2410         
2411         /*copy poly customdata*/
2412         mp = mpoly;
2413         for (i=0; i<cddm2->dm.numPolyData; i++, mp++) {
2414                 CustomData_copy_data(&dm->polyData, &cddm2->dm.polyData, oldp[i], i, 1);
2415         }
2416         
2417         /*copy over data.  CustomData_add_layer can do this, need to look it up.*/
2418         memcpy(cddm2->mvert, mvert, sizeof(MVert)*BLI_array_count(mvert));
2419         memcpy(cddm2->medge, medge, sizeof(MEdge)*BLI_array_count(medge));
2420         memcpy(cddm2->mloop, mloop, sizeof(MLoop)*BLI_array_count(mloop));
2421         memcpy(cddm2->mpoly, mpoly, sizeof(MPoly)*BLI_array_count(mpoly));
2422         BLI_array_free(mvert); BLI_array_free(medge); BLI_array_free(mloop); BLI_array_free(mpoly);
2423         
2424         if (newv) 
2425                 MEM_freeN(newv); 
2426         if (newe)
2427                 MEM_freeN(newe); 
2428         if (newl)
2429                 MEM_freeN(newl);
2430         if (oldv) 
2431                 MEM_freeN(oldv); 
2432         if (olde) 
2433                 MEM_freeN(olde); 
2434         if (oldl) 
2435                 MEM_freeN(oldl); 
2436         if (oldp) 
2437                 MEM_freeN(oldp);
2438         if (ehash)
2439                 BLI_edgehash_free(ehash, NULL);
2440
2441         /*free old derivedmesh*/
2442         dm->needsFree = 1;
2443         dm->release(dm);
2444         
2445         return (DerivedMesh*)cddm2;
2446 }
2447 #endif
2448
2449 void CDDM_calc_edges_tessface(DerivedMesh *dm)
2450 {
2451         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2452         CustomData edgeData;
2453         EdgeHashIterator *ehi;
2454         MFace *mf = cddm->mface;
2455         MEdge *med;
2456         EdgeHash *eh = BLI_edgehash_new();
2457         int i, *index, numEdges, maxFaces = dm->numTessFaceData;
2458
2459         for (i = 0; i < maxFaces; i++, mf++) {
2460                 if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
2461                         BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
2462                 if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
2463                         BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
2464                 
2465                 if (mf->v4) {
2466                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
2467                                 BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
2468                         if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
2469                                 BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
2470                 } else {
2471                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
2472                                 BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
2473                 }
2474         }
2475
2476         numEdges = BLI_edgehash_size(eh);
2477
2478         /* write new edges into a temporary CustomData */
2479         memset(&edgeData, 0, sizeof(edgeData));
2480         CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2481         CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2482
2483         ehi = BLI_edgehashIterator_new(eh);
2484         med = CustomData_get_layer(&edgeData, CD_MEDGE);
2485         index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
2486         for(i = 0; !BLI_edgehashIterator_isDone(ehi);
2487                 BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) {
2488                 BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2);
2489
2490                 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
2491                 *index = ORIGINDEX_NONE;
2492         }
2493         BLI_edgehashIterator_free(ehi);
2494
2495         /* free old CustomData and assign new one */
2496         CustomData_free(&dm->edgeData, dm->numEdgeData);
2497         dm->edgeData = edgeData;
2498         dm->numEdgeData = numEdges;
2499
2500         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2501
2502         BLI_edgehash_free(eh, NULL);
2503 }
2504
2505 /* warning, this uses existing edges but CDDM_calc_edges_tessface() doesn't */
2506 void CDDM_calc_edges(DerivedMesh *dm)
2507 {
2508         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2509         CustomData edgeData;
2510         EdgeHashIterator *ehi;
2511         MPoly *mp = cddm->mpoly;
2512         MLoop *ml;
2513         MEdge *med;
2514         EdgeHash *eh = BLI_edgehash_new();
2515         int v1, v2;
2516         int *eindex;
2517         int i, j, *index, numEdges = cddm->dm.numEdgeData, maxFaces = dm->numPolyData;
2518
2519         eindex = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
2520
2521         med = cddm->medge;
2522         if (med) {
2523                 for (i=0; i < numEdges; i++, med++) {
2524                         BLI_edgehash_insert(eh, med->v1, med->v2, SET_INT_IN_POINTER(i+1));
2525                 }
2526         }
2527
2528         for (i=0; i < maxFaces; i++, mp++) {
2529                 ml = cddm->mloop + mp->loopstart;
2530                 for (j=0; j<mp->totloop; j++, ml++) {
2531                         v1 = ml->v;
2532                         v2 = ME_POLY_LOOP_NEXT(cddm->mloop, mp, j)->v;
2533                         if (!BLI_edgehash_haskey(eh, v1, v2)) {
2534                                 BLI_edgehash_insert(eh, v1, v2, NULL);
2535                         }
2536                 }
2537         }
2538
2539         numEdges = BLI_edgehash_size(eh);
2540
2541         /* write new edges into a temporary CustomData */
2542         memset(&edgeData, 0, sizeof(edgeData));
2543         CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2544         CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2545
2546         ehi = BLI_edgehashIterator_new(eh);
2547         med = CustomData_get_layer(&edgeData, CD_MEDGE);
2548         index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
2549         for(i = 0; !BLI_edgehashIterator_isDone(ehi);
2550             BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) {
2551                 BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2);
2552                 j = GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi));
2553
2554                 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
2555                 *index = j==0 ? ORIGINDEX_NONE : eindex[j-1];
2556
2557                 BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(i));
2558         }
2559         BLI_edgehashIterator_free(ehi);
2560
2561         /* free old CustomData and assign new one */
2562         CustomData_free(&dm->edgeData, dm->numEdgeData);
2563         dm->edgeData = edgeData;
2564         dm->numEdgeData = numEdges;
2565
2566         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2567
2568         mp = cddm->mpoly;
2569         for (i=0; i < maxFaces; i++, mp++) {
2570                 ml = cddm->mloop + mp->loopstart;
2571                 for (j=0; j<mp->totloop; j++, ml++) {
2572                         v1 = ml->v;
2573                         v2 = ME_POLY_LOOP_NEXT(cddm->mloop, mp, j)->v;
2574                         ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, v1, v2));
2575                 }
2576         }
2577
2578         BLI_edgehash_free(eh, NULL);
2579 }
2580
2581 void CDDM_lower_num_verts(DerivedMesh *dm, int numVerts)
2582 {
2583         if (numVerts < dm->numVertData)
2584                 CustomData_free_elem(&dm->vertData, numVerts, dm->numVertData-numVerts);
2585
2586         dm->numVertData = numVerts;
2587 }
2588
2589 void CDDM_lower_num_edges(DerivedMesh *dm, int numEdges)
2590 {
2591         if (numEdges < dm->numEdgeData)
2592                 CustomData_free_elem(&dm->edgeData, numEdges, dm->numEdgeData-numEdges);
2593
2594         dm->numEdgeData = numEdges;
2595 }
2596
2597 void CDDM_lower_num_tessfaces(DerivedMesh *dm, int numTessFaces)
2598 {
2599         if (numTessFaces < dm->numTessFaceData)
2600                 CustomData_free_elem(&dm->faceData, numTessFaces, dm->numTessFaceData-numTessFaces);
2601
2602         dm->numTessFaceData = numTessFaces;
2603 }
2604
2605 void CDDM_lower_num_polys(DerivedMesh *dm, int numPolys)
2606 {
2607         if (numPolys < dm->numPolyData)
2608                 CustomData_free_elem(&dm->polyData, numPolys, dm->numPolyData-numPolys);
2609
2610         dm->numPolyData = numPolys;
2611 }
2612
2613 /* mesh element access functions */
2614
2615 MVert *CDDM_get_vert(DerivedMesh *dm, int index)
2616 {
2617         return &((CDDerivedMesh*)dm)->mvert[index];
2618 }
2619
2620 MEdge *CDDM_get_edge(DerivedMesh *dm, int index)
2621 {
2622         return &((CDDerivedMesh*)dm)->medge[index];
2623 }
2624
2625 MFace *CDDM_get_tessface(DerivedMesh *dm, int index)
2626 {
2627         return &((CDDerivedMesh*)dm)->mface[index];
2628 }
2629
2630 MLoop *CDDM_get_loop(DerivedMesh *dm, int index)
2631 {
2632         return &((CDDerivedMesh*)dm)->mloop[index];
2633 }
2634
2635 MPoly *CDDM_get_poly(DerivedMesh *dm, int index)
2636 {
2637         return &((CDDerivedMesh*)dm)->mpoly[index];
2638 }
2639
2640 /* array access functions */
2641
2642 MVert *CDDM_get_verts(DerivedMesh *dm)
2643 {
2644         return ((CDDerivedMesh*)dm)->mvert;
2645 }
2646
2647 MEdge *CDDM_get_edges(DerivedMesh *dm)
2648 {
2649         return ((CDDerivedMesh*)dm)->medge;
2650 }
2651
2652 MFace *CDDM_get_tessfaces(DerivedMesh *dm)
2653 {
2654         return ((CDDerivedMesh*)dm)->mface;
2655 }
2656
2657 MLoop *CDDM_get_loops(DerivedMesh *dm)
2658 {
2659         return ((CDDerivedMesh*)dm)->mloop;
2660 }
2661
2662 MPoly *CDDM_get_polys(DerivedMesh *dm)
2663 {
2664         return ((CDDerivedMesh*)dm)->mpoly;
2665 }
2666
2667 void CDDM_tessfaces_to_faces(DerivedMesh *dm)
2668 {
2669         /*converts mfaces to mpolys/mloops*/
2670         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2671         MFace *mf;
2672         MEdge *me;
2673         EdgeHash *eh = BLI_edgehash_new();
2674         int i, totloop;
2675         
2676         /*ensure we have all the edges we need*/
2677         CDDM_calc_edges_tessface(dm);
2678
2679         /*build edge hash*/
2680         me = cddm->medge;
2681         for (i=0; i<cddm->dm.numEdgeData; i++, me++) {
2682                 BLI_edgehash_insert(eh, me->v1, me->v2, SET_INT_IN_POINTER(i));
2683         }
2684
2685         mf = cddm->mface;
2686         totloop = 0;
2687         for (i=0; i<cddm->dm.numTessFaceData; i++, mf++) {
2688                 totloop += mf->v4 ? 4 : 3;
2689         }
2690
2691         CustomData_free(&cddm->dm.polyData, cddm->dm.numPolyData);
2692         CustomData_free(&cddm->dm.loopData, cddm->dm.numLoopData);
2693         
2694         cddm->dm.numLoopData = totloop;
2695         cddm->dm.numPolyData = cddm->dm.numTessFaceData;
2696
2697         if (totloop) {
2698                 MLoop *ml;
2699                 MPoly *mp;
2700                 int l, *polyindex;
2701
2702                 cddm->mloop = MEM_callocN(sizeof(MLoop)*totloop, "cddm->mloop in CDDM_tessfaces_to_faces");
2703                 cddm->mpoly = MEM_callocN(sizeof(MPoly)*cddm->dm.numTessFaceData, "cddm->mpoly in CDDM_tessfaces_to_faces");
2704
2705                 CustomData_add_layer(&cddm->dm.loopData, CD_MLOOP, CD_ASSIGN, cddm->mloop, totloop);
2706                 CustomData_add_layer(&cddm->dm.polyData, CD_MPOLY, CD_ASSIGN, cddm->mpoly, cddm->dm.numPolyData);
2707                 CustomData_merge(&cddm->dm.faceData, &cddm->dm.polyData,
2708                         CD_MASK_ORIGINDEX, CD_DUPLICATE, cddm->dm.numTessFaceData);
2709
2710                 polyindex = CustomData_get_layer(&cddm->dm.faceData, CD_POLYINDEX);
2711
2712                 mf = cddm->mface;
2713                 mp = cddm->mpoly;
2714                 ml = cddm->mloop;
2715                 l = 0;
2716                 for (i=0; i<cddm->dm.numTessFaceData; i++, mf++, mp++) {
2717                         mp->flag = mf->flag;
2718                         mp->loopstart = l;
2719                         mp->mat_nr = mf->mat_nr;
2720                         mp->totloop = mf->v4 ? 4 : 3;
2721
2722                         ml->v = mf->v1;
2723                         ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v1, mf->v2));
2724                         ml++, l++;
2725
2726                         ml->v = mf->v2;
2727                         ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v2, mf->v3));
2728                         ml++, l++;
2729
2730                         ml->v = mf->v3;
2731                         ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v3, mf->v4?mf->v4:mf->v1));
2732                         ml++, l++;
2733
2734                         if (mf->v4) {
2735                                 ml->v = mf->v4;
2736                                 ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v4, mf->v1));
2737                                 ml++, l++;
2738                         }
2739
2740                         *polyindex = i;
2741                 }
2742         }
2743
2744         BLI_edgehash_free(eh, NULL);
2745 }
2746
2747 void CDDM_set_mvert(DerivedMesh *dm, MVert *mvert)
2748 {
2749         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2750         
2751         if (!CustomData_has_layer(&dm->vertData, CD_MVERT))
2752                 CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, mvert, dm->numVertData);
2753                                 
2754         cddm->mvert = mvert;
2755 }
2756
2757 void CDDM_set_medge(DerivedMesh *dm, MEdge *medge)
2758 {
2759         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2760
2761         if (!CustomData_has_layer(&dm->edgeData, CD_MEDGE))
2762                 CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, medge, dm->numEdgeData);
2763
2764         cddm->medge = medge;
2765 }
2766
2767 void CDDM_set_mface(DerivedMesh *dm, MFace *mface)
2768 {
2769         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2770
2771         if (!CustomData_has_layer(&dm->faceData, CD_MFACE))
2772                 CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, mface, dm->numTessFaceData);
2773
2774         cddm->mface = mface;
2775 }
2776
2777 void CDDM_set_mloop(DerivedMesh *dm, MLoop *mloop)
2778 {
2779         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2780
2781         if (!CustomData_has_layer(&dm->loopData, CD_MLOOP))
2782                 CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_ASSIGN, mloop, dm->numLoopData);
2783
2784         cddm->mloop = mloop;
2785 }
2786
2787 void CDDM_set_mpoly(DerivedMesh *dm, MPoly *mpoly)
2788 {
2789         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2790
2791         if (!CustomData_has_layer(&dm->polyData, CD_MPOLY))
2792                 CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_ASSIGN, mpoly, dm->numPolyData);
2793
2794         cddm->mpoly = mpoly;
2795 }