style cleanup
[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         colType = CD_TEXTURE_MCOL;
651         mcol = dm->getTessFaceDataArray(dm, colType);
652         if (!mcol) {
653                 colType = CD_PREVIEW_MCOL;
654                 mcol = dm->getTessFaceDataArray(dm, colType);
655         }
656         if (!mcol) {
657                 colType = CD_MCOL;
658                 mcol = dm->getTessFaceDataArray(dm, colType);
659         }
660
661         cdDM_update_normals_from_pbvh(dm);
662
663         if (GPU_buffer_legacy(dm)) {
664                 DEBUG_VBO("Using legacy code. cdDM_drawFacesTex_common\n");
665                 for (i = 0; i < dm->numTessFaceData; i++, mf++) {
666                         MVert *mvert;
667                         DMDrawOption draw_option;
668                         unsigned char *cp = NULL;
669
670                         if (drawParams) {
671                                 draw_option = drawParams(tf ? &tf[i] : NULL, (mcol != NULL), mf->mat_nr);
672                         }
673                         else {
674                                 if (index_mf_to_mpoly) {
675                                         orig = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i);
676                                         if (orig == ORIGINDEX_NONE) {
677                                                 /* XXX, this is not really correct
678                                                  * it will draw the previous faces context for this one when we don't know its settings.
679                                                  * but better then skipping it altogether. - campbell */
680                                                 draw_option = DM_DRAW_OPTION_NORMAL;
681                                         }
682                                         else if (drawParamsMapped) {
683                                                 draw_option = drawParamsMapped(userData, orig);
684                                         }
685                                         else {
686                                                 if (nors) {
687                                                         nors += 3; continue;
688                                                 }
689                                         }
690                                 }
691                                 else if (drawParamsMapped) {
692                                         draw_option = drawParamsMapped(userData, i);
693                                 }
694                                 else {
695                                         if (nors) {
696                                                 nors += 3; continue;
697                                         }
698                                 }
699                         }
700                         
701                         if (draw_option != DM_DRAW_OPTION_SKIP) {
702                                 if (draw_option != DM_DRAW_OPTION_NO_MCOL && mcol)
703                                         cp = (unsigned char *) &mcol[i * 4];
704
705                                 if (!(mf->flag & ME_SMOOTH)) {
706                                         if (nors) {
707                                                 glNormal3fv(nors);
708                                         }
709                                         else {
710                                                 float nor[3];
711                                                 if (mf->v4) {
712                                                         normal_quad_v3(nor, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
713                                                 }
714                                                 else {
715                                                         normal_tri_v3(nor, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
716                                                 }
717                                                 glNormal3fv(nor);
718                                         }
719                                 }
720
721                                 glBegin(mf->v4 ? GL_QUADS : GL_TRIANGLES);
722                                 if (tf) glTexCoord2fv(tf[i].uv[0]);
723                                 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
724                                 mvert = &mv[mf->v1];
725                                 if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
726                                 glVertex3fv(mvert->co);
727                                         
728                                 if (tf) glTexCoord2fv(tf[i].uv[1]);
729                                 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
730                                 mvert = &mv[mf->v2];
731                                 if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
732                                 glVertex3fv(mvert->co);
733
734                                 if (tf) glTexCoord2fv(tf[i].uv[2]);
735                                 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
736                                 mvert = &mv[mf->v3];
737                                 if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
738                                 glVertex3fv(mvert->co);
739
740                                 if (mf->v4) {
741                                         if (tf) glTexCoord2fv(tf[i].uv[3]);
742                                         if (cp) glColor3ub(cp[15], cp[14], cp[13]);
743                                         mvert = &mv[mf->v4];
744                                         if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
745                                         glVertex3fv(mvert->co);
746                                 }
747                                 glEnd();
748                         }
749                         
750                         if (nors) nors += 3;
751                 }
752         }
753         else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
754                 GPU_vertex_setup(dm);
755                 GPU_normal_setup(dm);
756                 GPU_uv_setup(dm);
757                 if (mcol) {
758                         GPU_color_setup(dm, colType);
759                 }
760
761                 if (!GPU_buffer_legacy(dm)) {
762                         int tottri = dm->drawObject->tot_triangle_point / 3;
763                         int next_actualFace = dm->drawObject->triangle_to_mface[0];
764
765                         glShadeModel(GL_SMOOTH);
766                         /* lastFlag = 0; */ /* UNUSED */
767                         for (i = 0; i < tottri; i++) {
768                                 int actualFace = next_actualFace;
769                                 DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
770                                 int flush = 0;
771
772                                 if (i != tottri - 1)
773                                         next_actualFace = dm->drawObject->triangle_to_mface[i + 1];
774
775                                 if (drawParams) {
776                                         draw_option = drawParams(tf ? &tf[actualFace] : NULL, (mcol != NULL), mf[actualFace].mat_nr);
777                                 }
778                                 else {
779                                         if (index_mf_to_mpoly) {
780                                                 orig = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace);
781                                                 if (orig == ORIGINDEX_NONE) {
782                                                         /* XXX, this is not really correct
783                                                          * it will draw the previous faces context for this one when we don't know its settings.
784                                                          * but better then skipping it altogether. - campbell */
785                                                         draw_option = DM_DRAW_OPTION_NORMAL;
786                                                 }
787                                                 else if (drawParamsMapped) {
788                                                         draw_option = drawParamsMapped(userData, orig);
789                                                 }
790                                         }
791                                         else if (drawParamsMapped) {
792                                                 draw_option = drawParamsMapped(userData, actualFace);
793                                         }
794                                 }
795
796                                 /* flush buffer if current triangle isn't drawable or it's last triangle */
797                                 flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == tottri - 1);
798
799                                 if (!flush && compareDrawOptions) {
800                                         /* also compare draw options and flush buffer if they're different
801                                          * need for face selection highlight in edit mode */
802                                         flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
803                                 }
804
805                                 if (flush) {
806                                         int first = startFace * 3;
807                                         /* Add one to the length if we're drawing at the end of the array */
808                                         int count = (i - startFace + (draw_option != DM_DRAW_OPTION_SKIP ? 1 : 0)) * 3;
809
810                                         if (count) {
811                                                 if (mcol && draw_option != DM_DRAW_OPTION_NO_MCOL)
812                                                         GPU_color_switch(1);
813                                                 else
814                                                         GPU_color_switch(0);
815
816                                                 glDrawArrays(GL_TRIANGLES, first, count);
817                                         }
818
819                                         startFace = i + 1;
820                                 }
821                         }
822                 }
823
824                 GPU_buffer_unbind();
825                 glShadeModel(GL_FLAT);
826         }
827 }
828
829 static void cdDM_drawFacesTex(DerivedMesh *dm,
830                               DMSetDrawOptionsTex setDrawOptions,
831                               DMCompareDrawOptions compareDrawOptions,
832                               void *userData)
833 {
834         cdDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData);
835 }
836
837 static void cdDM_drawMappedFaces(DerivedMesh *dm,
838                                  DMSetDrawOptions setDrawOptions,
839                                  DMSetMaterial setMaterial,
840                                  DMCompareDrawOptions compareDrawOptions,
841                                  void *userData, DMDrawFlag flag)
842 {
843         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
844         MVert *mv = cddm->mvert;
845         MFace *mf = cddm->mface;
846         MCol *mcol;
847         float *nors = DM_get_tessface_data_layer(dm, CD_NORMAL);
848         int colType, useColors = flag & DM_DRAW_USE_COLORS;
849         int i, orig;
850
851
852         /* double lookup */
853         const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
854         const int *index_mp_to_orig  = dm->getPolyDataArray(dm, CD_ORIGINDEX);
855         if (index_mf_to_mpoly == NULL) {
856                 index_mp_to_orig = NULL;
857         }
858
859
860         colType = CD_ID_MCOL;
861         mcol = DM_get_tessface_data_layer(dm, colType);
862         if (!mcol) {
863                 colType = CD_PREVIEW_MCOL;
864                 mcol = DM_get_tessface_data_layer(dm, colType);
865         }
866         if (!mcol) {
867                 colType = CD_MCOL;
868                 mcol = DM_get_tessface_data_layer(dm, colType);
869         }
870
871         cdDM_update_normals_from_pbvh(dm);
872
873         /* back-buffer always uses legacy since VBO's would need the
874          * color array temporarily overwritten for drawing, then reset. */
875         if (GPU_buffer_legacy(dm) || G.f & G_BACKBUFSEL) {
876                 DEBUG_VBO("Using legacy code. cdDM_drawMappedFaces\n");
877                 for (i = 0; i < dm->numTessFaceData; i++, mf++) {
878                         int drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : (mf->flag & ME_SMOOTH);
879                         DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
880
881                         orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i) : i;
882                         
883                         if (orig == ORIGINDEX_NONE)
884                                 draw_option = setMaterial(mf->mat_nr + 1, NULL);
885                         else if (setDrawOptions != NULL)
886                                 draw_option = setDrawOptions(userData, orig);
887
888                         if (draw_option != DM_DRAW_OPTION_SKIP) {
889                                 unsigned char *cp = NULL;
890
891                                 if (useColors && mcol)
892                                         cp = (unsigned char *)&mcol[i * 4];
893
894                                 /* no need to set shading mode to flat because
895                                  *  normals are already used to change shading */
896                                 glShadeModel(GL_SMOOTH);
897                                 glBegin(mf->v4 ? GL_QUADS : GL_TRIANGLES);
898
899                                 if (!drawSmooth) {
900                                         if (nors) {
901                                                 glNormal3fv(nors);
902                                         }
903                                         else {
904                                                 float nor[3];
905                                                 if (mf->v4) {
906                                                         normal_quad_v3(nor, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
907                                                 }
908                                                 else {
909                                                         normal_tri_v3(nor, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
910                                                 }
911                                                 glNormal3fv(nor);
912                                         }
913
914                                         if (cp) glColor3ub(cp[3], cp[2], cp[1]);
915                                         glVertex3fv(mv[mf->v1].co);
916                                         if (cp) glColor3ub(cp[7], cp[6], cp[5]);
917                                         glVertex3fv(mv[mf->v2].co);
918                                         if (cp) glColor3ub(cp[11], cp[10], cp[9]);
919                                         glVertex3fv(mv[mf->v3].co);
920                                         if (mf->v4) {
921                                                 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
922                                                 glVertex3fv(mv[mf->v4].co);
923                                         }
924                                 }
925                                 else {
926                                         if (cp) glColor3ub(cp[3], cp[2], cp[1]);
927                                         glNormal3sv(mv[mf->v1].no);
928                                         glVertex3fv(mv[mf->v1].co);
929                                         if (cp) glColor3ub(cp[7], cp[6], cp[5]);
930                                         glNormal3sv(mv[mf->v2].no);
931                                         glVertex3fv(mv[mf->v2].co);
932                                         if (cp) glColor3ub(cp[11], cp[10], cp[9]);
933                                         glNormal3sv(mv[mf->v3].no);
934                                         glVertex3fv(mv[mf->v3].co);
935                                         if (mf->v4) {
936                                                 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
937                                                 glNormal3sv(mv[mf->v4].no);
938                                                 glVertex3fv(mv[mf->v4].co);
939                                         }
940                                 }
941
942                                 glEnd();
943                         }
944                         
945                         if (nors) nors += 3;
946                 }
947         }
948         else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
949                 int prevstart = 0;
950                 GPU_vertex_setup(dm);
951                 GPU_normal_setup(dm);
952                 if (useColors && mcol) {
953                         GPU_color_setup(dm, colType);
954                 }
955                 if (!GPU_buffer_legacy(dm)) {
956                         int tottri = dm->drawObject->tot_triangle_point / 3;
957                         glShadeModel(GL_SMOOTH);
958                         
959                         if (tottri == 0) {
960                                 /* avoid buffer problems in following code */
961                         }
962                         if (setDrawOptions == NULL) {
963                                 /* just draw the entire face array */
964                                 glDrawArrays(GL_TRIANGLES, 0, (tottri) * 3);
965                         }
966                         else {
967                                 /* we need to check if the next material changes */
968                                 int next_actualFace = dm->drawObject->triangle_to_mface[0];
969                                 
970                                 for (i = 0; i < tottri; i++) {
971                                         //int actualFace = dm->drawObject->triangle_to_mface[i];
972                                         int actualFace = next_actualFace;
973                                         MFace *mface = mf + actualFace;
974                                         /*int drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : (mface->flag & ME_SMOOTH);*/ /* UNUSED */
975                                         DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
976                                         int flush = 0;
977
978                                         if (i != tottri - 1)
979                                                 next_actualFace = dm->drawObject->triangle_to_mface[i + 1];
980
981                                         orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace) : actualFace;
982
983                                         if (orig == ORIGINDEX_NONE)
984                                                 draw_option = setMaterial(mface->mat_nr + 1, NULL);
985                                         else if (setDrawOptions != NULL)
986                                                 draw_option = setDrawOptions(userData, orig);
987         
988                                         /* Goal is to draw as long of a contiguous triangle
989                                          * array as possible, so draw when we hit either an
990                                          * invisible triangle or at the end of the array */
991
992                                         /* flush buffer if current triangle isn't drawable or it's last triangle... */
993                                         flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == tottri - 1);
994
995                                         /* ... or when material setting is dissferent  */
996                                         flush |= mf[actualFace].mat_nr != mf[next_actualFace].mat_nr;
997
998                                         if (!flush && compareDrawOptions) {
999                                                 flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
1000                                         }
1001
1002                                         if (flush) {
1003                                                 int first = prevstart * 3;
1004                                                 /* Add one to the length if we're drawing at the end of the array */
1005                                                 int count = (i - prevstart + (draw_option != DM_DRAW_OPTION_SKIP ? 1 : 0)) * 3;
1006
1007                                                 if (count)
1008                                                         glDrawArrays(GL_TRIANGLES, first, count);
1009
1010                                                 prevstart = i + 1;
1011                                         }
1012                                 }
1013                         }
1014
1015                         glShadeModel(GL_FLAT);
1016                 }
1017                 GPU_buffer_unbind();
1018         }
1019 }
1020
1021 static void cdDM_drawMappedFacesTex(DerivedMesh *dm,
1022                                     DMSetDrawOptions setDrawOptions,
1023                                     DMCompareDrawOptions compareDrawOptions,
1024                                     void *userData)
1025 {
1026         cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData);
1027 }
1028
1029 static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, MVert *mvert, int a, int index, int vert, int smoothnormal)
1030 {
1031         int b;
1032
1033         /* orco texture coordinates */
1034         if (attribs->totorco) {
1035                 if (attribs->orco.gl_texco)
1036                         glTexCoord3fv(attribs->orco.array[index]);
1037                 else
1038                         glVertexAttrib3fvARB(attribs->orco.gl_index, attribs->orco.array[index]);
1039         }
1040
1041         /* uv texture coordinates */
1042         for (b = 0; b < attribs->tottface; b++) {
1043                 MTFace *tf = &attribs->tface[b].array[a];
1044
1045                 if (attribs->tface[b].gl_texco)
1046                         glTexCoord2fv(tf->uv[vert]);
1047                 else
1048                         glVertexAttrib2fvARB(attribs->tface[b].gl_index, tf->uv[vert]);
1049         }
1050
1051         /* vertex colors */
1052         for (b = 0; b < attribs->totmcol; b++) {
1053                 MCol *cp = &attribs->mcol[b].array[a * 4 + vert];
1054                 GLubyte col[4];
1055                 col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1056                 glVertexAttrib4ubvARB(attribs->mcol[b].gl_index, col);
1057         }
1058
1059         /* tangent for normal mapping */
1060         if (attribs->tottang) {
1061                 float *tang = attribs->tang.array[a * 4 + vert];
1062                 glVertexAttrib4fvARB(attribs->tang.gl_index, tang);
1063         }
1064
1065         /* vertex normal */
1066         if (smoothnormal)
1067                 glNormal3sv(mvert[index].no);
1068         
1069         /* vertex coordinate */
1070         glVertex3fv(mvert[index].co);
1071 }
1072
1073 static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
1074                                      DMSetMaterial setMaterial,
1075                                      DMSetDrawOptions setDrawOptions,
1076                                      void *userData)
1077 {
1078         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
1079         GPUVertexAttribs gattribs;
1080         DMVertexAttribs attribs;
1081         MVert *mvert = cddm->mvert;
1082         MFace *mface = cddm->mface;
1083         /* MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */
1084         float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL);
1085         int a, b, do_draw, matnr, new_matnr;
1086         int orig;
1087
1088         /* double lookup */
1089         const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1090         const int *index_mp_to_orig  = dm->getPolyDataArray(dm, CD_ORIGINDEX);
1091         if (index_mf_to_mpoly == NULL) {
1092                 index_mp_to_orig = NULL;
1093         }
1094
1095         cdDM_update_normals_from_pbvh(dm);
1096
1097         matnr = -1;
1098         do_draw = FALSE;
1099
1100         glShadeModel(GL_SMOOTH);
1101
1102         if (GPU_buffer_legacy(dm) || setDrawOptions != NULL) {
1103                 DEBUG_VBO("Using legacy code. cdDM_drawMappedFacesGLSL\n");
1104                 memset(&attribs, 0, sizeof(attribs));
1105
1106                 glBegin(GL_QUADS);
1107
1108                 for (a = 0; a < dm->numTessFaceData; a++, mface++) {
1109                         const int smoothnormal = (mface->flag & ME_SMOOTH);
1110                         new_matnr = mface->mat_nr + 1;
1111
1112                         if (new_matnr != matnr) {
1113                                 glEnd();
1114
1115                                 do_draw = setMaterial(matnr = new_matnr, &gattribs);
1116                                 if (do_draw)
1117                                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1118
1119                                 glBegin(GL_QUADS);
1120                         }
1121
1122                         if (!do_draw) {
1123                                 continue;
1124                         }
1125                         else if (setDrawOptions) {
1126                                 orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a) : a;
1127
1128                                 if (orig == ORIGINDEX_NONE) {
1129                                         /* since the material is set by setMaterial(), faces with no
1130                                          * origin can be assumed to be generated by a modifier */ 
1131                                         
1132                                         /* continue */
1133                                 }
1134                                 else if (setDrawOptions(userData, orig) == DM_DRAW_OPTION_SKIP)
1135                                         continue;
1136                         }
1137
1138                         if (!smoothnormal) {
1139                                 if (nors) {
1140                                         glNormal3fv(nors[a]);
1141                                 }
1142                                 else {
1143                                         /* TODO ideally a normal layer should always be available */
1144                                         float nor[3];
1145                                         if (mface->v4) {
1146                                                 normal_quad_v3(nor, mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co);
1147                                         }
1148                                         else {
1149                                                 normal_tri_v3(nor, mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co);
1150                                         }
1151                                         glNormal3fv(nor);
1152                                 }
1153                         }
1154
1155                         cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v1, 0, smoothnormal);
1156                         cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v2, 1, smoothnormal);
1157                         cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal);
1158
1159                         if (mface->v4)
1160                                 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v4, 3, smoothnormal);
1161                         else
1162                                 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal);
1163                 }
1164                 glEnd();
1165         }
1166         else {
1167                 GPUBuffer *buffer = NULL;
1168                 char *varray = NULL;
1169                 int numdata = 0, elementsize = 0, offset;
1170                 int start = 0, numfaces = 0 /* , prevdraw = 0 */ /* UNUSED */, curface = 0;
1171                 int i;
1172
1173                 MFace *mf = mface;
1174                 GPUAttrib datatypes[GPU_MAX_ATTRIB]; /* TODO, messing up when switching materials many times - [#21056]*/
1175                 memset(&attribs, 0, sizeof(attribs));
1176
1177                 GPU_vertex_setup(dm);
1178                 GPU_normal_setup(dm);
1179
1180                 if (!GPU_buffer_legacy(dm)) {
1181                         for (i = 0; i < dm->drawObject->tot_triangle_point / 3; i++) {
1182
1183                                 a = dm->drawObject->triangle_to_mface[i];
1184
1185                                 mface = mf + a;
1186                                 new_matnr = mface->mat_nr + 1;
1187
1188                                 if (new_matnr != matnr) {
1189                                         numfaces = curface - start;
1190                                         if (numfaces > 0) {
1191
1192                                                 if (do_draw) {
1193
1194                                                         if (numdata != 0) {
1195
1196                                                                 GPU_buffer_unlock(buffer);
1197
1198                                                                 GPU_interleaved_attrib_setup(buffer, datatypes, numdata);
1199                                                         }
1200
1201                                                         glDrawArrays(GL_TRIANGLES, start * 3, numfaces * 3);
1202
1203                                                         if (numdata != 0) {
1204
1205                                                                 GPU_buffer_free(buffer);
1206
1207                                                                 buffer = NULL;
1208                                                         }
1209
1210                                                 }
1211                                         }
1212                                         numdata = 0;
1213                                         start = curface;
1214                                         /* prevdraw = do_draw; */ /* UNUSED */
1215                                         do_draw = setMaterial(matnr = new_matnr, &gattribs);
1216                                         if (do_draw) {
1217                                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1218
1219                                                 if (attribs.totorco) {
1220                                                         datatypes[numdata].index = attribs.orco.gl_index;
1221                                                         datatypes[numdata].size = 3;
1222                                                         datatypes[numdata].type = GL_FLOAT;
1223                                                         numdata++;
1224                                                 }
1225                                                 for (b = 0; b < attribs.tottface; b++) {
1226                                                         datatypes[numdata].index = attribs.tface[b].gl_index;
1227                                                         datatypes[numdata].size = 2;
1228                                                         datatypes[numdata].type = GL_FLOAT;
1229                                                         numdata++;
1230                                                 }
1231                                                 for (b = 0; b < attribs.totmcol; b++) {
1232                                                         datatypes[numdata].index = attribs.mcol[b].gl_index;
1233                                                         datatypes[numdata].size = 4;
1234                                                         datatypes[numdata].type = GL_UNSIGNED_BYTE;
1235                                                         numdata++;
1236                                                 }
1237                                                 if (attribs.tottang) {
1238                                                         datatypes[numdata].index = attribs.tang.gl_index;
1239                                                         datatypes[numdata].size = 4;
1240                                                         datatypes[numdata].type = GL_FLOAT;
1241                                                         numdata++;
1242                                                 }
1243                                                 if (numdata != 0) {
1244                                                         elementsize = GPU_attrib_element_size(datatypes, numdata);
1245                                                         buffer = GPU_buffer_alloc(elementsize * dm->drawObject->tot_triangle_point);
1246                                                         if (buffer == NULL) {
1247                                                                 GPU_buffer_unbind();
1248                                                                 dm->drawObject->legacy = 1;
1249                                                                 return;
1250                                                         }
1251                                                         varray = GPU_buffer_lock_stream(buffer);
1252                                                         if (varray == NULL) {
1253                                                                 GPU_buffer_unbind();
1254                                                                 GPU_buffer_free(buffer);
1255                                                                 dm->drawObject->legacy = 1;
1256                                                                 return;
1257                                                         }
1258                                                 }
1259                                                 else {
1260                                                         /* if the buffer was set, don't use it again.
1261                                                          * prevdraw was assumed true but didnt run so set to false - [#21036] */
1262                                                         /* prevdraw = 0; */ /* UNUSED */
1263                                                         buffer = NULL;
1264                                                 }
1265                                         }
1266                                 }
1267
1268                                 if (do_draw && numdata != 0) {
1269                                         offset = 0;
1270                                         if (attribs.totorco) {
1271                                                 copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[mface->v1]);
1272                                                 copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[mface->v2]);
1273                                                 copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[mface->v3]);
1274                                                 offset += sizeof(float) * 3;
1275                                         }
1276                                         for (b = 0; b < attribs.tottface; b++) {
1277                                                 MTFace *tf = &attribs.tface[b].array[a];
1278                                                 copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[0]);
1279                                                 copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[1]);
1280
1281                                                 copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[2]);
1282                                                 offset += sizeof(float) * 2;
1283                                         }
1284                                         for (b = 0; b < attribs.totmcol; b++) {
1285                                                 MCol *cp = &attribs.mcol[b].array[a * 4 + 0];
1286                                                 GLubyte col[4];
1287                                                 col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1288                                                 copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset], (char *)col);
1289                                                 cp = &attribs.mcol[b].array[a * 4 + 1];
1290                                                 col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1291                                                 copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize], (char *)col);
1292                                                 cp = &attribs.mcol[b].array[a * 4 + 2];
1293                                                 col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1294                                                 copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], (char *)col);
1295                                                 offset += sizeof(unsigned char) * 4;
1296                                         }
1297                                         if (attribs.tottang) {
1298                                                 float *tang = attribs.tang.array[a * 4 + 0];
1299                                                 copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang);
1300                                                 tang = attribs.tang.array[a * 4 + 1];
1301                                                 copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize], tang);
1302                                                 tang = attribs.tang.array[a * 4 + 2];
1303                                                 copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tang);
1304                                                 offset += sizeof(float) * 4;
1305                                         }
1306                                         (void)offset;
1307                                 }
1308                                 curface++;
1309                                 if (mface->v4) {
1310                                         if (do_draw && numdata != 0) {
1311                                                 offset = 0;
1312                                                 if (attribs.totorco) {
1313                                                         copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[mface->v3]);
1314                                                         copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[mface->v4]);
1315                                                         copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[mface->v1]);
1316                                                         offset += sizeof(float) * 3;
1317                                                 }
1318                                                 for (b = 0; b < attribs.tottface; b++) {
1319                                                         MTFace *tf = &attribs.tface[b].array[a];
1320                                                         copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[2]);
1321                                                         copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[3]);
1322                                                         copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[0]);
1323                                                         offset += sizeof(float) * 2;
1324                                                 }
1325                                                 for (b = 0; b < attribs.totmcol; b++) {
1326                                                         MCol *cp = &attribs.mcol[b].array[a * 4 + 2];
1327                                                         GLubyte col[4];
1328                                                         col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1329                                                         copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset], (char *)col);
1330                                                         cp = &attribs.mcol[b].array[a * 4 + 3];
1331                                                         col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1332                                                         copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize], (char *)col);
1333                                                         cp = &attribs.mcol[b].array[a * 4 + 0];
1334                                                         col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1335                                                         copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], (char *)col);
1336                                                         offset += sizeof(unsigned char) * 4;
1337                                                 }
1338                                                 if (attribs.tottang) {
1339                                                         float *tang = attribs.tang.array[a * 4 + 2];
1340                                                         copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang);
1341                                                         tang = attribs.tang.array[a * 4 + 3];
1342                                                         copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize], tang);
1343                                                         tang = attribs.tang.array[a * 4 + 0];
1344                                                         copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tang);
1345                                                         offset += sizeof(float) * 4;
1346                                                 }
1347                                                 (void)offset;
1348                                         }
1349                                         curface++;
1350                                         i++;
1351                                 }
1352                         }
1353                         numfaces = curface - start;
1354                         if (numfaces > 0) {
1355                                 if (do_draw) {
1356                                         if (numdata != 0) {
1357                                                 GPU_buffer_unlock(buffer);
1358                                                 GPU_interleaved_attrib_setup(buffer, datatypes, numdata);
1359                                         }
1360                                         glDrawArrays(GL_TRIANGLES, start * 3, (curface - start) * 3);
1361                                 }
1362                         }
1363                         GPU_buffer_unbind();
1364                 }
1365                 GPU_buffer_free(buffer);
1366         }
1367
1368         glShadeModel(GL_FLAT);
1369 }
1370
1371 static void cdDM_drawFacesGLSL(DerivedMesh *dm, DMSetMaterial setMaterial)
1372 {
1373         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1374 }
1375
1376 static void cdDM_drawMappedFacesMat(DerivedMesh *dm,
1377                                     void (*setMaterial)(void *userData, int, void *attribs),
1378                                     int (*setFace)(void *userData, int index), void *userData)
1379 {
1380         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
1381         GPUVertexAttribs gattribs;
1382         DMVertexAttribs attribs;
1383         MVert *mvert = cddm->mvert;
1384         MFace *mf = cddm->mface;
1385         float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL);
1386         int a, matnr, new_matnr;
1387         int orig;
1388
1389         /* double lookup */
1390         const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1391         const int *index_mp_to_orig  = dm->getPolyDataArray(dm, CD_ORIGINDEX);
1392         if (index_mf_to_mpoly == NULL) {
1393                 index_mp_to_orig = NULL;
1394         }
1395
1396         cdDM_update_normals_from_pbvh(dm);
1397
1398         matnr = -1;
1399
1400         glShadeModel(GL_SMOOTH);
1401
1402         memset(&attribs, 0, sizeof(attribs));
1403
1404         glBegin(GL_QUADS);
1405
1406         for (a = 0; a < dm->numTessFaceData; a++, mf++) {
1407                 const int smoothnormal = (mf->flag & ME_SMOOTH);
1408
1409                 /* material */
1410                 new_matnr = mf->mat_nr + 1;
1411
1412                 if (new_matnr != matnr) {
1413                         glEnd();
1414
1415                         setMaterial(userData, matnr = new_matnr, &gattribs);
1416                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1417
1418                         glBegin(GL_QUADS);
1419                 }
1420
1421                 /* skipping faces */
1422                 if (setFace) {
1423                         orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a) : a;
1424
1425                         if (orig != ORIGINDEX_NONE && !setFace(userData, orig))
1426                                 continue;
1427                 }
1428
1429                 /* smooth normal */
1430                 if (!smoothnormal) {
1431                         if (nors) {
1432                                 glNormal3fv(nors[a]);
1433                         }
1434                         else {
1435                                 /* TODO ideally a normal layer should always be available */
1436                                 float nor[3];
1437
1438                                 if (mf->v4)
1439                                         normal_quad_v3(nor, mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co);
1440                                 else
1441                                         normal_tri_v3(nor, mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co);
1442
1443                                 glNormal3fv(nor);
1444                         }
1445                 }
1446
1447                 /* vertices */
1448                 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v1, 0, smoothnormal);
1449                 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v2, 1, smoothnormal);
1450                 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal);
1451
1452                 if (mf->v4)
1453                         cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v4, 3, smoothnormal);
1454                 else
1455                         cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal);
1456         }
1457         glEnd();
1458
1459         glShadeModel(GL_FLAT);
1460 }
1461
1462 static void cdDM_drawMappedEdges(DerivedMesh *dm, DMSetDrawOptions setDrawOptions, void *userData)
1463 {
1464         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
1465         MVert *vert = cddm->mvert;
1466         MEdge *edge = cddm->medge;
1467         int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1468
1469         glBegin(GL_LINES);
1470         for (i = 0; i < dm->numEdgeData; i++, edge++) {
1471                 if (index) {
1472                         orig = *index++;
1473                         if (setDrawOptions && orig == ORIGINDEX_NONE) continue;
1474                 }
1475                 else
1476                         orig = i;
1477
1478                 if (!setDrawOptions || (setDrawOptions(userData, orig) != DM_DRAW_OPTION_SKIP)) {
1479                         glVertex3fv(vert[edge->v1].co);
1480                         glVertex3fv(vert[edge->v2].co);
1481                 }
1482         }
1483         glEnd();
1484 }
1485
1486 static void cdDM_foreachMappedVert(
1487         DerivedMesh *dm,
1488         void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]),
1489         void *userData)
1490 {
1491         MVert *mv = CDDM_get_verts(dm);
1492         int i, orig, *index = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
1493
1494         for (i = 0; i < dm->numVertData; i++, mv++) {
1495                 if (index) {
1496                         orig = *index++;
1497                         if (orig == ORIGINDEX_NONE) continue;
1498                         func(userData, orig, mv->co, NULL, mv->no);
1499                 }
1500                 else
1501                         func(userData, i, mv->co, NULL, mv->no);
1502         }
1503 }
1504
1505 static void cdDM_foreachMappedEdge(
1506         DerivedMesh *dm,
1507         void (*func)(void *userData, int index, const float v0co[3], const float v1co[3]),
1508         void *userData)
1509 {
1510         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
1511         MVert *mv = cddm->mvert;
1512         MEdge *med = cddm->medge;
1513         int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1514
1515         for (i = 0; i < dm->numEdgeData; i++, med++) {
1516                 if (index) {
1517                         orig = *index++;
1518                         if (orig == ORIGINDEX_NONE) continue;
1519                         func(userData, orig, mv[med->v1].co, mv[med->v2].co);
1520                 }
1521                 else
1522                         func(userData, i, mv[med->v1].co, mv[med->v2].co);
1523         }
1524 }
1525
1526 static void cdDM_foreachMappedFaceCenter(
1527         DerivedMesh *dm,
1528         void (*func)(void *userData, int index, const float cent[3], const float no[3]),
1529         void *userData)
1530 {
1531         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
1532         MVert *mvert = cddm->mvert;
1533         MPoly *mp;
1534         MLoop *ml;
1535         int i, j, orig, *index;
1536
1537         index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
1538         mp = cddm->mpoly;
1539         for (i = 0; i < dm->numPolyData; i++, mp++) {
1540                 float cent[3];
1541                 float no[3];
1542
1543                 if (index) {
1544                         orig = *index++;
1545                         if (orig == ORIGINDEX_NONE) continue;
1546                 }
1547                 else
1548                         orig = i;
1549                 
1550                 ml = &cddm->mloop[mp->loopstart];
1551                 cent[0] = cent[1] = cent[2] = 0.0f;
1552                 for (j = 0; j < mp->totloop; j++, ml++) {
1553                         add_v3_v3v3(cent, cent, mvert[ml->v].co);
1554                 }
1555                 mul_v3_fl(cent, 1.0f / (float)j);
1556
1557                 ml = &cddm->mloop[mp->loopstart];
1558                 if (j > 3) {
1559                         normal_quad_v3(no,
1560                                        mvert[(ml + 0)->v].co,
1561                                        mvert[(ml + 1)->v].co,
1562                                        mvert[(ml + 2)->v].co,
1563                                        mvert[(ml + 3)->v].co);
1564                 }
1565                 else {
1566                         normal_tri_v3(no,
1567                                       mvert[(ml + 0)->v].co,
1568                                       mvert[(ml + 1)->v].co,
1569                                       mvert[(ml + 2)->v].co);
1570                 }
1571
1572                 func(userData, orig, cent, no);
1573         }
1574
1575 }
1576
1577 void CDDM_recalc_tessellation_ex(DerivedMesh *dm, const int do_face_nor_cpy)
1578 {
1579         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
1580
1581         dm->numTessFaceData = BKE_mesh_recalc_tessellation(&dm->faceData, &dm->loopData, &dm->polyData,
1582                                                            cddm->mvert,
1583                                                            dm->numTessFaceData, dm->numLoopData, dm->numPolyData,
1584                                                            do_face_nor_cpy);
1585
1586         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1587
1588         /* Tessellation recreated faceData, and the active layer indices need to get re-propagated
1589          * from loops and polys to faces */
1590         CustomData_bmesh_update_active_layers(&dm->faceData, &dm->polyData, &dm->loopData);
1591 }
1592
1593 void CDDM_recalc_tessellation(DerivedMesh *dm)
1594 {
1595         CDDM_recalc_tessellation_ex(dm, TRUE);
1596 }
1597
1598 static void cdDM_free_internal(CDDerivedMesh *cddm)
1599 {
1600         if (cddm->pmap) MEM_freeN(cddm->pmap);
1601         if (cddm->pmap_mem) MEM_freeN(cddm->pmap_mem);
1602 }
1603
1604 static void cdDM_release(DerivedMesh *dm)
1605 {
1606         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
1607
1608         if (DM_release(dm)) {
1609                 cdDM_free_internal(cddm);
1610                 MEM_freeN(cddm);
1611         }
1612 }
1613
1614 int CDDM_Check(DerivedMesh *dm)
1615 {
1616         return dm && dm->getMinMax == cdDM_getMinMax;
1617 }
1618
1619 /**************** CDDM interface functions ****************/
1620 static CDDerivedMesh *cdDM_create(const char *desc)
1621 {
1622         CDDerivedMesh *cddm;
1623         DerivedMesh *dm;
1624
1625         cddm = MEM_callocN(sizeof(*cddm), desc);
1626         dm = &cddm->dm;
1627
1628         dm->getMinMax = cdDM_getMinMax;
1629
1630         dm->getNumVerts = cdDM_getNumVerts;
1631         dm->getNumEdges = cdDM_getNumEdges;
1632         dm->getNumTessFaces = cdDM_getNumTessFaces;
1633         dm->getNumLoops = cdDM_getNumLoops;
1634         dm->getNumPolys = cdDM_getNumPolys;
1635
1636         dm->getVert = cdDM_getVert;
1637         dm->getEdge = cdDM_getEdge;
1638         dm->getTessFace = cdDM_getTessFace;
1639
1640         dm->copyVertArray = cdDM_copyVertArray;
1641         dm->copyEdgeArray = cdDM_copyEdgeArray;
1642         dm->copyTessFaceArray = cdDM_copyTessFaceArray;
1643         dm->copyLoopArray = cdDM_copyLoopArray;
1644         dm->copyPolyArray = cdDM_copyPolyArray;
1645
1646         dm->getVertData = DM_get_vert_data;
1647         dm->getEdgeData = DM_get_edge_data;
1648         dm->getTessFaceData = DM_get_tessface_data;
1649         dm->getVertDataArray = DM_get_vert_data_layer;
1650         dm->getEdgeDataArray = DM_get_edge_data_layer;
1651         dm->getTessFaceDataArray = DM_get_tessface_data_layer;
1652
1653         dm->calcNormals = CDDM_calc_normals_mapping;
1654         dm->recalcTessellation = CDDM_recalc_tessellation;
1655
1656         dm->getVertCos = cdDM_getVertCos;
1657         dm->getVertCo = cdDM_getVertCo;
1658         dm->getVertNo = cdDM_getVertNo;
1659
1660         dm->getPBVH = cdDM_getPBVH;
1661         dm->getPolyMap = cdDM_getPolyMap;
1662
1663         dm->drawVerts = cdDM_drawVerts;
1664
1665         dm->drawUVEdges = cdDM_drawUVEdges;
1666         dm->drawEdges = cdDM_drawEdges;
1667         dm->drawLooseEdges = cdDM_drawLooseEdges;
1668         dm->drawMappedEdges = cdDM_drawMappedEdges;
1669
1670         dm->drawFacesSolid = cdDM_drawFacesSolid;
1671         dm->drawFacesTex = cdDM_drawFacesTex;
1672         dm->drawFacesGLSL = cdDM_drawFacesGLSL;
1673         dm->drawMappedFaces = cdDM_drawMappedFaces;
1674         dm->drawMappedFacesTex = cdDM_drawMappedFacesTex;
1675         dm->drawMappedFacesGLSL = cdDM_drawMappedFacesGLSL;
1676         dm->drawMappedFacesMat = cdDM_drawMappedFacesMat;
1677
1678         dm->foreachMappedVert = cdDM_foreachMappedVert;
1679         dm->foreachMappedEdge = cdDM_foreachMappedEdge;
1680         dm->foreachMappedFaceCenter = cdDM_foreachMappedFaceCenter;
1681
1682         dm->release = cdDM_release;
1683
1684         return cddm;
1685 }
1686
1687 DerivedMesh *CDDM_new(int numVerts, int numEdges, int numTessFaces, int numLoops, int numPolys)
1688 {
1689         CDDerivedMesh *cddm = cdDM_create("CDDM_new dm");
1690         DerivedMesh *dm = &cddm->dm;
1691
1692         DM_init(dm, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces, numLoops, numPolys);
1693
1694         CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
1695         CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
1696         CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numTessFaces);
1697         CustomData_add_layer(&dm->polyData, CD_ORIGINDEX, CD_CALLOC, NULL, numPolys);
1698
1699         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
1700         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
1701         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numTessFaces);
1702         CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL, numLoops);
1703         CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL, numPolys);
1704
1705         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1706         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1707         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1708         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
1709         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
1710
1711         return dm;
1712 }
1713
1714 DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob))
1715 {
1716         CDDerivedMesh *cddm = cdDM_create("CDDM_from_mesh dm");
1717         DerivedMesh *dm = &cddm->dm;
1718         CustomDataMask mask = CD_MASK_MESH & (~CD_MASK_MDISPS);
1719         int alloctype;
1720
1721         /* this does a referenced copy, with an exception for fluidsim */
1722
1723         DM_init(dm, DM_TYPE_CDDM, mesh->totvert, mesh->totedge, mesh->totface,
1724                 mesh->totloop, mesh->totpoly);
1725
1726         dm->deformedOnly = 1;
1727
1728         alloctype = CD_REFERENCE;
1729
1730         CustomData_merge(&mesh->vdata, &dm->vertData, mask, alloctype,
1731                          mesh->totvert);
1732         CustomData_merge(&mesh->edata, &dm->edgeData, mask, alloctype,
1733                          mesh->totedge);
1734         CustomData_merge(&mesh->fdata, &dm->faceData, mask | CD_MASK_ORIGINDEX, alloctype,
1735                          mesh->totface);
1736         CustomData_merge(&mesh->ldata, &dm->loopData, mask, alloctype,
1737                          mesh->totloop);
1738         CustomData_merge(&mesh->pdata, &dm->polyData, mask, alloctype,
1739                          mesh->totpoly);
1740
1741         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1742         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1743         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
1744         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
1745         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1746
1747         /* commented since even when CD_ORIGINDEX was first added this line fails
1748          * on the default cube, (after editmode toggle too) - campbell */
1749 #if 0
1750         BLI_assert(CustomData_has_layer(&cddm->dm.faceData, CD_ORIGINDEX));
1751 #endif
1752
1753         return dm;
1754 }
1755
1756 DerivedMesh *CDDM_from_curve(Object *ob)
1757 {
1758         return CDDM_from_curve_displist(ob, &ob->disp, NULL);
1759 }
1760
1761 DerivedMesh *CDDM_from_curve_orco(struct Scene *scene, Object *ob)
1762 {
1763         int *orco_index_ptr = NULL;
1764         int (*orco_index)[4] = NULL;
1765         float (*orco)[3] = NULL;
1766         DerivedMesh *dm = CDDM_from_curve_displist(ob, &ob->disp, &orco_index_ptr);
1767
1768         if (orco_index_ptr) {
1769                 orco = (float (*)[3])BKE_curve_make_orco(scene, ob);
1770         }
1771
1772         if (orco && orco_index_ptr) {
1773                 const char *uvname = "Orco";
1774
1775                 int totpoly = dm->getNumPolys(dm);
1776
1777                 MPoly *mpolys = dm->getPolyArray(dm);
1778                 MLoop *mloops = dm->getLoopArray(dm);
1779
1780                 MLoopUV *mloopuvs;
1781
1782                 CustomData_add_layer_named(&dm->polyData, CD_MTEXPOLY, CD_DEFAULT, NULL, dm->numPolyData, uvname);
1783                 mloopuvs = CustomData_add_layer_named(&dm->loopData, CD_MLOOPUV,  CD_DEFAULT, NULL, dm->numLoopData, uvname);
1784
1785                 BKE_mesh_nurbs_to_mdata_orco(mpolys, totpoly,
1786                                              mloops, mloopuvs,
1787                                              orco, orco_index);
1788         }
1789
1790         if (orco_index) {
1791                 MEM_freeN(orco_index);
1792         }
1793         if (orco) {
1794                 MEM_freeN(orco);
1795         }
1796
1797         return dm;
1798 }
1799
1800 DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase, int **orco_index_ptr)
1801 {
1802         DerivedMesh *dm;
1803         CDDerivedMesh *cddm;
1804         MVert *allvert;
1805         MEdge *alledge;
1806         MLoop *allloop;
1807         MPoly *allpoly;
1808         int totvert, totedge, totloop, totpoly;
1809
1810         if (BKE_mesh_nurbs_displist_to_mdata(ob, dispbase, &allvert, &totvert, &alledge,
1811                                              &totedge, &allloop, &allpoly, &totloop, &totpoly, orco_index_ptr) != 0)
1812         {
1813                 /* Error initializing mdata. This often happens when curve is empty */
1814                 return CDDM_new(0, 0, 0, 0, 0);
1815         }
1816
1817         dm = CDDM_new(totvert, totedge, 0, totloop, totpoly);
1818         dm->deformedOnly = 1;
1819
1820         cddm = (CDDerivedMesh *)dm;
1821
1822         memcpy(cddm->mvert, allvert, totvert * sizeof(MVert));
1823         memcpy(cddm->medge, alledge, totedge * sizeof(MEdge));
1824         memcpy(cddm->mloop, allloop, totloop * sizeof(MLoop));
1825         memcpy(cddm->mpoly, allpoly, totpoly * sizeof(MPoly));
1826
1827         MEM_freeN(allvert);
1828         MEM_freeN(alledge);
1829         MEM_freeN(allloop);
1830         MEM_freeN(allpoly);
1831
1832         CDDM_calc_edges(dm);
1833
1834         return dm;
1835 }
1836
1837 static void loops_to_customdata_corners(BMesh *bm, CustomData *facedata,
1838                                         int cdindex, const BMLoop *l3[3],
1839                                         int numCol, int numTex)
1840 {
1841         const BMLoop *l;
1842         BMFace *f = l3[0]->f;
1843         MTFace *texface;
1844         MTexPoly *texpoly;
1845         MCol *mcol;
1846         MLoopCol *mloopcol;
1847         MLoopUV *mloopuv;
1848         int i, j, hasPCol = CustomData_has_layer(&bm->ldata, CD_PREVIEW_MLOOPCOL);
1849
1850         for (i = 0; i < numTex; i++) {
1851                 texface = CustomData_get_n(facedata, CD_MTFACE, cdindex, i);
1852                 texpoly = CustomData_bmesh_get_n(&bm->pdata, f->head.data, CD_MTEXPOLY, i);
1853                 
1854                 ME_MTEXFACE_CPY(texface, texpoly);
1855         
1856                 for (j = 0; j < 3; j++) {
1857                         l = l3[j];
1858                         mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPUV, i);
1859                         copy_v2_v2(texface->uv[j], mloopuv->uv);
1860                 }
1861         }
1862
1863         for (i = 0; i < numCol; i++) {
1864                 mcol = CustomData_get_n(facedata, CD_MCOL, cdindex, i);
1865                 
1866                 for (j = 0; j < 3; j++) {
1867                         l = l3[j];
1868                         mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPCOL, i);
1869                         MESH_MLOOPCOL_TO_MCOL(mloopcol, &mcol[j]);
1870                 }
1871         }
1872
1873         if (hasPCol) {
1874                 mcol = CustomData_get(facedata, cdindex, CD_PREVIEW_MCOL);
1875
1876                 for (j = 0; j < 3; j++) {
1877                         l = l3[j];
1878                         mloopcol = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PREVIEW_MLOOPCOL);
1879                         MESH_MLOOPCOL_TO_MCOL(mloopcol, &mcol[j]);
1880                 }
1881         }
1882 }
1883
1884 /* used for both editbmesh and bmesh */
1885 static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
1886                                        /* EditBMesh vars for use_tessface */
1887                                        int use_tessface,
1888                                        const int em_tottri, const BMLoop *(*em_looptris)[3]
1889                                        )
1890 {
1891         DerivedMesh *dm = CDDM_new(bm->totvert,
1892                                    bm->totedge,
1893                                    use_tessface ? em_tottri : 0,
1894                                    bm->totloop,
1895                                    bm->totface);
1896
1897         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
1898         BMIter iter;
1899         BMVert *eve;
1900         BMEdge *eed;
1901         BMFace *efa;
1902         MVert *mvert = cddm->mvert;
1903         MEdge *medge = cddm->medge;
1904         MFace *mface = cddm->mface;
1905         MLoop *mloop = cddm->mloop;
1906         MPoly *mpoly = cddm->mpoly;
1907         int numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL);
1908         int numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
1909         int *index, add_orig;
1910         int has_crease, has_edge_bweight, has_vert_bweight;
1911         CustomDataMask mask;
1912         unsigned int i, j;
1913         
1914         has_edge_bweight = CustomData_has_layer(&bm->edata, CD_BWEIGHT);
1915         has_vert_bweight = CustomData_has_layer(&bm->vdata, CD_BWEIGHT);
1916         has_crease = CustomData_has_layer(&bm->edata, CD_CREASE);
1917         
1918         dm->deformedOnly = 1;
1919         
1920         /* don't add origindex layer if one already exists */
1921         add_orig = !CustomData_has_layer(&bm->pdata, CD_ORIGINDEX);
1922
1923         mask = use_mdisps ? CD_MASK_DERIVEDMESH | CD_MASK_MDISPS : CD_MASK_DERIVEDMESH;
1924         
1925         /* don't process shapekeys, we only feed them through the modifier stack as needed,
1926          * e.g. for applying modifiers or the like*/
1927         mask &= ~CD_MASK_SHAPEKEY;
1928         CustomData_merge(&bm->vdata, &dm->vertData, mask,
1929                          CD_CALLOC, dm->numVertData);
1930         CustomData_merge(&bm->edata, &dm->edgeData, mask,
1931                          CD_CALLOC, dm->numEdgeData);
1932         CustomData_merge(&bm->ldata, &dm->loopData, mask,
1933                          CD_CALLOC, dm->numLoopData);
1934         CustomData_merge(&bm->pdata, &dm->polyData, mask,
1935                          CD_CALLOC, dm->numPolyData);
1936
1937         /* add tessellation mface layers */
1938         if (use_tessface) {
1939                 CustomData_from_bmeshpoly(&dm->faceData, &dm->polyData, &dm->loopData, em_tottri);
1940         }
1941
1942         index = dm->getVertDataArray(dm, CD_ORIGINDEX);
1943
1944         eve = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL);
1945         for (i = 0; eve; eve = BM_iter_step(&iter), i++, index++) {
1946                 MVert *mv = &mvert[i];
1947
1948                 copy_v3_v3(mv->co, eve->co);
1949
1950                 BM_elem_index_set(eve, i); /* set_inline */
1951
1952                 normal_float_to_short_v3(mv->no, eve->no);
1953
1954                 mv->flag = BM_vert_flag_to_mflag(eve);
1955
1956                 if (has_vert_bweight)
1957                         mv->bweight = (unsigned char)(BM_elem_float_data_get(&bm->vdata, eve, CD_BWEIGHT) * 255.0f);
1958
1959                 if (add_orig) *index = i;
1960
1961                 CustomData_from_bmesh_block(&bm->vdata, &dm->vertData, eve->head.data, i);
1962         }
1963         bm->elem_index_dirty &= ~BM_VERT;
1964
1965         index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
1966         eed = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, NULL);
1967         for (i = 0; eed; eed = BM_iter_step(&iter), i++, index++) {
1968                 MEdge *med = &medge[i];
1969
1970                 BM_elem_index_set(eed, i); /* set_inline */
1971
1972                 med->v1 = BM_elem_index_get(eed->v1);
1973                 med->v2 = BM_elem_index_get(eed->v2);
1974
1975                 if (has_crease)
1976                         med->crease = (unsigned char)(BM_elem_float_data_get(&bm->edata, eed, CD_CREASE) * 255.0f);
1977                 if (has_edge_bweight)
1978                         med->bweight = (unsigned char)(BM_elem_float_data_get(&bm->edata, eed, CD_BWEIGHT) * 255.0f);
1979                 
1980                 med->flag = BM_edge_flag_to_mflag(eed);
1981
1982                 /* handle this differently to editmode switching,
1983                  * only enable draw for single user edges rather then calculating angle */
1984                 if ((med->flag & ME_EDGEDRAW) == 0) {
1985                         if (eed->l && eed->l == eed->l->radial_next) {
1986                                 med->flag |= ME_EDGEDRAW;
1987                         }
1988                 }
1989
1990                 CustomData_from_bmesh_block(&bm->edata, &dm->edgeData, eed->head.data, i);
1991                 if (add_orig) *index = i;
1992         }
1993         bm->elem_index_dirty &= ~BM_EDGE;
1994
1995         /* avoid this where possiblem, takes extra memory */
1996         if (use_tessface) {
1997
1998                 BM_mesh_elem_index_ensure(bm, BM_FACE);
1999
2000                 index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
2001                 for (i = 0; i < dm->numTessFaceData; i++, index++) {
2002                         MFace *mf = &mface[i];
2003                         const BMLoop **l = em_looptris[i];
2004                         efa = l[0]->f;
2005
2006                         mf->v1 = BM_elem_index_get(l[0]->v);
2007                         mf->v2 = BM_elem_index_get(l[1]->v);
2008                         mf->v3 = BM_elem_index_get(l[2]->v);
2009                         mf->v4 = 0;
2010                         mf->mat_nr = efa->mat_nr;
2011                         mf->flag = BM_face_flag_to_mflag(efa);
2012
2013                         /* map mfaces to polygons in the same cddm intentionally */
2014                         *index = BM_elem_index_get(efa);
2015
2016                         loops_to_customdata_corners(bm, &dm->faceData, i, l, numCol, numTex);
2017                         test_index_face(mf, &dm->faceData, i, 3);
2018                 }
2019         }
2020         
2021         index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
2022         j = 0;
2023         efa = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, NULL);
2024         for (i = 0; efa; i++, efa = BM_iter_step(&iter), index++) {
2025                 BMLoop *l_iter;
2026                 BMLoop *l_first;
2027                 MPoly *mp = &mpoly[i];
2028
2029                 BM_elem_index_set(efa, i); /* set_inline */
2030
2031                 mp->totloop = efa->len;
2032                 mp->flag = BM_face_flag_to_mflag(efa);
2033                 mp->loopstart = j;
2034                 mp->mat_nr = efa->mat_nr;
2035
2036                 l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
2037                 do {
2038                         mloop->v = BM_elem_index_get(l_iter->v);
2039                         mloop->e = BM_elem_index_get(l_iter->e);
2040                         CustomData_from_bmesh_block(&bm->ldata, &dm->loopData, l_iter->head.data, j);
2041
2042                         j++;
2043                         mloop++;
2044                 } while ((l_iter = l_iter->next) != l_first);
2045
2046                 CustomData_from_bmesh_block(&bm->pdata, &dm->polyData, efa->head.data, i);
2047
2048                 if (add_orig) *index = i;
2049         }
2050         bm->elem_index_dirty &= ~BM_FACE;
2051
2052         return dm;
2053 }
2054
2055 struct DerivedMesh *CDDM_from_bmesh(struct BMesh *bm, int use_mdisps)
2056 {
2057         return cddm_from_bmesh_ex(bm, use_mdisps, FALSE,
2058                                   /* these vars are for editmesh only */
2059                                   0, NULL);
2060 }
2061
2062 DerivedMesh *CDDM_from_editbmesh(BMEditMesh *em, int use_mdisps, int use_tessface)
2063 {
2064         return cddm_from_bmesh_ex(em->bm, use_mdisps,
2065                                   /* editmesh */
2066                                   use_tessface, em->tottri, (const BMLoop *(*)[3])em->looptris);
2067 }
2068
2069 static DerivedMesh *cddm_copy_ex(DerivedMesh *source, int faces_from_tessfaces)
2070 {
2071         CDDerivedMesh *cddm = cdDM_create("CDDM_copy cddm");
2072         DerivedMesh *dm = &cddm->dm;
2073         int numVerts = source->numVertData;
2074         int numEdges = source->numEdgeData;
2075         int numTessFaces = source->numTessFaceData;
2076         int numLoops = source->numLoopData;
2077         int numPolys = source->numPolyData;
2078
2079         /* ensure these are created if they are made on demand */
2080         source->getVertDataArray(source, CD_ORIGINDEX);
2081         source->getEdgeDataArray(source, CD_ORIGINDEX);
2082         source->getTessFaceDataArray(source, CD_ORIGINDEX);
2083         source->getPolyDataArray(source, CD_ORIGINDEX);
2084
2085         /* this initializes dm, and copies all non mvert/medge/mface layers */
2086         DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces,
2087                          numLoops, numPolys);
2088         dm->deformedOnly = source->deformedOnly;
2089         dm->dirty = source->dirty;
2090
2091         CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts);
2092         CustomData_copy_data(&source->edgeData, &dm->edgeData, 0, 0, numEdges);
2093         CustomData_copy_data(&source->faceData, &dm->faceData, 0, 0, numTessFaces);
2094
2095         /* now add mvert/medge/mface layers */
2096         cddm->mvert = source->dupVertArray(source);
2097         cddm->medge = source->dupEdgeArray(source);
2098         cddm->mface = source->dupTessFaceArray(source);
2099
2100         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, cddm->mvert, numVerts);
2101         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, cddm->medge, numEdges);
2102         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, cddm->mface, numTessFaces);
2103         
2104         if (!faces_from_tessfaces)
2105                 DM_DupPolys(source, dm);
2106         else
2107                 CDDM_tessfaces_to_faces(dm);
2108
2109         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
2110         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
2111
2112         return dm;
2113 }
2114
2115 DerivedMesh *CDDM_copy(DerivedMesh *source)
2116 {
2117         return cddm_copy_ex(source, 0);
2118 }
2119
2120 DerivedMesh *CDDM_copy_from_tessface(DerivedMesh *source)
2121 {
2122         return cddm_copy_ex(source, 1);
2123 }
2124
2125 /* note, the CD_ORIGINDEX layers are all 0, so if there is a direct
2126  * relationship between mesh data this needs to be set by the caller. */
2127 DerivedMesh *CDDM_from_template(DerivedMesh *source,
2128                                 int numVerts, int numEdges, int numTessFaces,
2129                                 int numLoops, int numPolys)
2130 {
2131         CDDerivedMesh *cddm = cdDM_create("CDDM_from_template dest");
2132         DerivedMesh *dm = &cddm->dm;
2133
2134         /* ensure these are created if they are made on demand */
2135         source->getVertDataArray(source, CD_ORIGINDEX);
2136         source->getEdgeDataArray(source, CD_ORIGINDEX);
2137         source->getTessFaceDataArray(source, CD_ORIGINDEX);
2138         source->getPolyDataArray(source, CD_ORIGINDEX);
2139
2140         /* this does a copy of all non mvert/medge/mface layers */
2141         DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces, numLoops, numPolys);
2142
2143         /* now add mvert/medge/mface layers */
2144         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
2145         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2146         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numTessFaces);
2147         CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL, numLoops);
2148         CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL, numPolys);
2149
2150         if (!CustomData_get_layer(&dm->vertData, CD_ORIGINDEX))
2151                 CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
2152         if (!CustomData_get_layer(&dm->edgeData, CD_ORIGINDEX))
2153                 CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2154         if (!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX))
2155                 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numTessFaces);
2156
2157         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
2158         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2159         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
2160         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
2161         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
2162
2163         return dm;
2164 }
2165
2166 void CDDM_apply_vert_coords(DerivedMesh *dm, float (*vertCoords)[3])
2167 {
2168         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2169         MVert *vert;
2170         int i;
2171
2172         /* this will just return the pointer if it wasn't a referenced layer */
2173         vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2174         cddm->mvert = vert;
2175
2176         for (i = 0; i < dm->numVertData; ++i, ++vert)
2177                 copy_v3_v3(vert->co, vertCoords[i]);
2178 }
2179
2180 void CDDM_apply_vert_normals(DerivedMesh *dm, short (*vertNormals)[3])
2181 {
2182         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2183         MVert *vert;
2184         int i;
2185
2186         /* this will just return the pointer if it wasn't a referenced layer */
2187         vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2188         cddm->mvert = vert;
2189
2190         for (i = 0; i < dm->numVertData; ++i, ++vert)
2191                 copy_v3_v3_short(vert->no, vertNormals[i]);
2192 }
2193
2194 void CDDM_calc_normals_mapping_ex(DerivedMesh *dm, const short only_face_normals)
2195 {
2196         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2197         float (*face_nors)[3] = NULL;
2198
2199         if (dm->numVertData == 0) return;
2200
2201         /* now we skip calculating vertex normals for referenced layer,
2202          * no need to duplicate verts.
2203          * WATCH THIS, bmesh only change!,
2204          * need to take care of the side effects here - campbell */
2205         #if 0
2206         /* we don't want to overwrite any referenced layers */
2207         cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2208         #endif
2209
2210
2211         if (dm->numTessFaceData == 0) {
2212                 /* No tessellation on this mesh yet, need to calculate one.
2213                  *
2214                  * Important not to update face normals from polys since it
2215                  * interferes with assigning the new normal layer in the following code.
2216                  */
2217                 CDDM_recalc_tessellation_ex(dm, FALSE);
2218         }
2219         else {
2220                 /* A tessellation already exists, it should always have a CD_ORIGINDEX */
2221                 BLI_assert(CustomData_has_layer(&dm->faceData, CD_ORIGINDEX));
2222                 CustomData_free_layers(&dm->faceData, CD_NORMAL, dm->numTessFaceData);
2223         }
2224
2225
2226         face_nors = MEM_mallocN(sizeof(float) * 3 * dm->numTessFaceData, "face_nors");
2227
2228         /* calculate face normals */
2229         BKE_mesh_calc_normals_mapping_ex(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm),
2230                                          dm->numLoopData, dm->numPolyData, NULL, cddm->mface, dm->numTessFaceData,
2231                                          CustomData_get_layer(&dm->faceData, CD_ORIGINDEX), face_nors,
2232                                          only_face_normals);
2233
2234         CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_ASSIGN,
2235                              face_nors, dm->numTessFaceData);
2236 }
2237
2238
2239 void CDDM_calc_normals_mapping(DerivedMesh *dm)
2240 {
2241         /* use this to skip calculating normals on original vert's, this may need to be changed */
2242         const short only_face_normals = CustomData_is_referenced_layer(&dm->vertData, CD_MVERT);
2243
2244         CDDM_calc_normals_mapping_ex(dm, only_face_normals);
2245 }
2246
2247 /* bmesh note: this matches what we have in trunk */
2248 void CDDM_calc_normals(DerivedMesh *dm)
2249 {
2250         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2251         float (*poly_nors)[3];
2252
2253         if (dm->numVertData == 0) return;
2254
2255         /* we don't want to overwrite any referenced layers */
2256         cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2257
2258         /* fill in if it exists */
2259         poly_nors = CustomData_get_layer(&dm->polyData, CD_NORMAL);
2260         if (!poly_nors) {
2261                 poly_nors = CustomData_add_layer(&dm->polyData, CD_NORMAL, CD_CALLOC, NULL, dm->numPolyData);
2262         }
2263
2264         BKE_mesh_calc_normals(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm),
2265                               dm->numLoopData, dm->numPolyData, poly_nors);
2266 }
2267
2268 void CDDM_calc_normals_tessface(DerivedMesh *dm)
2269 {
2270         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2271         float (*face_nors)[3];
2272
2273         if (dm->numVertData == 0) return;
2274
2275         /* we don't want to overwrite any referenced layers */
2276         cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2277
2278         /* fill in if it exists */
2279         face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
2280         if (!face_nors) {
2281                 face_nors = CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_CALLOC, NULL, dm->numTessFaceData);
2282         }
2283
2284         BKE_mesh_calc_normals_tessface(cddm->mvert, dm->numVertData,
2285                                        cddm->mface, dm->numTessFaceData, face_nors);
2286 }
2287
2288 #if 1
2289 /* merge verts
2290  *
2291  * vtargetmap is a table that maps vertices to target vertices.  a value of -1
2292  * indicates a vertex is a target, and is to be kept.
2293  *
2294  * this frees dm, and returns a new one.
2295  *
2296  * this is a really horribly written function.  ger. - joeedh
2297  *
2298  * note, CDDM_recalc_tessellation has to run on the returned DM if you want to access tessfaces.
2299  *
2300  * Note: This function is currently only used by the Mirror modifier, so it
2301  *       skips any faces that have all vertices merged (to avoid creating pairs
2302  *       of faces sharing the same set of vertices). If used elsewhere, it may
2303  *       be necessary to make this functionality optional.
2304  */
2305 DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap)
2306 {
2307         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2308         CDDerivedMesh *cddm2 = NULL;
2309         MVert *mv, *mvert = NULL;
2310         BLI_array_declare(mvert);
2311         MEdge *med, *medge = NULL;
2312         BLI_array_declare(medge);
2313         MPoly *mp, *mpoly = NULL;
2314         BLI_array_declare(mpoly);
2315         MLoop *ml, *mloop = NULL;
2316         BLI_array_declare(mloop);
2317         EdgeHash *ehash = BLI_edgehash_new();
2318         int *newv = NULL, *newe = NULL, *newl = NULL;
2319         int *oldv = NULL, *olde = NULL, *oldl = NULL, *oldp = NULL;
2320         BLI_array_declare(oldv); BLI_array_declare(olde); BLI_array_declare(oldl); BLI_array_declare(oldp);
2321         int i, j, c, totloop, totpoly;
2322         
2323         totloop = dm->numLoopData;
2324         totpoly = dm->numPolyData;
2325         
2326         newv = MEM_callocN(sizeof(int) * dm->numVertData, "newv vtable CDDM_merge_verts");
2327         newe = MEM_callocN(sizeof(int) * dm->numEdgeData, "newv etable CDDM_merge_verts");
2328         newl = MEM_callocN(sizeof(int) * totloop, "newv ltable CDDM_merge_verts");
2329         
2330         /* fill newl with destination vertex indices */
2331         mv = cddm->mvert;
2332         c = 0;
2333         for (i = 0; i < dm->numVertData; i++, mv++) {
2334                 if (vtargetmap[i] == -1) {
2335                         BLI_array_append(oldv, i);
2336                         newv[i] = c++;
2337                         BLI_array_append(mvert, *mv);
2338                 }
2339         }
2340         
2341         /* now link target vertices to destination indices */
2342         for (i = 0; i < dm->numVertData; i++) {
2343                 if (vtargetmap[i] != -1) {
2344                         newv[i] = newv[vtargetmap[i]];
2345                 }
2346         }
2347
2348         /* Don't remap vertices in cddm->mloop, because we need to know the original
2349          * indices in order to skip faces with all vertices merged.
2350          * The "update loop indices..." section further down remaps vertices in mloop.
2351          */
2352
2353         /* now go through and fix edges and faces */
2354         med = cddm->medge;
2355         c = 0;
2356         for (i = 0; i < dm->numEdgeData; i++, med++) {
2357                 
2358                 if (LIKELY(med->v1 != med->v2)) {
2359                         const unsigned int v1 = (vtargetmap[med->v1] != -1) ? vtargetmap[med->v1] : med->v1;
2360                         const unsigned int v2 = (vtargetmap[med->v2] != -1) ? vtargetmap[med->v2] : med->v2;
2361                         void **eh_p = BLI_edgehash_lookup_p(ehash, v1, v2);
2362
2363                         if (eh_p) {
2364                                 newe[i] = GET_INT_FROM_POINTER(*eh_p);
2365                         }
2366                         else {
2367                                 BLI_array_append(olde, i);
2368                                 newe[i] = c;
2369                                 BLI_array_append(medge, *med);
2370                                 BLI_edgehash_insert(ehash, v1, v2, SET_INT_IN_POINTER(c));
2371                                 c++;
2372                         }
2373                 }
2374                 else {
2375                         newe[i] = -1;
2376                 }
2377         }
2378         
2379         mp = cddm->mpoly;
2380         for (i = 0; i < totpoly; i++, mp++) {
2381                 MPoly *mp2;
2382                 
2383                 ml = cddm->mloop + mp->loopstart;
2384
2385                 /* skip faces with all vertices merged */
2386                 {
2387                         int all_vertices_merged = TRUE;
2388
2389                         for (j = 0; j < mp->totloop; j++, ml++) {
2390                                 if (vtargetmap[ml->v] == -1) {
2391                                         all_vertices_merged = FALSE;
2392                                         break;
2393                                 }
2394                         }
2395
2396                         if (UNLIKELY(all_vertices_merged)) {
2397                                 continue;
2398                         }
2399                 }
2400
2401                 ml = cddm->mloop + mp->loopstart;
2402
2403                 c = 0;
2404                 for (j = 0; j < mp->totloop; j++, ml++) {
2405                         med = cddm->medge + ml->e;
2406                         if (LIKELY(med->v1 != med->v2)) {
2407                                 newl[j + mp->loopstart] = BLI_array_count(mloop);
2408                                 BLI_array_append(oldl, j + mp->loopstart);
2409                                 BLI_array_append(mloop, *ml);
2410                                 c++;
2411                         }
2412                 }
2413
2414                 if (UNLIKELY(c == 0)) {
2415                         continue;
2416                 }
2417                 
2418                 mp2 = BLI_array_append_r(mpoly, *mp);
2419                 mp2->totloop = c;
2420                 mp2->loopstart = BLI_array_count(mloop) - c;
2421                 
2422                 BLI_array_append(oldp, i);
2423         }
2424         
2425         /*create new cddm*/
2426         cddm2 = (CDDerivedMesh *) CDDM_from_template((DerivedMesh *)cddm, BLI_array_count(mvert), BLI_array_count(medge), 0, BLI_array_count(mloop), BLI_array_count(mpoly));
2427         
2428         /*update edge indices and copy customdata*/
2429         med = medge;
2430         for (i = 0; i < cddm2->dm.numEdgeData; i++, med++) {
2431                 if (newv[med->v1] != -1)
2432                         med->v1 = newv[med->v1];
2433                 if (newv[med->v2] != -1)
2434                         med->v2 = newv[med->v2];
2435                 
2436                 CustomData_copy_data(&dm->edgeData, &cddm2->dm.edgeData, olde[i], i, 1);
2437         }
2438         
2439         /*update loop indices and copy customdata*/
2440         ml = mloop;
2441         for (i = 0; i < cddm2->dm.numLoopData; i++, ml++) {
2442                 if (newe[ml->e] != -1)
2443                         ml->e = newe[ml->e];
2444                 if (newv[ml->v] != -1)
2445                         ml->v = newv[ml->v];
2446                         
2447                 CustomData_copy_data(&dm->loopData, &cddm2->dm.loopData, oldl[i], i, 1);
2448         }
2449         
2450         /*copy vertex customdata*/
2451         mv = mvert;
2452         for (i = 0; i < cddm2->dm.numVertData; i++, mv++) {
2453                 CustomData_copy_data(&dm->vertData, &cddm2->dm.vertData, oldv[i], i, 1);
2454         }
2455         
2456         /*copy poly customdata*/
2457         mp = mpoly;
2458         for (i = 0; i < cddm2->dm.numPolyData; i++, mp++) {
2459                 CustomData_copy_data(&dm->polyData, &cddm2->dm.polyData, oldp[i], i, 1);
2460         }
2461         
2462         /*copy over data.  CustomData_add_layer can do this, need to look it up.*/
2463         memcpy(cddm2->mvert, mvert, sizeof(MVert) * BLI_array_count(mvert));
2464         memcpy(cddm2->medge, medge, sizeof(MEdge) * BLI_array_count(medge));
2465         memcpy(cddm2->mloop, mloop, sizeof(MLoop) * BLI_array_count(mloop));
2466         memcpy(cddm2->mpoly, mpoly, sizeof(MPoly) * BLI_array_count(mpoly));
2467         BLI_array_free(mvert); BLI_array_free(medge); BLI_array_free(mloop); BLI_array_free(mpoly);
2468         
2469         if (newv) 
2470                 MEM_freeN(newv); 
2471         if (newe)
2472                 MEM_freeN(newe); 
2473         if (newl)
2474                 MEM_freeN(newl);
2475         if (oldv) 
2476                 MEM_freeN(oldv); 
2477         if (olde) 
2478                 MEM_freeN(olde); 
2479         if (oldl) 
2480                 MEM_freeN(oldl); 
2481         if (oldp) 
2482                 MEM_freeN(oldp);
2483         if (ehash)
2484                 BLI_edgehash_free(ehash, NULL);
2485
2486         /*free old derivedmesh*/
2487         dm->needsFree = 1;
2488         dm->release(dm);
2489         
2490         return (DerivedMesh *)cddm2;
2491 }
2492 #endif
2493
2494 void CDDM_calc_edges_tessface(DerivedMesh *dm)
2495 {
2496         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2497         CustomData edgeData;
2498         EdgeHashIterator *ehi;
2499         MFace *mf = cddm->mface;
2500         MEdge *med;
2501         EdgeHash *eh = BLI_edgehash_new();
2502         int i, *index, numEdges, maxFaces = dm->numTessFaceData;
2503
2504         for (i = 0; i < maxFaces; i++, mf++) {
2505                 if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
2506                         BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
2507                 if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
2508                         BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
2509                 
2510                 if (mf->v4) {
2511                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
2512                                 BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
2513                         if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
2514                                 BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
2515                 }
2516                 else {
2517                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
2518                                 BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
2519                 }
2520         }
2521
2522         numEdges = BLI_edgehash_size(eh);
2523
2524         /* write new edges into a temporary CustomData */
2525         CustomData_reset(&edgeData);
2526         CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2527         CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2528
2529         med = CustomData_get_layer(&edgeData, CD_MEDGE);
2530         index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
2531
2532         for (ehi = BLI_edgehashIterator_new(eh), i = 0;
2533              BLI_edgehashIterator_isDone(ehi) == FALSE;
2534              BLI_edgehashIterator_step(ehi), ++i, ++med, ++index)
2535         {
2536                 BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2);
2537
2538                 med->flag = ME_EDGEDRAW | ME_EDGERENDER;
2539                 *index = ORIGINDEX_NONE;
2540         }
2541         BLI_edgehashIterator_free(ehi);
2542
2543         /* free old CustomData and assign new one */
2544         CustomData_free(&dm->edgeData, dm->numEdgeData);
2545         dm->edgeData = edgeData;
2546         dm->numEdgeData = numEdges;
2547
2548         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2549
2550         BLI_edgehash_free(eh, NULL);
2551 }
2552
2553 /* warning, this uses existing edges but CDDM_calc_edges_tessface() doesn't */
2554 void CDDM_calc_edges(DerivedMesh *dm)
2555 {
2556         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2557         CustomData edgeData;
2558         EdgeHashIterator *ehi;
2559         MPoly *mp = cddm->mpoly;
2560         MLoop *ml;
2561         MEdge *med, *origmed;
2562         EdgeHash *eh = BLI_edgehash_new();
2563         int v1, v2;
2564         int *eindex;
2565         int i, j, *index, numEdges = cddm->dm.numEdgeData, maxFaces = dm->numPolyData;
2566
2567         eindex = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
2568
2569         med = cddm->medge;
2570         if (med) {
2571                 for (i = 0; i < numEdges; i++, med++) {
2572                         BLI_edgehash_insert(eh, med->v1, med->v2, SET_INT_IN_POINTER(i + 1));
2573                 }
2574         }
2575
2576         for (i = 0; i < maxFaces; i++, mp++) {
2577                 ml = cddm->mloop + mp->loopstart;
2578                 for (j = 0; j < mp->totloop; j++, ml++) {
2579                         v1 = ml->v;
2580                         v2 = ME_POLY_LOOP_NEXT(cddm->mloop, mp, j)->v;
2581                         if (!BLI_edgehash_haskey(eh, v1, v2)) {
2582                                 BLI_edgehash_insert(eh, v1, v2, NULL);
2583                         }
2584                 }
2585         }
2586
2587         numEdges = BLI_edgehash_size(eh);
2588
2589         /* write new edges into a temporary CustomData */
2590         CustomData_reset(&edgeData);
2591         CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2592         CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2593
2594         origmed = cddm->medge;
2595         med = CustomData_get_layer(&edgeData, CD_MEDGE);
2596         index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
2597
2598         for (ehi = BLI_edgehashIterator_new(eh), i = 0;
2599              BLI_edgehashIterator_isDone(ehi) == FALSE;
2600              BLI_edgehashIterator_step(ehi), ++i, ++med, ++index)
2601         {
2602                 BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2);
2603                 j = GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi));
2604
2605                 if (j == 0) {
2606                         med->flag = ME_EDGEDRAW | ME_EDGERENDER;
2607                         *index = ORIGINDEX_NONE;
2608                 }
2609                 else {
2610                         med->flag = ME_EDGEDRAW | ME_EDGERENDER | origmed[j - 1].flag;
2611                         *index = eindex[j - 1];
2612                 }
2613
2614                 BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(i));
2615         }
2616         BLI_edgehashIterator_free(ehi);
2617
2618         /* free old CustomData and assign new one */
2619         CustomData_free(&dm->edgeData, dm->numEdgeData);
2620         dm->edgeData = edgeData;
2621         dm->numEdgeData = numEdges;
2622
2623         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2624
2625         mp = cddm->mpoly;
2626         for (i = 0; i < maxFaces; i++, mp++) {
2627                 ml = cddm->mloop + mp->loopstart;
2628                 for (j = 0; j < mp->totloop; j++, ml++) {
2629                         v1 = ml->v;
2630                         v2 = ME_POLY_LOOP_NEXT(cddm->mloop, mp, j)->v;
2631                         ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, v1, v2));
2632                 }
2633         }
2634
2635         BLI_edgehash_free(eh, NULL);
2636 }
2637
2638 void CDDM_lower_num_verts(DerivedMesh *dm, int numVerts)
2639 {
2640         if (numVerts < dm->numVertData)
2641                 CustomData_free_elem(&dm->vertData, numVerts, dm->numVertData - numVerts);
2642
2643         dm->numVertData = numVerts;
2644 }
2645
2646 void CDDM_lower_num_edges(DerivedMesh *dm, int numEdges)
2647 {
2648         if (numEdges < dm->numEdgeData)
2649                 CustomData_free_elem(&dm->edgeData, numEdges, dm->numEdgeData - numEdges);
2650
2651         dm->numEdgeData = numEdges;
2652 }
2653
2654 void CDDM_lower_num_tessfaces(DerivedMesh *dm, int numTessFaces)
2655 {
2656         if (numTessFaces < dm->numTessFaceData)
2657                 CustomData_free_elem(&dm->faceData, numTessFaces, dm->numTessFaceData - numTessFaces);
2658
2659         dm->numTessFaceData = numTessFaces;
2660 }
2661
2662 void CDDM_lower_num_polys(DerivedMesh *dm, int numPolys)
2663 {
2664         if (numPolys < dm->numPolyData)
2665                 CustomData_free_elem(&dm->polyData, numPolys, dm->numPolyData - numPolys);
2666
2667         dm->numPolyData = numPolys;
2668 }
2669
2670 /* mesh element access functions */
2671
2672 MVert *CDDM_get_vert(DerivedMesh *dm, int index)
2673 {
2674         return &((CDDerivedMesh *)dm)->mvert[index];
2675 }
2676
2677 MEdge *CDDM_get_edge(DerivedMesh *dm, int index)
2678 {
2679         return &((CDDerivedMesh *)dm)->medge[index];
2680 }
2681
2682 MFace *CDDM_get_tessface(DerivedMesh *dm, int index)
2683 {
2684         return &((CDDerivedMesh *)dm)->mface[index];
2685 }
2686
2687 MLoop *CDDM_get_loop(DerivedMesh *dm, int index)
2688 {
2689         return &((CDDerivedMesh *)dm)->mloop[index];
2690 }
2691
2692 MPoly *CDDM_get_poly(DerivedMesh *dm, int index)
2693 {
2694         return &((CDDerivedMesh *)dm)->mpoly[index];
2695 }
2696
2697 /* array access functions */
2698
2699 MVert *CDDM_get_verts(DerivedMesh *dm)
2700 {
2701         return ((CDDerivedMesh *)dm)->mvert;
2702 }
2703
2704 MEdge *CDDM_get_edges(DerivedMesh *dm)
2705 {
2706         return ((CDDerivedMesh *)dm)->medge;
2707 }
2708
2709 MFace *CDDM_get_tessfaces(DerivedMesh *dm)
2710 {
2711         return ((CDDerivedMesh *)dm)->mface;
2712 }
2713
2714 MLoop *CDDM_get_loops(DerivedMesh *dm)
2715 {
2716         return ((CDDerivedMesh *)dm)->mloop;
2717 }
2718
2719 MPoly *CDDM_get_polys(DerivedMesh *dm)
2720 {
2721         return ((CDDerivedMesh *)dm)->mpoly;
2722 }
2723
2724 void CDDM_tessfaces_to_faces(DerivedMesh *dm)
2725 {
2726         /* converts mfaces to mpolys/mloops */
2727         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2728
2729         BKE_mesh_convert_mfaces_to_mpolys_ex(NULL, &cddm->dm.faceData, &cddm->dm.loopData, &cddm->dm.polyData,
2730                                              cddm->dm.numEdgeData, cddm->dm.numTessFaceData,
2731                                              cddm->dm.numLoopData, cddm->dm.numPolyData,
2732                                              cddm->medge, cddm->mface,
2733                                              &cddm->dm.numLoopData, &cddm->dm.numPolyData,
2734                                              &cddm->mloop, &cddm->mpoly);
2735 }
2736
2737 void CDDM_set_mvert(DerivedMesh *dm, MVert *mvert)
2738 {
2739         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2740         
2741         if (!CustomData_has_layer(&dm->vertData, CD_MVERT))
2742                 CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, mvert, dm->numVertData);
2743                                 
2744         cddm->mvert = mvert;
2745 }
2746
2747 void CDDM_set_medge(DerivedMesh *dm, MEdge *medge)
2748 {
2749         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2750
2751         if (!CustomData_has_layer(&dm->edgeData, CD_MEDGE))
2752                 CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, medge, dm->numEdgeData);
2753
2754         cddm->medge = medge;
2755 }
2756
2757 void CDDM_set_mface(DerivedMesh *dm, MFace *mface)
2758 {
2759         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2760
2761         if (!CustomData_has_layer(&dm->faceData, CD_MFACE))
2762                 CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, mface, dm->numTessFaceData);
2763
2764         cddm->mface = mface;
2765 }
2766
2767 void CDDM_set_mloop(DerivedMesh *dm, MLoop *mloop)
2768 {
2769         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2770
2771         if (!CustomData_has_layer(&dm->loopData, CD_MLOOP))
2772                 CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_ASSIGN, mloop, dm->numLoopData);
2773
2774         cddm->mloop = mloop;
2775 }
2776
2777 void CDDM_set_mpoly(DerivedMesh *dm, MPoly *mpoly)
2778 {
2779         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2780
2781         if (!CustomData_has_layer(&dm->polyData, CD_MPOLY))
2782                 CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_ASSIGN, mpoly, dm->numPolyData);
2783
2784         cddm->mpoly = mpoly;
2785 }