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