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