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