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