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