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