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