f1285032802837ee18279add6de2c8b625f96fe2
[blender.git] / source / blender / blenkernel / intern / DerivedMesh.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2005 Blender Foundation.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33 #include <string.h>
34
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39 #include <zlib.h>
40
41 #include "PIL_time.h"
42
43 #include "MEM_guardedalloc.h"
44
45 #include "DNA_effect_types.h"
46 #include "DNA_mesh_types.h"
47 #include "DNA_key_types.h"
48 #include "DNA_meshdata_types.h"
49 #include "DNA_modifier_types.h"
50 #include "DNA_object_types.h"
51 #include "DNA_object_force.h"
52 #include "DNA_object_fluidsim.h" // N_T
53 #include "DNA_scene_types.h" // N_T
54
55 #include "BLI_arithb.h"
56 #include "BLI_blenlib.h"
57 #include "BLI_edgehash.h"
58 #include "BLI_editVert.h"
59
60 #include "BKE_utildefines.h"
61 #include "BKE_cdderivedmesh.h"
62 #include "BKE_customdata.h"
63 #include "BKE_DerivedMesh.h"
64 #include "BKE_displist.h"
65 #include "BKE_effect.h"
66 #include "BKE_global.h"
67 #include "BKE_material.h"
68 #include "BKE_mesh.h"
69 #include "BKE_object.h"
70 #include "BKE_subsurf.h"
71 #include "BKE_deform.h"
72 #include "BKE_modifier.h"
73 #include "BKE_key.h"
74
75 #ifdef WITH_VERSE
76 #include "BKE_verse.h"
77 #endif
78
79 #include "BIF_gl.h"
80 #include "BIF_glutil.h"
81
82 #include "multires.h"
83
84 // headers for fluidsim bobj meshes
85 #include <stdlib.h>
86 #include "LBM_fluidsim.h"
87 #include "elbeem.h"
88
89 ///////////////////////////////////
90 ///////////////////////////////////
91 #define DERIVEDMESH_INITIAL_LAYERS 5
92
93 MVert *dm_dupVertArray(DerivedMesh *dm)
94 {
95         MVert *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumVerts(dm),
96                                  "dm_dupVertArray tmp");
97
98         if(tmp) dm->getVertArray(dm, tmp);
99
100         return tmp;
101 }
102
103 MEdge *dm_dupEdgeArray(DerivedMesh *dm)
104 {
105         MEdge *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumEdges(dm),
106                                  "dm_dupEdgeArray tmp");
107
108         if(tmp) dm->getEdgeArray(dm, tmp);
109
110         return tmp;
111 }
112
113 MFace *dm_dupFaceArray(DerivedMesh *dm)
114 {
115         MFace *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumFaces(dm),
116                                  "dm_dupFaceArray tmp");
117
118         if(tmp) dm->getFaceArray(dm, tmp);
119
120         return tmp;
121 }
122
123 void DM_init_funcs(DerivedMesh *dm)
124 {
125         /* default function implementations */
126         dm->dupVertArray = dm_dupVertArray;
127         dm->dupEdgeArray = dm_dupEdgeArray;
128         dm->dupFaceArray = dm_dupFaceArray;
129
130         dm->getVertData = DM_get_vert_data;
131         dm->getEdgeData = DM_get_edge_data;
132         dm->getFaceData = DM_get_face_data;
133         dm->getVertDataArray = DM_get_vert_data_layer;
134         dm->getEdgeDataArray = DM_get_edge_data_layer;
135         dm->getFaceDataArray = DM_get_face_data_layer;
136 }
137
138 void DM_init(DerivedMesh *dm,
139              int numVerts, int numEdges, int numFaces)
140 {
141         CustomData_init(&dm->vertData, DERIVEDMESH_INITIAL_LAYERS, numVerts,
142                         SUB_ELEMS_VERT);
143         CustomData_init(&dm->edgeData, DERIVEDMESH_INITIAL_LAYERS, numEdges,
144                         SUB_ELEMS_EDGE);
145         CustomData_init(&dm->faceData, DERIVEDMESH_INITIAL_LAYERS, numFaces,
146                         SUB_ELEMS_FACE);
147
148         CustomData_add_layer(&dm->vertData, LAYERTYPE_ORIGINDEX, 0, NULL);
149         CustomData_add_layer(&dm->edgeData, LAYERTYPE_ORIGINDEX, 0, NULL);
150         CustomData_add_layer(&dm->faceData, LAYERTYPE_ORIGINDEX, 0, NULL);
151
152         DM_init_funcs(dm);
153 }
154
155 void DM_from_template(DerivedMesh *dm, DerivedMesh *source,
156                       int numVerts, int numEdges, int numFaces)
157 {
158         CustomData_from_template(&source->vertData, &dm->vertData, 0, numVerts);
159         CustomData_from_template(&source->edgeData, &dm->edgeData, 0, numEdges);
160         CustomData_from_template(&source->faceData, &dm->faceData, 0, numFaces);
161
162         DM_init_funcs(dm);
163 }
164
165 void DM_release(DerivedMesh *dm)
166 {
167         CustomData_free(&dm->vertData);
168         CustomData_free(&dm->edgeData);
169         CustomData_free(&dm->faceData);
170 }
171
172 void DM_to_mesh(DerivedMesh *dm, Mesh *me)
173 {
174         /* dm might depend on me, so we need to do everything with a local copy */
175         Mesh tmp_me = *me;
176         int numVerts = dm->getNumVerts(dm);
177
178         tmp_me.dvert = NULL;
179         tmp_me.tface = NULL;
180         tmp_me.mcol = NULL;
181
182         tmp_me.totvert = numVerts;
183         tmp_me.totedge = dm->getNumEdges(dm);
184         tmp_me.totface = dm->getNumFaces(dm);
185
186         tmp_me.mvert = dm->dupVertArray(dm);
187         tmp_me.medge = dm->dupEdgeArray(dm);
188         tmp_me.mface = dm->dupFaceArray(dm);
189
190         if(dm->getFaceDataArray(dm, LAYERTYPE_TFACE))
191                 tmp_me.tface = MEM_dupallocN(dm->getFaceDataArray(dm,
192                                                                   LAYERTYPE_TFACE));
193         if(dm->getFaceDataArray(dm, LAYERTYPE_MCOL))
194                 tmp_me.mcol = MEM_dupallocN(dm->getFaceDataArray(dm,
195                                                                  LAYERTYPE_MCOL));
196         if(dm->getVertDataArray(dm, LAYERTYPE_MDEFORMVERT)) {
197                 int i;
198                 MDeformVert *dv;
199
200                 tmp_me.dvert = MEM_dupallocN(
201                                     dm->getVertDataArray(dm, LAYERTYPE_MDEFORMVERT));
202
203                 for(i = 0, dv = tmp_me.dvert; i < numVerts; ++i, ++dv)
204                         dv->dw = MEM_dupallocN(dv->dw);
205         }
206
207         if(me->mvert) MEM_freeN(me->mvert);
208         if(me->dvert) free_dverts(me->dvert, me->totvert);
209         if(me->mface) MEM_freeN(me->mface);
210         if(me->tface) MEM_freeN(me->tface);
211         if(me->mcol) MEM_freeN(me->mcol);
212         if(me->medge) MEM_freeN(me->medge);
213
214         /* if the number of verts has changed, remove invalid data */
215         if(numVerts != me->totvert) {
216                 if(me->msticky) MEM_freeN(me->msticky);
217                 me->msticky = NULL;
218
219                 if(me->key) me->key->id.us--;
220                 me->key = NULL;
221         }
222
223         *me = tmp_me;
224 }
225
226 void DM_add_vert_layer(DerivedMesh *dm, int type, int flag, void *layer)
227 {
228         CustomData_add_layer(&dm->vertData, type, flag, layer);
229 }
230
231 void DM_add_edge_layer(DerivedMesh *dm, int type, int flag, void *layer)
232 {
233         CustomData_add_layer(&dm->edgeData, type, flag, layer);
234 }
235
236 void DM_add_face_layer(DerivedMesh *dm, int type, int flag, void *layer)
237 {
238         CustomData_add_layer(&dm->faceData, type, flag, layer);
239 }
240
241 void *DM_get_vert_data(DerivedMesh *dm, int index, int type)
242 {
243         return CustomData_get(&dm->vertData, index, type);
244 }
245
246 void *DM_get_edge_data(DerivedMesh *dm, int index, int type)
247 {
248         return CustomData_get(&dm->edgeData, index, type);
249 }
250
251 void *DM_get_face_data(DerivedMesh *dm, int index, int type)
252 {
253         return CustomData_get(&dm->faceData, index, type);
254 }
255
256 void *DM_get_vert_data_layer(DerivedMesh *dm, int type)
257 {
258         return CustomData_get_layer(&dm->vertData, type);
259 }
260
261 void *DM_get_edge_data_layer(DerivedMesh *dm, int type)
262 {
263         return CustomData_get_layer(&dm->edgeData, type);
264 }
265
266 void *DM_get_face_data_layer(DerivedMesh *dm, int type)
267 {
268         return CustomData_get_layer(&dm->faceData, type);
269 }
270
271 void DM_set_vert_data(DerivedMesh *dm, int index, int type, void *data)
272 {
273         CustomData_set(&dm->vertData, index, type, data);
274 }
275
276 void DM_set_edge_data(DerivedMesh *dm, int index, int type, void *data)
277 {
278         CustomData_set(&dm->edgeData, index, type, data);
279 }
280
281 void DM_set_face_data(DerivedMesh *dm, int index, int type, void *data)
282 {
283         CustomData_set(&dm->faceData, index, type, data);
284 }
285
286 void DM_copy_vert_data(DerivedMesh *source, DerivedMesh *dest,
287                        int source_index, int dest_index, int count)
288 {
289         CustomData_copy_data(&source->vertData, &dest->vertData,
290                              source_index, dest_index,
291                              count);
292 }
293
294 void DM_copy_edge_data(DerivedMesh *source, DerivedMesh *dest,
295                        int source_index, int dest_index, int count)
296 {
297         CustomData_copy_data(&source->edgeData, &dest->edgeData,
298                              source_index, dest_index,
299                              count);
300 }
301
302 void DM_copy_face_data(DerivedMesh *source, DerivedMesh *dest,
303                        int source_index, int dest_index, int count)
304 {
305         CustomData_copy_data(&source->faceData, &dest->faceData,
306                              source_index, dest_index,
307                              count);
308 }
309
310 void DM_free_vert_data(struct DerivedMesh *dm, int index, int count)
311 {
312         CustomData_free_elem(&dm->vertData, index, count);
313 }
314
315 void DM_free_edge_data(struct DerivedMesh *dm, int index, int count)
316 {
317         CustomData_free_elem(&dm->edgeData, index, count);
318 }
319
320 void DM_free_face_data(struct DerivedMesh *dm, int index, int count)
321 {
322         CustomData_free_elem(&dm->faceData, index, count);
323 }
324
325 void DM_interp_vert_data(DerivedMesh *source, DerivedMesh *dest,
326                          int *src_indices, float *weights,
327                          int count, int dest_index)
328 {
329         CustomData_interp(&source->vertData, &dest->vertData, src_indices,
330                           weights, NULL, count, dest_index);
331 }
332
333 void DM_interp_edge_data(DerivedMesh *source, DerivedMesh *dest,
334                          int *src_indices,
335                          float *weights, EdgeVertWeight *vert_weights,
336                          int count, int dest_index)
337 {
338         CustomData_interp(&source->edgeData, &dest->edgeData, src_indices,
339                           weights, (float*)vert_weights, count, dest_index);
340 }
341
342 void DM_interp_face_data(DerivedMesh *source, DerivedMesh *dest,
343                          int *src_indices,
344                          float *weights, FaceVertWeight *vert_weights,
345                          int count, int dest_index)
346 {
347         CustomData_interp(&source->faceData, &dest->faceData, src_indices,
348                           weights, (float*)vert_weights, count, dest_index);
349 }
350
351 typedef struct {
352         DerivedMesh dm;
353
354         Object *ob;
355         Mesh *me;
356         MVert *verts;
357         float *nors;
358         MCol *wpaintMCol;
359
360         int freeNors, freeVerts;
361 } MeshDerivedMesh;
362
363 static DispListMesh *meshDM_convertToDispListMesh(DerivedMesh *dm, int allowShared)
364 {
365         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
366         Mesh *me = mdm->me;
367         DispListMesh *dlm = MEM_callocN(sizeof(*dlm), "dlm");
368
369         dlm->totvert = me->totvert;
370         dlm->totedge = me->totedge;
371         dlm->totface = me->totface;
372         dlm->mvert = mdm->verts;
373         dlm->medge = me->medge;
374         dlm->mface = me->mface;
375         dlm->tface = me->tface;
376         dlm->mcol = me->mcol;
377         dlm->nors = mdm->nors;
378         dlm->dontFreeVerts = dlm->dontFreeOther = dlm->dontFreeNors = 1;
379
380         if (!allowShared) {
381                 dlm->mvert = MEM_dupallocN(dlm->mvert);
382                 if (dlm->nors) dlm->nors = MEM_dupallocN(dlm->nors);
383
384                 dlm->dontFreeVerts = dlm->dontFreeNors = 0;
385         }
386
387         return dlm;
388 }
389
390 static void meshDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
391 {
392         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
393         Mesh *me = mdm->me;
394         int i;
395
396         if (me->totvert) {
397                 for (i=0; i<me->totvert; i++) {
398                         DO_MINMAX(mdm->verts[i].co, min_r, max_r);
399                 }
400         } else {
401                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
402         }
403 }
404
405 static void meshDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
406 {
407         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
408         Mesh *me = mdm->me;
409         int i;
410
411         for (i=0; i<me->totvert; i++) {
412                 cos_r[i][0] = mdm->verts[i].co[0];
413                 cos_r[i][1] = mdm->verts[i].co[1];
414                 cos_r[i][2] = mdm->verts[i].co[2];
415         }
416 }
417
418 static void meshDM_getVertCo(DerivedMesh *dm, int index, float co_r[3])
419 {
420         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
421
422         VECCOPY(co_r, mdm->verts[index].co);
423 }
424
425 static void meshDM_getVertNo(DerivedMesh *dm, int index, float no_r[3])
426 {
427         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
428         short *no = mdm->verts[index].no;
429
430         no_r[0] = no[0]/32767.f;
431         no_r[1] = no[1]/32767.f;
432         no_r[2] = no[2]/32767.f;
433 }
434
435 static void meshDM_drawVerts(DerivedMesh *dm)
436 {
437         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
438         Mesh *me = mdm->me;
439         int i;
440
441         glBegin(GL_POINTS);
442         for(i=0; i<me->totvert; i++) {
443                 glVertex3fv(mdm->verts[i].co);
444         }
445         glEnd();
446 }
447 static void meshDM_drawUVEdges(DerivedMesh *dm)
448 {
449         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
450         Mesh *me = mdm->me;
451         int i;
452
453         if (me->tface) {
454                 glBegin(GL_LINES);
455                 for (i=0; i<me->totface; i++) {
456                         TFace *tf = &me->tface[i];
457
458                         if (!(tf->flag&TF_HIDE)) {
459                                 glVertex2fv(tf->uv[0]);
460                                 glVertex2fv(tf->uv[1]);
461
462                                 glVertex2fv(tf->uv[1]);
463                                 glVertex2fv(tf->uv[2]);
464
465                                 if (!me->mface[i].v4) {
466                                         glVertex2fv(tf->uv[2]);
467                                         glVertex2fv(tf->uv[0]);
468                                 } else {
469                                         glVertex2fv(tf->uv[2]);
470                                         glVertex2fv(tf->uv[3]);
471
472                                         glVertex2fv(tf->uv[3]);
473                                         glVertex2fv(tf->uv[0]);
474                                 }
475                         }
476                 }
477                 glEnd();
478         }
479 }
480 static void meshDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
481 {
482         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
483         Mesh *me= mdm->me;
484         MEdge *medge= me->medge;
485         int i;
486                 
487         glBegin(GL_LINES);
488         for(i=0; i<me->totedge; i++, medge++) {
489                 if ((medge->flag&ME_EDGEDRAW) && (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) {
490                         glVertex3fv(mdm->verts[medge->v1].co);
491                         glVertex3fv(mdm->verts[medge->v2].co);
492                 }
493         }
494         glEnd();
495 }
496 static void meshDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
497 {
498         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
499         Mesh *me= mdm->me;
500         int i;
501                 
502         glBegin(GL_LINES);
503         for (i=0; i<me->totedge; i++) {
504                 if (!setDrawOptions || setDrawOptions(userData, i)) {
505                         glVertex3fv(mdm->verts[me->medge[i].v1].co);
506                         glVertex3fv(mdm->verts[me->medge[i].v2].co);
507                 }
508         }
509         glEnd();
510 }
511 static void meshDM_drawLooseEdges(DerivedMesh *dm)
512 {
513         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
514         Mesh *me= mdm->me;
515         MEdge *medge= me->medge;
516         int i;
517
518         glBegin(GL_LINES);
519         for (i=0; i<me->totedge; i++, medge++) {
520                 if (medge->flag&ME_LOOSEEDGE) {
521                         glVertex3fv(mdm->verts[medge->v1].co);
522                         glVertex3fv(mdm->verts[medge->v2].co);
523                 }
524         }
525         glEnd();
526 }
527 static void meshDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int))
528 {
529         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
530         Mesh *me = mdm->me;
531         MVert *mvert= mdm->verts;
532         MFace *mface= me->mface;
533         float *nors = mdm->nors;
534         int a;
535         int glmode=-1, shademodel=-1, matnr=-1, drawCurrentMat=1;
536
537 #define PASSVERT(index) {                                               \
538         if (shademodel==GL_SMOOTH) {                            \
539                 short *no = mvert[index].no;                    \
540                 glNormal3sv(no);                                                \
541         }                                                                                       \
542         glVertex3fv(mvert[index].co);   \
543 }
544
545         glBegin(glmode=GL_QUADS);
546         for(a=0; a<me->totface; a++, mface++, nors+=3) {
547                 int new_glmode, new_matnr, new_shademodel;
548                         
549                 new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES;
550                 new_matnr = mface->mat_nr+1;
551                 new_shademodel = (mface->flag & ME_SMOOTH)?GL_SMOOTH:GL_FLAT;
552                 
553                 if (new_glmode!=glmode || new_matnr!=matnr || new_shademodel!=shademodel) {
554                         glEnd();
555
556                         drawCurrentMat = setMaterial(matnr=new_matnr);
557
558                         glShadeModel(shademodel=new_shademodel);
559                         glBegin(glmode=new_glmode);
560                 } 
561                 
562                 if (drawCurrentMat) {
563                         if(shademodel==GL_FLAT) 
564                                 glNormal3fv(nors);
565
566                         PASSVERT(mface->v1);
567                         PASSVERT(mface->v2);
568                         PASSVERT(mface->v3);
569                         if (mface->v4) {
570                                 PASSVERT(mface->v4);
571                         }
572                 }
573         }
574         glEnd();
575
576         glShadeModel(GL_FLAT);
577 #undef PASSVERT
578 }
579
580 static void meshDM_drawFacesColored(DerivedMesh *dm, int useTwoSide, unsigned char *col1, unsigned char *col2)
581 {
582         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
583         Mesh *me= mdm->me;
584         MFace *mface= me->mface;
585         int a, glmode;
586         unsigned char *cp1, *cp2;
587
588         cp1= col1;
589         if(col2) {
590                 cp2= col2;
591         } else {
592                 cp2= NULL;
593                 useTwoSide= 0;
594         }
595
596         /* there's a conflict here... twosided colors versus culling...? */
597         /* defined by history, only texture faces have culling option */
598         /* we need that as mesh option builtin, next to double sided lighting */
599         if(col1 && col2)
600                 glEnable(GL_CULL_FACE);
601         
602         glShadeModel(GL_SMOOTH);
603         glBegin(glmode=GL_QUADS);
604         for(a=0; a<me->totface; a++, mface++, cp1+= 16) {
605                 int new_glmode= mface->v4?GL_QUADS:GL_TRIANGLES;
606
607                 if (new_glmode!=glmode) {
608                         glEnd();
609                         glBegin(glmode= new_glmode);
610                 }
611                         
612                 glColor3ub(cp1[3], cp1[2], cp1[1]);
613                 glVertex3fv( mdm->verts[mface->v1].co );
614                 glColor3ub(cp1[7], cp1[6], cp1[5]);
615                 glVertex3fv( mdm->verts[mface->v2].co );
616                 glColor3ub(cp1[11], cp1[10], cp1[9]);
617                 glVertex3fv( mdm->verts[mface->v3].co );
618                 if(mface->v4) {
619                         glColor3ub(cp1[15], cp1[14], cp1[13]);
620                         glVertex3fv( mdm->verts[mface->v4].co );
621                 }
622                         
623                 if(useTwoSide) {
624                         glColor3ub(cp2[11], cp2[10], cp2[9]);
625                         glVertex3fv( mdm->verts[mface->v3].co );
626                         glColor3ub(cp2[7], cp2[6], cp2[5]);
627                         glVertex3fv( mdm->verts[mface->v2].co );
628                         glColor3ub(cp2[3], cp2[2], cp2[1]);
629                         glVertex3fv( mdm->verts[mface->v1].co );
630                         if(mface->v4) {
631                                 glColor3ub(cp2[15], cp2[14], cp2[13]);
632                                 glVertex3fv( mdm->verts[mface->v4].co );
633                         }
634                 }
635                 if(col2) cp2+= 16;
636         }
637         glEnd();
638
639         glShadeModel(GL_FLAT);
640         glDisable(GL_CULL_FACE);
641 }
642
643 static void meshDM_drawFacesTex_common(DerivedMesh *dm, int (*drawParams)(TFace *tface, int matnr), int (*drawParamsMapped)(void *userData, int index), void *userData) 
644 {
645         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
646         Mesh *me = mdm->me;
647         MVert *mvert= mdm->verts;
648         MFace *mface= me->mface;
649         TFace *tface = me->tface;
650         float *nors = mdm->nors;
651         int i;
652
653         for (i=0; i<me->totface; i++) {
654                 MFace *mf= &mface[i];
655                 TFace *tf = tface?&tface[i]:NULL;
656                 int flag;
657                 unsigned char *cp= NULL;
658                 
659                 if (drawParams)
660                         flag = drawParams(tf, mf->mat_nr);
661                 else
662                         flag = drawParamsMapped(userData, i);
663
664                 if (flag==0) {
665                         continue;
666                 } else if (flag==1) {
667                         if (mdm->wpaintMCol) {
668                                 cp= (unsigned char*) &mdm->wpaintMCol[i*4];
669                         } else if (tf) {
670                                 cp= (unsigned char*) tf->col;
671                         } else if (me->mcol) {
672                                 cp= (unsigned char*) &me->mcol[i*4];
673                         }
674                 }
675
676                 if (!(mf->flag&ME_SMOOTH)) {
677                         glNormal3fv(&nors[i*3]);
678                 }
679
680                 glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
681                 if (tf) glTexCoord2fv(tf->uv[0]);
682                 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
683                 if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v1].no);
684                 glVertex3fv(mvert[mf->v1].co);
685                         
686                 if (tf) glTexCoord2fv(tf->uv[1]);
687                 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
688                 if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v2].no);
689                 glVertex3fv(mvert[mf->v2].co);
690
691                 if (tf) glTexCoord2fv(tf->uv[2]);
692                 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
693                 if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v3].no);
694                 glVertex3fv(mvert[mf->v3].co);
695
696                 if(mf->v4) {
697                         if (tf) glTexCoord2fv(tf->uv[3]);
698                         if (cp) glColor3ub(cp[15], cp[14], cp[13]);
699                         if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v4].no);
700                         glVertex3fv(mvert[mf->v4].co);
701                 }
702                 glEnd();
703         }
704 }
705 static void meshDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tface, int matnr)) 
706 {
707         meshDM_drawFacesTex_common(dm, setDrawParams, NULL, NULL);
708 }
709 static void meshDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawParams)(void *userData, int index), void *userData) 
710 {
711         meshDM_drawFacesTex_common(dm, NULL, setDrawParams, userData);
712 }
713
714 static void meshDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors) 
715 {
716         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
717         Mesh *me = mdm->me;
718         MVert *mvert= mdm->verts;
719         MFace *mface= me->mface;
720         float *nors= mdm->nors;
721         int i;
722
723         for (i=0; i<me->totface; i++) {
724                 MFace *mf= &mface[i];
725                 int drawSmooth = (mf->flag & ME_SMOOTH);
726
727                 if (!setDrawOptions || setDrawOptions(userData, i, &drawSmooth)) {
728                         unsigned char *cp = NULL;
729
730                         if (useColors) {
731                                 if (mdm->wpaintMCol) {
732                                         cp= (unsigned char*) &mdm->wpaintMCol[i*4];
733                                 } else if (me->tface) {
734                                         cp= (unsigned char*) me->tface[i].col;
735                                 } else if (me->mcol) {
736                                         cp= (unsigned char*) &me->mcol[i*4];
737                                 }
738                         }
739
740                         glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
741                         glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
742
743                         if (!drawSmooth) {
744                                 glNormal3fv(&nors[i*3]);
745
746                                 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
747                                 glVertex3fv(mvert[mf->v1].co);
748                                 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
749                                 glVertex3fv(mvert[mf->v2].co);
750                                 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
751                                 glVertex3fv(mvert[mf->v3].co);
752                                 if(mf->v4) {
753                                         if (cp) glColor3ub(cp[15], cp[14], cp[13]);
754                                         glVertex3fv(mvert[mf->v4].co);
755                                 }
756                         } else {
757                                 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
758                                 glNormal3sv(mvert[mf->v1].no);
759                                 glVertex3fv(mvert[mf->v1].co);
760                                 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
761                                 glNormal3sv(mvert[mf->v2].no);
762                                 glVertex3fv(mvert[mf->v2].co);
763                                 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
764                                 glNormal3sv(mvert[mf->v3].no);
765                                 glVertex3fv(mvert[mf->v3].co);
766                                 if(mf->v4) {
767                                         if (cp) glColor3ub(cp[15], cp[14], cp[13]);
768                                         glNormal3sv(mvert[mf->v4].no);
769                                         glVertex3fv(mvert[mf->v4].co);
770                                 }
771                         }
772
773                         glEnd();
774                 }
775         }
776 }
777 static int meshDM_getNumVerts(DerivedMesh *dm)
778 {
779         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
780         Mesh *me = mdm->me;
781
782         return me->totvert;
783 }
784
785 static int meshDM_getNumEdges(DerivedMesh *dm)
786 {
787         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
788         Mesh *me = mdm->me;
789
790         return me->totedge;
791 }
792
793 static int meshDM_getNumFaces(DerivedMesh *dm)
794 {
795         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
796         Mesh *me = mdm->me;
797
798         return me->totface;
799 }
800
801 void meshDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
802 {
803         MVert *verts = ((MeshDerivedMesh *)dm)->verts;
804
805         *vert_r = verts[index];
806 }
807
808 void meshDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
809 {
810         Mesh *me = ((MeshDerivedMesh *)dm)->me;
811
812         *edge_r = me->medge[index];
813 }
814
815 void meshDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
816 {
817         Mesh *me = ((MeshDerivedMesh *)dm)->me;
818
819         *face_r = me->mface[index];
820 }
821
822 void meshDM_getVertArray(DerivedMesh *dm, MVert *vert_r)
823 {
824         MeshDerivedMesh *mdm = (MeshDerivedMesh *)dm;
825         memcpy(vert_r, mdm->verts, sizeof(*vert_r) * mdm->me->totvert);
826 }
827
828 void meshDM_getEdgeArray(DerivedMesh *dm, MEdge *edge_r)
829 {
830         MeshDerivedMesh *mdm = (MeshDerivedMesh *)dm;
831         memcpy(edge_r, mdm->me->medge, sizeof(*edge_r) * mdm->me->totedge);
832 }
833
834 void meshDM_getFaceArray(DerivedMesh *dm, MFace *face_r)
835 {
836         MeshDerivedMesh *mdm = (MeshDerivedMesh *)dm;
837         memcpy(face_r, mdm->me->mface, sizeof(*face_r) * mdm->me->totface);
838 }
839
840 static void meshDM_release(DerivedMesh *dm)
841 {
842         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
843
844         DM_release(dm);
845
846         if (mdm->wpaintMCol) MEM_freeN(mdm->wpaintMCol);
847         if (mdm->freeNors) MEM_freeN(mdm->nors);
848         if (mdm->freeVerts) MEM_freeN(mdm->verts);
849         MEM_freeN(mdm);
850 }
851
852 static DerivedMesh *getMeshDerivedMesh(Mesh *me, Object *ob, float (*vertCos)[3])
853 {
854         MeshDerivedMesh *mdm = MEM_callocN(sizeof(*mdm), "mdm");
855
856         DM_init(&mdm->dm, me->totvert, me->totedge, me->totface);
857
858         mdm->dm.getMinMax = meshDM_getMinMax;
859
860         mdm->dm.convertToDispListMesh = meshDM_convertToDispListMesh;
861         mdm->dm.getNumVerts = meshDM_getNumVerts;
862         mdm->dm.getNumEdges = meshDM_getNumEdges;
863         mdm->dm.getNumFaces = meshDM_getNumFaces;
864
865         mdm->dm.getVert = meshDM_getVert;
866         mdm->dm.getEdge = meshDM_getEdge;
867         mdm->dm.getFace = meshDM_getFace;
868         mdm->dm.getVertArray = meshDM_getVertArray;
869         mdm->dm.getEdgeArray = meshDM_getEdgeArray;
870         mdm->dm.getFaceArray = meshDM_getFaceArray;
871
872         mdm->dm.getVertCos = meshDM_getVertCos;
873         mdm->dm.getVertCo = meshDM_getVertCo;
874         mdm->dm.getVertNo = meshDM_getVertNo;
875
876         mdm->dm.drawVerts = meshDM_drawVerts;
877
878         mdm->dm.drawUVEdges = meshDM_drawUVEdges;
879         mdm->dm.drawEdges = meshDM_drawEdges;
880         mdm->dm.drawLooseEdges = meshDM_drawLooseEdges;
881         
882         mdm->dm.drawFacesSolid = meshDM_drawFacesSolid;
883         mdm->dm.drawFacesColored = meshDM_drawFacesColored;
884         mdm->dm.drawFacesTex = meshDM_drawFacesTex;
885         mdm->dm.drawMappedFaces = meshDM_drawMappedFaces;
886         mdm->dm.drawMappedFacesTex = meshDM_drawMappedFacesTex;
887
888         mdm->dm.drawMappedEdges = meshDM_drawMappedEdges;
889         mdm->dm.drawMappedFaces = meshDM_drawMappedFaces;
890
891         mdm->dm.release = meshDM_release;
892
893         /* add appropriate data layers (don't copy, just reference) */
894         if(me->msticky)
895                 DM_add_vert_layer(&mdm->dm, LAYERTYPE_MSTICKY,
896                                   LAYERFLAG_NOFREE, me->msticky);
897         if(me->dvert)
898                 DM_add_vert_layer(&mdm->dm, LAYERTYPE_MDEFORMVERT,
899                                   LAYERFLAG_NOFREE, me->dvert);
900
901         if(me->tface)
902                 DM_add_face_layer(&mdm->dm, LAYERTYPE_TFACE,
903                                   LAYERFLAG_NOFREE, me->tface);
904         if(me->mcol)
905                 DM_add_face_layer(&mdm->dm, LAYERTYPE_MCOL,
906                                   LAYERFLAG_NOFREE, me->mcol);
907
908                 /* Works in conjunction with hack during modifier calc */
909         if ((G.f & G_WEIGHTPAINT) && ob==(G.scene->basact?G.scene->basact->object:NULL)) {
910                 mdm->wpaintMCol = MEM_dupallocN(me->mcol);
911         }
912
913         mdm->ob = ob;
914         mdm->me = me;
915         mdm->verts = me->mvert;
916         mdm->nors = NULL;
917         mdm->freeNors = 0;
918         mdm->freeVerts = 0;
919
920         if((ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) &&
921                  (ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN)&&
922            (ob->fluidsimSettings->meshSurface) &&
923                  (1) && (!give_parteff(ob)) && // doesnt work together with particle systems!
924                  (me->totvert == ((Mesh *)(ob->fluidsimSettings->meshSurface))->totvert) ) {
925                 // dont recompute for fluidsim mesh, use from readBobjgz
926                 // TODO? check for modifiers!?
927                 int i;
928                 mesh_calc_normals(mdm->verts, me->totvert, me->mface, me->totface, &mdm->nors);
929                 mdm->freeNors = 1;
930                 for (i=0; i<me->totvert; i++) {
931                         MVert *mv= &mdm->verts[i];
932                         MVert *fsv; 
933                         fsv = &ob->fluidsimSettings->meshSurfNormals[i];
934                         VECCOPY(mv->no, fsv->no);
935                         //mv->no[0]= 30000; mv->no[1]= mv->no[2]= 0; // DEBUG fixed test normals
936                 }
937         } else {
938                 // recompute normally
939
940                 if (vertCos) {
941                         int i;
942
943                         /* copy the original verts to preserve flag settings; if this is too
944                          * costly, must at least use MEM_callocN to clear flags */
945                         mdm->verts = MEM_dupallocN( me->mvert );
946                         for (i=0; i<me->totvert; i++) {
947                                 VECCOPY(mdm->verts[i].co, vertCos[i]);
948                         }
949                         mesh_calc_normals(mdm->verts, me->totvert, me->mface, me->totface, &mdm->nors);
950                         mdm->freeNors = 1;
951                         mdm->freeVerts = 1;
952                 } else {
953                         // XXX this is kinda hacky because we shouldn't really be editing
954                         // the mesh here, however, we can't just call mesh_build_faceNormals(ob)
955                         // because in the case when a key is applied to a mesh the vertex normals
956                         // would never be correctly computed.
957                         mesh_calc_normals(mdm->verts, me->totvert, me->mface, me->totface, &mdm->nors);
958                         mdm->freeNors = 1;
959                 }
960         } // fs TEST
961
962         return (DerivedMesh*) mdm;
963 }
964
965 ///
966
967 typedef struct {
968         DerivedMesh dm;
969
970         EditMesh *em;
971         float (*vertexCos)[3];
972         float (*vertexNos)[3];
973         float (*faceNos)[3];
974 } EditMeshDerivedMesh;
975
976 static void emDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData)
977 {
978         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
979         EditVert *eve;
980         int i;
981
982         for (i=0,eve= emdm->em->verts.first; eve; i++,eve=eve->next) {
983                 if (emdm->vertexCos) {
984                         func(userData, i, emdm->vertexCos[i], emdm->vertexNos[i], NULL);
985                 } else {
986                         func(userData, i, eve->co, eve->no, NULL);
987                 }
988         }
989 }
990 static void emDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData)
991 {
992         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
993         EditEdge *eed;
994         int i;
995
996         if (emdm->vertexCos) {
997                 EditVert *eve, *preveve;
998
999                 for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
1000                         eve->prev = (EditVert*) i++;
1001                 for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next)
1002                         func(userData, i, emdm->vertexCos[(int) eed->v1->prev], emdm->vertexCos[(int) eed->v2->prev]);
1003                 for (preveve=NULL, eve=emdm->em->verts.first; eve; preveve=eve, eve= eve->next)
1004                         eve->prev = preveve;
1005         } else {
1006                 for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next)
1007                         func(userData, i, eed->v1->co, eed->v2->co);
1008         }
1009 }
1010 static void emDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) 
1011 {
1012         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
1013         EditEdge *eed;
1014         int i;
1015
1016         if (emdm->vertexCos) {
1017                 EditVert *eve, *preveve;
1018
1019                 for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
1020                         eve->prev = (EditVert*) i++;
1021
1022                 glBegin(GL_LINES);
1023                 for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
1024                         if(!setDrawOptions || setDrawOptions(userData, i)) {
1025                                 glVertex3fv(emdm->vertexCos[(int) eed->v1->prev]);
1026                                 glVertex3fv(emdm->vertexCos[(int) eed->v2->prev]);
1027                         }
1028                 }
1029                 glEnd();
1030
1031                 for (preveve=NULL, eve=emdm->em->verts.first; eve; preveve=eve, eve= eve->next)
1032                         eve->prev = preveve;
1033         } else {
1034                 glBegin(GL_LINES);
1035                 for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
1036                         if(!setDrawOptions || setDrawOptions(userData, i)) {
1037                                 glVertex3fv(eed->v1->co);
1038                                 glVertex3fv(eed->v2->co);
1039                         }
1040                 }
1041                 glEnd();
1042         }
1043 }
1044 static void emDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
1045 {
1046         emDM_drawMappedEdges(dm, NULL, NULL);
1047 }
1048 static void emDM_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) 
1049 {
1050         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
1051         EditEdge *eed;
1052         int i;
1053
1054         if (emdm->vertexCos) {
1055                 EditVert *eve, *preveve;
1056
1057                 for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
1058                         eve->prev = (EditVert*) i++;
1059
1060                 glBegin(GL_LINES);
1061                 for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
1062                         if(!setDrawOptions || setDrawOptions(userData, i)) {
1063                                 setDrawInterpOptions(userData, i, 0.0);
1064                                 glVertex3fv(emdm->vertexCos[(int) eed->v1->prev]);
1065                                 setDrawInterpOptions(userData, i, 1.0);
1066                                 glVertex3fv(emdm->vertexCos[(int) eed->v2->prev]);
1067                         }
1068                 }
1069                 glEnd();
1070
1071                 for (preveve=NULL, eve=emdm->em->verts.first; eve; preveve=eve, eve= eve->next)
1072                         eve->prev = preveve;
1073         } else {
1074                 glBegin(GL_LINES);
1075                 for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
1076                         if(!setDrawOptions || setDrawOptions(userData, i)) {
1077                                 setDrawInterpOptions(userData, i, 0.0);
1078                                 glVertex3fv(eed->v1->co);
1079                                 setDrawInterpOptions(userData, i, 1.0);
1080                                 glVertex3fv(eed->v2->co);
1081                         }
1082                 }
1083                 glEnd();
1084         }
1085 }
1086
1087 static void emDM_drawUVEdges(DerivedMesh *dm)
1088 {
1089         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
1090         EditFace *efa;
1091         TFace *tf;
1092
1093         glBegin(GL_LINES);
1094         for(efa= emdm->em->faces.first; efa; efa= efa->next) {
1095                 tf = CustomData_em_get(&emdm->em->fdata, efa->data, LAYERTYPE_TFACE);
1096
1097                 if(tf && !(tf->flag&TF_HIDE)) {
1098                         glVertex2fv(tf->uv[0]);
1099                         glVertex2fv(tf->uv[1]);
1100
1101                         glVertex2fv(tf->uv[1]);
1102                         glVertex2fv(tf->uv[2]);
1103
1104                         if (!efa->v4) {
1105                                 glVertex2fv(tf->uv[2]);
1106                                 glVertex2fv(tf->uv[0]);
1107                         } else {
1108                                 glVertex2fv(tf->uv[2]);
1109                                 glVertex2fv(tf->uv[3]);
1110                                 glVertex2fv(tf->uv[3]);
1111                                 glVertex2fv(tf->uv[0]);
1112                         }
1113                 }
1114         }
1115         glEnd();
1116 }
1117
1118 static void emDM__calcFaceCent(EditFace *efa, float cent[3], float (*vertexCos)[3])
1119 {
1120         if (vertexCos) {
1121                 VECCOPY(cent, vertexCos[(int) efa->v1->prev]);
1122                 VecAddf(cent, cent, vertexCos[(int) efa->v2->prev]);
1123                 VecAddf(cent, cent, vertexCos[(int) efa->v3->prev]);
1124                 if (efa->v4) VecAddf(cent, cent, vertexCos[(int) efa->v4->prev]);
1125         } else {
1126                 VECCOPY(cent, efa->v1->co);
1127                 VecAddf(cent, cent, efa->v2->co);
1128                 VecAddf(cent, cent, efa->v3->co);
1129                 if (efa->v4) VecAddf(cent, cent, efa->v4->co);
1130         }
1131
1132         if (efa->v4) {
1133                 VecMulf(cent, 0.25f);
1134         } else {
1135                 VecMulf(cent, 0.33333333333f);
1136         }
1137 }
1138 static void emDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData)
1139 {
1140         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
1141         EditVert *eve, *preveve;
1142         EditFace *efa;
1143         float cent[3];
1144         int i;
1145
1146         if (emdm->vertexCos) {
1147                 for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
1148                         eve->prev = (EditVert*) i++;
1149         }
1150
1151         for(i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
1152                 emDM__calcFaceCent(efa, cent, emdm->vertexCos);
1153                 func(userData, i, cent, emdm->vertexCos?emdm->faceNos[i]:efa->n);
1154         }
1155
1156         if (emdm->vertexCos) {
1157                 for (preveve=NULL, eve=emdm->em->verts.first; eve; preveve=eve, eve= eve->next)
1158                         eve->prev = preveve;
1159         }
1160 }
1161 static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors)
1162 {
1163         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
1164         EditFace *efa;
1165         int i;
1166
1167         if (emdm->vertexCos) {
1168                 EditVert *eve, *preveve;
1169
1170                 for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
1171                         eve->prev = (EditVert*) i++;
1172
1173                 for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
1174                         int drawSmooth = (efa->flag & ME_SMOOTH);
1175                         if(!setDrawOptions || setDrawOptions(userData, i, &drawSmooth)) {
1176                                 glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
1177
1178                                 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
1179                                 if (!drawSmooth) {
1180                                         glNormal3fv(emdm->faceNos[i]);
1181                                         glVertex3fv(emdm->vertexCos[(int) efa->v1->prev]);
1182                                         glVertex3fv(emdm->vertexCos[(int) efa->v2->prev]);
1183                                         glVertex3fv(emdm->vertexCos[(int) efa->v3->prev]);
1184                                         if(efa->v4) glVertex3fv(emdm->vertexCos[(int) efa->v4->prev]);
1185                                 } else {
1186                                         glNormal3fv(emdm->vertexNos[(int) efa->v1->prev]);
1187                                         glVertex3fv(emdm->vertexCos[(int) efa->v1->prev]);
1188                                         glNormal3fv(emdm->vertexNos[(int) efa->v2->prev]);
1189                                         glVertex3fv(emdm->vertexCos[(int) efa->v2->prev]);
1190                                         glNormal3fv(emdm->vertexNos[(int) efa->v3->prev]);
1191                                         glVertex3fv(emdm->vertexCos[(int) efa->v3->prev]);
1192                                         if(efa->v4) {
1193                                                 glNormal3fv(emdm->vertexNos[(int) efa->v4->prev]);
1194                                                 glVertex3fv(emdm->vertexCos[(int) efa->v4->prev]);
1195                                         }
1196                                 }
1197                                 glEnd();
1198                         }
1199                 }
1200
1201                 for (preveve=NULL, eve=emdm->em->verts.first; eve; preveve=eve, eve= eve->next)
1202                         eve->prev = preveve;
1203         } else {
1204                 for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
1205                         int drawSmooth = (efa->flag & ME_SMOOTH);
1206                         if(!setDrawOptions || setDrawOptions(userData, i, &drawSmooth)) {
1207                                 glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
1208
1209                                 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
1210                                 if (!drawSmooth) {
1211                                         glNormal3fv(efa->n);
1212                                         glVertex3fv(efa->v1->co);
1213                                         glVertex3fv(efa->v2->co);
1214                                         glVertex3fv(efa->v3->co);
1215                                         if(efa->v4) glVertex3fv(efa->v4->co);
1216                                 } else {
1217                                         glNormal3fv(efa->v1->no);
1218                                         glVertex3fv(efa->v1->co);
1219                                         glNormal3fv(efa->v2->no);
1220                                         glVertex3fv(efa->v2->co);
1221                                         glNormal3fv(efa->v3->no);
1222                                         glVertex3fv(efa->v3->co);
1223                                         if(efa->v4) {
1224                                                 glNormal3fv(efa->v4->no);
1225                                                 glVertex3fv(efa->v4->co);
1226                                         }
1227                                 }
1228                                 glEnd();
1229                         }
1230                 }
1231         }
1232 }
1233
1234 static void emDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
1235 {
1236         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
1237         EditVert *eve;
1238         int i;
1239
1240         if (emdm->em->verts.first) {
1241                 for (i=0,eve= emdm->em->verts.first; eve; i++,eve= eve->next) {
1242                         if (emdm->vertexCos) {
1243                                 DO_MINMAX(emdm->vertexCos[i], min_r, max_r);
1244                         } else {
1245                                 DO_MINMAX(eve->co, min_r, max_r);
1246                         }
1247                 }
1248         } else {
1249                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
1250         }
1251 }
1252 static int emDM_getNumVerts(DerivedMesh *dm)
1253 {
1254         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
1255
1256         return BLI_countlist(&emdm->em->verts);
1257 }
1258
1259 static int emDM_getNumEdges(DerivedMesh *dm)
1260 {
1261         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
1262
1263         return BLI_countlist(&emdm->em->edges);
1264 }
1265
1266 static int emDM_getNumFaces(DerivedMesh *dm)
1267 {
1268         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
1269
1270         return BLI_countlist(&emdm->em->faces);
1271 }
1272
1273 void emDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
1274 {
1275         EditVert *ev = ((EditMeshDerivedMesh *)dm)->em->verts.first;
1276         int i;
1277
1278         for(i = 0; i < index; ++i) ev = ev->next;
1279
1280         VECCOPY(vert_r->co, ev->co);
1281
1282         vert_r->no[0] = ev->no[0] * 32767.0;
1283         vert_r->no[1] = ev->no[1] * 32767.0;
1284         vert_r->no[2] = ev->no[2] * 32767.0;
1285
1286         /* TODO what to do with vert_r->flag and vert_r->mat_nr? */
1287         vert_r->mat_nr = 0;
1288 }
1289
1290 void emDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
1291 {
1292         EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
1293         EditEdge *ee = em->edges.first;
1294         EditVert *ev, *v1, *v2;
1295         int i;
1296
1297         for(i = 0; i < index; ++i) ee = ee->next;
1298
1299         edge_r->crease = (unsigned char) (ee->crease*255.0f);
1300         /* TODO what to do with edge_r->flag? */
1301         edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER;
1302         if (ee->seam) edge_r->flag |= ME_SEAM;
1303         if (ee->sharp) edge_r->flag |= ME_SHARP;
1304 #if 0
1305         /* this needs setup of f2 field */
1306         if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE;
1307 #endif
1308
1309         /* goddamn, we have to search all verts to find indices */
1310         v1 = ee->v1;
1311         v2 = ee->v2;
1312         for(i = 0, ev = em->verts.first; v1 || v2; i++, ev = ev->next) {
1313                 if(ev == v1) {
1314                         edge_r->v1 = i;
1315                         v1 = NULL;
1316                 }
1317                 if(ev == v2) {
1318                         edge_r->v2 = i;
1319                         v2 = NULL;
1320                 }
1321         }
1322 }
1323
1324 void emDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
1325 {
1326         EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
1327         EditFace *ef = em->faces.first;
1328         EditVert *ev, *v1, *v2, *v3, *v4;
1329         int i;
1330
1331         for(i = 0; i < index; ++i) ef = ef->next;
1332
1333         face_r->mat_nr = ef->mat_nr;
1334         face_r->flag = ef->flag;
1335
1336         /* goddamn, we have to search all verts to find indices */
1337         v1 = ef->v1;
1338         v2 = ef->v2;
1339         v3 = ef->v3;
1340         v4 = ef->v4;
1341         if(!v4) face_r->v4 = 0;
1342
1343         for(i = 0, ev = em->verts.first; v1 || v2 || v3 || v4;
1344             i++, ev = ev->next) {
1345                 if(ev == v1) {
1346                         face_r->v1 = i;
1347                         v1 = NULL;
1348                 }
1349                 if(ev == v2) {
1350                         face_r->v2 = i;
1351                         v2 = NULL;
1352                 }
1353                 if(ev == v3) {
1354                         face_r->v3 = i;
1355                         v3 = NULL;
1356                 }
1357                 if(ev == v4) {
1358                         face_r->v4 = i;
1359                         v4 = NULL;
1360                 }
1361         }
1362
1363         test_index_face(face_r, NULL, NULL, ef->v4?4:3);
1364 }
1365
1366 void emDM_getVertArray(DerivedMesh *dm, MVert *vert_r)
1367 {
1368         EditVert *ev = ((EditMeshDerivedMesh *)dm)->em->verts.first;
1369
1370         for( ; ev; ev = ev->next, ++vert_r) {
1371                 VECCOPY(vert_r->co, ev->co);
1372
1373                 vert_r->no[0] = ev->no[0] * 32767.0;
1374                 vert_r->no[1] = ev->no[1] * 32767.0;
1375                 vert_r->no[2] = ev->no[2] * 32767.0;
1376
1377                 /* TODO what to do with vert_r->flag and vert_r->mat_nr? */
1378                 vert_r->mat_nr = 0;
1379                 vert_r->flag = 0;
1380         }
1381 }
1382
1383 void emDM_getEdgeArray(DerivedMesh *dm, MEdge *edge_r)
1384 {
1385         EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
1386         EditEdge *ee = em->edges.first;
1387         EditVert *ev, *prevev;
1388         int i;
1389
1390         /* store vert indices in the prev pointer (kind of hacky) */
1391         for(ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
1392                 ev->prev = (EditVert*) i++;
1393
1394         for( ; ee; ee = ee->next, ++edge_r) {
1395                 edge_r->crease = (unsigned char) (ee->crease*255.0f);
1396                 /* TODO what to do with edge_r->flag? */
1397                 edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER;
1398                 if (ee->seam) edge_r->flag |= ME_SEAM;
1399                 if (ee->sharp) edge_r->flag |= ME_SHARP;
1400 #if 0
1401                 /* this needs setup of f2 field */
1402                 if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE;
1403 #endif
1404
1405                 edge_r->v1 = (int)ee->v1->prev;
1406                 edge_r->v2 = (int)ee->v2->prev;
1407         }
1408
1409         /* restore prev pointers */
1410         for(prevev = NULL, ev = em->verts.first; ev; prevev = ev, ev = ev->next)
1411                 ev->prev = prevev;
1412 }
1413
1414 void emDM_getFaceArray(DerivedMesh *dm, MFace *face_r)
1415 {
1416         EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
1417         EditFace *ef = em->faces.first;
1418         EditVert *ev, *prevev;
1419         int i;
1420
1421         /* store vert indices in the prev pointer (kind of hacky) */
1422         for(ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
1423                 ev->prev = (EditVert*) i++;
1424
1425         for( ; ef; ef = ef->next, ++face_r) {
1426                 face_r->mat_nr = ef->mat_nr;
1427                 face_r->flag = ef->flag;
1428
1429                 face_r->v1 = (int)ef->v1->prev;
1430                 face_r->v2 = (int)ef->v2->prev;
1431                 face_r->v3 = (int)ef->v3->prev;
1432                 if(ef->v4) face_r->v4 = (int)ef->v4->prev;
1433                 else face_r->v4 = 0;
1434
1435                 test_index_face(face_r, NULL, NULL, ef->v4?4:3);
1436         }
1437
1438         /* restore prev pointers */
1439         for(prevev = NULL, ev = em->verts.first; ev; prevev = ev, ev = ev->next)
1440                 ev->prev = prevev;
1441 }
1442
1443 static void emDM_release(DerivedMesh *dm)
1444 {
1445         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
1446
1447         DM_release(dm);
1448
1449         if (emdm->vertexCos) {
1450                 MEM_freeN(emdm->vertexCos);
1451                 MEM_freeN(emdm->vertexNos);
1452                 MEM_freeN(emdm->faceNos);
1453         }
1454
1455         MEM_freeN(emdm);
1456 }
1457
1458 static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em, Object *ob,
1459                                            float (*vertexCos)[3])
1460 {
1461         EditMeshDerivedMesh *emdm = MEM_callocN(sizeof(*emdm), "emdm");
1462
1463         DM_init(&emdm->dm, BLI_countlist(&em->verts),
1464                          BLI_countlist(&em->edges), BLI_countlist(&em->faces));
1465
1466         emdm->dm.getMinMax = emDM_getMinMax;
1467
1468         emdm->dm.getNumVerts = emDM_getNumVerts;
1469         emdm->dm.getNumEdges = emDM_getNumEdges;
1470         emdm->dm.getNumFaces = emDM_getNumFaces;
1471
1472         emdm->dm.getVert = emDM_getVert;
1473         emdm->dm.getEdge = emDM_getEdge;
1474         emdm->dm.getFace = emDM_getFace;
1475         emdm->dm.getVertArray = emDM_getVertArray;
1476         emdm->dm.getEdgeArray = emDM_getEdgeArray;
1477         emdm->dm.getFaceArray = emDM_getFaceArray;
1478
1479         emdm->dm.foreachMappedVert = emDM_foreachMappedVert;
1480         emdm->dm.foreachMappedEdge = emDM_foreachMappedEdge;
1481         emdm->dm.foreachMappedFaceCenter = emDM_foreachMappedFaceCenter;
1482
1483         emdm->dm.drawEdges = emDM_drawEdges;
1484         emdm->dm.drawMappedEdges = emDM_drawMappedEdges;
1485         emdm->dm.drawMappedEdgesInterp = emDM_drawMappedEdgesInterp;
1486         emdm->dm.drawMappedFaces = emDM_drawMappedFaces;
1487         emdm->dm.drawUVEdges = emDM_drawUVEdges;
1488
1489         emdm->dm.release = emDM_release;
1490         
1491         emdm->em = em;
1492         emdm->vertexCos = vertexCos;
1493
1494         if(CustomData_has_layer(&em->vdata, LAYERTYPE_MDEFORMVERT)) {
1495                 EditVert *eve;
1496                 int i;
1497
1498                 DM_add_vert_layer(&emdm->dm, LAYERTYPE_MDEFORMVERT, 0, NULL);
1499
1500                 for(eve = em->verts.first, i = 0; eve; eve = eve->next, ++i)
1501                         DM_set_vert_data(&emdm->dm, i, LAYERTYPE_MDEFORMVERT,
1502                                          CustomData_em_get(&em->vdata, eve->data, LAYERTYPE_MDEFORMVERT));
1503         }
1504
1505         if(vertexCos) {
1506                 EditVert *eve, *preveve;
1507                 EditFace *efa;
1508                 int totface = BLI_countlist(&em->faces);
1509                 int i;
1510
1511                 for (i=0,eve=em->verts.first; eve; eve= eve->next)
1512                         eve->prev = (EditVert*) i++;
1513
1514                 emdm->vertexNos = MEM_callocN(sizeof(*emdm->vertexNos)*i, "emdm_vno");
1515                 emdm->faceNos = MEM_mallocN(sizeof(*emdm->faceNos)*totface, "emdm_vno");
1516
1517                 for(i=0, efa= em->faces.first; efa; i++, efa=efa->next) {
1518                         float *v1 = vertexCos[(int) efa->v1->prev];
1519                         float *v2 = vertexCos[(int) efa->v2->prev];
1520                         float *v3 = vertexCos[(int) efa->v3->prev];
1521                         float *no = emdm->faceNos[i];
1522                         
1523                         if(efa->v4) {
1524                                 float *v4 = vertexCos[(int) efa->v3->prev];
1525
1526                                 CalcNormFloat4(v1, v2, v3, v4, no);
1527                                 VecAddf(emdm->vertexNos[(int) efa->v4->prev], emdm->vertexNos[(int) efa->v4->prev], no);
1528                         }
1529                         else {
1530                                 CalcNormFloat(v1, v2, v3, no);
1531                         }
1532
1533                         VecAddf(emdm->vertexNos[(int) efa->v1->prev], emdm->vertexNos[(int) efa->v1->prev], no);
1534                         VecAddf(emdm->vertexNos[(int) efa->v2->prev], emdm->vertexNos[(int) efa->v2->prev], no);
1535                         VecAddf(emdm->vertexNos[(int) efa->v3->prev], emdm->vertexNos[(int) efa->v3->prev], no);
1536                 }
1537
1538                 for(i=0, eve= em->verts.first; eve; i++, eve=eve->next) {
1539                         float *no = emdm->vertexNos[i];
1540                         /* following Mesh convention; we use vertex coordinate itself
1541                          * for normal in this case */
1542                         if (Normalise(no)==0.0) {
1543                                 VECCOPY(no, vertexCos[i]);
1544                                 Normalise(no);
1545                         }
1546                 }
1547
1548                 for (preveve=NULL, eve=emdm->em->verts.first; eve; preveve=eve, eve= eve->next)
1549                         eve->prev = preveve;
1550         }
1551
1552         return (DerivedMesh*) emdm;
1553 }
1554
1555 ///
1556
1557 typedef struct {
1558         DerivedMesh dm;
1559
1560         DispListMesh *dlm;
1561 } SSDerivedMesh;
1562
1563 static void ssDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData)
1564 {
1565         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1566         DispListMesh *dlm = ssdm->dlm;
1567         int i;
1568         int *index = dm->getVertDataArray(dm, LAYERTYPE_ORIGINDEX);
1569
1570         for (i=0; i<dlm->totvert; i++, index++) {
1571                 MVert *mv = &dlm->mvert[i];
1572
1573                 if(*index != ORIGINDEX_NONE)
1574                         func(userData, *index, mv->co, NULL, mv->no);
1575         }
1576 }
1577 static void ssDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData)
1578 {
1579         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1580         DispListMesh *dlm = ssdm->dlm;
1581         int i;
1582         int *index = dm->getEdgeDataArray(dm, LAYERTYPE_ORIGINDEX);
1583
1584         for (i=0; i<dlm->totedge; i++, index++) {
1585                 MEdge *med = &dlm->medge[i];
1586
1587                 if(*index != ORIGINDEX_NONE)
1588                         func(userData, *index, dlm->mvert[med->v1].co,
1589                              dlm->mvert[med->v2].co);
1590         }
1591 }
1592 static void ssDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) 
1593 {
1594         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1595         DispListMesh *dlm = ssdm->dlm;
1596         int i;
1597         int *index = dm->getEdgeDataArray(dm, LAYERTYPE_ORIGINDEX);
1598
1599         glBegin(GL_LINES);
1600         for(i=0; i<dlm->totedge; i++, index++) {
1601                 MEdge *med = &dlm->medge[i];
1602
1603                 if(*index != ORIGINDEX_NONE
1604                    && (!setDrawOptions || setDrawOptions(userData, *index))) {
1605                         glVertex3fv(dlm->mvert[med->v1].co);
1606                         glVertex3fv(dlm->mvert[med->v2].co);
1607                 }
1608         }
1609         glEnd();
1610 }
1611
1612 static void ssDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData)
1613 {
1614         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1615         DispListMesh *dlm = ssdm->dlm;
1616         int i;
1617         int *index = dm->getFaceDataArray(dm, LAYERTYPE_ORIGINDEX);
1618
1619         for (i=0; i<dlm->totface; i++, index++) {
1620                 MFace *mf = &dlm->mface[i];
1621
1622                 if(*index != ORIGINDEX_NONE) {
1623                         float cent[3];
1624                         float no[3];
1625
1626                         VECCOPY(cent, dlm->mvert[mf->v1].co);
1627                         VecAddf(cent, cent, dlm->mvert[mf->v2].co);
1628                         VecAddf(cent, cent, dlm->mvert[mf->v3].co);
1629
1630                         if (mf->v4) {
1631                                 CalcNormFloat4(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, dlm->mvert[mf->v4].co, no);
1632                                 VecAddf(cent, cent, dlm->mvert[mf->v4].co);
1633                                 VecMulf(cent, 0.25f);
1634                         } else {
1635                                 CalcNormFloat(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, no);
1636                                 VecMulf(cent, 0.33333333333f);
1637                         }
1638
1639                         func(userData, *index, cent, no);
1640                 }
1641         }
1642 }
1643 static void ssDM_drawVerts(DerivedMesh *dm)
1644 {
1645         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1646         DispListMesh *dlm = ssdm->dlm;
1647         MVert *mvert= dlm->mvert;
1648         int i;
1649
1650         bglBegin(GL_POINTS);
1651         for (i=0; i<dlm->totvert; i++) {
1652                 bglVertex3fv(mvert[i].co);
1653         }
1654         bglEnd();
1655 }
1656 static void ssDM_drawUVEdges(DerivedMesh *dm)
1657 {
1658         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1659         DispListMesh *dlm = ssdm->dlm;
1660         int i;
1661
1662         if (dlm->tface) {
1663                 glBegin(GL_LINES);
1664                 for (i=0; i<dlm->totface; i++) {
1665                         TFace *tf = &dlm->tface[i];
1666
1667                         if (!(tf->flag&TF_HIDE)) {
1668                                 glVertex2fv(tf->uv[0]);
1669                                 glVertex2fv(tf->uv[1]);
1670
1671                                 glVertex2fv(tf->uv[1]);
1672                                 glVertex2fv(tf->uv[2]);
1673
1674                                 if (!dlm->mface[i].v4) {
1675                                         glVertex2fv(tf->uv[2]);
1676                                         glVertex2fv(tf->uv[0]);
1677                                 } else {
1678                                         glVertex2fv(tf->uv[2]);
1679                                         glVertex2fv(tf->uv[3]);
1680
1681                                         glVertex2fv(tf->uv[3]);
1682                                         glVertex2fv(tf->uv[0]);
1683                                 }
1684                         }
1685                 }
1686                 glEnd();
1687         }
1688 }
1689 static void ssDM_drawLooseEdges(DerivedMesh *dm) 
1690 {
1691         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1692         DispListMesh *dlm = ssdm->dlm;
1693         MVert *mvert = dlm->mvert;
1694         MEdge *medge= dlm->medge;
1695         int i;
1696
1697         glBegin(GL_LINES);
1698         for (i=0; i<dlm->totedge; i++, medge++) {
1699                 if (medge->flag&ME_LOOSEEDGE) {
1700                         glVertex3fv(mvert[medge->v1].co); 
1701                         glVertex3fv(mvert[medge->v2].co);
1702                 }
1703         }
1704         glEnd();
1705 }
1706 static void ssDM_drawEdges(DerivedMesh *dm, int drawLooseEdges) 
1707 {
1708         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1709         DispListMesh *dlm = ssdm->dlm;
1710         MVert *mvert= dlm->mvert;
1711         MEdge *medge= dlm->medge;
1712         int i;
1713         
1714         glBegin(GL_LINES);
1715         for (i=0; i<dlm->totedge; i++, medge++) {
1716                 if ((medge->flag&ME_EDGEDRAW) && (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) {
1717                         glVertex3fv(mvert[medge->v1].co); 
1718                         glVertex3fv(mvert[medge->v2].co);
1719                 }
1720         }
1721         glEnd();
1722 }
1723 static void ssDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int))
1724 {
1725         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1726         DispListMesh *dlm = ssdm->dlm;
1727         float *nors = dlm->nors;
1728         int glmode=-1, shademodel=-1, matnr=-1, drawCurrentMat=1;
1729         int i;
1730
1731 #define PASSVERT(ind) {                                         \
1732         if (shademodel==GL_SMOOTH)                              \
1733                 glNormal3sv(dlm->mvert[(ind)].no);      \
1734         glVertex3fv(dlm->mvert[(ind)].co);              \
1735 }
1736
1737         glBegin(glmode=GL_QUADS);
1738         for (i=0; i<dlm->totface; i++) {
1739                 MFace *mf= &dlm->mface[i];
1740                 int new_glmode = mf->v4?GL_QUADS:GL_TRIANGLES;
1741                 int new_shademodel = (mf->flag&ME_SMOOTH)?GL_SMOOTH:GL_FLAT;
1742                 int new_matnr = mf->mat_nr+1;
1743                 
1744                 if(new_glmode!=glmode || new_shademodel!=shademodel || new_matnr!=matnr) {
1745                         glEnd();
1746
1747                         drawCurrentMat = setMaterial(matnr=new_matnr);
1748
1749                         glShadeModel(shademodel=new_shademodel);
1750                         glBegin(glmode=new_glmode);
1751                 }
1752                 
1753                 if (drawCurrentMat) {
1754                         if (shademodel==GL_FLAT)
1755                                 glNormal3fv(&nors[i*3]);
1756                                 
1757                         PASSVERT(mf->v1);
1758                         PASSVERT(mf->v2);
1759                         PASSVERT(mf->v3);
1760                         if (mf->v4)
1761                                 PASSVERT(mf->v4);
1762                 }
1763         }
1764         glEnd();
1765         
1766 #undef PASSVERT
1767 }
1768 static void ssDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *vcols1, unsigned char *vcols2)
1769 {
1770         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1771         DispListMesh *dlm = ssdm->dlm;
1772         int i, lmode;
1773         
1774         glShadeModel(GL_SMOOTH);
1775         if (vcols2) {
1776                 glEnable(GL_CULL_FACE);
1777         } else {
1778                 useTwoSided = 0;
1779         }
1780                 
1781 #define PASSVERT(vidx, fidx) {                                  \
1782         unsigned char *col= &colbase[fidx*4];           \
1783         glColor3ub(col[3], col[2], col[1]);                     \
1784         glVertex3fv(dlm->mvert[(vidx)].co);                     \
1785 }
1786
1787         glBegin(lmode= GL_QUADS);
1788         for (i=0; i<dlm->totface; i++) {
1789                 MFace *mf= &dlm->mface[i];
1790                 int nmode= mf->v4?GL_QUADS:GL_TRIANGLES;
1791                 unsigned char *colbase= &vcols1[i*16];
1792                 
1793                 if (nmode!=lmode) {
1794                         glEnd();
1795                         glBegin(lmode= nmode);
1796                 }
1797                 
1798                 PASSVERT(mf->v1, 0);
1799                 PASSVERT(mf->v2, 1);
1800                 PASSVERT(mf->v3, 2);
1801                 if (mf->v4)
1802                         PASSVERT(mf->v4, 3);
1803                 
1804                 if (useTwoSided) {
1805                         unsigned char *colbase= &vcols2[i*16];
1806
1807                         if (mf->v4)
1808                                 PASSVERT(mf->v4, 3);
1809                         PASSVERT(mf->v3, 2);
1810                         PASSVERT(mf->v2, 1);
1811                         PASSVERT(mf->v1, 0);
1812                 }
1813         }
1814         glEnd();
1815
1816         if (vcols2)
1817                 glDisable(GL_CULL_FACE);
1818         
1819 #undef PASSVERT
1820 }
1821
1822 static void ssDM_drawFacesTex_common(DerivedMesh *dm, int (*drawParams)(TFace *tface, int matnr), int (*drawParamsMapped)(void *userData, int index), void *userData) 
1823 {
1824         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1825         DispListMesh *dlm = ssdm->dlm;
1826         MVert *mvert= dlm->mvert;
1827         MFace *mface= dlm->mface;
1828         TFace *tface = dlm->tface;
1829         float *nors = dlm->nors;
1830         int a;
1831         int *index = dm->getFaceDataArray(dm, LAYERTYPE_ORIGINDEX);
1832         
1833         for (a=0; a<dlm->totface; a++, index++) {
1834                 MFace *mf= &mface[a];
1835                 TFace *tf = tface?&tface[a]:NULL;
1836                 int flag = 0;
1837                 unsigned char *cp= NULL;
1838                 
1839                 if (drawParams) {
1840                         flag = drawParams(tf, mf->mat_nr);
1841                 }
1842                 else {
1843                         if(*index != ORIGINDEX_NONE)
1844                                 flag = drawParamsMapped(userData, *index);
1845                 }
1846
1847                 if (flag==0) {
1848                         continue;
1849                 } else if (flag==1) {
1850                         if (tf) {
1851                                 cp= (unsigned char*) tf->col;
1852                         } else if (dlm->mcol) {
1853                                 cp= (unsigned char*) &dlm->mcol[a*4];
1854                         }
1855                 }
1856
1857                 if (!(mf->flag&ME_SMOOTH)) {
1858                         glNormal3fv(&nors[a*3]);
1859                 }
1860
1861                 glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
1862                 if (tf) glTexCoord2fv(tf->uv[0]);
1863                 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
1864                 if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v1].no);
1865                 glVertex3fv((mvert+mf->v1)->co);
1866                         
1867                 if (tf) glTexCoord2fv(tf->uv[1]);
1868                 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
1869                 if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v2].no);
1870                 glVertex3fv((mvert+mf->v2)->co);
1871
1872                 if (tf) glTexCoord2fv(tf->uv[2]);
1873                 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
1874                 if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v3].no);
1875                 glVertex3fv((mvert+mf->v3)->co);
1876
1877                 if(mf->v4) {
1878                         if (tf) glTexCoord2fv(tf->uv[3]);
1879                         if (cp) glColor3ub(cp[15], cp[14], cp[13]);
1880                         if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v4].no);
1881                         glVertex3fv((mvert+mf->v4)->co);
1882                 }
1883                 glEnd();
1884         }
1885 }
1886 static void ssDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tface, int matnr))
1887 {
1888         ssDM_drawFacesTex_common(dm, setDrawParams, NULL, NULL);
1889 }
1890 static void ssDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawParams)(void *userData, int index), void *userData) 
1891 {
1892         ssDM_drawFacesTex_common(dm, NULL, setDrawParams, userData);
1893 }
1894
1895 static void ssDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors) 
1896 {
1897         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1898         DispListMesh *dlm = ssdm->dlm;
1899         MVert *mvert= dlm->mvert;
1900         MFace *mface= dlm->mface;
1901         float *nors = dlm->nors;
1902         int i;
1903         int *index = dm->getFaceDataArray(dm, LAYERTYPE_ORIGINDEX);
1904
1905         for (i=0; i<dlm->totface; i++, index++) {
1906                 MFace *mf = &mface[i];
1907                 int drawSmooth = (mf->flag & ME_SMOOTH);
1908
1909                 if(*index != ORIGINDEX_NONE
1910                    && (!setDrawOptions
1911                        || setDrawOptions(userData, *index, &drawSmooth))) {
1912                         unsigned char *cp = NULL;
1913
1914                         if (useColors) {
1915                                 if (dlm->tface) {
1916                                         cp= (unsigned char*) dlm->tface[i].col;
1917                                 } else if (dlm->mcol) {
1918                                         cp= (unsigned char*) &dlm->mcol[i*4];
1919                                 }
1920                         }
1921
1922                         glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
1923                         glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
1924
1925                         if (!drawSmooth) {
1926                                 glNormal3fv(&nors[i*3]);
1927
1928                                 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
1929                                 glVertex3fv(mvert[mf->v1].co);
1930                                 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
1931                                 glVertex3fv(mvert[mf->v2].co);
1932                                 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
1933                                 glVertex3fv(mvert[mf->v3].co);
1934                                 if(mf->v4) {
1935                                         if (cp) glColor3ub(cp[15], cp[14], cp[13]);
1936                                         glVertex3fv(mvert[mf->v4].co);
1937                                 }
1938                         } else {
1939                                 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
1940                                 glNormal3sv(mvert[mf->v1].no);
1941                                 glVertex3fv(mvert[mf->v1].co);
1942                                 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
1943                                 glNormal3sv(mvert[mf->v2].no);
1944                                 glVertex3fv(mvert[mf->v2].co);
1945                                 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
1946                                 glNormal3sv(mvert[mf->v3].no);
1947                                 glVertex3fv(mvert[mf->v3].co);
1948                                 if(mf->v4) {
1949                                         if (cp) glColor3ub(cp[15], cp[14], cp[13]);
1950                                         glNormal3sv(mvert[mf->v4].no);
1951                                         glVertex3fv(mvert[mf->v4].co);
1952                                 }
1953                         }
1954
1955                         glEnd();
1956                 }
1957         }
1958 }
1959 static void ssDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
1960 {
1961         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1962         int i;
1963
1964         if (ssdm->dlm->totvert) {
1965                 for (i=0; i<ssdm->dlm->totvert; i++) {
1966                         DO_MINMAX(ssdm->dlm->mvert[i].co, min_r, max_r);
1967                 }
1968         } else {
1969                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
1970         }
1971 }
1972
1973 static void ssDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
1974 {
1975         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1976         int i;
1977
1978         for (i=0; i<ssdm->dlm->totvert; i++) {
1979                 cos_r[i][0] = ssdm->dlm->mvert[i].co[0];
1980                 cos_r[i][1] = ssdm->dlm->mvert[i].co[1];
1981                 cos_r[i][2] = ssdm->dlm->mvert[i].co[2];
1982         }
1983 }
1984
1985 static int ssDM_getNumVerts(DerivedMesh *dm)
1986 {
1987         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1988
1989         return ssdm->dlm->totvert;
1990 }
1991
1992 static int ssDM_getNumEdges(DerivedMesh *dm)
1993 {
1994         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1995
1996         return ssdm->dlm->totedge;
1997 }
1998
1999 static int ssDM_getNumFaces(DerivedMesh *dm)
2000 {
2001         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
2002
2003         return ssdm->dlm->totface;
2004 }
2005
2006 void ssDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
2007 {
2008         *vert_r = ((SSDerivedMesh *)dm)->dlm->mvert[index];
2009 }
2010
2011 void ssDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
2012 {
2013         *edge_r = ((SSDerivedMesh *)dm)->dlm->medge[index];
2014 }
2015
2016 void ssDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
2017 {
2018         *face_r = ((SSDerivedMesh *)dm)->dlm->mface[index];
2019 }
2020
2021 void ssDM_getVertArray(DerivedMesh *dm, MVert *vert_r)
2022 {
2023         SSDerivedMesh *ssdm = (SSDerivedMesh *)dm;
2024         memcpy(vert_r, ssdm->dlm->mvert, sizeof(*vert_r) * ssdm->dlm->totvert);
2025 }
2026
2027 void ssDM_getEdgeArray(DerivedMesh *dm, MEdge *edge_r)
2028 {
2029         SSDerivedMesh *ssdm = (SSDerivedMesh *)dm;
2030         memcpy(edge_r, ssdm->dlm->medge, sizeof(*edge_r) * ssdm->dlm->totedge);
2031 }
2032
2033 void ssDM_getFaceArray(DerivedMesh *dm, MFace *face_r)
2034 {
2035         SSDerivedMesh *ssdm = (SSDerivedMesh *)dm;
2036         memcpy(face_r, ssdm->dlm->mface, sizeof(*face_r) * ssdm->dlm->totface);
2037 }
2038
2039 static DispListMesh *ssDM_convertToDispListMesh(DerivedMesh *dm, int allowShared)
2040 {
2041         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
2042
2043         if (allowShared) {
2044                 return displistmesh_copyShared(ssdm->dlm);
2045         } else {
2046                 return displistmesh_copy(ssdm->dlm);
2047         }
2048 }
2049
2050 static void ssDM_release(DerivedMesh *dm)
2051 {
2052         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
2053
2054         DM_release(dm);
2055
2056         displistmesh_free(ssdm->dlm);
2057
2058         MEM_freeN(dm);
2059 }
2060
2061 DerivedMesh *derivedmesh_from_displistmesh(DispListMesh *dlm, float (*vertexCos)[3])
2062 {
2063         SSDerivedMesh *ssdm = MEM_callocN(sizeof(*ssdm), "ssdm");
2064
2065         DM_init(&ssdm->dm, dlm->totvert, dlm->totedge, dlm->totface);
2066
2067         ssdm->dm.getMinMax = ssDM_getMinMax;
2068
2069         ssdm->dm.getNumVerts = ssDM_getNumVerts;
2070         ssdm->dm.getNumEdges = ssDM_getNumEdges;
2071         ssdm->dm.getNumFaces = ssDM_getNumFaces;
2072
2073         ssdm->dm.getVert = ssDM_getVert;
2074         ssdm->dm.getEdge = ssDM_getEdge;
2075         ssdm->dm.getFace = ssDM_getFace;
2076         ssdm->dm.getVertArray = ssDM_getVertArray;
2077         ssdm->dm.getEdgeArray = ssDM_getEdgeArray;
2078         ssdm->dm.getFaceArray = ssDM_getFaceArray;
2079
2080         ssdm->dm.convertToDispListMesh = ssDM_convertToDispListMesh;
2081
2082         ssdm->dm.getVertCos = ssDM_getVertCos;
2083
2084         ssdm->dm.drawVerts = ssDM_drawVerts;
2085
2086         ssdm->dm.drawUVEdges = ssDM_drawUVEdges;
2087         ssdm->dm.drawEdges = ssDM_drawEdges;
2088         ssdm->dm.drawLooseEdges = ssDM_drawLooseEdges;
2089         
2090         ssdm->dm.drawFacesSolid = ssDM_drawFacesSolid;
2091         ssdm->dm.drawFacesColored = ssDM_drawFacesColored;
2092         ssdm->dm.drawFacesTex = ssDM_drawFacesTex;
2093         ssdm->dm.drawMappedFaces = ssDM_drawMappedFaces;
2094         ssdm->dm.drawMappedFacesTex = ssDM_drawMappedFacesTex;
2095
2096                 /* EM functions */
2097         
2098         ssdm->dm.foreachMappedVert = ssDM_foreachMappedVert;
2099         ssdm->dm.foreachMappedEdge = ssDM_foreachMappedEdge;
2100         ssdm->dm.foreachMappedFaceCenter = ssDM_foreachMappedFaceCenter;
2101         
2102         ssdm->dm.drawMappedEdges = ssDM_drawMappedEdges;
2103         ssdm->dm.drawMappedEdgesInterp = NULL; // no way to implement this one
2104         
2105         ssdm->dm.release = ssDM_release;
2106         
2107         ssdm->dlm = dlm;
2108
2109         if (vertexCos) {
2110                 int i;
2111
2112                 for (i=0; i<dlm->totvert; i++) {
2113                         VECCOPY(dlm->mvert[i].co, vertexCos[i]);
2114                 }
2115
2116                 if (dlm->nors && !dlm->dontFreeNors) {
2117                         MEM_freeN(dlm->nors);
2118                         dlm->nors = 0;
2119                 }
2120
2121                 mesh_calc_normals(dlm->mvert, dlm->totvert, dlm->mface, dlm->totface, &dlm->nors);
2122         }
2123
2124         return (DerivedMesh*) ssdm;
2125 }
2126
2127 #ifdef WITH_VERSE
2128
2129 /* verse derived mesh */
2130 typedef struct {
2131         struct DerivedMesh dm;
2132         struct VNode *vnode;
2133         struct VLayer *vertex_layer;
2134         struct VLayer *polygon_layer;
2135         float (*verts)[3];
2136 } VDerivedMesh;
2137
2138 /* this function set up border points of verse mesh bounding box */
2139 static void vDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
2140 {
2141         VDerivedMesh *vdm = (VDerivedMesh*)dm;
2142         struct VerseVert *vvert;
2143
2144         if(!vdm->vertex_layer) return;
2145
2146         vvert = (VerseVert*)vdm->vertex_layer->dl.lb.first;
2147
2148         if(vdm->vertex_layer->dl.da.count > 0) {
2149                 while(vvert) {
2150                         DO_MINMAX(vdm->verts ? vvert->cos : vvert->co, min_r, max_r);
2151                         vvert = vvert->next;
2152                 }
2153         }
2154         else {
2155                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
2156         }
2157 }
2158
2159 /* this function return number of vertexes in vertex layer */
2160 static int vDM_getNumVerts(DerivedMesh *dm)
2161 {
2162         VDerivedMesh *vdm = (VDerivedMesh*)dm;
2163
2164         if(!vdm->vertex_layer) return 0;
2165         else return vdm->vertex_layer->dl.da.count;
2166 }
2167
2168 /* this function return number of 'fake' edges */
2169 static int vDM_getNumEdges(DerivedMesh *dm)
2170 {
2171         return 0;
2172 }
2173
2174 /* this function returns number of polygons in polygon layer */
2175 static int vDM_getNumFaces(DerivedMesh *dm)
2176 {
2177         VDerivedMesh *vdm = (VDerivedMesh*)dm;
2178
2179         if(!vdm->polygon_layer) return 0;
2180         else return vdm->polygon_layer->dl.da.count;
2181 }
2182
2183 /* this function doesn't return vertex with index of access array,
2184  * but it return 'indexth' vertex of dynamic list */
2185 void vDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
2186 {
2187         VerseVert *vvert = ((VDerivedMesh*)dm)->vertex_layer->dl.lb.first;
2188         int i;
2189
2190         for(i=0 ; i<index; i++) vvert = vvert->next;
2191
2192         if(vvert) {
2193                 VECCOPY(vert_r->co, vvert->co);
2194
2195                 vert_r->no[0] = vvert->no[0] * 32767.0;
2196                 vert_r->no[1] = vvert->no[1] * 32767.0;
2197                 vert_r->no[2] = vvert->no[2] * 32767.0;
2198
2199                 /* TODO what to do with vert_r->flag and vert_r->mat_nr? */
2200                 vert_r->mat_nr = 0;
2201                 vert_r->flag = 0;
2202         }
2203 }
2204
2205 /* dummy function, because verse mesh doesn't store edges */
2206 void vDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
2207 {
2208         edge_r->flag = 0;
2209         edge_r->crease = 0;
2210         edge_r->v1 = 0;
2211         edge_r->v2 = 0;
2212 }
2213
2214 /* this function doesn't return face with index of access array,
2215  * but it returns 'indexth' vertex of dynamic list */
2216 void vDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
2217 {
2218         struct VerseFace *vface = ((VDerivedMesh*)dm)->polygon_layer->dl.lb.first;
2219         struct VerseVert *vvert = ((VDerivedMesh*)dm)->vertex_layer->dl.lb.first;
2220         struct VerseVert *vvert0, *vvert1, *vvert2, *vvert3;
2221         int i;
2222
2223         for(i = 0; i < index; ++i) vface = vface->next;
2224
2225         face_r->mat_nr = 0;
2226         face_r->flag = 0;
2227
2228         /* goddamn, we have to search all verts to find indices */
2229         vvert0 = vface->vvert0;
2230         vvert1 = vface->vvert1;
2231         vvert2 = vface->vvert2;
2232         vvert3 = vface->vvert3;
2233         if(!vvert3) face_r->v4 = 0;
2234
2235         for(i = 0; vvert0 || vvert1 || vvert2 || vvert3; i++, vvert = vvert->next) {
2236                 if(vvert == vvert0) {
2237                         face_r->v1 = i;
2238                         vvert0 = NULL;
2239                 }
2240                 if(vvert == vvert1) {
2241                         face_r->v2 = i;
2242                         vvert1 = NULL;
2243                 }
2244                 if(vvert == vvert2) {
2245                         face_r->v3 = i;
2246                         vvert2 = NULL;
2247                 }
2248                 if(vvert == vvert3) {
2249                         face_r->v4 = i;
2250                         vvert3 = NULL;
2251                 }
2252         }
2253
2254         test_index_face(face_r, NULL, NULL, vface->vvert3?4:3);
2255 }
2256
2257 /* fill array of mvert */
2258 void vDM_getVertArray(DerivedMesh *dm, MVert *vert_r)
2259 {
2260         VerseVert *vvert = ((VDerivedMesh *)dm)->vertex_layer->dl.lb.first;
2261
2262         for( ; vvert; vvert = vvert->next, ++vert_r) {
2263                 VECCOPY(vert_r->co, vvert->co);
2264
2265                 vert_r->no[0] = vvert->no[0] * 32767.0;
2266                 vert_r->no[1] = vvert->no[1] * 32767.0;
2267                 vert_r->no[2] = vvert->no[2] * 32767.0;
2268
2269                 vert_r->mat_nr = 0;
2270                 vert_r->flag = 0;
2271         }
2272 }
2273
2274 /* dummy function, edges arent supported in verse mesh */
2275 void vDM_getEdgeArray(DerivedMesh *dm, MEdge *edge_r)
2276 {
2277 }
2278
2279 /* fill array of mfaces */
2280 void vDM_getFaceArray(DerivedMesh *dm, MFace *face_r)
2281 {
2282         VerseFace *vface = ((VDerivedMesh*)dm)->polygon_layer->dl.lb.first;
2283         VerseVert *vvert = ((VDerivedMesh*)dm)->vertex_layer->dl.lb.first;
2284         int i;
2285
2286         /* store vert indices in the prev pointer (kind of hacky) */
2287         for(i = 0; vvert; vvert = vvert->next, ++i)
2288                 vvert->tmp.index = i;
2289
2290         for( ; vface; vface = vface->next, ++face_r) {
2291                 face_r->mat_nr = 0;
2292                 face_r->flag = 0;
2293
2294                 face_r->v1 = vface->vvert0->tmp.index;
2295                 face_r->v2 = vface->vvert1->tmp.index;
2296                 face_r->v3 = vface->vvert2->tmp.index;
2297                 if(vface->vvert3) face_r->v4 = vface->vvert3->tmp.index;
2298                 else face_r->v4 = 0;
2299
2300                 test_index_face(face_r, NULL, NULL, vface->vvert3?4:3);
2301         }
2302 }
2303
2304 /* create diplist mesh from verse mesh */
2305 static DispListMesh* vDM_convertToDispListMesh(DerivedMesh *dm, int allowShared)
2306 {
2307         VDerivedMesh *vdm = (VDerivedMesh*)dm;
2308         DispListMesh *dlm = MEM_callocN(sizeof(*dlm), "dlm");
2309         struct VerseVert *vvert;
2310         struct VerseFace *vface;
2311         struct MVert *mvert=NULL;
2312         struct MFace *mface=NULL;
2313         float *norms;
2314         unsigned int i;
2315         EdgeHash *edges;
2316
2317         if(!vdm->vertex_layer || !vdm->polygon_layer) {
2318                 dlm->totvert = 0;
2319                 dlm->totedge = 0;
2320                 dlm->totface = 0;
2321                 dlm->dontFreeVerts = dlm->dontFreeOther = dlm->dontFreeNors = 0;
2322
2323                 return dlm;
2324         };
2325         
2326         /* number of vertexes, edges and faces */
2327         dlm->totvert = vdm->vertex_layer->dl.da.count;
2328         dlm->totface = vdm->polygon_layer->dl.da.count;
2329
2330         /* create dynamic array of mverts */
2331         mvert = (MVert*)MEM_mallocN(sizeof(MVert)*dlm->totvert, "dlm verts");
2332         dlm->mvert = mvert;
2333         vvert = (VerseVert*)vdm->vertex_layer->dl.lb.first;
2334         i = 0;
2335         while(vvert) {
2336                 VECCOPY(mvert->co, vdm->verts ? vvert->cos : vvert->co);
2337                 VECCOPY(mvert->no, vvert->no);
2338                 mvert->mat_nr = 0;
2339                 mvert->flag = 0;
2340
2341                 vvert->tmp.index = i++;
2342                 mvert++;
2343                 vvert = vvert->next;
2344         }
2345
2346         edges = BLI_edgehash_new();
2347
2348         /* create dynamic array of faces */
2349         mface = (MFace*)MEM_mallocN(sizeof(MFace)*dlm->totface, "dlm faces");
2350         dlm->mface = mface;
2351         vface = (VerseFace*)vdm->polygon_layer->dl.lb.first;
2352         i = 0;
2353         while(vface) {
2354                 mface->v1 = vface->vvert0->tmp.index;
2355                 mface->v2 = vface->vvert1->tmp.index;
2356                 mface->v3 = vface->vvert2->tmp.index;
2357                 if(!BLI_edgehash_haskey(edges, mface->v1, mface->v2))
2358                         BLI_edgehash_insert(edges, mface->v1, mface->v2, NULL);
2359                 if(!BLI_edgehash_haskey(edges, mface->v2, mface->v3))
2360                         BLI_edgehash_insert(edges, mface->v2, mface->v3, NULL);
2361                 if(vface->vvert3) {
2362                         mface->v4 = vface->vvert3->tmp.index;
2363                         if(!BLI_edgehash_haskey(edges, mface->v3, mface->v4))
2364                                 BLI_edgehash_insert(edges, mface->v3, mface->v4, NULL);
2365                         if(!BLI_edgehash_haskey(edges, mface->v4, mface->v1))
2366                                 BLI_edgehash_insert(edges, mface->v4, mface->v1, NULL);
2367                 } else {
2368                         mface->v4 = 0;
2369                         if(!BLI_edgehash_haskey(edges, mface->v3, mface->v1))
2370                                 BLI_edgehash_insert(edges, mface->v3, mface->v1, NULL);
2371                 }
2372
2373                 mface->pad = 0;
2374                 mface->mat_nr = 0;
2375                 mface->flag = 0;
2376                 mface->edcode = 0;
2377
2378                 test_index_face(mface, NULL, NULL, vface->vvert3?4:3);
2379
2380                 mface++;
2381                 vface = vface->next;
2382         }
2383
2384         dlm->totedge = BLI_edgehash_size(edges);
2385
2386         if(dlm->totedge) {
2387                 EdgeHashIterator *i;
2388                 MEdge *medge = dlm->medge = (MEdge *)MEM_mallocN(sizeof(MEdge)*dlm->totedge, "mesh_from_verse edge");
2389
2390                 for(i = BLI_edgehashIterator_new(edges); !BLI_edgehashIterator_isDone(i); BLI_edgehashIterator_step(i), ++medge) {
2391                         BLI_edgehashIterator_getKey(i, (int*)&medge->v1, (int*)&medge->v2);
2392                         medge->crease = medge->pad = medge->flag = 0;
2393                 }
2394                 BLI_edgehashIterator_free(i);
2395         }
2396
2397         BLI_edgehash_free(edges, NULL);
2398
2399         /* textures and verex colors aren't supported yet */
2400         dlm->tface = NULL;
2401         dlm->mcol = NULL;
2402
2403         /* faces normals */
2404         norms = (float*)MEM_mallocN(sizeof(float)*3*dlm->totface, "dlm norms");
2405         dlm->nors = norms;
2406
2407         vface = (VerseFace*)vdm->polygon_layer->dl.lb.first;
2408         while(vface){
2409                 VECCOPY(norms, vface->no);
2410                 norms += 3;
2411                 vface = vface->next;
2412         }
2413
2414         /* free everything, nothing is shared */
2415         dlm->dontFreeVerts = dlm->dontFreeOther = dlm->dontFreeNors = 0;
2416
2417         return dlm;
2418 }
2419
2420 /* return coordination of vertex with index ... I suppose, that it will
2421  * be very hard to do, becuase there can be holes in access array */
2422 static void vDM_getVertCo(DerivedMesh *dm, int index, float co_r[3])
2423 {
2424         VDerivedMesh *vdm = (VDerivedMesh*)dm;
2425         struct VerseVert *vvert = NULL;
2426
2427         if(!vdm->vertex_layer) return;
2428
2429         vvert = BLI_dlist_find_link(&(vdm->vertex_layer->dl), index);
2430         if(vvert) {
2431                 VECCOPY(co_r, vdm->verts ? vvert->cos : vvert->co);
2432         }
2433         else {
2434                 co_r[0] = co_r[1] = co_r[2] = 0.0;
2435         }
2436 }
2437
2438 /* return array of vertex coordiantions */
2439 static void vDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
2440 {
2441         VDerivedMesh *vdm = (VDerivedMesh*)dm;
2442         struct VerseVert *vvert;
2443         int i = 0;
2444
2445         if(!vdm->vertex_layer) return;
2446
2447         vvert = vdm->vertex_layer->dl.lb.first;
2448         while(vvert) {
2449                 VECCOPY(cos_r[i], vdm->verts ? vvert->cos : vvert->co);
2450                 i++;
2451                 vvert = vvert->next;
2452         }
2453 }
2454
2455 /* return normal of vertex with index ... again, it will be hard to
2456  * implemente, because access array */
2457 static void vDM_getVertNo(DerivedMesh *dm, int index, float no_r[3])
2458 {
2459         VDerivedMesh *vdm = (VDerivedMesh*)dm;
2460         struct VerseVert *vvert = NULL;
2461
2462         if(!vdm->vertex_layer) return;
2463
2464         vvert = BLI_dlist_find_link(&(vdm->vertex_layer->dl), index);
2465         if(vvert) {
2466                 VECCOPY(no_r, vvert->no);
2467         }
2468         else {
2469                 no_r[0] = no_r[1] = no_r[2] = 0.0;
2470         }
2471 }
2472
2473 /* draw all VerseVertexes */
2474 static void vDM_drawVerts(DerivedMesh *dm)
2475 {
2476         VDerivedMesh *vdm = (VDerivedMesh*)dm;
2477         struct VerseVert *vvert;
2478
2479         if(!vdm->vertex_layer) return;
2480
2481         vvert = vdm->vertex_layer->dl.lb.first;
2482
2483         bglBegin(GL_POINTS);
2484         while(vvert) {
2485                 bglVertex3fv(vdm->verts ? vvert->cos : vvert->co);
2486                 vvert = vvert->next;
2487         }
2488         bglEnd();
2489 }
2490
2491 /* draw all edges of VerseFaces ... it isn't optimal, because verse
2492  * specification doesn't support edges :-( ... bother eskil ;-)
2493  * ... some edges (most of edges) are drawn twice */
2494 static void vDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
2495 {
2496         VDerivedMesh *vdm = (VDerivedMesh*)dm;
2497         struct VerseFace *vface;
2498
2499         if(!vdm->polygon_layer) return;
2500
2501         vface = vdm->polygon_layer->dl.lb.first;
2502
2503         while(vface) {
2504                 glBegin(GL_LINE_LOOP);
2505                 glVertex3fv(vdm->verts ? vface->vvert0->cos : vface->vvert0->co);
2506                 glVertex3fv(vdm->verts ? vface->vvert1->cos : vface->vvert1->co);
2507                 glVertex3fv(vdm->verts ? vface->vvert2->cos : vface->vvert2->co);
2508                 if(vface->vvert3) glVertex3fv(vdm->verts ? vface->vvert3->cos : vface->vvert3->co);
2509                 glEnd();
2510
2511                 vface = vface->next;
2512         }
2513 }
2514
2515 /* verse spec doesn't support edges ... loose edges can't exist */
2516 void vDM_drawLooseEdges(DerivedMesh *dm)
2517 {
2518 }
2519
2520 /* draw uv edges, not supported yet */
2521 static void vDM_drawUVEdges(DerivedMesh *dm)
2522 {
2523 }
2524
2525 /* draw all VerseFaces */
2526 static void vDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int))
2527 {
2528         VDerivedMesh *vdm = (VDerivedMesh*)dm;
2529         struct VerseFace *vface;
2530
2531         if(!vdm->polygon_layer) return;
2532
2533         vface = vdm->polygon_layer->dl.lb.first;
2534
2535         while(vface) {
2536 /*              if((vface->smooth) && (vface->smooth->value)){
2537                         glShadeModel(GL_SMOOTH);
2538                         glBegin(vface->vvert3?GL_QUADS:GL_TRIANGLES);
2539                         glNormal3fv(vface->vvert0->no);
2540                         glVertex3fv(vdm->verts ? vface->vvert0->cos : vface->vvert0->co);
2541                         glNormal3fv(vface->vvert1->no);
2542                         glVertex3fv(vdm->verts ? vface->vvert1->cos : vface->vvert1->co);
2543                         glNormal3fv(vface->vvert2->no);
2544                         glVertex3fv(vdm->verts ? vface->vvert2->cos : vface->vvert2->co);
2545                         if(vface->vvert3){
2546                                 glNormal3fv(vface->vvert3->no);
2547                                 glVertex3fv(vdm->verts ? vface->vvert3->cos : vface->vvert3->co);
2548                         }
2549                         glEnd();
2550                 }
2551                 else { */
2552                         glShadeModel(GL_FLAT);
2553                         glBegin(vface->vvert3?GL_QUADS:GL_TRIANGLES);
2554                         glNormal3fv(vface->no);
2555                         glVertex3fv(vdm->verts ? vface->vvert0->cos : vface->vvert0->co);
2556                         glVertex3fv(vdm->verts ? vface->vvert1->cos : vface->vvert1->co);
2557                         glVertex3fv(vdm->verts ? vface->vvert2->cos : vface->vvert2->co);
2558                         if(vface->vvert3)
2559                                 glVertex3fv(vdm->verts ? vface->vvert3->cos : vface->vvert3->co);
2560                         glEnd();
2561 /*              } */
2562
2563                 vface = vface->next;
2564         }
2565         glShadeModel(GL_FLAT);
2566 }
2567
2568 /* thsi function should draw mesh with mapped texture, but it isn't supported yet */
2569 static void vDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(struct TFace *tface, int matnr))
2570 {
2571         VDerivedMesh *vdm = (VDerivedMesh*)dm;
2572         struct VerseFace *vface;
2573
2574         if(!vdm->polygon_layer) return;
2575
2576         vface = vdm->polygon_layer->dl.lb.first;
2577
2578         while(vface) {
2579                 glBegin(vface->vvert3?GL_QUADS:GL_TRIANGLES);
2580                 glVertex3fv(vdm->verts ? vface->vvert0->cos : vface->vvert0->co);
2581                 glVertex3fv(vdm->verts ? vface->vvert1->cos : vface->vvert1->co);
2582                 glVertex3fv(vdm->verts ? vface->vvert2->cos : vface->vvert2->co);
2583                 if(vface->vvert3)
2584                         glVertex3fv(vdm->verts ? vface->vvert3->cos : vface->vvert3->co);
2585                 glEnd();
2586
2587                 vface = vface->next;
2588         }
2589 }
2590
2591 /* this function should draw mesh with colored faces (weight paint, vertex
2592  * colors, etc.), but it isn't supported yet */
2593 static void vDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *col1, unsigned char *col2)
2594 {
2595         VDerivedMesh *vdm = (VDerivedMesh*)dm;
2596         struct VerseFace *vface;
2597
2598         if(!vdm->polygon_layer) return;
2599
2600         vface = vdm->polygon_layer->dl.lb.first;
2601
2602         while(vface) {
2603                 glBegin(vface->vvert3?GL_QUADS:GL_TRIANGLES);
2604                 glVertex3fv(vdm->verts ? vface->vvert0->cos : vface->vvert0->co);
2605                 glVertex3fv(vdm->verts ? vface->vvert1->cos : vface->vvert1->co);
2606                 glVertex3fv(vdm->verts ? vface->vvert2->cos : vface->vvert2->co);
2607                 if(vface->vvert3)
2608                         glVertex3fv(vdm->verts ? vface->vvert3->cos : vface->vvert3->co);
2609                 glEnd();
2610
2611                 vface = vface->next;
2612         }
2613 }
2614
2615 /**/
2616 static void vDM_foreachMappedVert(
2617                 DerivedMesh *dm,
2618                 void (*func)(void *userData, int index, float *co, float *no_f, short *no_s),
2619                 void *userData)
2620 {
2621 }
2622
2623 /**/
2624 static void vDM_foreachMappedEdge(
2625                 DerivedMesh *dm,
2626                 void (*func)(void *userData, int index, float *v0co, float *v1co),
2627                 void *userData)
2628 {
2629 }
2630
2631 /**/
2632 static void vDM_foreachMappedFaceCenter(
2633                 DerivedMesh *dm,
2634                 void (*func)(void *userData, int index, float *cent, float *no),
2635                 void *userData)
2636 {
2637 }
2638
2639 /**/
2640 static void vDM_drawMappedFacesTex(
2641                 DerivedMesh *dm,
2642                 int (*setDrawParams)(void *userData, int index),
2643                 void *userData)
2644 {
2645 }
2646
2647 /**/
2648 static void vDM_drawMappedFaces(
2649                 DerivedMesh *dm,
2650                 int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r),
2651                 void *userData,
2652                 int useColors)
2653 {
2654 }
2655
2656 /**/
2657 static void vDM_drawMappedEdges(
2658                 DerivedMesh *dm,
2659                 int (*setDrawOptions)(void *userData, int index),
2660                 void *userData)
2661 {
2662 }
2663
2664 /**/
2665 static void vDM_drawMappedEdgesInterp(
2666                 DerivedMesh *dm, 
2667                 int (*setDrawOptions)(void *userData, int index), 
2668                 void (*setDrawInterpOptions)(void *userData, int index, float t),
2669                 void *userData)
2670 {
2671 }
2672
2673 /* free all DerivedMesh data */
2674 static void vDM_release(DerivedMesh *dm)
2675 {
2676         VDerivedMesh *vdm = (VDerivedMesh*)dm;
2677
2678         DM_release(dm);
2679
2680         if(vdm->verts) MEM_freeN(vdm->verts);
2681         MEM_freeN(vdm);
2682 }
2683
2684 /* create derived mesh from verse mesh ... it is used in object mode, when some other client can
2685  * change shared data and want to see this changes in real time too */
2686 DerivedMesh *derivedmesh_from_versemesh(VNode *vnode, float (*vertexCos)[3])
2687 {
2688         VDerivedMesh *vdm = MEM_callocN(sizeof(*vdm), "vdm");
2689         struct VerseVert *vvert;
2690
2691         vdm->vnode = vnode;
2692         vdm->vertex_layer = find_verse_layer_type((VGeomData*)vnode->data, VERTEX_LAYER);
2693         vdm->polygon_layer = find_verse_layer_type((VGeomData*)vnode->data, POLYGON_LAYER);
2694
2695         if(vdm->vertex_layer && vdm->polygon_layer)
2696                 DM_init(&vdm->dm, vdm->vertex_layer->dl.da.count, 0, vdm->polygon_layer->dl.da.count);
2697         else
2698                 DM_init(&vdm->dm, 0, 0, 0);
2699         
2700         vdm->dm.getMinMax = vDM_getMinMax;
2701
2702         vdm->dm.getNumVerts = vDM_getNumVerts;
2703         vdm->dm.getNumEdges = vDM_getNumEdges;
2704         vdm->dm.getNumFaces = vDM_getNumFaces;
2705
2706         vdm->dm.getVert = vDM_getVert;
2707         vdm->dm.getEdge = vDM_getEdge;
2708         vdm->dm.getFace = vDM_getFace;
2709         vdm->dm.getVertArray = vDM_getVertArray;
2710         vdm->dm.getEdgeArray = vDM_getEdgeArray;
2711         vdm->dm.getFaceArray = vDM_getFaceArray;
2712         
2713         vdm->dm.foreachMappedVert = vDM_foreachMappedVert;
2714         vdm->dm.foreachMappedEdge = vDM_foreachMappedEdge;
2715         vdm->dm.foreachMappedFaceCenter = vDM_foreachMappedFaceCenter;
2716
2717         vdm->dm.convertToDispListMesh = vDM_convertToDispListMesh;
2718
2719         vdm->dm.getVertCos = vDM_getVertCos;
2720         vdm->dm.getVertCo = vDM_getVertCo;
2721         vdm->dm.getVertNo = vDM_getVertNo;
2722
2723         vdm->dm.drawVerts = vDM_drawVerts;
2724
2725         vdm->dm.drawEdges = vDM_drawEdges;
2726         vdm->dm.drawLooseEdges = vDM_drawLooseEdges;
2727         vdm->dm.drawUVEdges = vDM_drawUVEdges;
2728
2729         vdm->dm.drawFacesSolid = vDM_drawFacesSolid;
2730         vdm->dm.drawFacesTex = vDM_drawFacesTex;
2731         vdm->dm.drawFacesColored = vDM_drawFacesColored;
2732
2733         vdm->dm.drawMappedFacesTex = vDM_drawMappedFacesTex;
2734         vdm->dm.drawMappedFaces = vDM_drawMappedFaces;
2735         vdm->dm.drawMappedEdges = vDM_drawMappedEdges;
2736         vdm->dm.drawMappedEdgesInterp = vDM_drawMappedEdgesInterp;
2737
2738         vdm->dm.release = vDM_release;
2739
2740         if(vdm->vertex_layer) {
2741                 if(vertexCos) {
2742                         int i;
2743
2744                         vdm->verts = MEM_mallocN(sizeof(float)*3*vdm->vertex_layer->dl.da.count, "verse mod vertexes");
2745                         vvert = vdm->vertex_layer->dl.lb.first;
2746
2747                         for(i=0; i<vdm->vertex_layer->dl.da.count && vvert; i++, vvert = vvert->next) {
2748                                 VECCOPY(vdm->verts[i], vertexCos[i]);
2749                                 vvert->cos = vdm->verts[i];
2750                         }
2751                 }
2752                 else {
2753                         vdm->verts = NULL;
2754                         vvert = vdm->vertex_layer->dl.lb.first;
2755
2756                         while(vvert) {
2757                                 vvert->cos = NULL;
2758                                 vvert = vvert->next;
2759                         }
2760                 }
2761         }
2762
2763         return (DerivedMesh*) vdm;
2764 }
2765
2766 #endif
2767
2768 /***/
2769
2770 DerivedMesh *mesh_create_derived_for_modifier(Object *ob, ModifierData *md)
2771 {
2772         Mesh *me = ob->data;
2773         ModifierTypeInfo *mti = modifierType_getInfo(md->type);
2774         DerivedMesh *dm;
2775
2776         if (!(md->mode&eModifierMode_Realtime)) return NULL;
2777         if (mti->isDisabled && mti->isDisabled(md)) return NULL;
2778
2779         if (mti->type==eModifierTypeType_OnlyDeform) {
2780                 int numVerts;
2781                 float (*deformedVerts)[3] = mesh_getVertexCos(me, &numVerts);
2782
2783                 mti->deformVerts(md, ob, NULL, deformedVerts, numVerts);
2784 #ifdef WITH_VERSE
2785                 if(me->vnode) dm = derivedmesh_from_versemesh(me->vnode, deformedVerts);
2786                 else dm = getMeshDerivedMesh(me, ob, deformedVerts);
2787 #else
2788                 dm = getMeshDerivedMesh(me, ob, deformedVerts);
2789 #endif
2790
2791                 MEM_freeN(deformedVerts);
2792         } else {
2793                 DerivedMesh *tdm = getMeshDerivedMesh(me, ob, NULL);
2794                 dm = mti->applyModifier(md, ob, tdm, 0, 0);
2795
2796                 if(tdm != dm) tdm->release(tdm);
2797         }
2798
2799         return dm;
2800 }
2801
2802 static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
2803                                 DerivedMesh **deform_r, DerivedMesh **final_r,
2804                                 int useRenderParams, int useDeform,
2805                                 int needMapping)
2806 {
2807         Mesh *me = ob->data;
2808         ModifierData *md = modifiers_getVirtualModifierList(ob);
2809         float (*deformedVerts)[3] = NULL;
2810         DerivedMesh *dm;
2811         int numVerts = me->totvert;
2812         int fluidsimMeshUsed = 0;
2813         int required_mode;
2814
2815         modifiers_clearErrors(ob);
2816
2817         if(deform_r) *deform_r = NULL;
2818         *final_r = NULL;
2819
2820         /* replace original mesh by fluidsim surface mesh for fluidsim
2821          * domain objects
2822          */
2823         if((G.obedit!=ob) && !needMapping) {
2824                 if((ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) &&
2825                    (1) && (!give_parteff(ob)) ) { // doesnt work together with particle systems!
2826                         if(ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN) {
2827                                 loadFluidsimMesh(ob,useRenderParams);
2828                                 fluidsimMeshUsed = 1;
2829                                 /* might have changed... */
2830                                 me = ob->data;
2831                                 numVerts = me->totvert;
2832                         }
2833                 }
2834         }
2835
2836         if(useRenderParams) required_mode = eModifierMode_Render;
2837         else required_mode = eModifierMode_Realtime;
2838
2839         if(useDeform) {
2840                 if(do_ob_key(ob)) /* shape key makes deform verts */
2841                         deformedVerts = mesh_getVertexCos(me, &numVerts);
2842                 
2843                 /* Apply all leading deforming modifiers */
2844                 for(; md; md = md->next) {
2845                         ModifierTypeInfo *mti = modifierType_getInfo(md->type);
2846
2847                         if((md->mode & required_mode) != required_mode) continue;
2848                         if(mti->isDisabled && mti->isDisabled(md)) continue;
2849
2850                         if(mti->type == eModifierTypeType_OnlyDeform) {
2851                                 if(!deformedVerts)
2852                                         deformedVerts = mesh_getVertexCos(me, &numVerts);
2853
2854                                 mti->deformVerts(md, ob, NULL, deformedVerts, numVerts);
2855                         } else {
2856                                 break;
2857                         }
2858                 }
2859
2860                 /* Result of all leading deforming modifiers is cached for
2861                  * places that wish to use the original mesh but with deformed
2862                  * coordinates (vpaint, etc.)
2863                  */
2864                 if (deform_r) {
2865 #ifdef WITH_VERSE
2866                         if(me->vnode) *deform_r = derivedmesh_from_versemesh(me->vnode, deformedVerts);
2867                         else {
2868                                 *deform_r = CDDM_from_mesh(me);
2869                                 if(deformedVerts) {
2870                                         CDDM_apply_vert_coords(*deform_r, deformedVerts);
2871                                         CDDM_calc_normals(*deform_r);
2872                                 }
2873                         }
2874 #else
2875                         *deform_r = CDDM_from_mesh(me);
2876                         if(deformedVerts) {
2877                                 CDDM_apply_vert_coords(*deform_r, deformedVerts);
2878                                 CDDM_calc_normals(*deform_r);
2879                         }
2880 #endif
2881                 }
2882         } else {
2883                 if(!fluidsimMeshUsed) {
2884                         /* default behaviour for meshes */
2885                         deformedVerts = inputVertexCos;
2886                 } else {
2887                         /* the fluid sim mesh might have more vertices than the original 
2888                          * one, so inputVertexCos shouldnt be used
2889                          */
2890                         deformedVerts = mesh_getVertexCos(me, &numVerts);
2891                 }
2892         }
2893
2894
2895         /* Now apply all remaining modifiers. If useDeform is off then skip
2896          * OnlyDeform ones. 
2897          */
2898         dm = NULL;
2899
2900 #ifdef WITH_VERSE
2901         /* hack to make sure modifiers don't try to use mesh data from a verse
2902          * node
2903          */
2904         if(me->vnode) dm = derivedmesh_from_versemesh(me->vnode, deformedVerts);
2905 #endif
2906
2907         for(; md; md = md->next) {
2908                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
2909
2910                 if((md->mode & required_mode) != required_mode) continue;
2911                 if(mti->type == eModifierTypeType_OnlyDeform && !useDeform) continue;
2912                 if((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) {
2913                         modifier_setError(md, "Internal error, modifier requires "
2914                                           "original data (bad stack position).");
2915                         continue;
2916                 }
2917                 if(mti->isDisabled && mti->isDisabled(md)) continue;
2918                 if(needMapping && !modifier_supportsMapping(md)) continue;
2919
2920                 /* How to apply modifier depends on (a) what we already have as
2921                  * a result of previous modifiers (could be a DerivedMesh or just
2922                  * deformed vertices) and (b) what type the modifier is.
2923                  */
2924
2925                 if(mti->type == eModifierTypeType_OnlyDeform) {
2926                         /* No existing verts to deform, need to build them. */
2927                         if(!deformedVerts) {
2928                                 if(dm) {
2929                                         /* Deforming a derived mesh, read the vertex locations
2930                                          * out of the mesh and deform them. Once done with this
2931                                          * run of deformers verts will be written back.
2932                                          */
2933                                         numVerts = dm->getNumVerts(dm);
2934                                         deformedVerts =
2935                                             MEM_mallocN(sizeof(*deformedVerts) * numVerts, "dfmv");
2936                                         dm->getVertCos(dm, deformedVerts);
2937                                 } else {
2938                                         deformedVerts = mesh_getVertexCos(me, &numVerts);
2939                                 }
2940                         }
2941
2942                         mti->deformVerts(md, ob, dm, deformedVerts, numVerts);
2943                 } else {
2944                         DerivedMesh *ndm;
2945
2946                         /* apply vertex coordinates or build a DerivedMesh as necessary */
2947                         if(dm) {
2948                                 if(deformedVerts) {
2949                                         DerivedMesh *tdm = CDDM_copy(dm);
2950                                         dm->release(dm);
2951                                         dm = tdm;
2952
2953                                         CDDM_apply_vert_coords(dm, deformedVerts);
2954                                         CDDM_calc_normals(dm);
2955                                 }
2956                         } else {
2957                                 dm = CDDM_from_mesh(me);
2958
2959                                 if(deformedVerts) {
2960                                         CDDM_apply_vert_coords(dm, deformedVerts);
2961                                         CDDM_calc_normals(dm);
2962                                 }
2963                         }
2964
2965                         ndm = mti->applyModifier(md, ob, dm, useRenderParams,
2966                                                  !inputVertexCos);
2967
2968                         if(ndm) {
2969                                 /* if the modifier returned a new dm, release the old one */
2970                                 if(dm && dm != ndm) dm->release(dm);
2971
2972                                 dm = ndm;
2973
2974                                 if(deformedVerts) {
2975                                         if(deformedVerts != inputVertexCos)
2976                                                 MEM_freeN(deformedVerts);
2977
2978                                         deformedVerts = NULL;
2979                                 }
2980                         } 
2981                 }
2982         }
2983
2984         /* Yay, we are done. If we have a DerivedMesh and deformed vertices
2985          * need to apply these back onto the DerivedMesh. If we have no
2986          * DerivedMesh then we need to build one.
2987          */
2988         if(dm && deformedVerts) {
2989                 *final_r = CDDM_copy(dm);
2990
2991                 dm->release(dm);
2992
2993                 CDDM_apply_vert_coords(*final_r, deformedVerts);
2994                 CDDM_calc_normals(*final_r);
2995         } else if(dm) {
2996                 *final_r = dm;
2997         } else {
2998 #ifdef WITH_VERSE
2999                 if(me->vnode)
3000                         *final_r = derivedmesh_from_versemesh(me->vnode, deformedVerts);
3001                 else {
3002                         *final_r = CDDM_from_mesh(me);
3003                         if(deformedVerts) {
3004                                 CDDM_apply_vert_coords(*final_r, deformedVerts);
3005                                 CDDM_calc_normals(*final_r);
3006                         }
3007                 }
3008 #else
3009                 *final_r = CDDM_from_mesh(me);
3010                 if(deformedVerts) {
3011                         CDDM_apply_vert_coords(*final_r, deformedVerts);
3012                         CDDM_calc_normals(*final_r);
3013                 }
3014 #endif
3015         }
3016
3017         if(deformedVerts && deformedVerts != inputVertexCos)
3018                 MEM_freeN(deformedVerts);
3019
3020         /* restore mesh in any case */
3021         if(fluidsimMeshUsed) ob->data = ob->fluidsimSettings->orgMesh;
3022 }
3023
3024 static float (*editmesh_getVertexCos(EditMesh *em, int *numVerts_r))[3]
3025 {
3026         int i, numVerts = *numVerts_r = BLI_countlist(&em->verts);
3027         float (*cos)[3];
3028         EditVert *eve;
3029
3030         cos = MEM_mallocN(sizeof(*cos)*numVerts, "vertexcos");
3031         for (i=0,eve=em->verts.first; i<numVerts; i++,eve=eve->next) {
3032                 VECCOPY(cos[i], eve->co);
3033         }
3034
3035         return cos;
3036 }
3037
3038 static void editmesh_calc_modifiers(DerivedMesh **cage_r, DerivedMesh **final_r)
3039 {
3040         Object *ob = G.obedit;
3041         EditMesh *em = G.editMesh;
3042         ModifierData *md;
3043         float (*deformedVerts)[3] = NULL;
3044         DerivedMesh *dm;
3045         int i, numVerts = 0, cageIndex = modifiers_getCageIndex(ob, NULL);
3046         int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
3047
3048         modifiers_clearErrors(ob);
3049
3050         if(cage_r && cageIndex == -1) {
3051                 *cage_r = getEditMeshDerivedMesh(em, ob, NULL);
3052         }
3053
3054         dm = NULL;
3055         for(i = 0, md = ob->modifiers.first; md; i++, md = md->next) {
3056                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
3057
3058                 if((md->mode & required_mode) != required_mode) continue;
3059                 if((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) {
3060                         modifier_setError(md, "Internal error, modifier requires"
3061                                           "original data (bad stack position).");
3062                         continue;
3063                 }
3064                 if(mti->isDisabled && mti->isDisabled(md)) continue;
3065                 if(!(mti->flags & eModifierTypeFlag_SupportsEditmode)) continue;
3066
3067                 /* How to apply modifier depends on (a) what we already have as
3068                  * a result of previous modifiers (could be a DerivedMesh or just
3069                  * deformed vertices) and (b) what type the modifier is.
3070                  */
3071
3072                 if(mti->type == eModifierTypeType_OnlyDeform) {
3073                         /* No existing verts to deform, need to build them. */
3074                         if(!deformedVerts) {
3075                                 if(dm) {
3076                                         /* Deforming a derived mesh, read the vertex locations
3077                                          * out of the mesh and deform them. Once done with this
3078                                          * run of deformers verts will be written back.
3079                                          */
3080                                         numVerts = dm->getNumVerts(dm);
3081                                         deformedVerts =
3082                                             MEM_mallocN(sizeof(*deformedVerts) * numVerts, "dfmv");
3083                                         dm->getVertCos(dm, deformedVerts);
3084                                 } else {
3085                                         deformedVerts = editmesh_getVertexCos(em, &numVerts);
3086                                 }
3087                         }
3088
3089                         mti->deformVertsEM(md, ob, em, dm, deformedVerts, numVerts);
3090                 } else {
3091                         DerivedMesh *ndm;
3092
3093                         /* apply vertex coordinates or build a DerivedMesh as necessary */
3094                         if(dm) {
3095                                 if(deformedVerts) {
3096                                         DerivedMesh *tdm = CDDM_copy(dm);
3097                                         if(!(cage_r && dm == *cage_r)) dm->release(dm);
3098                                         dm = tdm;
3099
3100                                         CDDM_apply_vert_coords(dm, deformedVerts);
3101                                         CDDM_calc_normals(dm);
3102                                 } else if(cage_r && dm == *cage_r) {
3103                                         /* dm may be changed by this modifier, so we need to copy it
3104                                          */
3105                                         dm = CDDM_copy(dm);
3106                                 }
3107
3108                         } else {
3109                                 dm = CDDM_from_editmesh(em, ob->data);
3110
3111                                 if(deformedVerts) {
3112                                         CDDM_apply_vert_coords(dm, deformedVerts);
3113                                         CDDM_calc_normals(dm);
3114                                 }
3115                         }
3116
3117                         ndm = mti->applyModifierEM(md, ob, em, dm);
3118
3119                         if (ndm) {
3120                                 if(dm && dm != ndm)
3121                                         dm->release(dm);
3122
3123                                 dm = ndm;
3124
3125                                 if (deformedVerts) {
3126                                         MEM_freeN(deformedVerts);
3127                                         deformedVerts = NULL;
3128                                 }
3129                         }
3130                 }
3131
3132                 if(cage_r && i == cageIndex) {
3133                         if(dm && deformedVerts) {
3134                                 *cage_r = CDDM_copy(dm);
3135                                 CDDM_apply_vert_coords(*cage_r, deformedVerts);
3136                         } else if(dm) {
3137                                 *cage_r = dm;
3138                         } else {
3139                                 *cage_r =
3140                                     getEditMeshDerivedMesh(em, ob,
3141                                         deformedVerts ? MEM_dupallocN(deformedVerts) : NULL);
3142                         }
3143                 }
3144         }
3145
3146         /* Yay, we are done. If we have a DerivedMesh and deformed vertices need
3147          * to apply these back onto the DerivedMesh. If we have no DerivedMesh
3148          * then we need to build one.
3149          */
3150         if(dm && deformedVerts) {
3151                 *final_r = CDDM_copy(dm);
3152
3153                 if(!(cage_r && dm == *cage_r)) dm->release(dm);
3154
3155                 CDDM_apply_vert_coords(*final_r, deformedVerts);
3156                 CDDM_calc_normals(*final_r);
3157
3158                 MEM_freeN(deformedVerts);
3159         } else if (dm) {
3160                 *final_r = dm;
3161         } else {
3162                 *final_r = getEditMeshDerivedMesh(em, ob, deformedVerts);
3163         }
3164 }
3165
3166 /***/
3167
3168
3169         /* Something of a hack, at the moment deal with weightpaint
3170          * by tucking into colors during modifier eval, only in
3171          * wpaint mode. Works ok but need to make sure recalc
3172          * happens on enter/exit wpaint.
3173          */
3174
3175 void weight_to_rgb(float input, float *fr, float *fg, float *fb)
3176 {
3177         float blend;
3178         
3179         blend= ((input/2.0f)+0.5f);
3180         
3181         if (input<=0.25f){      // blue->cyan
3182                 *fr= 0.0f;
3183                 *fg= blend*input*4.0f;
3184                 *fb= blend;
3185         }
3186         else if (input<=0.50f){ // cyan->green
3187                 *fr= 0.0f;
3188                 *fg= blend;
3189                 *fb= blend*(1.0f-((input-0.25f)*4.0f)); 
3190         }
3191         else if (input<=0.75){  // green->yellow
3192                 *fr= blend * ((input-0.50f)*4.0f);
3193                 *fg= blend;
3194                 *fb= 0.0f;
3195         }
3196         else if (input<=1.0){ // yellow->red
3197                 *fr= blend;
3198                 *fg= blend * (1.0f-((input-0.75f)*4.0f)); 
3199                 *fb= 0.0f;
3200         }
3201 }
3202 static void calc_weightpaint_vert_color(Object *ob, int vert, unsigned char *col)
3203 {
3204         Mesh *me = ob->data;
3205         float fr, fg, fb, input = 0.0f;
3206         int i;
3207
3208         if (me->dvert) {
3209                 for (i=0; i<me->dvert[vert].totweight; i++)
3210                         if (me->dvert[vert].dw[i].def_nr==ob->actdef-1)
3211                                 input+=me->dvert[vert].dw[i].weight;