Added custom face data support in edit mode. The code used to do this is
[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         Mesh *me = ob->data;
1463
1464         DM_init(&emdm->dm, BLI_countlist(&em->verts),
1465                          BLI_countlist(&em->edges), BLI_countlist(&em->faces));
1466
1467         emdm->dm.getMinMax = emDM_getMinMax;
1468
1469         emdm->dm.getNumVerts = emDM_getNumVerts;
1470         emdm->dm.getNumEdges = emDM_getNumEdges;
1471         emdm->dm.getNumFaces = emDM_getNumFaces;
1472
1473         emdm->dm.getVert = emDM_getVert;
1474         emdm->dm.getEdge = emDM_getEdge;
1475         emdm->dm.getFace = emDM_getFace;
1476         emdm->dm.getVertArray = emDM_getVertArray;
1477         emdm->dm.getEdgeArray = emDM_getEdgeArray;
1478         emdm->dm.getFaceArray = emDM_getFaceArray;
1479
1480         emdm->dm.foreachMappedVert = emDM_foreachMappedVert;
1481         emdm->dm.foreachMappedEdge = emDM_foreachMappedEdge;
1482         emdm->dm.foreachMappedFaceCenter = emDM_foreachMappedFaceCenter;
1483
1484         emdm->dm.drawEdges = emDM_drawEdges;
1485         emdm->dm.drawMappedEdges = emDM_drawMappedEdges;
1486         emdm->dm.drawMappedEdgesInterp = emDM_drawMappedEdgesInterp;
1487         emdm->dm.drawMappedFaces = emDM_drawMappedFaces;
1488         emdm->dm.drawUVEdges = emDM_drawUVEdges;
1489
1490         emdm->dm.release = emDM_release;
1491         
1492         emdm->em = em;
1493         emdm->vertexCos = vertexCos;
1494
1495         if(me->dvert) {
1496                 EditVert *eve;
1497                 int i;
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                         if(eve->keyindex != -1)
1502                                 DM_set_vert_data(&emdm->dm, i, LAYERTYPE_MDEFORMVERT,
1503                                                  &me->dvert[eve->keyindex]);
1504                 }
1505         }
1506
1507         if(vertexCos) {
1508                 EditVert *eve, *preveve;
1509                 EditFace *efa;
1510                 int totface = BLI_countlist(&em->faces);
1511                 int i;
1512
1513                 for (i=0,eve=em->verts.first; eve; eve= eve->next)
1514                         eve->prev = (EditVert*) i++;
1515
1516                 emdm->vertexNos = MEM_callocN(sizeof(*emdm->vertexNos)*i, "emdm_vno");
1517                 emdm->faceNos = MEM_mallocN(sizeof(*emdm->faceNos)*totface, "emdm_vno");
1518
1519                 for(i=0, efa= em->faces.first; efa; i++, efa=efa->next) {
1520                         float *v1 = vertexCos[(int) efa->v1->prev];
1521                         float *v2 = vertexCos[(int) efa->v2->prev];
1522                         float *v3 = vertexCos[(int) efa->v3->prev];
1523                         float *no = emdm->faceNos[i];
1524                         
1525                         if(efa->v4) {
1526                                 float *v4 = vertexCos[(int) efa->v3->prev];
1527
1528                                 CalcNormFloat4(v1, v2, v3, v4, no);
1529                                 VecAddf(emdm->vertexNos[(int) efa->v4->prev], emdm->vertexNos[(int) efa->v4->prev], no);
1530                         }
1531                         else {
1532                                 CalcNormFloat(v1, v2, v3, no);
1533                         }
1534
1535                         VecAddf(emdm->vertexNos[(int) efa->v1->prev], emdm->vertexNos[(int) efa->v1->prev], no);
1536                         VecAddf(emdm->vertexNos[(int) efa->v2->prev], emdm->vertexNos[(int) efa->v2->prev], no);
1537                         VecAddf(emdm->vertexNos[(int) efa->v3->prev], emdm->vertexNos[(int) efa->v3->prev], no);
1538                 }
1539
1540                 for(i=0, eve= em->verts.first; eve; i++, eve=eve->next) {
1541                         float *no = emdm->vertexNos[i];
1542                         /* following Mesh convention; we use vertex coordinate itself
1543                          * for normal in this case */
1544                         if (Normalise(no)==0.0) {
1545                                 VECCOPY(no, vertexCos[i]);
1546                                 Normalise(no);
1547                         }
1548                 }
1549
1550                 for (preveve=NULL, eve=emdm->em->verts.first; eve; preveve=eve, eve= eve->next)
1551                         eve->prev = preveve;
1552         }
1553
1554         return (DerivedMesh*) emdm;
1555 }
1556
1557 ///
1558
1559 typedef struct {
1560         DerivedMesh dm;
1561
1562         DispListMesh *dlm;
1563 } SSDerivedMesh;
1564
1565 static void ssDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData)
1566 {
1567         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1568         DispListMesh *dlm = ssdm->dlm;
1569         int i;
1570         int *index = dm->getVertDataArray(dm, LAYERTYPE_ORIGINDEX);
1571
1572         for (i=0; i<dlm->totvert; i++, index++) {
1573                 MVert *mv = &dlm->mvert[i];
1574
1575                 if(*index != ORIGINDEX_NONE)
1576                         func(userData, *index, mv->co, NULL, mv->no);
1577         }
1578 }
1579 static void ssDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData)
1580 {
1581         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1582         DispListMesh *dlm = ssdm->dlm;
1583         int i;
1584         int *index = dm->getEdgeDataArray(dm, LAYERTYPE_ORIGINDEX);
1585
1586         for (i=0; i<dlm->totedge; i++, index++) {
1587                 MEdge *med = &dlm->medge[i];
1588
1589                 if(*index != ORIGINDEX_NONE)
1590                         func(userData, *index, dlm->mvert[med->v1].co,
1591                              dlm->mvert[med->v2].co);
1592         }
1593 }
1594 static void ssDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) 
1595 {
1596         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1597         DispListMesh *dlm = ssdm->dlm;
1598         int i;
1599         int *index = dm->getEdgeDataArray(dm, LAYERTYPE_ORIGINDEX);
1600
1601         glBegin(GL_LINES);
1602         for(i=0; i<dlm->totedge; i++, index++) {
1603                 MEdge *med = &dlm->medge[i];
1604
1605                 if(*index != ORIGINDEX_NONE
1606                    && (!setDrawOptions || setDrawOptions(userData, *index))) {
1607                         glVertex3fv(dlm->mvert[med->v1].co);
1608                         glVertex3fv(dlm->mvert[med->v2].co);
1609                 }
1610         }
1611         glEnd();
1612 }
1613
1614 static void ssDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData)
1615 {
1616         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1617         DispListMesh *dlm = ssdm->dlm;
1618         int i;
1619         int *index = dm->getFaceDataArray(dm, LAYERTYPE_ORIGINDEX);
1620
1621         for (i=0; i<dlm->totface; i++, index++) {
1622                 MFace *mf = &dlm->mface[i];
1623
1624                 if(*index != ORIGINDEX_NONE) {
1625                         float cent[3];
1626                         float no[3];
1627
1628                         VECCOPY(cent, dlm->mvert[mf->v1].co);
1629                         VecAddf(cent, cent, dlm->mvert[mf->v2].co);
1630                         VecAddf(cent, cent, dlm->mvert[mf->v3].co);
1631
1632                         if (mf->v4) {
1633                                 CalcNormFloat4(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, dlm->mvert[mf->v4].co, no);
1634                                 VecAddf(cent, cent, dlm->mvert[mf->v4].co);
1635                                 VecMulf(cent, 0.25f);
1636                         } else {
1637                                 CalcNormFloat(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, no);
1638                                 VecMulf(cent, 0.33333333333f);
1639                         }
1640
1641                         func(userData, *index, cent, no);
1642                 }
1643         }
1644 }
1645 static void ssDM_drawVerts(DerivedMesh *dm)
1646 {
1647         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1648         DispListMesh *dlm = ssdm->dlm;
1649         MVert *mvert= dlm->mvert;
1650         int i;
1651
1652         bglBegin(GL_POINTS);
1653         for (i=0; i<dlm->totvert; i++) {
1654                 bglVertex3fv(mvert[i].co);
1655         }
1656         bglEnd();
1657 }
1658 static void ssDM_drawUVEdges(DerivedMesh *dm)
1659 {
1660         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1661         DispListMesh *dlm = ssdm->dlm;
1662         int i;
1663
1664         if (dlm->tface) {
1665                 glBegin(GL_LINES);
1666                 for (i=0; i<dlm->totface; i++) {
1667                         TFace *tf = &dlm->tface[i];
1668
1669                         if (!(tf->flag&TF_HIDE)) {
1670                                 glVertex2fv(tf->uv[0]);
1671                                 glVertex2fv(tf->uv[1]);
1672
1673                                 glVertex2fv(tf->uv[1]);
1674                                 glVertex2fv(tf->uv[2]);
1675
1676                                 if (!dlm->mface[i].v4) {
1677                                         glVertex2fv(tf->uv[2]);
1678                                         glVertex2fv(tf->uv[0]);
1679                                 } else {
1680                                         glVertex2fv(tf->uv[2]);
1681                                         glVertex2fv(tf->uv[3]);
1682
1683                                         glVertex2fv(tf->uv[3]);
1684                                         glVertex2fv(tf->uv[0]);
1685                                 }
1686                         }
1687                 }
1688                 glEnd();
1689         }
1690 }
1691 static void ssDM_drawLooseEdges(DerivedMesh *dm) 
1692 {
1693         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1694         DispListMesh *dlm = ssdm->dlm;
1695         MVert *mvert = dlm->mvert;
1696         MEdge *medge= dlm->medge;
1697         int i;
1698
1699         glBegin(GL_LINES);
1700         for (i=0; i<dlm->totedge; i++, medge++) {
1701                 if (medge->flag&ME_LOOSEEDGE) {
1702                         glVertex3fv(mvert[medge->v1].co); 
1703                         glVertex3fv(mvert[medge->v2].co);
1704                 }
1705         }
1706         glEnd();
1707 }
1708 static void ssDM_drawEdges(DerivedMesh *dm, int drawLooseEdges) 
1709 {
1710         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1711         DispListMesh *dlm = ssdm->dlm;
1712         MVert *mvert= dlm->mvert;
1713         MEdge *medge= dlm->medge;
1714         int i;
1715         
1716         glBegin(GL_LINES);
1717         for (i=0; i<dlm->totedge; i++, medge++) {
1718                 if ((medge->flag&ME_EDGEDRAW) && (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) {
1719                         glVertex3fv(mvert[medge->v1].co); 
1720                         glVertex3fv(mvert[medge->v2].co);
1721                 }
1722         }
1723         glEnd();
1724 }
1725 static void ssDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int))
1726 {
1727         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1728         DispListMesh *dlm = ssdm->dlm;
1729         float *nors = dlm->nors;
1730         int glmode=-1, shademodel=-1, matnr=-1, drawCurrentMat=1;
1731         int i;
1732
1733 #define PASSVERT(ind) {                                         \
1734         if (shademodel==GL_SMOOTH)                              \
1735                 glNormal3sv(dlm->mvert[(ind)].no);      \
1736         glVertex3fv(dlm->mvert[(ind)].co);              \
1737 }
1738
1739         glBegin(glmode=GL_QUADS);
1740         for (i=0; i<dlm->totface; i++) {
1741                 MFace *mf= &dlm->mface[i];
1742                 int new_glmode = mf->v4?GL_QUADS:GL_TRIANGLES;
1743                 int new_shademodel = (mf->flag&ME_SMOOTH)?GL_SMOOTH:GL_FLAT;
1744                 int new_matnr = mf->mat_nr+1;
1745                 
1746                 if(new_glmode!=glmode || new_shademodel!=shademodel || new_matnr!=matnr) {
1747                         glEnd();
1748
1749                         drawCurrentMat = setMaterial(matnr=new_matnr);
1750
1751                         glShadeModel(shademodel=new_shademodel);
1752                         glBegin(glmode=new_glmode);
1753                 }
1754                 
1755                 if (drawCurrentMat) {
1756                         if (shademodel==GL_FLAT)
1757                                 glNormal3fv(&nors[i*3]);
1758                                 
1759                         PASSVERT(mf->v1);
1760                         PASSVERT(mf->v2);
1761                         PASSVERT(mf->v3);
1762                         if (mf->v4)
1763                                 PASSVERT(mf->v4);
1764                 }
1765         }
1766         glEnd();
1767         
1768 #undef PASSVERT
1769 }
1770 static void ssDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *vcols1, unsigned char *vcols2)
1771 {
1772         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1773         DispListMesh *dlm = ssdm->dlm;
1774         int i, lmode;
1775         
1776         glShadeModel(GL_SMOOTH);
1777         if (vcols2) {
1778                 glEnable(GL_CULL_FACE);
1779         } else {
1780                 useTwoSided = 0;
1781         }
1782                 
1783 #define PASSVERT(vidx, fidx) {                                  \
1784         unsigned char *col= &colbase[fidx*4];           \
1785         glColor3ub(col[3], col[2], col[1]);                     \
1786         glVertex3fv(dlm->mvert[(vidx)].co);                     \
1787 }
1788
1789         glBegin(lmode= GL_QUADS);
1790         for (i=0; i<dlm->totface; i++) {
1791                 MFace *mf= &dlm->mface[i];
1792                 int nmode= mf->v4?GL_QUADS:GL_TRIANGLES;
1793                 unsigned char *colbase= &vcols1[i*16];
1794                 
1795                 if (nmode!=lmode) {
1796                         glEnd();
1797                         glBegin(lmode= nmode);
1798                 }
1799                 
1800                 PASSVERT(mf->v1, 0);
1801                 PASSVERT(mf->v2, 1);
1802                 PASSVERT(mf->v3, 2);
1803                 if (mf->v4)
1804                         PASSVERT(mf->v4, 3);
1805                 
1806                 if (useTwoSided) {
1807                         unsigned char *colbase= &vcols2[i*16];
1808
1809                         if (mf->v4)
1810                                 PASSVERT(mf->v4, 3);
1811                         PASSVERT(mf->v3, 2);
1812                         PASSVERT(mf->v2, 1);
1813                         PASSVERT(mf->v1, 0);
1814                 }
1815         }
1816         glEnd();
1817
1818         if (vcols2)
1819                 glDisable(GL_CULL_FACE);
1820         
1821 #undef PASSVERT
1822 }
1823
1824 static void ssDM_drawFacesTex_common(DerivedMesh *dm, int (*drawParams)(TFace *tface, int matnr), int (*drawParamsMapped)(void *userData, int index), void *userData) 
1825 {
1826         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1827         DispListMesh *dlm = ssdm->dlm;
1828         MVert *mvert= dlm->mvert;
1829         MFace *mface= dlm->mface;
1830         TFace *tface = dlm->tface;
1831         float *nors = dlm->nors;
1832         int a;
1833         int *index = dm->getFaceDataArray(dm, LAYERTYPE_ORIGINDEX);
1834         
1835         for (a=0; a<dlm->totface; a++, index++) {
1836                 MFace *mf= &mface[a];
1837                 TFace *tf = tface?&tface[a]:NULL;
1838                 int flag = 0;
1839                 unsigned char *cp= NULL;
1840                 
1841                 if (drawParams) {
1842                         flag = drawParams(tf, mf->mat_nr);
1843                 }
1844                 else {
1845                         if(*index != ORIGINDEX_NONE)
1846                                 flag = drawParamsMapped(userData, *index);
1847                 }
1848
1849                 if (flag==0) {
1850                         continue;
1851                 } else if (flag==1) {
1852                         if (tf) {
1853                                 cp= (unsigned char*) tf->col;
1854                         } else if (dlm->mcol) {
1855                                 cp= (unsigned char*) &dlm->mcol[a*4];
1856                         }
1857                 }
1858
1859                 if (!(mf->flag&ME_SMOOTH)) {
1860                         glNormal3fv(&nors[a*3]);
1861                 }
1862
1863                 glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
1864                 if (tf) glTexCoord2fv(tf->uv[0]);
1865                 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
1866                 if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v1].no);
1867                 glVertex3fv((mvert+mf->v1)->co);
1868                         
1869                 if (tf) glTexCoord2fv(tf->uv[1]);
1870                 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
1871                 if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v2].no);
1872                 glVertex3fv((mvert+mf->v2)->co);
1873
1874                 if (tf) glTexCoord2fv(tf->uv[2]);
1875                 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
1876                 if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v3].no);
1877                 glVertex3fv((mvert+mf->v3)->co);
1878
1879                 if(mf->v4) {
1880                         if (tf) glTexCoord2fv(tf->uv[3]);
1881                         if (cp) glColor3ub(cp[15], cp[14], cp[13]);
1882                         if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v4].no);
1883                         glVertex3fv((mvert+mf->v4)->co);
1884                 }
1885                 glEnd();
1886         }
1887 }
1888 static void ssDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tface, int matnr))
1889 {
1890         ssDM_drawFacesTex_common(dm, setDrawParams, NULL, NULL);
1891 }
1892 static void ssDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawParams)(void *userData, int index), void *userData) 
1893 {
1894         ssDM_drawFacesTex_common(dm, NULL, setDrawParams, userData);
1895 }
1896
1897 static void ssDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors) 
1898 {
1899         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1900         DispListMesh *dlm = ssdm->dlm;
1901         MVert *mvert= dlm->mvert;
1902         MFace *mface= dlm->mface;
1903         float *nors = dlm->nors;
1904         int i;
1905         int *index = dm->getFaceDataArray(dm, LAYERTYPE_ORIGINDEX);
1906
1907         for (i=0; i<dlm->totface; i++, index++) {
1908                 MFace *mf = &mface[i];
1909                 int drawSmooth = (mf->flag & ME_SMOOTH);
1910
1911                 if(*index != ORIGINDEX_NONE
1912                    && (!setDrawOptions
1913                        || setDrawOptions(userData, *index, &drawSmooth))) {
1914                         unsigned char *cp = NULL;
1915
1916                         if (useColors) {
1917                                 if (dlm->tface) {
1918                                         cp= (unsigned char*) dlm->tface[i].col;
1919                                 } else if (dlm->mcol) {
1920                                         cp= (unsigned char*) &dlm->mcol[i*4];
1921                                 }
1922                         }
1923
1924                         glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
1925                         glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
1926
1927                         if (!drawSmooth) {
1928                                 glNormal3fv(&nors[i*3]);
1929
1930                                 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
1931                                 glVertex3fv(mvert[mf->v1].co);
1932                                 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
1933                                 glVertex3fv(mvert[mf->v2].co);
1934                                 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
1935                                 glVertex3fv(mvert[mf->v3].co);
1936                                 if(mf->v4) {
1937                                         if (cp) glColor3ub(cp[15], cp[14], cp[13]);
1938                                         glVertex3fv(mvert[mf->v4].co);
1939                                 }
1940                         } else {
1941                                 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
1942                                 glNormal3sv(mvert[mf->v1].no);
1943                                 glVertex3fv(mvert[mf->v1].co);
1944                                 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
1945                                 glNormal3sv(mvert[mf->v2].no);
1946                                 glVertex3fv(mvert[mf->v2].co);
1947                                 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
1948                                 glNormal3sv(mvert[mf->v3].no);
1949                                 glVertex3fv(mvert[mf->v3].co);
1950                                 if(mf->v4) {
1951                                         if (cp) glColor3ub(cp[15], cp[14], cp[13]);
1952                                         glNormal3sv(mvert[mf->v4].no);
1953                                         glVertex3fv(mvert[mf->v4].co);
1954                                 }
1955                         }
1956
1957                         glEnd();
1958                 }
1959         }
1960 }
1961 static void ssDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
1962 {
1963         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1964         int i;
1965
1966         if (ssdm->dlm->totvert) {
1967                 for (i=0; i<ssdm->dlm->totvert; i++) {
1968                         DO_MINMAX(ssdm->dlm->mvert[i].co, min_r, max_r);
1969                 }
1970         } else {
1971                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
1972         }
1973 }
1974
1975 static void ssDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
1976 {
1977         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1978         int i;
1979
1980         for (i=0; i<ssdm->dlm->totvert; i++) {
1981                 cos_r[i][0] = ssdm->dlm->mvert[i].co[0];
1982                 cos_r[i][1] = ssdm->dlm->mvert[i].co[1];
1983                 cos_r[i][2] = ssdm->dlm->mvert[i].co[2];
1984         }
1985 }
1986
1987 static int ssDM_getNumVerts(DerivedMesh *dm)
1988 {
1989         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1990
1991         return ssdm->dlm->totvert;
1992 }
1993
1994 static int ssDM_getNumEdges(DerivedMesh *dm)
1995 {
1996         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
1997
1998         return ssdm->dlm->totedge;
1999 }
2000
2001 static int ssDM_getNumFaces(DerivedMesh *dm)
2002 {
2003         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
2004
2005         return ssdm->dlm->totface;
2006 }
2007
2008 void ssDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
2009 {
2010         *vert_r = ((SSDerivedMesh *)dm)->dlm->mvert[index];
2011 }
2012
2013 void ssDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
2014 {
2015         *edge_r = ((SSDerivedMesh *)dm)->dlm->medge[index];
2016 }
2017
2018 void ssDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
2019 {
2020         *face_r = ((SSDerivedMesh *)dm)->dlm->mface[index];
2021 }
2022
2023 void ssDM_getVertArray(DerivedMesh *dm, MVert *vert_r)
2024 {
2025         SSDerivedMesh *ssdm = (SSDerivedMesh *)dm;
2026         memcpy(vert_r, ssdm->dlm->mvert, sizeof(*vert_r) * ssdm->dlm->totvert);
2027 }
2028
2029 void ssDM_getEdgeArray(DerivedMesh *dm, MEdge *edge_r)
2030 {
2031         SSDerivedMesh *ssdm = (SSDerivedMesh *)dm;
2032         memcpy(edge_r, ssdm->dlm->medge, sizeof(*edge_r) * ssdm->dlm->totedge);
2033 }
2034
2035 void ssDM_getFaceArray(DerivedMesh *dm, MFace *face_r)
2036 {
2037         SSDerivedMesh *ssdm = (SSDerivedMesh *)dm;
2038         memcpy(face_r, ssdm->dlm->mface, sizeof(*face_r) * ssdm->dlm->totface);
2039 }
2040
2041 static DispListMesh *ssDM_convertToDispListMesh(DerivedMesh *dm, int allowShared)
2042 {
2043         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
2044
2045         if (allowShared) {
2046                 return displistmesh_copyShared(ssdm->dlm);
2047         } else {
2048                 return displistmesh_copy(ssdm->dlm);
2049         }
2050 }
2051
2052 static void ssDM_release(DerivedMesh *dm)
2053 {
2054         SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
2055
2056         DM_release(dm);
2057
2058         displistmesh_free(ssdm->dlm);
2059
2060         MEM_freeN(dm);
2061 }
2062
2063 DerivedMesh *derivedmesh_from_displistmesh(DispListMesh *dlm, float (*vertexCos)[3])
2064 {
2065         SSDerivedMesh *ssdm = MEM_callocN(sizeof(*ssdm), "ssdm");
2066
2067         DM_init(&ssdm->dm, dlm->totvert, dlm->totedge, dlm->totface);
2068
2069         ssdm->dm.getMinMax = ssDM_getMinMax;
2070
2071         ssdm->dm.getNumVerts = ssDM_getNumVerts;
2072         ssdm->dm.getNumEdges = ssDM_getNumEdges;
2073         ssdm->dm.getNumFaces = ssDM_getNumFaces;
2074
2075         ssdm->dm.getVert = ssDM_getVert;
2076         ssdm->dm.getEdge = ssDM_getEdge;
2077         ssdm->dm.getFace = ssDM_getFace;
2078         ssdm->dm.getVertArray = ssDM_getVertArray;
2079         ssdm->dm.getEdgeArray = ssDM_getEdgeArray;
2080         ssdm->dm.getFaceArray = ssDM_getFaceArray;
2081
2082         ssdm->dm.convertToDispListMesh = ssDM_convertToDispListMesh;
2083
2084         ssdm->dm.getVertCos = ssDM_getVertCos;
2085
2086         ssdm->dm.drawVerts = ssDM_drawVerts;
2087
2088         ssdm->dm.drawUVEdges = ssDM_drawUVEdges;
2089         ssdm->dm.drawEdges = ssDM_drawEdges;
2090         ssdm->dm.drawLooseEdges = ssDM_drawLooseEdges;
2091         
2092         ssdm->dm.drawFacesSolid = ssDM_drawFacesSolid;
2093         ssdm->dm.drawFacesColored = ssDM_drawFacesColored;
2094         ssdm->dm.drawFacesTex = ssDM_drawFacesTex;
2095         ssdm->dm.drawMappedFaces = ssDM_drawMappedFaces;
2096         ssdm->dm.drawMappedFacesTex = ssDM_drawMappedFacesTex;
2097
2098                 /* EM functions */
2099         
2100         ssdm->dm.foreachMappedVert = ssDM_foreachMappedVert;
2101         ssdm->dm.foreachMappedEdge = ssDM_foreachMappedEdge;
2102         ssdm->dm.foreachMappedFaceCenter = ssDM_foreachMappedFaceCenter;
2103         
2104         ssdm->dm.drawMappedEdges = ssDM_drawMappedEdges;
2105         ssdm->dm.drawMappedEdgesInterp = NULL; // no way to implement this one
2106         
2107         ssdm->dm.release = ssDM_release;
2108         
2109         ssdm->dlm = dlm;
2110
2111         if (vertexCos) {
2112                 int i;
2113
2114                 for (i=0; i<dlm->totvert; i++) {
2115                         VECCOPY(dlm->mvert[i].co, vertexCos[i]);
2116                 }
2117
2118                 if (dlm->nors && !dlm->dontFreeNors) {
2119                         MEM_freeN(dlm->nors);
2120                         dlm->nors = 0;
2121                 }
2122
2123                 mesh_calc_normals(dlm->mvert, dlm->totvert, dlm->mface, dlm->totface, &dlm->nors);
2124         }
2125
2126         return (DerivedMesh*) ssdm;
2127 }
2128
2129 #ifdef WITH_VERSE
2130
2131 /* verse derived mesh */
2132 typedef struct {
2133         struct DerivedMesh dm;
2134         struct VNode *vnode;
2135         struct VLayer *vertex_layer;
2136         struct VLayer *polygon_layer;
2137         float (*verts)[3];
2138 } VDerivedMesh;
2139
2140 /* this function set up border points of verse mesh bounding box */
2141 static void vDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
2142 {
2143         VDerivedMesh *vdm = (VDerivedMesh*)dm;
2144         struct VerseVert *vvert;
2145
2146         if(!vdm->vertex_layer) return;
2147
2148         vvert = (VerseVert*)vdm->vertex_layer->dl.lb.first;
2149
2150         if(vdm->vertex_layer->dl.da.count > 0) {
2151                 while(vvert) {
2152                         DO_MINMAX(vdm->verts ? vvert->cos : vvert->co, min_r, max_r);
2153                         vvert = vvert->next;
2154                 }
2155         }
2156         else {
2157                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
2158         }
2159 }
2160
2161 /* this function return number of vertexes in vertex layer */
2162 static int vDM_getNumVerts(DerivedMesh *dm)
2163 {
2164         VDerivedMesh *vdm = (VDerivedMesh*)dm;
2165
2166         if(!vdm->vertex_layer) return 0;
2167         else return vdm->vertex_layer->dl.da.count;
2168 }
2169
2170 /* this function return number of 'fake' edges */
2171 static int vDM_getNumEdges(DerivedMesh *dm)
2172 {
2173         return 0;
2174 }
2175
2176 /* this function returns number of polygons in polygon layer */
2177 static int vDM_getNumFaces(DerivedMesh *dm)
2178 {
2179         VDerivedMesh *vdm = (VDerivedMesh*)dm;
2180
2181         if(!vdm->polygon_layer) return 0;
2182         else return vdm->polygon_layer->dl.da.count;
2183 }
2184
2185 /* this function doesn't return vertex with index of access array,
2186  * but it return 'indexth' vertex of dynamic list */
2187 void vDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
2188 {
2189         VerseVert *vvert = ((VDerivedMesh*)dm)->vertex_layer->dl.lb.first;
2190         int i;
2191
2192         for(i=0 ; i<index; i++) vvert = vvert->next;
2193
2194         if(vvert) {
2195                 VECCOPY(vert_r->co, vvert->co);
2196
2197                 vert_r->no[0] = vvert->no[0] * 32767.0;
2198                 vert_r->no[1] = vvert->no[1] * 32767.0;
2199                 vert_r->no[2] = vvert->no[2] * 32767.0;
2200
2201                 /* TODO what to do with vert_r->flag and vert_r->mat_nr? */
2202                 vert_r->mat_nr = 0;
2203                 vert_r->flag = 0;
2204         }
2205 }
2206
2207 /* dummy function, because verse mesh doesn't store edges */
2208 void vDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
2209 {
2210         edge_r->flag = 0;
2211         edge_r->crease = 0;
2212         edge_r->v1 = 0;
2213         edge_r->v2 = 0;
2214 }
2215
2216 /* this function doesn't return face with index of access array,
2217  * but it returns 'indexth' vertex of dynamic list */
2218 void vDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
2219 {
2220         struct VerseFace *vface = ((VDerivedMesh*)dm)->polygon_layer->dl.lb.first;
2221         struct VerseVert *vvert = ((VDerivedMesh*)dm)->vertex_layer->dl.lb.first;
2222         struct VerseVert *vvert0, *vvert1, *vvert2, *vvert3;
2223         int i;
2224
2225         for(i = 0; i < index; ++i) vface = vface->next;
2226
2227         face_r->mat_nr = 0;
2228         face_r->flag = 0;
2229
2230         /* goddamn, we have to search all verts to find indices */
2231         vvert0 = vface->vvert0;
2232         vvert1 = vface->vvert1;
2233         vvert2 = vface->vvert2;
2234         vvert3 = vface->vvert3;
2235         if(!vvert3) face_r->v4 = 0;
2236
2237         for(i = 0; vvert0 || vvert1 || vvert2 || vvert3; i++, vvert = vvert->next) {
2238                 if(vvert == vvert0) {
2239                         face_r->v1 = i;
2240                         vvert0 = NULL;
2241                 }
2242                 if(vvert == vvert1) {
2243                         face_r->v2 = i;
2244                         vvert1 = NULL;
2245                 }
2246                 if(vvert == vvert2) {
2247                         face_r->v3 = i;
2248                         vvert2 = NULL;
2249                 }
2250                 if(vvert == vvert3) {
2251                         face_r->v4 = i;
2252                         vvert3 = NULL;
2253                 }
2254         }
2255
2256         test_index_face(face_r, NULL, NULL, vface->vvert3?4:3);
2257 }
2258
2259 /* fill array of mvert */
2260 void vDM_getVertArray(DerivedMesh *dm, MVert *vert_r)
2261 {
2262         VerseVert *vvert = ((VDerivedMesh *)dm)->vertex_layer->dl.lb.first;
2263
2264         for( ; vvert; vvert = vvert->next, ++vert_r) {
2265                 VECCOPY(vert_r->co, vvert->co);
2266
2267                 vert_r->no[0] = vvert->no[0] * 32767.0;
2268                 vert_r->no[1] = vvert->no[1] * 32767.0;
2269                 vert_r->no[2] = vvert->no[2] * 32767.0;
2270
2271                 vert_r->mat_nr = 0;
2272                 vert_r->flag = 0;
2273         }
2274 }
2275
2276 /* dummy function, edges arent supported in verse mesh */
2277 void vDM_getEdgeArray(DerivedMesh *dm, MEdge *edge_r)
2278 {
2279 }
2280
2281 /* fill array of mfaces */
2282 void vDM_getFaceArray(DerivedMesh *dm, MFace *face_r)
2283 {
2284         VerseFace *vface = ((VDerivedMesh*)dm)->polygon_layer->dl.lb.first;
2285         VerseVert *vvert = ((VDerivedMesh*)dm)->vertex_layer->dl.lb.first;
2286         int i;
2287
2288         /* store vert indices in the prev pointer (kind of hacky) */
2289         for(i = 0; vvert; vvert = vvert->next, ++i)
2290                 vvert->tmp.index = i;
2291
2292         for( ; vface; vface = vface->next, ++face_r) {
2293                 face_r->mat_nr = 0;
2294                 face_r->flag = 0;
2295
2296                 face_r->v1 = vface->vvert0->tmp.index;
2297                 face_r->v2 = vface->vvert1->tmp.index;
2298                 face_r->v3 = vface->vvert2->tmp.index;
2299                 if(vface->vvert3) face_r->v4 = vface->vvert3->tmp.index;
2300                 else face_r->v4 = 0;
2301
2302                 test_index_face(face_r, NULL, NULL, vface->vvert3?4:3);
2303         }
2304 }
2305
2306 /* create diplist mesh from verse mesh */
2307 static DispListMesh* vDM_convertToDispListMesh(DerivedMesh *dm, int allowShared)
2308 {
2309         VDerivedMesh *vdm = (VDerivedMesh*)dm;
2310         DispListMesh *dlm = MEM_callocN(sizeof(*dlm), "dlm");
2311         struct VerseVert *vvert;
2312         struct VerseFace *vface;
2313         struct MVert *mvert=NULL;
2314         struct MFace *mface=NULL;
2315         float *norms;
2316         unsigned int i;
2317         EdgeHash *edges;
2318
2319         if(!vdm->vertex_layer || !vdm->polygon_layer) {
2320                 dlm->totvert = 0;
2321                 dlm->totedge = 0;
2322                 dlm->totface = 0;
2323                 dlm->dontFreeVerts = dlm->dontFreeOther = dlm->dontFreeNors = 0;
2324
2325                 return dlm;
2326         };
2327         
2328         /* number of vertexes, edges and faces */
2329         dlm->totvert = vdm->vertex_layer->dl.da.count;
2330         dlm->totface = vdm->polygon_layer->dl.da.count;
2331
2332         /* create dynamic array of mverts */
2333         mvert = (MVert*)MEM_mallocN(sizeof(MVert)*dlm->totvert, "dlm verts");
2334         dlm->mvert = mvert;
2335         vvert = (VerseVert*)vdm->vertex_layer->dl.lb.first;
2336         i = 0;
2337         while(vvert) {
2338                 VECCOPY(mvert->co, vdm->verts ? vvert->cos : vvert->co);
2339                 VECCOPY(mvert->no, vvert->no);
2340                 mvert->mat_nr = 0;
2341                 mvert->flag = 0;
2342
2343                 vvert->tmp.index = i++;
2344                 mvert++;
2345                 vvert = vvert->next;
2346         }
2347
2348         edges = BLI_edgehash_new();
2349
2350         /* create dynamic array of faces */
2351         mface = (MFace*)MEM_mallocN(sizeof(MFace)*dlm->totface, "dlm faces");
2352         dlm->mface = mface;
2353         vface = (VerseFace*)vdm->polygon_layer->dl.lb.first;
2354         i = 0;
2355         while(vface) {
2356                 mface->v1 = vface->vvert0->tmp.index;
2357                 mface->v2 = vface->vvert1->tmp.index;
2358                 mface->v3 = vface->vvert2->tmp.index;
2359                 if(!BLI_edgehash_haskey(edges, mface->v1, mface->v2))
2360                         BLI_edgehash_insert(edges, mface->v1, mface->v2, NULL);
2361                 if(!BLI_edgehash_haskey(edges, mface->v2, mface->v3))
2362                         BLI_edgehash_insert(edges, mface->v2, mface->v3, NULL);
2363                 if(vface->vvert3) {
2364                         mface->v4 = vface->vvert3->tmp.index;
2365                         if(!BLI_edgehash_haskey(edges, mface->v3, mface->v4))
2366                                 BLI_edgehash_insert(edges, mface->v3, mface->v4, NULL);
2367                         if(!BLI_edgehash_haskey(edges, mface->v4, mface->v1))
2368                                 BLI_edgehash_insert(edges, mface->v4, mface->v1, NULL);
2369                 } else {
2370                         mface->v4 = 0;
2371                         if(!BLI_edgehash_haskey(edges, mface->v3, mface->v1))
2372                                 BLI_edgehash_insert(edges, mface->v3, mface->v1, NULL);
2373                 }
2374
2375                 mface->pad = 0;
2376                 mface->mat_nr = 0;
2377                 mface->flag = 0;
2378                 mface->edcode = 0;
2379
2380                 test_index_face(mface, NULL, NULL, vface->vvert3?4:3);
2381
2382                 mface++;
2383                 vface = vface->next;
2384         }
2385
2386         dlm->totedge = BLI_edgehash_size(edges);
2387
2388         if(dlm->totedge) {
2389                 EdgeHashIterator *i;
2390                 MEdge *medge = dlm->medge = (MEdge *)MEM_mallocN(sizeof(MEdge)*dlm->totedge, "mesh_from_verse edge");
2391
2392                 for(i = BLI_edgehashIterator_new(edges); !BLI_edgehashIterator_isDone(i); BLI_edgehashIterator_step(i), ++medge) {
2393                         BLI_edgehashIterator_getKey(i, (int*)&medge->v1, (int*)&medge->v2);
2394                         medge->crease = medge->pad = medge->flag = 0;
2395                 }
2396                 BLI_edgehashIterator_free(i);
2397         }
2398
2399         BLI_edgehash_free(edges, NULL);
2400
2401         /* textures and verex colors aren't supported yet */
2402         dlm->tface = NULL;
2403         dlm->mcol = NULL;
2404
2405         /* faces normals */
2406         norms = (float*)MEM_mallocN(sizeof(float)*3*dlm->totface, "dlm norms");
2407         dlm->nors = norms;
2408
2409         vface = (VerseFace*)vdm->polygon_layer->dl.lb.first;
2410         while(vface){
2411                 VECCOPY(norms, vface->no);
2412                 norms += 3;
2413                 vface = vface->next;
2414         }
2415
2416         /* free everything, nothing is shared */
2417         dlm->dontFreeVerts = dlm->dontFreeOther = dlm->dontFreeNors = 0;
2418
2419         return dlm;
2420 }
2421
2422 /* return coordination of vertex with index ... I suppose, that it will
2423  * be very hard to do, becuase there can be holes in access array */
2424 static void vDM_getVertCo(DerivedMesh *dm, int index, float co_r[3])
2425 {
2426         VDerivedMesh *vdm = (VDerivedMesh*)dm;
2427         struct VerseVert *vvert = NULL;
2428
2429         if(!vdm->vertex_layer) return;
2430
2431         vvert = BLI_dlist_find_link(&(vdm->vertex_layer->dl), index);
2432         if(vvert) {
2433                 VECCOPY(co_r, vdm->verts ? vvert->cos : vvert->co);
2434         }
2435         else {
2436                 co_r[0] = co_r[1] = co_r[2] = 0.0;
2437         }
2438 }
2439
2440 /* return array of vertex coordiantions */
2441 static void vDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
2442 {
2443         VDerivedMesh *vdm = (VDerivedMesh*)dm;
2444         struct VerseVert *vvert;
2445         int i = 0;
2446
2447         if(!vdm->vertex_layer) return;
2448
2449         vvert = vdm->vertex_layer->dl.lb.first;
2450         while(vvert) {
2451                 VECCOPY(cos_r[i], vdm->verts ? vvert->cos : vvert->co);
2452                 i++;
2453                 vvert = vvert->next;
2454         }
2455 }
2456
2457 /* return normal of vertex with index ... again, it will be hard to
2458  * implemente, because access array */
2459 static void vDM_getVertNo(DerivedMesh *dm, int index, float no_r[3])
2460 {
2461         VDerivedMesh *vdm = (VDerivedMesh*)dm;
2462         struct VerseVert *vvert = NULL;
2463
2464         if(!vdm->vertex_layer) return;
2465
2466         vvert = BLI_dlist_find_link(&(vdm->vertex_layer->dl), index);
2467         if(vvert) {
2468                 VECCOPY(no_r, vvert->no);
2469         }
2470         else {
2471                 no_r[0] = no_r[1] = no_r[2] = 0.0;
2472         }
2473 }
2474
2475 /* draw all VerseVertexes */
2476 static void vDM_drawVerts(DerivedMesh *dm)
2477 {
2478         VDerivedMesh *vdm = (VDerivedMesh*)dm;
2479         struct VerseVert *vvert;
2480
2481         if(!vdm->vertex_layer) return;
2482
2483         vvert = vdm->vertex_layer->dl.lb.first;
2484
2485         bglBegin(GL_POINTS);
2486         while(vvert) {
2487                 bglVertex3fv(vdm->verts ? vvert->cos : vvert->co);
2488                 vvert = vvert->next;
2489         }
2490         bglEnd();
2491 }
2492
2493 /* draw all edges of VerseFaces ... it isn't optimal, because verse
2494  * specification doesn't support edges :-( ... bother eskil ;-)
2495  * ... some edges (most of edges) are drawn twice */
2496 static void vDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
2497 {
2498         VDerivedMesh *vdm = (VDerivedMesh*)dm;
2499         struct VerseFace *vface;
2500
2501         if(!vdm->polygon_layer) return;
2502
2503         vface = vdm->polygon_layer->dl.lb.first;
2504
2505         while(vface) {
2506                 glBegin(GL_LINE_LOOP);
2507                 glVertex3fv(vdm->verts ? vface->vvert0->cos : vface->vvert0->co);
2508                 glVertex3fv(vdm->verts ? vface->vvert1->cos : vface->vvert1->co);
2509                 glVertex3fv(vdm->verts ? vface->vvert2->cos : vface->vvert2->co);
2510                 if(vface->vvert3) glVertex3fv(vdm->verts ? vface->vvert3->cos : vface->vvert3->co);
2511                 glEnd();
2512
2513                 vface = vface->next;
2514         }
2515 }
2516
2517 /* verse spec doesn't support edges ... loose edges can't exist */
2518 void vDM_drawLooseEdges(DerivedMesh *dm)
2519 {
2520 }
2521
2522 /* draw uv edges, not supported yet */
2523 static void vDM_drawUVEdges(DerivedMesh *dm)
2524 {
2525 }
2526
2527 /* draw all VerseFaces */
2528 static void vDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int))
2529 {
2530         VDerivedMesh *vdm = (VDerivedMesh*)dm;
2531         struct VerseFace *vface;
2532
2533         if(!vdm->polygon_layer) return;
2534
2535         vface = vdm->polygon_layer->dl.lb.first;
2536
2537         while(vface) {
2538 /*              if((vface->smooth) && (vface->smooth->value)){
2539                         glShadeModel(GL_SMOOTH);
2540                         glBegin(vface->vvert3?GL_QUADS:GL_TRIANGLES);
2541                         glNormal3fv(vface->vvert0->no);
2542                         glVertex3fv(vdm->verts ? vface->vvert0->cos : vface->vvert0->co);
2543                         glNormal3fv(vface->vvert1->no);
2544                         glVertex3fv(vdm->verts ? vface->vvert1->cos : vface->vvert1->co);
2545                         glNormal3fv(vface->vvert2->no);
2546                         glVertex3fv(vdm->verts ? vface->vvert2->cos : vface->vvert2->co);
2547                         if(vface->vvert3){
2548                                 glNormal3fv(vface->vvert3->no);
2549                                 glVertex3fv(vdm->verts ? vface->vvert3->cos : vface->vvert3->co);
2550                         }
2551                         glEnd();
2552                 }
2553                 else { */
2554                         glShadeModel(GL_FLAT);
2555                         glBegin(vface->vvert3?GL_QUADS:GL_TRIANGLES);
2556                         glNormal3fv(vface->no);
2557                         glVertex3fv(vdm->verts ? vface->vvert0->cos : vface->vvert0->co);
2558                         glVertex3fv(vdm->verts ? vface->vvert1->cos : vface->vvert1->co);
2559                         glVertex3fv(vdm->verts ? vface->vvert2->cos : vface->vvert2->co);
2560                         if(vface->vvert3)
2561                                 glVertex3fv(vdm->verts ? vface->vvert3->cos : vface->vvert3->co);
2562                         glEnd();
2563 /*              } */
2564
2565                 vface = vface->next;
2566         }
2567         glShadeModel(GL_FLAT);
2568 }
2569
2570 /* thsi function should draw mesh with mapped texture, but it isn't supported yet */
2571 static void vDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(struct TFace *tface, int matnr))
2572 {
2573         VDerivedMesh *vdm = (VDerivedMesh*)dm;
2574         struct VerseFace *vface;
2575
2576         if(!vdm->polygon_layer) return;
2577
2578         vface = vdm->polygon_layer->dl.lb.first;
2579
2580         while(vface) {
2581                 glBegin(vface->vvert3?GL_QUADS:GL_TRIANGLES);
2582                 glVertex3fv(vdm->verts ? vface->vvert0->cos : vface->vvert0->co);
2583                 glVertex3fv(vdm->verts ? vface->vvert1->cos : vface->vvert1->co);
2584                 glVertex3fv(vdm->verts ? vface->vvert2->cos : vface->vvert2->co);
2585                 if(vface->vvert3)
2586                         glVertex3fv(vdm->verts ? vface->vvert3->cos : vface->vvert3->co);
2587                 glEnd();
2588
2589                 vface = vface->next;
2590         }
2591 }
2592
2593 /* this function should draw mesh with colored faces (weight paint, vertex
2594  * colors, etc.), but it isn't supported yet */
2595 static void vDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *col1, unsigned char *col2)
2596 {
2597         VDerivedMesh *vdm = (VDerivedMesh*)dm;
2598         struct VerseFace *vface;
2599
2600         if(!vdm->polygon_layer) return;
2601
2602         vface = vdm->polygon_layer->dl.lb.first;
2603
2604         while(vface) {
2605                 glBegin(vface->vvert3?GL_QUADS:GL_TRIANGLES);
2606                 glVertex3fv(vdm->verts ? vface->vvert0->cos : vface->vvert0->co);
2607                 glVertex3fv(vdm->verts ? vface->vvert1->cos : vface->vvert1->co);
2608                 glVertex3fv(vdm->verts ? vface->vvert2->cos : vface->vvert2->co);
2609                 if(vface->vvert3)
2610                         glVertex3fv(vdm->verts ? vface->vvert3->cos : vface->vvert3->co);
2611                 glEnd();
2612
2613                 vface = vface->next;
2614         }
2615 }
2616
2617 /**/
2618 static void vDM_foreachMappedVert(
2619                 DerivedMesh *dm,
2620                 void (*func)(void *userData, int index, float *co, float *no_f, short *no_s),
2621                 void *userData)
2622 {
2623 }
2624
2625 /**/
2626 static void vDM_foreachMappedEdge(
2627                 DerivedMesh *dm,
2628                 void (*func)(void *userData, int index, float *v0co, float *v1co),
2629                 void *userData)
2630 {
2631 }
2632
2633 /**/
2634 static void vDM_foreachMappedFaceCenter(
2635                 DerivedMesh *dm,
2636                 void (*func)(void *userData, int index, float *cent, float *no),
2637                 void *userData)
2638 {
2639 }
2640
2641 /**/
2642 static void vDM_drawMappedFacesTex(
2643                 DerivedMesh *dm,
2644                 int (*setDrawParams)(void *userData, int index),
2645                 void *userData)
2646 {
2647 }
2648
2649 /**/
2650 static void vDM_drawMappedFaces(
2651                 DerivedMesh *dm,
2652                 int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r),
2653                 void *userData,
2654                 int useColors)
2655 {
2656 }
2657
2658 /**/
2659 static void vDM_drawMappedEdges(
2660                 DerivedMesh *dm,
2661                 int (*setDrawOptions)(void *userData, int index),
2662                 void *userData)
2663 {
2664 }
2665
2666 /**/
2667 static void vDM_drawMappedEdgesInterp(
2668                 DerivedMesh *dm, 
2669                 int (*setDrawOptions)(void *userData, int index), 
2670                 void (*setDrawInterpOptions)(void *userData, int index, float t),
2671                 void *userData)
2672 {
2673 }
2674
2675 /* free all DerivedMesh data */
2676 static void vDM_release(DerivedMesh *dm)
2677 {
2678         VDerivedMesh *vdm = (VDerivedMesh*)dm;
2679
2680         DM_release(dm);
2681
2682         if(vdm->verts) MEM_freeN(vdm->verts);
2683         MEM_freeN(vdm);
2684 }
2685
2686 /* create derived mesh from verse mesh ... it is used in object mode, when some other client can
2687  * change shared data and want to see this changes in real time too */
2688 DerivedMesh *derivedmesh_from_versemesh(VNode *vnode, float (*vertexCos)[3])
2689 {
2690         VDerivedMesh *vdm = MEM_callocN(sizeof(*vdm), "vdm");
2691         struct VerseVert *vvert;
2692
2693         vdm->vnode = vnode;
2694         vdm->vertex_layer = find_verse_layer_type((VGeomData*)vnode->data, VERTEX_LAYER);
2695         vdm->polygon_layer = find_verse_layer_type((VGeomData*)vnode->data, POLYGON_LAYER);
2696
2697         if(vdm->vertex_layer && vdm->polygon_layer)
2698                 DM_init(&vdm->dm, vdm->vertex_layer->dl.da.count, 0, vdm->polygon_layer->dl.da.count);
2699         else
2700                 DM_init(&vdm->dm, 0, 0, 0);
2701         
2702         vdm->dm.getMinMax = vDM_getMinMax;
2703
2704         vdm->dm.getNumVerts = vDM_getNumVerts;
2705         vdm->dm.getNumEdges = vDM_getNumEdges;
2706         vdm->dm.getNumFaces = vDM_getNumFaces;
2707
2708         vdm->dm.getVert = vDM_getVert;
2709         vdm->dm.getEdge = vDM_getEdge;
2710         vdm->dm.getFace = vDM_getFace;
2711         vdm->dm.getVertArray = vDM_getVertArray;
2712         vdm->dm.getEdgeArray = vDM_getEdgeArray;
2713         vdm->dm.getFaceArray = vDM_getFaceArray;
2714         
2715         vdm->dm.foreachMappedVert = vDM_foreachMappedVert;
2716         vdm->dm.foreachMappedEdge = vDM_foreachMappedEdge;
2717         vdm->dm.foreachMappedFaceCenter = vDM_foreachMappedFaceCenter;
2718
2719         vdm->dm.convertToDispListMesh = vDM_convertToDispListMesh;
2720
2721         vdm->dm.getVertCos = vDM_getVertCos;
2722         vdm->dm.getVertCo = vDM_getVertCo;
2723         vdm->dm.getVertNo = vDM_getVertNo;
2724
2725         vdm->dm.drawVerts = vDM_drawVerts;
2726
2727         vdm->dm.drawEdges = vDM_drawEdges;
2728         vdm->dm.drawLooseEdges = vDM_drawLooseEdges;
2729         vdm->dm.drawUVEdges = vDM_drawUVEdges;
2730
2731         vdm->dm.drawFacesSolid = vDM_drawFacesSolid;
2732         vdm->dm.drawFacesTex = vDM_drawFacesTex;
2733         vdm->dm.drawFacesColored = vDM_drawFacesColored;
2734
2735         vdm->dm.drawMappedFacesTex = vDM_drawMappedFacesTex;
2736         vdm->dm.drawMappedFaces = vDM_drawMappedFaces;
2737         vdm->dm.drawMappedEdges = vDM_drawMappedEdges;
2738         vdm->dm.drawMappedEdgesInterp = vDM_drawMappedEdgesInterp;
2739
2740         vdm->dm.release = vDM_release;
2741
2742         if(vdm->vertex_layer) {
2743                 if(vertexCos) {
2744                         int i;
2745
2746                         vdm->verts = MEM_mallocN(sizeof(float)*3*vdm->vertex_layer->dl.da.count, "verse mod vertexes");
2747                         vvert = vdm->vertex_layer->dl.lb.first;
2748
2749                         for(i=0; i<vdm->vertex_layer->dl.da.count && vvert; i++, vvert = vvert->next) {
2750                                 VECCOPY(vdm->verts[i], vertexCos[i]);
2751                                 vvert->cos = vdm->verts[i];
2752                         }
2753                 }
2754                 else {
2755                         vdm->verts = NULL;
2756                         vvert = vdm->vertex_layer->dl.lb.first;
2757
2758                         while(vvert) {
2759                                 vvert->cos = NULL;
2760                                 vvert = vvert->next;
2761                         }
2762                 }
2763         }
2764
2765         return (DerivedMesh*) vdm;
2766 }
2767
2768 #endif
2769
2770 /***/
2771
2772 DerivedMesh *mesh_create_derived_for_modifier(Object *ob, ModifierData *md)
2773 {
2774         Mesh *me = ob->data;
2775         ModifierTypeInfo *mti = modifierType_getInfo(md->type);
2776         DerivedMesh *dm;
2777
2778         if (!(md->mode&eModifierMode_Realtime)) return NULL;
2779         if (mti->isDisabled && mti->isDisabled(md)) return NULL;
2780
2781         if (mti->type==eModifierTypeType_OnlyDeform) {
2782                 int numVerts;
2783                 float (*deformedVerts)[3] = mesh_getVertexCos(me, &numVerts);
2784
2785                 mti->deformVerts(md, ob, NULL, deformedVerts, numVerts);
2786 #ifdef WITH_VERSE
2787                 if(me->vnode) dm = derivedmesh_from_versemesh(me->vnode, deformedVerts);
2788                 else dm = getMeshDerivedMesh(me, ob, deformedVerts);
2789 #else
2790                 dm = getMeshDerivedMesh(me, ob, deformedVerts);
2791 #endif
2792
2793                 MEM_freeN(deformedVerts);
2794         } else {
2795                 DerivedMesh *tdm = getMeshDerivedMesh(me, ob, NULL);
2796                 dm = mti->applyModifier(md, ob, tdm, 0, 0);
2797
2798                 if(tdm != dm) tdm->release(tdm);
2799         }
2800
2801         return dm;
2802 }
2803
2804 static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
2805                                 DerivedMesh **deform_r, DerivedMesh **final_r,
2806                                 int useRenderParams, int useDeform,
2807                                 int needMapping)
2808 {
2809         Mesh *me = ob->data;
2810         ModifierData *md = modifiers_getVirtualModifierList(ob);
2811         float (*deformedVerts)[3] = NULL;
2812         DerivedMesh *dm;
2813         int numVerts = me->totvert;
2814         int fluidsimMeshUsed = 0;
2815         int required_mode;
2816
2817         modifiers_clearErrors(ob);
2818
2819         if(deform_r) *deform_r = NULL;
2820         *final_r = NULL;
2821
2822         /* replace original mesh by fluidsim surface mesh for fluidsim
2823          * domain objects
2824          */
2825         if((G.obedit!=ob) && !needMapping) {
2826                 if((ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) &&
2827                    (1) && (!give_parteff(ob)) ) { // doesnt work together with particle systems!
2828                         if(ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN) {
2829                                 loadFluidsimMesh(ob,useRenderParams);
2830                                 fluidsimMeshUsed = 1;
2831                                 /* might have changed... */
2832                                 me = ob->data;
2833                                 numVerts = me->totvert;
2834                         }
2835                 }
2836         }
2837
2838         if(useRenderParams) required_mode = eModifierMode_Render;
2839         else required_mode = eModifierMode_Realtime;
2840
2841         if(useDeform) {
2842                 if(do_ob_key(ob)) /* shape key makes deform verts */
2843                         deformedVerts = mesh_getVertexCos(me, &numVerts);
2844                 
2845                 /* Apply all leading deforming modifiers */
2846                 for(; md; md = md->next) {
2847                         ModifierTypeInfo *mti = modifierType_getInfo(md->type);
2848
2849                         if((md->mode & required_mode) != required_mode) continue;
2850                         if(mti->isDisabled && mti->isDisabled(md)) continue;
2851
2852                         if(mti->type == eModifierTypeType_OnlyDeform) {
2853                                 if(!deformedVerts)
2854                                         deformedVerts = mesh_getVertexCos(me, &numVerts);
2855
2856                                 mti->deformVerts(md, ob, NULL, deformedVerts, numVerts);
2857                         } else {
2858                                 break;
2859                         }
2860                 }
2861
2862                 /* Result of all leading deforming modifiers is cached for
2863                  * places that wish to use the original mesh but with deformed
2864                  * coordinates (vpaint, etc.)
2865                  */
2866                 if (deform_r) {
2867 #ifdef WITH_VERSE
2868                         if(me->vnode) *deform_r = derivedmesh_from_versemesh(me->vnode, deformedVerts);
2869                         else {
2870                                 *deform_r = CDDM_from_mesh(me);
2871                                 if(deformedVerts) {
2872                                         CDDM_apply_vert_coords(*deform_r, deformedVerts);
2873                                         CDDM_calc_normals(*deform_r);
2874                                 }
2875                         }
2876 #else
2877                         *deform_r = CDDM_from_mesh(me);
2878                         if(deformedVerts) {
2879                                 CDDM_apply_vert_coords(*deform_r, deformedVerts);
2880                                 CDDM_calc_normals(*deform_r);
2881                         }
2882 #endif
2883                 }
2884         } else {
2885                 if(!fluidsimMeshUsed) {
2886                         /* default behaviour for meshes */
2887                         deformedVerts = inputVertexCos;
2888                 } else {
2889                         /* the fluid sim mesh might have more vertices than the original 
2890                          * one, so inputVertexCos shouldnt be used
2891                          */
2892                         deformedVerts = mesh_getVertexCos(me, &numVerts);
2893                 }
2894         }
2895
2896
2897         /* Now apply all remaining modifiers. If useDeform is off then skip
2898          * OnlyDeform ones. 
2899          */
2900         dm = NULL;
2901
2902 #ifdef WITH_VERSE
2903         /* hack to make sure modifiers don't try to use mesh data from a verse
2904          * node
2905          */
2906         if(me->vnode) dm = derivedmesh_from_versemesh(me->vnode, deformedVerts);
2907 #endif
2908
2909         for(; md; md = md->next) {
2910                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
2911
2912                 if((md->mode & required_mode) != required_mode) continue;
2913                 if(mti->type == eModifierTypeType_OnlyDeform && !useDeform) continue;
2914                 if((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) {
2915                         modifier_setError(md, "Internal error, modifier requires "
2916                                           "original data (bad stack position).");
2917                         continue;
2918                 }
2919                 if(mti->isDisabled && mti->isDisabled(md)) continue;
2920                 if(needMapping && !modifier_supportsMapping(md)) continue;
2921
2922                 /* How to apply modifier depends on (a) what we already have as
2923                  * a result of previous modifiers (could be a DerivedMesh or just
2924                  * deformed vertices) and (b) what type the modifier is.
2925                  */
2926
2927                 if(mti->type == eModifierTypeType_OnlyDeform) {
2928                         /* No existing verts to deform, need to build them. */
2929                         if(!deformedVerts) {
2930                                 if(dm) {
2931                                         /* Deforming a derived mesh, read the vertex locations
2932                                          * out of the mesh and deform them. Once done with this
2933                                          * run of deformers verts will be written back.
2934                                          */
2935                                         numVerts = dm->getNumVerts(dm);
2936                                         deformedVerts =
2937                                             MEM_mallocN(sizeof(*deformedVerts) * numVerts, "dfmv");
2938                                         dm->getVertCos(dm, deformedVerts);
2939                                 } else {
2940                                         deformedVerts = mesh_getVertexCos(me, &numVerts);
2941                                 }
2942                         }
2943
2944                         mti->deformVerts(md, ob, dm, deformedVerts, numVerts);
2945                 } else {
2946                         DerivedMesh *ndm;
2947
2948                         /* apply vertex coordinates or build a DerivedMesh as necessary */
2949                         if(dm) {
2950                                 if(deformedVerts) {
2951                                         DerivedMesh *tdm = CDDM_copy(dm);
2952                                         dm->release(dm);
2953                                         dm = tdm;
2954
2955                                         CDDM_apply_vert_coords(dm, deformedVerts);
2956                                         CDDM_calc_normals(dm);
2957                                 }
2958                         } else {
2959                                 dm = CDDM_from_mesh(me);
2960
2961                                 if(deformedVerts) {
2962                                         CDDM_apply_vert_coords(dm, deformedVerts);
2963                                         CDDM_calc_normals(dm);
2964                                 }
2965                         }
2966
2967                         ndm = mti->applyModifier(md, ob, dm, useRenderParams,
2968                                                  !inputVertexCos);
2969
2970                         if(ndm) {
2971                                 /* if the modifier returned a new dm, release the old one */
2972                                 if(dm && dm != ndm) dm->release(dm);
2973
2974                                 dm = ndm;
2975
2976                                 if(deformedVerts) {
2977                                         if(deformedVerts != inputVertexCos)
2978                                                 MEM_freeN(deformedVerts);
2979
2980                                         deformedVerts = NULL;
2981                                 }
2982                         } 
2983                 }
2984         }
2985
2986         /* Yay, we are done. If we have a DerivedMesh and deformed vertices
2987          * need to apply these back onto the DerivedMesh. If we have no
2988          * DerivedMesh then we need to build one.
2989          */
2990         if(dm && deformedVerts) {
2991                 *final_r = CDDM_copy(dm);
2992
2993                 dm->release(dm);
2994
2995                 CDDM_apply_vert_coords(*final_r, deformedVerts);
2996                 CDDM_calc_normals(*final_r);
2997         } else if(dm) {
2998                 *final_r = dm;
2999         } else {
3000 #ifdef WITH_VERSE
3001                 if(me->vnode)
3002                         *final_r = derivedmesh_from_versemesh(me->vnode, deformedVerts);
3003                 else {
3004                         *final_r = CDDM_from_mesh(me);
3005                         if(deformedVerts) {
3006                                 CDDM_apply_vert_coords(*final_r, deformedVerts);
3007                                 CDDM_calc_normals(*final_r);
3008                         }
3009                 }
3010 #else
3011                 *final_r = CDDM_from_mesh(me);
3012                 if(deformedVerts) {
3013                         CDDM_apply_vert_coords(*final_r, deformedVerts);
3014                         CDDM_calc_normals(*final_r);
3015                 }
3016 #endif
3017         }
3018
3019         if(deformedVerts && deformedVerts != inputVertexCos)
3020                 MEM_freeN(deformedVerts);
3021
3022         /* restore mesh in any case */
3023         if(fluidsimMeshUsed) ob->data = ob->fluidsimSettings->orgMesh;
3024 }
3025
3026 static float (*editmesh_getVertexCos(EditMesh *em, int *numVerts_r))[3]
3027 {
3028         int i, numVerts = *numVerts_r = BLI_countlist(&em->verts);
3029         float (*cos)[3];
3030         EditVert *eve;
3031
3032         cos = MEM_mallocN(sizeof(*cos)*numVerts, "vertexcos");
3033         for (i=0,eve=em->verts.first; i<numVerts; i++,eve=eve->next) {
3034                 VECCOPY(cos[i], eve->co);
3035         }
3036
3037         return cos;
3038 }
3039
3040 static void editmesh_calc_modifiers(DerivedMesh **cage_r, DerivedMesh **final_r)
3041 {
3042         Object *ob = G.obedit;
3043         EditMesh *em = G.editMesh;
3044         ModifierData *md;
3045         float (*deformedVerts)[3] = NULL;
3046         DerivedMesh *dm;
3047         int i, numVerts = 0, cageIndex = modifiers_getCageIndex(ob, NULL);
3048         int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
3049
3050         modifiers_clearErrors(ob);
3051
3052         if(cage_r && cageIndex == -1) {
3053                 *cage_r = getEditMeshDerivedMesh(em, ob, NULL);
3054         }
3055
3056         dm = NULL;
3057         for(i = 0, md = ob->modifiers.first; md; i++, md = md->next) {
3058                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
3059
3060                 if((md->mode & required_mode) != required_mode) continue;
3061                 if((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) {
3062                         modifier_setError(md, "Internal error, modifier requires"
3063                                           "original data (bad stack position).");
3064                         continue;
3065                 }
3066                 if(mti->isDisabled && mti->isDisabled(md)) continue;
3067                 if(!(mti->flags & eModifierTypeFlag_SupportsEditmode)) continue;
3068
3069                 /* How to apply modifier depends on (a) what we already have as
3070                  * a result of previous modifiers (could be a DerivedMesh or just
3071                  * deformed vertices) and (b) what type the modifier is.
3072                  */
3073
3074                 if(mti->type == eModifierTypeType_OnlyDeform) {
3075                         /* No existing verts to deform, need to build them. */
3076                         if(!deformedVerts) {
3077                                 if(dm) {
3078                                         /* Deforming a derived mesh, read the vertex locations
3079                                          * out of the mesh and deform them. Once done with this
3080                                          * run of deformers verts will be written back.
3081                                          */
3082                                         numVerts = dm->getNumVerts(dm);
3083                                         deformedVerts =
3084                                             MEM_mallocN(sizeof(*deformedVerts) * numVerts, "dfmv");
3085                                         dm->getVertCos(dm, deformedVerts);
3086                                 } else {
3087                                         deformedVerts = editmesh_getVertexCos(em, &numVerts);
3088                                 }
3089                         }
3090
3091                         mti->deformVertsEM(md, ob, em, dm, deformedVerts, numVerts);
3092                 } else {
3093                         DerivedMesh *ndm;
3094
3095                         /* apply vertex coordinates or build a DerivedMesh as necessary */
3096                         if(dm) {
3097                                 if(deformedVerts) {
3098                                         DerivedMesh *tdm = CDDM_copy(dm);
3099                                         if(!(cage_r && dm == *cage_r)) dm->release(dm);
3100                                         dm = tdm;
3101
3102                                         CDDM_apply_vert_coords(dm, deformedVerts);
3103                                         CDDM_calc_normals(dm);
3104                                 } else if(cage_r && dm == *cage_r) {
3105                                         /* dm may be changed by this modifier, so we need to copy it
3106                                          */
3107                                         dm = CDDM_copy(dm);
3108                                 }
3109
3110                         } else {
3111                                 dm = CDDM_from_editmesh(em, ob->data);
3112
3113                                 if(deformedVerts) {
3114                                         CDDM_apply_vert_coords(dm, deformedVerts);
3115                                         CDDM_calc_normals(dm);
3116                                 }
3117                         }
3118
3119                         ndm = mti->applyModifierEM(md, ob, em, dm);
3120
3121                         if (ndm) {
3122                                 if(dm && dm != ndm)
3123                                         dm->release(dm);
3124
3125                                 dm = ndm;
3126
3127                                 if (deformedVerts) {
3128                                         MEM_freeN(deformedVerts);
3129                                         deformedVerts = NULL;
3130                                 }
3131                         }
3132                 }
3133
3134                 if(cage_r && i == cageIndex) {
3135                         if(dm && deformedVerts) {
3136                                 *cage_r = CDDM_copy(dm);
3137                                 CDDM_apply_vert_coords(*cage_r, deformedVerts);
3138                         } else if(dm) {
3139                                 *cage_r = dm;
3140                         } else {
3141                                 *cage_r =
3142                                     getEditMeshDerivedMesh(em, ob,
3143                                         deformedVerts ? MEM_dupallocN(deformedVerts) : NULL);
3144                         }
3145                 }
3146         }
3147
3148         /* Yay, we are done. If we have a DerivedMesh and deformed vertices need
3149          * to apply these back onto the DerivedMesh. If we have no DerivedMesh
3150          * then we need to build one.
3151          */
3152         if(dm && deformedVerts) {
3153                 *final_r = CDDM_copy(dm);
3154
3155                 if(!(cage_r && dm == *cage_r)) dm->release(dm);
3156
3157                 CDDM_apply_vert_coords(*final_r, deformedVerts);
3158                 CDDM_calc_normals(*final_r);
3159
3160                 MEM_freeN(deformedVerts);
3161         } else if (dm) {
3162                 *final_r = dm;
3163         } else {
3164                 *final_r = getEditMeshDerivedMesh(em, ob, deformedVerts);
3165         }
3166 }
3167
3168 /***/
3169
3170
3171         /* Something of a hack, at the moment deal with weightpaint
3172          * by tucking into colors during modifier eval, only in
3173          * wpaint mode. Works ok but need to make sure recalc
3174          * happens on enter/exit wpaint.
3175          */
3176
3177 void weight_to_rgb(float input, float *fr, float *fg, float *fb)
3178 {
3179         float blend;
3180         
3181         blend= ((input/2.0f)+0.5f);
3182         
3183         if (input<=0.25f){      // blue->cyan
3184                 *fr= 0.0f;
3185                 *fg= blend*input*4.0f;
3186                 *fb= blend;
3187         }
3188         else if (input<=0.50f){ // cyan->green
3189                 *fr= 0.0f;
3190                 *fg= blend;
3191                 *fb= blend*(1.0f-((input-0.25f)*4.0f)); 
3192         }
3193         else if (input<=0.75){  // green->yellow
3194                 *fr= blend * ((input-0.50f)*4.0f);
3195                 *fg= blend;
3196                 *fb= 0.0f;
3197         }
3198         else if (input<=1.0){ // yellow->red
3199                 *fr= blend;
3200                 *fg= blend * (1.0f-((input-0.75f)*4.0f)); 
3201                 *fb= 0.0f;
3202         }
3203 }
3204 static void calc_weightpaint_vert_color(Object *ob, int vert, unsigned char *col)
3205 {
3206         Mesh *me = ob->data;
3207         float fr, fg, fb, input = 0.0f;
3208         int i;
3209
3210         if (me->dvert) {
3211                 for (i=0; i<me->dvert[vert].totweight; i++)
3212                         if (me->dvert[vert].dw[i].def_nr==ob->actdef-1)
3213                                 input+=me->dvert[vert].dw[i].weight;            
3214         }
3215
3216         CLAMP(input, 0.0f, 1.0f);