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