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