Merge with -r 22620:23107.
[blender.git] / source / blender / blenkernel / intern / cdderivedmesh.c
1 /*
2 * $Id$
3 *
4 * ***** BEGIN GPL LICENSE BLOCK *****
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software  Foundation,
18 * Inc., 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_ghash.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_draw.h"
64 #include "GPU_extensions.h"
65 #include "GPU_material.h"
66
67 #include <string.h>
68 #include <limits.h>
69 #include <math.h>
70
71 typedef struct {
72         DerivedMesh dm;
73
74         /* these point to data in the DerivedMesh custom data layers,
75            they are only here for efficiency and convenience **/
76         MVert *mvert;
77         MEdge *medge;
78         MFace *mface;
79 } CDDerivedMesh;
80
81 /**************** DerivedMesh interface functions ****************/
82 static int cdDM_getNumVerts(DerivedMesh *dm)
83 {
84         return dm->numVertData;
85 }
86
87 static int cdDM_getNumEdges(DerivedMesh *dm)
88 {
89         return dm->numEdgeData;
90 }
91
92 static int cdDM_getNumFaces(DerivedMesh *dm)
93 {
94         return dm->numFaceData;
95 }
96
97 static void cdDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
98 {
99         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
100         *vert_r = cddm->mvert[index];
101 }
102
103 static void cdDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
104 {
105         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
106         *edge_r = cddm->medge[index];
107 }
108
109 static void cdDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
110 {
111         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
112         *face_r = cddm->mface[index];
113 }
114
115 static void cdDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
116 {
117         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
118         memcpy(vert_r, cddm->mvert, sizeof(*vert_r) * dm->numVertData);
119 }
120
121 static void cdDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
122 {
123         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
124         memcpy(edge_r, cddm->medge, sizeof(*edge_r) * dm->numEdgeData);
125 }
126
127 static void cdDM_copyFaceArray(DerivedMesh *dm, MFace *face_r)
128 {
129         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
130         memcpy(face_r, cddm->mface, sizeof(*face_r) * dm->numFaceData);
131 }
132
133 static void cdDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
134 {
135         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
136         int i;
137
138         if (dm->numVertData) {
139                 for (i=0; i<dm->numVertData; i++) {
140                         DO_MINMAX(cddm->mvert[i].co, min_r, max_r);
141                 }
142         } else {
143                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
144         }
145 }
146
147 static void cdDM_getVertCo(DerivedMesh *dm, int index, float co_r[3])
148 {
149         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
150
151         VECCOPY(co_r, cddm->mvert[index].co);
152 }
153
154 static void cdDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
155 {
156         MVert *mv = CDDM_get_verts(dm);
157         int i;
158
159         for(i = 0; i < dm->numVertData; i++, mv++)
160                 VECCOPY(cos_r[i], mv->co);
161 }
162
163 static void cdDM_getVertNo(DerivedMesh *dm, int index, float no_r[3])
164 {
165         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
166         short *no = cddm->mvert[index].no;
167
168         no_r[0] = no[0]/32767.f;
169         no_r[1] = no[1]/32767.f;
170         no_r[2] = no[2]/32767.f;
171 }
172
173 static void cdDM_drawVerts(DerivedMesh *dm)
174 {
175         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
176         MVert *mv = cddm->mvert;
177         int i;
178
179         glBegin(GL_POINTS);
180         for(i = 0; i < dm->numVertData; i++, mv++)
181                 glVertex3fv(mv->co);
182         glEnd();
183 }
184
185 static void cdDM_drawUVEdges(DerivedMesh *dm)
186 {
187         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
188         MFace *mf = cddm->mface;
189         MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
190         int i;
191
192         if(mf) {
193                 glBegin(GL_LINES);
194                 for(i = 0; i < dm->numFaceData; i++, mf++, tf++) {
195                         if(!(mf->flag&ME_HIDE)) {
196                                 glVertex2fv(tf->uv[0]);
197                                 glVertex2fv(tf->uv[1]);
198
199                                 glVertex2fv(tf->uv[1]);
200                                 glVertex2fv(tf->uv[2]);
201
202                                 if(!mf->v4) {
203                                         glVertex2fv(tf->uv[2]);
204                                         glVertex2fv(tf->uv[0]);
205                                 } else {
206                                         glVertex2fv(tf->uv[2]);
207                                         glVertex2fv(tf->uv[3]);
208
209                                         glVertex2fv(tf->uv[3]);
210                                         glVertex2fv(tf->uv[0]);
211                                 }
212                         }
213                 }
214                 glEnd();
215         }
216 }
217
218 static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
219 {
220         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
221         MVert *mvert = cddm->mvert;
222         MEdge *medge = cddm->medge;
223         int i;
224                 
225         glBegin(GL_LINES);
226         for(i = 0; i < dm->numEdgeData; i++, medge++) {
227                 if((medge->flag&ME_EDGEDRAW)
228                    && (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) {
229                         glVertex3fv(mvert[medge->v1].co);
230                         glVertex3fv(mvert[medge->v2].co);
231                 }
232         }
233         glEnd();
234 }
235
236 static void cdDM_drawLooseEdges(DerivedMesh *dm)
237 {
238         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
239         MVert *mvert = cddm->mvert;
240         MEdge *medge = cddm->medge;
241         int i;
242
243         glBegin(GL_LINES);
244         for(i = 0; i < dm->numEdgeData; i++, medge++) {
245                 if(medge->flag&ME_LOOSEEDGE) {
246                         glVertex3fv(mvert[medge->v1].co);
247                         glVertex3fv(mvert[medge->v2].co);
248                 }
249         }
250         glEnd();
251 }
252
253 static void cdDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int, void *attribs))
254 {
255         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
256         MVert *mvert = cddm->mvert;
257         MFace *mface = cddm->mface;
258         float *nors= dm->getFaceDataArray(dm, CD_NORMAL);
259         int a, glmode = -1, shademodel = -1, matnr = -1, drawCurrentMat = 1;
260
261 #define PASSVERT(index) {                                               \
262         if(shademodel == GL_SMOOTH) {                           \
263                 short *no = mvert[index].no;                    \
264                 glNormal3sv(no);                                                \
265         }                                                                                       \
266         glVertex3fv(mvert[index].co);   \
267 }
268
269         glBegin(glmode = GL_QUADS);
270         for(a = 0; a < dm->numFaceData; a++, mface++) {
271                 int new_glmode, new_matnr, new_shademodel;
272
273                 new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES;
274                 new_matnr = mface->mat_nr + 1;
275                 new_shademodel = (mface->flag & ME_SMOOTH)?GL_SMOOTH:GL_FLAT;
276                 
277                 if(new_glmode != glmode || new_matnr != matnr
278                    || new_shademodel != shademodel) {
279                         glEnd();
280
281                         drawCurrentMat = setMaterial(matnr = new_matnr, NULL);
282
283                         glShadeModel(shademodel = new_shademodel);
284                         glBegin(glmode = new_glmode);
285                 } 
286                 
287                 if(drawCurrentMat) {
288                         if(shademodel == GL_FLAT) {
289                                 if (nors) {
290                                         glNormal3fv(nors);
291                                 }
292                                 else {
293                                         /* TODO make this better (cache facenormals as layer?) */
294                                         float nor[3];
295                                         if(mface->v4) {
296                                                 CalcNormFloat4(mvert[mface->v1].co, mvert[mface->v2].co,
297                                                                            mvert[mface->v3].co, mvert[mface->v4].co,
298                                                                            nor);
299                                         } else {
300                                                 CalcNormFloat(mvert[mface->v1].co, mvert[mface->v2].co,
301                                                                           mvert[mface->v3].co, nor);
302                                         }
303                                         glNormal3fv(nor);
304                                 }
305                         }
306
307                         PASSVERT(mface->v1);
308                         PASSVERT(mface->v2);
309                         PASSVERT(mface->v3);
310                         if(mface->v4) {
311                                 PASSVERT(mface->v4);
312                         }
313                 }
314
315                 if(nors) nors += 3;
316         }
317         glEnd();
318
319         glShadeModel(GL_FLAT);
320 #undef PASSVERT
321 }
322
323 static void cdDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *col1, unsigned char *col2)
324 {
325         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
326         int a, glmode;
327         unsigned char *cp1, *cp2;
328         MVert *mvert = cddm->mvert;
329         MFace *mface = cddm->mface;
330
331         cp1 = col1;
332         if(col2) {
333                 cp2 = col2;
334         } else {
335                 cp2 = NULL;
336                 useTwoSided = 0;
337         }
338
339         /* there's a conflict here... twosided colors versus culling...? */
340         /* defined by history, only texture faces have culling option */
341         /* we need that as mesh option builtin, next to double sided lighting */
342         if(col1 && col2)
343                 glEnable(GL_CULL_FACE);
344         
345         glShadeModel(GL_SMOOTH);
346         glBegin(glmode = GL_QUADS);
347         for(a = 0; a < dm->numFaceData; a++, mface++, cp1 += 16) {
348                 int new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES;
349
350                 if(new_glmode != glmode) {
351                         glEnd();
352                         glBegin(glmode = new_glmode);
353                 }
354                         
355                 glColor3ub(cp1[0], cp1[1], cp1[2]);
356                 glVertex3fv(mvert[mface->v1].co);
357                 glColor3ub(cp1[4], cp1[5], cp1[6]);
358                 glVertex3fv(mvert[mface->v2].co);
359                 glColor3ub(cp1[8], cp1[9], cp1[10]);
360                 glVertex3fv(mvert[mface->v3].co);
361                 if(mface->v4) {
362                         glColor3ub(cp1[12], cp1[13], cp1[14]);
363                         glVertex3fv(mvert[mface->v4].co);
364                 }
365                         
366                 if(useTwoSided) {
367                         glColor3ub(cp2[8], cp2[9], cp2[10]);
368                         glVertex3fv(mvert[mface->v3].co );
369                         glColor3ub(cp2[4], cp2[5], cp2[6]);
370                         glVertex3fv(mvert[mface->v2].co );
371                         glColor3ub(cp2[0], cp2[1], cp2[2]);
372                         glVertex3fv(mvert[mface->v1].co );
373                         if(mface->v4) {
374                                 glColor3ub(cp2[12], cp2[13], cp2[14]);
375                                 glVertex3fv(mvert[mface->v4].co );
376                         }
377                 }
378                 if(col2) cp2 += 16;
379         }
380         glEnd();
381
382         glShadeModel(GL_FLAT);
383         glDisable(GL_CULL_FACE);
384 }
385
386 static void cdDM_drawFacesTex_common(DerivedMesh *dm,
387                int (*drawParams)(MTFace *tface, MCol *mcol, int matnr),
388                int (*drawParamsMapped)(void *userData, int index),
389                void *userData) 
390 {
391         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
392         MVert *mv = cddm->mvert;
393         MFace *mf = cddm->mface;
394         MCol *mcol = dm->getFaceDataArray(dm, CD_MCOL);
395         float *nors= dm->getFaceDataArray(dm, CD_NORMAL);
396         MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
397         int i, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
398
399         for(i = 0; i < dm->numFaceData; i++, mf++) {
400                 MVert *mvert;
401                 int flag;
402                 unsigned char *cp = NULL;
403
404                 if(drawParams) {
405                         flag = drawParams(tf? &tf[i]: NULL, mcol? &mcol[i*4]: NULL, mf->mat_nr);
406                 }
407                 else {
408                         if(index) {
409                                 orig = *index++;
410                                 if(orig == ORIGINDEX_NONE)              { if(nors) nors += 3; continue; }
411                                 if(drawParamsMapped) flag = drawParamsMapped(userData, orig);
412                                 else    { if(nors) nors += 3; continue; }
413                         }
414                         else
415                                 if(drawParamsMapped) flag = drawParamsMapped(userData, i);
416                                 else    { if(nors) nors += 3; continue; }
417                 }
418                 
419                 if(flag != 0) { /* if the flag is 0 it means the face is hidden or invisible */
420                         if (flag==1 && mcol)
421                                 cp= (unsigned char*) &mcol[i*4];
422
423                         if(!(mf->flag&ME_SMOOTH)) {
424                                 if (nors) {
425                                         glNormal3fv(nors);
426                                 }
427                                 else {
428                                         /* TODO make this better (cache facenormals as layer?) */
429                                         float nor[3];
430                                         if(mf->v4) {
431                                                 CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co,
432                                                                            mv[mf->v3].co, mv[mf->v4].co,
433                                                                            nor);
434                                         } else {
435                                                 CalcNormFloat(mv[mf->v1].co, mv[mf->v2].co,
436                                                                           mv[mf->v3].co, nor);
437                                         }
438                                         glNormal3fv(nor);
439                                 }
440                         }
441
442                         glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
443                         if(tf) glTexCoord2fv(tf[i].uv[0]);
444                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
445                         mvert = &mv[mf->v1];
446                         if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
447                         glVertex3fv(mvert->co);
448                                 
449                         if(tf) glTexCoord2fv(tf[i].uv[1]);
450                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
451                         mvert = &mv[mf->v2];
452                         if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
453                         glVertex3fv(mvert->co);
454
455                         if(tf) glTexCoord2fv(tf[i].uv[2]);
456                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
457                         mvert = &mv[mf->v3];
458                         if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
459                         glVertex3fv(mvert->co);
460
461                         if(mf->v4) {
462                                 if(tf) glTexCoord2fv(tf[i].uv[3]);
463                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
464                                 mvert = &mv[mf->v4];
465                                 if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
466                                 glVertex3fv(mvert->co);
467                         }
468                         glEnd();
469                 }
470                 
471                 if(nors) nors += 3;
472         }
473 }
474
475 static void cdDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr))
476 {
477         cdDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
478 }
479
480 static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors)
481 {
482         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
483         MVert *mv = cddm->mvert;
484         MFace *mf = cddm->mface;
485         MCol *mc;
486         float *nors= dm->getFaceDataArray(dm, CD_NORMAL);
487         int i, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
488
489         mc = DM_get_face_data_layer(dm, CD_WEIGHT_MCOL);
490         if(!mc)
491                 mc = DM_get_face_data_layer(dm, CD_MCOL);
492
493         for(i = 0; i < dm->numFaceData; i++, mf++) {
494                 int drawSmooth = (mf->flag & ME_SMOOTH);
495
496                 if(index) {
497                         orig = *index++;
498                         if(setDrawOptions && orig == ORIGINDEX_NONE)
499                                 { if(nors) nors += 3; continue; }
500                 }
501                 else
502                         orig = i;
503
504                 if(!setDrawOptions || setDrawOptions(userData, orig, &drawSmooth)) {
505                         unsigned char *cp = NULL;
506
507                         if(useColors && mc)
508                                 cp = (unsigned char *)&mc[i * 4];
509
510                         glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
511                         glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
512
513                         if (!drawSmooth) {
514                                 if (nors) {
515                                         glNormal3fv(nors);
516                                 }
517                                 else {
518                                         /* TODO make this better (cache facenormals as layer?) */
519                                         float nor[3];
520                                         if(mf->v4) {
521                                                 CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co,
522                                                                            mv[mf->v3].co, mv[mf->v4].co,
523                                                                            nor);
524                                         } else {
525                                                 CalcNormFloat(mv[mf->v1].co, mv[mf->v2].co,
526                                                                           mv[mf->v3].co, nor);
527                                         }
528                                         glNormal3fv(nor);
529                                 }
530
531                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
532                                 glVertex3fv(mv[mf->v1].co);
533                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
534                                 glVertex3fv(mv[mf->v2].co);
535                                 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
536                                 glVertex3fv(mv[mf->v3].co);
537                                 if(mf->v4) {
538                                         if(cp) glColor3ub(cp[15], cp[14], cp[13]);
539                                         glVertex3fv(mv[mf->v4].co);
540                                 }
541                         } else {
542                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
543                                 glNormal3sv(mv[mf->v1].no);
544                                 glVertex3fv(mv[mf->v1].co);
545                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
546                                 glNormal3sv(mv[mf->v2].no);
547                                 glVertex3fv(mv[mf->v2].co);
548                                 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
549                                 glNormal3sv(mv[mf->v3].no);
550                                 glVertex3fv(mv[mf->v3].co);
551                                 if(mf->v4) {
552                                         if(cp) glColor3ub(cp[15], cp[14], cp[13]);
553                                         glNormal3sv(mv[mf->v4].no);
554                                         glVertex3fv(mv[mf->v4].co);
555                                 }
556                         }
557
558                         glEnd();
559                 }
560                 
561                 if (nors) nors += 3;
562         }
563 }
564
565 static void cdDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
566 {
567         cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
568 }
569
570 static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs), int (*setDrawOptions)(void *userData, int index), void *userData)
571 {
572         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
573         GPUVertexAttribs gattribs;
574         DMVertexAttribs attribs;
575         MVert *mvert = cddm->mvert;
576         MFace *mface = cddm->mface;
577         MTFace *tf = dm->getFaceDataArray(dm, CD_MTFACE);
578         float (*nors)[3] = dm->getFaceDataArray(dm, CD_NORMAL);
579         int a, b, dodraw, smoothnormal, matnr, new_matnr;
580         int transp, new_transp, orig_transp;
581         int orig, *index = dm->getFaceDataArray(dm, CD_ORIGINDEX);
582
583         matnr = -1;
584         smoothnormal = 0;
585         dodraw = 0;
586         transp = GPU_get_material_blend_mode();
587         orig_transp = transp;
588
589         memset(&attribs, 0, sizeof(attribs));
590
591         glShadeModel(GL_SMOOTH);
592         glBegin(GL_QUADS);
593
594         for(a = 0; a < dm->numFaceData; a++, mface++) {
595                 new_matnr = mface->mat_nr + 1;
596
597                 if(new_matnr != matnr) {
598                         glEnd();
599
600                         dodraw = setMaterial(matnr = new_matnr, &gattribs);
601                         if(dodraw)
602                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
603
604                         glBegin(GL_QUADS);
605                 }
606
607                 if(!dodraw) {
608                         continue;
609                 }
610                 else if(setDrawOptions) {
611                         orig = index[a];
612
613                         if(orig == ORIGINDEX_NONE)
614                                 continue;
615                         else if(!setDrawOptions(userData, orig))
616                                 continue;
617                 }
618
619                 if(tf) {
620                         new_transp = tf[a].transp;
621
622                         if(new_transp != transp) {
623                                 glEnd();
624
625                                 if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
626                                         GPU_set_material_blend_mode(orig_transp);
627                                 else
628                                         GPU_set_material_blend_mode(new_transp);
629                                 transp = new_transp;
630
631                                 glBegin(GL_QUADS);
632                         }
633                 }
634
635                 smoothnormal = (mface->flag & ME_SMOOTH);
636
637                 if(!smoothnormal) {
638                         if(nors) {
639                                 glNormal3fv(nors[a]);
640                         }
641                         else {
642                                 /* TODO ideally a normal layer should always be available */
643                                 float nor[3];
644                                 if(mface->v4) {
645                                         CalcNormFloat4(mvert[mface->v1].co, mvert[mface->v2].co,
646                                                                    mvert[mface->v3].co, mvert[mface->v4].co,
647                                                                    nor);
648                                 } else {
649                                         CalcNormFloat(mvert[mface->v1].co, mvert[mface->v2].co,
650                                                                   mvert[mface->v3].co, nor);
651                                 }
652                                 glNormal3fv(nor);
653                         }
654                 }
655
656 #define PASSVERT(index, vert) {                                                                                                 \
657         if(attribs.totorco)                                                                                                                     \
658                 glVertexAttrib3fvARB(attribs.orco.glIndex, attribs.orco.array[index]);  \
659         for(b = 0; b < attribs.tottface; b++) {                                                                         \
660                 MTFace *tf = &attribs.tface[b].array[a];                                                                \
661                 glVertexAttrib2fvARB(attribs.tface[b].glIndex, tf->uv[vert]);                   \
662         }                                                                                                                                                       \
663         for(b = 0; b < attribs.totmcol; b++) {                                                                          \
664                 MCol *cp = &attribs.mcol[b].array[a*4 + vert];                                                  \
665                 GLubyte col[4];                                                                                                                 \
666                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;                             \
667                 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col);                                    \
668         }                                                                                                                                                       \
669         if(attribs.tottang) {                                                                                                           \
670                 float *tang = attribs.tang.array[a*4 + vert];                                                   \
671                 glVertexAttrib3fvARB(attribs.tang.glIndex, tang);                                               \
672         }                                                                                                                                                       \
673         if(smoothnormal)                                                                                                                        \
674                 glNormal3sv(mvert[index].no);                                                                                   \
675         glVertex3fv(mvert[index].co);                                                                                           \
676 }
677
678                 PASSVERT(mface->v1, 0);
679                 PASSVERT(mface->v2, 1);
680                 PASSVERT(mface->v3, 2);
681                 if(mface->v4)
682                         PASSVERT(mface->v4, 3)
683                 else
684                         PASSVERT(mface->v3, 2)
685
686 #undef PASSVERT
687         }
688         glEnd();
689
690         glShadeModel(GL_FLAT);
691 }
692
693 static void cdDM_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs))
694 {
695         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
696 }
697
698 static void cdDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
699 {
700         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
701         MVert *vert = cddm->mvert;
702         MEdge *edge = cddm->medge;
703         int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
704
705         glBegin(GL_LINES);
706         for(i = 0; i < dm->numEdgeData; i++, edge++) {
707                 if(index) {
708                         orig = *index++;
709                         if(setDrawOptions && orig == ORIGINDEX_NONE) continue;
710                 }
711                 else
712                         orig = i;
713
714                 if(!setDrawOptions || setDrawOptions(userData, orig)) {
715                         glVertex3fv(vert[edge->v1].co);
716                         glVertex3fv(vert[edge->v2].co);
717                 }
718         }
719         glEnd();
720 }
721
722 static void cdDM_foreachMappedVert(
723                            DerivedMesh *dm,
724                            void (*func)(void *userData, int index, float *co,
725                                         float *no_f, short *no_s),
726                            void *userData)
727 {
728         MVert *mv = CDDM_get_verts(dm);
729         int i, orig, *index = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
730
731         for(i = 0; i < dm->numVertData; i++, mv++) {
732                 if(index) {
733                         orig = *index++;
734                         if(orig == ORIGINDEX_NONE) continue;
735                         func(userData, orig, mv->co, NULL, mv->no);
736                 }
737                 else
738                         func(userData, i, mv->co, NULL, mv->no);
739         }
740 }
741
742 static void cdDM_foreachMappedEdge(
743                            DerivedMesh *dm,
744                            void (*func)(void *userData, int index,
745                                         float *v0co, float *v1co),
746                            void *userData)
747 {
748         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
749         MVert *mv = cddm->mvert;
750         MEdge *med = cddm->medge;
751         int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
752
753         for(i = 0; i < dm->numEdgeData; i++, med++) {
754                 if (index) {
755                         orig = *index++;
756                         if(orig == ORIGINDEX_NONE) continue;
757                         func(userData, orig, mv[med->v1].co, mv[med->v2].co);
758                 }
759                 else
760                         func(userData, i, mv[med->v1].co, mv[med->v2].co);
761         }
762 }
763
764 static void cdDM_foreachMappedFaceCenter(
765                            DerivedMesh *dm,
766                            void (*func)(void *userData, int index,
767                                         float *cent, float *no),
768                            void *userData)
769 {
770         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
771         MVert *mv = cddm->mvert;
772         MFace *mf = cddm->mface;
773         int i, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
774
775         for(i = 0; i < dm->numFaceData; i++, mf++) {
776                 float cent[3];
777                 float no[3];
778
779                 if (index) {
780                         orig = *index++;
781                         if(orig == ORIGINDEX_NONE) continue;
782                 }
783                 else
784                         orig = i;
785
786                 VECCOPY(cent, mv[mf->v1].co);
787                 VecAddf(cent, cent, mv[mf->v2].co);
788                 VecAddf(cent, cent, mv[mf->v3].co);
789
790                 if (mf->v4) {
791                         CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co,
792                                        mv[mf->v3].co, mv[mf->v4].co, no);
793                         VecAddf(cent, cent, mv[mf->v4].co);
794                         VecMulf(cent, 0.25f);
795                 } else {
796                         CalcNormFloat(mv[mf->v1].co, mv[mf->v2].co,
797                                       mv[mf->v3].co, no);
798                         VecMulf(cent, 0.33333333333f);
799                 }
800
801                 func(userData, orig, cent, no);
802         }
803 }
804
805 static void cdDM_release(DerivedMesh *dm)
806 {
807         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
808
809         if (DM_release(dm))
810                 MEM_freeN(cddm);
811 }
812
813 /**************** CDDM interface functions ****************/
814 static CDDerivedMesh *cdDM_create(const char *desc)
815 {
816         CDDerivedMesh *cddm;
817         DerivedMesh *dm;
818
819         cddm = MEM_callocN(sizeof(*cddm), desc);
820         dm = &cddm->dm;
821
822         dm->getMinMax = cdDM_getMinMax;
823
824         dm->getNumVerts = cdDM_getNumVerts;
825         dm->getNumFaces = cdDM_getNumFaces;
826         dm->getNumEdges = cdDM_getNumEdges;
827
828         dm->getVert = cdDM_getVert;
829         dm->getEdge = cdDM_getEdge;
830         dm->getFace = cdDM_getFace;
831         dm->copyVertArray = cdDM_copyVertArray;
832         dm->copyEdgeArray = cdDM_copyEdgeArray;
833         dm->copyFaceArray = cdDM_copyFaceArray;
834         dm->getVertData = DM_get_vert_data;
835         dm->getEdgeData = DM_get_edge_data;
836         dm->getFaceData = DM_get_face_data;
837         dm->getVertDataArray = DM_get_vert_data_layer;
838         dm->getEdgeDataArray = DM_get_edge_data_layer;
839         dm->getFaceDataArray = DM_get_face_data_layer;
840
841         dm->getVertCos = cdDM_getVertCos;
842         dm->getVertCo = cdDM_getVertCo;
843         dm->getVertNo = cdDM_getVertNo;
844
845         dm->drawVerts = cdDM_drawVerts;
846
847         dm->drawUVEdges = cdDM_drawUVEdges;
848         dm->drawEdges = cdDM_drawEdges;
849         dm->drawLooseEdges = cdDM_drawLooseEdges;
850         dm->drawMappedEdges = cdDM_drawMappedEdges;
851
852         dm->drawFacesSolid = cdDM_drawFacesSolid;
853         dm->drawFacesColored = cdDM_drawFacesColored;
854         dm->drawFacesTex = cdDM_drawFacesTex;
855         dm->drawFacesGLSL = cdDM_drawFacesGLSL;
856         dm->drawMappedFaces = cdDM_drawMappedFaces;
857         dm->drawMappedFacesTex = cdDM_drawMappedFacesTex;
858         dm->drawMappedFacesGLSL = cdDM_drawMappedFacesGLSL;
859
860         dm->foreachMappedVert = cdDM_foreachMappedVert;
861         dm->foreachMappedEdge = cdDM_foreachMappedEdge;
862         dm->foreachMappedFaceCenter = cdDM_foreachMappedFaceCenter;
863
864         dm->release = cdDM_release;
865
866         return cddm;
867 }
868
869 DerivedMesh *CDDM_new(int numVerts, int numEdges, int numFaces)
870 {
871         CDDerivedMesh *cddm = cdDM_create("CDDM_new dm");
872         DerivedMesh *dm = &cddm->dm;
873
874         DM_init(dm, numVerts, numEdges, numFaces);
875
876         CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
877         CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
878         CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numFaces);
879
880         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
881         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
882         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numFaces);
883
884         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
885         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
886         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
887
888         return dm;
889 }
890
891 DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *ob)
892 {
893         CDDerivedMesh *cddm = cdDM_create("CDDM_from_mesh dm");
894         DerivedMesh *dm = &cddm->dm;
895         CustomDataMask mask = CD_MASK_MESH & (~CD_MASK_MDISPS);
896         int i, *index, alloctype;
897
898         /* this does a referenced copy, the only new layers being ORIGINDEX,
899          * with an exception for fluidsim */
900
901         DM_init(dm, mesh->totvert, mesh->totedge, mesh->totface);
902
903         CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totvert);
904         CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totedge);
905         CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totface);
906
907         dm->deformedOnly = 1;
908
909         alloctype= CD_REFERENCE;
910
911         CustomData_merge(&mesh->vdata, &dm->vertData, mask, alloctype,
912                          mesh->totvert);
913         CustomData_merge(&mesh->edata, &dm->edgeData, mask, alloctype,
914                          mesh->totedge);
915         CustomData_merge(&mesh->fdata, &dm->faceData, mask, alloctype,
916                          mesh->totface);
917
918         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
919         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
920         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
921
922         index = CustomData_get_layer(&dm->vertData, CD_ORIGINDEX);
923         for(i = 0; i < mesh->totvert; ++i, ++index)
924                 *index = i;
925
926         index = CustomData_get_layer(&dm->edgeData, CD_ORIGINDEX);
927         for(i = 0; i < mesh->totedge; ++i, ++index)
928                 *index = i;
929
930         index = CustomData_get_layer(&dm->faceData, CD_ORIGINDEX);
931         for(i = 0; i < mesh->totface; ++i, ++index)
932                 *index = i;
933
934         return dm;
935 }
936
937 DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
938 {
939         DerivedMesh *dm = CDDM_new(BLI_countlist(&em->verts),
940                                    BLI_countlist(&em->edges),
941                                    BLI_countlist(&em->faces));
942         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
943         EditVert *eve;
944         EditEdge *eed;
945         EditFace *efa;
946         MVert *mvert = cddm->mvert;
947         MEdge *medge = cddm->medge;
948         MFace *mface = cddm->mface;
949         int i, *index;
950
951         dm->deformedOnly = 1;
952
953         CustomData_merge(&em->vdata, &dm->vertData, CD_MASK_DERIVEDMESH,
954                          CD_CALLOC, dm->numVertData);
955         /* CustomData_merge(&em->edata, &dm->edgeData, CD_MASK_DERIVEDMESH,
956                          CD_CALLOC, dm->numEdgeData); */
957         CustomData_merge(&em->fdata, &dm->faceData, CD_MASK_DERIVEDMESH,
958                          CD_CALLOC, dm->numFaceData);
959
960         /* set eve->hash to vert index */
961         for(i = 0, eve = em->verts.first; eve; eve = eve->next, ++i)
962                 eve->tmp.l = i;
963
964         /* Need to be able to mark loose edges */
965         for(eed = em->edges.first; eed; eed = eed->next) {
966                 eed->f2 = 0;
967         }
968         for(efa = em->faces.first; efa; efa = efa->next) {
969                 efa->e1->f2 = 1;
970                 efa->e2->f2 = 1;
971                 efa->e3->f2 = 1;
972                 if(efa->e4) efa->e4->f2 = 1;
973         }
974
975         index = dm->getVertDataArray(dm, CD_ORIGINDEX);
976         for(i = 0, eve = em->verts.first; i < dm->numVertData;
977             i++, eve = eve->next, index++) {
978                 MVert *mv = &mvert[i];
979
980                 VECCOPY(mv->co, eve->co);
981
982                 mv->no[0] = eve->no[0] * 32767.0;
983                 mv->no[1] = eve->no[1] * 32767.0;
984                 mv->no[2] = eve->no[2] * 32767.0;
985                 mv->bweight = (unsigned char) (eve->bweight * 255.0f);
986
987                 mv->mat_nr = 0;
988                 mv->flag = 0;
989
990                 *index = i;
991
992                 CustomData_from_em_block(&em->vdata, &dm->vertData, eve->data, i);
993         }
994
995         index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
996         for(i = 0, eed = em->edges.first; i < dm->numEdgeData;
997             i++, eed = eed->next, index++) {
998                 MEdge *med = &medge[i];
999
1000                 med->v1 = eed->v1->tmp.l;
1001                 med->v2 = eed->v2->tmp.l;
1002                 med->crease = (unsigned char) (eed->crease * 255.0f);
1003                 med->bweight = (unsigned char) (eed->bweight * 255.0f);
1004                 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
1005                 
1006                 if(eed->seam) med->flag |= ME_SEAM;
1007                 if(eed->sharp) med->flag |= ME_SHARP;
1008                 if(!eed->f2) med->flag |= ME_LOOSEEDGE;
1009
1010                 *index = i;
1011
1012                 /* CustomData_from_em_block(&em->edata, &dm->edgeData, eed->data, i); */
1013         }
1014
1015         index = dm->getFaceDataArray(dm, CD_ORIGINDEX);
1016         for(i = 0, efa = em->faces.first; i < dm->numFaceData;
1017             i++, efa = efa->next, index++) {
1018                 MFace *mf = &mface[i];
1019
1020                 mf->v1 = efa->v1->tmp.l;
1021                 mf->v2 = efa->v2->tmp.l;
1022                 mf->v3 = efa->v3->tmp.l;
1023                 mf->v4 = efa->v4 ? efa->v4->tmp.l : 0;
1024                 mf->mat_nr = efa->mat_nr;
1025                 mf->flag = efa->flag;
1026
1027                 *index = i;
1028
1029                 CustomData_from_em_block(&em->fdata, &dm->faceData, efa->data, i);
1030                 test_index_face(mf, &dm->faceData, i, efa->v4?4:3);
1031         }
1032
1033         return dm;
1034 }
1035
1036 DerivedMesh *CDDM_copy(DerivedMesh *source)
1037 {
1038         CDDerivedMesh *cddm = cdDM_create("CDDM_copy cddm");
1039         DerivedMesh *dm = &cddm->dm;
1040         int numVerts = source->numVertData;
1041         int numEdges = source->numEdgeData;
1042         int numFaces = source->numFaceData;
1043
1044         /* this initializes dm, and copies all non mvert/medge/mface layers */
1045         DM_from_template(dm, source, numVerts, numEdges, numFaces);
1046         dm->deformedOnly = source->deformedOnly;
1047
1048         CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts);
1049         CustomData_copy_data(&source->edgeData, &dm->edgeData, 0, 0, numEdges);
1050         CustomData_copy_data(&source->faceData, &dm->faceData, 0, 0, numFaces);
1051
1052         /* now add mvert/medge/mface layers */
1053         cddm->mvert = source->dupVertArray(source);
1054         cddm->medge = source->dupEdgeArray(source);
1055         cddm->mface = source->dupFaceArray(source);
1056
1057         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, cddm->mvert, numVerts);
1058         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, cddm->medge, numEdges);
1059         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, cddm->mface, numFaces);
1060
1061         return dm;
1062 }
1063
1064 DerivedMesh *CDDM_from_template(DerivedMesh *source,
1065                                 int numVerts, int numEdges, int numFaces)
1066 {
1067         CDDerivedMesh *cddm = cdDM_create("CDDM_from_template dest");
1068         DerivedMesh *dm = &cddm->dm;
1069
1070         /* this does a copy of all non mvert/medge/mface layers */
1071         DM_from_template(dm, source, numVerts, numEdges, numFaces);
1072
1073         /* now add mvert/medge/mface layers */
1074         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
1075         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
1076         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numFaces);
1077
1078         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1079         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1080         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1081
1082         return dm;
1083 }
1084
1085 void CDDM_apply_vert_coords(DerivedMesh *dm, float (*vertCoords)[3])
1086 {
1087         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1088         MVert *vert;
1089         int i;
1090
1091         /* this will just return the pointer if it wasn't a referenced layer */
1092         vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
1093         cddm->mvert = vert;
1094
1095         for(i = 0; i < dm->numVertData; ++i, ++vert)
1096                 VECCOPY(vert->co, vertCoords[i]);
1097 }
1098
1099 void CDDM_apply_vert_normals(DerivedMesh *dm, short (*vertNormals)[3])
1100 {
1101         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1102         MVert *vert;
1103         int i;
1104
1105         /* this will just return the pointer if it wasn't a referenced layer */
1106         vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
1107         cddm->mvert = vert;
1108
1109         for(i = 0; i < dm->numVertData; ++i, ++vert)
1110                 VECCOPY(vert->no, vertNormals[i]);
1111 }
1112
1113 /* adapted from mesh_calc_normals */
1114 void CDDM_calc_normals(DerivedMesh *dm)
1115 {
1116         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1117         float (*temp_nors)[3];
1118         float (*face_nors)[3];
1119         int i;
1120         int numVerts = dm->numVertData;
1121         int numFaces = dm->numFaceData;
1122         MFace *mf;
1123         MVert *mv;
1124
1125         if(numVerts == 0) return;
1126
1127         temp_nors = MEM_callocN(numVerts * sizeof(*temp_nors),
1128                                 "CDDM_calc_normals temp_nors");
1129
1130         /* we don't want to overwrite any referenced layers */
1131         mv = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
1132         cddm->mvert = mv;
1133
1134         /* make a face normal layer if not present */
1135         face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
1136         if(!face_nors)
1137                 face_nors = CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_CALLOC,
1138                                                  NULL, dm->numFaceData);
1139
1140         /* calculate face normals and add to vertex normals */
1141         mf = CDDM_get_faces(dm);
1142         for(i = 0; i < numFaces; i++, mf++) {
1143                 float *f_no = face_nors[i];
1144
1145                 if(mf->v4)
1146                         CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co,
1147                                        mv[mf->v3].co, mv[mf->v4].co, f_no);
1148                 else
1149                         CalcNormFloat(mv[mf->v1].co, mv[mf->v2].co,
1150                                       mv[mf->v3].co, f_no);
1151                 
1152                 VecAddf(temp_nors[mf->v1], temp_nors[mf->v1], f_no);
1153                 VecAddf(temp_nors[mf->v2], temp_nors[mf->v2], f_no);
1154                 VecAddf(temp_nors[mf->v3], temp_nors[mf->v3], f_no);
1155                 if(mf->v4)
1156                         VecAddf(temp_nors[mf->v4], temp_nors[mf->v4], f_no);
1157         }
1158
1159         /* normalize vertex normals and assign */
1160         for(i = 0; i < numVerts; i++, mv++) {
1161                 float *no = temp_nors[i];
1162                 
1163                 if (Normalize(no) == 0.0) {
1164                         VECCOPY(no, mv->co);
1165                         Normalize(no);
1166                 }
1167
1168                 mv->no[0] = (short)(no[0] * 32767.0);
1169                 mv->no[1] = (short)(no[1] * 32767.0);
1170                 mv->no[2] = (short)(no[2] * 32767.0);
1171         }
1172         
1173         MEM_freeN(temp_nors);
1174 }
1175
1176 void CDDM_calc_edges(DerivedMesh *dm)
1177 {
1178         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1179         CustomData edgeData;
1180         EdgeHashIterator *ehi;
1181         MFace *mf = cddm->mface;
1182         MEdge *med;
1183         EdgeHash *eh = BLI_edgehash_new();
1184         int i, *index, numEdges, maxFaces = dm->numFaceData;
1185
1186         for (i = 0; i < maxFaces; i++, mf++) {
1187                 if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
1188                         BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
1189                 if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
1190                         BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
1191                 
1192                 if (mf->v4) {
1193                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
1194                                 BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
1195                         if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
1196                                 BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
1197                 } else {
1198                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
1199                                 BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
1200                 }
1201         }
1202
1203         numEdges = BLI_edgehash_size(eh);
1204
1205         /* write new edges into a temporary CustomData */
1206         memset(&edgeData, 0, sizeof(edgeData));
1207         CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
1208         CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
1209
1210         ehi = BLI_edgehashIterator_new(eh);
1211         med = CustomData_get_layer(&edgeData, CD_MEDGE);
1212         index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
1213         for(i = 0; !BLI_edgehashIterator_isDone(ehi);
1214             BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) {
1215                 BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2);
1216
1217                 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
1218                 *index = ORIGINDEX_NONE;
1219         }
1220         BLI_edgehashIterator_free(ehi);
1221
1222         /* free old CustomData and assign new one */
1223         CustomData_free(&dm->edgeData, dm->numEdgeData);
1224         dm->edgeData = edgeData;
1225         dm->numEdgeData = numEdges;
1226
1227         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1228
1229         BLI_edgehash_free(eh, NULL);
1230 }
1231
1232 void CDDM_lower_num_verts(DerivedMesh *dm, int numVerts)
1233 {
1234         if (numVerts < dm->numVertData)
1235                 CustomData_free_elem(&dm->vertData, numVerts, dm->numVertData-numVerts);
1236
1237         dm->numVertData = numVerts;
1238 }
1239
1240 void CDDM_lower_num_edges(DerivedMesh *dm, int numEdges)
1241 {
1242         if (numEdges < dm->numEdgeData)
1243                 CustomData_free_elem(&dm->edgeData, numEdges, dm->numEdgeData-numEdges);
1244
1245         dm->numEdgeData = numEdges;
1246 }
1247
1248 void CDDM_lower_num_faces(DerivedMesh *dm, int numFaces)
1249 {
1250         if (numFaces < dm->numFaceData)
1251                 CustomData_free_elem(&dm->faceData, numFaces, dm->numFaceData-numFaces);
1252
1253         dm->numFaceData = numFaces;
1254 }
1255
1256 MVert *CDDM_get_vert(DerivedMesh *dm, int index)
1257 {
1258         return &((CDDerivedMesh*)dm)->mvert[index];
1259 }
1260
1261 MEdge *CDDM_get_edge(DerivedMesh *dm, int index)
1262 {
1263         return &((CDDerivedMesh*)dm)->medge[index];
1264 }
1265
1266 MFace *CDDM_get_face(DerivedMesh *dm, int index)
1267 {
1268         return &((CDDerivedMesh*)dm)->mface[index];
1269 }
1270
1271 MVert *CDDM_get_verts(DerivedMesh *dm)
1272 {
1273         return ((CDDerivedMesh*)dm)->mvert;
1274 }
1275
1276 MEdge *CDDM_get_edges(DerivedMesh *dm)
1277 {
1278         return ((CDDerivedMesh*)dm)->medge;
1279 }
1280
1281 MFace *CDDM_get_faces(DerivedMesh *dm)
1282 {
1283         return ((CDDerivedMesh*)dm)->mface;
1284 }
1285
1286 /* Multires DerivedMesh, extends CDDM */
1287 typedef struct MultiresDM {
1288         CDDerivedMesh cddm;
1289
1290         MultiresModifierData *mmd;
1291         int local_mmd;
1292
1293         int lvl, totlvl;
1294         float (*orco)[3];
1295         MVert *subco;
1296
1297         ListBase *vert_face_map, *vert_edge_map;
1298         IndexNode *vert_face_map_mem, *vert_edge_map_mem;
1299         int *face_offsets;
1300
1301         Object *ob;
1302         int modified;
1303
1304         void (*update)(DerivedMesh*);
1305 } MultiresDM;
1306
1307 static void MultiresDM_release(DerivedMesh *dm)
1308 {
1309         MultiresDM *mrdm = (MultiresDM*)dm;
1310         int mvert_layer;
1311
1312         /* Before freeing, need to update the displacement map */
1313         if(dm->needsFree && mrdm->modified) {
1314                 /* Check that mmd still exists */
1315                 if(!mrdm->local_mmd && BLI_findindex(&mrdm->ob->modifiers, mrdm->mmd) < 0)
1316                         mrdm->mmd = NULL;
1317                 if(mrdm->mmd)
1318                         mrdm->update(dm);
1319         }
1320
1321         /* If the MVert data is being used as the sculpt undo store, don't free it */
1322         mvert_layer = CustomData_get_layer_index(&dm->vertData, CD_MVERT);
1323         if(mvert_layer != -1) {
1324                 CustomDataLayer *cd = &dm->vertData.layers[mvert_layer];
1325                 if(mrdm->mmd && cd->data == mrdm->mmd->undo_verts)
1326                         cd->flag |= CD_FLAG_NOFREE;
1327         }
1328
1329         if(DM_release(dm)) {
1330                 MEM_freeN(mrdm->subco);
1331                 MEM_freeN(mrdm->orco);
1332                 if(mrdm->vert_face_map)
1333                         MEM_freeN(mrdm->vert_face_map);
1334                 if(mrdm->vert_face_map_mem)
1335                         MEM_freeN(mrdm->vert_face_map_mem);
1336                 if(mrdm->vert_edge_map)
1337                         MEM_freeN(mrdm->vert_edge_map);
1338                 if(mrdm->vert_edge_map_mem)
1339                         MEM_freeN(mrdm->vert_edge_map_mem);
1340                 if(mrdm->face_offsets)
1341                         MEM_freeN(mrdm->face_offsets);
1342                 MEM_freeN(mrdm);
1343         }
1344 }
1345
1346 DerivedMesh *MultiresDM_new(MultiresSubsurf *ms, DerivedMesh *orig, int numVerts, int numEdges, int numFaces)
1347 {
1348         MultiresDM *mrdm = MEM_callocN(sizeof(MultiresDM), "MultiresDM");
1349         CDDerivedMesh *cddm = cdDM_create("MultiresDM CDDM");
1350         DerivedMesh *dm = NULL;
1351
1352         mrdm->cddm = *cddm;
1353         MEM_freeN(cddm);
1354         dm = &mrdm->cddm.dm;
1355
1356         mrdm->mmd = ms->mmd;
1357         mrdm->ob = ms->ob;
1358         mrdm->local_mmd = ms->local_mmd;
1359
1360         if(dm) {
1361                 MDisps *disps;
1362                 MVert *mvert;
1363                 int i;
1364
1365                 DM_from_template(dm, orig, numVerts, numEdges, numFaces);
1366                 CustomData_free_layers(&dm->faceData, CD_MDISPS, numFaces);
1367
1368                 disps = CustomData_get_layer(&orig->faceData, CD_MDISPS);
1369                 if(disps)
1370                         CustomData_add_layer(&dm->faceData, CD_MDISPS, CD_REFERENCE, disps, numFaces);
1371
1372
1373                 mvert = CustomData_get_layer(&orig->vertData, CD_MVERT);
1374                 mrdm->orco = MEM_callocN(sizeof(float) * 3 * orig->getNumVerts(orig), "multires orco");
1375                 for(i = 0; i < orig->getNumVerts(orig); ++i)
1376                         VecCopyf(mrdm->orco[i], mvert[i].co);
1377         }
1378         else
1379                 DM_init(dm, numVerts, numEdges, numFaces);
1380
1381         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
1382         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
1383         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numFaces);
1384
1385         mrdm->cddm.mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1386         mrdm->cddm.medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1387         mrdm->cddm.mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1388
1389         mrdm->lvl = ms->mmd->lvl;
1390         mrdm->totlvl = ms->mmd->totlvl;
1391         mrdm->subco = MEM_callocN(sizeof(MVert)*numVerts, "multires subdivided verts");
1392         mrdm->modified = 0;
1393
1394         dm->release = MultiresDM_release;
1395
1396         return dm;
1397 }
1398
1399 Mesh *MultiresDM_get_mesh(DerivedMesh *dm)
1400 {
1401         return get_mesh(((MultiresDM*)dm)->ob);
1402 }
1403
1404 Object *MultiresDM_get_object(DerivedMesh *dm)
1405 {
1406         return ((MultiresDM*)dm)->ob;
1407 }
1408
1409 void *MultiresDM_get_orco(DerivedMesh *dm)
1410 {
1411         return ((MultiresDM*)dm)->orco;
1412
1413 }
1414
1415 MVert *MultiresDM_get_subco(DerivedMesh *dm)
1416 {
1417         return ((MultiresDM*)dm)->subco;
1418 }
1419
1420 int MultiresDM_get_totlvl(DerivedMesh *dm)
1421 {
1422         return ((MultiresDM*)dm)->totlvl;
1423 }
1424
1425 int MultiresDM_get_lvl(DerivedMesh *dm)
1426 {
1427         return ((MultiresDM*)dm)->lvl;
1428 }
1429
1430 void MultiresDM_set_orco(DerivedMesh *dm, float (*orco)[3])
1431 {
1432         ((MultiresDM*)dm)->orco = orco;
1433 }
1434
1435 void MultiresDM_set_update(DerivedMesh *dm, void (*update)(DerivedMesh*))
1436 {
1437         ((MultiresDM*)dm)->update = update;
1438 }
1439
1440 ListBase *MultiresDM_get_vert_face_map(DerivedMesh *dm)
1441 {
1442         MultiresDM *mrdm = (MultiresDM*)dm;
1443         Mesh *me = mrdm->ob->data;
1444
1445         if(!mrdm->vert_face_map)
1446                 create_vert_face_map(&mrdm->vert_face_map, &mrdm->vert_face_map_mem, me->mface,
1447                                      me->totvert, me->totface);
1448
1449         return mrdm->vert_face_map;
1450 }
1451
1452 ListBase *MultiresDM_get_vert_edge_map(DerivedMesh *dm)
1453 {
1454         MultiresDM *mrdm = (MultiresDM*)dm;
1455         Mesh *me = mrdm->ob->data;
1456
1457         if(!mrdm->vert_edge_map)
1458                 create_vert_edge_map(&mrdm->vert_edge_map, &mrdm->vert_edge_map_mem, me->medge,
1459                                      me->totvert, me->totedge);
1460
1461         return mrdm->vert_edge_map;
1462 }
1463
1464 int *MultiresDM_get_face_offsets(DerivedMesh *dm)
1465 {
1466         MultiresDM *mrdm = (MultiresDM*)dm;
1467         Mesh *me = mrdm->ob->data;
1468         int i, accum = 0;
1469
1470         if(!mrdm->face_offsets) {
1471                 int len = (int)pow(2, mrdm->lvl - 2) - 1;
1472                 int area = len * len;
1473                 int t = 1 + len * 3 + area * 3, q = t + len + area;
1474
1475                 mrdm->face_offsets = MEM_callocN(sizeof(int) * me->totface, "mrdm face offsets");
1476                 for(i = 0; i < me->totface; ++i) {
1477                         mrdm->face_offsets[i] = accum;
1478
1479                         accum += (me->mface[i].v4 ? q : t);
1480                 }
1481         }
1482
1483         return mrdm->face_offsets;
1484 }
1485
1486 void MultiresDM_mark_as_modified(DerivedMesh *dm)
1487 {
1488         ((MultiresDM*)dm)->modified = 1;
1489 }