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