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