2.50: svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r17853...
[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 = DM_get_face_data_layer(dm, CD_MCOL);
486         float *nors= dm->getFaceDataArray(dm, CD_NORMAL);
487         int i, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
488
489         for(i = 0; i < dm->numFaceData; i++, mf++) {
490                 int drawSmooth = (mf->flag & ME_SMOOTH);
491
492                 if(index) {
493                         orig = *index++;
494                         if(setDrawOptions && orig == ORIGINDEX_NONE)
495                                 { if(nors) nors += 3; continue; }
496                 }
497                 else
498                         orig = i;
499
500                 if(!setDrawOptions || setDrawOptions(userData, orig, &drawSmooth)) {
501                         unsigned char *cp = NULL;
502
503                         if(useColors && mc)
504                                 cp = (unsigned char *)&mc[i * 4];
505
506                         glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
507                         glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
508
509                         if (!drawSmooth) {
510                                 if (nors) {
511                                         glNormal3fv(nors);
512                                 }
513                                 else {
514                                         /* TODO make this better (cache facenormals as layer?) */
515                                         float nor[3];
516                                         if(mf->v4) {
517                                                 CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co,
518                                                                            mv[mf->v3].co, mv[mf->v4].co,
519                                                                            nor);
520                                         } else {
521                                                 CalcNormFloat(mv[mf->v1].co, mv[mf->v2].co,
522                                                                           mv[mf->v3].co, nor);
523                                         }
524                                         glNormal3fv(nor);
525                                 }
526
527                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
528                                 glVertex3fv(mv[mf->v1].co);
529                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
530                                 glVertex3fv(mv[mf->v2].co);
531                                 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
532                                 glVertex3fv(mv[mf->v3].co);
533                                 if(mf->v4) {
534                                         if(cp) glColor3ub(cp[15], cp[14], cp[13]);
535                                         glVertex3fv(mv[mf->v4].co);
536                                 }
537                         } else {
538                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
539                                 glNormal3sv(mv[mf->v1].no);
540                                 glVertex3fv(mv[mf->v1].co);
541                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
542                                 glNormal3sv(mv[mf->v2].no);
543                                 glVertex3fv(mv[mf->v2].co);
544                                 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
545                                 glNormal3sv(mv[mf->v3].no);
546                                 glVertex3fv(mv[mf->v3].co);
547                                 if(mf->v4) {
548                                         if(cp) glColor3ub(cp[15], cp[14], cp[13]);
549                                         glNormal3sv(mv[mf->v4].no);
550                                         glVertex3fv(mv[mf->v4].co);
551                                 }
552                         }
553
554                         glEnd();
555                 }
556                 
557                 if (nors) nors += 3;
558         }
559 }
560
561 static void cdDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
562 {
563         cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
564 }
565
566 static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs), int (*setDrawOptions)(void *userData, int index), void *userData)
567 {
568         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
569         GPUVertexAttribs gattribs;
570         DMVertexAttribs attribs;
571         MVert *mvert = cddm->mvert;
572         MFace *mface = cddm->mface;
573         MTFace *tf = dm->getFaceDataArray(dm, CD_MTFACE);
574         float (*nors)[3] = dm->getFaceDataArray(dm, CD_NORMAL);
575         int a, b, dodraw, smoothnormal, matnr, new_matnr;
576         int transp, new_transp, orig_transp;
577         int orig, *index = dm->getFaceDataArray(dm, CD_ORIGINDEX);
578
579         matnr = -1;
580         smoothnormal = 0;
581         dodraw = 0;
582         transp = GPU_get_material_blend_mode();
583         orig_transp = transp;
584
585         memset(&attribs, 0, sizeof(attribs));
586
587         glShadeModel(GL_SMOOTH);
588         glBegin(GL_QUADS);
589
590         for(a = 0; a < dm->numFaceData; a++, mface++) {
591                 new_matnr = mface->mat_nr + 1;
592
593                 if(new_matnr != matnr) {
594                         glEnd();
595
596                         dodraw = setMaterial(matnr = new_matnr, &gattribs);
597                         if(dodraw)
598                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
599
600                         glBegin(GL_QUADS);
601                 }
602
603                 if(!dodraw) {
604                         continue;
605                 }
606                 else if(setDrawOptions) {
607                         orig = index[a];
608
609                         if(orig == ORIGINDEX_NONE)
610                                 continue;
611                         else if(!setDrawOptions(userData, orig))
612                                 continue;
613                 }
614
615                 if(tf) {
616                         new_transp = tf[a].transp;
617
618                         if(new_transp != transp) {
619                                 glEnd();
620
621                                 if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
622                                         GPU_set_material_blend_mode(orig_transp);
623                                 else
624                                         GPU_set_material_blend_mode(new_transp);
625                                 transp = new_transp;
626
627                                 glBegin(GL_QUADS);
628                         }
629                 }
630
631                 smoothnormal = (mface->flag & ME_SMOOTH);
632
633                 if(!smoothnormal) {
634                         if(nors) {
635                                 glNormal3fv(nors[a]);
636                         }
637                         else {
638                                 /* TODO ideally a normal layer should always be available */
639                                 float nor[3];
640                                 if(mface->v4) {
641                                         CalcNormFloat4(mvert[mface->v1].co, mvert[mface->v2].co,
642                                                                    mvert[mface->v3].co, mvert[mface->v4].co,
643                                                                    nor);
644                                 } else {
645                                         CalcNormFloat(mvert[mface->v1].co, mvert[mface->v2].co,
646                                                                   mvert[mface->v3].co, nor);
647                                 }
648                                 glNormal3fv(nor);
649                         }
650                 }
651
652 #define PASSVERT(index, vert) {                                                                                                 \
653         if(attribs.totorco)                                                                                                                     \
654                 glVertexAttrib3fvARB(attribs.orco.glIndex, attribs.orco.array[index]);  \
655         for(b = 0; b < attribs.tottface; b++) {                                                                         \
656                 MTFace *tf = &attribs.tface[b].array[a];                                                                \
657                 glVertexAttrib2fvARB(attribs.tface[b].glIndex, tf->uv[vert]);                   \
658         }                                                                                                                                                       \
659         for(b = 0; b < attribs.totmcol; b++) {                                                                          \
660                 MCol *cp = &attribs.mcol[b].array[a*4 + vert];                                                  \
661                 GLubyte col[4];                                                                                                                 \
662                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;                             \
663                 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col);                                    \
664         }                                                                                                                                                       \
665         if(attribs.tottang) {                                                                                                           \
666                 float *tang = attribs.tang.array[a*4 + vert];                                                   \
667                 glVertexAttrib3fvARB(attribs.tang.glIndex, tang);                                               \
668         }                                                                                                                                                       \
669         if(smoothnormal)                                                                                                                        \
670                 glNormal3sv(mvert[index].no);                                                                                   \
671         glVertex3fv(mvert[index].co);                                                                                           \
672 }
673
674                 PASSVERT(mface->v1, 0);
675                 PASSVERT(mface->v2, 1);
676                 PASSVERT(mface->v3, 2);
677                 if(mface->v4)
678                         PASSVERT(mface->v4, 3)
679                 else
680                         PASSVERT(mface->v3, 2)
681
682 #undef PASSVERT
683         }
684         glEnd();
685
686         glShadeModel(GL_FLAT);
687 }
688
689 static void cdDM_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs))
690 {
691         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
692 }
693
694 static void cdDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
695 {
696         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
697         MVert *vert = cddm->mvert;
698         MEdge *edge = cddm->medge;
699         int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
700
701         glBegin(GL_LINES);
702         for(i = 0; i < dm->numEdgeData; i++, edge++) {
703                 if(index) {
704                         orig = *index++;
705                         if(setDrawOptions && orig == ORIGINDEX_NONE) continue;
706                 }
707                 else
708                         orig = i;
709
710                 if(!setDrawOptions || setDrawOptions(userData, orig)) {
711                         glVertex3fv(vert[edge->v1].co);
712                         glVertex3fv(vert[edge->v2].co);
713                 }
714         }
715         glEnd();
716 }
717
718 static void cdDM_foreachMappedVert(
719                            DerivedMesh *dm,
720                            void (*func)(void *userData, int index, float *co,
721                                         float *no_f, short *no_s),
722                            void *userData)
723 {
724         MVert *mv = CDDM_get_verts(dm);
725         int i, orig, *index = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
726
727         for(i = 0; i < dm->numVertData; i++, mv++) {
728                 if(index) {
729                         orig = *index++;
730                         if(orig == ORIGINDEX_NONE) continue;
731                         func(userData, orig, mv->co, NULL, mv->no);
732                 }
733                 else
734                         func(userData, i, mv->co, NULL, mv->no);
735         }
736 }
737
738 static void cdDM_foreachMappedEdge(
739                            DerivedMesh *dm,
740                            void (*func)(void *userData, int index,
741                                         float *v0co, float *v1co),
742                            void *userData)
743 {
744         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
745         MVert *mv = cddm->mvert;
746         MEdge *med = cddm->medge;
747         int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
748
749         for(i = 0; i < dm->numEdgeData; i++, med++) {
750                 if (index) {
751                         orig = *index++;
752                         if(orig == ORIGINDEX_NONE) continue;
753                         func(userData, orig, mv[med->v1].co, mv[med->v2].co);
754                 }
755                 else
756                         func(userData, i, mv[med->v1].co, mv[med->v2].co);
757         }
758 }
759
760 static void cdDM_foreachMappedFaceCenter(
761                            DerivedMesh *dm,
762                            void (*func)(void *userData, int index,
763                                         float *cent, float *no),
764                            void *userData)
765 {
766         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
767         MVert *mv = cddm->mvert;
768         MFace *mf = cddm->mface;
769         int i, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
770
771         for(i = 0; i < dm->numFaceData; i++, mf++) {
772                 float cent[3];
773                 float no[3];
774
775                 if (index) {
776                         orig = *index++;
777                         if(orig == ORIGINDEX_NONE) continue;
778                 }
779                 else
780                         orig = i;
781
782                 VECCOPY(cent, mv[mf->v1].co);
783                 VecAddf(cent, cent, mv[mf->v2].co);
784                 VecAddf(cent, cent, mv[mf->v3].co);
785
786                 if (mf->v4) {
787                         CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co,
788                                        mv[mf->v3].co, mv[mf->v4].co, no);
789                         VecAddf(cent, cent, mv[mf->v4].co);
790                         VecMulf(cent, 0.25f);
791                 } else {
792                         CalcNormFloat(mv[mf->v1].co, mv[mf->v2].co,
793                                       mv[mf->v3].co, no);
794                         VecMulf(cent, 0.33333333333f);
795                 }
796
797                 func(userData, orig, cent, no);
798         }
799 }
800
801 static void cdDM_release(DerivedMesh *dm)
802 {
803         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
804
805         if (DM_release(dm))
806                 MEM_freeN(cddm);
807 }
808
809 /**************** CDDM interface functions ****************/
810 static CDDerivedMesh *cdDM_create(const char *desc)
811 {
812         CDDerivedMesh *cddm;
813         DerivedMesh *dm;
814
815         cddm = MEM_callocN(sizeof(*cddm), desc);
816         dm = &cddm->dm;
817
818         dm->getMinMax = cdDM_getMinMax;
819
820         dm->getNumVerts = cdDM_getNumVerts;
821         dm->getNumFaces = cdDM_getNumFaces;
822         dm->getNumEdges = cdDM_getNumEdges;
823
824         dm->getVert = cdDM_getVert;
825         dm->getEdge = cdDM_getEdge;
826         dm->getFace = cdDM_getFace;
827         dm->copyVertArray = cdDM_copyVertArray;
828         dm->copyEdgeArray = cdDM_copyEdgeArray;
829         dm->copyFaceArray = cdDM_copyFaceArray;
830         dm->getVertData = DM_get_vert_data;
831         dm->getEdgeData = DM_get_edge_data;
832         dm->getFaceData = DM_get_face_data;
833         dm->getVertDataArray = DM_get_vert_data_layer;
834         dm->getEdgeDataArray = DM_get_edge_data_layer;
835         dm->getFaceDataArray = DM_get_face_data_layer;
836
837         dm->getVertCos = cdDM_getVertCos;
838         dm->getVertCo = cdDM_getVertCo;
839         dm->getVertNo = cdDM_getVertNo;
840
841         dm->drawVerts = cdDM_drawVerts;
842
843         dm->drawUVEdges = cdDM_drawUVEdges;
844         dm->drawEdges = cdDM_drawEdges;
845         dm->drawLooseEdges = cdDM_drawLooseEdges;
846         dm->drawMappedEdges = cdDM_drawMappedEdges;
847
848         dm->drawFacesSolid = cdDM_drawFacesSolid;
849         dm->drawFacesColored = cdDM_drawFacesColored;
850         dm->drawFacesTex = cdDM_drawFacesTex;
851         dm->drawFacesGLSL = cdDM_drawFacesGLSL;
852         dm->drawMappedFaces = cdDM_drawMappedFaces;
853         dm->drawMappedFacesTex = cdDM_drawMappedFacesTex;
854         dm->drawMappedFacesGLSL = cdDM_drawMappedFacesGLSL;
855
856         dm->foreachMappedVert = cdDM_foreachMappedVert;
857         dm->foreachMappedEdge = cdDM_foreachMappedEdge;
858         dm->foreachMappedFaceCenter = cdDM_foreachMappedFaceCenter;
859
860         dm->release = cdDM_release;
861
862         return cddm;
863 }
864
865 DerivedMesh *CDDM_new(int numVerts, int numEdges, int numFaces)
866 {
867         CDDerivedMesh *cddm = cdDM_create("CDDM_new dm");
868         DerivedMesh *dm = &cddm->dm;
869
870         DM_init(dm, numVerts, numEdges, numFaces);
871
872         CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
873         CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
874         CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numFaces);
875
876         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
877         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
878         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numFaces);
879
880         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
881         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
882         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
883
884         return dm;
885 }
886
887 DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *ob)
888 {
889         CDDerivedMesh *cddm = cdDM_create("CDDM_from_mesh dm");
890         DerivedMesh *dm = &cddm->dm;
891         CustomDataMask mask = CD_MASK_MESH & (~CD_MASK_MDISPS);
892         int i, *index, alloctype;
893
894         /* this does a referenced copy, the only new layers being ORIGINDEX,
895          * with an exception for fluidsim */
896
897         DM_init(dm, mesh->totvert, mesh->totedge, mesh->totface);
898
899         CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totvert);
900         CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totedge);
901         CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totface);
902
903         dm->deformedOnly = 1;
904
905         alloctype= CD_REFERENCE;
906
907         CustomData_merge(&mesh->vdata, &dm->vertData, mask, alloctype,
908                          mesh->totvert);
909         CustomData_merge(&mesh->edata, &dm->edgeData, mask, alloctype,
910                          mesh->totedge);
911         CustomData_merge(&mesh->fdata, &dm->faceData, mask, alloctype,
912                          mesh->totface);
913
914         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
915         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
916         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
917
918         index = CustomData_get_layer(&dm->vertData, CD_ORIGINDEX);
919         for(i = 0; i < mesh->totvert; ++i, ++index)
920                 *index = i;
921
922         index = CustomData_get_layer(&dm->edgeData, CD_ORIGINDEX);
923         for(i = 0; i < mesh->totedge; ++i, ++index)
924                 *index = i;
925
926         index = CustomData_get_layer(&dm->faceData, CD_ORIGINDEX);
927         for(i = 0; i < mesh->totface; ++i, ++index)
928                 *index = i;
929         
930         /* works in conjunction with hack during modifier calc, where active mcol
931            layer with weight paint colors is temporarily added */
932         /* XXX make this real but temporary layer */
933 //      if ((G.f & G_WEIGHTPAINT) &&
934 //              (ob && ob==(scene->basact?scene->basact->object:NULL)))
935 //              CustomData_duplicate_referenced_layer(&dm->faceData, CD_MCOL);
936
937         return dm;
938 }
939
940 DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
941 {
942         DerivedMesh *dm = CDDM_new(BLI_countlist(&em->verts),
943                                    BLI_countlist(&em->edges),
944                                    BLI_countlist(&em->faces));
945         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
946         EditVert *eve;
947         EditEdge *eed;
948         EditFace *efa;
949         MVert *mvert = cddm->mvert;
950         MEdge *medge = cddm->medge;
951         MFace *mface = cddm->mface;
952         int i, *index;
953
954         dm->deformedOnly = 1;
955
956         CustomData_merge(&em->vdata, &dm->vertData, CD_MASK_DERIVEDMESH,
957                          CD_CALLOC, dm->numVertData);
958         /* CustomData_merge(&em->edata, &dm->edgeData, CD_MASK_DERIVEDMESH,
959                          CD_CALLOC, dm->numEdgeData); */
960         CustomData_merge(&em->fdata, &dm->faceData, CD_MASK_DERIVEDMESH,
961                          CD_CALLOC, dm->numFaceData);
962
963         /* set eve->hash to vert index */
964         for(i = 0, eve = em->verts.first; eve; eve = eve->next, ++i)
965                 eve->tmp.l = i;
966
967         /* Need to be able to mark loose edges */
968         for(eed = em->edges.first; eed; eed = eed->next) {
969                 eed->f2 = 0;
970         }
971         for(efa = em->faces.first; efa; efa = efa->next) {
972                 efa->e1->f2 = 1;
973                 efa->e2->f2 = 1;
974                 efa->e3->f2 = 1;
975                 if(efa->e4) efa->e4->f2 = 1;
976         }
977
978         index = dm->getVertDataArray(dm, CD_ORIGINDEX);
979         for(i = 0, eve = em->verts.first; i < dm->numVertData;
980             i++, eve = eve->next, index++) {
981                 MVert *mv = &mvert[i];
982
983                 VECCOPY(mv->co, eve->co);
984
985                 mv->no[0] = eve->no[0] * 32767.0;
986                 mv->no[1] = eve->no[1] * 32767.0;
987                 mv->no[2] = eve->no[2] * 32767.0;
988                 mv->bweight = (unsigned char) (eve->bweight * 255.0f);
989
990                 mv->mat_nr = 0;
991                 mv->flag = 0;
992
993                 *index = i;
994
995                 CustomData_from_em_block(&em->vdata, &dm->vertData, eve->data, i);
996         }
997
998         index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
999         for(i = 0, eed = em->edges.first; i < dm->numEdgeData;
1000             i++, eed = eed->next, index++) {
1001                 MEdge *med = &medge[i];
1002
1003                 med->v1 = eed->v1->tmp.l;
1004                 med->v2 = eed->v2->tmp.l;
1005                 med->crease = (unsigned char) (eed->crease * 255.0f);
1006                 med->bweight = (unsigned char) (eed->bweight * 255.0f);
1007                 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
1008                 
1009                 if(eed->seam) med->flag |= ME_SEAM;
1010                 if(eed->sharp) med->flag |= ME_SHARP;
1011                 if(!eed->f2) med->flag |= ME_LOOSEEDGE;
1012
1013                 *index = i;
1014
1015                 /* CustomData_from_em_block(&em->edata, &dm->edgeData, eed->data, i); */
1016         }
1017
1018         index = dm->getFaceDataArray(dm, CD_ORIGINDEX);
1019         for(i = 0, efa = em->faces.first; i < dm->numFaceData;
1020             i++, efa = efa->next, index++) {
1021                 MFace *mf = &mface[i];
1022
1023                 mf->v1 = efa->v1->tmp.l;
1024                 mf->v2 = efa->v2->tmp.l;
1025                 mf->v3 = efa->v3->tmp.l;
1026                 mf->v4 = efa->v4 ? efa->v4->tmp.l : 0;
1027                 mf->mat_nr = efa->mat_nr;
1028                 mf->flag = efa->flag;
1029
1030                 *index = i;
1031
1032                 CustomData_from_em_block(&em->fdata, &dm->faceData, efa->data, i);
1033                 test_index_face(mf, &dm->faceData, i, efa->v4?4:3);
1034         }
1035
1036         return dm;
1037 }
1038
1039 DerivedMesh *CDDM_copy(DerivedMesh *source)
1040 {
1041         CDDerivedMesh *cddm = cdDM_create("CDDM_copy cddm");
1042         DerivedMesh *dm = &cddm->dm;
1043         int numVerts = source->numVertData;
1044         int numEdges = source->numEdgeData;
1045         int numFaces = source->numFaceData;
1046
1047         /* this initializes dm, and copies all non mvert/medge/mface layers */
1048         DM_from_template(dm, source, numVerts, numEdges, numFaces);
1049         dm->deformedOnly = source->deformedOnly;
1050
1051         CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts);
1052         CustomData_copy_data(&source->edgeData, &dm->edgeData, 0, 0, numEdges);
1053         CustomData_copy_data(&source->faceData, &dm->faceData, 0, 0, numFaces);
1054
1055         /* now add mvert/medge/mface layers */
1056         cddm->mvert = source->dupVertArray(source);
1057         cddm->medge = source->dupEdgeArray(source);
1058         cddm->mface = source->dupFaceArray(source);
1059
1060         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, cddm->mvert, numVerts);
1061         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, cddm->medge, numEdges);
1062         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, cddm->mface, numFaces);
1063
1064         return dm;
1065 }
1066
1067 DerivedMesh *CDDM_from_template(DerivedMesh *source,
1068                                 int numVerts, int numEdges, int numFaces)
1069 {
1070         CDDerivedMesh *cddm = cdDM_create("CDDM_from_template dest");
1071         DerivedMesh *dm = &cddm->dm;
1072
1073         /* this does a copy of all non mvert/medge/mface layers */
1074         DM_from_template(dm, source, numVerts, numEdges, numFaces);
1075
1076         /* now add mvert/medge/mface layers */
1077         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
1078         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
1079         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numFaces);
1080
1081         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1082         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1083         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1084
1085         return dm;
1086 }
1087
1088 void CDDM_apply_vert_coords(DerivedMesh *dm, float (*vertCoords)[3])
1089 {
1090         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1091         MVert *vert;
1092         int i;
1093
1094         /* this will just return the pointer if it wasn't a referenced layer */
1095         vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
1096         cddm->mvert = vert;
1097
1098         for(i = 0; i < dm->numVertData; ++i, ++vert)
1099                 VECCOPY(vert->co, vertCoords[i]);
1100 }
1101
1102 void CDDM_apply_vert_normals(DerivedMesh *dm, short (*vertNormals)[3])
1103 {
1104         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1105         MVert *vert;
1106         int i;
1107
1108         /* this will just return the pointer if it wasn't a referenced layer */
1109         vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
1110         cddm->mvert = vert;
1111
1112         for(i = 0; i < dm->numVertData; ++i, ++vert)
1113                 VECCOPY(vert->no, vertNormals[i]);
1114 }
1115
1116 /* adapted from mesh_calc_normals */
1117 void CDDM_calc_normals(DerivedMesh *dm)
1118 {
1119         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1120         float (*temp_nors)[3];
1121         float (*face_nors)[3];
1122         int i;
1123         int numVerts = dm->numVertData;
1124         int numFaces = dm->numFaceData;
1125         MFace *mf;
1126         MVert *mv;
1127
1128         if(numVerts == 0) return;
1129
1130         temp_nors = MEM_callocN(numVerts * sizeof(*temp_nors),
1131                                 "CDDM_calc_normals temp_nors");
1132
1133         /* we don't want to overwrite any referenced layers */
1134         mv = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
1135         cddm->mvert = mv;
1136
1137         /* make a face normal layer if not present */
1138         face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
1139         if(!face_nors)
1140                 face_nors = CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_CALLOC,
1141                                                  NULL, dm->numFaceData);
1142
1143         /* calculate face normals and add to vertex normals */
1144         mf = CDDM_get_faces(dm);
1145         for(i = 0; i < numFaces; i++, mf++) {
1146                 float *f_no = face_nors[i];
1147
1148                 if(mf->v4)
1149                         CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co,
1150                                        mv[mf->v3].co, mv[mf->v4].co, f_no);
1151                 else
1152                         CalcNormFloat(mv[mf->v1].co, mv[mf->v2].co,
1153                                       mv[mf->v3].co, f_no);
1154                 
1155                 VecAddf(temp_nors[mf->v1], temp_nors[mf->v1], f_no);
1156                 VecAddf(temp_nors[mf->v2], temp_nors[mf->v2], f_no);
1157                 VecAddf(temp_nors[mf->v3], temp_nors[mf->v3], f_no);
1158                 if(mf->v4)
1159                         VecAddf(temp_nors[mf->v4], temp_nors[mf->v4], f_no);
1160         }
1161
1162         /* normalize vertex normals and assign */
1163         for(i = 0; i < numVerts; i++, mv++) {
1164                 float *no = temp_nors[i];
1165                 
1166                 if (Normalize(no) == 0.0) {
1167                         VECCOPY(no, mv->co);
1168                         Normalize(no);
1169                 }
1170
1171                 mv->no[0] = (short)(no[0] * 32767.0);
1172                 mv->no[1] = (short)(no[1] * 32767.0);
1173                 mv->no[2] = (short)(no[2] * 32767.0);
1174         }
1175         
1176         MEM_freeN(temp_nors);
1177 }
1178
1179 void CDDM_calc_edges(DerivedMesh *dm)
1180 {
1181         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1182         CustomData edgeData;
1183         EdgeHashIterator *ehi;
1184         MFace *mf = cddm->mface;
1185         MEdge *med;
1186         EdgeHash *eh = BLI_edgehash_new();
1187         int i, *index, numEdges, maxFaces = dm->numFaceData;
1188
1189         for (i = 0; i < maxFaces; i++, mf++) {
1190                 if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
1191                         BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
1192                 if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
1193                         BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
1194                 
1195                 if (mf->v4) {
1196                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
1197                                 BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
1198                         if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
1199                                 BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
1200                 } else {
1201                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
1202                                 BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
1203                 }
1204         }
1205
1206         numEdges = BLI_edgehash_size(eh);
1207
1208         /* write new edges into a temporary CustomData */
1209         memset(&edgeData, 0, sizeof(edgeData));
1210         CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
1211         CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
1212
1213         ehi = BLI_edgehashIterator_new(eh);
1214         med = CustomData_get_layer(&edgeData, CD_MEDGE);
1215         index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
1216         for(i = 0; !BLI_edgehashIterator_isDone(ehi);
1217             BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) {
1218                 BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2);
1219
1220                 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
1221                 *index = ORIGINDEX_NONE;
1222         }
1223         BLI_edgehashIterator_free(ehi);
1224
1225         /* free old CustomData and assign new one */
1226         CustomData_free(&dm->edgeData, dm->numVertData);
1227         dm->edgeData = edgeData;
1228         dm->numEdgeData = numEdges;
1229
1230         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1231
1232         BLI_edgehash_free(eh, NULL);
1233 }
1234
1235 void CDDM_lower_num_verts(DerivedMesh *dm, int numVerts)
1236 {
1237         if (numVerts < dm->numVertData)
1238                 CustomData_free_elem(&dm->vertData, numVerts, dm->numVertData-numVerts);
1239
1240         dm->numVertData = numVerts;
1241 }
1242
1243 void CDDM_lower_num_edges(DerivedMesh *dm, int numEdges)
1244 {
1245         if (numEdges < dm->numEdgeData)
1246                 CustomData_free_elem(&dm->edgeData, numEdges, dm->numEdgeData-numEdges);
1247
1248         dm->numEdgeData = numEdges;
1249 }
1250
1251 void CDDM_lower_num_faces(DerivedMesh *dm, int numFaces)
1252 {
1253         if (numFaces < dm->numFaceData)
1254                 CustomData_free_elem(&dm->faceData, numFaces, dm->numFaceData-numFaces);
1255
1256         dm->numFaceData = numFaces;
1257 }
1258
1259 MVert *CDDM_get_vert(DerivedMesh *dm, int index)
1260 {
1261         return &((CDDerivedMesh*)dm)->mvert[index];
1262 }
1263
1264 MEdge *CDDM_get_edge(DerivedMesh *dm, int index)
1265 {
1266         return &((CDDerivedMesh*)dm)->medge[index];
1267 }
1268
1269 MFace *CDDM_get_face(DerivedMesh *dm, int index)
1270 {
1271         return &((CDDerivedMesh*)dm)->mface[index];
1272 }
1273
1274 MVert *CDDM_get_verts(DerivedMesh *dm)
1275 {
1276         return ((CDDerivedMesh*)dm)->mvert;
1277 }
1278
1279 MEdge *CDDM_get_edges(DerivedMesh *dm)
1280 {
1281         return ((CDDerivedMesh*)dm)->medge;
1282 }
1283
1284 MFace *CDDM_get_faces(DerivedMesh *dm)
1285 {
1286         return ((CDDerivedMesh*)dm)->mface;
1287 }
1288
1289 /* Multires DerivedMesh, extends CDDM */
1290 typedef struct MultiresDM {
1291         CDDerivedMesh cddm;
1292
1293         MultiresModifierData *mmd;
1294
1295         int lvl, totlvl;
1296         float (*orco)[3];
1297         MVert *subco;
1298
1299         ListBase *vert_face_map, *vert_edge_map;
1300         IndexNode *vert_face_map_mem, *vert_edge_map_mem;
1301         int *face_offsets;
1302
1303         Mesh *me;
1304         int flags;
1305
1306         void (*update)(DerivedMesh*);
1307 } MultiresDM;
1308
1309 static void MultiresDM_release(DerivedMesh *dm)
1310 {
1311         MultiresDM *mrdm = (MultiresDM*)dm;
1312         int mvert_layer;
1313
1314         /* Before freeing, need to update the displacement map */
1315         if(dm->needsFree && !(mrdm->flags & MULTIRES_DM_UPDATE_BLOCK))
1316                 mrdm->update(dm);
1317
1318         /* If the MVert data is being used as the sculpt undo store, don't free it */
1319         mvert_layer = CustomData_get_layer_index(&dm->vertData, CD_MVERT);
1320         if(mvert_layer != -1) {
1321                 CustomDataLayer *cd = &dm->vertData.layers[mvert_layer];
1322                 if(cd->data == mrdm->mmd->undo_verts)
1323                         cd->flag |= CD_FLAG_NOFREE;
1324         }
1325
1326         if(DM_release(dm)) {
1327                 MEM_freeN(mrdm->subco);
1328                 MEM_freeN(mrdm->orco);
1329                 if(mrdm->vert_face_map)
1330                         MEM_freeN(mrdm->vert_face_map);
1331                 if(mrdm->vert_face_map_mem)
1332                         MEM_freeN(mrdm->vert_face_map_mem);
1333                 if(mrdm->vert_edge_map)
1334                         MEM_freeN(mrdm->vert_edge_map);
1335                 if(mrdm->vert_edge_map_mem)
1336                         MEM_freeN(mrdm->vert_edge_map_mem);
1337                 if(mrdm->face_offsets)
1338                         MEM_freeN(mrdm->face_offsets);
1339                 MEM_freeN(mrdm);
1340         }
1341 }
1342
1343 DerivedMesh *MultiresDM_new(MultiresSubsurf *ms, DerivedMesh *orig, int numVerts, int numEdges, int numFaces)
1344 {
1345         MultiresDM *mrdm = MEM_callocN(sizeof(MultiresDM), "MultiresDM");
1346         CDDerivedMesh *cddm = cdDM_create("MultiresDM CDDM");
1347         DerivedMesh *dm = NULL;
1348
1349         mrdm->cddm = *cddm;
1350         MEM_freeN(cddm);
1351         dm = &mrdm->cddm.dm;
1352
1353         mrdm->mmd = ms->mmd;
1354         mrdm->me = ms->me;
1355
1356         if(dm) {
1357                 MDisps *disps;
1358                 MVert *mvert;
1359                 int i;
1360
1361                 DM_from_template(dm, orig, numVerts, numEdges, numFaces);
1362                 CustomData_free_layers(&dm->faceData, CD_MDISPS, numFaces);
1363
1364                 disps = CustomData_get_layer(&orig->faceData, CD_MDISPS);
1365                 if(disps)
1366                         CustomData_add_layer(&dm->faceData, CD_MDISPS, CD_REFERENCE, disps, numFaces);
1367
1368
1369                 mvert = CustomData_get_layer(&orig->vertData, CD_MVERT);
1370                 mrdm->orco = MEM_callocN(sizeof(float) * 3 * orig->getNumVerts(orig), "multires orco");
1371                 for(i = 0; i < orig->getNumVerts(orig); ++i)
1372                         VecCopyf(mrdm->orco[i], mvert[i].co);
1373         }
1374         else
1375                 DM_init(dm, numVerts, numEdges, numFaces);
1376
1377         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
1378         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
1379         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numFaces);
1380
1381         mrdm->cddm.mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1382         mrdm->cddm.medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1383         mrdm->cddm.mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1384
1385         mrdm->lvl = ms->mmd->lvl;
1386         mrdm->totlvl = ms->mmd->totlvl;
1387         mrdm->subco = MEM_callocN(sizeof(MVert)*numVerts, "multires subdivided verts");
1388         mrdm->flags = 0;
1389
1390         dm->release = MultiresDM_release;
1391
1392         return dm;
1393 }
1394
1395 Mesh *MultiresDM_get_mesh(DerivedMesh *dm)
1396 {
1397         return ((MultiresDM*)dm)->me;
1398 }
1399
1400 void *MultiresDM_get_orco(DerivedMesh *dm)
1401 {
1402         return ((MultiresDM*)dm)->orco;
1403
1404 }
1405
1406 MVert *MultiresDM_get_subco(DerivedMesh *dm)
1407 {
1408         return ((MultiresDM*)dm)->subco;
1409 }
1410
1411 int MultiresDM_get_totlvl(DerivedMesh *dm)
1412 {
1413         return ((MultiresDM*)dm)->totlvl;
1414 }
1415
1416 int MultiresDM_get_lvl(DerivedMesh *dm)
1417 {
1418         return ((MultiresDM*)dm)->lvl;
1419 }
1420
1421 void MultiresDM_set_orco(DerivedMesh *dm, float (*orco)[3])
1422 {
1423         ((MultiresDM*)dm)->orco = orco;
1424 }
1425
1426 void MultiresDM_set_update(DerivedMesh *dm, void (*update)(DerivedMesh*))
1427 {
1428         ((MultiresDM*)dm)->update = update;
1429 }
1430
1431 ListBase *MultiresDM_get_vert_face_map(DerivedMesh *dm)
1432 {
1433         MultiresDM *mrdm = (MultiresDM*)dm;
1434
1435         if(!mrdm->vert_face_map)
1436                 create_vert_face_map(&mrdm->vert_face_map, &mrdm->vert_face_map_mem, mrdm->me->mface,
1437                                      mrdm->me->totvert, mrdm->me->totface);
1438
1439         return mrdm->vert_face_map;
1440 }
1441
1442 ListBase *MultiresDM_get_vert_edge_map(DerivedMesh *dm)
1443 {
1444         MultiresDM *mrdm = (MultiresDM*)dm;
1445
1446         if(!mrdm->vert_edge_map)
1447                 create_vert_edge_map(&mrdm->vert_edge_map, &mrdm->vert_edge_map_mem, mrdm->me->medge,
1448                                      mrdm->me->totvert, mrdm->me->totedge);
1449
1450         return mrdm->vert_edge_map;
1451 }
1452
1453 int *MultiresDM_get_face_offsets(DerivedMesh *dm)
1454 {
1455         MultiresDM *mrdm = (MultiresDM*)dm;
1456         int i, accum = 0;
1457
1458         if(!mrdm->face_offsets) {
1459                 int len = (int)pow(2, mrdm->lvl - 2) - 1;
1460                 int area = len * len;
1461                 int t = 1 + len * 3 + area * 3, q = t + len + area;
1462
1463                 mrdm->face_offsets = MEM_callocN(sizeof(int) * mrdm->me->totface, "mrdm face offsets");
1464                 for(i = 0; i < mrdm->me->totface; ++i) {
1465                         mrdm->face_offsets[i] = accum;
1466
1467                         accum += (mrdm->me->mface[i].v4 ? q : t);
1468                 }
1469         }
1470
1471         return mrdm->face_offsets;
1472 }
1473
1474 int *MultiresDM_get_flags(DerivedMesh *dm)
1475 {
1476         return &((MultiresDM*)dm)->flags;
1477 }