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