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