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