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