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