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