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