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