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