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