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