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