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