BGE: Support mesh modifiers in the game engine.
[blender.git] / source / blender / blenkernel / intern / DerivedMesh.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2005 Blender Foundation.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #include <string.h>
31
32 #ifdef HAVE_CONFIG_H
33 #include <config.h>
34 #endif
35
36 #include "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 = (long) 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         /* we always want to keep original indices */
2138         dataMask |= CD_MASK_ORIGINDEX;
2139
2140         datamasks = modifiers_calcDataMasks(md, dataMask);
2141         curr = datamasks;
2142
2143         if(deform_r) *deform_r = NULL;
2144         *final_r = NULL;
2145
2146         if(useRenderParams) required_mode = eModifierMode_Render;
2147         else required_mode = eModifierMode_Realtime;
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((md->mode & required_mode) != required_mode) continue;
2160                         if(mti->isDisabled && mti->isDisabled(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((md->mode & required_mode) != 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(mti->isDisabled && mti->isDisabled(md)) continue;
2230                 if(needMapping && !modifier_supportsMapping(md)) continue;
2231
2232                 /* add an orco layer if needed by this modifier */
2233                 if(dm && mti->requiredDataMask) {
2234                         mask = mti->requiredDataMask(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((md->mode & required_mode) != 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         if(mti->isDisabled && mti->isDisabled(md)) return 0;
2412         if(!(mti->flags & eModifierTypeFlag_SupportsEditmode)) return 0;
2413         if(md->mode & eModifierMode_DisableTemporary) return 0;
2414         
2415         return 1;
2416 }
2417
2418 static void editmesh_calc_modifiers(DerivedMesh **cage_r,
2419                                     DerivedMesh **final_r,
2420                                     CustomDataMask dataMask)
2421 {
2422         Object *ob = G.obedit;
2423         EditMesh *em = G.editMesh;
2424         ModifierData *md;
2425         float (*deformedVerts)[3] = NULL;
2426         CustomDataMask mask;
2427         DerivedMesh *dm, *orcodm = NULL;
2428         int i, numVerts = 0, cageIndex = modifiers_getCageIndex(ob, NULL);
2429         LinkNode *datamasks, *curr;
2430
2431         modifiers_clearErrors(ob);
2432
2433         if(cage_r && cageIndex == -1) {
2434                 *cage_r = getEditMeshDerivedMesh(em, ob, NULL);
2435         }
2436
2437         dm = NULL;
2438         md = ob->modifiers.first;
2439
2440         /* we always want to keep original indices */
2441         dataMask |= CD_MASK_ORIGINDEX;
2442
2443         datamasks = modifiers_calcDataMasks(md, dataMask);
2444
2445         curr = datamasks;
2446         for(i = 0; md; i++, md = md->next, curr = curr->next) {
2447                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
2448
2449                 if(!editmesh_modifier_is_enabled(md, dm))
2450                         continue;
2451
2452                 /* add an orco layer if needed by this modifier */
2453                 if(dm && mti->requiredDataMask) {
2454                         mask = mti->requiredDataMask(md);
2455                         if(mask & CD_MASK_ORCO)
2456                                 add_orco_dm(ob, em, dm, orcodm);
2457                 }
2458
2459                 /* How to apply modifier depends on (a) what we already have as
2460                  * a result of previous modifiers (could be a DerivedMesh or just
2461                  * deformed vertices) and (b) what type the modifier is.
2462                  */
2463
2464                 if(mti->type == eModifierTypeType_OnlyDeform) {
2465                         /* No existing verts to deform, need to build them. */
2466                         if(!deformedVerts) {
2467                                 if(dm) {
2468                                         /* Deforming a derived mesh, read the vertex locations
2469                                          * out of the mesh and deform them. Once done with this
2470                                          * run of deformers verts will be written back.
2471                                          */
2472                                         numVerts = dm->getNumVerts(dm);
2473                                         deformedVerts =
2474                                             MEM_mallocN(sizeof(*deformedVerts) * numVerts, "dfmv");
2475                                         dm->getVertCos(dm, deformedVerts);
2476                                 } else {
2477                                         deformedVerts = editmesh_getVertexCos(em, &numVerts);
2478                                 }
2479                         }
2480
2481                         mti->deformVertsEM(md, ob, em, dm, deformedVerts, numVerts);
2482                 } else {
2483                         DerivedMesh *ndm;
2484
2485                         /* apply vertex coordinates or build a DerivedMesh as necessary */
2486                         if(dm) {
2487                                 if(deformedVerts) {
2488                                         DerivedMesh *tdm = CDDM_copy(dm);
2489                                         if(!(cage_r && dm == *cage_r)) dm->release(dm);
2490                                         dm = tdm;
2491
2492                                         CDDM_apply_vert_coords(dm, deformedVerts);
2493                                         CDDM_calc_normals(dm);
2494                                 } else if(cage_r && dm == *cage_r) {
2495                                         /* dm may be changed by this modifier, so we need to copy it
2496                                          */
2497                                         dm = CDDM_copy(dm);
2498                                 }
2499
2500                         } else {
2501                                 dm = CDDM_from_editmesh(em, ob->data);
2502
2503                                 if(deformedVerts) {
2504                                         CDDM_apply_vert_coords(dm, deformedVerts);
2505                                         CDDM_calc_normals(dm);
2506                                 }
2507                         }
2508
2509                         /* create an orco derivedmesh in parallel */
2510                         mask= (CustomDataMask)curr->link;
2511                         if(mask & CD_MASK_ORCO) {
2512                                 if(!orcodm)
2513                                         orcodm= create_orco_dm(ob, ob->data, em);
2514
2515                                 mask &= ~CD_MASK_ORCO;
2516                                 DM_set_only_copy(orcodm, mask);
2517                                 ndm = mti->applyModifierEM(md, ob, em, orcodm);
2518
2519                                 if(ndm) {
2520                                         /* if the modifier returned a new dm, release the old one */
2521                                         if(orcodm && orcodm != ndm) orcodm->release(orcodm);
2522                                         orcodm = ndm;
2523                                 }
2524                         }
2525
2526                         /* set the DerivedMesh to only copy needed data */
2527                         DM_set_only_copy(dm, (CustomDataMask)curr->link);
2528
2529                         if(((CustomDataMask)curr->link) & CD_MASK_ORIGSPACE)
2530                                 if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE))
2531                                         DM_add_face_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL);
2532                         
2533                         ndm = mti->applyModifierEM(md, ob, em, dm);
2534
2535                         if (ndm) {
2536                                 if(dm && dm != ndm)
2537                                         dm->release(dm);
2538
2539                                 dm = ndm;
2540
2541                                 if (deformedVerts) {
2542                                         MEM_freeN(deformedVerts);
2543                                         deformedVerts = NULL;
2544                                 }
2545                         }
2546                 }
2547
2548                 if(cage_r && i == cageIndex) {
2549                         if(dm && deformedVerts) {
2550                                 *cage_r = CDDM_copy(dm);
2551                                 CDDM_apply_vert_coords(*cage_r, deformedVerts);
2552                         } else if(dm) {
2553                                 *cage_r = dm;
2554                         } else {
2555                                 *cage_r =
2556                                     getEditMeshDerivedMesh(em, ob,
2557                                         deformedVerts ? MEM_dupallocN(deformedVerts) : NULL);
2558                         }
2559                 }
2560         }
2561
2562         BLI_linklist_free(datamasks, NULL);
2563
2564         /* Yay, we are done. If we have a DerivedMesh and deformed vertices need
2565          * to apply these back onto the DerivedMesh. If we have no DerivedMesh
2566          * then we need to build one.
2567          */
2568         if(dm && deformedVerts) {
2569                 *final_r = CDDM_copy(dm);
2570
2571                 if(!(cage_r && dm == *cage_r)) dm->release(dm);
2572
2573                 CDDM_apply_vert_coords(*final_r, deformedVerts);
2574                 CDDM_calc_normals(*final_r);
2575         } else if (dm) {
2576                 *final_r = dm;
2577         } else if (!deformedVerts && cage_r && *cage_r) {
2578                 *final_r = *cage_r;
2579         } else {
2580                 *final_r = getEditMeshDerivedMesh(em, ob, deformedVerts);
2581                 deformedVerts = NULL;
2582         }
2583
2584         /* add an orco layer if needed */
2585         if(dataMask & CD_MASK_ORCO)
2586                 add_orco_dm(ob, em, *final_r, orcodm);
2587
2588         if(orcodm)
2589                 orcodm->release(orcodm);
2590
2591         if(deformedVerts)
2592                 MEM_freeN(deformedVerts);
2593 }
2594
2595 /***/
2596
2597
2598         /* Something of a hack, at the moment deal with weightpaint
2599          * by tucking into colors during modifier eval, only in
2600          * wpaint mode. Works ok but need to make sure recalc
2601          * happens on enter/exit wpaint.
2602          */
2603
2604 void weight_to_rgb(float input, float *fr, float *fg, float *fb)
2605 {
2606         float blend;
2607         
2608         blend= ((input/2.0f)+0.5f);
2609         
2610         if (input<=0.25f){      // blue->cyan
2611                 *fr= 0.0f;
2612                 *fg= blend*input*4.0f;
2613                 *fb= blend;
2614         }
2615         else if (input<=0.50f){ // cyan->green
2616                 *fr= 0.0f;
2617                 *fg= blend;
2618                 *fb= blend*(1.0f-((input-0.25f)*4.0f)); 
2619         }
2620         else if (input<=0.75){  // green->yellow
2621                 *fr= blend * ((input-0.50f)*4.0f);
2622                 *fg= blend;
2623                 *fb= 0.0f;
2624         }
2625         else if (input<=1.0){ // yellow->red
2626                 *fr= blend;
2627                 *fg= blend * (1.0f-((input-0.75f)*4.0f)); 
2628                 *fb= 0.0f;
2629         }
2630 }
2631 static void calc_weightpaint_vert_color(Object *ob, ColorBand *coba, int vert, unsigned char *col)
2632 {
2633         Mesh *me = ob->data;
2634         float colf[4], input = 0.0f;
2635         int i;
2636
2637         if (me->dvert) {
2638                 for (i=0; i<me->dvert[vert].totweight; i++)
2639                         if (me->dvert[vert].dw[i].def_nr==ob->actdef-1)
2640                                 input+=me->dvert[vert].dw[i].weight;            
2641         }
2642
2643         CLAMP(input, 0.0f, 1.0f);
2644         
2645         if(coba)
2646                 do_colorband(coba, input, colf);
2647         else
2648                 weight_to_rgb(input, colf, colf+1, colf+2);
2649         
2650         col[3] = (unsigned char)(colf[0] * 255.0f);
2651         col[2] = (unsigned char)(colf[1] * 255.0f);
2652         col[1] = (unsigned char)(colf[2] * 255.0f);
2653         col[0] = 255;
2654 }
2655
2656 static ColorBand *stored_cb= NULL;
2657
2658 void vDM_ColorBand_store(ColorBand *coba)
2659 {
2660         stored_cb= coba;
2661 }
2662
2663 static unsigned char *calc_weightpaint_colors(Object *ob) 
2664 {
2665         Mesh *me = ob->data;
2666         MFace *mf = me->mface;
2667         ColorBand *coba= stored_cb;     /* warning, not a local var */
2668         unsigned char *wtcol;
2669         int i;
2670         
2671         wtcol = MEM_callocN (sizeof (unsigned char) * me->totface*4*4, "weightmap");
2672         
2673         memset(wtcol, 0x55, sizeof (unsigned char) * me->totface*4*4);
2674         for (i=0; i<me->totface; i++, mf++) {
2675                 calc_weightpaint_vert_color(ob, coba, mf->v1, &wtcol[(i*4 + 0)*4]); 
2676                 calc_weightpaint_vert_color(ob, coba, mf->v2, &wtcol[(i*4 + 1)*4]); 
2677                 calc_weightpaint_vert_color(ob, coba, mf->v3, &wtcol[(i*4 + 2)*4]); 
2678                 if (mf->v4)
2679                         calc_weightpaint_vert_color(ob, coba, mf->v4, &wtcol[(i*4 + 3)*4]); 
2680         }
2681         
2682         return wtcol;
2683 }
2684
2685 static void clear_mesh_caches(Object *ob)
2686 {
2687         Mesh *me= ob->data;
2688
2689                 /* also serves as signal to remake texspace */
2690         if (ob->bb) {
2691                 MEM_freeN(ob->bb);
2692                 ob->bb = NULL;
2693         }
2694         if (me->bb) {
2695                 MEM_freeN(me->bb);
2696                 me->bb = NULL;
2697         }
2698
2699         freedisplist(&ob->disp);
2700
2701         if (ob->derivedFinal) {
2702                 ob->derivedFinal->needsFree = 1;
2703                 ob->derivedFinal->release(ob->derivedFinal);
2704                 ob->derivedFinal= NULL;
2705         }
2706         if (ob->derivedDeform) {
2707                 ob->derivedDeform->needsFree = 1;
2708                 ob->derivedDeform->release(ob->derivedDeform);
2709                 ob->derivedDeform= NULL;
2710         }
2711 }
2712
2713 static void mesh_build_data(Object *ob, CustomDataMask dataMask)
2714 {
2715         Mesh *me = ob->data;
2716         float min[3], max[3];
2717
2718         clear_mesh_caches(ob);
2719
2720         if(ob!=G.obedit) {
2721                 Object *obact = G.scene->basact?G.scene->basact->object:NULL;
2722                 int editing = (FACESEL_PAINT_TEST)|(G.f & G_PARTICLEEDIT);
2723                 int needMapping = editing && (ob==obact);
2724
2725                 if( (G.f & G_WEIGHTPAINT) && ob==obact ) {
2726                         MCol *wpcol = (MCol*)calc_weightpaint_colors(ob);
2727                         int layernum = CustomData_number_of_layers(&me->fdata, CD_MCOL);
2728                         int prevactive = CustomData_get_active_layer(&me->fdata, CD_MCOL);
2729                         int prevrender = CustomData_get_render_layer(&me->fdata, CD_MCOL);
2730
2731                         /* ugly hack here, we temporarily add a new active mcol layer with
2732                            weightpaint colors in it, that is then duplicated in CDDM_from_mesh */
2733                         CustomData_add_layer(&me->fdata, CD_MCOL, CD_ASSIGN, wpcol, me->totface);
2734                         CustomData_set_layer_active(&me->fdata, CD_MCOL, layernum);
2735                         CustomData_set_layer_render(&me->fdata, CD_MCOL, layernum);
2736
2737                         mesh_calc_modifiers(ob, NULL, &ob->derivedDeform,
2738                                             &ob->derivedFinal, 0, 1,
2739                                             needMapping, dataMask, -1);
2740
2741                         CustomData_free_layer_active(&me->fdata, CD_MCOL, me->totface);
2742                         CustomData_set_layer_active(&me->fdata, CD_MCOL, prevactive);
2743                         CustomData_set_layer_render(&me->fdata, CD_MCOL, prevrender);
2744                 } else {
2745                         mesh_calc_modifiers(ob, NULL, &ob->derivedDeform,
2746                                             &ob->derivedFinal, G.rendering, 1,
2747                                             needMapping, dataMask, -1);
2748                 }
2749
2750                 INIT_MINMAX(min, max);
2751
2752                 ob->derivedFinal->getMinMax(ob->derivedFinal, min, max);
2753
2754                 if(!ob->bb)
2755                         ob->bb= MEM_callocN(sizeof(BoundBox), "bb");
2756                 boundbox_set_from_min_max(ob->bb, min, max);
2757
2758                 ob->derivedFinal->needsFree = 0;
2759                 ob->derivedDeform->needsFree = 0;
2760                 ob->lastDataMask = dataMask;
2761         }
2762 }
2763
2764 static void editmesh_build_data(CustomDataMask dataMask)
2765 {
2766         float min[3], max[3];
2767
2768         EditMesh *em = G.editMesh;
2769
2770         clear_mesh_caches(G.obedit);
2771
2772         if (em->derivedFinal) {
2773                 if (em->derivedFinal!=em->derivedCage) {
2774                         em->derivedFinal->needsFree = 1;
2775                         em->derivedFinal->release(em->derivedFinal);
2776                 }
2777                 em->derivedFinal = NULL;
2778         }
2779         if (em->derivedCage) {
2780                 em->derivedCage->needsFree = 1;
2781                 em->derivedCage->release(em->derivedCage);
2782                 em->derivedCage = NULL;
2783         }
2784
2785         editmesh_calc_modifiers(&em->derivedCage, &em->derivedFinal, dataMask);
2786         em->lastDataMask = dataMask;
2787
2788         INIT_MINMAX(min, max);
2789
2790         em->derivedFinal->getMinMax(em->derivedFinal, min, max);
2791
2792         if(!G.obedit->bb)
2793                 G.obedit->bb= MEM_callocN(sizeof(BoundBox), "bb");
2794         boundbox_set_from_min_max(G.obedit->bb, min, max);
2795
2796         em->derivedFinal->needsFree = 0;
2797         em->derivedCage->needsFree = 0;
2798 }
2799
2800 void makeDerivedMesh(Object *ob, CustomDataMask dataMask)
2801 {
2802         if (ob==G.obedit) {
2803                 editmesh_build_data(dataMask);
2804         } else {
2805                 mesh_build_data(ob, dataMask);
2806         }
2807 }
2808
2809 /***/
2810
2811 DerivedMesh *mesh_get_derived_final(Object *ob, CustomDataMask dataMask)
2812 {
2813         /* if there's no derived mesh or the last data mask used doesn't include
2814          * the data we need, rebuild the derived mesh
2815          */
2816         if(!ob->derivedFinal || (dataMask & ob->lastDataMask) != dataMask)
2817                 mesh_build_data(ob, dataMask);
2818
2819         return ob->derivedFinal;
2820 }
2821
2822 DerivedMesh *mesh_get_derived_deform(Object *ob, CustomDataMask dataMask)
2823 {
2824         /* if there's no derived mesh or the last data mask used doesn't include
2825          * the data we need, rebuild the derived mesh
2826          */
2827         if(!ob->derivedDeform || (dataMask & ob->lastDataMask) != dataMask)
2828                 mesh_build_data(ob, dataMask);
2829
2830         return ob->derivedDeform;
2831 }
2832
2833 /* Move to multires Pin level, returns a copy of the original vertex coords. */
2834 float *multires_render_pin(Object *ob, Mesh *me, int *orig_lvl)
2835 {
2836         float *vert_copy= NULL;
2837
2838         if(me->mr && !(me->mr->flag & MULTIRES_NO_RENDER)) {
2839                 MultiresLevel *lvl= NULL;
2840                 int i;
2841                 
2842                 /* Make sure all mesh edits are properly stored in the multires data*/
2843                 multires_update_levels(me, 1);
2844         
2845                 /* Copy the highest level of multires verts */
2846                 *orig_lvl= me->mr->current;
2847                 lvl= multires_level_n(me->mr, BLI_countlist(&me->mr->levels));
2848                 vert_copy= MEM_callocN(sizeof(float)*3*lvl->totvert, "multires vert_copy");
2849                 for(i=0; i<lvl->totvert; ++i)
2850                         VecCopyf(&vert_copy[i*3], me->mr->verts[i].co);
2851         
2852                 /* Goto the pin level for multires */
2853                 me->mr->newlvl= me->mr->pinlvl;
2854                 multires_set_level(ob, me, 1);
2855         }
2856         
2857         return vert_copy;
2858 }
2859
2860 /* Propagate the changes to render level - fails if mesh topology changed */
2861 void multires_render_final(Object *ob, Mesh *me, DerivedMesh **dm, float *vert_copy,
2862                            const int orig_lvl, CustomDataMask dataMask)
2863 {
2864         if(me->mr && !(me->mr->flag & MULTIRES_NO_RENDER)) {
2865                 if((*dm)->getNumVerts(*dm) == me->totvert &&
2866                    (*dm)->getNumFaces(*dm) == me->totface) {
2867                         MultiresLevel *lvl= multires_level_n(me->mr, BLI_countlist(&me->mr->levels));
2868                         DerivedMesh *old= NULL;
2869                         MVert *vertdup= NULL;
2870                         int i;
2871
2872                         /* Copy the verts into the mesh */
2873                         vertdup= (*dm)->dupVertArray(*dm);
2874                         (*dm)->release(*dm);
2875                         for(i=0; i<me->totvert; ++i)
2876                                 me->mvert[i]= vertdup[i];
2877                         /* Free vertdup after use*/
2878                         MEM_freeN(vertdup);
2879                         /* Go to the render level */
2880                         me->mr->newlvl= me->mr->renderlvl;
2881                         multires_set_level(ob, me, 1);
2882                         (*dm)= getMeshDerivedMesh(me, ob, NULL);
2883
2884                         /* Some of the data in dm is referenced externally, so make a copy */
2885                         old= *dm;
2886                         (*dm)= CDDM_copy(old);
2887                         old->release(old);
2888
2889                         if(dataMask & CD_MASK_ORCO)
2890                                 add_orco_dm(ob, NULL, *dm, NULL);
2891
2892                         /* Restore the original verts */
2893                         me->mr->newlvl= BLI_countlist(&me->mr->levels);
2894                         multires_set_level(ob, me, 1);
2895                         for(i=0; i<lvl->totvert; ++i)
2896                                 VecCopyf(me->mvert[i].co, &vert_copy[i*3]);
2897                 }
2898                 
2899                 if(vert_copy)
2900                         MEM_freeN(vert_copy);
2901                         
2902                 me->mr->newlvl= orig_lvl;
2903                 multires_set_level(ob, me, 1);
2904         }
2905 }
2906
2907 /* Multires note - if mesh has multires enabled, mesh is first set to the Pin level,
2908    where all modifiers are applied, then if the topology hasn't changed, the changes
2909    from modifiers are propagated up to the Render level. */
2910 DerivedMesh *mesh_create_derived_render(Object *ob, CustomDataMask dataMask)
2911 {
2912         DerivedMesh *final;
2913         Mesh *me= get_mesh(ob);
2914         float *vert_copy= NULL;
2915         int orig_lvl= 0;
2916         
2917         vert_copy= multires_render_pin(ob, me, &orig_lvl);
2918         mesh_calc_modifiers(ob, NULL, NULL, &final, 1, 1, 0, dataMask, -1);
2919         multires_render_final(ob, me, &final, vert_copy, orig_lvl, dataMask);
2920
2921         return final;
2922 }
2923
2924 DerivedMesh *mesh_create_derived_index_render(Object *ob, CustomDataMask dataMask, int index)
2925 {
2926         DerivedMesh *final;
2927         Mesh *me= get_mesh(ob);
2928         float *vert_copy= NULL;
2929         int orig_lvl= 0;
2930         
2931         vert_copy= multires_render_pin(ob, me, &orig_lvl);
2932         mesh_calc_modifiers(ob, NULL, NULL, &final, 1, 1, 0, dataMask, index);
2933         multires_render_final(ob, me, &final, vert_copy, orig_lvl, dataMask);
2934
2935         return final;
2936 }
2937
2938 DerivedMesh *mesh_create_derived_view(Object *ob, CustomDataMask dataMask)
2939 {
2940         DerivedMesh *final;
2941
2942         mesh_calc_modifiers(ob, NULL, NULL, &final, 0, 1, 0, dataMask, -1);
2943
2944         return final;
2945 }
2946
2947 DerivedMesh *mesh_create_derived_no_deform(Object *ob, float (*vertCos)[3],
2948                                            CustomDataMask dataMask)
2949 {
2950         DerivedMesh *final;
2951         
2952         mesh_calc_modifiers(ob, vertCos, NULL, &final, 0, 0, 0, dataMask, -1);
2953
2954         return final;
2955 }
2956
2957 DerivedMesh *mesh_create_derived_no_virtual(Object *ob, float (*vertCos)[3],
2958                                             CustomDataMask dataMask)
2959 {
2960         DerivedMesh *final;
2961         
2962         mesh_calc_modifiers(ob, vertCos, NULL, &final, 0, -1, 0, dataMask, -1);
2963
2964         return final;
2965 }
2966
2967 DerivedMesh *mesh_create_derived_no_deform_render(Object *ob,
2968                                                   float (*vertCos)[3],
2969                                                   CustomDataMask dataMask)
2970 {
2971         DerivedMesh *final;
2972         Mesh *me= get_mesh(ob);
2973         float *vert_copy= NULL;
2974         int orig_lvl= 0;
2975
2976         vert_copy= multires_render_pin(ob, me, &orig_lvl);
2977         mesh_calc_modifiers(ob, vertCos, NULL, &final, 1, 0, 0, dataMask, -1);
2978         multires_render_final(ob, me, &final, vert_copy, orig_lvl, dataMask);
2979
2980         return final;
2981 }
2982
2983 /***/
2984
2985 DerivedMesh *editmesh_get_derived_cage_and_final(DerivedMesh **final_r,
2986                                                  CustomDataMask dataMask)
2987 {
2988         /* if there's no derived mesh or the last data mask used doesn't include
2989          * the data we need, rebuild the derived mesh
2990          */
2991         if(!G.editMesh->derivedCage ||
2992            (G.editMesh->lastDataMask & dataMask) != dataMask)
2993                 editmesh_build_data(dataMask);
2994
2995         *final_r = G.editMesh->derivedFinal;
2996         return G.editMesh->derivedCage;
2997 }
2998
2999 DerivedMesh *editmesh_get_derived_cage(CustomDataMask dataMask)
3000 {
3001         /* if there's no derived mesh or the last data mask used doesn't include
3002          * the data we need, rebuild the derived mesh
3003          */
3004         if(!G.editMesh->derivedCage ||
3005            (G.editMesh->lastDataMask & dataMask) != dataMask)
3006                 editmesh_build_data(dataMask);
3007
3008         return G.editMesh->derivedCage;
3009 }
3010
3011 DerivedMesh *editmesh_get_derived_base(void)
3012 {
3013         return getEditMeshDerivedMesh(G.editMesh, G.obedit, NULL);
3014 }
3015
3016
3017 /* ********* For those who don't grasp derived stuff! (ton) :) *************** */
3018
3019 static void make_vertexcosnos__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
3020 {
3021         float *vec = userData;
3022         
3023         vec+= 6*index;
3024
3025         /* check if we've been here before (normal should not be 0) */
3026         if(vec[3] || vec[4] || vec[5]) return;
3027
3028         VECCOPY(vec, co);
3029         vec+= 3;
3030         if(no_f) {
3031                 VECCOPY(vec, no_f);
3032         }
3033         else {
3034                 VECCOPY(vec, no_s);
3035         }
3036 }
3037
3038 /* always returns original amount me->totvert of vertices and normals, but fully deformed and subsurfered */
3039 /* this is needed for all code using vertexgroups (no subsurf support) */
3040 /* it stores the normals as floats, but they can still be scaled as shorts (32767 = unit) */
3041 /* in use now by vertex/weight paint and particle generating */
3042
3043 float *mesh_get_mapped_verts_nors(Object *ob)
3044 {
3045         Mesh *me= ob->data;
3046         DerivedMesh *dm;
3047         float *vertexcosnos;
3048         
3049         /* lets prevent crashing... */
3050         if(ob->type!=OB_MESH || me->totvert==0)
3051                 return NULL;
3052         
3053         dm= mesh_get_derived_final(ob, CD_MASK_BAREMESH);
3054         vertexcosnos= MEM_callocN(6*sizeof(float)*me->totvert, "vertexcosnos map");
3055         
3056         if(dm->foreachMappedVert) {
3057                 dm->foreachMappedVert(dm, make_vertexcosnos__mapFunc, vertexcosnos);
3058         }
3059         else {
3060                 float *fp= vertexcosnos;
3061                 int a;
3062                 
3063                 for(a=0; a< me->totvert; a++, fp+=6) {
3064                         dm->getVertCo(dm, a, fp);
3065                         dm->getVertNo(dm, a, fp+3);
3066                 }
3067         }
3068         
3069         dm->release(dm);
3070         return vertexcosnos;
3071 }
3072
3073 /* ********* crazyspace *************** */
3074
3075 int editmesh_get_first_deform_matrices(float (**deformmats)[3][3], float (**deformcos)[3])
3076 {
3077         Object *ob = G.obedit;
3078         EditMesh *em = G.editMesh;
3079         ModifierData *md;
3080         DerivedMesh *dm;
3081         int i, a, numleft = 0, numVerts = 0;
3082         int cageIndex = modifiers_getCageIndex(ob, NULL);
3083         float (*defmats)[3][3] = NULL, (*deformedVerts)[3] = NULL;
3084
3085         modifiers_clearErrors(ob);
3086
3087         dm = NULL;
3088         md = ob->modifiers.first;
3089
3090         /* compute the deformation matrices and coordinates for the first
3091            modifiers with on cage editing that are enabled and support computing
3092            deform matrices */
3093         for(i = 0; md && i <= cageIndex; i++, md = md->next) {
3094                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
3095
3096                 if(!editmesh_modifier_is_enabled(md, dm))
3097                         continue;
3098
3099                 if(mti->type==eModifierTypeType_OnlyDeform && mti->deformMatricesEM) {
3100                         if(!defmats) {
3101                                 dm= getEditMeshDerivedMesh(em, ob, NULL);
3102                                 deformedVerts= editmesh_getVertexCos(em, &numVerts);
3103                                 defmats= MEM_callocN(sizeof(*defmats)*numVerts, "defmats");
3104
3105                                 for(a=0; a<numVerts; a++)
3106                                         Mat3One(defmats[a]);
3107                         }
3108
3109                         mti->deformMatricesEM(md, ob, em, dm, deformedVerts, defmats,
3110                                 numVerts);
3111                 }
3112                 else
3113                         break;
3114         }
3115
3116         for(; md && i <= cageIndex; md = md->next, i++)
3117                 if(editmesh_modifier_is_enabled(md, dm) && modifier_isDeformer(md))
3118                         numleft++;
3119
3120         if(dm)
3121                 dm->release(dm);
3122         
3123         *deformmats= defmats;
3124         *deformcos= deformedVerts;
3125