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