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