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