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