Making compiler happy;
[blender.git] / source / blender / blenkernel / intern / DerivedMesh.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL 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. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2005 Blender Foundation.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33 #include <string.h>
34
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39 #include "PIL_time.h"
40
41 #include "MEM_guardedalloc.h"
42
43 #include "DNA_effect_types.h"
44 #include "DNA_mesh_types.h"
45 #include "DNA_meshdata_types.h"
46 #include "DNA_modifier_types.h"
47 #include "DNA_object_types.h"
48 #include "DNA_object_force.h"
49
50 #include "BLI_arithb.h"
51 #include "BLI_blenlib.h"
52 #include "BLI_editVert.h"
53
54 #include "BKE_utildefines.h"
55 #include "BKE_DerivedMesh.h"
56 #include "BKE_displist.h"
57 #include "BKE_effect.h"
58 #include "BKE_global.h"
59 #include "BKE_material.h"
60 #include "BKE_mesh.h"
61 #include "BKE_object.h"
62 #include "BKE_subsurf.h"
63 #include "BKE_deform.h"
64 #include "BKE_modifier.h"
65 #include "BKE_key.h"
66
67 #include "BIF_gl.h"
68 #include "BIF_glutil.h"
69
70 ///////////////////////////////////
71 ///////////////////////////////////
72
73 typedef struct {
74         DerivedMesh dm;
75
76         Object *ob;
77         Mesh *me;
78         MVert *verts;
79         float *nors;
80         MCol *wpaintMCol;
81
82         int freeNors, freeVerts;
83 } MeshDerivedMesh;
84
85 static DispListMesh *meshDM_convertToDispListMesh(DerivedMesh *dm, int allowShared)
86 {
87         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
88         Mesh *me = mdm->me;
89         DispListMesh *dlm = MEM_callocN(sizeof(*dlm), "dlm");
90
91         dlm->totvert = me->totvert;
92         dlm->totedge = me->totedge;
93         dlm->totface = me->totface;
94         dlm->mvert = mdm->verts;
95         dlm->medge = me->medge;
96         dlm->mface = me->mface;
97         dlm->tface = me->tface;
98         dlm->mcol = me->mcol;
99         dlm->nors = mdm->nors;
100         dlm->dontFreeVerts = dlm->dontFreeOther = dlm->dontFreeNors = 1;
101
102         if (!allowShared) {
103                 dlm->mvert = MEM_dupallocN(dlm->mvert);
104                 if (dlm->nors) dlm->nors = MEM_dupallocN(dlm->nors);
105
106                 dlm->dontFreeVerts = dlm->dontFreeNors = 0;
107         }
108
109         return dlm;
110 }
111
112 static void meshDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
113 {
114         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
115         Mesh *me = mdm->me;
116         int i;
117
118         if (me->totvert) {
119                 for (i=0; i<me->totvert; i++) {
120                         DO_MINMAX(mdm->verts[i].co, min_r, max_r);
121                 }
122         } else {
123                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
124         }
125 }
126
127 static void meshDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
128 {
129         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
130         Mesh *me = mdm->me;
131         int i;
132
133         for (i=0; i<me->totvert; i++) {
134                 cos_r[i][0] = mdm->verts[i].co[0];
135                 cos_r[i][1] = mdm->verts[i].co[1];
136                 cos_r[i][2] = mdm->verts[i].co[2];
137         }
138 }
139
140 static void meshDM_getVertCo(DerivedMesh *dm, int index, float co_r[3])
141 {
142         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
143
144         VECCOPY(co_r, mdm->verts[index].co);
145 }
146
147 static void meshDM_getVertNo(DerivedMesh *dm, int index, float no_r[3])
148 {
149         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
150         short *no = mdm->verts[index].no;
151
152         no_r[0] = no[0]/32767.f;
153         no_r[1] = no[1]/32767.f;
154         no_r[2] = no[2]/32767.f;
155 }
156
157 static void meshDM_drawVerts(DerivedMesh *dm)
158 {
159         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
160         Mesh *me = mdm->me;
161         int i;
162
163         glBegin(GL_POINTS);
164         for(i=0; i<me->totvert; i++) {
165                 glVertex3fv(mdm->verts[i].co);
166         }
167         glEnd();
168 }
169 static void meshDM_drawUVEdges(DerivedMesh *dm)
170 {
171         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
172         Mesh *me = mdm->me;
173         int i;
174
175         if (me->tface) {
176                 glBegin(GL_LINES);
177                 for (i=0; i<me->totface; i++) {
178                         TFace *tf = &me->tface[i];
179
180                         if (!(tf->flag&TF_HIDE)) {
181                                 glVertex2fv(tf->uv[0]);
182                                 glVertex2fv(tf->uv[1]);
183
184                                 glVertex2fv(tf->uv[1]);
185                                 glVertex2fv(tf->uv[2]);
186
187                                 if (!me->mface[i].v4) {
188                                         glVertex2fv(tf->uv[2]);
189                                         glVertex2fv(tf->uv[0]);
190                                 } else {
191                                         glVertex2fv(tf->uv[2]);
192                                         glVertex2fv(tf->uv[3]);
193
194                                         glVertex2fv(tf->uv[3]);
195                                         glVertex2fv(tf->uv[0]);
196                                 }
197                         }
198                 }
199                 glEnd();
200         }
201 }
202 static void meshDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
203 {
204         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
205         Mesh *me= mdm->me;
206         MEdge *medge= me->medge;
207         int i;
208                 
209         glBegin(GL_LINES);
210         for(i=0; i<me->totedge; i++, medge++) {
211                 if ((medge->flag&ME_EDGEDRAW) && (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) {
212                         glVertex3fv(mdm->verts[medge->v1].co);
213                         glVertex3fv(mdm->verts[medge->v2].co);
214                 }
215         }
216         glEnd();
217 }
218 static void meshDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
219 {
220         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
221         Mesh *me= mdm->me;
222         int i;
223                 
224         glBegin(GL_LINES);
225         for (i=0; i<me->totedge; i++) {
226                 if (!setDrawOptions || setDrawOptions(userData, i)) {
227                         glVertex3fv(mdm->verts[me->medge[i].v1].co);
228                         glVertex3fv(mdm->verts[me->medge[i].v2].co);
229                 }
230         }
231         glEnd();
232 }
233 static void meshDM_drawLooseEdges(DerivedMesh *dm)
234 {
235         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
236         Mesh *me= mdm->me;
237         MEdge *medge= me->medge;
238         int i;
239
240         glBegin(GL_LINES);
241         for (i=0; i<me->totedge; i++, medge++) {
242                 if (medge->flag&ME_LOOSEEDGE) {
243                         glVertex3fv(mdm->verts[medge->v1].co);
244                         glVertex3fv(mdm->verts[medge->v2].co);
245                 }
246         }
247         glEnd();
248 }
249 static void meshDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int))
250 {
251         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
252         Mesh *me = mdm->me;
253         MVert *mvert= mdm->verts;
254         MFace *mface= me->mface;
255         float *nors = mdm->nors;
256         int a;
257         int glmode=-1, shademodel=-1, matnr=-1, drawCurrentMat=1;
258
259 #define PASSVERT(index) {                                               \
260         if (shademodel==GL_SMOOTH) {                            \
261                 short *no = mvert[index].no;                    \
262                 glNormal3sv(no);                                                \
263         }                                                                                       \
264         glVertex3fv(mvert[index].co);   \
265 }
266
267         glBegin(glmode=GL_QUADS);
268         for(a=0; a<me->totface; a++, mface++, nors+=3) {
269                 int new_glmode, new_matnr, new_shademodel;
270                         
271                 new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES;
272                 new_matnr = mface->mat_nr+1;
273                 new_shademodel = (!(me->flag&ME_AUTOSMOOTH) && (mface->flag & ME_SMOOTH))?GL_SMOOTH:GL_FLAT;
274                 
275                 if (new_glmode!=glmode || new_matnr!=matnr || new_shademodel!=shademodel) {
276                         glEnd();
277
278                         drawCurrentMat = setMaterial(matnr=new_matnr);
279
280                         glShadeModel(shademodel=new_shademodel);
281                         glBegin(glmode=new_glmode);
282                 } 
283                 
284                 if (drawCurrentMat) {
285                         if(shademodel==GL_FLAT) 
286                                 glNormal3fv(nors);
287
288                         PASSVERT(mface->v1);
289                         PASSVERT(mface->v2);
290                         PASSVERT(mface->v3);
291                         if (mface->v4) {
292                                 PASSVERT(mface->v4);
293                         }
294                 }
295         }
296         glEnd();
297
298         glShadeModel(GL_FLAT);
299 #undef PASSVERT
300 }
301
302 static void meshDM_drawFacesColored(DerivedMesh *dm, int useTwoSide, unsigned char *col1, unsigned char *col2)
303 {
304         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
305         Mesh *me= mdm->me;
306         MFace *mface= me->mface;
307         int a, glmode;
308         unsigned char *cp1, *cp2;
309
310         cp1= col1;
311         if(col2) {
312                 cp2= col2;
313         } else {
314                 cp2= NULL;
315                 useTwoSide= 0;
316         }
317
318         /* there's a conflict here... twosided colors versus culling...? */
319         /* defined by history, only texture faces have culling option */
320         /* we need that as mesh option builtin, next to double sided lighting */
321         if(col1 && col2)
322                 glEnable(GL_CULL_FACE);
323         
324         glShadeModel(GL_SMOOTH);
325         glBegin(glmode=GL_QUADS);
326         for(a=0; a<me->totface; a++, mface++, cp1+= 16) {
327                 int new_glmode= mface->v4?GL_QUADS:GL_TRIANGLES;
328
329                 if (new_glmode!=glmode) {
330                         glEnd();
331                         glBegin(glmode= new_glmode);
332                 }
333                         
334                 glColor3ub(cp1[3], cp1[2], cp1[1]);
335                 glVertex3fv( mdm->verts[mface->v1].co );
336                 glColor3ub(cp1[7], cp1[6], cp1[5]);
337                 glVertex3fv( mdm->verts[mface->v2].co );
338                 glColor3ub(cp1[11], cp1[10], cp1[9]);
339                 glVertex3fv( mdm->verts[mface->v3].co );
340                 if(mface->v4) {
341                         glColor3ub(cp1[15], cp1[14], cp1[13]);
342                         glVertex3fv( mdm->verts[mface->v4].co );
343                 }
344                         
345                 if(useTwoSide) {
346                         glColor3ub(cp2[11], cp2[10], cp2[9]);
347                         glVertex3fv( mdm->verts[mface->v3].co );
348                         glColor3ub(cp2[7], cp2[6], cp2[5]);
349                         glVertex3fv( mdm->verts[mface->v2].co );
350                         glColor3ub(cp2[3], cp2[2], cp2[1]);
351                         glVertex3fv( mdm->verts[mface->v1].co );
352                         if(mface->v4) {
353                                 glColor3ub(cp2[15], cp2[14], cp2[13]);
354                                 glVertex3fv( mdm->verts[mface->v4].co );
355                         }
356                 }
357                 if(col2) cp2+= 16;
358         }
359         glEnd();
360
361         glShadeModel(GL_FLAT);
362         glDisable(GL_CULL_FACE);
363 }
364 static void meshDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf, int matnr)) 
365 {
366         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
367         Mesh *me = mdm->me;
368         MVert *mvert= mdm->verts;
369         MFace *mface= me->mface;
370         TFace *tface = me->tface;
371         float *nors = mdm->nors;
372         int i;
373
374         for (i=0; i<me->totface; i++) {
375                 MFace *mf= &mface[i];
376                 TFace *tf = tface?&tface[i]:NULL;
377                 int flag;
378                 unsigned char *cp= NULL;
379                 
380                 flag = setDrawParams(tf, mf->mat_nr);
381
382                 if (flag==0) {
383                         continue;
384                 } else if (flag==1) {
385                         if (mdm->wpaintMCol) {
386                                 cp= (unsigned char*) &mdm->wpaintMCol[i*4];
387                         } else if (tf) {
388                                 cp= (unsigned char*) tf->col;
389                         } else if (me->mcol) {
390                                 cp= (unsigned char*) &me->mcol[i*4];
391                         }
392                 }
393
394                 if (!(mf->flag&ME_SMOOTH)) {
395                         glNormal3fv(&nors[i*3]);
396                 }
397
398                 glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
399                 if (tf) glTexCoord2fv(tf->uv[0]);
400                 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
401                 if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v1].no);
402                 glVertex3fv(mvert[mf->v1].co);
403                         
404                 if (tf) glTexCoord2fv(tf->uv[1]);
405                 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
406                 if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v2].no);
407                 glVertex3fv(mvert[mf->v2].co);
408
409                 if (tf) glTexCoord2fv(tf->uv[2]);
410                 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
411                 if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v3].no);
412                 glVertex3fv(mvert[mf->v3].co);
413
414                 if(mf->v4) {
415                         if (tf) glTexCoord2fv(tf->uv[3]);
416                         if (cp) glColor3ub(cp[15], cp[14], cp[13]);
417                         if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v4].no);
418                         glVertex3fv(mvert[mf->v4].co);
419                 }
420                 glEnd();
421         }
422 }
423 static void meshDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors) 
424 {
425         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
426         Mesh *me = mdm->me;
427         MVert *mvert= mdm->verts;
428         MFace *mface= me->mface;
429         float *nors= mdm->nors;
430         int i;
431
432         for (i=0; i<me->totface; i++) {
433                 MFace *mf= &mface[i];
434                 int drawSmooth = 1;
435
436                 if (!setDrawOptions || setDrawOptions(userData, i, &drawSmooth)) {
437                         unsigned char *cp = NULL;
438
439                         if (useColors) {
440                                 if (mdm->wpaintMCol) {
441                                         cp= (unsigned char*) &mdm->wpaintMCol[i*4];
442                                 } else if (me->tface) {
443                                         cp= (unsigned char*) me->tface[i].col;
444                                 } else if (me->mcol) {
445                                         cp= (unsigned char*) &me->mcol[i*4];
446                                 }
447                         }
448
449                         glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
450                         glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
451
452                         if (!drawSmooth) {
453                                 glNormal3fv(&nors[i*3]);
454
455                                 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
456                                 glVertex3fv(mvert[mf->v1].co);
457                                 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
458                                 glVertex3fv(mvert[mf->v2].co);
459                                 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
460                                 glVertex3fv(mvert[mf->v3].co);
461                                 if(mf->v4) {
462                                         if (cp) glColor3ub(cp[15], cp[14], cp[13]);
463                                         glVertex3fv(mvert[mf->v4].co);
464                                 }
465                         } else {
466                                 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
467                                 glNormal3sv(mvert[mf->v1].no);
468                                 glVertex3fv(mvert[mf->v1].co);
469                                 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
470                                 glNormal3sv(mvert[mf->v2].no);
471                                 glVertex3fv(mvert[mf->v2].co);
472                                 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
473                                 glNormal3sv(mvert[mf->v3].no);
474                                 glVertex3fv(mvert[mf->v3].co);
475                                 if(mf->v4) {
476                                         if (cp) glColor3ub(cp[15], cp[14], cp[13]);
477                                         glNormal3sv(mvert[mf->v4].no);
478                                         glVertex3fv(mvert[mf->v4].co);
479                                 }
480                         }
481
482                         glEnd();
483                 }
484         }
485 }
486 static int meshDM_getNumVerts(DerivedMesh *dm)
487 {
488         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
489         Mesh *me = mdm->me;
490
491         return me->totvert;
492 }
493 static int meshDM_getNumFaces(DerivedMesh *dm)
494 {
495         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
496         Mesh *me = mdm->me;
497
498         return me->totface;
499 }
500
501 static void meshDM_release(DerivedMesh *dm)
502 {
503         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
504
505         if (mdm->wpaintMCol) MEM_freeN(mdm->wpaintMCol);
506         if (mdm->freeNors) MEM_freeN(mdm->nors);
507         if (mdm->freeVerts) MEM_freeN(mdm->verts);
508         MEM_freeN(mdm);
509 }
510
511 static DerivedMesh *getMeshDerivedMesh(Mesh *me, Object *ob, float (*vertCos)[3])
512 {
513         MeshDerivedMesh *mdm = MEM_callocN(sizeof(*mdm), "mdm");
514
515         mdm->dm.getMinMax = meshDM_getMinMax;
516
517         mdm->dm.convertToDispListMesh = meshDM_convertToDispListMesh;
518         mdm->dm.getNumVerts = meshDM_getNumVerts;
519         mdm->dm.getNumFaces = meshDM_getNumFaces;
520
521         mdm->dm.getVertCos = meshDM_getVertCos;
522         mdm->dm.getVertCo = meshDM_getVertCo;
523         mdm->dm.getVertNo = meshDM_getVertNo;
524
525         mdm->dm.drawVerts = meshDM_drawVerts;
526
527         mdm->dm.drawUVEdges = meshDM_drawUVEdges;
528         mdm->dm.drawEdges = meshDM_drawEdges;
529         mdm->dm.drawLooseEdges = meshDM_drawLooseEdges;
530         
531         mdm->dm.drawFacesSolid = meshDM_drawFacesSolid;
532         mdm->dm.drawFacesColored = meshDM_drawFacesColored;
533         mdm->dm.drawFacesTex = meshDM_drawFacesTex;
534
535         mdm->dm.drawMappedEdges = meshDM_drawMappedEdges;
536         mdm->dm.drawMappedFaces = meshDM_drawMappedFaces;
537
538         mdm->dm.release = meshDM_release;
539
540                 /* Works in conjunction with hack during modifier calc */
541         if (G.f & G_WEIGHTPAINT) {
542                 mdm->wpaintMCol = MEM_dupallocN(me->mcol);
543         }
544
545         mdm->ob = ob;
546         mdm->me = me;
547         mdm->verts = me->mvert;
548         mdm->nors = NULL;
549         mdm->freeNors = 0;
550         mdm->freeVerts = 0;
551
552         if (vertCos) {
553                 int i;
554
555                 mdm->verts = MEM_mallocN(sizeof(*mdm->verts)*me->totvert, "deformedVerts");
556                 for (i=0; i<me->totvert; i++) {
557                         VECCOPY(mdm->verts[i].co, vertCos[i]);
558                 }
559                 mesh_calc_normals(mdm->verts, me->totvert, me->mface, me->totface, &mdm->nors);
560                 mdm->freeNors = 1;
561                 mdm->freeVerts = 1;
562         } else {
563                         // XXX this is kinda hacky because we shouldn't really be editing
564                         // the mesh here, however, we can't just call mesh_build_faceNormals(ob)
565                         // because in the case when a key is applied to a mesh the vertex normals
566                         // would never be correctly computed.
567                 mesh_calc_normals(mdm->verts, me->totvert, me->mface, me->totface, &mdm->nors);
568                 mdm->freeNors = 1;
569         }
570
571         return (DerivedMesh*) mdm;
572 }
573
574 ///
575
576 typedef struct {
577         DerivedMesh dm;
578
579         EditMesh *em;
580         float (*vertexCos)[3];
581         float (*vertexNos)[3];
582         float (*faceNos)[3];
583 } EditMeshDerivedMesh;
584
585 static void emDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData)
586 {
587         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
588         EditVert *eve;
589         int i;
590
591         for (i=0,eve= emdm->em->verts.first; eve; i++,eve=eve->next) {
592                 if (emdm->vertexCos) {
593                         func(userData, i, emdm->vertexCos[i], emdm->vertexNos[i], NULL);
594                 } else {
595                         func(userData, i, eve->co, eve->no, NULL);
596                 }
597         }
598 }
599 static void emDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData)
600 {
601         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
602         EditEdge *eed;
603         int i;
604
605         if (emdm->vertexCos) {
606                 EditVert *eve, *preveve;
607
608                 for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
609                         eve->prev = (EditVert*) i++;
610                 for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next)
611                         func(userData, i, emdm->vertexCos[(int) eed->v1->prev], emdm->vertexCos[(int) eed->v2->prev]);
612                 for (preveve=NULL, eve=emdm->em->verts.first; eve; preveve=eve, eve= eve->next)
613                         eve->prev = preveve;
614         } else {
615                 for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next)
616                         func(userData, i, eed->v1->co, eed->v2->co);
617         }
618 }
619 static void emDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) 
620 {
621         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
622         EditEdge *eed;
623         int i;
624
625         if (emdm->vertexCos) {
626                 EditVert *eve, *preveve;
627
628                 for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
629                         eve->prev = (EditVert*) i++;
630
631                 glBegin(GL_LINES);
632                 for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
633                         if(!setDrawOptions || setDrawOptions(userData, i)) {
634                                 glVertex3fv(emdm->vertexCos[(int) eed->v1->prev]);
635                                 glVertex3fv(emdm->vertexCos[(int) eed->v2->prev]);
636                         }
637                 }
638                 glEnd();
639
640                 for (preveve=NULL, eve=emdm->em->verts.first; eve; preveve=eve, eve= eve->next)
641                         eve->prev = preveve;
642         } else {
643                 glBegin(GL_LINES);
644                 for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
645                         if(!setDrawOptions || setDrawOptions(userData, i)) {
646                                 glVertex3fv(eed->v1->co);
647                                 glVertex3fv(eed->v2->co);
648                         }
649                 }
650                 glEnd();
651         }
652 }
653 static void emDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
654 {
655         emDM_drawMappedEdges(dm, NULL, NULL);
656 }
657 static void emDM_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) 
658 {
659         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
660         EditEdge *eed;
661         int i;
662
663         if (emdm->vertexCos) {
664                 EditVert *eve, *preveve;
665
666                 for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
667                         eve->prev = (EditVert*) i++;
668
669                 glBegin(GL_LINES);
670                 for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
671                         if(!setDrawOptions || setDrawOptions(userData, i)) {
672                                 setDrawInterpOptions(userData, i, 0.0);
673                                 glVertex3fv(emdm->vertexCos[(int) eed->v1->prev]);
674                                 setDrawInterpOptions(userData, i, 1.0);
675                                 glVertex3fv(emdm->vertexCos[(int) eed->v2->prev]);
676                         }
677                 }
678                 glEnd();
679
680                 for (preveve=NULL, eve=emdm->em->verts.first; eve; preveve=eve, eve= eve->next)
681                         eve->prev = preveve;
682         } else {
683                 glBegin(GL_LINES);
684                 for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
685                         if(!setDrawOptions || setDrawOptions(userData, i)) {
686                                 setDrawInterpOptions(userData, i, 0.0);
687                                 glVertex3fv(eed->v1->co);
688                                 setDrawInterpOptions(userData, i, 1.0);
689                                 glVertex3fv(eed->v2->co);
690                         }
691                 }
692                 glEnd();
693         }
694 }
695 static void emDM__calcFaceCent(EditFace *efa, float cent[3], float (*vertexCos)[3])
696 {
697         if (vertexCos) {
698                 VECCOPY(cent, vertexCos[(int) efa->v1->prev]);
699                 VecAddf(cent, cent, vertexCos[(int) efa->v2->prev]);
700                 VecAddf(cent, cent, vertexCos[(int) efa->v3->prev]);
701                 if (efa->v4) VecAddf(cent, cent, vertexCos[(int) efa->v4->prev]);
702         } else {
703                 VECCOPY(cent, efa->v1->co);
704                 VecAddf(cent, cent, efa->v2->co);
705                 VecAddf(cent, cent, efa->v3->co);
706                 if (efa->v4) VecAddf(cent, cent, efa->v4->co);
707         }
708
709         if (efa->v4) {
710                 VecMulf(cent, 0.25f);
711         } else {
712                 VecMulf(cent, 0.33333333333f);
713         }
714 }
715 static void emDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData)
716 {
717         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
718         EditVert *eve, *preveve;
719         EditFace *efa;
720         float cent[3];
721         int i;
722
723         if (emdm->vertexCos) {
724                 for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
725                         eve->prev = (EditVert*) i++;
726         }
727
728         for(i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
729                 emDM__calcFaceCent(efa, cent, emdm->vertexCos);
730                 func(userData, i, cent, emdm->vertexCos?emdm->faceNos[i]:efa->n);
731         }
732
733         if (emdm->vertexCos) {
734                 for (preveve=NULL, eve=emdm->em->verts.first; eve; preveve=eve, eve= eve->next)
735                         eve->prev = preveve;
736         }
737 }
738 static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors)
739 {
740         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
741         EditFace *efa;
742         int i;
743
744         if (emdm->vertexCos) {
745                 EditVert *eve, *preveve;
746                 int drawSmooth = 1;
747
748                 for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
749                         eve->prev = (EditVert*) i++;
750
751                 for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
752                         if(!setDrawOptions || setDrawOptions(userData, i, &drawSmooth)) {
753                                 glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
754
755                                 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
756                                 if (!drawSmooth) {
757                                         glNormal3fv(emdm->faceNos[i]);
758                                         glVertex3fv(emdm->vertexCos[(int) efa->v1->prev]);
759                                         glVertex3fv(emdm->vertexCos[(int) efa->v2->prev]);
760                                         glVertex3fv(emdm->vertexCos[(int) efa->v3->prev]);
761                                         if(efa->v4) glVertex3fv(emdm->vertexCos[(int) efa->v4->prev]);
762                                 } else {
763                                         glNormal3fv(emdm->vertexNos[(int) efa->v1->prev]);
764                                         glVertex3fv(emdm->vertexCos[(int) efa->v1->prev]);
765                                         glNormal3fv(emdm->vertexNos[(int) efa->v2->prev]);
766                                         glVertex3fv(emdm->vertexCos[(int) efa->v2->prev]);
767                                         glNormal3fv(emdm->vertexNos[(int) efa->v3->prev]);
768                                         glVertex3fv(emdm->vertexCos[(int) efa->v3->prev]);
769                                         if(efa->v4) {
770                                                 glNormal3fv(emdm->vertexNos[(int) efa->v4->prev]);
771                                                 glVertex3fv(emdm->vertexCos[(int) efa->v4->prev]);
772                                         }
773                                 }
774                                 glEnd();
775                         }
776                 }
777
778                 for (preveve=NULL, eve=emdm->em->verts.first; eve; preveve=eve, eve= eve->next)
779                         eve->prev = preveve;
780         } else {
781                 int drawSmooth = 1;
782
783                 for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
784                         if(!setDrawOptions || setDrawOptions(userData, i, &drawSmooth)) {
785                                 glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
786
787                                 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
788                                 if (!drawSmooth) {
789                                         glNormal3fv(efa->n);
790                                         glVertex3fv(efa->v1->co);
791                                         glVertex3fv(efa->v2->co);
792                                         glVertex3fv(efa->v3->co);
793                                         if(efa->v4) glVertex3fv(efa->v4->co);
794                                 } else {
795                                         glNormal3fv(efa->v1->no);
796                                         glVertex3fv(efa->v1->co);
797                                         glNormal3fv(efa->v2->no);
798                                         glVertex3fv(efa->v2->co);
799                                         glNormal3fv(efa->v3->no);
800                                         glVertex3fv(efa->v3->co);
801                                         if(efa->v4) {
802                                                 glNormal3fv(efa->v4->no);
803                                                 glVertex3fv(efa->v4->co);
804                                         }
805                                 }
806                                 glEnd();
807                         }
808                 }
809         }
810 }
811
812 static void emDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
813 {
814         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
815         EditVert *eve;
816         int i;
817
818         if (emdm->em->verts.first) {
819                 for (i=0,eve= emdm->em->verts.first; eve; i++,eve= eve->next) {
820                         if (emdm->vertexCos) {
821                                 DO_MINMAX(emdm->vertexCos[i], min_r, max_r);
822                         } else {
823                                 DO_MINMAX(eve->co, min_r, max_r);
824                         }
825                 }
826         } else {
827                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
828         }
829 }
830 static int emDM_getNumVerts(DerivedMesh *dm)
831 {
832         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
833
834         return BLI_countlist(&emdm->em->verts);
835 }
836 static int emDM_getNumFaces(DerivedMesh *dm)
837 {
838         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
839
840         return BLI_countlist(&emdm->em->faces);
841 }
842
843 static void emDM_release(DerivedMesh *dm)
844 {
845         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
846
847         if (emdm->vertexCos) {
848                 MEM_freeN(emdm->vertexCos);
849                 MEM_freeN(emdm->vertexNos);
850                 MEM_freeN(emdm->faceNos);
851         }
852
853         MEM_freeN(emdm);
854 }
855
856 static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em, float (*vertexCos)[3])
857 {
858         EditMeshDerivedMesh *emdm = MEM_callocN(sizeof(*emdm), "emdm");
859
860         emdm->dm.getMinMax = emDM_getMinMax;
861
862         emdm->dm.getNumVerts = emDM_getNumVerts;
863         emdm->dm.getNumFaces = emDM_getNumFaces;
864         emdm->dm.foreachMappedVert = emDM_foreachMappedVert;
865         emdm->dm.foreachMappedEdge = emDM_foreachMappedEdge;
866         emdm->dm.foreachMappedFaceCenter = emDM_foreachMappedFaceCenter;
867
868         emdm->dm.drawEdges = emDM_drawEdges;
869         emdm->dm.drawMappedEdges = emDM_drawMappedEdges;
870         emdm->dm.drawMappedEdgesInterp = emDM_drawMappedEdgesInterp;
871         emdm->dm.drawMappedFaces = emDM_drawMappedFaces;
872
873         emdm->dm.release = emDM_release;
874         
875         emdm->em = em;
876         emdm->vertexCos = vertexCos;
877
878         if (vertexCos) {
879                 EditVert *eve, *preveve;
880                 EditFace *efa;
881                 int totface = BLI_countlist(&em->faces);
882                 int i;
883
884                 for (i=0,eve=em->verts.first; eve; eve= eve->next)
885                         eve->prev = (EditVert*) i++;
886
887                 emdm->vertexNos = MEM_callocN(sizeof(*emdm->vertexNos)*i, "emdm_vno");
888                 emdm->faceNos = MEM_mallocN(sizeof(*emdm->faceNos)*totface, "emdm_vno");
889
890                 for(i=0, efa= em->faces.first; efa; i++, efa=efa->next) {
891                         float *v1 = vertexCos[(int) efa->v1->prev];
892                         float *v2 = vertexCos[(int) efa->v2->prev];
893                         float *v3 = vertexCos[(int) efa->v3->prev];
894                         float *no = emdm->faceNos[i];
895                         
896                         if(efa->v4) {
897                                 float *v4 = vertexCos[(int) efa->v3->prev];
898
899                                 CalcNormFloat4(v1, v2, v3, v4, no);
900                                 VecAddf(emdm->vertexNos[(int) efa->v4->prev], emdm->vertexNos[(int) efa->v4->prev], no);
901                         }
902                         else {
903                                 CalcNormFloat(v1, v2, v3, no);
904                         }
905
906                         VecAddf(emdm->vertexNos[(int) efa->v1->prev], emdm->vertexNos[(int) efa->v1->prev], no);
907                         VecAddf(emdm->vertexNos[(int) efa->v2->prev], emdm->vertexNos[(int) efa->v2->prev], no);
908                         VecAddf(emdm->vertexNos[(int) efa->v3->prev], emdm->vertexNos[(int) efa->v3->prev], no);
909                 }
910
911                 for(i=0, eve= em->verts.first; eve; i++, eve=eve->next) {
912                         float *no = emdm->vertexNos[i];
913
914                         if (Normalise(no)==0.0) {
915                                 VECCOPY(no, vertexCos[i]);
916                                 Normalise(no);
917                         }
918                 }
919
920                 for (preveve=NULL, eve=emdm->em->verts.first; eve; preveve=eve, eve= eve->next)
921                         eve->prev = preveve;
922         }
923
924         return (DerivedMesh*) emdm;
925 }
926
927 ///
928
929 typedef struct {
930         DerivedMesh dm;
931
932         DispListMesh *dlm;
933 } SSDerivedMesh;
934
935 static void ssDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData)
936 {
937         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
938         DispListMesh *dlm = ssdm->dlm;
939         int i, index=-1;
940
941         for (i=0; i<dlm->totvert; i++) {
942                 MVert *mv = &dlm->mvert[i];
943
944                 if (mv->flag&ME_VERT_STEPINDEX) index++;
945
946                 if (index!=-1) {
947                         func(userData, index, mv->co, NULL, mv->no);
948                 }
949         }
950 }
951 static void ssDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData)
952 {
953         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
954         DispListMesh *dlm = ssdm->dlm;
955         int i, index=-1;
956
957         for (i=0; i<dlm->totedge; i++) {
958                 MEdge *med = &dlm->medge[i];
959
960                 if (med->flag&ME_EDGE_STEPINDEX) index++;
961
962                 if (index!=-1) {
963                         func(userData, index, dlm->mvert[med->v1].co, dlm->mvert[med->v2].co);
964                 }
965         }
966 }
967 static void ssDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) 
968 {
969         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
970         DispListMesh *dlm = ssdm->dlm;
971         int i, index=-1;
972
973         glBegin(GL_LINES);
974         for(i=0; i<dlm->totedge; i++) {
975                 MEdge *med = &dlm->medge[i];
976
977                 if (med->flag&ME_EDGE_STEPINDEX) index++;
978
979                 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
980                         glVertex3fv(dlm->mvert[med->v1].co);
981                         glVertex3fv(dlm->mvert[med->v2].co);
982                 }
983         }
984         glEnd();
985 }
986
987 static void ssDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData)
988 {
989         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
990         DispListMesh *dlm = ssdm->dlm;
991         int i, index=-1;
992
993         for (i=0; i<dlm->totface; i++) {
994                 MFace *mf = &dlm->mface[i];
995
996                 if (mf->flag&ME_FACE_STEPINDEX) index++;
997
998                 if(index!=-1) {
999                         float cent[3];
1000                         float no[3];
1001
1002                         VECCOPY(cent, dlm->mvert[mf->v1].co);
1003                         VecAddf(cent, cent, dlm->mvert[mf->v2].co);
1004                         VecAddf(cent, cent, dlm->mvert[mf->v3].co);
1005
1006                         if (mf->v4) {
1007                                 CalcNormFloat4(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, dlm->mvert[mf->v4].co, no);
1008                                 VecAddf(cent, cent, dlm->mvert[mf->v4].co);
1009                                 VecMulf(cent, 0.25f);
1010                         } else {
1011                                 CalcNormFloat(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, no);
1012                                 VecMulf(cent, 0.33333333333f);
1013                         }
1014
1015                         func(userData, index, cent, no);
1016                 }
1017         }
1018 }
1019 static void ssDM_drawVerts(DerivedMesh *dm)
1020 {
1021         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1022         DispListMesh *dlm = ssdm->dlm;
1023         MVert *mvert= dlm->mvert;
1024         int i;
1025
1026         bglBegin(GL_POINTS);
1027         for (i=0; i<dlm->totvert; i++) {
1028                 bglVertex3fv(mvert[i].co);
1029         }
1030         bglEnd();
1031 }
1032 static void ssDM_drawUVEdges(DerivedMesh *dm)
1033 {
1034         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1035         DispListMesh *dlm = ssdm->dlm;
1036         int i;
1037
1038         if (dlm->tface) {
1039                 glBegin(GL_LINES);
1040                 for (i=0; i<dlm->totface; i++) {
1041                         TFace *tf = &dlm->tface[i];
1042
1043                         if (!(tf->flag&TF_HIDE)) {
1044                                 glVertex2fv(tf->uv[0]);
1045                                 glVertex2fv(tf->uv[1]);
1046
1047                                 glVertex2fv(tf->uv[1]);
1048                                 glVertex2fv(tf->uv[2]);
1049
1050                                 if (!dlm->mface[i].v4) {
1051                                         glVertex2fv(tf->uv[2]);
1052                                         glVertex2fv(tf->uv[0]);
1053                                 } else {
1054                                         glVertex2fv(tf->uv[2]);
1055                                         glVertex2fv(tf->uv[3]);
1056
1057                                         glVertex2fv(tf->uv[3]);
1058                                         glVertex2fv(tf->uv[0]);
1059                                 }
1060                         }
1061                 }
1062                 glEnd();
1063         }
1064 }
1065 static void ssDM_drawLooseEdges(DerivedMesh *dm) 
1066 {
1067         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1068         DispListMesh *dlm = ssdm->dlm;
1069         MVert *mvert = dlm->mvert;
1070         MEdge *medge= dlm->medge;
1071         int i;
1072
1073         glBegin(GL_LINES);
1074         for (i=0; i<dlm->totedge; i++, medge++) {
1075                 if (medge->flag&ME_LOOSEEDGE) {
1076                         glVertex3fv(mvert[medge->v1].co); 
1077                         glVertex3fv(mvert[medge->v2].co);
1078                 }
1079         }
1080         glEnd();
1081 }
1082 static void ssDM_drawEdges(DerivedMesh *dm, int drawLooseEdges) 
1083 {
1084         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1085         DispListMesh *dlm = ssdm->dlm;
1086         MVert *mvert= dlm->mvert;
1087         MEdge *medge= dlm->medge;
1088         int i;
1089         
1090         glBegin(GL_LINES);
1091         for (i=0; i<dlm->totedge; i++, medge++) {
1092                 if ((medge->flag&ME_EDGEDRAW) && (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) {
1093                         glVertex3fv(mvert[medge->v1].co); 
1094                         glVertex3fv(mvert[medge->v2].co);
1095                 }
1096         }
1097         glEnd();
1098 }
1099 static void ssDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int))
1100 {
1101         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1102         DispListMesh *dlm = ssdm->dlm;
1103         float *nors = dlm->nors;
1104         int glmode=-1, shademodel=-1, matnr=-1, drawCurrentMat=1;
1105         int i;
1106
1107 #define PASSVERT(ind) {                                         \
1108         if (shademodel==GL_SMOOTH)                              \
1109                 glNormal3sv(dlm->mvert[(ind)].no);      \
1110         glVertex3fv(dlm->mvert[(ind)].co);              \
1111 }
1112
1113         glBegin(glmode=GL_QUADS);
1114         for (i=0; i<dlm->totface; i++) {
1115                 MFace *mf= &dlm->mface[i];
1116                 int new_glmode = mf->v4?GL_QUADS:GL_TRIANGLES;
1117                 int new_shademodel = (mf->flag&ME_SMOOTH)?GL_SMOOTH:GL_FLAT;
1118                 int new_matnr = mf->mat_nr+1;
1119                 
1120                 if(new_glmode!=glmode || new_shademodel!=shademodel || new_matnr!=matnr) {
1121                         glEnd();
1122
1123                         drawCurrentMat = setMaterial(matnr=new_matnr);
1124
1125                         glShadeModel(shademodel=new_shademodel);
1126                         glBegin(glmode=new_glmode);
1127                 }
1128                 
1129                 if (drawCurrentMat) {
1130                         if (shademodel==GL_FLAT)
1131                                 glNormal3fv(&nors[i*3]);
1132                                 
1133                         PASSVERT(mf->v1);
1134                         PASSVERT(mf->v2);
1135                         PASSVERT(mf->v3);
1136                         if (mf->v4)
1137                                 PASSVERT(mf->v4);
1138                 }
1139         }
1140         glEnd();
1141         
1142 #undef PASSVERT
1143 }
1144 static void ssDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *vcols1, unsigned char *vcols2)
1145 {
1146         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1147         DispListMesh *dlm = ssdm->dlm;
1148         int i, lmode;
1149         
1150         glShadeModel(GL_SMOOTH);
1151         if (vcols2) {
1152                 glEnable(GL_CULL_FACE);
1153         } else {
1154                 useTwoSided = 0;
1155         }
1156                 
1157 #define PASSVERT(vidx, fidx) {                                  \
1158         unsigned char *col= &colbase[fidx*4];           \
1159         glColor3ub(col[3], col[2], col[1]);                     \
1160         glVertex3fv(dlm->mvert[(vidx)].co);                     \
1161 }
1162
1163         glBegin(lmode= GL_QUADS);
1164         for (i=0; i<dlm->totface; i++) {
1165                 MFace *mf= &dlm->mface[i];
1166                 int nmode= mf->v4?GL_QUADS:GL_TRIANGLES;
1167                 unsigned char *colbase= &vcols1[i*16];
1168                 
1169                 if (nmode!=lmode) {
1170                         glEnd();
1171                         glBegin(lmode= nmode);
1172                 }
1173                 
1174                 PASSVERT(mf->v1, 0);
1175                 PASSVERT(mf->v2, 1);
1176                 PASSVERT(mf->v3, 2);
1177                 if (mf->v4)
1178                         PASSVERT(mf->v4, 3);
1179                 
1180                 if (useTwoSided) {
1181                         unsigned char *colbase= &vcols2[i*16];
1182
1183                         if (mf->v4)
1184                                 PASSVERT(mf->v4, 3);
1185                         PASSVERT(mf->v3, 2);
1186                         PASSVERT(mf->v2, 1);
1187                         PASSVERT(mf->v1, 0);
1188                 }
1189         }
1190         glEnd();
1191
1192         if (vcols2)
1193                 glDisable(GL_CULL_FACE);
1194         
1195 #undef PASSVERT
1196 }
1197 static void ssDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf, int matnr)) 
1198 {
1199         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1200         DispListMesh *dlm = ssdm->dlm;
1201         MVert *mvert= dlm->mvert;
1202         MFace *mface= dlm->mface;
1203         TFace *tface = dlm->tface;
1204         float *nors = dlm->nors;
1205         int a;
1206         
1207         for (a=0; a<dlm->totface; a++) {
1208                 MFace *mf= &mface[a];
1209                 TFace *tf = tface?&tface[a]:NULL;
1210                 int flag;
1211                 unsigned char *cp= NULL;
1212                 
1213                 flag = setDrawParams(tf, mf->mat_nr);
1214
1215                 if (flag==0) {
1216                         continue;
1217                 } else if (flag==1) {
1218                         if (tf) {
1219                                 cp= (unsigned char*) tf->col;
1220                         } else if (dlm->mcol) {
1221                                 cp= (unsigned char*) &dlm->mcol[a*4];
1222                         }
1223                 }
1224
1225                 if (!(mf->flag&ME_SMOOTH)) {
1226                         glNormal3fv(&nors[a*3]);
1227                 }
1228
1229                 glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
1230                 if (tf) glTexCoord2fv(tf->uv[0]);
1231                 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
1232                 if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v1].no);
1233                 glVertex3fv((mvert+mf->v1)->co);
1234                         
1235                 if (tf) glTexCoord2fv(tf->uv[1]);
1236                 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
1237                 if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v2].no);
1238                 glVertex3fv((mvert+mf->v2)->co);
1239
1240                 if (tf) glTexCoord2fv(tf->uv[2]);
1241                 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
1242                 if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v3].no);
1243                 glVertex3fv((mvert+mf->v3)->co);
1244
1245                 if(mf->v4) {
1246                         if (tf) glTexCoord2fv(tf->uv[3]);
1247                         if (cp) glColor3ub(cp[15], cp[14], cp[13]);
1248                         if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v4].no);
1249                         glVertex3fv((mvert+mf->v4)->co);
1250                 }
1251                 glEnd();
1252         }
1253 }
1254 static void ssDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors) 
1255 {
1256         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1257         DispListMesh *dlm = ssdm->dlm;
1258         MVert *mvert= dlm->mvert;
1259         MFace *mface= dlm->mface;
1260         float *nors = dlm->nors;
1261         int i, index=-1;
1262
1263         for (i=0; i<dlm->totface; i++) {
1264                 MFace *mf = &mface[i];
1265                 int drawSmooth = 1;
1266
1267                 if (mf->flag&ME_FACE_STEPINDEX) index++;
1268
1269                 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index, &drawSmooth))) {
1270                         unsigned char *cp = NULL;
1271
1272                         if (useColors) {
1273                                 if (dlm->tface) {
1274                                         cp= (unsigned char*) dlm->tface[i].col;
1275                                 } else if (dlm->mcol) {
1276                                         cp= (unsigned char*) &dlm->mcol[i*4];
1277                                 }
1278                         }
1279
1280                         glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
1281                         glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
1282
1283                         if (!drawSmooth) {
1284                                 glNormal3fv(&nors[i*3]);
1285
1286                                 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
1287                                 glVertex3fv(mvert[mf->v1].co);
1288                                 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
1289                                 glVertex3fv(mvert[mf->v2].co);
1290                                 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
1291                                 glVertex3fv(mvert[mf->v3].co);
1292                                 if(mf->v4) {
1293                                         if (cp) glColor3ub(cp[15], cp[14], cp[13]);
1294                                         glVertex3fv(mvert[mf->v4].co);
1295                                 }
1296                         } else {
1297                                 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
1298                                 glNormal3sv(mvert[mf->v1].no);
1299                                 glVertex3fv(mvert[mf->v1].co);
1300                                 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
1301                                 glNormal3sv(mvert[mf->v2].no);
1302                                 glVertex3fv(mvert[mf->v2].co);
1303                                 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
1304                                 glNormal3sv(mvert[mf->v3].no);
1305                                 glVertex3fv(mvert[mf->v3].co);
1306                                 if(mf->v4) {
1307                                         if (cp) glColor3ub(cp[15], cp[14], cp[13]);
1308                                         glNormal3sv(mvert[mf->v4].no);
1309                                         glVertex3fv(mvert[mf->v4].co);
1310                                 }
1311                         }
1312
1313                         glEnd();
1314                 }
1315         }
1316 }
1317 static void ssDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
1318 {
1319         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1320         int i;
1321
1322         if (ssdm->dlm->totvert) {
1323                 for (i=0; i<ssdm->dlm->totvert; i++) {
1324                         DO_MINMAX(ssdm->dlm->mvert[i].co, min_r, max_r);
1325                 }
1326         } else {
1327                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
1328         }
1329 }
1330
1331 static void ssDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
1332 {
1333         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1334         int i;
1335
1336         for (i=0; i<ssdm->dlm->totvert; i++) {
1337                 cos_r[i][0] = ssdm->dlm->mvert[i].co[0];
1338                 cos_r[i][1] = ssdm->dlm->mvert[i].co[1];
1339                 cos_r[i][2] = ssdm->dlm->mvert[i].co[2];
1340         }
1341 }
1342
1343 static int ssDM_getNumVerts(DerivedMesh *dm)
1344 {
1345         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1346
1347         return ssdm->dlm->totvert;
1348 }
1349 static int ssDM_getNumFaces(DerivedMesh *dm)
1350 {
1351         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1352
1353         return ssdm->dlm->totface;
1354 }
1355
1356 static DispListMesh *ssDM_convertToDispListMesh(DerivedMesh *dm, int allowShared)
1357 {
1358         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1359
1360         if (allowShared) {
1361                 return displistmesh_copyShared(ssdm->dlm);
1362         } else {
1363                 return displistmesh_copy(ssdm->dlm);
1364         }
1365 }
1366
1367 static void ssDM_release(DerivedMesh *dm)
1368 {
1369         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1370
1371         displistmesh_free(ssdm->dlm);
1372
1373         MEM_freeN(dm);
1374 }
1375
1376 DerivedMesh *derivedmesh_from_displistmesh(DispListMesh *dlm, float (*vertexCos)[3])
1377 {
1378         SSDerivedMesh *ssdm = MEM_callocN(sizeof(*ssdm), "ssdm");
1379
1380         ssdm->dm.getMinMax = ssDM_getMinMax;
1381
1382         ssdm->dm.getNumVerts = ssDM_getNumVerts;
1383         ssdm->dm.getNumFaces = ssDM_getNumFaces;
1384         ssdm->dm.convertToDispListMesh = ssDM_convertToDispListMesh;
1385
1386         ssdm->dm.getVertCos = ssDM_getVertCos;
1387
1388         ssdm->dm.drawVerts = ssDM_drawVerts;
1389
1390         ssdm->dm.drawUVEdges = ssDM_drawUVEdges;
1391         ssdm->dm.drawEdges = ssDM_drawEdges;
1392         ssdm->dm.drawLooseEdges = ssDM_drawLooseEdges;
1393         
1394         ssdm->dm.drawFacesSolid = ssDM_drawFacesSolid;
1395         ssdm->dm.drawFacesColored = ssDM_drawFacesColored;
1396         ssdm->dm.drawFacesTex = ssDM_drawFacesTex;
1397         ssdm->dm.drawMappedFaces = ssDM_drawMappedFaces;
1398
1399                 /* EM functions */
1400         
1401         ssdm->dm.foreachMappedVert = ssDM_foreachMappedVert;
1402         ssdm->dm.foreachMappedEdge = ssDM_foreachMappedEdge;
1403         ssdm->dm.foreachMappedFaceCenter = ssDM_foreachMappedFaceCenter;
1404         
1405         ssdm->dm.drawMappedEdges = ssDM_drawMappedEdges;
1406         ssdm->dm.drawMappedEdgesInterp = NULL; // no way to implement this one
1407         
1408         ssdm->dm.release = ssDM_release;
1409         
1410         ssdm->dlm = dlm;
1411
1412         if (vertexCos) {
1413                 int i;
1414
1415                 for (i=0; i<dlm->totvert; i++) {
1416                         VECCOPY(dlm->mvert[i].co, vertexCos[i]);
1417                 }
1418
1419                 if (dlm->nors && !dlm->dontFreeNors) {
1420                         MEM_freeN(dlm->nors);
1421                         dlm->nors = 0;
1422                 }
1423
1424                 mesh_calc_normals(dlm->mvert, dlm->totvert, dlm->mface, dlm->totface, &dlm->nors);
1425         }
1426
1427         return (DerivedMesh*) ssdm;
1428 }
1429
1430 /***/
1431
1432 typedef float vec3f[3];
1433
1434 DerivedMesh *mesh_create_derived_for_modifier(Object *ob, ModifierData *md)
1435 {
1436         Mesh *me = ob->data;
1437         ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1438         DerivedMesh *dm;
1439
1440         if (!(md->mode&eModifierMode_Realtime)) return NULL;
1441         if (mti->isDisabled && mti->isDisabled(md)) return NULL;
1442
1443         if (mti->type==eModifierTypeType_OnlyDeform) {
1444                 int numVerts;
1445                 float (*deformedVerts)[3] = mesh_getVertexCos(me, &numVerts);
1446
1447                 mti->deformVerts(md, ob, NULL, deformedVerts, numVerts);
1448                 
1449                 dm = getMeshDerivedMesh(me, ob, deformedVerts);
1450                 MEM_freeN(deformedVerts);
1451         } else {
1452                 dm = mti->applyModifier(md, ob, NULL, NULL, 0, 0);
1453         }
1454
1455         return dm;
1456 }
1457
1458 static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedMesh **deform_r, DerivedMesh **final_r, int useRenderParams, int useDeform)
1459 {
1460         Mesh *me = ob->data;
1461         ModifierData *md= modifiers_getVirtualModifierList(ob);
1462         float (*deformedVerts)[3] = NULL;
1463         DerivedMesh *dm;
1464         int numVerts = me->totvert;
1465
1466         modifiers_clearErrors(ob);
1467
1468         if (deform_r) *deform_r = NULL;
1469         *final_r = NULL;
1470
1471         if (useDeform) {
1472                 do_mesh_key(me);
1473
1474                         /* Apply all leading deforming modifiers */
1475                 for (; md; md=md->next) {
1476                         ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1477
1478                         if (!(md->mode&(1<<useRenderParams))) continue;
1479                         if (mti->isDisabled && mti->isDisabled(md)) continue;
1480
1481                         if (mti->type==eModifierTypeType_OnlyDeform) {
1482                                 if (!deformedVerts) deformedVerts = mesh_getVertexCos(me, &numVerts);
1483                                 mti->deformVerts(md, ob, NULL, deformedVerts, numVerts);
1484                         } else {
1485                                 break;
1486                         }
1487                 }
1488
1489                         /* Result of all leading deforming modifiers is cached for
1490                          * places that wish to use the original mesh but with deformed
1491                          * coordinates (vpaint, etc.)
1492                          */
1493                 if (deform_r) *deform_r = getMeshDerivedMesh(me, ob, deformedVerts);
1494         } else {
1495                 deformedVerts = inputVertexCos;
1496         }
1497
1498                 /* Now apply all remaining modifiers. If useDeform is off then skip
1499                  * OnlyDeform ones. 
1500                  */
1501         dm = NULL;
1502         for (; md; md=md->next) {
1503                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1504
1505                 if (!(md->mode&(1<<useRenderParams))) continue;
1506                 if (mti->type==eModifierTypeType_OnlyDeform && !useDeform) continue;
1507                 if ((mti->flags&eModifierTypeFlag_RequiresOriginalData) && dm) {
1508                         modifier_setError(md, "Internal error, modifier requires original data (bad stack position).");
1509                         continue;
1510                 }
1511                 if (mti->isDisabled && mti->isDisabled(md)) continue;
1512
1513                         /* How to apply modifier depends on (a) what we already have as
1514                          * a result of previous modifiers (could be a DerivedMesh or just
1515                          * deformed vertices) and (b) what type the modifier is.
1516                          */
1517
1518                 if (mti->type==eModifierTypeType_OnlyDeform) {
1519                                 /* No existing verts to deform, need to build them. */
1520                         if (!deformedVerts) {
1521                                 if (dm) {
1522                                                 /* Deforming a derived mesh, read the vertex locations out of the mesh and
1523                                                  * deform them. Once done with this run of deformers verts will be written back.
1524                                                  */
1525                                         numVerts = dm->getNumVerts(dm);
1526                                         deformedVerts = MEM_mallocN(sizeof(*deformedVerts)*numVerts, "dfmv");
1527                                         dm->getVertCos(dm, deformedVerts);
1528                                 } else {
1529                                         deformedVerts = mesh_getVertexCos(me, &numVerts);
1530                                 }
1531                         }
1532
1533                         mti->deformVerts(md, ob, dm, deformedVerts, numVerts);
1534                 } else {
1535                                 /* There are 4 cases here (have deform? have dm?) but they all are handled
1536                                  * by the modifier apply function, which will also free the DerivedMesh if
1537                                  * it exists.
1538                                  */
1539                         DerivedMesh *ndm = mti->applyModifier(md, ob, dm, deformedVerts, useRenderParams, !inputVertexCos);
1540
1541                         if (ndm) {
1542                                 if (dm) dm->release(dm);
1543
1544                                 dm = ndm;
1545
1546                                 if (deformedVerts) {
1547                                         if (deformedVerts!=inputVertexCos) {
1548                                                 MEM_freeN(deformedVerts);
1549                                         }
1550                                         deformedVerts = NULL;
1551                                 }
1552                         } 
1553                 }
1554         }
1555
1556                 /* Yay, we are done. If we have a DerivedMesh and deformed vertices need to apply
1557                  * these back onto the DerivedMesh. If we have no DerivedMesh then we need to build
1558                  * one.
1559                  */
1560         if (dm && deformedVerts) {
1561                 DispListMesh *dlm = dm->convertToDispListMesh(dm, 0);
1562
1563                 dm->release(dm);
1564
1565                 *final_r = derivedmesh_from_displistmesh(dlm, deformedVerts);
1566         } else if (dm) {
1567                 *final_r = dm;
1568         } else {
1569                 *final_r = getMeshDerivedMesh(me, ob, deformedVerts);
1570         }
1571
1572         if (deformedVerts && deformedVerts!=inputVertexCos) {
1573                 MEM_freeN(deformedVerts);
1574         }
1575 }
1576
1577 static vec3f *editmesh_getVertexCos(EditMesh *em, int *numVerts_r)
1578 {
1579         int i, numVerts = *numVerts_r = BLI_countlist(&em->verts);
1580         float (*cos)[3];
1581         EditVert *eve;
1582
1583         cos = MEM_mallocN(sizeof(*cos)*numVerts, "vertexcos");
1584         for (i=0,eve=em->verts.first; i<numVerts; i++,eve=eve->next) {
1585                 VECCOPY(cos[i], eve->co);
1586         }
1587
1588         return cos;
1589 }
1590
1591 static void editmesh_calc_modifiers(DerivedMesh **cage_r, DerivedMesh **final_r)
1592 {
1593         Object *ob = G.obedit;
1594         EditMesh *em = G.editMesh;
1595         ModifierData *md;
1596         float (*deformedVerts)[3] = NULL;
1597         DerivedMesh *dm;
1598         int i, numVerts, cageIndex = modifiers_getCageIndex(ob, NULL);
1599
1600         modifiers_clearErrors(ob);
1601
1602         if (cage_r && cageIndex==-1) {
1603                 *cage_r = getEditMeshDerivedMesh(em, NULL);
1604         }
1605
1606         dm = NULL;
1607         for (i=0,md= ob->modifiers.first; md; i++,md=md->next) {
1608                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1609
1610                 if (!(md->mode&eModifierMode_Realtime)) continue;
1611                 if (!(md->mode&eModifierMode_Editmode)) continue;
1612                 if ((mti->flags&eModifierTypeFlag_RequiresOriginalData) && dm) {
1613                         modifier_setError(md, "Internal error, modifier requires original data (bad stack position).");
1614                         continue;
1615                 }
1616                 if (mti->isDisabled && mti->isDisabled(md)) continue;
1617                 if (!(mti->flags&eModifierTypeFlag_SupportsEditmode)) continue;
1618
1619                         /* How to apply modifier depends on (a) what we already have as
1620                          * a result of previous modifiers (could be a DerivedMesh or just
1621                          * deformed vertices) and (b) what type the modifier is.
1622                          */
1623
1624                 if (mti->type==eModifierTypeType_OnlyDeform) {
1625                                 /* No existing verts to deform, need to build them. */
1626                         if (!deformedVerts) {
1627                                 if (dm) {
1628                                                 /* Deforming a derived mesh, read the vertex locations out of the mesh and
1629                                                  * deform them. Once done with this run of deformers verts will be written back.
1630                                                  */
1631                                         numVerts = dm->getNumVerts(dm);
1632                                         deformedVerts = MEM_mallocN(sizeof(*deformedVerts)*numVerts, "dfmv");
1633                                         dm->getVertCos(dm, deformedVerts);
1634                                 } else {
1635                                         deformedVerts = editmesh_getVertexCos(em, &numVerts);
1636                                 }
1637                         }
1638
1639                         mti->deformVertsEM(md, ob, em, dm, deformedVerts, numVerts);
1640                 } else {
1641                                 /* There are 4 cases here (have deform? have dm?) but they all are handled
1642                                  * by the modifier apply function, which will also free the DerivedMesh if
1643                                  * it exists.
1644                                  */
1645                         DerivedMesh *ndm = mti->applyModifierEM(md, ob, em, dm, deformedVerts);
1646
1647                         if (ndm) {
1648                                 if (dm && (!cage_r || dm!=*cage_r)) dm->release(dm);
1649
1650                                 dm = ndm;
1651
1652                                 if (deformedVerts) {
1653                                         MEM_freeN(deformedVerts);
1654                                         deformedVerts = NULL;
1655                                 }
1656                         }
1657                 }
1658
1659                 if (cage_r && i==cageIndex) {
1660                         if (dm && deformedVerts) {
1661                                 DispListMesh *dlm;
1662
1663                                 dlm = dm->convertToDispListMesh(dm, 0);
1664
1665                                 *cage_r = derivedmesh_from_displistmesh(dlm, deformedVerts);
1666                         } else if (dm) {
1667                                 *cage_r = dm;
1668                         } else {
1669                                 *cage_r = getEditMeshDerivedMesh(em, deformedVerts?MEM_dupallocN(deformedVerts):NULL);
1670                         }
1671                 }
1672         }
1673
1674                 /* Yay, we are done. If we have a DerivedMesh and deformed vertices need to apply
1675                  * these back onto the DerivedMesh. If we have no DerivedMesh then we need to build
1676                  * one.
1677                  */
1678         if (dm && deformedVerts) {
1679                 DispListMesh *dlm = dm->convertToDispListMesh(dm, 0);
1680
1681                 if (!cage_r || dm!=*cage_r) dm->release(dm);
1682
1683                 *final_r = derivedmesh_from_displistmesh(dlm, deformedVerts);
1684                 MEM_freeN(deformedVerts);
1685         } else if (dm) {
1686                 *final_r = dm;
1687         } else {
1688                 *final_r = getEditMeshDerivedMesh(em, deformedVerts);
1689         }
1690 }
1691
1692 /***/
1693
1694
1695         /* Something of a hack, at the moment deal with weightpaint
1696          * by tucking into colors during modifier eval, only in
1697          * wpaint mode. Works ok but need to make sure recalc
1698          * happens on enter/exit wpaint.
1699          */
1700
1701 static void weight_to_rgb(float input, float *fr, float *fg, float *fb)
1702 {
1703         float blend;
1704         
1705         blend= ((input/2.0f)+0.5f);
1706         
1707         if (input<=0.25f){      // blue->cyan
1708                 *fr= 0.0f;
1709                 *fg= blend*input*4.0f;
1710                 *fb= blend;
1711         }
1712         else if (input<=0.50f){ // cyan->green
1713                 *fr= 0.0f;
1714                 *fg= blend;
1715                 *fb= blend*(1.0f-((input-0.25f)*4.0f)); 
1716         }
1717         else if (input<=0.75){  // green->yellow
1718                 *fr= blend * ((input-0.50f)*4.0f);
1719                 *fg= blend;
1720                 *fb= 0.0f;
1721         }
1722         else if (input<=1.0){ // yellow->red
1723                 *fr= blend;
1724                 *fg= blend * (1.0f-((input-0.75f)*4.0f)); 
1725                 *fb= 0.0f;
1726         }
1727 }
1728 static void calc_weightpaint_vert_color(Object *ob, int vert, unsigned char *col)
1729 {
1730         Mesh *me = ob->data;
1731         float fr, fg, fb, input = 0.0f;
1732         int i;
1733
1734         if (me->dvert) {
1735                 for (i=0; i<me->dvert[vert].totweight; i++)
1736                         if (me->dvert[vert].dw[i].def_nr==ob->actdef-1)
1737                                 input+=me->dvert[vert].dw[i].weight;            
1738         }
1739
1740         CLAMP(input, 0.0f, 1.0f);
1741         
1742         weight_to_rgb(input, &fr, &fg, &fb);
1743         
1744         col[3] = (unsigned char)(fr * 255.0f);
1745         col[2] = (unsigned char)(fg * 255.0f);
1746         col[1] = (unsigned char)(fb * 255.0f);
1747         col[0] = 255;
1748 }
1749 static unsigned char *calc_weightpaint_colors(Object *ob) 
1750 {
1751         Mesh *me = ob->data;
1752         MFace *mf = me->mface;
1753         unsigned char *wtcol;
1754         int i;
1755         
1756         wtcol = MEM_callocN (sizeof (unsigned char) * me->totface*4*4, "weightmap");
1757         
1758         memset(wtcol, 0x55, sizeof (unsigned char) * me->totface*4*4);
1759         for (i=0; i<me->totface; i++, mf++){
1760                 calc_weightpaint_vert_color(ob, mf->v1, &wtcol[(i*4 + 0)*4]); 
1761                 calc_weightpaint_vert_color(ob, mf->v2, &wtcol[(i*4 + 1)*4]); 
1762                 calc_weightpaint_vert_color(ob, mf->v3, &wtcol[(i*4 + 2)*4]); 
1763                 if (mf->v4)
1764                         calc_weightpaint_vert_color(ob, mf->v4, &wtcol[(i*4 + 3)*4]); 
1765         }
1766         
1767         return wtcol;
1768 }
1769
1770 static void clear_mesh_caches(Object *ob)
1771 {
1772         Mesh *me= ob->data;
1773
1774                 /* also serves as signal to remake texspace */
1775         if (me->bb) {
1776                 MEM_freeN(me->bb);
1777                 me->bb = NULL;
1778         }
1779
1780         freedisplist(&ob->disp);
1781
1782         if (ob->derivedFinal) {
1783                 ob->derivedFinal->release(ob->derivedFinal);
1784                 ob->derivedFinal= NULL;
1785         }
1786         if (ob->derivedDeform) {
1787                 ob->derivedDeform->release(ob->derivedDeform);
1788                 ob->derivedDeform= NULL;
1789         }
1790 }
1791
1792 static void mesh_build_data(Object *ob)
1793 {
1794         Mesh *me = ob->data;
1795         float min[3], max[3];
1796
1797         if(ob->flag&OB_FROMDUPLI) return;
1798
1799         clear_mesh_caches(ob);
1800
1801         if( (G.f & G_WEIGHTPAINT)) {
1802                 MCol *mcol = me->mcol;
1803                 TFace *tface =  me->tface;
1804
1805                 me->tface = NULL;
1806                 me->mcol = (MCol*) calc_weightpaint_colors(ob);
1807
1808                 mesh_calc_modifiers(ob, NULL, &ob->derivedDeform, &ob->derivedFinal, 0, 1);
1809
1810                 MEM_freeN(me->mcol);
1811                 me->mcol = mcol;
1812                 me->tface = tface;
1813         } else {
1814                 mesh_calc_modifiers(ob, NULL, &ob->derivedDeform, &ob->derivedFinal, 0, 1);
1815         }
1816
1817         INIT_MINMAX(min, max);
1818
1819         ob->derivedFinal->getMinMax(ob->derivedFinal, min, max);
1820
1821         boundbox_set_from_min_max(mesh_get_bb(ob->data), min, max);
1822 }
1823
1824 static void editmesh_build_data(void)
1825 {
1826         float min[3], max[3];
1827
1828         EditMesh *em = G.editMesh;
1829
1830         clear_mesh_caches(G.obedit);
1831
1832         if (em->derivedFinal) {
1833                 if (em->derivedFinal!=em->derivedCage) {
1834                         em->derivedFinal->release(em->derivedFinal);
1835                 }
1836                 em->derivedFinal = NULL;
1837         }
1838         if (em->derivedCage) {
1839                 em->derivedCage->release(em->derivedCage);
1840                 em->derivedCage = NULL;
1841         }
1842
1843         editmesh_calc_modifiers(&em->derivedCage, &em->derivedFinal);
1844
1845         INIT_MINMAX(min, max);
1846
1847         em->derivedFinal->getMinMax(em->derivedFinal, min, max);
1848
1849         boundbox_set_from_min_max(mesh_get_bb(G.obedit->data), min, max);
1850 }
1851
1852 void makeDispListMesh(Object *ob)
1853 {
1854         if (ob==G.obedit) {
1855                 editmesh_build_data();
1856         } else {
1857                 mesh_build_data(ob);
1858
1859                 build_particle_system(ob);
1860         }
1861 }
1862
1863 /***/
1864
1865 DerivedMesh *mesh_get_derived_final(Object *ob, int *needsFree_r)
1866 {
1867         if (!ob->derivedFinal) {
1868                 mesh_build_data(ob);
1869         }
1870
1871         *needsFree_r = 0;
1872         return ob->derivedFinal;
1873 }
1874
1875 DerivedMesh *mesh_get_derived_deform(Object *ob, int *needsFree_r)
1876 {
1877         if (!ob->derivedDeform) {
1878                 mesh_build_data(ob);
1879         } 
1880
1881         *needsFree_r = 0;
1882         return ob->derivedDeform;
1883 }
1884
1885 DerivedMesh *mesh_create_derived_render(Object *ob)
1886 {
1887         DerivedMesh *final;
1888
1889         mesh_calc_modifiers(ob, NULL, NULL, &final, 1, 1);
1890
1891         return final;
1892 }
1893
1894 DerivedMesh *mesh_create_derived_no_deform(Object *ob, float (*vertCos)[3])
1895 {
1896         DerivedMesh *final;
1897
1898         mesh_calc_modifiers(ob, vertCos, NULL, &final, 0, 0);
1899
1900         return final;
1901 }
1902
1903 DerivedMesh *mesh_create_derived_no_deform_render(Object *ob, float (*vertCos)[3])
1904 {
1905         DerivedMesh *final;
1906
1907         mesh_calc_modifiers(ob, vertCos, NULL, &final, 1, 0);
1908
1909         return final;
1910 }
1911
1912 /***/
1913
1914 DerivedMesh *editmesh_get_derived_cage_and_final(DerivedMesh **final_r, int *cageNeedsFree_r, int *finalNeedsFree_r)
1915 {
1916         *cageNeedsFree_r = *finalNeedsFree_r = 0;
1917
1918         if (!G.editMesh->derivedCage)
1919                 editmesh_build_data();
1920
1921         *final_r = G.editMesh->derivedFinal;
1922         return G.editMesh->derivedCage;
1923 }
1924
1925 DerivedMesh *editmesh_get_derived_cage(int *needsFree_r)
1926 {
1927         *needsFree_r = 0;
1928
1929         if (!G.editMesh->derivedCage)
1930                 editmesh_build_data();
1931
1932         return G.editMesh->derivedCage;
1933 }
1934
1935 DerivedMesh *editmesh_get_derived_base(void)
1936 {
1937         return getEditMeshDerivedMesh(G.editMesh, NULL);
1938 }