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