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