made editmode face copy menu appier with when there is no active face (without option...
[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         if (vertexCos) {
737                 EditVert *eve;
738
739                 for (i=0,eve=em->verts.first; eve; eve= eve->next)
740                         eve->tmp.l = (long) i++;
741
742                 for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
743                         MTFace *tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
744                         MCol *mcol= CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
745                         unsigned char *cp= NULL;
746                         int drawSmooth= (efa->flag & ME_SMOOTH);
747                         int flag;
748
749                         if(drawParams)
750                                 flag= drawParams(tf, mcol, efa->mat_nr);
751                         else if(drawParamsMapped)
752                                 flag= drawParamsMapped(userData, i);
753                         else
754                                 flag= 1;
755
756                         if(flag != 0) { /* flag 0 == the face is hidden or invisible */
757                                 if (flag==1 && mcol)
758                                         cp= (unsigned char*)mcol;
759
760                                 glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
761
762                                 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
763                                 if (!drawSmooth) {
764                                         glNormal3fv(emdm->faceNos[i]);
765
766                                         if(tf) glTexCoord2fv(tf->uv[0]);
767                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
768                                         glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
769
770                                         if(tf) glTexCoord2fv(tf->uv[1]);
771                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
772                                         glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
773
774                                         if(tf) glTexCoord2fv(tf->uv[2]);
775                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
776                                         glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
777
778                                         if(efa->v4) {
779                                                 if(tf) glTexCoord2fv(tf->uv[3]);
780                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
781                                                 glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
782                                         }
783                                 } else {
784                                         if(tf) glTexCoord2fv(tf->uv[0]);
785                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
786                                         glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
787                                         glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
788
789                                         if(tf) glTexCoord2fv(tf->uv[1]);
790                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
791                                         glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
792                                         glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
793
794                                         if(tf) glTexCoord2fv(tf->uv[2]);
795                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
796                                         glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
797                                         glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
798
799                                         if(efa->v4) {
800                                                 if(tf) glTexCoord2fv(tf->uv[3]);
801                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
802                                                 glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
803                                                 glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
804                                         }
805                                 }
806                                 glEnd();
807                         }
808                 }
809         } else {
810                 for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
811                         MTFace *tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
812                         MCol *mcol= CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
813                         unsigned char *cp= NULL;
814                         int drawSmooth= (efa->flag & ME_SMOOTH);
815                         int flag;
816
817                         if(drawParams)
818                                 flag= drawParams(tf, mcol, efa->mat_nr);
819                         else if(drawParamsMapped)
820                                 flag= drawParamsMapped(userData, i);
821                         else
822                                 flag= 1;
823
824                         if(flag != 0) { /* flag 0 == the face is hidden or invisible */
825                                 if (flag==1 && mcol)
826                                         cp= (unsigned char*)mcol;
827
828                                 glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
829
830                                 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
831                                 if (!drawSmooth) {
832                                         glNormal3fv(efa->n);
833
834                                         if(tf) glTexCoord2fv(tf->uv[0]);
835                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
836                                         glVertex3fv(efa->v1->co);
837
838                                         if(tf) glTexCoord2fv(tf->uv[1]);
839                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
840                                         glVertex3fv(efa->v2->co);
841
842                                         if(tf) glTexCoord2fv(tf->uv[2]);
843                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
844                                         glVertex3fv(efa->v3->co);
845
846                                         if(efa->v4) {
847                                                 if(tf) glTexCoord2fv(tf->uv[3]);
848                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
849                                                 glVertex3fv(efa->v4->co);
850                                         }
851                                 } else {
852                                         if(tf) glTexCoord2fv(tf->uv[0]);
853                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
854                                         glNormal3fv(efa->v1->no);
855                                         glVertex3fv(efa->v1->co);
856
857                                         if(tf) glTexCoord2fv(tf->uv[1]);
858                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
859                                         glNormal3fv(efa->v2->no);
860                                         glVertex3fv(efa->v2->co);
861
862                                         if(tf) glTexCoord2fv(tf->uv[2]);
863                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
864                                         glNormal3fv(efa->v3->no);
865                                         glVertex3fv(efa->v3->co);
866
867                                         if(efa->v4) {
868                                                 if(tf) glTexCoord2fv(tf->uv[3]);
869                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
870                                                 glNormal3fv(efa->v4->no);
871                                                 glVertex3fv(efa->v4->co);
872                                         }
873                                 }
874                                 glEnd();
875                         }
876                 }
877         }
878 }
879
880 static void emDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr))
881 {
882         emDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
883 }
884
885 static void emDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
886 {
887         emDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
888 }
889
890 static void emDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
891 {
892         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
893         EditVert *eve;
894         int i;
895
896         if (emdm->em->verts.first) {
897                 for (i=0,eve= emdm->em->verts.first; eve; i++,eve= eve->next) {
898                         if (emdm->vertexCos) {
899                                 DO_MINMAX(emdm->vertexCos[i], min_r, max_r);
900                         } else {
901                                 DO_MINMAX(eve->co, min_r, max_r);
902                         }
903                 }
904         } else {
905                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
906         }
907 }
908 static int emDM_getNumVerts(DerivedMesh *dm)
909 {
910         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
911
912         return BLI_countlist(&emdm->em->verts);
913 }
914
915 static int emDM_getNumEdges(DerivedMesh *dm)
916 {
917         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
918
919         return BLI_countlist(&emdm->em->edges);
920 }
921
922 static int emDM_getNumFaces(DerivedMesh *dm)
923 {
924         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
925
926         return BLI_countlist(&emdm->em->faces);
927 }
928
929 void emDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
930 {
931         EditVert *ev = ((EditMeshDerivedMesh *)dm)->em->verts.first;
932         int i;
933
934         for(i = 0; i < index; ++i) ev = ev->next;
935
936         VECCOPY(vert_r->co, ev->co);
937
938         vert_r->no[0] = ev->no[0] * 32767.0;
939         vert_r->no[1] = ev->no[1] * 32767.0;
940         vert_r->no[2] = ev->no[2] * 32767.0;
941
942         /* TODO what to do with vert_r->flag and vert_r->mat_nr? */
943         vert_r->mat_nr = 0;
944         vert_r->bweight = (unsigned char) (ev->bweight*255.0f);
945 }
946
947 void emDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
948 {
949         EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
950         EditEdge *ee = em->edges.first;
951         EditVert *ev, *v1, *v2;
952         int i;
953
954         for(i = 0; i < index; ++i) ee = ee->next;
955
956         edge_r->crease = (unsigned char) (ee->crease*255.0f);
957         edge_r->bweight = (unsigned char) (ee->bweight*255.0f);
958         /* TODO what to do with edge_r->flag? */
959         edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER;
960         if (ee->seam) edge_r->flag |= ME_SEAM;
961         if (ee->sharp) edge_r->flag |= ME_SHARP;
962 #if 0
963         /* this needs setup of f2 field */
964         if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE;
965 #endif
966
967         /* goddamn, we have to search all verts to find indices */
968         v1 = ee->v1;
969         v2 = ee->v2;
970         for(i = 0, ev = em->verts.first; v1 || v2; i++, ev = ev->next) {
971                 if(ev == v1) {
972                         edge_r->v1 = i;
973                         v1 = NULL;
974                 }
975                 if(ev == v2) {
976                         edge_r->v2 = i;
977                         v2 = NULL;
978                 }
979         }
980 }
981
982 void emDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
983 {
984         EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
985         EditFace *ef = em->faces.first;
986         EditVert *ev, *v1, *v2, *v3, *v4;
987         int i;
988
989         for(i = 0; i < index; ++i) ef = ef->next;
990
991         face_r->mat_nr = ef->mat_nr;
992         face_r->flag = ef->flag;
993
994         /* goddamn, we have to search all verts to find indices */
995         v1 = ef->v1;
996         v2 = ef->v2;
997         v3 = ef->v3;
998         v4 = ef->v4;
999         if(!v4) face_r->v4 = 0;
1000
1001         for(i = 0, ev = em->verts.first; v1 || v2 || v3 || v4;
1002             i++, ev = ev->next) {
1003                 if(ev == v1) {
1004                         face_r->v1 = i;
1005                         v1 = NULL;
1006                 }
1007                 if(ev == v2) {
1008                         face_r->v2 = i;
1009                         v2 = NULL;
1010                 }
1011                 if(ev == v3) {
1012                         face_r->v3 = i;
1013                         v3 = NULL;
1014                 }
1015                 if(ev == v4) {
1016                         face_r->v4 = i;
1017                         v4 = NULL;
1018                 }
1019         }
1020
1021         test_index_face(face_r, NULL, 0, ef->v4?4:3);
1022 }
1023
1024 void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
1025 {
1026         EditVert *ev = ((EditMeshDerivedMesh *)dm)->em->verts.first;
1027
1028         for( ; ev; ev = ev->next, ++vert_r) {
1029                 VECCOPY(vert_r->co, ev->co);
1030
1031                 vert_r->no[0] = ev->no[0] * 32767.0;
1032                 vert_r->no[1] = ev->no[1] * 32767.0;
1033                 vert_r->no[2] = ev->no[2] * 32767.0;
1034
1035                 /* TODO what to do with vert_r->flag and vert_r->mat_nr? */
1036                 vert_r->mat_nr = 0;
1037                 vert_r->flag = 0;
1038                 vert_r->bweight = (unsigned char) (ev->bweight*255.0f);
1039         }
1040 }
1041
1042 void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
1043 {
1044         EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
1045         EditEdge *ee = em->edges.first;
1046         EditVert *ev;
1047         int i;
1048
1049         /* store vertex indices in tmp union */
1050         for(ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
1051                 ev->tmp.l = (long) i++;
1052
1053         for( ; ee; ee = ee->next, ++edge_r) {
1054                 edge_r->crease = (unsigned char) (ee->crease*255.0f);
1055                 edge_r->bweight = (unsigned char) (ee->bweight*255.0f);
1056                 /* TODO what to do with edge_r->flag? */
1057                 edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER;
1058                 if (ee->seam) edge_r->flag |= ME_SEAM;
1059                 if (ee->sharp) edge_r->flag |= ME_SHARP;
1060 #if 0
1061                 /* this needs setup of f2 field */
1062                 if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE;
1063 #endif
1064
1065                 edge_r->v1 = (int)ee->v1->tmp.l;
1066                 edge_r->v2 = (int)ee->v2->tmp.l;
1067         }
1068 }
1069
1070 void emDM_copyFaceArray(DerivedMesh *dm, MFace *face_r)
1071 {
1072         EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
1073         EditFace *ef = em->faces.first;
1074         EditVert *ev;
1075         int i;
1076
1077         /* store vertexes indices in tmp union */
1078         for(ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
1079                 ev->tmp.l = (long) i;
1080
1081         for( ; ef; ef = ef->next, ++face_r) {
1082                 face_r->mat_nr = ef->mat_nr;
1083                 face_r->flag = ef->flag;
1084
1085                 face_r->v1 = (int)ef->v1->tmp.l;
1086                 face_r->v2 = (int)ef->v2->tmp.l;
1087                 face_r->v3 = (int)ef->v3->tmp.l;
1088                 if(ef->v4) face_r->v4 = (int)ef->v4->tmp.l;
1089                 else face_r->v4 = 0;
1090
1091                 test_index_face(face_r, NULL, 0, ef->v4?4:3);
1092         }
1093 }
1094
1095 static void emDM_release(DerivedMesh *dm)
1096 {
1097         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
1098
1099         if (DM_release(dm)) {
1100                 if (emdm->vertexCos) {
1101                         MEM_freeN(emdm->vertexCos);
1102                         MEM_freeN(emdm->vertexNos);
1103                         MEM_freeN(emdm->faceNos);
1104                 }
1105
1106                 MEM_freeN(emdm);
1107         }
1108 }
1109
1110 static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em, Object *ob,
1111                                            float (*vertexCos)[3])
1112 {
1113         EditMeshDerivedMesh *emdm = MEM_callocN(sizeof(*emdm), "emdm");
1114
1115         DM_init(&emdm->dm, BLI_countlist(&em->verts),
1116                          BLI_countlist(&em->edges), BLI_countlist(&em->faces));
1117
1118         emdm->dm.getMinMax = emDM_getMinMax;
1119
1120         emdm->dm.getNumVerts = emDM_getNumVerts;
1121         emdm->dm.getNumEdges = emDM_getNumEdges;
1122         emdm->dm.getNumFaces = emDM_getNumFaces;
1123
1124         emdm->dm.getVert = emDM_getVert;
1125         emdm->dm.getEdge = emDM_getEdge;
1126         emdm->dm.getFace = emDM_getFace;
1127         emdm->dm.copyVertArray = emDM_copyVertArray;
1128         emdm->dm.copyEdgeArray = emDM_copyEdgeArray;
1129         emdm->dm.copyFaceArray = emDM_copyFaceArray;
1130
1131         emdm->dm.foreachMappedVert = emDM_foreachMappedVert;
1132         emdm->dm.foreachMappedEdge = emDM_foreachMappedEdge;
1133         emdm->dm.foreachMappedFaceCenter = emDM_foreachMappedFaceCenter;
1134
1135         emdm->dm.drawEdges = emDM_drawEdges;
1136         emdm->dm.drawMappedEdges = emDM_drawMappedEdges;
1137         emdm->dm.drawMappedEdgesInterp = emDM_drawMappedEdgesInterp;
1138         emdm->dm.drawMappedFaces = emDM_drawMappedFaces;
1139         emdm->dm.drawMappedFacesTex = emDM_drawMappedFacesTex;
1140         emdm->dm.drawFacesTex = emDM_drawFacesTex;
1141         emdm->dm.drawUVEdges = emDM_drawUVEdges;
1142
1143         emdm->dm.release = emDM_release;
1144         
1145         emdm->em = em;
1146         emdm->vertexCos = vertexCos;
1147
1148         if(CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) {
1149                 EditVert *eve;
1150                 int i;
1151
1152                 DM_add_vert_layer(&emdm->dm, CD_MDEFORMVERT, CD_CALLOC, NULL);
1153
1154                 for(eve = em->verts.first, i = 0; eve; eve = eve->next, ++i)
1155                         DM_set_vert_data(&emdm->dm, i, CD_MDEFORMVERT,
1156                                          CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT));
1157         }
1158
1159         if(vertexCos) {
1160                 EditVert *eve;
1161                 EditFace *efa;
1162                 int totface = BLI_countlist(&em->faces);
1163                 int i;
1164
1165                 for (i=0,eve=em->verts.first; eve; eve= eve->next)
1166                         eve->tmp.l = (long) i++;
1167
1168                 emdm->vertexNos = MEM_callocN(sizeof(*emdm->vertexNos)*i, "emdm_vno");
1169                 emdm->faceNos = MEM_mallocN(sizeof(*emdm->faceNos)*totface, "emdm_vno");
1170
1171                 for(i=0, efa= em->faces.first; efa; i++, efa=efa->next) {
1172                         float *v1 = vertexCos[(int) efa->v1->tmp.l];
1173                         float *v2 = vertexCos[(int) efa->v2->tmp.l];
1174                         float *v3 = vertexCos[(int) efa->v3->tmp.l];
1175                         float *no = emdm->faceNos[i];
1176                         
1177                         if(efa->v4) {
1178                                 float *v4 = vertexCos[(int) efa->v4->tmp.l];
1179
1180                                 CalcNormFloat4(v1, v2, v3, v4, no);
1181                                 VecAddf(emdm->vertexNos[(int) efa->v4->tmp.l], emdm->vertexNos[(int) efa->v4->tmp.l], no);
1182                         }
1183                         else {
1184                                 CalcNormFloat(v1, v2, v3, no);
1185                         }
1186
1187                         VecAddf(emdm->vertexNos[(int) efa->v1->tmp.l], emdm->vertexNos[(int) efa->v1->tmp.l], no);
1188                         VecAddf(emdm->vertexNos[(int) efa->v2->tmp.l], emdm->vertexNos[(int) efa->v2->tmp.l], no);
1189                         VecAddf(emdm->vertexNos[(int) efa->v3->tmp.l], emdm->vertexNos[(int) efa->v3->tmp.l], no);
1190                 }
1191
1192                 for(i=0, eve= em->verts.first; eve; i++, eve=eve->next) {
1193                         float *no = emdm->vertexNos[i];
1194                         /* following Mesh convention; we use vertex coordinate itself
1195                          * for normal in this case */
1196                         if (Normalize(no)==0.0) {
1197                                 VECCOPY(no, vertexCos[i]);
1198                                 Normalize(no);
1199                         }
1200                 }
1201         }
1202
1203         return (DerivedMesh*) emdm;
1204 }
1205
1206 #ifdef WITH_VERSE
1207
1208 /* verse derived mesh */
1209 typedef struct {
1210         struct DerivedMesh dm;
1211         struct VNode *vnode;
1212         struct VLayer *vertex_layer;
1213         struct VLayer *polygon_layer;
1214         struct ListBase *edges;
1215         float (*vertexCos)[3];
1216 } VDerivedMesh;
1217
1218 /* this function set up border points of verse mesh bounding box */
1219 static void vDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
1220 {
1221         VDerivedMesh *vdm = (VDerivedMesh*)dm;
1222         struct VerseVert *vvert;
1223
1224         if(!vdm->vertex_layer) return;
1225
1226         vvert = (VerseVert*)vdm->vertex_layer->dl.lb.first;
1227
1228         if(vdm->vertex_layer->dl.da.count > 0) {
1229                 while(vvert) {
1230                         DO_MINMAX(vdm->vertexCos ? vvert->cos : vvert->co, min_r, max_r);
1231                         vvert = vvert->next;
1232                 }
1233         }
1234         else {
1235                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
1236         }
1237 }
1238
1239 /* this function return number of vertexes in vertex layer */
1240 static int vDM_getNumVerts(DerivedMesh *dm)
1241 {
1242         VDerivedMesh *vdm = (VDerivedMesh*)dm;
1243
1244         if(!vdm->vertex_layer) return 0;
1245         else return vdm->vertex_layer->dl.da.count;
1246 }
1247
1248 /* this function return number of 'fake' edges */
1249 static int vDM_getNumEdges(DerivedMesh *dm)
1250 {
1251         VDerivedMesh *vdm = (VDerivedMesh*)dm;
1252
1253         return BLI_countlist(vdm->edges);
1254 }
1255
1256 /* this function returns number of polygons in polygon layer */
1257 static int vDM_getNumFaces(DerivedMesh *dm)
1258 {
1259         VDerivedMesh *vdm = (VDerivedMesh*)dm;
1260
1261         if(!vdm->polygon_layer) return 0;
1262         else return vdm->polygon_layer->dl.da.count;
1263 }
1264
1265 /* this function doesn't return vertex with index of access array,
1266  * but it return 'indexth' vertex of dynamic list */
1267 void vDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
1268 {
1269         VDerivedMesh *vdm = (VDerivedMesh*)dm;
1270         struct VerseVert *vvert;
1271         int i;
1272
1273         if(!vdm->vertex_layer) return;
1274
1275         for(vvert = vdm->vertex_layer->dl.lb.first, i=0 ; i<index; i++) vvert = vvert->next;
1276
1277         if(vvert) {
1278                 VECCOPY(vert_r->co, vvert->co);
1279
1280                 vert_r->no[0] = vvert->no[0] * 32767.0;
1281                 vert_r->no[1] = vvert->no[1] * 32767.0;
1282                 vert_r->no[2] = vvert->no[2] * 32767.0;
1283
1284                 /* TODO what to do with vert_r->flag and vert_r->mat_nr? */
1285                 vert_r->mat_nr = 0;
1286                 vert_r->flag = 0;
1287         }
1288 }
1289
1290 /* this function returns fake verse edge */
1291 void vDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
1292 {
1293         VDerivedMesh *vdm = (VDerivedMesh*)dm;
1294         struct VerseEdge *vedge;
1295         struct VLayer *vert_vlayer = vdm->vertex_layer;
1296         struct VerseVert *vvert;
1297         int j;
1298
1299         if(!vdm->vertex_layer || !vdm->edges) return;
1300
1301         if(vdm->edges->first) {
1302                 struct VerseVert *vvert1, *vvert2;
1303
1304                 /* store vert indices in tmp union */
1305                 for(vvert = vdm->vertex_layer->dl.lb.first, j = 0; vvert; vvert = vvert->next, j++)
1306                         vvert->tmp.index = j;
1307
1308                 for(vedge = vdm->edges->first; vedge; vedge = vedge->next) {
1309                         if(vedge->tmp.index==index) {
1310                                 vvert1 = BLI_dlist_find_link(&(vert_vlayer->dl), (unsigned int)vedge->v0);
1311                                 vvert2 = BLI_dlist_find_link(&(vert_vlayer->dl), (unsigned int)vedge->v1);
1312                                 
1313                                 if(vvert1 && vvert2) {
1314                                         edge_r->v1 = vvert1->tmp.index;
1315                                         edge_r->v2 = vvert2->tmp.index;
1316                                 }
1317                                 else {
1318                                         edge_r->v1 = 0;
1319                                         edge_r->v2 = 0;
1320                                 }
1321                                 /* not supported yet */
1322                                 edge_r->flag = 0;
1323                                 edge_r->crease = 0;
1324                                 edge_r->bweight = 0;
1325                                 break;
1326                         }
1327                 }
1328         }
1329 }
1330
1331 /* this function doesn't return face with index of access array,
1332  * but it returns 'indexth' vertex of dynamic list */
1333 void vDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
1334 {
1335         VDerivedMesh *vdm = (VDerivedMesh*)dm;
1336         struct VerseFace *vface;
1337         struct VerseVert *vvert;
1338         struct VerseVert *vvert0, *vvert1, *vvert2, *vvert3;
1339         int i;
1340
1341         if(!vdm->vertex_layer || !vdm->polygon_layer) return;
1342
1343         for(vface = vdm->polygon_layer->dl.lb.first, i = 0; i < index; ++i) vface = vface->next;
1344
1345         face_r->mat_nr = 0;
1346         face_r->flag = 0;
1347
1348         /* goddamn, we have to search all verts to find indices */
1349         vvert0 = vface->vvert0;
1350         vvert1 = vface->vvert1;
1351         vvert2 = vface->vvert2;
1352         vvert3 = vface->vvert3;
1353         if(!vvert3) face_r->v4 = 0;
1354
1355         for(vvert = vdm->vertex_layer->dl.lb.first, i = 0; vvert0 || vvert1 || vvert2 || vvert3; i++, vvert = vvert->next) {
1356                 if(vvert == vvert0) {
1357                         face_r->v1 = i;
1358                         vvert0 = NULL;
1359                 }
1360                 if(vvert == vvert1) {
1361                         face_r->v2 = i;
1362                         vvert1 = NULL;
1363                 }
1364                 if(vvert == vvert2) {
1365                         face_r->v3 = i;
1366                         vvert2 = NULL;
1367                 }
1368                 if(vvert == vvert3) {
1369                         face_r->v4 = i;
1370                         vvert3 = NULL;
1371                 }
1372         }
1373
1374         test_index_face(face_r, NULL, 0, vface->vvert3?4:3);
1375 }
1376
1377 /* fill array of mvert */
1378 void vDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
1379 {
1380         VDerivedMesh *vdm = (VDerivedMesh*)dm;
1381         struct VerseVert *vvert;
1382
1383         if(!vdm->vertex_layer) return;
1384
1385         for(vvert = vdm->vertex_layer->dl.lb.first ; vvert; vvert = vvert->next, ++vert_r) {
1386                 VECCOPY(vert_r->co, vvert->co);
1387
1388                 vert_r->no[0] = vvert->no[0] * 32767.0;
1389                 vert_r->no[1] = vvert->no[1] * 32767.0;
1390                 vert_r->no[2] = vvert->no[2] * 32767.0;
1391
1392                 vert_r->mat_nr = 0;
1393                 vert_r->flag = 0;
1394         }
1395 }
1396
1397 /* dummy function, edges arent supported in verse mesh */
1398 void vDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
1399 {
1400         VDerivedMesh *vdm = (VDerivedMesh*)dm;
1401
1402         if(!vdm->vertex_layer || !vdm->edges) return;
1403
1404         if(vdm->edges->first) {
1405                 struct VerseEdge *vedge;
1406                 struct VLayer *vert_vlayer = vdm->vertex_layer;
1407                 struct VerseVert *vvert, *vvert1, *vvert2;
1408                 int j;
1409
1410                 /* store vert indices in tmp union */
1411                 for(vvert = vdm->vertex_layer->dl.lb.first, j = 0; vvert; vvert = vvert->next, ++j)
1412                         vvert->tmp.index = j;
1413
1414                 for(vedge = vdm->edges->first, j=0 ; vedge; vedge = vedge->next, ++edge_r, j++) {
1415                         /* create temporary edge index */
1416                         vedge->tmp.index = j;
1417                         vvert1 = BLI_dlist_find_link(&(vert_vlayer->dl), (unsigned int)vedge->v0);
1418                         vvert2 = BLI_dlist_find_link(&(vert_vlayer->dl), (unsigned int)vedge->v1);
1419                         if(vvert1 && vvert2) {
1420                                 edge_r->v1 = vvert1->tmp.index;
1421                                 edge_r->v2 = vvert2->tmp.index;
1422                         }
1423                         else {
1424                                 printf("error: vDM_copyEdgeArray: %d, %d\n", vedge->v0, vedge->v1);
1425                                 edge_r->v1 = 0;
1426                                 edge_r->v2 = 0;
1427                         }
1428                         /* not supported yet */
1429                         edge_r->flag = 0;
1430                         edge_r->crease = 0;
1431                         edge_r->bweight = 0;
1432                 }
1433         }
1434 }
1435
1436 /* fill array of mfaces */
1437 void vDM_copyFaceArray(DerivedMesh *dm, MFace *face_r)
1438 {
1439         VDerivedMesh *vdm = (VDerivedMesh*)dm;
1440         struct VerseFace *vface;
1441         struct VerseVert *vvert;
1442         int i;
1443         
1444         if(!vdm->vertex_layer || !vdm->polygon_layer) return;
1445         
1446         /* store vertexes indices in tmp union */
1447         for(vvert = vdm->vertex_layer->dl.lb.first, i = 0; vvert; vvert = vvert->next, ++i)
1448                 vvert->tmp.index = i;
1449
1450         for(vface = vdm->polygon_layer->dl.lb.first; vface; vface = vface->next, ++face_r) {
1451                 face_r->mat_nr = 0;
1452                 face_r->flag = 0;
1453
1454                 face_r->v1 = vface->vvert0->tmp.index;
1455                 face_r->v2 = vface->vvert1->tmp.index;
1456                 face_r->v3 = vface->vvert2->tmp.index;
1457                 if(vface->vvert3) face_r->v4 = vface->vvert3->tmp.index;
1458                 else face_r->v4 = 0;
1459
1460                 test_index_face(face_r, NULL, 0, vface->vvert3?4:3);
1461         }
1462 }
1463
1464 /* return coordination of vertex with index */
1465 static void vDM_getVertCo(DerivedMesh *dm, int index, float co_r[3])
1466 {
1467         VDerivedMesh *vdm = (VDerivedMesh*)dm;
1468         struct VerseVert *vvert = NULL;
1469
1470         if(!vdm->vertex_layer) return;
1471
1472         vvert = BLI_dlist_find_link(&(vdm->vertex_layer->dl), index);
1473         
1474         if(vvert) {
1475                 VECCOPY(co_r, vdm->vertexCos ? vvert->cos : vvert->co);
1476         }
1477         else {
1478                 co_r[0] = co_r[1] = co_r[2] = 0.0;
1479         }
1480 }
1481
1482 /* return array of vertex coordiantions */
1483 static void vDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
1484 {
1485         VDerivedMesh *vdm = (VDerivedMesh*)dm;
1486         struct VerseVert *vvert;
1487         int i = 0;
1488
1489         if(!vdm->vertex_layer) return;
1490
1491         vvert = vdm->vertex_layer->dl.lb.first;
1492         while(vvert) {
1493                 VECCOPY(cos_r[i], vdm->vertexCos ? vvert->cos : vvert->co);
1494                 i++;
1495                 vvert = vvert->next;
1496         }
1497 }
1498
1499 /* return normal of vertex with index */
1500 static void vDM_getVertNo(DerivedMesh *dm, int index, float no_r[3])
1501 {
1502         VDerivedMesh *vdm = (VDerivedMesh*)dm;
1503         struct VerseVert *vvert = NULL;
1504
1505         if(!vdm->vertex_layer) return;
1506
1507         vvert = BLI_dlist_find_link(&(vdm->vertex_layer->dl), index);
1508         if(vvert) {
1509                 VECCOPY(no_r, vvert->no);
1510         }
1511         else {
1512                 no_r[0] = no_r[1] = no_r[2] = 0.0;
1513         }
1514 }
1515
1516 /* draw all VerseVertexes */
1517 static void vDM_drawVerts(DerivedMesh *dm)
1518 {
1519         VDerivedMesh *vdm = (VDerivedMesh*)dm;
1520         struct VerseVert *vvert;
1521
1522         if(!vdm->vertex_layer) return;
1523
1524         vvert = vdm->vertex_layer->dl.lb.first;
1525
1526         bglBegin(GL_POINTS);
1527         while(vvert) {
1528                 bglVertex3fv(vdm->vertexCos ? vvert->cos : vvert->co);
1529                 vvert = vvert->next;
1530         }
1531         bglEnd();
1532 }
1533
1534 /* draw all edges of VerseFaces ... it isn't optimal, because verse
1535  * specification doesn't support edges :-( ... bother eskil ;-)
1536  * ... some edges (most of edges) are drawn twice */
1537 static void vDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
1538 {
1539         VDerivedMesh *vdm = (VDerivedMesh*)dm;
1540         struct VerseEdge *vedge;
1541         struct VLayer *vert_vlayer = vdm->vertex_layer;
1542
1543         if(vert_vlayer && vdm->edges && (BLI_countlist(vdm->edges) > 0)) {
1544                 struct VerseVert *vvert1, *vvert2;
1545
1546                 glBegin(GL_LINES);
1547                 for(vedge = vdm->edges->first; vedge; vedge = vedge->next) {
1548                         vvert1 = BLI_dlist_find_link(&(vert_vlayer->dl), (unsigned int)vedge->v0);
1549                         vvert2 = BLI_dlist_find_link(&(vert_vlayer->dl), (unsigned int)vedge->v1);
1550                         if(vvert1 && vvert2) {
1551                                 glVertex3fv(vdm->vertexCos ? vvert1->cos : vvert1->co);
1552                                 glVertex3fv(vdm->vertexCos ? vvert2->cos : vvert2->co);
1553                         }
1554                 }
1555                 glEnd();
1556         }
1557 }
1558
1559 /* verse spec doesn't support edges ... loose edges can't exist */
1560 void vDM_drawLooseEdges(DerivedMesh *dm)
1561 {
1562 }
1563
1564 /* draw uv edges, not supported yet */
1565 static void vDM_drawUVEdges(DerivedMesh *dm)
1566 {
1567 }
1568
1569 /* draw all VerseFaces */
1570 static void vDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int))
1571 {
1572         VDerivedMesh *vdm = (VDerivedMesh*)dm;
1573         struct VerseFace *vface;
1574
1575         if(!vdm->polygon_layer) return;
1576
1577         vface = vdm->polygon_layer->dl.lb.first;
1578
1579         glShadeModel(GL_FLAT);
1580         while(vface) {
1581                 glBegin(vface->vvert3?GL_QUADS:GL_TRIANGLES);
1582                 glNormal3fv(vface->no);
1583                 glVertex3fv(vdm->vertexCos ? vface->vvert0->cos : vface->vvert0->co);
1584                 glVertex3fv(vdm->vertexCos ? vface->vvert1->cos : vface->vvert1->co);
1585                 glVertex3fv(vdm->vertexCos ? vface->vvert2->cos : vface->vvert2->co);
1586                 if(vface->vvert3)
1587                         glVertex3fv(vdm->vertexCos ? vface->vvert3->cos : vface->vvert3->co);
1588                 glEnd();
1589                 vface = vface->next;
1590         }
1591 }
1592
1593 /* this function should draw mesh with mapped texture, but it isn't supported yet */
1594 static void vDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr))
1595 {
1596         VDerivedMesh *vdm = (VDerivedMesh*)dm;
1597         struct VerseFace *vface;
1598
1599         if(!vdm->polygon_layer) return;
1600
1601         vface = vdm->polygon_layer->dl.lb.first;
1602
1603         while(vface) {
1604                 glBegin(vface->vvert3?GL_QUADS:GL_TRIANGLES);
1605                 glVertex3fv(vdm->vertexCos ? vface->vvert0->cos : vface->vvert0->co);
1606                 glVertex3fv(vdm->vertexCos ? vface->vvert1->cos : vface->vvert1->co);
1607                 glVertex3fv(vdm->vertexCos ? vface->vvert2->cos : vface->vvert2->co);
1608                 if(vface->vvert3)
1609                         glVertex3fv(vdm->vertexCos ? vface->vvert3->cos : vface->vvert3->co);
1610                 glEnd();
1611
1612                 vface = vface->next;
1613         }
1614 }
1615
1616 /* this function should draw mesh with colored faces (weight paint, vertex
1617  * colors, etc.), but it isn't supported yet */
1618 static void vDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *col1, unsigned char *col2)
1619 {
1620         VDerivedMesh *vdm = (VDerivedMesh*)dm;
1621         struct VerseFace *vface;
1622
1623         if(!vdm->polygon_layer) return;
1624
1625         vface = vdm->polygon_layer->dl.lb.first;
1626
1627         while(vface) {
1628                 glBegin(vface->vvert3?GL_QUADS:GL_TRIANGLES);
1629                 glVertex3fv(vdm->vertexCos ? vface->vvert0->cos : vface->vvert0->co);
1630                 glVertex3fv(vdm->vertexCos ? vface->vvert1->cos : vface->vvert1->co);
1631                 glVertex3fv(vdm->vertexCos ? vface->vvert2->cos : vface->vvert2->co);
1632                 if(vface->vvert3)
1633                         glVertex3fv(vdm->vertexCos ? vface->vvert3->cos : vface->vvert3->co);
1634                 glEnd();
1635
1636                 vface = vface->next;
1637         }
1638 }
1639
1640 /**/
1641 static void vDM_foreachMappedVert(
1642                 DerivedMesh *dm,
1643                 void (*func)(void *userData, int index, float *co, float *no_f, short *no_s),
1644                 void *userData)
1645 {
1646 }
1647
1648 /**/
1649 static void vDM_foreachMappedEdge(
1650                 DerivedMesh *dm,
1651                 void (*func)(void *userData, int index, float *v0co, float *v1co),
1652                 void *userData)
1653 {
1654 }
1655
1656 /**/
1657 static void vDM_foreachMappedFaceCenter(
1658                 DerivedMesh *dm,
1659                 void (*func)(void *userData, int index, float *cent, float *no),
1660                 void *userData)
1661 {
1662 }
1663
1664 /**/
1665 static void vDM_drawMappedFacesTex(
1666                 DerivedMesh *dm,
1667                 int (*setDrawParams)(void *userData, int index),
1668                 void *userData)
1669 {
1670 }
1671
1672 /**/
1673 static void vDM_drawMappedFaces(
1674                 DerivedMesh *dm,
1675                 int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r),
1676                 void *userData,
1677                 int useColors)
1678 {
1679 }
1680
1681 /**/
1682 static void vDM_drawMappedEdges(
1683                 DerivedMesh *dm,
1684                 int (*setDrawOptions)(void *userData, int index),
1685                 void *userData)
1686 {
1687 }
1688
1689 /**/
1690 static void vDM_drawMappedEdgesInterp(
1691                 DerivedMesh *dm, 
1692                 int (*setDrawOptions)(void *userData, int index), 
1693                 void (*setDrawInterpOptions)(void *userData, int index, float t),
1694                 void *userData)
1695 {
1696 }
1697
1698 /* free all DerivedMesh data */
1699 static void vDM_release(DerivedMesh *dm)
1700 {
1701         VDerivedMesh *vdm = (VDerivedMesh*)dm;
1702
1703         if (DM_release(dm)) {
1704                 if(vdm->vertexCos) MEM_freeN(vdm->vertexCos);
1705                 MEM_freeN(vdm);
1706         }
1707 }
1708
1709 /* create derived mesh from verse mesh ... it is used in object mode, when some other client can
1710  * change shared data and want to see this changes in real time too */
1711 DerivedMesh *derivedmesh_from_versemesh(VNode *vnode, float (*vertexCos)[3])
1712 {
1713         VDerivedMesh *vdm = MEM_callocN(sizeof(*vdm), "vdm");
1714
1715         vdm->vnode = vnode;
1716         vdm->vertex_layer = find_verse_layer_type((VGeomData*)vnode->data, VERTEX_LAYER);
1717         vdm->polygon_layer = find_verse_layer_type((VGeomData*)vnode->data, POLYGON_LAYER);
1718         vdm->edges = &((VGeomData*)vnode->data)->edges;
1719
1720         /* vertex and polygon layer has to exist */
1721         if(vdm->vertex_layer && vdm->polygon_layer)
1722                 DM_init(&vdm->dm, vdm->vertex_layer->dl.da.count, BLI_countlist(vdm->edges), vdm->polygon_layer->dl.da.count);
1723         else
1724                 DM_init(&vdm->dm, 0, 0, 0);
1725         
1726         vdm->dm.getMinMax = vDM_getMinMax;
1727
1728         vdm->dm.getNumVerts = vDM_getNumVerts;
1729         vdm->dm.getNumEdges = vDM_getNumEdges;
1730         vdm->dm.getNumFaces = vDM_getNumFaces;
1731
1732         vdm->dm.getVert = vDM_getVert;
1733         vdm->dm.getEdge = vDM_getEdge;
1734         vdm->dm.getFace = vDM_getFace;
1735         vdm->dm.copyVertArray = vDM_copyVertArray;
1736         vdm->dm.copyEdgeArray = vDM_copyEdgeArray;
1737         vdm->dm.copyFaceArray = vDM_copyFaceArray;
1738         
1739         vdm->dm.foreachMappedVert = vDM_foreachMappedVert;
1740         vdm->dm.foreachMappedEdge = vDM_foreachMappedEdge;
1741         vdm->dm.foreachMappedFaceCenter = vDM_foreachMappedFaceCenter;
1742
1743         vdm->dm.getVertCos = vDM_getVertCos;
1744         vdm->dm.getVertCo = vDM_getVertCo;
1745         vdm->dm.getVertNo = vDM_getVertNo;
1746
1747         vdm->dm.drawVerts = vDM_drawVerts;
1748
1749         vdm->dm.drawEdges = vDM_drawEdges;
1750         vdm->dm.drawLooseEdges = vDM_drawLooseEdges;
1751         vdm->dm.drawUVEdges = vDM_drawUVEdges;
1752
1753         vdm->dm.drawFacesSolid = vDM_drawFacesSolid;
1754         vdm->dm.drawFacesTex = vDM_drawFacesTex;
1755         vdm->dm.drawFacesColored = vDM_drawFacesColored;
1756
1757         vdm->dm.drawMappedFacesTex = vDM_drawMappedFacesTex;
1758         vdm->dm.drawMappedFaces = vDM_drawMappedFaces;
1759         vdm->dm.drawMappedEdges = vDM_drawMappedEdges;
1760         vdm->dm.drawMappedEdgesInterp = vDM_drawMappedEdgesInterp;
1761
1762         vdm->dm.release = vDM_release;
1763
1764         vdm->vertexCos = vertexCos;
1765
1766         return (DerivedMesh*) vdm;
1767 }
1768
1769 #endif
1770
1771 /***/
1772
1773 DerivedMesh *mesh_create_derived_for_modifier(Object *ob, ModifierData *md)
1774 {
1775         Mesh *me = ob->data;
1776         ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1777         DerivedMesh *dm;
1778
1779         if (!(md->mode&eModifierMode_Realtime)) return NULL;
1780         if (mti->isDisabled && mti->isDisabled(md)) return NULL;
1781
1782         if (mti->type==eModifierTypeType_OnlyDeform) {
1783                 int numVerts;
1784                 float (*deformedVerts)[3] = mesh_getVertexCos(me, &numVerts);
1785
1786                 mti->deformVerts(md, ob, NULL, deformedVerts, numVerts);
1787 #ifdef WITH_VERSE
1788                 if(me->vnode) dm = derivedmesh_from_versemesh(me->vnode, deformedVerts);
1789                 else dm = getMeshDerivedMesh(me, ob, deformedVerts);
1790 #else
1791                 dm = getMeshDerivedMesh(me, ob, deformedVerts);
1792 #endif
1793
1794                 MEM_freeN(deformedVerts);
1795         } else {
1796                 DerivedMesh *tdm = getMeshDerivedMesh(me, ob, NULL);
1797                 dm = mti->applyModifier(md, ob, tdm, 0, 0);
1798
1799                 if(tdm != dm) tdm->release(tdm);
1800         }
1801
1802         return dm;
1803 }
1804
1805 CustomDataMask get_viewedit_datamask()
1806 {
1807         CustomDataMask mask = CD_MASK_BAREMESH;
1808         ScrArea *sa;
1809
1810         /* check if we need tfaces & mcols due to face select or texture paint */
1811         if(FACESEL_PAINT_TEST || G.f & G_TEXTUREPAINT) {
1812                 mask |= CD_MASK_MTFACE | CD_MASK_MCOL;
1813         } else {
1814                 /* check if we need tfaces & mcols due to view mode */
1815                 for(sa = G.curscreen->areabase.first; sa; sa = sa->next) {
1816                         if(sa->spacetype == SPACE_VIEW3D) {
1817                                 View3D *view = sa->spacedata.first;
1818                                 if(view->drawtype == OB_SHADED) {
1819                                         /* this includes normals for mesh_create_shadedColors */
1820                                         mask |= CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_NORMAL | CD_MASK_ORCO;
1821                                 }
1822                                 if((view->drawtype == OB_TEXTURE) || ((view->drawtype == OB_SOLID) && (view->flag2 & V3D_SOLID_TEX))) {
1823                                         mask |= CD_MASK_MTFACE | CD_MASK_MCOL;
1824                                 }
1825                         }
1826                 }
1827         }
1828
1829         /* check if we need mcols due to vertex paint or weightpaint */
1830         if(G.f & G_VERTEXPAINT || G.f & G_WEIGHTPAINT)
1831                 mask |= CD_MASK_MCOL;
1832
1833         return mask;
1834 }
1835
1836 static DerivedMesh *create_orco_dm(Object *ob, Mesh *me)
1837 {
1838         DerivedMesh *dm;
1839         float (*orco)[3];
1840
1841         dm= CDDM_from_mesh(me, ob);
1842         orco= (float(*)[3])get_mesh_orco_verts(ob);
1843         CDDM_apply_vert_coords(dm, orco);
1844         CDDM_calc_normals(dm);
1845         MEM_freeN(orco);
1846
1847         return dm;
1848 }
1849
1850 static void add_orco_dm(Object *ob, DerivedMesh *dm, DerivedMesh *orcodm)
1851 {
1852         float (*orco)[3], (*layerorco)[3];
1853         int totvert;
1854
1855         totvert= dm->getNumVerts(dm);
1856
1857         if(orcodm) {
1858                 orco= MEM_callocN(sizeof(float)*3*totvert, "dm orco");
1859
1860                 if(orcodm->getNumVerts(orcodm) == totvert)
1861                         orcodm->getVertCos(orcodm, orco);
1862                 else
1863                         dm->getVertCos(dm, orco);
1864         }
1865         else
1866                 orco= (float(*)[3])get_mesh_orco_verts(ob);
1867
1868         transform_mesh_orco_verts(ob->data, orco, totvert, 0);
1869
1870         if((layerorco = DM_get_vert_data_layer(dm, CD_ORCO))) {
1871                 memcpy(layerorco, orco, sizeof(float)*totvert);
1872                 MEM_freeN(orco);
1873         }
1874         else
1875                 DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, orco);
1876 }
1877
1878 static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
1879                                 DerivedMesh **deform_r, DerivedMesh **final_r,
1880                                 int useRenderParams, int useDeform,
1881                                 int needMapping, CustomDataMask dataMask)
1882 {
1883         Mesh *me = ob->data;
1884         ModifierData *firstmd, *md;
1885         LinkNode *datamasks, *curr;
1886         CustomDataMask mask;
1887         float (*deformedVerts)[3] = NULL;
1888         DerivedMesh *dm, *orcodm, *finaldm;
1889         int numVerts = me->totvert;
1890         int fluidsimMeshUsed = 0;
1891         int required_mode;
1892
1893         md = firstmd = modifiers_getVirtualModifierList(ob);
1894
1895         modifiers_clearErrors(ob);
1896
1897         /* we always want to keep original indices */
1898         dataMask |= CD_MASK_ORIGINDEX;
1899
1900         datamasks = modifiers_calcDataMasks(md, dataMask);
1901         curr = datamasks;
1902
1903         if(deform_r) *deform_r = NULL;
1904         *final_r = NULL;
1905
1906         /* replace original mesh by fluidsim surface mesh for fluidsim
1907          * domain objects
1908          */
1909         if((G.obedit!=ob) && !needMapping) {
1910                 if((ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) &&
1911                    (1) && (!give_parteff(ob)) ) { // doesnt work together with particle systems!
1912                         if(ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN) {
1913                                 loadFluidsimMesh(ob,useRenderParams);
1914                                 fluidsimMeshUsed = 1;
1915                                 /* might have changed... */
1916                                 me = ob->data;
1917                                 numVerts = me->totvert;
1918                         }
1919                 }
1920         }
1921
1922         if(useRenderParams) required_mode = eModifierMode_Render;
1923         else required_mode = eModifierMode_Realtime;
1924
1925         if(useDeform) {
1926                 if(do_ob_key(ob)) /* shape key makes deform verts */
1927                         deformedVerts = mesh_getVertexCos(me, &numVerts);
1928                 
1929                 /* Apply all leading deforming modifiers */
1930                 for(; md; md = md->next, curr = curr->next) {
1931                         ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1932
1933                         if((md->mode & required_mode) != required_mode) continue;
1934                         if(mti->isDisabled && mti->isDisabled(md)) continue;
1935
1936                         if(mti->type == eModifierTypeType_OnlyDeform) {
1937                                 if(!deformedVerts)
1938                                         deformedVerts = mesh_getVertexCos(me, &numVerts);
1939
1940                                 mti->deformVerts(md, ob, NULL, deformedVerts, numVerts);
1941                         } else {
1942                                 break;
1943                         }
1944                 }
1945
1946                 /* Result of all leading deforming modifiers is cached for
1947                  * places that wish to use the original mesh but with deformed
1948                  * coordinates (vpaint, etc.)
1949                  */
1950                 if (deform_r) {
1951 #ifdef WITH_VERSE
1952                         if(me->vnode) *deform_r = derivedmesh_from_versemesh(me->vnode, deformedVerts);
1953                         else {
1954                                 *deform_r = CDDM_from_mesh(me, ob);
1955                                 if(deformedVerts) {
1956                                         CDDM_apply_vert_coords(*deform_r, deformedVerts);
1957                                         CDDM_calc_normals(*deform_r);
1958                                 }
1959                         }
1960 #else
1961                         *deform_r = CDDM_from_mesh(me, ob);
1962                         if(deformedVerts) {
1963                                 CDDM_apply_vert_coords(*deform_r, deformedVerts);
1964                                 CDDM_calc_normals(*deform_r);
1965                         }
1966 #endif
1967                 }
1968         } else {
1969                 if(!fluidsimMeshUsed) {
1970                         /* default behaviour for meshes */
1971                         if(inputVertexCos)
1972                                 deformedVerts = inputVertexCos;
1973                         else
1974                                 deformedVerts = mesh_getRefKeyCos(me, &numVerts);
1975                 } else {
1976                         /* the fluid sim mesh might have more vertices than the original 
1977                          * one, so inputVertexCos shouldnt be used
1978                          */
1979                         deformedVerts = mesh_getVertexCos(me, &numVerts);
1980                 }
1981         }
1982
1983
1984         /* Now apply all remaining modifiers. If useDeform is off then skip
1985          * OnlyDeform ones. 
1986          */
1987         dm = NULL;
1988         orcodm = NULL;
1989
1990 #ifdef WITH_VERSE
1991         /* hack to make sure modifiers don't try to use mesh data from a verse
1992          * node
1993          */
1994         if(me->vnode) dm = derivedmesh_from_versemesh(me->vnode, deformedVerts);
1995 #endif
1996
1997         for(; md; md = md->next, curr = curr->next) {
1998                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1999
2000                 if((md->mode & required_mode) != required_mode) continue;
2001                 if(mti->type == eModifierTypeType_OnlyDeform && !useDeform) continue;
2002                 if((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) {
2003                         modifier_setError(md, "Internal error, modifier requires "
2004                                           "original data (bad stack position).");
2005                         continue;
2006                 }
2007                 if(mti->isDisabled && mti->isDisabled(md)) continue;
2008                 if(needMapping && !modifier_supportsMapping(md)) continue;
2009
2010                 /* add an orco layer if needed by this modifier */
2011                 if(dm && mti->requiredDataMask) {
2012                         mask = mti->requiredDataMask(md);
2013                         if(mask & CD_MASK_ORCO)
2014                                 add_orco_dm(ob, dm, orcodm);
2015                 }
2016
2017                 /* How to apply modifier depends on (a) what we already have as
2018                  * a result of previous modifiers (could be a DerivedMesh or just
2019                  * deformed vertices) and (b) what type the modifier is.
2020                  */
2021
2022                 if(mti->type == eModifierTypeType_OnlyDeform) {
2023                         
2024                         /* No existing verts to deform, need to build them. */
2025                         if(!deformedVerts) {
2026                                 if(dm) {
2027                                         /* Deforming a derived mesh, read the vertex locations
2028                                          * out of the mesh and deform them. Once done with this
2029                                          * run of deformers verts will be written back.
2030                                          */
2031                                         numVerts = dm->getNumVerts(dm);
2032                                         deformedVerts =
2033                                             MEM_mallocN(sizeof(*deformedVerts) * numVerts, "dfmv");
2034                                         dm->getVertCos(dm, deformedVerts);
2035                                 } else {
2036                                         deformedVerts = mesh_getVertexCos(me, &numVerts);
2037                                 }
2038                         }
2039
2040                         mti->deformVerts(md, ob, dm, deformedVerts, numVerts);
2041                 } else {
2042                         DerivedMesh *ndm;
2043
2044                         /* apply vertex coordinates or build a DerivedMesh as necessary */
2045                         if(dm) {
2046                                 if(deformedVerts) {
2047                                         DerivedMesh *tdm = CDDM_copy(dm);
2048                                         dm->release(dm);
2049                                         dm = tdm;
2050
2051                                         CDDM_apply_vert_coords(dm, deformedVerts);
2052                                         CDDM_calc_normals(dm);
2053                                 }
2054                         } else {
2055                                 dm = CDDM_from_mesh(me, ob);
2056
2057                                 if(deformedVerts) {
2058                                         CDDM_apply_vert_coords(dm, deformedVerts);
2059                                         CDDM_calc_normals(dm);
2060                                 }
2061                         }
2062
2063                         /* create an orco derivedmesh in parallel */
2064                         mask= (CustomDataMask)curr->link;
2065                         if(mask & CD_MASK_ORCO) {
2066                                 if(!orcodm)
2067                                         orcodm= create_orco_dm(ob, me);
2068
2069                                 mask &= ~CD_MASK_ORCO;
2070                                 DM_set_only_copy(orcodm, mask);
2071                                 ndm = mti->applyModifier(md, ob, orcodm, useRenderParams, !inputVertexCos);
2072
2073                                 if(ndm) {
2074                                         /* if the modifier returned a new dm, release the old one */
2075                                         if(orcodm && orcodm != ndm) orcodm->release(orcodm);
2076                                         orcodm = ndm;
2077                                 }
2078                         }
2079
2080                         /* set the DerivedMesh to only copy needed data */
2081                         DM_set_only_copy(dm, mask);
2082                         
2083                         /* add an origspace layer if needed */
2084                         if(((CustomDataMask)curr->link) & CD_MASK_ORIGSPACE)
2085                                 if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE))
2086                                         DM_add_face_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL);
2087
2088                         ndm = mti->applyModifier(md, ob, dm, useRenderParams, !inputVertexCos);
2089
2090                         if(ndm) {
2091                                 /* if the modifier returned a new dm, release the old one */
2092                                 if(dm && dm != ndm) dm->release(dm);
2093
2094                                 dm = ndm;
2095
2096                                 if(deformedVerts) {
2097                                         if(deformedVerts != inputVertexCos)
2098                                                 MEM_freeN(deformedVerts);
2099
2100                                         deformedVerts = NULL;
2101                                 }
2102                         } 
2103                 }
2104         }
2105
2106         for(md=firstmd; md; md=md->next)
2107                 modifier_freeTemporaryData(md);
2108
2109         /* Yay, we are done. If we have a DerivedMesh and deformed vertices
2110          * need to apply these back onto the DerivedMesh. If we have no
2111          * DerivedMesh then we need to build one.
2112          */
2113         if(dm && deformedVerts) {
2114                 finaldm = CDDM_copy(dm);
2115
2116                 dm->release(dm);
2117
2118                 CDDM_apply_vert_coords(finaldm, deformedVerts);
2119                 CDDM_calc_normals(finaldm);
2120         } else if(dm) {
2121                 finaldm = dm;
2122         } else {
2123 #ifdef WITH_VERSE
2124                 if(me->vnode)
2125                         finaldm = derivedmesh_from_versemesh(me->vnode, deformedVerts);
2126                 else {
2127                         finaldm = CDDM_from_mesh(me, ob);
2128                         if(deformedVerts) {
2129                                 CDDM_apply_vert_coords(finaldm, deformedVerts);
2130                                 CDDM_calc_normals(finaldm);
2131                         }
2132                 }
2133 #else
2134                 finaldm = CDDM_from_mesh(me, ob);
2135                 if(deformedVerts) {
2136                         CDDM_apply_vert_coords(finaldm, deformedVerts);
2137                         CDDM_calc_normals(finaldm);
2138                 }
2139 #endif
2140         }
2141
2142         /* add an orco layer if needed */
2143         if(dataMask & CD_MASK_ORCO) {
2144                 add_orco_dm(ob, finaldm, orcodm);
2145
2146                 if(deform_r && *deform_r)
2147                         add_orco_dm(ob, *deform_r, NULL);
2148         }
2149
2150         *final_r = finaldm;
2151
2152         if(orcodm)
2153                 orcodm->release(orcodm);
2154
2155         if(deformedVerts && deformedVerts != inputVertexCos)
2156                 MEM_freeN(deformedVerts);
2157
2158         BLI_linklist_free(datamasks, NULL);
2159
2160         /* restore mesh in any case */
2161         if(fluidsimMeshUsed) ob->data = ob->fluidsimSettings->orgMesh;
2162 }
2163
2164 static float (*editmesh_getVertexCos(EditMesh *em, int *numVerts_r))[3]
2165 {
2166         int i, numVerts = *numVerts_r = BLI_countlist(&em->verts);
2167         float (*cos)[3];
2168         EditVert *eve;
2169
2170         cos = MEM_mallocN(sizeof(*cos)*numVerts, "vertexcos");
2171         for (i=0,eve=em->verts.first; i<numVerts; i++,eve=eve->next) {
2172                 VECCOPY(cos[i], eve->co);
2173         }
2174
2175         return cos;
2176 }
2177
2178 static int editmesh_modifier_is_enabled(ModifierData *md, DerivedMesh *dm)
2179 {
2180         ModifierTypeInfo *mti = modifierType_getInfo(md->type);
2181         int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
2182
2183         if((md->mode & required_mode) != required_mode) return 0;
2184         if((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) {
2185                 modifier_setError(md, "Internal error, modifier requires"
2186                                   "original data (bad stack position).");
2187                 return 0;
2188         }
2189         if(mti->isDisabled && mti->isDisabled(md)) return 0;
2190         if(!(mti->flags & eModifierTypeFlag_SupportsEditmode)) return 0;
2191         if(md->mode & eModifierMode_DisableTemporary) return 0;
2192         
2193         return 1;
2194 }
2195
2196 static void editmesh_calc_modifiers(DerivedMesh **cage_r,
2197                                     DerivedMesh **final_r,
2198                                     CustomDataMask dataMask)
2199 {
2200         Object *ob = G.obedit;
2201         EditMesh *em = G.editMesh;
2202         ModifierData *md;
2203         float (*deformedVerts)[3] = NULL;
2204         DerivedMesh *dm;
2205         int i, numVerts = 0, cageIndex = modifiers_getCageIndex(ob, NULL);
2206         LinkNode *datamasks, *curr;
2207
2208         modifiers_clearErrors(ob);
2209
2210         if(cage_r && cageIndex == -1) {
2211                 *cage_r = getEditMeshDerivedMesh(em, ob, NULL);
2212         }
2213
2214         dm = NULL;
2215         md = ob->modifiers.first;
2216
2217         /* we always want to keep original indices */
2218         dataMask |= CD_MASK_ORIGINDEX;
2219
2220         datamasks = modifiers_calcDataMasks(md, dataMask);
2221
2222         curr = datamasks;
2223         for(i = 0; md; i++, md = md->next, curr = curr->next) {
2224                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
2225
2226                 if(!editmesh_modifier_is_enabled(md, dm))
2227                         continue;
2228
2229                 /* How to apply modifier depends on (a) what we already have as
2230                  * a result of previous modifiers (could be a DerivedMesh or just
2231                  * deformed vertices) and (b) what type the modifier is.
2232                  */
2233
2234                 if(mti->type == eModifierTypeType_OnlyDeform) {
2235                         /* No existing verts to deform, need to build them. */
2236                         if(!deformedVerts) {
2237                                 if(dm) {
2238                                         /* Deforming a derived mesh, read the vertex locations
2239                                          * out of the mesh and deform them. Once done with this
2240                                          * run of deformers verts will be written back.
2241                                          */
2242                                         numVerts = dm->getNumVerts(dm);
2243                                         deformedVerts =
2244                                             MEM_mallocN(sizeof(*deformedVerts) * numVerts, "dfmv");
2245                                         dm->getVertCos(dm, deformedVerts);
2246                                 } else {
2247                                         deformedVerts = editmesh_getVertexCos(em, &numVerts);
2248                                 }
2249                         }
2250
2251                         mti->deformVertsEM(md, ob, em, dm, deformedVerts, numVerts);
2252                 } else {
2253                         DerivedMesh *ndm;
2254
2255                         /* apply vertex coordinates or build a DerivedMesh as necessary */
2256                         if(dm) {
2257                                 if(deformedVerts) {
2258                                         DerivedMesh *tdm = CDDM_copy(dm);
2259                                         if(!(cage_r && dm == *cage_r)) dm->release(dm);
2260                                         dm = tdm;
2261
2262                                         CDDM_apply_vert_coords(dm, deformedVerts);
2263                                         CDDM_calc_normals(dm);
2264                                 } else if(cage_r && dm == *cage_r) {
2265                                         /* dm may be changed by this modifier, so we need to copy it
2266                                          */
2267                                         dm = CDDM_copy(dm);
2268                                 }
2269
2270                         } else {
2271                                 dm = CDDM_from_editmesh(em, ob->data);
2272
2273                                 if(deformedVerts) {
2274                                         CDDM_apply_vert_coords(dm, deformedVerts);
2275                                         CDDM_calc_normals(dm);
2276                                 }
2277                         }
2278
2279                         /* set the DerivedMesh to only copy needed data */
2280                         DM_set_only_copy(dm, (CustomDataMask)curr->link);
2281
2282                         if(((CustomDataMask)curr->link) & CD_MASK_ORIGSPACE)
2283                                 if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE))
2284                                         DM_add_face_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL);
2285                         
2286                         ndm = mti->applyModifierEM(md, ob, em, dm);
2287
2288                         if (ndm) {
2289                                 if(dm && dm != ndm)
2290                                         dm->release(dm);
2291
2292                                 dm = ndm;
2293
2294                                 if (deformedVerts) {
2295                                         MEM_freeN(deformedVerts);
2296                                         deformedVerts = NULL;
2297                                 }
2298                         }
2299                 }
2300
2301                 if(cage_r && i == cageIndex) {
2302                         if(dm && deformedVerts) {
2303                                 *cage_r = CDDM_copy(dm);
2304                                 CDDM_apply_vert_coords(*cage_r, deformedVerts);
2305                         } else if(dm) {
2306                                 *cage_r = dm;
2307                         } else {
2308                                 *cage_r =
2309                                     getEditMeshDerivedMesh(em, ob,
2310                                         deformedVerts ? MEM_dupallocN(deformedVerts) : NULL);
2311                         }
2312                 }
2313         }
2314
2315         BLI_linklist_free(datamasks, NULL);
2316
2317         /* Yay, we are done. If we have a DerivedMesh and deformed vertices need
2318          * to apply these back onto the DerivedMesh. If we have no DerivedMesh
2319          * then we need to build one.
2320          */
2321         if(dm && deformedVerts) {
2322                 *final_r = CDDM_copy(dm);
2323
2324                 if(!(cage_r && dm == *cage_r)) dm->release(dm);
2325
2326                 CDDM_apply_vert_coords(*final_r, deformedVerts);
2327                 CDDM_calc_normals(*final_r);
2328         } else if (dm) {
2329                 *final_r = dm;
2330         } else if (!deformedVerts && cage_r && *cage_r) {
2331                 *final_r = *cage_r;
2332         } else {
2333                 *final_r = getEditMeshDerivedMesh(em, ob, deformedVerts);
2334                 deformedVerts = NULL;
2335         }
2336
2337         if(deformedVerts)
2338                 MEM_freeN(deformedVerts);
2339 }
2340
2341 /***/
2342
2343
2344         /* Something of a hack, at the moment deal with weightpaint
2345          * by tucking into colors during modifier eval, only in
2346          * wpaint mode. Works ok but need to make sure recalc
2347          * happens on enter/exit wpaint.
2348          */
2349
2350 void weight_to_rgb(float input, float *fr, float *fg, float *fb)
2351 {
2352         float blend;
2353         
2354         blend= ((input/2.0f)+0.5f);
2355         
2356         if (input<=0.25f){      // blue->cyan
2357                 *fr= 0.0f;
2358                 *fg= blend*input*4.0f;
2359                 *fb= blend;
2360         }
2361         else if (input<=0.50f){ // cyan->green
2362                 *fr= 0.0f;
2363                 *fg= blend;
2364                 *fb= blend*(1.0f-((input-0.25f)*4.0f)); 
2365         }
2366         else if (input<=0.75){  // green->yellow
2367                 *fr= blend * ((input-0.50f)*4.0f);
2368                 *fg= blend;
2369                 *fb= 0.0f;
2370         }
2371         else if (input<=1.0){ // yellow->red
2372                 *fr= blend;
2373                 *fg= blend * (1.0f-((input-0.75f)*4.0f)); 
2374                 *fb= 0.0f;
2375         }
2376 }
2377 static void calc_weightpaint_vert_color(Object *ob, ColorBand *coba, int vert, unsigned char *col)
2378 {
2379         Mesh *me = ob->data;
2380         float colf[4], input = 0.0f;
2381         int i;
2382
2383         if (me->dvert) {
2384                 for (i=0; i<me->dvert[vert].totweight; i++)
2385                         if (me->dvert[vert].dw[i].def_nr==ob->actdef-1)
2386                                 input+=me->dvert[vert].dw[i].weight;            
2387         }
2388
2389         CLAMP(input, 0.0f, 1.0f);
2390         
2391         if(coba)
2392                 do_colorband(coba, input, colf);
2393         else
2394                 weight_to_rgb(input, colf, colf+1, colf+2);
2395         
2396         col[3] = (unsigned char)(colf[0] * 255.0f);
2397         col[2] = (unsigned char)(colf[1] * 255.0f);
2398         col[1] = (unsigned char)(colf[2] * 255.0f);
2399         col[0] = 255;
2400 }
2401
2402 static ColorBand *stored_cb= NULL;
2403
2404 void vDM_ColorBand_store(ColorBand *coba)
2405 {
2406         stored_cb= coba;
2407 }
2408
2409 static unsigned char *calc_weightpaint_colors(Object *ob) 
2410 {
2411         Mesh *me = ob->data;
2412         MFace *mf = me->mface;
2413         ColorBand *coba= stored_cb;     /* warning, not a local var */
2414         unsigned char *wtcol;
2415         int i;
2416         
2417         wtcol = MEM_callocN (sizeof (unsigned char) * me->totface*4*4, "weightmap");
2418         
2419         memset(wtcol, 0x55, sizeof (unsigned char) * me->totface*4*4);
2420         for (i=0; i<me->totface; i++, mf++) {
2421                 calc_weightpaint_vert_color(ob, coba, mf->v1, &wtcol[(i*4 + 0)*4]); 
2422                 calc_weightpaint_vert_color(ob, coba, mf->v2, &wtcol[(i*4 + 1)*4]); 
2423                 calc_weightpaint_vert_color(ob, coba, mf->v3, &wtcol[(i*4 + 2)*4]); 
2424                 if (mf->v4)
2425                         calc_weightpaint_vert_color(ob, coba, mf->v4, &wtcol[(i*4 + 3)*4]); 
2426         }
2427         
2428         return wtcol;
2429 }
2430
2431 static void clear_mesh_caches(Object *ob)
2432 {
2433         Mesh *me= ob->data;
2434
2435                 /* also serves as signal to remake texspace */
2436         if (ob->bb) {
2437                 MEM_freeN(ob->bb);
2438                 ob->bb = NULL;
2439         }
2440         if (me->bb) {
2441                 MEM_freeN(me->bb);
2442                 me->bb = NULL;
2443         }
2444
2445         freedisplist(&ob->disp);
2446
2447         if (ob->derivedFinal) {
2448                 ob->derivedFinal->needsFree = 1;
2449                 ob->derivedFinal->release(ob->derivedFinal);
2450                 ob->derivedFinal= NULL;
2451         }
2452         if (ob->derivedDeform) {
2453                 ob->derivedDeform->needsFree = 1;
2454                 ob->derivedDeform->release(ob->derivedDeform);
2455                 ob->derivedDeform= NULL;
2456         }
2457 }
2458
2459 static void mesh_build_data(Object *ob, CustomDataMask dataMask)
2460 {
2461         Mesh *me = ob->data;
2462         float min[3], max[3];
2463
2464         clear_mesh_caches(ob);
2465
2466         if(ob!=G.obedit) {
2467                 Object *obact = G.scene->basact?G.scene->basact->object:NULL;
2468                 int editing = (FACESEL_PAINT_TEST)|(G.f & G_PARTICLEEDIT);
2469                 int needMapping = editing && (ob==obact);
2470
2471                 if( (G.f & G_WEIGHTPAINT) && ob==obact ) {
2472                         MCol *wpcol = (MCol*)calc_weightpaint_colors(ob);
2473                         int layernum = CustomData_number_of_layers(&me->fdata, CD_MCOL);
2474
2475                         /* ugly hack here, we temporarily add a new active mcol layer with
2476                            weightpaint colors in it, that is then duplicated in CDDM_from_mesh */
2477                         CustomData_add_layer(&me->fdata, CD_MCOL, CD_ASSIGN, wpcol, me->totface);
2478                         CustomData_set_layer_active(&me->fdata, CD_MCOL, layernum);
2479
2480                         mesh_calc_modifiers(ob, NULL, &ob->derivedDeform,
2481                                             &ob->derivedFinal, 0, 1,
2482                                             needMapping, dataMask);
2483
2484                         CustomData_free_layer_active(&me->fdata, CD_MCOL, me->totface);
2485                 } else {
2486                         mesh_calc_modifiers(ob, NULL, &ob->derivedDeform,
2487                                             &ob->derivedFinal, G.rendering, 1,
2488                                             needMapping, dataMask);
2489                 }
2490
2491                 INIT_MINMAX(min, max);
2492
2493                 ob->derivedFinal->getMinMax(ob->derivedFinal, min, max);
2494
2495                 if(!ob->bb)
2496                         ob->bb= MEM_callocN(sizeof(BoundBox), "bb");
2497                 boundbox_set_from_min_max(ob->bb, min, max);
2498
2499                 ob->derivedFinal->needsFree = 0;
2500                 ob->derivedDeform->needsFree = 0;
2501                 ob->lastDataMask = dataMask;
2502         }
2503 }
2504
2505 static void editmesh_build_data(CustomDataMask dataMask)
2506 {
2507         float min[3], max[3];
2508
2509         EditMesh *em = G.editMesh;
2510
2511         clear_mesh_caches(G.obedit);
2512
2513         if (em->derivedFinal) {
2514                 if (em->derivedFinal!=em->derivedCage) {
2515                         em->derivedFinal->needsFree = 1;
2516                         em->derivedFinal->release(em->derivedFinal);
2517                 }
2518                 em->derivedFinal = NULL;
2519         }
2520         if (em->derivedCage) {
2521                 em->derivedCage->needsFree = 1;
2522                 em->derivedCage->release(em->derivedCage);
2523                 em->derivedCage = NULL;
2524         }
2525
2526         editmesh_calc_modifiers(&em->derivedCage, &em->derivedFinal, dataMask);
2527         em->lastDataMask = dataMask;
2528
2529         INIT_MINMAX(min, max);
2530
2531         em->derivedFinal->getMinMax(em->derivedFinal, min, max);
2532
2533         if(!G.obedit->bb)
2534                 G.obedit->bb= MEM_callocN(sizeof(BoundBox), "bb");
2535         boundbox_set_from_min_max(G.obedit->bb, min, max);
2536
2537         em->derivedFinal->needsFree = 0;
2538         em->derivedCage->needsFree = 0;
2539 }
2540
2541 void makeDerivedMesh(Object *ob, CustomDataMask dataMask)
2542 {
2543         if (ob==G.obedit) {
2544                 editmesh_build_data(dataMask);
2545         } else {
2546                 PartEff *paf= give_parteff(ob);
2547                 
2548                 mesh_build_data(ob, dataMask);
2549                 
2550                 if(paf) {
2551                         if((paf->flag & PAF_STATIC) || (ob->recalc & OB_RECALC_TIME)==0)
2552                                 build_particle_system(ob);
2553                 }
2554         }
2555 }
2556
2557 /***/
2558
2559 DerivedMesh *mesh_get_derived_final(Object *ob, CustomDataMask dataMask)
2560 {
2561         /* if there's no derived mesh or the last data mask used doesn't include
2562          * the data we need, rebuild the derived mesh
2563          */
2564         if(!ob->derivedFinal || (dataMask & ob->lastDataMask) != dataMask)
2565                 mesh_build_data(ob, dataMask);
2566
2567         return ob->derivedFinal;
2568 }
2569
2570 DerivedMesh *mesh_get_derived_deform(Object *ob, CustomDataMask dataMask)
2571 {
2572         /* if there's no derived mesh or the last data mask used doesn't include
2573          * the data we need, rebuild the derived mesh
2574          */
2575         if(!ob->derivedDeform || (dataMask & ob->lastDataMask) != dataMask)
2576                 mesh_build_data(ob, dataMask);
2577
2578         return ob->derivedDeform;
2579 }
2580
2581 /* Move to multires Pin level, returns a copy of the original vertex coords. */
2582 float *multires_render_pin(Object *ob, Mesh *me, int *orig_lvl)
2583 {
2584         float *vert_copy= NULL;
2585
2586         if(me->mr && !(me->mr->flag & MULTIRES_NO_RENDER)) {
2587                 MultiresLevel *lvl= NULL;
2588                 int i;
2589                 
2590                 /* Make sure all mesh edits are properly stored in the multires data*/
2591                 multires_update_levels(me, 1);
2592         
2593                 /* Copy the highest level of multires verts */
2594                 *orig_lvl= me->mr->current;
2595                 lvl= multires_level_n(me->mr, BLI_countlist(&me->mr->levels));
2596                 vert_copy= MEM_callocN(sizeof(float)*3*lvl->totvert, "multires vert_copy");
2597                 for(i=0; i<lvl->totvert; ++i)
2598                         VecCopyf(&vert_copy[i*3], me->mr->verts[i].co);
2599         
2600                 /* Goto the pin level for multires */
2601                 me->mr->newlvl= me->mr->pinlvl;
2602                 multires_set_level(ob, me, 1);
2603         }
2604         
2605         return vert_copy;
2606 }
2607
2608 /* Propagate the changes to render level - fails if mesh topology changed */
2609 void multires_render_final(Object *ob, Mesh *me, DerivedMesh **dm, float *vert_copy,
2610                            const int orig_lvl, CustomDataMask dataMask)
2611 {
2612         if(me->mr && !(me->mr->flag & MULTIRES_NO_RENDER)) {
2613                 if((*dm)->getNumVerts(*dm) == me->totvert &&
2614                    (*dm)->getNumFaces(*dm) == me->totface) {
2615                         MultiresLevel *lvl= multires_level_n(me->mr, BLI_countlist(&me->mr->levels));
2616                         DerivedMesh *old= NULL;
2617                         MVert *vertdup= NULL;
2618                         int i;
2619
2620                         /* Copy the verts into the mesh */
2621                         vertdup= (*dm)->dupVertArray(*dm);
2622                         (*dm)->release(*dm);
2623                         for(i=0; i<me->totvert; ++i)
2624                                 me->mvert[i]= vertdup[i];
2625
2626                         /* Go to the render level */
2627                         me->mr->newlvl= me->mr->renderlvl;
2628                         multires_set_level(ob, me, 1);
2629                         (*dm)= getMeshDerivedMesh(me, ob, NULL);
2630
2631                         /* Some of the data in dm is referenced externally, so make a copy */
2632                         old= *dm;
2633                         (*dm)= CDDM_copy(old);
2634                         old->release(old);
2635
2636                         if(dataMask & CD_MASK_ORCO)
2637                                 add_orco_dm(ob, *dm, NULL);
2638
2639                         /* Restore the original verts */
2640                         me->mr->newlvl= BLI_countlist(&me->mr->levels);
2641                         multires_set_level(ob, me, 1);
2642                         for(i=0; i<lvl->totvert; ++i)
2643                                 VecCopyf(me->mvert[i].co, &vert_copy[i*3]);
2644                 }
2645                 
2646                 if(vert_copy)
2647                         MEM_freeN(vert_copy);
2648                         
2649                 me->mr->newlvl= orig_lvl;
2650                 multires_set_level(ob, me, 1);
2651         }
2652 }
2653
2654 /* Multires note - if mesh has multires enabled, mesh is first set to the Pin level,
2655    where all modifiers are applied, then if the topology hasn't changed, the changes
2656    from modifiers are propagated up to the Render level. */
2657 DerivedMesh *mesh_create_derived_render(Object *ob, CustomDataMask dataMask)
2658 {
2659         DerivedMesh *final;
2660         Mesh *me= get_mesh(ob);
2661         float *vert_copy= NULL;
2662         int orig_lvl= 0;
2663         
2664         vert_copy= multires_render_pin(ob, me, &orig_lvl);
2665         mesh_calc_modifiers(ob, NULL, NULL, &final, 1, 1, 0, dataMask);
2666         multires_render_final(ob, me, &final, vert_copy, orig_lvl, dataMask);
2667
2668         return final;
2669 }
2670
2671 DerivedMesh *mesh_create_derived_view(Object *ob, CustomDataMask dataMask)
2672 {
2673         DerivedMesh *final;
2674
2675         mesh_calc_modifiers(ob, NULL, NULL, &final, 0, 1, 0, dataMask);
2676
2677         return final;
2678 }
2679
2680 DerivedMesh *mesh_create_derived_no_deform(Object *ob, float (*vertCos)[3],
2681                                            CustomDataMask dataMask)
2682 {
2683         DerivedMesh *final;
2684         
2685         mesh_calc_modifiers(ob, vertCos, NULL, &final, 0, 0, 0, dataMask);
2686
2687         return final;
2688 }
2689
2690 DerivedMesh *mesh_create_derived_no_deform_render(Object *ob,
2691                                                   float (*vertCos)[3],
2692                                                   CustomDataMask dataMask)
2693 {
2694         DerivedMesh *final;
2695         Mesh *me= get_mesh(ob);
2696         float *vert_copy= NULL;
2697         int orig_lvl= 0;
2698
2699         vert_copy= multires_render_pin(ob, me, &orig_lvl);
2700         mesh_calc_modifiers(ob, vertCos, NULL, &final, 1, 0, 0, dataMask);
2701         multires_render_final(ob, me, &final, vert_copy, orig_lvl, dataMask);
2702
2703         return final;
2704 }
2705
2706 /***/
2707
2708 DerivedMesh *editmesh_get_derived_cage_and_final(DerivedMesh **final_r,
2709                                                  CustomDataMask dataMask)
2710 {
2711         /* if there's no derived mesh or the last data mask used doesn't include
2712          * the data we need, rebuild the derived mesh
2713          */
2714         if(!G.editMesh->derivedCage ||
2715            (G.editMesh->lastDataMask & dataMask) != dataMask)
2716                 editmesh_build_data(dataMask);
2717
2718         *final_r = G.editMesh->derivedFinal;
2719         return G.editMesh->derivedCage;
2720 }
2721
2722 DerivedMesh *editmesh_get_derived_cage(CustomDataMask dataMask)
2723 {
2724         /* if there's no derived mesh or the last data mask used doesn't include
2725          * the data we need, rebuild the derived mesh
2726          */
2727         if(!G.editMesh->derivedCage ||
2728            (G.editMesh->lastDataMask & dataMask) != dataMask)
2729                 editmesh_build_data(dataMask);
2730
2731         return G.editMesh->derivedCage;
2732 }
2733
2734 DerivedMesh *editmesh_get_derived_base(void)
2735 {
2736         return getEditMeshDerivedMesh(G.editMesh, G.obedit, NULL);
2737 }
2738
2739
2740 /* ********* For those who don't grasp derived stuff! (ton) :) *************** */
2741
2742 static void make_vertexcosnos__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
2743 {
2744         float *vec = userData;
2745         
2746         vec+= 6*index;
2747
2748         /* check if we've been here before (normal should not be 0) */
2749         if(vec[3] || vec[4] || vec[5]) return;
2750
2751         VECCOPY(vec, co);
2752         vec+= 3;
2753         if(no_f) {
2754                 VECCOPY(vec, no_f);
2755         }
2756         else {
2757                 VECCOPY(vec, no_s);
2758         }
2759 }
2760
2761 /* always returns original amount me->totvert of vertices and normals, but fully deformed and subsurfered */
2762 /* this is needed for all code using vertexgroups (no subsurf support) */
2763 /* it stores the normals as floats, but they can still be scaled as shorts (32767 = unit) */
2764 /* in use now by vertex/weight paint and particle generating */
2765
2766 float *mesh_get_mapped_verts_nors(Object *ob)
2767 {
2768         Mesh *me= ob->data;
2769         DerivedMesh *dm;
2770         float *vertexcosnos;
2771         
2772         /* lets prevent crashing... */
2773         if(ob->type!=OB_MESH || me->totvert==0)
2774                 return NULL;
2775         
2776         dm= mesh_get_derived_final(ob, CD_MASK_BAREMESH);
2777         vertexcosnos= MEM_callocN(6*sizeof(float)*me->totvert, "vertexcosnos map");
2778         
2779         if(dm->foreachMappedVert) {
2780                 dm->foreachMappedVert(dm, make_vertexcosnos__mapFunc, vertexcosnos);
2781         }
2782         else {
2783                 float *fp= vertexcosnos;
2784                 int a;
2785                 
2786                 for(a=0; a< me->totvert; a++, fp+=6) {
2787                         dm->getVertCo(dm, a, fp);
2788                         dm->getVertNo(dm, a, fp+3);
2789                 }
2790         }
2791         
2792         dm->release(dm);
2793         return vertexcosnos;
2794 }
2795
2796 /* ********* crazyspace *************** */
2797
2798 int editmesh_get_first_deform_matrices(float (**deformmats)[3][3], float (**deformcos)[3])
2799 {
2800         Object *ob = G.obedit;
2801         EditMesh *em = G.editMesh;
2802         ModifierData *md;
2803         DerivedMesh *dm;
2804         int i, a, numleft = 0, numVerts = 0;
2805         int cageIndex = modifiers_getCageIndex(ob, NULL);
2806         float (*defmats)[3][3] = NULL, (*deformedVerts)[3] = NULL;
2807
2808         modifiers_clearErrors(ob);
2809
2810         dm = NULL;
2811         md = ob->modifiers.first;
2812
2813         /* compute the deformation matrices and coordinates for the first
2814            modifiers with on cage editing that are enabled and support computing
2815            deform matrices */
2816         for(i = 0; md && i <= cageIndex; i++, md = md->next) {
2817                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
2818
2819                 if(!editmesh_modifier_is_enabled(md, dm))
2820                         continue;
2821
2822                 if(mti->type==eModifierTypeType_OnlyDeform && mti->deformMatricesEM) {
2823                         if(!defmats) {
2824                                 dm= getEditMeshDerivedMesh(em, ob, NULL);
2825                                 deformedVerts= editmesh_getVertexCos(em, &numVerts);
2826                                 defmats= MEM_callocN(sizeof(*defmats)*numVerts, "defmats");
2827
2828                                 for(a=0; a<numVerts; a++)
2829                                         Mat3One(defmats[a]);
2830                         }
2831
2832                         mti->deformMatricesEM(md, ob, em, dm, deformedVerts, defmats,
2833                                 numVerts);
2834                 }
2835                 else
2836                         break;
2837         }
2838
2839         for(; md && i <= cageIndex; md = md->next, i++)
2840                 if(editmesh_modifier_is_enabled(md, dm) && modifier_isDeformer(md))
2841                         numleft++;
2842
2843         if(dm)
2844                 dm->release(dm);
2845         
2846         *deformmats= defmats;
2847         *deformcos= deformedVerts;
2848
2849         return numleft;
2850 }
2851
2852 /* ************************* fluidsim bobj file handling **************************** */
2853
2854 #ifndef DISABLE_ELBEEM
2855
2856 #ifdef WIN32
2857 #ifndef snprintf
2858 #define snprintf _snprintf
2859 #endif
2860 #endif
2861
2862 /* write .bobj.gz file for a mesh object */
2863 void writeBobjgz(char *filename, struct Object *ob, int useGlobalCoords, int append, float time) 
2864 {
2865         char debugStrBuffer[256];
2866         int wri,i,j,totvert,totface;
2867         float wrf;
2868         gzFile gzf;
2869         DerivedMesh *dm;
2870         float vec[3];
2871         float rotmat[3][3];
2872         MVert *mvert;
2873         MFace *mface;
2874         //if(append)return; // DEBUG
2875
2876         if(!ob->data || (ob->type!=OB_MESH)) {
2877                 snprintf(debugStrBuffer,256,"Writing GZ_BOBJ Invalid object %s ...\n", ob->id.name); 
2878                 elbeemDebugOut(debugStrBuffer);
2879                 return;
2880         }
2881         if((ob->size[0]<0.0) || (ob->size[0]<0.0) || (ob->size[0]<0.0) ) {
2882                 snprintf(debugStrBuffer,256,"\nfluidSim::writeBobjgz:: Warning object %s has negative scaling - check triangle ordering...?\n\n", ob->id.name); 
2883                 elbeemDebugOut(debugStrBuffer);
2884         }
2885
2886         snprintf(debugStrBuffer,256,"Writing GZ_BOBJ '%s' ... ",filename); elbeemDebugOut(debugStrBuffer); 
2887         if(append) gzf = gzopen(filename, "a+b9");
2888         else       gzf = gzopen(filename, "wb9");
2889         if (!gzf) {
2890                 snprintf(debugStrBuffer,256,"writeBobjgz::error - Unable to open file for writing '%s'\n", filename);
2891                 elbeemDebugOut(debugStrBuffer);
2892                 return;
2893         }
2894
2895         dm = mesh_create_derived_render(ob, CD_MASK_BAREMESH);
2896         //dm = mesh_create_derived_no_deform(ob,NULL);
2897
2898         mvert = dm->getVertArray(dm);
2899         mface = dm->getFaceArray(dm);
2900         totvert = dm->getNumVerts(dm);
2901         totface = dm->getNumFaces(dm);
2902
2903         // write time value for appended anim mesh
2904         if(append) {
2905                 gzwrite(gzf, &time, sizeof(time));
2906         }
2907
2908         // continue with verts/norms
2909         if(sizeof(wri)!=4) { snprintf(debugStrBuffer,256,"Writing GZ_BOBJ, Invalid int size %d...\n", wri); elbeemDebugOut(debugStrBuffer); return; } // paranoia check
2910         wri = dm->getNumVerts(dm);
2911         mvert = dm->getVertArray(dm);
2912         gzwrite(gzf, &wri, sizeof(wri));
2913         for(i=0; i<wri;i++) {
2914                 VECCOPY(vec, mvert[i].co);
2915                 if(useGlobalCoords) { Mat4MulVecfl(ob->obmat, vec); }
2916                 for(j=0; j<3; j++) {
2917                         wrf = vec[j]; 
2918                         gzwrite(gzf, &wrf, sizeof( wrf )); 
2919                 }
2920         }
2921
2922         // should be the same as Vertices.size
2923         wri = totvert;
2924         gzwrite(gzf, &wri, sizeof(wri));
2925         EulToMat3(ob->rot, rotmat);
2926         for(i=0; i<wri;i++) {
2927                 VECCOPY(vec, mvert[i].no);
2928                 Normalize(vec);
2929                 if(useGlobalCoords) { Mat3MulVecfl(rotmat, vec); }
2930                 for(j=0; j<3; j++) {
2931                         wrf = vec[j];
2932                         gzwrite(gzf, &wrf, sizeof( wrf )); 
2933                 }
2934         }
2935
2936         // append only writes verts&norms 
2937         if(!append) {
2938                 //float side1[3],side2[3],norm1[3],norm2[3];
2939                 //float inpf;
2940         
2941                 // compute no. of triangles 
2942                 wri = 0;
2943                 for(i=0; i<totface; i++) {
2944                         wri++;
2945                         if(mface[i].v4) { wri++; }
2946                 }
2947                 gzwrite(gzf, &wri, sizeof(wri));
2948                 for(i=0; i<totface; i++) {
2949
2950                         int face[4];
2951                         face[0] = mface[i].v1;
2952                         face[1] = mface[i].v2;
2953                         face[2] = mface[i].v3;
2954                         face[3] = mface[i].v4;
2955                         //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);
2956                         //VecSubf(side1, mvert[face[1]].co,mvert[face[0]].co);
2957                         //VecSubf(side2, mvert[face[2]].co,mvert[face[0]].co);
2958                         //Crossf(norm1,side1,side2);
2959                         gzwrite(gzf, &(face[0]), sizeof( face[0] )); 
2960                         gzwrite(gzf, &(face[1]), sizeof( face[1] )); 
2961                         gzwrite(gzf, &(face[2]), sizeof( face[2] )); 
2962                         if(face[3]) { 
2963                                 //VecSubf(side1, mvert[face[2]].co,mvert[face[0]].co);
2964                                 //VecSubf(side2, mvert[face[3]].co,mvert[face[0]].co);
2965                                 //Crossf(norm2,side1,side2);
2966                                 //inpf = Inpf(norm1,norm2);
2967                                 //if(inpf>0.) {
2968                                 gzwrite(gzf, &(face[0]), sizeof( face[0] )); 
2969                                 gzwrite(gzf, &(face[2]), sizeof( face[2] )); 
2970                                 gzwrite(gzf, &(face[3]), sizeof( face[3] )); 
2971                                 //} else {
2972                                         //gzwrite(gzf, &(face[0]), sizeof( face[0] )); 
2973                                         //gzwrite(gzf, &(face[3]), sizeof( face[3] )); 
2974                                         //gzwrite(gzf, &(face[2]), sizeof( face[2] )); 
2975                                 //}
2976                         } // quad
2977                 }
2978         }
2979
2980         snprintf(debugStrBuffer,256,"Done. #Vertices: %d, #Triangles: %d\n", totvert, totface ); 
2981         elbeemDebugOut(debugStrBuffer);
2982         
2983         gzclose( gzf );
2984         dm->release(dm);
2985 }
2986
2987 void initElbeemMesh(struct Object *ob, 
2988                 int *numVertices, float **vertices, 
2989                 int *numTriangles, int **triangles,
2990                 int useGlobalCoords) 
2991 {
2992         DerivedMesh *dm = NULL;
2993         MVert *mvert;
2994         MFace *mface;
2995         int countTris=0, i, totvert, totface;
2996         float *verts;
2997         int *tris;
2998
2999         dm = mesh_create_derived_render(ob, CD_MASK_BAREMESH);
3000         //dm = mesh_create_derived_no_deform(ob,NULL);
3001
3002         mvert = dm->getVertArray(dm);
3003         mface = dm->getFaceArray(dm);
3004         totvert = dm->getNumVerts(dm);
3005         totface = dm->getNumFaces(dm);
3006
3007         *numVertices = totvert;
3008         verts = MEM_callocN( totvert*3*sizeof(float), "elbeemmesh_vertices");
3009         for(i=0; i<totvert; i++) {
3010                 VECCOPY( &verts[i*3], mvert[i].co);
3011                 if(useGlobalCoords) { Mat4MulVecfl(ob->obmat, &verts[i*3]); }
3012         }
3013         *vertices = verts;
3014
3015         for(i=0; i<totface; i++) {
3016                 countTris++;
3017                 if(mface[i].v4) { countTris++; }
3018         }
3019         *numTriangles = countTris;
3020         tris = MEM_callocN( countTris*3*sizeof(int), "elbeemmesh_triangles");
3021         countTris = 0;
3022         for(i=0; i<totface; i++) {
3023                 int face[4];
3024                 face[0] = mface[i].v1;
3025                 face[1] = mface[i].v2;
3026                 face[2] = mface[i].v3;
3027                 face[3] = mface[i].v4;
3028
3029                 tris[countTris*3+0] = face[0]; 
3030                 tris[countTris*3+1] = face[1]; 
3031                 tris[countTris*3+2] = face[2]; 
3032                 countTris++;
3033                 if(face[3]) { 
3034                         tris[countTris*3+0] = face[0]; 
3035                         tris[countTris*3+1] = face[2]; 
3036                         tris[countTris*3+2] = face[3]; 
3037                         countTris++;
3038                 }
3039         }
3040         *triangles = tris;
3041
3042         dm->release(dm);
3043 }
3044
3045 /* read .bobj.gz file into a fluidsimDerivedMesh struct */
3046 Mesh* readBobjgz(char *filename, Mesh *orgmesh, float* bbstart, float *bbsize) //, fluidsimDerivedMesh *fsdm)
3047 {
3048         int wri,i,j;
3049         char debugStrBuffer[256];
3050         float wrf;
3051         Mesh *newmesh; 
3052         const int debugBobjRead = 1;
3053         // init data from old mesh (materials,flags)
3054         MFace *origMFace = &((MFace*) orgmesh->mface)[0];
3055         int mat_nr = -1;
3056         int flag = -1;
3057         MFace *fsface = NULL;
3058         int gotBytes;
3059         gzFile gzf;
3060
3061         if(!orgmesh) return NULL;
3062         if(!origMFace) return NULL;
3063         mat_nr = origMFace->mat_nr;
3064         flag = origMFace->flag;
3065
3066         // similar to copy_mesh
3067         newmesh = MEM_dupallocN(orgmesh);
3068         newmesh->mat= orgmesh->mat;
3069
3070         newmesh->mvert= NULL;
3071         newmesh->medge= NULL;
3072         newmesh->mface= NULL;
3073         newmesh->mtface= NULL;
3074
3075         newmesh->dvert = NULL;
3076
3077         newmesh->mcol= NULL;
3078         newmesh->msticky= NULL;
3079         newmesh->texcomesh= NULL;
3080         memset(&newmesh->vdata, 0, sizeof(newmesh->vdata));
3081         memset(&newmesh->edata, 0, sizeof(newmesh->edata));
3082         memset(&newmesh->fdata, 0, sizeof(newmesh->fdata));
3083
3084         newmesh->key= NULL;
3085         newmesh->totface = 0;
3086         newmesh->totvert = 0;
3087         newmesh->totedge = 0;
3088         newmesh->medge = NULL;
3089
3090
3091         snprintf(debugStrBuffer,256,"Reading '%s' GZ_BOBJ... ",filename); elbeemDebugOut(debugStrBuffer); 
3092         gzf = gzopen(filename, "rb");
3093         // gzf = fopen(filename, "rb");
3094         // debug: fread(b,c,1,a) = gzread(a,b,c)
3095         if (!gzf) {
3096                 //snprintf(debugStrBuffer,256,"readBobjgz::error - Unable to open file for reading '%s'\n", filename); // DEBUG
3097                 MEM_freeN(newmesh);
3098                 return NULL;
3099         }
3100
3101         //if(sizeof(wri)!=4) { snprintf(debugStrBuffer,256,"Reading GZ_BOBJ, Invalid int size %d...\n", wri); return NULL; } // paranoia check
3102         gotBytes = gzread(gzf, &wri, sizeof(wri));
3103         newmesh->totvert = wri;
3104         newmesh->mvert = CustomData_add_layer(&newmesh->vdata, CD_MVERT, CD_CALLOC, NULL, newmesh->totvert);
3105         if(debugBobjRead){ snprintf(debugStrBuffer,256,"#vertices %d ", newmesh->totvert); elbeemDebugOut(debugStrBuffer); } //DEBUG
3106         for(i=0; i<newmesh->totvert;i++) {
3107                 //if(debugBobjRead) snprintf(debugStrBuffer,256,"V %d = ",i);
3108                 for(j=0; j<3; j++) {
3109                         gotBytes = gzread(gzf, &wrf, sizeof( wrf )); 
3110                         newmesh->mvert[i].co[j] = wrf;
3111                         //if(debugBobjRead) snprintf(debugStrBuffer,256,"%25.20f ", wrf);
3112                 }
3113                 //if(debugBobjRead) snprintf(debugStrBuffer,256,"\n");
3114         }
3115
3116         // should be the same as Vertices.size
3117         gotBytes = gzread(gzf, &wri, sizeof(wri));
3118         if(wri != newmesh->totvert) {
3119                 // complain #vertices has to be equal to #normals, reset&abort
3120                 CustomData_free_layer_active(&newmesh->vdata, CD_MVERT, newmesh->totvert);
3121                 MEM_freeN(newmesh);
3122                 snprintf(debugStrBuffer,256,"Reading GZ_BOBJ, #normals=%d, #vertices=%d, aborting...\n", wri,newmesh->totvert );
3123                 return NULL;
3124         }
3125         for(i=0; i<newmesh->totvert;i++) {
3126                 for(j=0; j<3; j++) {
3127                         gotBytes = gzread(gzf, &wrf, sizeof( wrf )); 
3128                         newmesh->mvert[i].no[j] = (short)(wrf*32767.0f);
3129                         //newmesh->mvert[i].no[j] = 0.5; // DEBUG tst
3130                 }
3131         //fprintf(stderr,"  DEBDPCN nm%d, %d = %d,%d,%d \n",
3132                         //(int)(newmesh->mvert), i, newmesh->mvert[i].no[0], newmesh->mvert[i].no[1], newmesh->mvert[i].no[2]);
3133         }
3134         //fprintf(stderr,"  DPCN 0 = %d,%d,%d \n", newmesh->mvert[0].no[0], newmesh->mvert[0].no[1], newmesh->mvert[0].no[2]);
3135
3136         
3137         /* compute no. of triangles */
3138         gotBytes = gzread(gzf, &wri, sizeof(wri));
3139         newmesh->totface = wri;
3140         newmesh->mface = CustomData_add_layer(&newmesh->fdata, CD_MFACE, CD_CALLOC, NULL, newmesh->totface);
3141         if(debugBobjRead){ snprintf(debugStrBuffer,256,"#faces %d ", newmesh->totface); elbeemDebugOut(debugStrBuffer); } //DEBUG
3142         fsface = newmesh->mface;
3143         for(i=0; i<newmesh->totface; i++) {
3144                 int face[4];
3145
3146                 gotBytes = gzread(gzf, &(face[0]), sizeof( face[0] )); 
3147                 gotBytes = gzread(gzf, &(face[1]), sizeof( face[1] )); 
3148                 gotBytes = gzread(gzf, &(face[2]), sizeof( face[2] )); 
3149                 face[3] = 0;
3150
3151                 fsface[i].v1 = face[0];
3152                 fsface[i].v2 = face[1];
3153                 fsface[i].v3 = face[2];
3154                 fsface[i].v4 = face[3];
3155         }
3156
3157         // correct triangles with v3==0 for blender, cycle verts
3158         for(i=0; i<newmesh->totface; i++) {
3159                 if(!fsface[i].v3) {
3160                         int temp = fsface[i].v1;
3161                         fsface[i].v1 = fsface[i].v2;
3162                         fsface[i].v2 = fsface[i].v3;
3163                         fsface[i].v3 = temp;
3164                 }
3165         }
3166         
3167         gzclose( gzf );
3168         for(i=0;i<newmesh->totface;i++) { 
3169                 fsface[i].mat_nr = mat_nr;
3170                 fsface[i].flag = flag;
3171                 fsface[i].edcode = ME_V1V2 | ME_V2V3 | ME_V3V1;
3172                 //snprintf(debugStrBuffer,256,"%d : %d,%d,%d\n", i,fsface[i].mat_nr, fsface[i].flag, fsface[i].edcode );
3173         }
3174
3175         snprintf(debugStrBuffer,256," (%d,%d) done\n", newmesh->totvert,newmesh->totface); elbeemDebugOut(debugStrBuffer); //DEBUG