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