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