Sculpt: svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r24257...
[blender-staging.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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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 /* TODO maybe BIF_gl.h should include string.h? */
36 #include <string.h>
37 #include "BIF_gl.h"
38
39 #include "BKE_cdderivedmesh.h"
40 #include "BKE_customdata.h"
41 #include "BKE_DerivedMesh.h"
42 #include "BKE_displist.h"
43 #include "BKE_global.h"
44 #include "BKE_mesh.h"
45 #include "BKE_multires.h"
46 #include "BKE_utildefines.h"
47
48 #include "BLI_arithb.h"
49 #include "BLI_blenlib.h"
50 #include "BLI_edgehash.h"
51 #include "BLI_editVert.h"
52 #include "BLI_pbvh.h"
53
54 #include "DNA_mesh_types.h"
55 #include "DNA_meshdata_types.h"
56 #include "DNA_modifier_types.h"
57 #include "DNA_object_fluidsim.h"
58 #include "DNA_object_types.h"
59 #include "DNA_scene_types.h"
60
61 #include "MEM_guardedalloc.h"
62
63 #include "gpu_buffers.h"
64 #include "GPU_draw.h"
65 #include "GPU_extensions.h"
66 #include "GPU_material.h"
67
68 #include <string.h>
69 #include <limits.h>
70 #include <math.h>
71
72 typedef struct {
73         DerivedMesh dm;
74
75         /* these point to data in the DerivedMesh custom data layers,
76            they are only here for efficiency and convenience **/
77         MVert *mvert;
78         MEdge *medge;
79         MFace *mface;
80
81         /* Cached */
82         struct PBVH *pbvh;
83         /* Mesh connectivity */
84         struct ListBase *fmap;
85         struct IndexNode *fmap_mem;
86 } CDDerivedMesh;
87
88 /**************** DerivedMesh interface functions ****************/
89 static int cdDM_getNumVerts(DerivedMesh *dm)
90 {
91         return dm->numVertData;
92 }
93
94 static int cdDM_getNumEdges(DerivedMesh *dm)
95 {
96         return dm->numEdgeData;
97 }
98
99 static int cdDM_getNumFaces(DerivedMesh *dm)
100 {
101         return dm->numFaceData;
102 }
103
104 static void cdDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
105 {
106         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
107         *vert_r = cddm->mvert[index];
108 }
109
110 static void cdDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
111 {
112         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
113         *edge_r = cddm->medge[index];
114 }
115
116 static void cdDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
117 {
118         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
119         *face_r = cddm->mface[index];
120 }
121
122 static void cdDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
123 {
124         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
125         memcpy(vert_r, cddm->mvert, sizeof(*vert_r) * dm->numVertData);
126 }
127
128 static void cdDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
129 {
130         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
131         memcpy(edge_r, cddm->medge, sizeof(*edge_r) * dm->numEdgeData);
132 }
133
134 static void cdDM_copyFaceArray(DerivedMesh *dm, MFace *face_r)
135 {
136         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
137         memcpy(face_r, cddm->mface, sizeof(*face_r) * dm->numFaceData);
138 }
139
140 static void cdDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
141 {
142         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
143         int i;
144
145         if (dm->numVertData) {
146                 for (i=0; i<dm->numVertData; i++) {
147                         DO_MINMAX(cddm->mvert[i].co, min_r, max_r);
148                 }
149         } else {
150                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
151         }
152 }
153
154 static void cdDM_getVertCo(DerivedMesh *dm, int index, float co_r[3])
155 {
156         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
157
158         VECCOPY(co_r, cddm->mvert[index].co);
159 }
160
161 static void cdDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
162 {
163         MVert *mv = CDDM_get_verts(dm);
164         int i;
165
166         for(i = 0; i < dm->numVertData; i++, mv++)
167                 VECCOPY(cos_r[i], mv->co);
168 }
169
170 static void cdDM_getVertNo(DerivedMesh *dm, int index, float no_r[3])
171 {
172         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
173         short *no = cddm->mvert[index].no;
174
175         no_r[0] = no[0]/32767.f;
176         no_r[1] = no[1]/32767.f;
177         no_r[2] = no[2]/32767.f;
178 }
179
180 static ListBase *cdDM_getFaceMap(DerivedMesh *dm)
181 {
182         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
183
184         if(!cddm->fmap) {
185                 create_vert_face_map(&cddm->fmap, &cddm->fmap_mem, cddm->mface,
186                                      dm->getNumVerts(dm), dm->getNumFaces(dm));
187                 printf("rebuild fmap\n");
188         }
189
190         return cddm->fmap;
191 }
192
193 static struct PBVH *cdDM_getPBVH(DerivedMesh *dm)
194 {
195         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
196
197         if(!cddm->pbvh) {
198                 cddm->pbvh = BLI_pbvh_new();
199                 BLI_pbvh_build(cddm->pbvh, cddm->mface, cddm->mvert,
200                                dm->getNumFaces(dm), dm->getNumVerts(dm));
201                 printf("rebuild pbvh\n");
202         }
203
204         return cddm->pbvh;
205 }
206
207 static void cdDM_drawVerts(DerivedMesh *dm)
208 {
209         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
210         MVert *mv = cddm->mvert;
211         int i;
212
213         if( GPU_buffer_legacy(dm) ) {
214                 glBegin(GL_POINTS);
215                 for(i = 0; i < dm->numVertData; i++, mv++)
216                         glVertex3fv(mv->co);
217                 glEnd();
218         }
219         else {  /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
220                 GPU_vertex_setup(dm);
221                 if( !GPU_buffer_legacy(dm) ) {
222                         glDrawArrays(GL_POINTS,0,dm->drawObject->nelements);
223                 }
224                 GPU_buffer_unbind();
225         }
226 }
227
228 static void cdDM_drawUVEdges(DerivedMesh *dm)
229 {
230         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
231         MFace *mf = cddm->mface;
232         MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
233         int i;
234
235         if(mf) {
236                 if( GPU_buffer_legacy(dm) ) {
237                         glBegin(GL_LINES);
238                         for(i = 0; i < dm->numFaceData; i++, mf++, tf++) {
239                                 if(!(mf->flag&ME_HIDE)) {
240                                         glVertex2fv(tf->uv[0]);
241                                         glVertex2fv(tf->uv[1]);
242
243                                         glVertex2fv(tf->uv[1]);
244                                         glVertex2fv(tf->uv[2]);
245
246                                         if(!mf->v4) {
247                                                 glVertex2fv(tf->uv[2]);
248                                                 glVertex2fv(tf->uv[0]);
249                                         } else {
250                                                 glVertex2fv(tf->uv[2]);
251                                                 glVertex2fv(tf->uv[3]);
252
253                                                 glVertex2fv(tf->uv[3]);
254                                                 glVertex2fv(tf->uv[0]);
255                                         }
256                                 }
257                         }
258                         glEnd();
259                 }
260                 else {
261                         int prevstart = 0;
262                         int prevdraw = 1;
263                         int draw = 1;
264                         int curpos = 0;
265
266                         GPU_uvedge_setup(dm);
267                         if( !GPU_buffer_legacy(dm) ) {
268                                 for(i = 0; i < dm->numFaceData; i++, mf++) {
269                                         if(mf->flag&ME_LOOSEEDGE) {
270                                                 draw = 1;
271                                         } 
272                                         else {
273                                                 draw = 0;
274                                         }
275                                         if( prevdraw != draw ) {
276                                                 if( prevdraw > 0 && (curpos-prevstart) > 0) {
277                                                         glDrawArrays(GL_LINES,prevstart,curpos-prevstart);
278                                                 }
279                                                 prevstart = curpos;
280                                         }
281                                         if( mf->v4 ) {
282                                                 curpos += 8;
283                                         }
284                                         else {
285                                                 curpos += 6;
286                                         }
287                                         prevdraw = draw;
288                                 }
289                                 if( prevdraw > 0 && (curpos-prevstart) > 0 ) {
290                                         glDrawArrays(GL_LINES,prevstart,curpos-prevstart);
291                                 }
292                         }
293                         GPU_buffer_unbind();
294                 }
295         }
296 }
297
298 static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
299 {
300         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
301         MVert *mvert = cddm->mvert;
302         MEdge *medge = cddm->medge;
303         int i;
304         
305         if( GPU_buffer_legacy(dm) ) {
306                 DEBUG_VBO( "Using legacy code. cdDM_drawEdges\n" );
307                 glBegin(GL_LINES);
308                 for(i = 0; i < dm->numEdgeData; i++, medge++) {
309                         if((medge->flag&ME_EDGEDRAW)
310                            && (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) {
311                                 glVertex3fv(mvert[medge->v1].co);
312                                 glVertex3fv(mvert[medge->v2].co);
313                         }
314                 }
315                 glEnd();
316         }
317         else {  /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
318                 int prevstart = 0;
319                 int prevdraw = 1;
320                 int draw = 1;
321
322                 GPU_edge_setup(dm);
323                 if( !GPU_buffer_legacy(dm) ) {
324                         for(i = 0; i < dm->numEdgeData; i++, medge++) {
325                                 if((medge->flag&ME_EDGEDRAW)
326                                    && (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) {
327                                         draw = 1;
328                                 } 
329                                 else {
330                                         draw = 0;
331                                 }
332                                 if( prevdraw != draw ) {
333                                         if( prevdraw > 0 && (i-prevstart) > 0 ) {
334                                                 GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2  );
335                                         }
336                                         prevstart = i;
337                                 }
338                                 prevdraw = draw;
339                         }
340                         if( prevdraw > 0 && (i-prevstart) > 0 ) {
341                                 GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2  );
342                         }
343                 }
344                 GPU_buffer_unbind();
345         }
346 }
347
348 static void cdDM_drawLooseEdges(DerivedMesh *dm)
349 {
350         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
351         MVert *mvert = cddm->mvert;
352         MEdge *medge = cddm->medge;
353         int i;
354
355         if( GPU_buffer_legacy(dm) ) {
356                 DEBUG_VBO( "Using legacy code. cdDM_drawLooseEdges\n" );
357                 glBegin(GL_LINES);
358                 for(i = 0; i < dm->numEdgeData; i++, medge++) {
359                         if(medge->flag&ME_LOOSEEDGE) {
360                                 glVertex3fv(mvert[medge->v1].co);
361                                 glVertex3fv(mvert[medge->v2].co);
362                         }
363                 }
364                 glEnd();
365         }
366         else {  /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
367                 int prevstart = 0;
368                 int prevdraw = 1;
369                 int draw = 1;
370
371                 GPU_edge_setup(dm);
372                 if( !GPU_buffer_legacy(dm) ) {
373                         for(i = 0; i < dm->numEdgeData; i++, medge++) {
374                                 if(medge->flag&ME_LOOSEEDGE) {
375                                         draw = 1;
376                                 } 
377                                 else {
378                                         draw = 0;
379                                 }
380                                 if( prevdraw != draw ) {
381                                         if( prevdraw > 0 && (i-prevstart) > 0) {
382                                                 GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2  );
383                                         }
384                                         prevstart = i;
385                                 }
386                                 prevdraw = draw;
387                         }
388                         if( prevdraw > 0 && (i-prevstart) > 0 ) {
389                                 GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2  );
390                         }
391                 }
392                 GPU_buffer_unbind();
393         }
394 }
395
396 static int nodes_drawn = 0;
397 static int is_partial = 0;
398 /* XXX: Just a temporary replacement for the real drawing code */
399 static void draw_partial_cb(PBVHNode *node, void *data)
400 {
401         /* XXX: Just some quick code to show leaf nodes in different colors */
402         /*float col[3]; int i;
403         if(is_partial) {
404                 col[0] = (rand() / (float)RAND_MAX); col[1] = col[2] = 0.6;
405         }
406         else {
407                 srand((long long)data_v);
408                 for(i = 0; i < 3; ++i)
409                         col[i] = (rand() / (float)RAND_MAX) * 0.3 + 0.7;
410         }
411         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col);
412
413         glColor3f(1, 0, 0);*/
414         GPU_draw_buffers(BLI_pbvh_node_get_draw_buffers(node));
415         ++nodes_drawn;
416 }
417
418 /* Adapted from:
419    http://www.gamedev.net/community/forums/topic.asp?topic_id=512123
420    Returns true if the AABB is at least partially within the frustum
421    (ok, not a real frustum), false otherwise.
422 */
423 int planes_contain_AABB(PBVHNode *node, float bb_min[3], float bb_max[3], void *data)
424 {
425         float (*planes)[4] = data;
426         int i, axis;
427         float vmin[3], vmax[3];
428
429         for(i = 0; i < 4; ++i) { 
430                 for(axis = 0; axis < 3; ++axis) {
431                         if(planes[i][axis] > 0) { 
432                                 vmin[axis] = bb_min[axis];
433                                 vmax[axis] = bb_max[axis];
434                         }
435                         else {
436                                 vmin[axis] = bb_max[axis];
437                                 vmax[axis] = bb_min[axis];
438                         }
439                 }
440                 
441                 if(Inpf(planes[i], vmin) + planes[i][3] > 0)
442                         return 0;
443         } 
444
445         return 1;
446 }
447
448 static void cdDM_drawFacesSolid(DerivedMesh *dm,
449                                 float (*partial_redraw_planes)[4],
450                                 int (*setMaterial)(int, void *attribs))
451 {
452         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
453         MVert *mvert = cddm->mvert;
454         MFace *mface = cddm->mface;
455         float *nors= dm->getFaceDataArray(dm, CD_NORMAL);
456         int a, glmode = -1, shademodel = -1, matnr = -1, drawCurrentMat = 1;
457
458 #define PASSVERT(index) {                                               \
459         if(shademodel == GL_SMOOTH) {                           \
460                 short *no = mvert[index].no;                    \
461                 glNormal3sv(no);                                                \
462         }                                                                                       \
463         glVertex3fv(mvert[index].co);   \
464 }
465
466         if(cddm->pbvh) {
467                 float (*face_nors)[3] = CustomData_get_layer(&dm->faceData, CD_NORMAL);
468
469                 BLI_pbvh_update(cddm->pbvh, PBVH_UpdateNormals|PBVH_UpdateDrawBuffers,
470                         face_nors);
471
472                 /* should be per face */
473                 if(dm->numFaceData && mface->flag & ME_SMOOTH)
474                         glShadeModel(GL_SMOOTH);
475
476                 if(partial_redraw_planes) {
477                         BLI_pbvh_search_callback(cddm->pbvh, planes_contain_AABB,
478                                         partial_redraw_planes, draw_partial_cb, NULL);
479                 }
480                 else {
481                         BLI_pbvh_search_callback(cddm->pbvh, NULL, NULL,
482                                         draw_partial_cb, NULL);
483                 }
484
485                 is_partial = !!partial_redraw_planes;
486
487                 //printf("nodes drawn=%d\n", nodes_drawn);
488                 nodes_drawn = 0;
489
490                 glShadeModel(GL_FLAT);
491
492                 return;
493         }
494
495         if( GPU_buffer_legacy(dm) ) {
496                 DEBUG_VBO( "Using legacy code. cdDM_drawFacesSolid\n" );
497                 glBegin(glmode = GL_QUADS);
498                 for(a = 0; a < dm->numFaceData; a++, mface++) {
499                         int new_glmode, new_matnr, new_shademodel;
500
501                         new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES;
502                         new_matnr = mface->mat_nr + 1;
503                         new_shademodel = (mface->flag & ME_SMOOTH)?GL_SMOOTH:GL_FLAT;
504                         
505                         if(new_glmode != glmode || new_matnr != matnr
506                            || new_shademodel != shademodel) {
507                                 glEnd();
508
509                                 drawCurrentMat = setMaterial(matnr = new_matnr, NULL);
510
511                                 glShadeModel(shademodel = new_shademodel);
512                                 glBegin(glmode = new_glmode);
513                         } 
514                         
515                         if(drawCurrentMat) {
516                                 if(shademodel == GL_FLAT) {
517                                         if (nors) {
518                                                 glNormal3fv(nors);
519                                         }
520                                         else {
521                                                 /* TODO make this better (cache facenormals as layer?) */
522                                                 float nor[3];
523                                                 if(mface->v4) {
524                                                         CalcNormFloat4(mvert[mface->v1].co, mvert[mface->v2].co,
525                                                                                    mvert[mface->v3].co, mvert[mface->v4].co,
526                                                                                    nor);
527                                                 } else {
528                                                         CalcNormFloat(mvert[mface->v1].co, mvert[mface->v2].co,
529                                                                                   mvert[mface->v3].co, nor);
530                                                 }
531                                                 glNormal3fv(nor);
532                                         }
533                                 }
534
535                                 PASSVERT(mface->v1);
536                                 PASSVERT(mface->v2);
537                                 PASSVERT(mface->v3);
538                                 if(mface->v4) {
539                                         PASSVERT(mface->v4);
540                                 }
541                         }
542
543                         if(nors) nors += 3;
544                 }
545                 glEnd();
546         }
547         else {  /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
548                 GPU_vertex_setup( dm );
549                 GPU_normal_setup( dm );
550                 if( !GPU_buffer_legacy(dm) ) {
551                         glShadeModel(GL_SMOOTH);
552                         for( a = 0; a < dm->drawObject->nmaterials; a++ ) {
553                                 if( setMaterial(dm->drawObject->materials[a].mat_nr+1, NULL) )
554                                         glDrawArrays(GL_TRIANGLES, dm->drawObject->materials[a].start, dm->drawObject->materials[a].end-dm->drawObject->materials[a].start);
555                         }
556                 }
557                 GPU_buffer_unbind( );
558         }
559
560 #undef PASSVERT
561         glShadeModel(GL_FLAT);
562 }
563
564 static void cdDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *col1, unsigned char *col2)
565 {
566         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
567         int a, glmode;
568         unsigned char *cp1, *cp2;
569         MVert *mvert = cddm->mvert;
570         MFace *mface = cddm->mface;
571
572         cp1 = col1;
573         if(col2) {
574                 cp2 = col2;
575         } else {
576                 cp2 = NULL;
577                 useTwoSided = 0;
578         }
579
580         /* there's a conflict here... twosided colors versus culling...? */
581         /* defined by history, only texture faces have culling option */
582         /* we need that as mesh option builtin, next to double sided lighting */
583         if(col1 && col2)
584                 glEnable(GL_CULL_FACE);
585
586         if( GPU_buffer_legacy(dm) ) {
587                 DEBUG_VBO( "Using legacy code. cdDM_drawFacesColored\n" );
588                 glShadeModel(GL_SMOOTH);
589                 glBegin(glmode = GL_QUADS);
590                 for(a = 0; a < dm->numFaceData; a++, mface++, cp1 += 16) {
591                         int new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES;
592
593                         if(new_glmode != glmode) {
594                                 glEnd();
595                                 glBegin(glmode = new_glmode);
596                         }
597                                 
598                         glColor3ub(cp1[0], cp1[1], cp1[2]);
599                         glVertex3fv(mvert[mface->v1].co);
600                         glColor3ub(cp1[4], cp1[5], cp1[6]);
601                         glVertex3fv(mvert[mface->v2].co);
602                         glColor3ub(cp1[8], cp1[9], cp1[10]);
603                         glVertex3fv(mvert[mface->v3].co);
604                         if(mface->v4) {
605                                 glColor3ub(cp1[12], cp1[13], cp1[14]);
606                                 glVertex3fv(mvert[mface->v4].co);
607                         }
608                                 
609                         if(useTwoSided) {
610                                 glColor3ub(cp2[8], cp2[9], cp2[10]);
611                                 glVertex3fv(mvert[mface->v3].co );
612                                 glColor3ub(cp2[4], cp2[5], cp2[6]);
613                                 glVertex3fv(mvert[mface->v2].co );
614                                 glColor3ub(cp2[0], cp2[1], cp2[2]);
615                                 glVertex3fv(mvert[mface->v1].co );
616                                 if(mface->v4) {
617                                         glColor3ub(cp2[12], cp2[13], cp2[14]);
618                                         glVertex3fv(mvert[mface->v4].co );
619                                 }
620                         }
621                         if(col2) cp2 += 16;
622                 }
623                 glEnd();
624         }
625         else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
626                 GPU_color4_upload(dm,cp1);
627                 GPU_vertex_setup(dm);
628                 GPU_color_setup(dm);
629                 if( !GPU_buffer_legacy(dm) ) {
630                         glShadeModel(GL_SMOOTH);
631                         glDrawArrays(GL_TRIANGLES, 0, dm->drawObject->nelements);
632
633                         if( useTwoSided ) {
634                                 GPU_color4_upload(dm,cp2);
635                                 GPU_color_setup(dm);
636                                 glCullFace(GL_FRONT);
637                                 glDrawArrays(GL_TRIANGLES, 0, dm->drawObject->nelements);
638                                 glCullFace(GL_BACK);
639                         }
640                 }
641                 GPU_buffer_unbind();
642         }
643
644         glShadeModel(GL_FLAT);
645         glDisable(GL_CULL_FACE);
646 }
647
648 static void cdDM_drawFacesTex_common(DerivedMesh *dm,
649                int (*drawParams)(MTFace *tface, MCol *mcol, int matnr),
650                int (*drawParamsMapped)(void *userData, int index),
651                void *userData) 
652 {
653         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
654         MVert *mv = cddm->mvert;
655         MFace *mf = DM_get_face_data_layer(dm, CD_MFACE);
656         MCol *realcol = dm->getFaceDataArray(dm, CD_TEXTURE_MCOL);
657         float *nors= dm->getFaceDataArray(dm, CD_NORMAL);
658         MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
659         int i, j, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
660         int startFace = 0, lastFlag = 0xdeadbeef;
661         MCol *mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL);
662         if(!mcol)
663                 mcol = dm->getFaceDataArray(dm, CD_MCOL);
664
665         if( GPU_buffer_legacy(dm) ) {
666                 DEBUG_VBO( "Using legacy code. cdDM_drawFacesTex_common\n" );
667                 for(i = 0; i < dm->numFaceData; i++, mf++) {
668                         MVert *mvert;
669                         int flag;
670                         unsigned char *cp = NULL;
671
672                         if(drawParams) {
673                                 flag = drawParams(tf? &tf[i]: NULL, mcol? &mcol[i*4]: NULL, mf->mat_nr);
674                         }
675                         else {
676                                 if(index) {
677                                         orig = *index++;
678                                         if(orig == ORIGINDEX_NONE)              { if(nors) nors += 3; continue; }
679                                         if(drawParamsMapped) flag = drawParamsMapped(userData, orig);
680                                         else    { if(nors) nors += 3; continue; }
681                                 }
682                                 else
683                                         if(drawParamsMapped) flag = drawParamsMapped(userData, i);
684                                         else    { if(nors) nors += 3; continue; }
685                         }
686                         
687                         if(flag != 0) {
688                                 if (flag==1 && mcol)
689                                         cp= (unsigned char*) &mcol[i*4];
690
691                                 if(!(mf->flag&ME_SMOOTH)) {
692                                         if (nors) {
693                                                 glNormal3fv(nors);
694                                         }
695                                         else {
696                                                 float nor[3];
697                                                 if(mf->v4) {
698                                                         CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co,
699                                                                                    mv[mf->v3].co, mv[mf->v4].co,
700                                                                                    nor);
701                                                 } else {
702                                                         CalcNormFloat(mv[mf->v1].co, mv[mf->v2].co,
703                                                                                   mv[mf->v3].co, nor);
704                                                 }
705                                                 glNormal3fv(nor);
706                                         }
707                                 }
708
709                                 glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
710                                 if(tf) glTexCoord2fv(tf[i].uv[0]);
711                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
712                                 mvert = &mv[mf->v1];
713                                 if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
714                                 glVertex3fv(mvert->co);
715                                         
716                                 if(tf) glTexCoord2fv(tf[i].uv[1]);
717                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
718                                 mvert = &mv[mf->v2];
719                                 if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
720                                 glVertex3fv(mvert->co);
721
722                                 if(tf) glTexCoord2fv(tf[i].uv[2]);
723                                 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
724                                 mvert = &mv[mf->v3];
725                                 if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
726                                 glVertex3fv(mvert->co);
727
728                                 if(mf->v4) {
729                                         if(tf) glTexCoord2fv(tf[i].uv[3]);
730                                         if(cp) glColor3ub(cp[15], cp[14], cp[13]);
731                                         mvert = &mv[mf->v4];
732                                         if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
733                                         glVertex3fv(mvert->co);
734                                 }
735                                 glEnd();
736                         }
737                         
738                         if(nors) nors += 3;
739                 }
740         } else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
741                 MCol *col = realcol;
742                 if(!col)
743                         col = mcol;
744
745                 GPU_vertex_setup( dm );
746                 GPU_normal_setup( dm );
747                 GPU_uv_setup( dm );
748                 if( col != 0 ) {
749                         /*if( realcol && dm->drawObject->colType == CD_TEXTURE_MCOL )  {
750                                 col = 0;
751                         } else if( mcol && dm->drawObject->colType == CD_MCOL ) {
752                                 col = 0;
753                         }
754                         
755                         if( col != 0 ) {*/
756                                 unsigned char *colors = MEM_mallocN(dm->getNumFaces(dm)*4*3*sizeof(unsigned char), "cdDM_drawFacesTex_common");
757                                 for( i=0; i < dm->getNumFaces(dm); i++ ) {
758                                         for( j=0; j < 4; j++ ) {
759                                                 colors[i*12+j*3] = col[i*4+j].r;
760                                                 colors[i*12+j*3+1] = col[i*4+j].g;
761                                                 colors[i*12+j*3+2] = col[i*4+j].b;
762                                         }
763                                 }
764                                 GPU_color3_upload(dm,colors);
765                                 MEM_freeN(colors);
766                                 if(realcol)
767                                         dm->drawObject->colType = CD_TEXTURE_MCOL;
768                                 else if(mcol)
769                                         dm->drawObject->colType = CD_MCOL;
770                         //}
771                         GPU_color_setup( dm );
772                 }
773
774                 if( !GPU_buffer_legacy(dm) ) {
775                         glShadeModel( GL_SMOOTH );
776                         for(i = 0; i < dm->drawObject->nelements/3; i++) {
777                                 int actualFace = dm->drawObject->faceRemap[i];
778                                 int flag = 1;
779
780                                 if(drawParams) {
781                                         flag = drawParams(tf? &tf[actualFace]: NULL, mcol? &mcol[actualFace*4]: NULL, mf[actualFace].mat_nr);
782                                 }
783                                 else {
784                                         if(index) {
785                                                 orig = index[actualFace];
786                                                 if(drawParamsMapped)
787                                                         flag = drawParamsMapped(userData, orig);
788                                         }
789                                         else
790                                                 if(drawParamsMapped)
791                                                         flag = drawParamsMapped(userData, actualFace);
792                                 }
793                                 if( flag != lastFlag ) {
794                                         if( startFace < i ) {
795                                                 if( lastFlag != 0 ) { /* if the flag is 0 it means the face is hidden or invisible */
796                                                         if (lastFlag==1 && mcol)
797                                                                 GPU_color_switch(1);
798                                                         else
799                                                                 GPU_color_switch(0);
800                                                         glDrawArrays(GL_TRIANGLES,startFace*3,(i-startFace)*3);
801                                                 }
802                                         }
803                                         lastFlag = flag;
804                                         startFace = i;
805                                 }
806                         }
807                         if( startFace < dm->drawObject->nelements/3 ) {
808                                 if( lastFlag != 0 ) { /* if the flag is 0 it means the face is hidden or invisible */
809                                         if (lastFlag==1 && mcol)
810                                                 GPU_color_switch(1);
811                                         else
812                                                 GPU_color_switch(0);
813                                         glDrawArrays(GL_TRIANGLES,startFace*3,dm->drawObject->nelements-startFace*3);
814                                 }
815                         }
816                 }
817
818                 GPU_buffer_unbind();
819                 glShadeModel( GL_FLAT );
820         }
821 }
822
823 static void cdDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr))
824 {
825         cdDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
826 }
827
828 static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors)
829 {
830         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
831         MVert *mv = cddm->mvert;
832         MFace *mf = cddm->mface;
833         MCol *mc;
834         float *nors= dm->getFaceDataArray(dm, CD_NORMAL);
835         int i, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
836
837
838         mc = DM_get_face_data_layer(dm, CD_ID_MCOL);
839         if(!mc)
840                 mc = DM_get_face_data_layer(dm, CD_WEIGHT_MCOL);
841         if(!mc)
842                 mc = DM_get_face_data_layer(dm, CD_MCOL);
843
844         if( GPU_buffer_legacy(dm) ) {
845                 DEBUG_VBO( "Using legacy code. cdDM_drawMappedFaces\n" );
846                 for(i = 0; i < dm->numFaceData; i++, mf++) {
847                         int drawSmooth = (mf->flag & ME_SMOOTH);
848
849                         if(index) {
850                                 orig = *index++;
851                                 if(setDrawOptions && orig == ORIGINDEX_NONE)
852                                         { if(nors) nors += 3; continue; }
853                         }
854                         else
855                                 orig = i;
856
857                         if(!setDrawOptions || setDrawOptions(userData, orig, &drawSmooth)) {
858                                 unsigned char *cp = NULL;
859
860                                 if(useColors && mc)
861                                         cp = (unsigned char *)&mc[i * 4];
862
863                                 glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
864                                 glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
865
866                                 if (!drawSmooth) {
867                                         if (nors) {
868                                                 glNormal3fv(nors);
869                                         }
870                                         else {
871                                                 float nor[3];
872                                                 if(mf->v4) {
873                                                         CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co,
874                                                                                    mv[mf->v3].co, mv[mf->v4].co,
875                                                                                    nor);
876                                                 } else {
877                                                         CalcNormFloat(mv[mf->v1].co, mv[mf->v2].co,
878                                                                                   mv[mf->v3].co, nor);
879                                                 }
880                                                 glNormal3fv(nor);
881                                         }
882
883                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
884                                         glVertex3fv(mv[mf->v1].co);
885                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
886                                         glVertex3fv(mv[mf->v2].co);
887                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
888                                         glVertex3fv(mv[mf->v3].co);
889                                         if(mf->v4) {
890                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
891                                                 glVertex3fv(mv[mf->v4].co);
892                                         }
893                                 } else {
894                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
895                                         glNormal3sv(mv[mf->v1].no);
896                                         glVertex3fv(mv[mf->v1].co);
897                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
898                                         glNormal3sv(mv[mf->v2].no);
899                                         glVertex3fv(mv[mf->v2].co);
900                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
901                                         glNormal3sv(mv[mf->v3].no);
902                                         glVertex3fv(mv[mf->v3].co);
903                                         if(mf->v4) {
904                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
905                                                 glNormal3sv(mv[mf->v4].no);
906                                                 glVertex3fv(mv[mf->v4].co);
907                                         }
908                                 }
909
910                                 glEnd();
911                         }
912                         
913                         if (nors) nors += 3;
914                 }
915         }
916         else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
917                 int state = 1;
918                 int prevstate = 1;
919                 int prevstart = 0;
920                 GPU_vertex_setup(dm);
921                 GPU_normal_setup(dm);
922                 if( useColors && mc )
923                         GPU_color_setup(dm);
924                 if( !GPU_buffer_legacy(dm) ) {
925                         glShadeModel(GL_SMOOTH);
926                         for( i = 0; i < dm->drawObject->nelements/3; i++ ) {
927                                 int actualFace = dm->drawObject->faceRemap[i];
928                                 int drawSmooth = (mf[actualFace].flag & ME_SMOOTH);
929                                 int dontdraw = 0;
930                                 if(index) {
931                                         orig = index[actualFace];
932                                         if(setDrawOptions && orig == ORIGINDEX_NONE)
933                                                 dontdraw = 1;
934                                 }
935                                 else
936                                         orig = i;
937                                 if( dontdraw ) {
938                                         state = 0;
939                                 }
940                                 else {
941                                         if(!setDrawOptions || setDrawOptions(userData, orig, &drawSmooth)) {
942                                                 state = 1;
943                                         }
944                                         else {
945                                                 state = 0;
946                                         }
947                                 }
948                                 if( prevstate != state && prevstate == 1 ) {
949                                         if( i-prevstart > 0 ) {
950                                                 glDrawArrays(GL_TRIANGLES,prevstart*3,(i-prevstart)*3);
951                                         }
952                                         prevstart = i;
953                                 }
954                                 prevstate = state;
955                         }
956                         if(state==1) {
957                                 glDrawArrays(GL_TRIANGLES,prevstart*3,dm->drawObject->nelements-prevstart*3);
958                         }
959                         glShadeModel(GL_FLAT);
960                 }
961                 GPU_buffer_unbind();
962         }
963 }
964
965 static void cdDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
966 {
967         cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
968 }
969
970 static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs), int (*setDrawOptions)(void *userData, int index), void *userData)
971 {
972         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
973         GPUVertexAttribs gattribs;
974         DMVertexAttribs attribs;
975         MVert *mvert = cddm->mvert;
976         MFace *mface = cddm->mface;
977         MTFace *tf = dm->getFaceDataArray(dm, CD_MTFACE);
978         float (*nors)[3] = dm->getFaceDataArray(dm, CD_NORMAL);
979         int a, b, dodraw, smoothnormal, matnr, new_matnr;
980         int transp, new_transp, orig_transp;
981         int orig, *index = dm->getFaceDataArray(dm, CD_ORIGINDEX);
982
983         matnr = -1;
984         smoothnormal = 0;
985         dodraw = 0;
986         transp = GPU_get_material_blend_mode();
987         orig_transp = transp;
988
989         glShadeModel(GL_SMOOTH);
990
991         if( GPU_buffer_legacy(dm) || setDrawOptions != 0 ) {
992                 DEBUG_VBO( "Using legacy code. cdDM_drawMappedFacesGLSL\n" );
993                 memset(&attribs, 0, sizeof(attribs));
994
995                 glBegin(GL_QUADS);
996
997                 for(a = 0; a < dm->numFaceData; a++, mface++) {
998                         new_matnr = mface->mat_nr + 1;
999
1000                         if(new_matnr != matnr) {
1001                                 glEnd();
1002
1003                                 dodraw = setMaterial(matnr = new_matnr, &gattribs);
1004                                 if(dodraw)
1005                                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1006
1007                                 glBegin(GL_QUADS);
1008                         }
1009
1010                         if(!dodraw) {
1011                                 continue;
1012                         }
1013                         else if(setDrawOptions) {
1014                                 orig = (index)? index[a]: a;
1015
1016                                 if(orig == ORIGINDEX_NONE)
1017                                         continue;
1018                                 else if(!setDrawOptions(userData, orig))
1019                                         continue;
1020                         }
1021
1022                         if(tf) {
1023                                 new_transp = tf[a].transp;
1024
1025                                 if(new_transp != transp) {
1026                                         glEnd();
1027
1028                                         if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
1029                                                 GPU_set_material_blend_mode(orig_transp);
1030                                         else
1031                                                 GPU_set_material_blend_mode(new_transp);
1032                                         transp = new_transp;
1033
1034                                         glBegin(GL_QUADS);
1035                                 }
1036                         }
1037
1038                         smoothnormal = (mface->flag & ME_SMOOTH);
1039
1040                         if(!smoothnormal) {
1041                                 if(nors) {
1042                                         glNormal3fv(nors[a]);
1043                                 }
1044                                 else {
1045                                         /* TODO ideally a normal layer should always be available */
1046                                         float nor[3];
1047                                         if(mface->v4) {
1048                                                 CalcNormFloat4(mvert[mface->v1].co, mvert[mface->v2].co,
1049                                                                            mvert[mface->v3].co, mvert[mface->v4].co,
1050                                                                            nor);
1051                                         } else {
1052                                                 CalcNormFloat(mvert[mface->v1].co, mvert[mface->v2].co,
1053                                                                           mvert[mface->v3].co, nor);
1054                                         }
1055                                         glNormal3fv(nor);
1056                                 }
1057                         }
1058
1059 #define PASSVERT(index, vert) {                                                                                                 \
1060                 if(attribs.totorco)                                                                                                                     \
1061                         glVertexAttrib3fvARB(attribs.orco.glIndex, attribs.orco.array[index]);  \
1062                 for(b = 0; b < attribs.tottface; b++) {                                                                         \
1063                         MTFace *tf = &attribs.tface[b].array[a];                                                                \
1064                         glVertexAttrib2fvARB(attribs.tface[b].glIndex, tf->uv[vert]);                   \
1065                 }                                                                                                                                                       \
1066                 for(b = 0; b < attribs.totmcol; b++) {                                                                          \
1067                         MCol *cp = &attribs.mcol[b].array[a*4 + vert];                                                  \
1068                         GLubyte col[4];                                                                                                                 \
1069                         col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;                             \
1070                         glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col);                                    \
1071                 }                                                                                                                                                       \
1072                 if(attribs.tottang) {                                                                                                           \
1073                         float *tang = attribs.tang.array[a*4 + vert];                                                   \
1074                         glVertexAttrib3fvARB(attribs.tang.glIndex, tang);                                               \
1075                 }                                                                                                                                                       \
1076                 if(smoothnormal)                                                                                                                        \
1077                         glNormal3sv(mvert[index].no);                                                                                   \
1078                 glVertex3fv(mvert[index].co);                                                                                           \
1079         }
1080
1081                         PASSVERT(mface->v1, 0);
1082                         PASSVERT(mface->v2, 1);
1083                         PASSVERT(mface->v3, 2);
1084                         if(mface->v4)
1085                                 PASSVERT(mface->v4, 3)
1086                         else
1087                                 PASSVERT(mface->v3, 2)
1088
1089 #undef PASSVERT
1090                 }
1091                 glEnd();
1092         }
1093         else {
1094                 GPUBuffer *buffer = 0;
1095                 char *varray = 0;
1096                 int numdata = 0, elementsize = 0, offset;
1097                 int start = 0, numfaces = 0, prevdraw = 0, curface = 0;
1098                 GPUAttrib datatypes[32];
1099                 memset(&attribs, 0, sizeof(attribs));
1100
1101                 GPU_vertex_setup(dm);
1102                 GPU_normal_setup(dm);
1103
1104                 if( !GPU_buffer_legacy(dm) ) {
1105                         for(a = 0; a < dm->numFaceData; a++, mface++) {
1106                                 new_matnr = mface->mat_nr + 1;
1107
1108                                 if(new_matnr != matnr ) {
1109                                         numfaces = curface - start;
1110                                         if( numfaces > 0 ) {
1111                                                 if( prevdraw ) {
1112                                                         GPU_buffer_unlock(buffer);
1113                                                         GPU_interleaved_attrib_setup(buffer,datatypes,numdata);
1114                                                         glDrawArrays(GL_TRIANGLES,start*3,numfaces*3);
1115                                                         GPU_buffer_free(buffer,0);
1116                                                 }
1117                                         }
1118                                         start = curface;
1119                                         prevdraw = dodraw;
1120                                         dodraw = setMaterial(matnr = new_matnr, &gattribs);
1121                                         if(dodraw) {
1122                                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1123
1124                                                 if(attribs.totorco) {
1125                                                         datatypes[numdata].index = attribs.orco.glIndex;
1126                                                         datatypes[numdata].size = 3;
1127                                                         datatypes[numdata].type = GL_FLOAT;
1128                                                         numdata++;
1129                                                 }
1130                                                 for(b = 0; b < attribs.tottface; b++) {
1131                                                         datatypes[numdata].index = attribs.tface[b].glIndex;
1132                                                         datatypes[numdata].size = 2;
1133                                                         datatypes[numdata].type = GL_FLOAT;
1134                                                         numdata++;
1135                                                 }       
1136                                                 for(b = 0; b < attribs.totmcol; b++) {
1137                                                         datatypes[numdata].index = attribs.mcol[b].glIndex;
1138                                                         datatypes[numdata].size = 4;
1139                                                         datatypes[numdata].type = GL_UNSIGNED_BYTE;
1140                                                         numdata++;
1141                                                 }       
1142                                                 if(attribs.tottang) {
1143                                                         datatypes[numdata].index = attribs.tang.glIndex;
1144                                                         datatypes[numdata].size = 3;
1145                                                         datatypes[numdata].type = GL_FLOAT;
1146                                                         numdata++;
1147                                                 }
1148                                                 if( numdata != 0 ) {
1149                                                         elementsize = GPU_attrib_element_size( datatypes, numdata );
1150                                                         buffer = GPU_buffer_alloc( elementsize*dm->drawObject->nelements, 0 );
1151                                                         if( buffer == 0 ) {
1152                                                                 GPU_buffer_unbind();
1153                                                                 dm->drawObject->legacy = 1;
1154                                                                 return;
1155                                                         }
1156                                                         varray = GPU_buffer_lock_stream(buffer);
1157                                                         if( varray == 0 ) {
1158                                                                 GPU_buffer_unbind();
1159                                                                 GPU_buffer_free(buffer, 0);
1160                                                                 dm->drawObject->legacy = 1;
1161                                                                 return;
1162                                                         }
1163                                                 }
1164                                         }
1165                                 }
1166                                 if(!dodraw) {
1167                                         continue;
1168                                 }
1169
1170                                 if(tf) {
1171                                         new_transp = tf[a].transp;
1172
1173                                         if(new_transp != transp) {
1174                                                 numfaces = curface - start;
1175                                                 if( numfaces > 0 ) {
1176                                                         if( dodraw ) {
1177                                                                 if( numdata != 0 ) {
1178                                                                         GPU_buffer_unlock(buffer);
1179                                                                         GPU_interleaved_attrib_setup(buffer,datatypes,numdata);
1180                                                                 }
1181                                                                 glDrawArrays(GL_TRIANGLES,start*3,(curface-start)*3);
1182                                                                 if( numdata != 0 ) {
1183                                                                         varray = GPU_buffer_lock_stream(buffer);
1184                                                                 }
1185                                                         }
1186                                                 }
1187                                                 start = curface;
1188
1189                                                 if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
1190                                                         GPU_set_material_blend_mode(orig_transp);
1191                                                 else
1192                                                         GPU_set_material_blend_mode(new_transp);
1193                                                 transp = new_transp;
1194                                         }
1195                                 }
1196                                 
1197                                 if( numdata != 0 ) {
1198                                         offset = 0;
1199                                         if(attribs.totorco) {
1200                                                 VECCOPY((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v1]);
1201                                                 VECCOPY((float *)&varray[elementsize*curface*3+elementsize],(float *)attribs.orco.array[mface->v2]);
1202                                                 VECCOPY((float *)&varray[elementsize*curface*3+elementsize*2],(float *)attribs.orco.array[mface->v3]);
1203                                                 offset += sizeof(float)*3;
1204                                         }
1205                                         for(b = 0; b < attribs.tottface; b++) {
1206                                                 MTFace *tf = &attribs.tface[b].array[a];
1207                                                 VECCOPY((float *)&varray[elementsize*curface*3+offset],tf->uv[0]);
1208                                                 VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize],tf->uv[1]);
1209                                                 VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize*2],tf->uv[2]);
1210                                                 offset += sizeof(float)*2;
1211                                         }
1212                                         for(b = 0; b < attribs.totmcol; b++) {
1213                                                 MCol *cp = &attribs.mcol[b].array[a*4 + 0];
1214                                                 GLubyte col[4];
1215                                                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1216                                                 QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset], col);
1217                                                 cp = &attribs.mcol[b].array[a*4 + 1];
1218                                                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1219                                                 QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset+elementsize], col);
1220                                                 cp = &attribs.mcol[b].array[a*4 + 2];
1221                                                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1222                                                 QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset+elementsize*2], col);
1223                                                 offset += sizeof(unsigned char)*4;
1224                                         }       
1225                                         if(attribs.tottang) {
1226                                                 float *tang = attribs.tang.array[a*4 + 0];
1227                                                 VECCOPY((float *)&varray[elementsize*curface*3+offset], tang);
1228                                                 tang = attribs.tang.array[a*4 + 1];
1229                                                 VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize], tang);
1230                                                 tang = attribs.tang.array[a*4 + 2];
1231                                                 VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize], tang);
1232                                                 offset += sizeof(float)*3;
1233                                         }
1234                                 }
1235                                 curface++;
1236                                 if(mface->v4) {
1237                                         if( numdata != 0 ) {
1238                                                 offset = 0;
1239                                                 if(attribs.totorco) {
1240                                                         VECCOPY((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v3]);
1241                                                         VECCOPY((float *)&varray[elementsize*curface*3+elementsize],(float *)attribs.orco.array[mface->v4]);
1242                                                         VECCOPY((float *)&varray[elementsize*curface*3+elementsize*2],(float *)attribs.orco.array[mface->v1]);
1243                                                         offset += sizeof(float)*3;
1244                                                 }
1245                                                 for(b = 0; b < attribs.tottface; b++) {
1246                                                         MTFace *tf = &attribs.tface[b].array[a];
1247                                                         VECCOPY((float *)&varray[elementsize*curface*3+offset],tf->uv[2]);
1248                                                         VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize],tf->uv[3]);
1249                                                         VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize*2],tf->uv[0]);
1250                                                         offset += sizeof(float)*2;
1251                                                 }
1252                                                 for(b = 0; b < attribs.totmcol; b++) {
1253                                                         MCol *cp = &attribs.mcol[b].array[a*4 + 2];
1254                                                         GLubyte col[4];
1255                                                         col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1256                                                         QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset], col);
1257                                                         cp = &attribs.mcol[b].array[a*4 + 3];
1258                                                         col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1259                                                         QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset+elementsize], col);
1260                                                         cp = &attribs.mcol[b].array[a*4 + 0];
1261                                                         col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1262                                                         QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset+elementsize*2], col);
1263                                                         offset += sizeof(unsigned char)*4;
1264                                                 }       
1265                                                 if(attribs.tottang) {
1266                                                         float *tang = attribs.tang.array[a*4 + 2];
1267                                                         VECCOPY((float *)&varray[elementsize*curface*3+offset], tang);
1268                                                         tang = attribs.tang.array[a*4 + 3];
1269                                                         VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize], tang);
1270                                                         tang = attribs.tang.array[a*4 + 0];
1271                                                         VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize], tang);
1272                                                         offset += sizeof(float)*3;
1273                                                 }
1274                                         }
1275                                         curface++;
1276                                 }
1277                         }
1278                         numfaces = curface - start;
1279                         if( numfaces > 0 ) {
1280                                 if( dodraw ) {
1281                                         if( numdata != 0 ) {
1282                                                 GPU_buffer_unlock(buffer);
1283                                                 GPU_interleaved_attrib_setup(buffer,datatypes,numdata);
1284                                         }
1285                                         glDrawArrays(GL_TRIANGLES,start*3,(curface-start)*3);
1286                                 }
1287                         }
1288                         GPU_buffer_unbind();
1289                 }
1290                 GPU_buffer_free( buffer, 0 );
1291         }
1292
1293         glShadeModel(GL_FLAT);
1294 }
1295
1296 static void cdDM_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs))
1297 {
1298         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1299 }
1300
1301 static void cdDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
1302 {
1303         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
1304         MVert *vert = cddm->mvert;
1305         MEdge *edge = cddm->medge;
1306         int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1307
1308         glBegin(GL_LINES);
1309         for(i = 0; i < dm->numEdgeData; i++, edge++) {
1310                 if(index) {
1311                         orig = *index++;
1312                         if(setDrawOptions && orig == ORIGINDEX_NONE) continue;
1313                 }
1314                 else
1315                         orig = i;
1316
1317                 if(!setDrawOptions || setDrawOptions(userData, orig)) {
1318                         glVertex3fv(vert[edge->v1].co);
1319                         glVertex3fv(vert[edge->v2].co);
1320                 }
1321         }
1322         glEnd();
1323 }
1324
1325 static void cdDM_foreachMappedVert(
1326                            DerivedMesh *dm,
1327                            void (*func)(void *userData, int index, float *co,
1328                                         float *no_f, short *no_s),
1329                            void *userData)
1330 {
1331         MVert *mv = CDDM_get_verts(dm);
1332         int i, orig, *index = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
1333
1334         for(i = 0; i < dm->numVertData; i++, mv++) {
1335                 if(index) {
1336                         orig = *index++;
1337                         if(orig == ORIGINDEX_NONE) continue;
1338                         func(userData, orig, mv->co, NULL, mv->no);
1339                 }
1340                 else
1341                         func(userData, i, mv->co, NULL, mv->no);
1342         }
1343 }
1344
1345 static void cdDM_foreachMappedEdge(
1346                            DerivedMesh *dm,
1347                            void (*func)(void *userData, int index,
1348                                         float *v0co, float *v1co),
1349                            void *userData)
1350 {
1351         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
1352         MVert *mv = cddm->mvert;
1353         MEdge *med = cddm->medge;
1354         int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1355
1356         for(i = 0; i < dm->numEdgeData; i++, med++) {
1357                 if (index) {
1358                         orig = *index++;
1359                         if(orig == ORIGINDEX_NONE) continue;
1360                         func(userData, orig, mv[med->v1].co, mv[med->v2].co);
1361                 }
1362                 else
1363                         func(userData, i, mv[med->v1].co, mv[med->v2].co);
1364         }
1365 }
1366
1367 static void cdDM_foreachMappedFaceCenter(
1368                            DerivedMesh *dm,
1369                            void (*func)(void *userData, int index,
1370                                         float *cent, float *no),
1371                            void *userData)
1372 {
1373         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1374         MVert *mv = cddm->mvert;
1375         MFace *mf = cddm->mface;
1376         int i, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
1377
1378         for(i = 0; i < dm->numFaceData; i++, mf++) {
1379                 float cent[3];
1380                 float no[3];
1381
1382                 if (index) {
1383                         orig = *index++;
1384                         if(orig == ORIGINDEX_NONE) continue;
1385                 }
1386                 else
1387                         orig = i;
1388
1389                 VECCOPY(cent, mv[mf->v1].co);
1390                 VecAddf(cent, cent, mv[mf->v2].co);
1391                 VecAddf(cent, cent, mv[mf->v3].co);
1392
1393                 if (mf->v4) {
1394                         CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co,
1395                                        mv[mf->v3].co, mv[mf->v4].co, no);
1396                         VecAddf(cent, cent, mv[mf->v4].co);
1397                         VecMulf(cent, 0.25f);
1398                 } else {
1399                         CalcNormFloat(mv[mf->v1].co, mv[mf->v2].co,
1400                                       mv[mf->v3].co, no);
1401                         VecMulf(cent, 0.33333333333f);
1402                 }
1403
1404                 func(userData, orig, cent, no);
1405         }
1406 }
1407
1408 static void cdDM_free_internal(CDDerivedMesh *cddm)
1409 {
1410         if(cddm->pbvh) BLI_pbvh_free(cddm->pbvh);
1411         if(cddm->fmap) MEM_freeN(cddm->fmap);
1412         if(cddm->fmap_mem) MEM_freeN(cddm->fmap_mem);
1413 }
1414
1415 static void cdDM_release(DerivedMesh *dm)
1416 {
1417         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1418
1419         if (DM_release(dm)) {
1420                 cdDM_free_internal(cddm);
1421                 MEM_freeN(cddm);
1422         }
1423 }
1424
1425 /**************** CDDM interface functions ****************/
1426 static CDDerivedMesh *cdDM_create(const char *desc)
1427 {
1428         CDDerivedMesh *cddm;
1429         DerivedMesh *dm;
1430
1431         cddm = MEM_callocN(sizeof(*cddm), desc);
1432         dm = &cddm->dm;
1433
1434         dm->getMinMax = cdDM_getMinMax;
1435
1436         dm->getNumVerts = cdDM_getNumVerts;
1437         dm->getNumFaces = cdDM_getNumFaces;
1438         dm->getNumEdges = cdDM_getNumEdges;
1439
1440         dm->getVert = cdDM_getVert;
1441         dm->getEdge = cdDM_getEdge;
1442         dm->getFace = cdDM_getFace;
1443         dm->copyVertArray = cdDM_copyVertArray;
1444         dm->copyEdgeArray = cdDM_copyEdgeArray;
1445         dm->copyFaceArray = cdDM_copyFaceArray;
1446         dm->getVertData = DM_get_vert_data;
1447         dm->getEdgeData = DM_get_edge_data;
1448         dm->getFaceData = DM_get_face_data;
1449         dm->getVertDataArray = DM_get_vert_data_layer;
1450         dm->getEdgeDataArray = DM_get_edge_data_layer;
1451         dm->getFaceDataArray = DM_get_face_data_layer;
1452
1453         dm->getVertCos = cdDM_getVertCos;
1454         dm->getVertCo = cdDM_getVertCo;
1455         dm->getVertNo = cdDM_getVertNo;
1456
1457         dm->getPBVH = cdDM_getPBVH;
1458         dm->getFaceMap = cdDM_getFaceMap;
1459
1460         dm->drawVerts = cdDM_drawVerts;
1461
1462         dm->drawUVEdges = cdDM_drawUVEdges;
1463         dm->drawEdges = cdDM_drawEdges;
1464         dm->drawLooseEdges = cdDM_drawLooseEdges;
1465         dm->drawMappedEdges = cdDM_drawMappedEdges;
1466
1467         dm->drawFacesSolid = cdDM_drawFacesSolid;
1468         dm->drawFacesColored = cdDM_drawFacesColored;
1469         dm->drawFacesTex = cdDM_drawFacesTex;
1470         dm->drawFacesGLSL = cdDM_drawFacesGLSL;
1471         dm->drawMappedFaces = cdDM_drawMappedFaces;
1472         dm->drawMappedFacesTex = cdDM_drawMappedFacesTex;
1473         dm->drawMappedFacesGLSL = cdDM_drawMappedFacesGLSL;
1474
1475         dm->foreachMappedVert = cdDM_foreachMappedVert;
1476         dm->foreachMappedEdge = cdDM_foreachMappedEdge;
1477         dm->foreachMappedFaceCenter = cdDM_foreachMappedFaceCenter;
1478
1479         dm->release = cdDM_release;
1480
1481         return cddm;
1482 }
1483
1484 DerivedMesh *CDDM_new(int numVerts, int numEdges, int numFaces)
1485 {
1486         CDDerivedMesh *cddm = cdDM_create("CDDM_new dm");
1487         DerivedMesh *dm = &cddm->dm;
1488
1489         DM_init(dm, numVerts, numEdges, numFaces);
1490
1491         CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
1492         CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
1493         CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numFaces);
1494
1495         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
1496         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
1497         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numFaces);
1498
1499         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1500         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1501         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1502
1503         return dm;
1504 }
1505
1506 DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *ob)
1507 {
1508         CDDerivedMesh *cddm = cdDM_create("CDDM_from_mesh dm");
1509         DerivedMesh *dm = &cddm->dm;
1510         CustomDataMask mask = CD_MASK_MESH & (~CD_MASK_MDISPS);
1511         int alloctype;
1512
1513         /* this does a referenced copy, with an exception for fluidsim */
1514
1515         DM_init(dm, mesh->totvert, mesh->totedge, mesh->totface);
1516
1517         dm->deformedOnly = 1;
1518
1519         alloctype= CD_REFERENCE;
1520
1521         CustomData_merge(&mesh->vdata, &dm->vertData, mask, alloctype,
1522                          mesh->totvert);
1523         CustomData_merge(&mesh->edata, &dm->edgeData, mask, alloctype,
1524                          mesh->totedge);
1525         CustomData_merge(&mesh->fdata, &dm->faceData, mask, alloctype,
1526                          mesh->totface);
1527
1528         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1529         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1530         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1531
1532         return dm;
1533 }
1534
1535 DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
1536 {
1537         DerivedMesh *dm = CDDM_new(BLI_countlist(&em->verts),
1538                                    BLI_countlist(&em->edges),
1539                                    BLI_countlist(&em->faces));
1540         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1541         EditVert *eve;
1542         EditEdge *eed;
1543         EditFace *efa;
1544         MVert *mvert = cddm->mvert;
1545         MEdge *medge = cddm->medge;
1546         MFace *mface = cddm->mface;
1547         int i, *index;
1548
1549         dm->deformedOnly = 1;
1550
1551         CustomData_merge(&em->vdata, &dm->vertData, CD_MASK_DERIVEDMESH,
1552                          CD_CALLOC, dm->numVertData);
1553         /* CustomData_merge(&em->edata, &dm->edgeData, CD_MASK_DERIVEDMESH,
1554                          CD_CALLOC, dm->numEdgeData); */
1555         CustomData_merge(&em->fdata, &dm->faceData, CD_MASK_DERIVEDMESH,
1556                          CD_CALLOC, dm->numFaceData);
1557
1558         /* set eve->hash to vert index */
1559         for(i = 0, eve = em->verts.first; eve; eve = eve->next, ++i)
1560                 eve->tmp.l = i;
1561
1562         /* Need to be able to mark loose edges */
1563         for(eed = em->edges.first; eed; eed = eed->next) {
1564                 eed->f2 = 0;
1565         }
1566         for(efa = em->faces.first; efa; efa = efa->next) {
1567                 efa->e1->f2 = 1;
1568                 efa->e2->f2 = 1;
1569                 efa->e3->f2 = 1;
1570                 if(efa->e4) efa->e4->f2 = 1;
1571         }
1572
1573         index = dm->getVertDataArray(dm, CD_ORIGINDEX);
1574         for(i = 0, eve = em->verts.first; i < dm->numVertData;
1575             i++, eve = eve->next, index++) {
1576                 MVert *mv = &mvert[i];
1577
1578                 VECCOPY(mv->co, eve->co);
1579
1580                 mv->no[0] = eve->no[0] * 32767.0;
1581                 mv->no[1] = eve->no[1] * 32767.0;
1582                 mv->no[2] = eve->no[2] * 32767.0;
1583                 mv->bweight = (unsigned char) (eve->bweight * 255.0f);
1584
1585                 mv->mat_nr = 0;
1586                 mv->flag = 0;
1587
1588                 *index = i;
1589
1590                 CustomData_from_em_block(&em->vdata, &dm->vertData, eve->data, i);
1591         }
1592
1593         index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
1594         for(i = 0, eed = em->edges.first; i < dm->numEdgeData;
1595             i++, eed = eed->next, index++) {
1596                 MEdge *med = &medge[i];
1597
1598                 med->v1 = eed->v1->tmp.l;
1599                 med->v2 = eed->v2->tmp.l;
1600                 med->crease = (unsigned char) (eed->crease * 255.0f);
1601                 med->bweight = (unsigned char) (eed->bweight * 255.0f);
1602                 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
1603                 
1604                 if(eed->seam) med->flag |= ME_SEAM;
1605                 if(eed->sharp) med->flag |= ME_SHARP;
1606                 if(!eed->f2) med->flag |= ME_LOOSEEDGE;
1607
1608                 *index = i;
1609
1610                 /* CustomData_from_em_block(&em->edata, &dm->edgeData, eed->data, i); */
1611         }
1612
1613         index = dm->getFaceDataArray(dm, CD_ORIGINDEX);
1614         for(i = 0, efa = em->faces.first; i < dm->numFaceData;
1615             i++, efa = efa->next, index++) {
1616                 MFace *mf = &mface[i];
1617
1618                 mf->v1 = efa->v1->tmp.l;
1619                 mf->v2 = efa->v2->tmp.l;
1620                 mf->v3 = efa->v3->tmp.l;
1621                 mf->v4 = efa->v4 ? efa->v4->tmp.l : 0;
1622                 mf->mat_nr = efa->mat_nr;
1623                 mf->flag = efa->flag;
1624
1625                 *index = i;
1626
1627                 CustomData_from_em_block(&em->fdata, &dm->faceData, efa->data, i);
1628                 test_index_face(mf, &dm->faceData, i, efa->v4?4:3);
1629         }
1630
1631         return dm;
1632 }
1633
1634 DerivedMesh *CDDM_copy(DerivedMesh *source)
1635 {
1636         CDDerivedMesh *cddm = cdDM_create("CDDM_copy cddm");
1637         DerivedMesh *dm = &cddm->dm;
1638         int numVerts = source->numVertData;
1639         int numEdges = source->numEdgeData;
1640         int numFaces = source->numFaceData;
1641
1642         /* this initializes dm, and copies all non mvert/medge/mface layers */
1643         DM_from_template(dm, source, numVerts, numEdges, numFaces);
1644         dm->deformedOnly = source->deformedOnly;
1645
1646         CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts);
1647         CustomData_copy_data(&source->edgeData, &dm->edgeData, 0, 0, numEdges);
1648         CustomData_copy_data(&source->faceData, &dm->faceData, 0, 0, numFaces);
1649
1650         /* now add mvert/medge/mface layers */
1651         cddm->mvert = source->dupVertArray(source);
1652         cddm->medge = source->dupEdgeArray(source);
1653         cddm->mface = source->dupFaceArray(source);
1654
1655         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, cddm->mvert, numVerts);
1656         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, cddm->medge, numEdges);
1657         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, cddm->mface, numFaces);
1658
1659         return dm;
1660 }
1661
1662 DerivedMesh *CDDM_from_template(DerivedMesh *source,
1663                                 int numVerts, int numEdges, int numFaces)
1664 {
1665         CDDerivedMesh *cddm = cdDM_create("CDDM_from_template dest");
1666         DerivedMesh *dm = &cddm->dm;
1667
1668         /* this does a copy of all non mvert/medge/mface layers */
1669         DM_from_template(dm, source, numVerts, numEdges, numFaces);
1670
1671         /* now add mvert/medge/mface layers */
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
1676         if(!CustomData_get_layer(&dm->vertData, CD_ORIGINDEX))
1677                 CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
1678         if(!CustomData_get_layer(&dm->edgeData, CD_ORIGINDEX))
1679                 CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
1680         if(!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX))
1681                 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numFaces);
1682
1683         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1684         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1685         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1686
1687         return dm;
1688 }
1689
1690 void CDDM_apply_vert_coords(DerivedMesh *dm, float (*vertCoords)[3])
1691 {
1692         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1693         MVert *vert;
1694         int i;
1695
1696         /* this will just return the pointer if it wasn't a referenced layer */
1697         vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
1698         cddm->mvert = vert;
1699
1700         for(i = 0; i < dm->numVertData; ++i, ++vert)
1701                 VECCOPY(vert->co, vertCoords[i]);
1702 }
1703
1704 void CDDM_apply_vert_normals(DerivedMesh *dm, short (*vertNormals)[3])
1705 {
1706         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1707         MVert *vert;
1708         int i;
1709
1710         /* this will just return the pointer if it wasn't a referenced layer */
1711         vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
1712         cddm->mvert = vert;
1713
1714         for(i = 0; i < dm->numVertData; ++i, ++vert)
1715                 VECCOPY(vert->no, vertNormals[i]);
1716 }
1717
1718 /* adapted from mesh_calc_normals */
1719 void CDDM_calc_normals(DerivedMesh *dm)
1720 {
1721         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1722         float (*temp_nors)[3];
1723         float (*face_nors)[3];
1724         int i;
1725         int numVerts = dm->numVertData;
1726         int numFaces = dm->numFaceData;
1727         MFace *mf;
1728         MVert *mv;
1729
1730         if(numVerts == 0) return;
1731
1732         temp_nors = MEM_callocN(numVerts * sizeof(*temp_nors),
1733                                 "CDDM_calc_normals temp_nors");
1734
1735         /* we don't want to overwrite any referenced layers */
1736         mv = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
1737         cddm->mvert = mv;
1738
1739         /* make a face normal layer if not present */
1740         face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
1741         if(!face_nors)
1742                 face_nors = CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_CALLOC,
1743                                                  NULL, dm->numFaceData);
1744
1745         /* calculate face normals and add to vertex normals */
1746         mf = CDDM_get_faces(dm);
1747         for(i = 0; i < numFaces; i++, mf++) {
1748                 float *f_no = face_nors[i];
1749
1750                 if(mf->v4)
1751                         CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co,
1752                                        mv[mf->v3].co, mv[mf->v4].co, f_no);
1753                 else
1754                         CalcNormFloat(mv[mf->v1].co, mv[mf->v2].co,
1755                                       mv[mf->v3].co, f_no);
1756                 
1757                 VecAddf(temp_nors[mf->v1], temp_nors[mf->v1], f_no);
1758                 VecAddf(temp_nors[mf->v2], temp_nors[mf->v2], f_no);
1759                 VecAddf(temp_nors[mf->v3], temp_nors[mf->v3], f_no);
1760                 if(mf->v4)
1761                         VecAddf(temp_nors[mf->v4], temp_nors[mf->v4], f_no);
1762         }
1763
1764         /* normalize vertex normals and assign */
1765         for(i = 0; i < numVerts; i++, mv++) {
1766                 float *no = temp_nors[i];
1767                 
1768                 if (Normalize(no) == 0.0) {
1769                         VECCOPY(no, mv->co);
1770                         Normalize(no);
1771                 }
1772
1773                 mv->no[0] = (short)(no[0] * 32767.0);
1774                 mv->no[1] = (short)(no[1] * 32767.0);
1775                 mv->no[2] = (short)(no[2] * 32767.0);
1776         }
1777         
1778         MEM_freeN(temp_nors);
1779 }
1780
1781 void CDDM_calc_edges(DerivedMesh *dm)
1782 {
1783         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1784         CustomData edgeData;
1785         EdgeHashIterator *ehi;
1786         MFace *mf = cddm->mface;
1787         MEdge *med;
1788         EdgeHash *eh = BLI_edgehash_new();
1789         int i, *index, numEdges, maxFaces = dm->numFaceData;
1790
1791         for (i = 0; i < maxFaces; i++, mf++) {
1792                 if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
1793                         BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
1794                 if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
1795                         BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
1796                 
1797                 if (mf->v4) {
1798                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
1799                                 BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
1800                         if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
1801                                 BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
1802                 } else {
1803                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
1804                                 BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
1805                 }
1806         }
1807
1808         numEdges = BLI_edgehash_size(eh);
1809
1810         /* write new edges into a temporary CustomData */
1811         memset(&edgeData, 0, sizeof(edgeData));
1812         CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
1813         CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
1814
1815         ehi = BLI_edgehashIterator_new(eh);
1816         med = CustomData_get_layer(&edgeData, CD_MEDGE);
1817         index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
1818         for(i = 0; !BLI_edgehashIterator_isDone(ehi);
1819             BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) {
1820                 BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2);
1821
1822                 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
1823                 *index = ORIGINDEX_NONE;
1824         }
1825         BLI_edgehashIterator_free(ehi);
1826
1827         /* free old CustomData and assign new one */
1828         CustomData_free(&dm->edgeData, dm->numEdgeData);
1829         dm->edgeData = edgeData;
1830         dm->numEdgeData = numEdges;
1831
1832         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1833
1834         BLI_edgehash_free(eh, NULL);
1835 }
1836
1837 void CDDM_lower_num_verts(DerivedMesh *dm, int numVerts)
1838 {
1839         if (numVerts < dm->numVertData)
1840                 CustomData_free_elem(&dm->vertData, numVerts, dm->numVertData-numVerts);
1841
1842         dm->numVertData = numVerts;
1843 }
1844
1845 void CDDM_lower_num_edges(DerivedMesh *dm, int numEdges)
1846 {
1847         if (numEdges < dm->numEdgeData)
1848                 CustomData_free_elem(&dm->edgeData, numEdges, dm->numEdgeData-numEdges);
1849
1850         dm->numEdgeData = numEdges;
1851 }
1852
1853 void CDDM_lower_num_faces(DerivedMesh *dm, int numFaces)
1854 {
1855         if (numFaces < dm->numFaceData)
1856                 CustomData_free_elem(&dm->faceData, numFaces, dm->numFaceData-numFaces);
1857
1858         dm->numFaceData = numFaces;
1859 }
1860
1861 MVert *CDDM_get_vert(DerivedMesh *dm, int index)
1862 {
1863         return &((CDDerivedMesh*)dm)->mvert[index];
1864 }
1865
1866 MEdge *CDDM_get_edge(DerivedMesh *dm, int index)
1867 {
1868         return &((CDDerivedMesh*)dm)->medge[index];
1869 }
1870
1871 MFace *CDDM_get_face(DerivedMesh *dm, int index)
1872 {
1873         return &((CDDerivedMesh*)dm)->mface[index];
1874 }
1875
1876 MVert *CDDM_get_verts(DerivedMesh *dm)
1877 {
1878         return ((CDDerivedMesh*)dm)->mvert;
1879 }
1880
1881 MEdge *CDDM_get_edges(DerivedMesh *dm)
1882 {
1883         return ((CDDerivedMesh*)dm)->medge;
1884 }
1885
1886 MFace *CDDM_get_faces(DerivedMesh *dm)
1887 {
1888         return ((CDDerivedMesh*)dm)->mface;
1889 }
1890
1891 /* Multires DerivedMesh, extends CDDM */
1892 typedef struct MultiresDM {
1893         CDDerivedMesh cddm;
1894
1895         MultiresModifierData *mmd;
1896         int local_mmd;
1897
1898         int lvl, totlvl;
1899         float (*orco)[3];
1900         MVert *subco;
1901
1902         ListBase *vert_face_map, *vert_edge_map;
1903         IndexNode *vert_face_map_mem, *vert_edge_map_mem;
1904         int *face_offsets;
1905
1906         Object *ob;
1907         int modified;
1908
1909         void (*update)(DerivedMesh*);
1910 } MultiresDM;
1911
1912 static void MultiresDM_release(DerivedMesh *dm)
1913 {
1914         MultiresDM *mrdm = (MultiresDM*)dm;
1915         int mvert_layer;
1916
1917         /* Before freeing, need to update the displacement map */
1918         if(dm->needsFree && mrdm->modified) {
1919                 /* Check that mmd still exists */
1920                 if(!mrdm->local_mmd && BLI_findindex(&mrdm->ob->modifiers, mrdm->mmd) < 0)
1921                         mrdm->mmd = NULL;
1922                 if(mrdm->mmd)
1923                         mrdm->update(dm);
1924         }
1925
1926         /* If the MVert data is being used as the sculpt undo store, don't free it */
1927         mvert_layer = CustomData_get_layer_index(&dm->vertData, CD_MVERT);
1928         if(mvert_layer != -1) {
1929                 CustomDataLayer *cd = &dm->vertData.layers[mvert_layer];
1930                 if(mrdm->mmd && cd->data == mrdm->mmd->undo_verts)
1931                         cd->flag |= CD_FLAG_NOFREE;
1932         }
1933
1934         if(DM_release(dm)) {
1935                 cdDM_free_internal(&mrdm->cddm);
1936                 MEM_freeN(mrdm->subco);
1937                 MEM_freeN(mrdm->orco);
1938                 if(mrdm->vert_face_map)
1939                         MEM_freeN(mrdm->vert_face_map);
1940                 if(mrdm->vert_face_map_mem)
1941                         MEM_freeN(mrdm->vert_face_map_mem);
1942                 if(mrdm->vert_edge_map)
1943                         MEM_freeN(mrdm->vert_edge_map);
1944                 if(mrdm->vert_edge_map_mem)
1945                         MEM_freeN(mrdm->vert_edge_map_mem);
1946                 if(mrdm->face_offsets)
1947                         MEM_freeN(mrdm->face_offsets);
1948                 MEM_freeN(mrdm);
1949         }
1950 }
1951
1952 DerivedMesh *MultiresDM_new(MultiresSubsurf *ms, DerivedMesh *orig, int numVerts, int numEdges, int numFaces)
1953 {
1954         MultiresDM *mrdm = MEM_callocN(sizeof(MultiresDM), "MultiresDM");
1955         CDDerivedMesh *cddm = cdDM_create("MultiresDM CDDM");
1956         DerivedMesh *dm = NULL;
1957
1958         mrdm->cddm = *cddm;
1959         MEM_freeN(cddm);
1960         dm = &mrdm->cddm.dm;
1961
1962         mrdm->mmd = ms->mmd;
1963         mrdm->ob = ms->ob;
1964         mrdm->local_mmd = ms->local_mmd;
1965
1966         if(dm) {
1967                 MDisps *disps;
1968                 MVert *mvert;
1969                 int i;
1970
1971                 DM_from_template(dm, orig, numVerts, numEdges, numFaces);
1972                 CustomData_free_layers(&dm->faceData, CD_MDISPS, numFaces);
1973
1974                 disps = CustomData_get_layer(&orig->faceData, CD_MDISPS);
1975                 if(disps)
1976                         CustomData_add_layer(&dm->faceData, CD_MDISPS, CD_REFERENCE, disps, numFaces);
1977
1978
1979                 mvert = CustomData_get_layer(&orig->vertData, CD_MVERT);
1980                 mrdm->orco = MEM_callocN(sizeof(float) * 3 * orig->getNumVerts(orig), "multires orco");
1981                 for(i = 0; i < orig->getNumVerts(orig); ++i)
1982                         VecCopyf(mrdm->orco[i], mvert[i].co);
1983         }
1984         else
1985                 DM_init(dm, numVerts, numEdges, numFaces);
1986
1987         if(!CustomData_get_layer(&dm->vertData, CD_ORIGINDEX))
1988                 CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
1989         if(!CustomData_get_layer(&dm->edgeData, CD_ORIGINDEX))
1990                 CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
1991         if(!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX))
1992                 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numFaces);
1993
1994         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
1995         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
1996         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numFaces);
1997
1998         mrdm->cddm.mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1999         mrdm->cddm.medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2000         mrdm->cddm.mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
2001
2002         mrdm->lvl = ms->mmd->lvl;
2003         mrdm->totlvl = ms->mmd->totlvl;
2004         mrdm->subco = MEM_callocN(sizeof(MVert)*numVerts, "multires subdivided verts");
2005         mrdm->modified = 0;
2006
2007         dm->release = MultiresDM_release;
2008
2009         return dm;
2010 }
2011
2012 Mesh *MultiresDM_get_mesh(DerivedMesh *dm)
2013 {
2014         return get_mesh(((MultiresDM*)dm)->ob);
2015 }
2016
2017 Object *MultiresDM_get_object(DerivedMesh *dm)
2018 {
2019         return ((MultiresDM*)dm)->ob;
2020 }
2021
2022 void *MultiresDM_get_orco(DerivedMesh *dm)
2023 {
2024         return ((MultiresDM*)dm)->orco;
2025
2026 }
2027
2028 MVert *MultiresDM_get_subco(DerivedMesh *dm)
2029 {
2030         return ((MultiresDM*)dm)->subco;
2031 }
2032
2033 int MultiresDM_get_totlvl(DerivedMesh *dm)
2034 {
2035         return ((MultiresDM*)dm)->totlvl;
2036 }
2037
2038 int MultiresDM_get_lvl(DerivedMesh *dm)
2039 {
2040         return ((MultiresDM*)dm)->lvl;
2041 }
2042
2043 void MultiresDM_set_orco(DerivedMesh *dm, float (*orco)[3])
2044 {
2045         ((MultiresDM*)dm)->orco = orco;
2046 }
2047
2048 void MultiresDM_set_update(DerivedMesh *dm, void (*update)(DerivedMesh*))
2049 {
2050         ((MultiresDM*)dm)->update = update;
2051 }
2052
2053 ListBase *MultiresDM_get_vert_face_map(DerivedMesh *dm)
2054 {
2055         MultiresDM *mrdm = (MultiresDM*)dm;
2056         Mesh *me = mrdm->ob->data;
2057
2058         if(!mrdm->vert_face_map)
2059                 create_vert_face_map(&mrdm->vert_face_map, &mrdm->vert_face_map_mem, me->mface,
2060                                      me->totvert, me->totface);
2061
2062         return mrdm->vert_face_map;
2063 }
2064
2065 ListBase *MultiresDM_get_vert_edge_map(DerivedMesh *dm)
2066 {
2067         MultiresDM *mrdm = (MultiresDM*)dm;
2068         Mesh *me = mrdm->ob->data;
2069
2070         if(!mrdm->vert_edge_map)
2071                 create_vert_edge_map(&mrdm->vert_edge_map, &mrdm->vert_edge_map_mem, me->medge,
2072                                      me->totvert, me->totedge);
2073
2074         return mrdm->vert_edge_map;
2075 }
2076
2077 int *MultiresDM_get_face_offsets(DerivedMesh *dm)
2078 {
2079         MultiresDM *mrdm = (MultiresDM*)dm;
2080         Mesh *me = mrdm->ob->data;
2081         int i, accum = 0;
2082
2083         if(!mrdm->face_offsets) {
2084                 int len = (int)pow(2, mrdm->lvl - 2) - 1;
2085                 int area = len * len;
2086                 int t = 1 + len * 3 + area * 3, q = t + len + area;
2087
2088                 mrdm->face_offsets = MEM_callocN(sizeof(int) * me->totface, "mrdm face offsets");
2089                 for(i = 0; i < me->totface; ++i) {
2090                         mrdm->face_offsets[i] = accum;
2091
2092                         accum += (me->mface[i].v4 ? q : t);
2093                 }
2094         }
2095
2096         return mrdm->face_offsets;
2097 }
2098
2099 void MultiresDM_mark_as_modified(DerivedMesh *dm)
2100 {
2101         ((MultiresDM*)dm)->modified = 1;
2102 }