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