- change max threads from 8 to 64, need to keep an eye on stack memory use here.
[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_math.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_object.h"
75 #include "BKE_paint.h"
76 #include "BKE_subsurf.h"
77 #include "BKE_texture.h"
78 #include "BKE_utildefines.h"
79 #include "BKE_particle.h"
80 #include "BKE_bvhutils.h"
81
82 #include "BLO_sys_types.h" // for intptr_t support
83
84 #include "BIF_gl.h"
85 #include "BIF_glutil.h"
86
87 #include "gpu_buffers.h"
88 #include "GPU_draw.h"
89 #include "GPU_extensions.h"
90 #include "GPU_material.h"
91
92 ///////////////////////////////////
93 ///////////////////////////////////
94
95 static MVert *dm_getVertArray(DerivedMesh *dm)
96 {
97         MVert *mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
98
99         if (!mvert) {
100                 mvert = CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL,
101                         dm->getNumVerts(dm));
102                 CustomData_set_layer_flag(&dm->vertData, CD_MVERT, CD_FLAG_TEMPORARY);
103                 dm->copyVertArray(dm, mvert);
104         }
105
106         return mvert;
107 }
108
109 static MEdge *dm_getEdgeArray(DerivedMesh *dm)
110 {
111         MEdge *medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
112
113         if (!medge) {
114                 medge = CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL,
115                         dm->getNumEdges(dm));
116                 CustomData_set_layer_flag(&dm->edgeData, CD_MEDGE, CD_FLAG_TEMPORARY);
117                 dm->copyEdgeArray(dm, medge);
118         }
119
120         return medge;
121 }
122
123 static MFace *dm_getFaceArray(DerivedMesh *dm)
124 {
125         MFace *mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
126
127         if (!mface) {
128                 mface = CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL,
129                         dm->getNumFaces(dm));
130                 CustomData_set_layer_flag(&dm->faceData, CD_MFACE, CD_FLAG_TEMPORARY);
131                 dm->copyFaceArray(dm, mface);
132         }
133
134         return mface;
135 }
136
137 static MVert *dm_dupVertArray(DerivedMesh *dm)
138 {
139         MVert *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumVerts(dm),
140                                  "dm_dupVertArray tmp");
141
142         if(tmp) dm->copyVertArray(dm, tmp);
143
144         return tmp;
145 }
146
147 static MEdge *dm_dupEdgeArray(DerivedMesh *dm)
148 {
149         MEdge *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumEdges(dm),
150                                  "dm_dupEdgeArray tmp");
151
152         if(tmp) dm->copyEdgeArray(dm, tmp);
153
154         return tmp;
155 }
156
157 static MFace *dm_dupFaceArray(DerivedMesh *dm)
158 {
159         MFace *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumFaces(dm),
160                                  "dm_dupFaceArray tmp");
161
162         if(tmp) dm->copyFaceArray(dm, tmp);
163
164         return tmp;
165 }
166
167 void DM_init_funcs(DerivedMesh *dm)
168 {
169         /* default function implementations */
170         dm->getVertArray = dm_getVertArray;
171         dm->getEdgeArray = dm_getEdgeArray;
172         dm->getFaceArray = dm_getFaceArray;
173         dm->dupVertArray = dm_dupVertArray;
174         dm->dupEdgeArray = dm_dupEdgeArray;
175         dm->dupFaceArray = dm_dupFaceArray;
176
177         dm->getVertData = DM_get_vert_data;
178         dm->getEdgeData = DM_get_edge_data;
179         dm->getFaceData = DM_get_face_data;
180         dm->getVertDataArray = DM_get_vert_data_layer;
181         dm->getEdgeDataArray = DM_get_edge_data_layer;
182         dm->getFaceDataArray = DM_get_face_data_layer;
183
184         bvhcache_init(&dm->bvhCache);
185 }
186
187 void DM_init(DerivedMesh *dm, DerivedMeshType type,
188              int numVerts, int numEdges, int numFaces)
189 {
190         dm->type = type;
191         dm->numVertData = numVerts;
192         dm->numEdgeData = numEdges;
193         dm->numFaceData = numFaces;
194
195         DM_init_funcs(dm);
196         
197         dm->needsFree = 1;
198 }
199
200 void DM_from_template(DerivedMesh *dm, DerivedMesh *source, DerivedMeshType type,
201                       int numVerts, int numEdges, int numFaces)
202 {
203         CustomData_copy(&source->vertData, &dm->vertData, CD_MASK_DERIVEDMESH,
204                         CD_CALLOC, numVerts);
205         CustomData_copy(&source->edgeData, &dm->edgeData, CD_MASK_DERIVEDMESH,
206                         CD_CALLOC, numEdges);
207         CustomData_copy(&source->faceData, &dm->faceData, CD_MASK_DERIVEDMESH,
208                         CD_CALLOC, numFaces);
209
210         dm->type = type;
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                 bvhcache_free(&dm->bvhCache);
224                 GPU_drawobject_free( dm );
225                 CustomData_free(&dm->vertData, dm->numVertData);
226                 CustomData_free(&dm->edgeData, dm->numEdgeData);
227                 CustomData_free(&dm->faceData, dm->numFaceData);
228
229                 return 1;
230         }
231         else {
232                 CustomData_free_temporary(&dm->vertData, dm->numVertData);
233                 CustomData_free_temporary(&dm->edgeData, dm->numEdgeData);
234                 CustomData_free_temporary(&dm->faceData, dm->numFaceData);
235
236                 return 0;
237         }
238 }
239
240 void DM_to_mesh(DerivedMesh *dm, Mesh *me)
241 {
242         /* dm might depend on me, so we need to do everything with a local copy */
243         Mesh tmp = *me;
244         int totvert, totedge, totface;
245
246         memset(&tmp.vdata, 0, sizeof(tmp.vdata));
247         memset(&tmp.edata, 0, sizeof(tmp.edata));
248         memset(&tmp.fdata, 0, sizeof(tmp.fdata));
249
250         totvert = tmp.totvert = dm->getNumVerts(dm);
251         totedge = tmp.totedge = dm->getNumEdges(dm);
252         totface = tmp.totface = dm->getNumFaces(dm);
253
254         CustomData_copy(&dm->vertData, &tmp.vdata, CD_MASK_MESH, CD_DUPLICATE, totvert);
255         CustomData_copy(&dm->edgeData, &tmp.edata, CD_MASK_MESH, CD_DUPLICATE, totedge);
256         CustomData_copy(&dm->faceData, &tmp.fdata, CD_MASK_MESH, CD_DUPLICATE, totface);
257
258         /* not all DerivedMeshes store their verts/edges/faces in CustomData, so
259            we set them here in case they are missing */
260         if(!CustomData_has_layer(&tmp.vdata, CD_MVERT))
261                 CustomData_add_layer(&tmp.vdata, CD_MVERT, CD_ASSIGN, dm->dupVertArray(dm), totvert);
262         if(!CustomData_has_layer(&tmp.edata, CD_MEDGE))
263                 CustomData_add_layer(&tmp.edata, CD_MEDGE, CD_ASSIGN, dm->dupEdgeArray(dm), totedge);
264         if(!CustomData_has_layer(&tmp.fdata, CD_MFACE))
265                 CustomData_add_layer(&tmp.fdata, CD_MFACE, CD_ASSIGN, dm->dupFaceArray(dm), totface);
266
267         mesh_update_customdata_pointers(&tmp);
268
269         CustomData_free(&me->vdata, me->totvert);
270         CustomData_free(&me->edata, me->totedge);
271         CustomData_free(&me->fdata, me->totface);
272
273         /* if the number of verts has changed, remove invalid data */
274         if(tmp.totvert != me->totvert) {
275                 if(me->key) me->key->id.us--;
276                 me->key = NULL;
277         }
278
279         *me = tmp;
280 }
281
282 void DM_to_meshkey(DerivedMesh *dm, Mesh *me, KeyBlock *kb)
283 {
284         int a, totvert = dm->getNumVerts(dm);
285         float *fp;
286         MVert *mvert;
287         
288         if(totvert==0 || me->totvert==0 || me->totvert!=totvert) return;
289         
290         if(kb->data) MEM_freeN(kb->data);
291         kb->data= MEM_callocN(me->key->elemsize*me->totvert, "kb->data");
292         kb->totelem= totvert;
293         
294         fp= kb->data;
295         mvert=dm->getVertDataArray(dm, CD_MVERT);
296         
297         for(a=0; a<kb->totelem; a++, fp+=3, mvert++) {
298                 VECCOPY(fp, mvert->co);
299         }
300 }
301
302 void DM_set_only_copy(DerivedMesh *dm, CustomDataMask mask)
303 {
304         CustomData_set_only_copy(&dm->vertData, mask);
305         CustomData_set_only_copy(&dm->edgeData, mask);
306         CustomData_set_only_copy(&dm->faceData, mask);
307 }
308
309 void DM_add_vert_layer(DerivedMesh *dm, int type, int alloctype, void *layer)
310 {
311         CustomData_add_layer(&dm->vertData, type, alloctype, layer, dm->numVertData);
312 }
313
314 void DM_add_edge_layer(DerivedMesh *dm, int type, int alloctype, void *layer)
315 {
316         CustomData_add_layer(&dm->edgeData, type, alloctype, layer, dm->numEdgeData);
317 }
318
319 void DM_add_face_layer(DerivedMesh *dm, int type, int alloctype, void *layer)
320 {
321         CustomData_add_layer(&dm->faceData, type, alloctype, layer, dm->numFaceData);
322 }
323
324 void *DM_get_vert_data(DerivedMesh *dm, int index, int type)
325 {
326         return CustomData_get(&dm->vertData, index, type);
327 }
328
329 void *DM_get_edge_data(DerivedMesh *dm, int index, int type)
330 {
331         return CustomData_get(&dm->edgeData, index, type);
332 }
333
334 void *DM_get_face_data(DerivedMesh *dm, int index, int type)
335 {
336         return CustomData_get(&dm->faceData, index, type);
337 }
338
339 void *DM_get_vert_data_layer(DerivedMesh *dm, int type)
340 {
341         if(type == CD_MVERT)
342                 return dm->getVertArray(dm);
343
344         return CustomData_get_layer(&dm->vertData, type);
345 }
346
347 void *DM_get_edge_data_layer(DerivedMesh *dm, int type)
348 {
349         if(type == CD_MEDGE)
350                 return dm->getEdgeArray(dm);
351
352         return CustomData_get_layer(&dm->edgeData, type);
353 }
354
355 void *DM_get_face_data_layer(DerivedMesh *dm, int type)
356 {
357         if(type == CD_MFACE)
358                 return dm->getFaceArray(dm);
359
360         return CustomData_get_layer(&dm->faceData, type);
361 }
362
363 void DM_set_vert_data(DerivedMesh *dm, int index, int type, void *data)
364 {
365         CustomData_set(&dm->vertData, index, type, data);
366 }
367
368 void DM_set_edge_data(DerivedMesh *dm, int index, int type, void *data)
369 {
370         CustomData_set(&dm->edgeData, index, type, data);
371 }
372
373 void DM_set_face_data(DerivedMesh *dm, int index, int type, void *data)
374 {
375         CustomData_set(&dm->faceData, index, type, data);
376 }
377
378 void DM_copy_vert_data(DerivedMesh *source, DerivedMesh *dest,
379                        int source_index, int dest_index, int count)
380 {
381         CustomData_copy_data(&source->vertData, &dest->vertData,
382                              source_index, dest_index, count);
383 }
384
385 void DM_copy_edge_data(DerivedMesh *source, DerivedMesh *dest,
386                        int source_index, int dest_index, int count)
387 {
388         CustomData_copy_data(&source->edgeData, &dest->edgeData,
389                              source_index, dest_index, count);
390 }
391
392 void DM_copy_face_data(DerivedMesh *source, DerivedMesh *dest,
393                        int source_index, int dest_index, int count)
394 {
395         CustomData_copy_data(&source->faceData, &dest->faceData,
396                              source_index, dest_index, count);
397 }
398
399 void DM_free_vert_data(struct DerivedMesh *dm, int index, int count)
400 {
401         CustomData_free_elem(&dm->vertData, index, count);
402 }
403
404 void DM_free_edge_data(struct DerivedMesh *dm, int index, int count)
405 {
406         CustomData_free_elem(&dm->edgeData, index, count);
407 }
408
409 void DM_free_face_data(struct DerivedMesh *dm, int index, int count)
410 {
411         CustomData_free_elem(&dm->faceData, index, count);
412 }
413
414 void DM_interp_vert_data(DerivedMesh *source, DerivedMesh *dest,
415                          int *src_indices, float *weights,
416                          int count, int dest_index)
417 {
418         CustomData_interp(&source->vertData, &dest->vertData, src_indices,
419                           weights, NULL, count, dest_index);
420 }
421
422 void DM_interp_edge_data(DerivedMesh *source, DerivedMesh *dest,
423                          int *src_indices,
424                          float *weights, EdgeVertWeight *vert_weights,
425                          int count, int dest_index)
426 {
427         CustomData_interp(&source->edgeData, &dest->edgeData, src_indices,
428                           weights, (float*)vert_weights, count, dest_index);
429 }
430
431 void DM_interp_face_data(DerivedMesh *source, DerivedMesh *dest,
432                          int *src_indices,
433                          float *weights, FaceVertWeight *vert_weights,
434                          int count, int dest_index)
435 {
436         CustomData_interp(&source->faceData, &dest->faceData, src_indices,
437                           weights, (float*)vert_weights, count, dest_index);
438 }
439
440 void DM_swap_face_data(DerivedMesh *dm, int index, int *corner_indices)
441 {
442         CustomData_swap(&dm->faceData, index, corner_indices);
443 }
444
445 ///
446
447 static DerivedMesh *getMeshDerivedMesh(Mesh *me, Object *ob, float (*vertCos)[3])
448 {
449         DerivedMesh *dm = CDDM_from_mesh(me, ob);
450         
451         if(!dm)
452                 return NULL;
453         
454         if (vertCos)
455                 CDDM_apply_vert_coords(dm, vertCos);
456
457         CDDM_calc_normals(dm);
458
459         return dm;
460 }
461
462 ///
463
464 typedef struct {
465         DerivedMesh dm;
466
467         EditMesh *em;
468         float (*vertexCos)[3];
469         float (*vertexNos)[3];
470         float (*faceNos)[3];
471 } EditMeshDerivedMesh;
472
473 static void emDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData)
474 {
475         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
476         EditVert *eve;
477         int i;
478
479         for (i=0,eve= emdm->em->verts.first; eve; i++,eve=eve->next) {
480                 if (emdm->vertexCos) {
481                         func(userData, i, emdm->vertexCos[i], emdm->vertexNos[i], NULL);
482                 } else {
483                         func(userData, i, eve->co, eve->no, NULL);
484                 }
485         }
486 }
487 static void emDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData)
488 {
489         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
490         EditEdge *eed;
491         int i;
492
493         if (emdm->vertexCos) {
494                 EditVert *eve;
495
496                 for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
497                         eve->tmp.l = (intptr_t) i++;
498                 for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next)
499                         func(userData, i, emdm->vertexCos[(int) eed->v1->tmp.l], emdm->vertexCos[(int) eed->v2->tmp.l]);
500         } else {
501                 for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next)
502                         func(userData, i, eed->v1->co, eed->v2->co);
503         }
504 }
505 static void emDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) 
506 {
507         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
508         EditEdge *eed;
509         int i;
510
511         if (emdm->vertexCos) {
512                 EditVert *eve;
513
514                 for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
515                         eve->tmp.l = (intptr_t) i++;
516
517                 glBegin(GL_LINES);
518                 for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
519                         if(!setDrawOptions || setDrawOptions(userData, i)) {
520                                 glVertex3fv(emdm->vertexCos[(int) eed->v1->tmp.l]);
521                                 glVertex3fv(emdm->vertexCos[(int) eed->v2->tmp.l]);
522                         }
523                 }
524                 glEnd();
525         } else {
526                 glBegin(GL_LINES);
527                 for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
528                         if(!setDrawOptions || setDrawOptions(userData, i)) {
529                                 glVertex3fv(eed->v1->co);
530                                 glVertex3fv(eed->v2->co);
531                         }
532                 }
533                 glEnd();
534         }
535 }
536 static void emDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
537 {
538         emDM_drawMappedEdges(dm, NULL, NULL);
539 }
540 static void emDM_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) 
541 {
542         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
543         EditEdge *eed;
544         int i;
545
546         if (emdm->vertexCos) {
547                 EditVert *eve;
548
549                 for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
550                         eve->tmp.l = (intptr_t) i++;
551
552                 glBegin(GL_LINES);
553                 for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
554                         if(!setDrawOptions || setDrawOptions(userData, i)) {
555                                 setDrawInterpOptions(userData, i, 0.0);
556                                 glVertex3fv(emdm->vertexCos[(int) eed->v1->tmp.l]);
557                                 setDrawInterpOptions(userData, i, 1.0);
558                                 glVertex3fv(emdm->vertexCos[(int) eed->v2->tmp.l]);
559                         }
560                 }
561                 glEnd();
562         } else {
563                 glBegin(GL_LINES);
564                 for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
565                         if(!setDrawOptions || setDrawOptions(userData, i)) {
566                                 setDrawInterpOptions(userData, i, 0.0);
567                                 glVertex3fv(eed->v1->co);
568                                 setDrawInterpOptions(userData, i, 1.0);
569                                 glVertex3fv(eed->v2->co);
570                         }
571                 }
572                 glEnd();
573         }
574 }
575
576 static void emDM_drawUVEdges(DerivedMesh *dm)
577 {
578         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
579         EditFace *efa;
580         MTFace *tf;
581
582         glBegin(GL_LINES);
583         for(efa= emdm->em->faces.first; efa; efa= efa->next) {
584                 tf = CustomData_em_get(&emdm->em->fdata, efa->data, CD_MTFACE);
585
586                 if(tf && !(efa->h)) {
587                         glVertex2fv(tf->uv[0]);
588                         glVertex2fv(tf->uv[1]);
589
590                         glVertex2fv(tf->uv[1]);
591                         glVertex2fv(tf->uv[2]);
592
593                         if (!efa->v4) {
594                                 glVertex2fv(tf->uv[2]);
595                                 glVertex2fv(tf->uv[0]);
596                         } else {
597                                 glVertex2fv(tf->uv[2]);
598                                 glVertex2fv(tf->uv[3]);
599                                 glVertex2fv(tf->uv[3]);
600                                 glVertex2fv(tf->uv[0]);
601                         }
602                 }
603         }
604         glEnd();
605 }
606
607 static void emDM__calcFaceCent(EditFace *efa, float cent[3], float (*vertexCos)[3])
608 {
609         if (vertexCos) {
610                 VECCOPY(cent, vertexCos[(int) efa->v1->tmp.l]);
611                 add_v3_v3v3(cent, cent, vertexCos[(int) efa->v2->tmp.l]);
612                 add_v3_v3v3(cent, cent, vertexCos[(int) efa->v3->tmp.l]);
613                 if (efa->v4) add_v3_v3v3(cent, cent, vertexCos[(int) efa->v4->tmp.l]);
614         } else {
615                 VECCOPY(cent, efa->v1->co);
616                 add_v3_v3v3(cent, cent, efa->v2->co);
617                 add_v3_v3v3(cent, cent, efa->v3->co);
618                 if (efa->v4) add_v3_v3v3(cent, cent, efa->v4->co);
619         }
620
621         if (efa->v4) {
622                 mul_v3_fl(cent, 0.25f);
623         } else {
624                 mul_v3_fl(cent, 0.33333333333f);
625         }
626 }
627 static void emDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData)
628 {
629         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
630         EditVert *eve;
631         EditFace *efa;
632         float cent[3];
633         int i;
634
635         if (emdm->vertexCos) {
636                 for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
637                         eve->tmp.l = (intptr_t) i++;
638         }
639
640         for(i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
641                 emDM__calcFaceCent(efa, cent, emdm->vertexCos);
642                 func(userData, i, cent, emdm->vertexCos?emdm->faceNos[i]:efa->n);
643         }
644 }
645 static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors)
646 {
647         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
648         EditFace *efa;
649         int i, draw;
650
651         if (emdm->vertexCos) {
652                 EditVert *eve;
653
654                 for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
655                         eve->tmp.l = (intptr_t) i++;
656
657                 for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
658                         int drawSmooth = (efa->flag & ME_SMOOTH);
659                         draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth);
660                         if(draw) {
661                                 if (draw==2) { /* enabled with stipple */
662                                         glEnable(GL_POLYGON_STIPPLE);
663                                         glPolygonStipple(stipple_quarttone);
664                                 }
665                                 
666                                 glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
667
668                                 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
669                                 if (!drawSmooth) {
670                                         glNormal3fv(emdm->faceNos[i]);
671                                         glVertex3fv(emdm->vertexCos[(int) efa->v1->tmp.l]);
672                                         glVertex3fv(emdm->vertexCos[(int) efa->v2->tmp.l]);
673                                         glVertex3fv(emdm->vertexCos[(int) efa->v3->tmp.l]);
674                                         if(efa->v4) glVertex3fv(emdm->vertexCos[(int) efa->v4->tmp.l]);
675                                 } else {
676                                         glNormal3fv(emdm->vertexNos[(int) efa->v1->tmp.l]);
677                                         glVertex3fv(emdm->vertexCos[(int) efa->v1->tmp.l]);
678                                         glNormal3fv(emdm->vertexNos[(int) efa->v2->tmp.l]);
679                                         glVertex3fv(emdm->vertexCos[(int) efa->v2->tmp.l]);
680                                         glNormal3fv(emdm->vertexNos[(int) efa->v3->tmp.l]);
681                                         glVertex3fv(emdm->vertexCos[(int) efa->v3->tmp.l]);
682                                         if(efa->v4) {
683                                                 glNormal3fv(emdm->vertexNos[(int) efa->v4->tmp.l]);
684                                                 glVertex3fv(emdm->vertexCos[(int) efa->v4->tmp.l]);
685                                         }
686                                 }
687                                 glEnd();
688                                 
689                                 if (draw==2)
690                                         glDisable(GL_POLYGON_STIPPLE);
691                         }
692                 }
693         } else {
694                 for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
695                         int drawSmooth = (efa->flag & ME_SMOOTH);
696                         draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth);
697                         if(draw) {
698                                 if (draw==2) { /* enabled with stipple */
699                                         glEnable(GL_POLYGON_STIPPLE);
700                                         glPolygonStipple(stipple_quarttone);
701                                 }
702                                 glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
703
704                                 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
705                                 if (!drawSmooth) {
706                                         glNormal3fv(efa->n);
707                                         glVertex3fv(efa->v1->co);
708                                         glVertex3fv(efa->v2->co);
709                                         glVertex3fv(efa->v3->co);
710                                         if(efa->v4) glVertex3fv(efa->v4->co);
711                                 } else {
712                                         glNormal3fv(efa->v1->no);
713                                         glVertex3fv(efa->v1->co);
714                                         glNormal3fv(efa->v2->no);
715                                         glVertex3fv(efa->v2->co);
716                                         glNormal3fv(efa->v3->no);
717                                         glVertex3fv(efa->v3->co);
718                                         if(efa->v4) {
719                                                 glNormal3fv(efa->v4->no);
720                                                 glVertex3fv(efa->v4->co);
721                                         }
722                                 }
723                                 glEnd();
724                                 
725                                 if (draw==2)
726                                         glDisable(GL_POLYGON_STIPPLE);
727                         }
728                 }
729         }
730 }
731
732 static void emDM_drawFacesTex_common(DerivedMesh *dm,
733                int (*drawParams)(MTFace *tface, MCol *mcol, int matnr),
734                int (*drawParamsMapped)(void *userData, int index),
735                void *userData) 
736 {
737         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
738         EditMesh *em= emdm->em;
739         float (*vertexCos)[3]= emdm->vertexCos;
740         float (*vertexNos)[3]= emdm->vertexNos;
741         EditFace *efa;
742         int i;
743
744         /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
745         glShadeModel(GL_SMOOTH);
746         
747         if (vertexCos) {
748                 EditVert *eve;
749
750                 for (i=0,eve=em->verts.first; eve; eve= eve->next)
751                         eve->tmp.l = (intptr_t) i++;
752
753                 for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
754                         MTFace *tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
755                         MCol *mcol= CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
756                         unsigned char *cp= NULL;
757                         int drawSmooth= (efa->flag & ME_SMOOTH);
758                         int flag;
759
760                         if(drawParams)
761                                 flag= drawParams(tf, mcol, efa->mat_nr);
762                         else if(drawParamsMapped)
763                                 flag= drawParamsMapped(userData, i);
764                         else
765                                 flag= 1;
766
767                         if(flag != 0) { /* flag 0 == the face is hidden or invisible */
768                                 
769                                 /* we always want smooth here since otherwise vertex colors dont interpolate */
770                                 if (mcol) {
771                                         if (flag==1) {
772                                                 cp= (unsigned char*)mcol;
773                                         }
774                                 } else {
775                                         glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
776                                 } 
777                                 
778                                 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
779                                 if (!drawSmooth) {
780                                         glNormal3fv(emdm->faceNos[i]);
781
782                                         if(tf) glTexCoord2fv(tf->uv[0]);
783                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
784                                         glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
785
786                                         if(tf) glTexCoord2fv(tf->uv[1]);
787                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
788                                         glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
789
790                                         if(tf) glTexCoord2fv(tf->uv[2]);
791                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
792                                         glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
793
794                                         if(efa->v4) {
795                                                 if(tf) glTexCoord2fv(tf->uv[3]);
796                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
797                                                 glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
798                                         }
799                                 } else {
800                                         if(tf) glTexCoord2fv(tf->uv[0]);
801                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
802                                         glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
803                                         glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
804
805                                         if(tf) glTexCoord2fv(tf->uv[1]);
806                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
807                                         glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
808                                         glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
809
810                                         if(tf) glTexCoord2fv(tf->uv[2]);
811                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
812                                         glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
813                                         glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
814
815                                         if(efa->v4) {
816                                                 if(tf) glTexCoord2fv(tf->uv[3]);
817                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
818                                                 glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
819                                                 glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
820                                         }
821                                 }
822                                 glEnd();
823                         }
824                 }
825         } else {
826                 for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
827                         MTFace *tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
828                         MCol *mcol= CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
829                         unsigned char *cp= NULL;
830                         int drawSmooth= (efa->flag & ME_SMOOTH);
831                         int flag;
832
833                         if(drawParams)
834                                 flag= drawParams(tf, mcol, efa->mat_nr);
835                         else if(drawParamsMapped)
836                                 flag= drawParamsMapped(userData, i);
837                         else
838                                 flag= 1;
839
840                         if(flag != 0) { /* flag 0 == the face is hidden or invisible */
841                                 /* we always want smooth here since otherwise vertex colors dont interpolate */
842                                 if (mcol) {
843                                         if (flag==1) {
844                                                 cp= (unsigned char*)mcol;
845                                         }
846                                 } else {
847                                         glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
848                                 } 
849
850                                 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
851                                 if (!drawSmooth) {
852                                         glNormal3fv(efa->n);
853
854                                         if(tf) glTexCoord2fv(tf->uv[0]);
855                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
856                                         glVertex3fv(efa->v1->co);
857
858                                         if(tf) glTexCoord2fv(tf->uv[1]);
859                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
860                                         glVertex3fv(efa->v2->co);
861
862                                         if(tf) glTexCoord2fv(tf->uv[2]);
863                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
864                                         glVertex3fv(efa->v3->co);
865
866                                         if(efa->v4) {
867                                                 if(tf) glTexCoord2fv(tf->uv[3]);
868                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
869                                                 glVertex3fv(efa->v4->co);
870                                         }
871                                 } else {
872                                         if(tf) glTexCoord2fv(tf->uv[0]);
873                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
874                                         glNormal3fv(efa->v1->no);
875                                         glVertex3fv(efa->v1->co);
876
877                                         if(tf) glTexCoord2fv(tf->uv[1]);
878                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
879                                         glNormal3fv(efa->v2->no);
880                                         glVertex3fv(efa->v2->co);
881
882                                         if(tf) glTexCoord2fv(tf->uv[2]);
883                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
884                                         glNormal3fv(efa->v3->no);
885                                         glVertex3fv(efa->v3->co);
886
887                                         if(efa->v4) {
888                                                 if(tf) glTexCoord2fv(tf->uv[3]);
889                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
890                                                 glNormal3fv(efa->v4->no);
891                                                 glVertex3fv(efa->v4->co);
892                                         }
893                                 }
894                                 glEnd();
895                         }
896                 }
897         }
898 }
899
900 static void emDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr))
901 {
902         emDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
903 }
904
905 static void emDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
906 {
907         emDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
908 }
909
910 static void emDM_drawMappedFacesGLSL(DerivedMesh *dm,
911                int (*setMaterial)(int, void *attribs),
912                int (*setDrawOptions)(void *userData, int index), void *userData) 
913 {
914         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
915         EditMesh *em= emdm->em;
916         float (*vertexCos)[3]= emdm->vertexCos;
917         float (*vertexNos)[3]= emdm->vertexNos;
918         EditVert *eve;
919         EditFace *efa;
920         DMVertexAttribs attribs;
921         GPUVertexAttribs gattribs;
922         MTFace *tf;
923         int transp, new_transp, orig_transp, tfoffset;
924         int i, b, matnr, new_matnr, dodraw, layer;
925
926         dodraw = 0;
927         matnr = -1;
928
929         transp = GPU_get_material_blend_mode();
930         orig_transp = transp;
931         layer = CustomData_get_layer_index(&em->fdata, CD_MTFACE);
932         tfoffset = (layer == -1)? -1: em->fdata.layers[layer].offset;
933
934         memset(&attribs, 0, sizeof(attribs));
935
936         /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
937         glShadeModel(GL_SMOOTH);
938
939         for (i=0,eve=em->verts.first; eve; eve= eve->next)
940                 eve->tmp.l = (intptr_t) i++;
941
942 #define PASSATTRIB(efa, eve, vert) {                                                                                    \
943         if(attribs.totorco) {                                                                                                           \
944                 float *orco = attribs.orco.array[eve->tmp.l];                                                   \
945                 glVertexAttrib3fvARB(attribs.orco.glIndex, orco);                                               \
946         }                                                                                                                                                       \
947         for(b = 0; b < attribs.tottface; b++) {                                                                         \
948                 MTFace *_tf = (MTFace*)((char*)efa->data + attribs.tface[b].emOffset);  \
949                 glVertexAttrib2fvARB(attribs.tface[b].glIndex, _tf->uv[vert]);                  \
950         }                                                                                                                                                       \
951         for(b = 0; b < attribs.totmcol; b++) {                                                                          \
952                 MCol *cp = (MCol*)((char*)efa->data + attribs.mcol[b].emOffset);                \
953                 GLubyte col[4];                                                                                                                 \
954                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;                             \
955                 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col);                                    \
956         }                                                                                                                                                       \
957         if(attribs.tottang) {                                                                                                           \
958                 float *tang = attribs.tang.array[i*4 + vert];                                                   \
959                 glVertexAttrib3fvARB(attribs.tang.glIndex, tang);                                               \
960         }                                                                                                                                                       \
961 }
962
963         for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
964                 int drawSmooth= (efa->flag & ME_SMOOTH);
965
966                 if(setDrawOptions && !setDrawOptions(userData, i))
967                         continue;
968
969                 new_matnr = efa->mat_nr + 1;
970                 if(new_matnr != matnr) {
971                         dodraw = setMaterial(matnr = new_matnr, &gattribs);
972                         if(dodraw)
973                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
974                 }
975
976                 if(tfoffset != -1) {
977                         tf = (MTFace*)((char*)efa->data)+tfoffset;
978                         new_transp = tf->transp;
979
980                         if(new_transp != transp) {
981                                 if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
982                                         GPU_set_material_blend_mode(orig_transp);
983                                 else
984                                         GPU_set_material_blend_mode(new_transp);
985                                 transp = new_transp;
986                         }
987                 }
988
989                 if(dodraw) {
990                         glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
991                         if (!drawSmooth) {
992                                 if(vertexCos) glNormal3fv(emdm->faceNos[i]);
993                                 else glNormal3fv(efa->n);
994
995                                 PASSATTRIB(efa, efa->v1, 0);
996                                 if(vertexCos) glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
997                                 else glVertex3fv(efa->v1->co);
998
999                                 PASSATTRIB(efa, efa->v2, 1);
1000                                 if(vertexCos) glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
1001                                 else glVertex3fv(efa->v2->co);
1002
1003                                 PASSATTRIB(efa, efa->v3, 2);
1004                                 if(vertexCos) glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
1005                                 else glVertex3fv(efa->v3->co);
1006
1007                                 if(efa->v4) {
1008                                         PASSATTRIB(efa, efa->v4, 3);
1009                                         if(vertexCos) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
1010                                         else glVertex3fv(efa->v4->co);
1011                                 }
1012                         } else {
1013                                 PASSATTRIB(efa, efa->v1, 0);
1014                                 if(vertexCos) {
1015                                         glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
1016                                         glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
1017                                 }
1018                                 else {
1019                                         glNormal3fv(efa->v1->no);
1020                                         glVertex3fv(efa->v1->co);
1021                                 }
1022
1023                                 PASSATTRIB(efa, efa->v2, 1);
1024                                 if(vertexCos) {
1025                                         glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
1026                                         glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
1027                                 }
1028                                 else {
1029                                         glNormal3fv(efa->v2->no);
1030                                         glVertex3fv(efa->v2->co);
1031                                 }
1032
1033                                 PASSATTRIB(efa, efa->v3, 2);
1034                                 if(vertexCos) {
1035                                         glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
1036                                         glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
1037                                 }
1038                                 else {
1039                                         glNormal3fv(efa->v3->no);
1040                                         glVertex3fv(efa->v3->co);
1041                                 }
1042
1043                                 if(efa->v4) {
1044                                         PASSATTRIB(efa, efa->v4, 3);
1045                                         if(vertexCos) {
1046                                                 glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
1047                                                 glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
1048                                         }
1049                                         else {
1050                                                 glNormal3fv(efa->v4->no);
1051                                                 glVertex3fv(efa->v4->co);
1052                                         }
1053                                 }
1054                         }
1055                         glEnd();
1056                 }
1057         }
1058 }
1059
1060 static void emDM_drawFacesGLSL(DerivedMesh *dm,
1061                int (*setMaterial)(int, void *attribs))
1062 {
1063         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1064 }
1065
1066 static void emDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
1067 {
1068         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
1069         EditVert *eve;
1070         int i;
1071
1072         if (emdm->em->verts.first) {
1073                 for (i=0,eve= emdm->em->verts.first; eve; i++,eve= eve->next) {
1074                         if (emdm->vertexCos) {
1075                                 DO_MINMAX(emdm->vertexCos[i], min_r, max_r);
1076                         } else {
1077                                 DO_MINMAX(eve->co, min_r, max_r);
1078                         }
1079                 }
1080         } else {
1081                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
1082         }
1083 }
1084 static int emDM_getNumVerts(DerivedMesh *dm)
1085 {
1086         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
1087
1088         return BLI_countlist(&emdm->em->verts);
1089 }
1090
1091 static int emDM_getNumEdges(DerivedMesh *dm)
1092 {
1093         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
1094
1095         return BLI_countlist(&emdm->em->edges);
1096 }
1097
1098 static int emDM_getNumFaces(DerivedMesh *dm)
1099 {
1100         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
1101
1102         return BLI_countlist(&emdm->em->faces);
1103 }
1104
1105 static void emDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
1106 {
1107         EditVert *ev = ((EditMeshDerivedMesh *)dm)->em->verts.first;
1108         int i;
1109
1110         for(i = 0; i < index; ++i) ev = ev->next;
1111
1112         VECCOPY(vert_r->co, ev->co);
1113
1114         vert_r->no[0] = ev->no[0] * 32767.0;
1115         vert_r->no[1] = ev->no[1] * 32767.0;
1116         vert_r->no[2] = ev->no[2] * 32767.0;
1117
1118         /* TODO what to do with vert_r->flag and vert_r->mat_nr? */
1119         vert_r->mat_nr = 0;
1120         vert_r->bweight = (unsigned char) (ev->bweight*255.0f);
1121 }
1122
1123 static void emDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
1124 {
1125         EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
1126         EditEdge *ee = em->edges.first;
1127         EditVert *ev, *v1, *v2;
1128         int i;
1129
1130         for(i = 0; i < index; ++i) ee = ee->next;
1131
1132         edge_r->crease = (unsigned char) (ee->crease*255.0f);
1133         edge_r->bweight = (unsigned char) (ee->bweight*255.0f);
1134         /* TODO what to do with edge_r->flag? */
1135         edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER;
1136         if (ee->seam) edge_r->flag |= ME_SEAM;
1137         if (ee->sharp) edge_r->flag |= ME_SHARP;
1138 #if 0
1139         /* this needs setup of f2 field */
1140         if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE;
1141 #endif
1142
1143         /* goddamn, we have to search all verts to find indices */
1144         v1 = ee->v1;
1145         v2 = ee->v2;
1146         for(i = 0, ev = em->verts.first; v1 || v2; i++, ev = ev->next) {
1147                 if(ev == v1) {
1148                         edge_r->v1 = i;
1149                         v1 = NULL;
1150                 }
1151                 if(ev == v2) {
1152                         edge_r->v2 = i;
1153                         v2 = NULL;
1154                 }
1155         }
1156 }
1157
1158 static void emDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
1159 {
1160         EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
1161         EditFace *ef = em->faces.first;
1162         EditVert *ev, *v1, *v2, *v3, *v4;
1163         int i;
1164
1165         for(i = 0; i < index; ++i) ef = ef->next;
1166
1167         face_r->mat_nr = ef->mat_nr;
1168         face_r->flag = ef->flag;
1169
1170         /* goddamn, we have to search all verts to find indices */
1171         v1 = ef->v1;
1172         v2 = ef->v2;
1173         v3 = ef->v3;
1174         v4 = ef->v4;
1175         if(!v4) face_r->v4 = 0;
1176
1177         for(i = 0, ev = em->verts.first; v1 || v2 || v3 || v4;
1178             i++, ev = ev->next) {
1179                 if(ev == v1) {
1180                         face_r->v1 = i;
1181                         v1 = NULL;
1182                 }
1183                 if(ev == v2) {
1184                         face_r->v2 = i;
1185                         v2 = NULL;
1186                 }
1187                 if(ev == v3) {
1188                         face_r->v3 = i;
1189                         v3 = NULL;
1190                 }
1191                 if(ev == v4) {
1192                         face_r->v4 = i;
1193                         v4 = NULL;
1194                 }
1195         }
1196
1197         test_index_face(face_r, NULL, 0, ef->v4?4:3);
1198 }
1199
1200 static void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
1201 {
1202         EditVert *ev = ((EditMeshDerivedMesh *)dm)->em->verts.first;
1203
1204         for( ; ev; ev = ev->next, ++vert_r) {
1205                 VECCOPY(vert_r->co, ev->co);
1206
1207                 vert_r->no[0] = ev->no[0] * 32767.0;
1208                 vert_r->no[1] = ev->no[1] * 32767.0;
1209                 vert_r->no[2] = ev->no[2] * 32767.0;
1210
1211                 /* TODO what to do with vert_r->flag and vert_r->mat_nr? */
1212                 vert_r->mat_nr = 0;
1213                 vert_r->flag = 0;
1214                 vert_r->bweight = (unsigned char) (ev->bweight*255.0f);
1215         }
1216 }
1217
1218 static void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
1219 {
1220         EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
1221         EditEdge *ee = em->edges.first;
1222         EditVert *ev;
1223         int i;
1224
1225         /* store vertex indices in tmp union */
1226         for(ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
1227                 ev->tmp.l = (intptr_t) i;
1228
1229         for( ; ee; ee = ee->next, ++edge_r) {
1230                 edge_r->crease = (unsigned char) (ee->crease*255.0f);
1231                 edge_r->bweight = (unsigned char) (ee->bweight*255.0f);
1232                 /* TODO what to do with edge_r->flag? */
1233                 edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER;
1234                 if (ee->seam) edge_r->flag |= ME_SEAM;
1235                 if (ee->sharp) edge_r->flag |= ME_SHARP;
1236 #if 0
1237                 /* this needs setup of f2 field */
1238                 if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE;
1239 #endif
1240
1241                 edge_r->v1 = (int)ee->v1->tmp.l;
1242                 edge_r->v2 = (int)ee->v2->tmp.l;
1243         }
1244 }
1245
1246 static void emDM_copyFaceArray(DerivedMesh *dm, MFace *face_r)
1247 {
1248         EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
1249         EditFace *ef = em->faces.first;
1250         EditVert *ev;
1251         int i;
1252
1253         /* store vertexes indices in tmp union */
1254         for(ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
1255                 ev->tmp.l = (intptr_t) i;
1256
1257         for( ; ef; ef = ef->next, ++face_r) {
1258                 face_r->mat_nr = ef->mat_nr;
1259                 face_r->flag = ef->flag;
1260
1261                 face_r->v1 = (int)ef->v1->tmp.l;
1262                 face_r->v2 = (int)ef->v2->tmp.l;
1263                 face_r->v3 = (int)ef->v3->tmp.l;
1264                 if(ef->v4) face_r->v4 = (int)ef->v4->tmp.l;
1265                 else face_r->v4 = 0;
1266
1267                 test_index_face(face_r, NULL, 0, ef->v4?4:3);
1268         }
1269 }
1270
1271 static void *emDM_getFaceDataArray(DerivedMesh *dm, int type)
1272 {
1273         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
1274         EditMesh *em= emdm->em;
1275         EditFace *efa;
1276         char *data, *emdata;
1277         void *datalayer;
1278         int index, offset, size;
1279
1280         datalayer = DM_get_face_data_layer(dm, type);
1281         if(datalayer)
1282                 return datalayer;
1283
1284         /* layers are store per face for editmesh, we convert to a temporary
1285          * data layer array in the derivedmesh when these are requested */
1286         if(type == CD_MTFACE || type == CD_MCOL) {
1287                 index = CustomData_get_layer_index(&em->fdata, type);
1288
1289                 if(index != -1) {
1290                         offset = em->fdata.layers[index].offset;
1291                         size = CustomData_sizeof(type);
1292
1293                         DM_add_face_layer(dm, type, CD_CALLOC, NULL);
1294                         index = CustomData_get_layer_index(&dm->faceData, type);
1295                         dm->faceData.layers[index].flag |= CD_FLAG_TEMPORARY;
1296
1297                         data = datalayer = DM_get_face_data_layer(dm, type);
1298                         for(efa=em->faces.first; efa; efa=efa->next, data+=size) {
1299                                 emdata = CustomData_em_get(&em->fdata, efa->data, type);
1300                                 memcpy(data, emdata, size);
1301                         }
1302                 }
1303         }
1304
1305         return datalayer;
1306 }
1307
1308 static void emDM_release(DerivedMesh *dm)
1309 {
1310         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
1311
1312         if (DM_release(dm)) {
1313                 if (emdm->vertexCos) {
1314                         MEM_freeN(emdm->vertexCos);
1315                         MEM_freeN(emdm->vertexNos);
1316                         MEM_freeN(emdm->faceNos);
1317                 }
1318
1319                 MEM_freeN(emdm);
1320         }
1321 }
1322
1323 static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em, Object *ob,
1324                                            float (*vertexCos)[3])
1325 {
1326         EditMeshDerivedMesh *emdm = MEM_callocN(sizeof(*emdm), "emdm");
1327
1328         DM_init(&emdm->dm, DM_TYPE_EDITMESH, BLI_countlist(&em->verts),
1329                          BLI_countlist(&em->edges), BLI_countlist(&em->faces));
1330
1331         emdm->dm.getMinMax = emDM_getMinMax;
1332
1333         emdm->dm.getNumVerts = emDM_getNumVerts;
1334         emdm->dm.getNumEdges = emDM_getNumEdges;
1335         emdm->dm.getNumFaces = emDM_getNumFaces;
1336
1337         emdm->dm.getVert = emDM_getVert;
1338         emdm->dm.getEdge = emDM_getEdge;
1339         emdm->dm.getFace = emDM_getFace;
1340         emdm->dm.copyVertArray = emDM_copyVertArray;
1341         emdm->dm.copyEdgeArray = emDM_copyEdgeArray;
1342         emdm->dm.copyFaceArray = emDM_copyFaceArray;
1343         emdm->dm.getFaceDataArray = emDM_getFaceDataArray;
1344
1345         emdm->dm.foreachMappedVert = emDM_foreachMappedVert;
1346         emdm->dm.foreachMappedEdge = emDM_foreachMappedEdge;
1347         emdm->dm.foreachMappedFaceCenter = emDM_foreachMappedFaceCenter;
1348
1349         emdm->dm.drawEdges = emDM_drawEdges;
1350         emdm->dm.drawMappedEdges = emDM_drawMappedEdges;
1351         emdm->dm.drawMappedEdgesInterp = emDM_drawMappedEdgesInterp;
1352         emdm->dm.drawMappedFaces = emDM_drawMappedFaces;
1353         emdm->dm.drawMappedFacesTex = emDM_drawMappedFacesTex;
1354         emdm->dm.drawMappedFacesGLSL = emDM_drawMappedFacesGLSL;
1355         emdm->dm.drawFacesTex = emDM_drawFacesTex;
1356         emdm->dm.drawFacesGLSL = emDM_drawFacesGLSL;
1357         emdm->dm.drawUVEdges = emDM_drawUVEdges;
1358
1359         emdm->dm.release = emDM_release;
1360         
1361         emdm->em = em;
1362         emdm->vertexCos = vertexCos;
1363
1364         if(CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) {
1365                 EditVert *eve;
1366                 int i;
1367
1368                 DM_add_vert_layer(&emdm->dm, CD_MDEFORMVERT, CD_CALLOC, NULL);
1369
1370                 for(eve = em->verts.first, i = 0; eve; eve = eve->next, ++i)
1371                         DM_set_vert_data(&emdm->dm, i, CD_MDEFORMVERT,
1372                                          CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT));
1373         }
1374
1375         if(vertexCos) {
1376                 EditVert *eve;
1377                 EditFace *efa;
1378                 int totface = BLI_countlist(&em->faces);
1379                 int i;
1380
1381                 for (i=0,eve=em->verts.first; eve; eve= eve->next)
1382                         eve->tmp.l = (intptr_t) i++;
1383
1384                 emdm->vertexNos = MEM_callocN(sizeof(*emdm->vertexNos)*i, "emdm_vno");
1385                 emdm->faceNos = MEM_mallocN(sizeof(*emdm->faceNos)*totface, "emdm_vno");
1386
1387                 for(i=0, efa= em->faces.first; efa; i++, efa=efa->next) {
1388                         float *v1 = vertexCos[(int) efa->v1->tmp.l];
1389                         float *v2 = vertexCos[(int) efa->v2->tmp.l];
1390                         float *v3 = vertexCos[(int) efa->v3->tmp.l];
1391                         float *no = emdm->faceNos[i];
1392                         
1393                         if(efa->v4) {
1394                                 float *v4 = vertexCos[(int) efa->v4->tmp.l];
1395
1396                                 normal_quad_v3( no,v1, v2, v3, v4);
1397                                 add_v3_v3v3(emdm->vertexNos[(int) efa->v4->tmp.l], emdm->vertexNos[(int) efa->v4->tmp.l], no);
1398                         }
1399                         else {
1400                                 normal_tri_v3( no,v1, v2, v3);
1401                         }
1402
1403                         add_v3_v3v3(emdm->vertexNos[(int) efa->v1->tmp.l], emdm->vertexNos[(int) efa->v1->tmp.l], no);
1404                         add_v3_v3v3(emdm->vertexNos[(int) efa->v2->tmp.l], emdm->vertexNos[(int) efa->v2->tmp.l], no);
1405                         add_v3_v3v3(emdm->vertexNos[(int) efa->v3->tmp.l], emdm->vertexNos[(int) efa->v3->tmp.l], no);
1406                 }
1407
1408                 for(i=0, eve= em->verts.first; eve; i++, eve=eve->next) {
1409                         float *no = emdm->vertexNos[i];
1410                         /* following Mesh convention; we use vertex coordinate itself
1411                          * for normal in this case */
1412                         if (normalize_v3(no)==0.0) {
1413                                 VECCOPY(no, vertexCos[i]);
1414                                 normalize_v3(no);
1415                         }
1416                 }
1417         }
1418
1419         return (DerivedMesh*) emdm;
1420 }
1421
1422 /***/
1423
1424 DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob, ModifierData *md)
1425 {
1426         Mesh *me = ob->data;
1427         ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1428         DerivedMesh *dm;
1429
1430         md->scene= scene;
1431         
1432         if (!(md->mode&eModifierMode_Realtime)) return NULL;
1433         if (mti->isDisabled && mti->isDisabled(md, 0)) return NULL;
1434
1435         if (mti->type==eModifierTypeType_OnlyDeform) {
1436                 int numVerts;
1437                 float (*deformedVerts)[3] = mesh_getVertexCos(me, &numVerts);
1438
1439                 mti->deformVerts(md, ob, NULL, deformedVerts, numVerts, 0, 0);
1440                 dm = getMeshDerivedMesh(me, ob, deformedVerts);
1441
1442                 MEM_freeN(deformedVerts);
1443         } else {
1444                 DerivedMesh *tdm = getMeshDerivedMesh(me, ob, NULL);
1445                 dm = mti->applyModifier(md, ob, tdm, 0, 0);
1446
1447                 if(tdm != dm) tdm->release(tdm);
1448         }
1449
1450         return dm;
1451 }
1452
1453 static float *get_editmesh_orco_verts(EditMesh *em)
1454 {
1455         EditVert *eve;
1456         float *orco;
1457         int a, totvert;
1458
1459         /* these may not really be the orco's, but it's only for preview.
1460          * could be solver better once, but isn't simple */
1461
1462         totvert= 0;
1463         for(eve=em->verts.first; eve; eve=eve->next)
1464                 totvert++;
1465         
1466         orco = MEM_mallocN(sizeof(float)*3*totvert, "EditMesh Orco");
1467
1468         for(a=0, eve=em->verts.first; eve; eve=eve->next, a+=3)
1469                 VECCOPY(orco+a, eve->co);
1470         
1471         return orco;
1472 }
1473
1474 /* orco custom data layer */
1475
1476 static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, EditMesh *em)
1477 {
1478         DerivedMesh *dm;
1479         float (*orco)[3];
1480
1481         if(em) {
1482                 dm= CDDM_from_editmesh(em, me);
1483                 orco= (float(*)[3])get_editmesh_orco_verts(em);
1484         }
1485         else {
1486                 dm= CDDM_from_mesh(me, ob);
1487                 orco= (float(*)[3])get_mesh_orco_verts(ob);
1488         }
1489
1490         CDDM_apply_vert_coords(dm, orco);
1491         CDDM_calc_normals(dm);
1492         MEM_freeN(orco);
1493
1494         return dm;
1495 }
1496
1497 static void add_orco_dm(Object *ob, EditMesh *em, DerivedMesh *dm, DerivedMesh *orcodm)
1498 {
1499         float (*orco)[3], (*layerorco)[3];
1500         int totvert;
1501
1502         totvert= dm->getNumVerts(dm);
1503
1504         if(orcodm) {
1505                 orco= MEM_callocN(sizeof(float)*3*totvert, "dm orco");
1506
1507                 if(orcodm->getNumVerts(orcodm) == totvert)
1508                         orcodm->getVertCos(orcodm, orco);
1509                 else
1510                         dm->getVertCos(dm, orco);
1511         }
1512         else {
1513                 if(em) orco= (float(*)[3])get_editmesh_orco_verts(em);
1514                 else orco= (float(*)[3])get_mesh_orco_verts(ob);
1515         }
1516
1517         transform_mesh_orco_verts(ob->data, orco, totvert, 0);
1518
1519         if((layerorco = DM_get_vert_data_layer(dm, CD_ORCO))) {
1520                 memcpy(layerorco, orco, sizeof(float)*totvert);
1521                 MEM_freeN(orco);
1522         }
1523         else
1524                 DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, orco);
1525 }
1526
1527 /* weight paint colors */
1528
1529 /* Something of a hack, at the moment deal with weightpaint
1530  * by tucking into colors during modifier eval, only in
1531  * wpaint mode. Works ok but need to make sure recalc
1532  * happens on enter/exit wpaint.
1533  */
1534
1535 void weight_to_rgb(float input, float *fr, float *fg, float *fb)
1536 {
1537         float blend;
1538         
1539         blend= ((input/2.0f)+0.5f);
1540         
1541         if (input<=0.25f){      // blue->cyan
1542                 *fr= 0.0f;
1543                 *fg= blend*input*4.0f;
1544                 *fb= blend;
1545         }
1546         else if (input<=0.50f){ // cyan->green
1547                 *fr= 0.0f;
1548                 *fg= blend;
1549                 *fb= blend*(1.0f-((input-0.25f)*4.0f)); 
1550         }
1551         else if (input<=0.75){  // green->yellow
1552                 *fr= blend * ((input-0.50f)*4.0f);
1553                 *fg= blend;
1554                 *fb= 0.0f;
1555         }
1556         else if (input<=1.0){ // yellow->red
1557                 *fr= blend;
1558                 *fg= blend * (1.0f-((input-0.75f)*4.0f)); 
1559                 *fb= 0.0f;
1560         }
1561 }
1562
1563 static void calc_weightpaint_vert_color(Object *ob, ColorBand *coba, int vert, unsigned char *col)
1564 {
1565         Mesh *me = ob->data;
1566         float colf[4], input = 0.0f;
1567         int i;
1568
1569         if (me->dvert) {
1570                 for (i=0; i<me->dvert[vert].totweight; i++)
1571                         if (me->dvert[vert].dw[i].def_nr==ob->actdef-1)
1572                                 input+=me->dvert[vert].dw[i].weight;            
1573         }
1574
1575         CLAMP(input, 0.0f, 1.0f);
1576         
1577         if(coba)
1578                 do_colorband(coba, input, colf);
1579         else
1580                 weight_to_rgb(input, colf, colf+1, colf+2);
1581         
1582         col[3] = (unsigned char)(colf[0] * 255.0f);
1583         col[2] = (unsigned char)(colf[1] * 255.0f);
1584         col[1] = (unsigned char)(colf[2] * 255.0f);
1585         col[0] = 255;
1586 }
1587
1588 static ColorBand *stored_cb= NULL;
1589
1590 void vDM_ColorBand_store(ColorBand *coba)
1591 {
1592         stored_cb= coba;
1593 }
1594
1595 static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm)
1596 {
1597         Mesh *me = ob->data;
1598         MFace *mf = me->mface;
1599         ColorBand *coba= stored_cb;     /* warning, not a local var */
1600         unsigned char *wtcol;
1601         int i;
1602         
1603         wtcol = MEM_callocN (sizeof (unsigned char) * me->totface*4*4, "weightmap");
1604         
1605         memset(wtcol, 0x55, sizeof (unsigned char) * me->totface*4*4);
1606         for (i=0; i<me->totface; i++, mf++) {
1607                 calc_weightpaint_vert_color(ob, coba, mf->v1, &wtcol[(i*4 + 0)*4]); 
1608                 calc_weightpaint_vert_color(ob, coba, mf->v2, &wtcol[(i*4 + 1)*4]); 
1609                 calc_weightpaint_vert_color(ob, coba, mf->v3, &wtcol[(i*4 + 2)*4]); 
1610                 if (mf->v4)
1611                         calc_weightpaint_vert_color(ob, coba, mf->v4, &wtcol[(i*4 + 3)*4]); 
1612         }
1613         
1614         CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_ASSIGN, wtcol, dm->numFaceData);
1615 }
1616
1617 /* new value for useDeform -1  (hack for the gameengine):
1618  * - apply only the modifier stack of the object, skipping the virtual modifiers,
1619  * - don't apply the key
1620  * - apply deform modifiers and input vertexco
1621  */
1622 static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos)[3],
1623                                 DerivedMesh **deform_r, DerivedMesh **final_r,
1624                                 int useRenderParams, int useDeform,
1625                                 int needMapping, CustomDataMask dataMask, int index)
1626 {
1627         Mesh *me = ob->data;
1628         ModifierData *firstmd, *md;
1629         LinkNode *datamasks, *curr;
1630         CustomDataMask mask;
1631         float (*deformedVerts)[3] = NULL;
1632         DerivedMesh *dm, *orcodm, *finaldm;
1633         int numVerts = me->totvert;
1634         int required_mode;
1635
1636         md = firstmd = (useDeform<0) ? ob->modifiers.first : modifiers_getVirtualModifierList(ob);
1637
1638         modifiers_clearErrors(ob);
1639
1640         if(useRenderParams) required_mode = eModifierMode_Render;
1641         else required_mode = eModifierMode_Realtime;
1642
1643         /* we always want to keep original indices */
1644         dataMask |= CD_MASK_ORIGINDEX;
1645
1646         datamasks = modifiers_calcDataMasks(scene, ob, md, dataMask, required_mode);
1647         curr = datamasks;
1648
1649         if(deform_r) *deform_r = NULL;
1650         *final_r = NULL;
1651
1652         if(useDeform) {
1653                 if(inputVertexCos)
1654                         deformedVerts = inputVertexCos;
1655                 
1656                 /* Apply all leading deforming modifiers */
1657                 for(;md; md = md->next, curr = curr->next) {
1658                         ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1659
1660                         md->scene= scene;
1661                         
1662                         if(!modifier_isEnabled(scene, md, required_mode)) continue;
1663                         if(useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue;
1664
1665                         if(mti->type == eModifierTypeType_OnlyDeform) {
1666                                 if(!deformedVerts)
1667                                         deformedVerts = mesh_getVertexCos(me, &numVerts);
1668
1669                                 mti->deformVerts(md, ob, NULL, deformedVerts, numVerts, useRenderParams, useDeform);
1670                         } else {
1671                                 break;
1672                         }
1673                         
1674                         /* grab modifiers until index i */
1675                         if((index >= 0) && (modifiers_indexInObject(ob, md) >= index))
1676                                 break;
1677                 }
1678
1679                 /* Result of all leading deforming modifiers is cached for
1680                  * places that wish to use the original mesh but with deformed
1681                  * coordinates (vpaint, etc.)
1682                  */
1683                 if (deform_r) {
1684                         *deform_r = CDDM_from_mesh(me, ob);
1685
1686                         if(deformedVerts) {
1687                                 CDDM_apply_vert_coords(*deform_r, deformedVerts);
1688                                 CDDM_calc_normals(*deform_r);
1689                         }
1690                 }
1691         } else {
1692                 /* default behaviour for meshes */
1693                 if(inputVertexCos)
1694                         deformedVerts = inputVertexCos;
1695                 else
1696                         deformedVerts = mesh_getVertexCos(me, &numVerts);
1697         }
1698
1699
1700         /* Now apply all remaining modifiers. If useDeform is off then skip
1701          * OnlyDeform ones. 
1702          */
1703         dm = NULL;
1704         orcodm = NULL;
1705
1706         for(;md; md = md->next, curr = curr->next) {
1707                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1708
1709                 md->scene= scene;
1710                 
1711                 if(!modifier_isEnabled(scene, md, required_mode)) continue;
1712                 if(mti->type == eModifierTypeType_OnlyDeform && !useDeform) continue;
1713                 if((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) {
1714                         modifier_setError(md, "Modifier requires original data, bad stack position.");
1715                         continue;
1716                 }
1717                 if(needMapping && !modifier_supportsMapping(md)) continue;
1718                 if(useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue;
1719
1720                 /* add an orco layer if needed by this modifier */
1721                 if(dm && mti->requiredDataMask) {
1722                         mask = mti->requiredDataMask(ob, md);
1723                         if(mask & CD_MASK_ORCO)
1724                                 add_orco_dm(ob, NULL, dm, orcodm);
1725                 }
1726
1727                 /* How to apply modifier depends on (a) what we already have as
1728                  * a result of previous modifiers (could be a DerivedMesh or just
1729                  * deformed vertices) and (b) what type the modifier is.
1730                  */
1731
1732                 if(mti->type == eModifierTypeType_OnlyDeform) {
1733                         
1734                         /* No existing verts to deform, need to build them. */
1735                         if(!deformedVerts) {
1736                                 if(dm) {
1737                                         /* Deforming a derived mesh, read the vertex locations
1738                                          * out of the mesh and deform them. Once done with this
1739                                          * run of deformers verts will be written back.
1740                                          */
1741                                         numVerts = dm->getNumVerts(dm);
1742                                         deformedVerts =
1743                                             MEM_mallocN(sizeof(*deformedVerts) * numVerts, "dfmv");
1744                                         dm->getVertCos(dm, deformedVerts);
1745                                 } else {
1746                                         deformedVerts = mesh_getVertexCos(me, &numVerts);
1747                                 }
1748                         }
1749
1750                         mti->deformVerts(md, ob, dm, deformedVerts, numVerts, useRenderParams, useDeform);
1751                 } else {
1752                         DerivedMesh *ndm;
1753
1754                         /* apply vertex coordinates or build a DerivedMesh as necessary */
1755                         if(dm) {
1756                                 if(deformedVerts) {
1757                                         DerivedMesh *tdm = CDDM_copy(dm);
1758                                         dm->release(dm);
1759                                         dm = tdm;
1760
1761                                         CDDM_apply_vert_coords(dm, deformedVerts);
1762                                         CDDM_calc_normals(dm);
1763                                 }
1764                         } else {
1765                                 dm = CDDM_from_mesh(me, ob);
1766
1767                                 if(deformedVerts) {
1768                                         CDDM_apply_vert_coords(dm, deformedVerts);
1769                                         CDDM_calc_normals(dm);
1770                                 }
1771
1772                                 if(dataMask & CD_MASK_WEIGHT_MCOL)
1773                                         add_weight_mcol_dm(ob, dm);
1774                         }
1775
1776                         /* create an orco derivedmesh in parallel */
1777                         mask= (CustomDataMask)GET_INT_FROM_POINTER(curr->link);
1778                         if(mask & CD_MASK_ORCO) {
1779                                 if(!orcodm)
1780                                         orcodm= create_orco_dm(ob, me, NULL);
1781
1782                                 mask &= ~CD_MASK_ORCO;
1783                                 DM_set_only_copy(orcodm, mask);
1784                                 ndm = mti->applyModifier(md, ob, orcodm, useRenderParams, 0);
1785
1786                                 if(ndm) {
1787                                         /* if the modifier returned a new dm, release the old one */
1788                                         if(orcodm && orcodm != ndm) orcodm->release(orcodm);
1789                                         orcodm = ndm;
1790                                 }
1791                         }
1792
1793                         /* set the DerivedMesh to only copy needed data */
1794                         DM_set_only_copy(dm, mask);
1795                         
1796                         /* add an origspace layer if needed */
1797                         if(((CustomDataMask)GET_INT_FROM_POINTER(curr->link)) & CD_MASK_ORIGSPACE)
1798                                 if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE))
1799                                         DM_add_face_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL);
1800
1801                         ndm = mti->applyModifier(md, ob, dm, useRenderParams, !inputVertexCos);
1802
1803                         if(ndm) {
1804                                 /* if the modifier returned a new dm, release the old one */
1805                                 if(dm && dm != ndm) dm->release(dm);
1806
1807                                 dm = ndm;
1808
1809                                 if(deformedVerts) {
1810                                         if(deformedVerts != inputVertexCos)
1811                                                 MEM_freeN(deformedVerts);
1812
1813                                         deformedVerts = NULL;
1814                                 }
1815                         } 
1816                 }
1817                 
1818                 /* grab modifiers until index i */
1819                 if((index >= 0) && (modifiers_indexInObject(ob, md) >= index))
1820                         break;
1821         }
1822
1823         for(md=firstmd; md; md=md->next)
1824                 modifier_freeTemporaryData(md);
1825
1826         /* Yay, we are done. If we have a DerivedMesh and deformed vertices
1827          * need to apply these back onto the DerivedMesh. If we have no
1828          * DerivedMesh then we need to build one.
1829          */
1830         if(dm && deformedVerts) {
1831                 finaldm = CDDM_copy(dm);
1832
1833                 dm->release(dm);
1834
1835                 CDDM_apply_vert_coords(finaldm, deformedVerts);
1836                 CDDM_calc_normals(finaldm);
1837
1838                 if(dataMask & CD_MASK_WEIGHT_MCOL)
1839                         add_weight_mcol_dm(ob, finaldm);
1840         } else if(dm) {
1841                 finaldm = dm;
1842         } else {
1843                 finaldm = CDDM_from_mesh(me, ob);
1844
1845                 if(deformedVerts) {
1846                         CDDM_apply_vert_coords(finaldm, deformedVerts);
1847                         CDDM_calc_normals(finaldm);
1848                 }
1849
1850                 if(dataMask & CD_MASK_WEIGHT_MCOL)
1851                         add_weight_mcol_dm(ob, finaldm);
1852         }
1853
1854         /* add an orco layer if needed */
1855         if(dataMask & CD_MASK_ORCO) {
1856                 add_orco_dm(ob, NULL, finaldm, orcodm);
1857
1858                 if(deform_r && *deform_r)
1859                         add_orco_dm(ob, NULL, *deform_r, NULL);
1860         }
1861
1862         *final_r = finaldm;
1863
1864         if(orcodm)
1865                 orcodm->release(orcodm);
1866
1867         if(deformedVerts && deformedVerts != inputVertexCos)
1868                 MEM_freeN(deformedVerts);
1869
1870         BLI_linklist_free(datamasks, NULL);
1871 }
1872
1873 static float (*editmesh_getVertexCos(EditMesh *em, int *numVerts_r))[3]
1874 {
1875         int i, numVerts = *numVerts_r = BLI_countlist(&em->verts);
1876         float (*cos)[3];
1877         EditVert *eve;
1878
1879         cos = MEM_mallocN(sizeof(*cos)*numVerts, "vertexcos");
1880         for (i=0,eve=em->verts.first; i<numVerts; i++,eve=eve->next) {
1881                 VECCOPY(cos[i], eve->co);
1882         }
1883
1884         return cos;
1885 }
1886
1887 static int editmesh_modifier_is_enabled(Scene *scene, ModifierData *md, DerivedMesh *dm)
1888 {
1889         ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1890         int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
1891
1892         if(!modifier_isEnabled(scene, md, required_mode)) return 0;
1893         if((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) {
1894                 modifier_setError(md, "Modifier requires original data, bad stack position.");
1895                 return 0;
1896         }
1897         
1898         return 1;
1899 }
1900
1901 static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, DerivedMesh **cage_r,
1902                                     DerivedMesh **final_r,
1903                                     CustomDataMask dataMask)
1904 {
1905         ModifierData *md;
1906         float (*deformedVerts)[3] = NULL;
1907         CustomDataMask mask;
1908         DerivedMesh *dm, *orcodm = NULL;
1909         int i, numVerts = 0, cageIndex = modifiers_getCageIndex(scene, ob, NULL, 1);
1910         LinkNode *datamasks, *curr;
1911         int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
1912
1913         modifiers_clearErrors(ob);
1914
1915         if(cage_r && cageIndex == -1) {
1916                 *cage_r = getEditMeshDerivedMesh(em, ob, NULL);
1917         }
1918
1919         dm = NULL;
1920         md = modifiers_getVirtualModifierList(ob);
1921         
1922         /* we always want to keep original indices */
1923         dataMask |= CD_MASK_ORIGINDEX;
1924
1925         datamasks = modifiers_calcDataMasks(scene, ob, md, dataMask, required_mode);
1926
1927         curr = datamasks;
1928         for(i = 0; md; i++, md = md->next, curr = curr->next) {
1929                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1930
1931                 md->scene= scene;
1932                 
1933                 if(!editmesh_modifier_is_enabled(scene, md, dm))
1934                         continue;
1935
1936                 /* add an orco layer if needed by this modifier */
1937                 if(dm && mti->requiredDataMask) {
1938                         mask = mti->requiredDataMask(ob, md);
1939                         if(mask & CD_MASK_ORCO)
1940                                 add_orco_dm(ob, em, dm, orcodm);
1941                 }
1942
1943                 /* How to apply modifier depends on (a) what we already have as
1944                  * a result of previous modifiers (could be a DerivedMesh or just
1945                  * deformed vertices) and (b) what type the modifier is.
1946                  */
1947
1948                 if(mti->type == eModifierTypeType_OnlyDeform) {
1949                         /* No existing verts to deform, need to build them. */
1950                         if(!deformedVerts) {
1951                                 if(dm) {
1952                                         /* Deforming a derived mesh, read the vertex locations
1953                                          * out of the mesh and deform them. Once done with this
1954                                          * run of deformers verts will be written back.
1955                                          */
1956                                         numVerts = dm->getNumVerts(dm);
1957                                         deformedVerts =
1958                                             MEM_mallocN(sizeof(*deformedVerts) * numVerts, "dfmv");
1959                                         dm->getVertCos(dm, deformedVerts);
1960                                 } else {
1961                                         deformedVerts = editmesh_getVertexCos(em, &numVerts);
1962                                 }
1963                         }
1964
1965                         mti->deformVertsEM(md, ob, em, dm, deformedVerts, numVerts);
1966                 } else {
1967                         DerivedMesh *ndm;
1968
1969                         /* apply vertex coordinates or build a DerivedMesh as necessary */
1970                         if(dm) {
1971                                 if(deformedVerts) {
1972                                         DerivedMesh *tdm = CDDM_copy(dm);
1973                                         if(!(cage_r && dm == *cage_r)) dm->release(dm);
1974                                         dm = tdm;
1975
1976                                         CDDM_apply_vert_coords(dm, deformedVerts);
1977                                         CDDM_calc_normals(dm);
1978                                 } else if(cage_r && dm == *cage_r) {
1979                                         /* dm may be changed by this modifier, so we need to copy it
1980                                          */
1981                                         dm = CDDM_copy(dm);
1982                                 }
1983
1984                         } else {
1985                                 dm = CDDM_from_editmesh(em, ob->data);
1986
1987                                 if(deformedVerts) {
1988                                         CDDM_apply_vert_coords(dm, deformedVerts);
1989                                         CDDM_calc_normals(dm);
1990                                 }
1991                         }
1992
1993                         /* create an orco derivedmesh in parallel */
1994                         mask= (CustomDataMask)GET_INT_FROM_POINTER(curr->link);
1995                         if(mask & CD_MASK_ORCO) {
1996                                 if(!orcodm)
1997                                         orcodm= create_orco_dm(ob, ob->data, em);
1998
1999                                 mask &= ~CD_MASK_ORCO;
2000                                 DM_set_only_copy(orcodm, mask);
2001                                 ndm = mti->applyModifierEM(md, ob, em, orcodm);
2002
2003                                 if(ndm) {
2004                                         /* if the modifier returned a new dm, release the old one */
2005                                         if(orcodm && orcodm != ndm) orcodm->release(orcodm);
2006                                         orcodm = ndm;
2007                                 }
2008                         }
2009
2010                         /* set the DerivedMesh to only copy needed data */
2011                         DM_set_only_copy(dm, (CustomDataMask)GET_INT_FROM_POINTER(curr->link));
2012
2013                         if(((CustomDataMask)GET_INT_FROM_POINTER(curr->link)) & CD_MASK_ORIGSPACE)
2014                                 if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE))
2015                                         DM_add_face_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL);
2016                         
2017                         ndm = mti->applyModifierEM(md, ob, em, dm);
2018
2019                         if (ndm) {
2020                                 if(dm && dm != ndm)
2021                                         dm->release(dm);
2022
2023                                 dm = ndm;
2024
2025                                 if (deformedVerts) {
2026                                         MEM_freeN(deformedVerts);
2027                                         deformedVerts = NULL;
2028                                 }
2029                         }
2030                 }
2031
2032                 if(cage_r && i == cageIndex) {
2033                         if(dm && deformedVerts) {
2034                                 *cage_r = CDDM_copy(dm);
2035                                 CDDM_apply_vert_coords(*cage_r, deformedVerts);
2036                         } else if(dm) {
2037                                 *cage_r = dm;
2038                         } else {
2039                                 *cage_r =
2040                                     getEditMeshDerivedMesh(em, ob,
2041                                         deformedVerts ? MEM_dupallocN(deformedVerts) : NULL);
2042                         }
2043                 }
2044         }
2045
2046         BLI_linklist_free(datamasks, NULL);
2047
2048         /* Yay, we are done. If we have a DerivedMesh and deformed vertices need
2049          * to apply these back onto the DerivedMesh. If we have no DerivedMesh
2050          * then we need to build one.
2051          */
2052         if(dm && deformedVerts) {
2053                 *final_r = CDDM_copy(dm);
2054
2055                 if(!(cage_r && dm == *cage_r)) dm->release(dm);
2056
2057                 CDDM_apply_vert_coords(*final_r, deformedVerts);
2058                 CDDM_calc_normals(*final_r);
2059         } else if (dm) {
2060                 *final_r = dm;
2061         } else if (!deformedVerts && cage_r && *cage_r) {
2062                 *final_r = *cage_r;
2063         } else {
2064                 *final_r = getEditMeshDerivedMesh(em, ob, deformedVerts);
2065                 deformedVerts = NULL;
2066         }
2067
2068         /* add an orco layer if needed */
2069         if(dataMask & CD_MASK_ORCO)
2070                 add_orco_dm(ob, em, *final_r, orcodm);
2071
2072         if(orcodm)
2073                 orcodm->release(orcodm);
2074
2075         if(deformedVerts)
2076                 MEM_freeN(deformedVerts);
2077 }
2078
2079 static void clear_mesh_caches(Object *ob)
2080 {
2081         Mesh *me= ob->data;
2082
2083                 /* also serves as signal to remake texspace */
2084         if (ob->bb) {
2085                 MEM_freeN(ob->bb);
2086                 ob->bb = NULL;
2087         }
2088         if (me->bb) {
2089                 MEM_freeN(me->bb);
2090                 me->bb = NULL;
2091         }
2092
2093         freedisplist(&ob->disp);
2094
2095         if (ob->derivedFinal) {
2096                 ob->derivedFinal->needsFree = 1;
2097                 ob->derivedFinal->release(ob->derivedFinal);
2098                 ob->derivedFinal= NULL;
2099         }
2100         if (ob->derivedDeform) {
2101                 ob->derivedDeform->needsFree = 1;
2102                 ob->derivedDeform->release(ob->derivedDeform);
2103                 ob->derivedDeform= NULL;
2104         }
2105 }
2106
2107 static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask)
2108 {
2109         Object *obact = scene->basact?scene->basact->object:NULL;
2110         int editing = paint_facesel_test(ob);
2111         /* weight paint and face select need original indicies because of selection buffer drawing */
2112         int needMapping = (ob==obact) && (editing || (ob->mode & OB_MODE_WEIGHT_PAINT) || paint_facesel_test(ob));
2113         float min[3], max[3];
2114         
2115         clear_mesh_caches(ob);
2116
2117         mesh_calc_modifiers(scene, ob, NULL, &ob->derivedDeform,
2118                                                 &ob->derivedFinal, 0, 1,
2119                                                 needMapping, dataMask, -1);
2120
2121         INIT_MINMAX(min, max);
2122
2123         ob->derivedFinal->getMinMax(ob->derivedFinal, min, max);
2124
2125         if(!ob->bb)
2126                 ob->bb= MEM_callocN(sizeof(BoundBox), "bb");
2127         boundbox_set_from_min_max(ob->bb, min, max);
2128
2129         ob->derivedFinal->needsFree = 0;
2130         ob->derivedDeform->needsFree = 0;
2131         ob->lastDataMask = dataMask;
2132
2133 }
2134
2135 static void editmesh_build_data(Scene *scene, Object *obedit, EditMesh *em, CustomDataMask dataMask)
2136 {
2137         float min[3], max[3];
2138
2139         clear_mesh_caches(obedit);
2140
2141         if (em->derivedFinal) {
2142                 if (em->derivedFinal!=em->derivedCage) {
2143                         em->derivedFinal->needsFree = 1;
2144                         em->derivedFinal->release(em->derivedFinal);
2145                 }
2146                 em->derivedFinal = NULL;
2147         }
2148         if (em->derivedCage) {
2149                 em->derivedCage->needsFree = 1;
2150                 em->derivedCage->release(em->derivedCage);
2151                 em->derivedCage = NULL;
2152         }
2153
2154         editmesh_calc_modifiers(scene, obedit, em, &em->derivedCage, &em->derivedFinal, dataMask);
2155         em->lastDataMask = dataMask;
2156
2157         INIT_MINMAX(min, max);
2158
2159         em->derivedFinal->getMinMax(em->derivedFinal, min, max);
2160
2161         if(!obedit->bb)
2162                 obedit->bb= MEM_callocN(sizeof(BoundBox), "bb");
2163         boundbox_set_from_min_max(obedit->bb, min, max);
2164
2165         em->derivedFinal->needsFree = 0;
2166         em->derivedCage->needsFree = 0;
2167 }
2168
2169 void makeDerivedMesh(Scene *scene, Object *ob, EditMesh *em, CustomDataMask dataMask)
2170 {
2171         if (em) {
2172                 editmesh_build_data(scene, ob, em, dataMask);
2173         } else {
2174                 mesh_build_data(scene, ob, dataMask);
2175         }
2176 }
2177
2178 /***/
2179
2180 DerivedMesh *mesh_get_derived_final(Scene *scene, Object *ob, CustomDataMask dataMask)
2181 {
2182         /* if there's no derived mesh or the last data mask used doesn't include
2183          * the data we need, rebuild the derived mesh
2184          */
2185         if(!ob->derivedFinal || (dataMask & ob->lastDataMask) != dataMask)
2186                 mesh_build_data(scene, ob, dataMask);
2187
2188         return ob->derivedFinal;
2189 }
2190
2191 DerivedMesh *mesh_get_derived_deform(Scene *scene, Object *ob, CustomDataMask dataMask)
2192 {
2193         /* if there's no derived mesh or the last data mask used doesn't include
2194          * the data we need, rebuild the derived mesh
2195          */
2196         if(!ob->derivedDeform || (dataMask & ob->lastDataMask) != dataMask)
2197                 mesh_build_data(scene, ob, dataMask);
2198
2199         return ob->derivedDeform;
2200 }
2201
2202 DerivedMesh *mesh_create_derived_render(Scene *scene, Object *ob, CustomDataMask dataMask)
2203 {
2204         DerivedMesh *final;
2205         
2206         mesh_calc_modifiers(scene, ob, NULL, NULL, &final, 1, 1, 0, dataMask, -1);
2207
2208         return final;
2209 }
2210
2211 DerivedMesh *mesh_create_derived_index_render(Scene *scene, Object *ob, CustomDataMask dataMask, int index)
2212 {
2213         DerivedMesh *final;
2214         
2215         mesh_calc_modifiers(scene, ob, NULL, NULL, &final, 1, 1, 0, dataMask, index);
2216
2217         return final;
2218 }
2219
2220 DerivedMesh *mesh_create_derived_view(Scene *scene, Object *ob, CustomDataMask dataMask)
2221 {
2222         DerivedMesh *final;
2223
2224         mesh_calc_modifiers(scene, ob, NULL, NULL, &final, 0, 1, 0, dataMask, -1);
2225
2226         return final;
2227 }
2228
2229 DerivedMesh *mesh_create_derived_no_deform(Scene *scene, Object *ob, float (*vertCos)[3],
2230                                            CustomDataMask dataMask)
2231 {
2232         DerivedMesh *final;
2233         
2234         mesh_calc_modifiers(scene, ob, vertCos, NULL, &final, 0, 0, 0, dataMask, -1);
2235
2236         return final;
2237 }
2238
2239 DerivedMesh *mesh_create_derived_no_virtual(Scene *scene, Object *ob, float (*vertCos)[3],
2240                                             CustomDataMask dataMask)
2241 {
2242         DerivedMesh *final;
2243         
2244         mesh_calc_modifiers(scene, ob, vertCos, NULL, &final, 0, -1, 0, dataMask, -1);
2245
2246         return final;
2247 }
2248
2249 DerivedMesh *mesh_create_derived_no_deform_render(Scene *scene, Object *ob,
2250                                                   float (*vertCos)[3],
2251                                                   CustomDataMask dataMask)
2252 {
2253         DerivedMesh *final;
2254
2255         mesh_calc_modifiers(scene, ob, vertCos, NULL, &final, 1, 0, 0, dataMask, -1);
2256
2257         return final;
2258 }
2259
2260 /***/
2261
2262 DerivedMesh *editmesh_get_derived_cage_and_final(Scene *scene, Object *obedit, EditMesh *em, DerivedMesh **final_r,
2263                                                  CustomDataMask dataMask)
2264 {
2265         /* if there's no derived mesh or the last data mask used doesn't include
2266          * the data we need, rebuild the derived mesh
2267          */
2268         if(!em->derivedCage ||
2269            (em->lastDataMask & dataMask) != dataMask)
2270                 editmesh_build_data(scene, obedit, em, dataMask);
2271
2272         *final_r = em->derivedFinal;
2273         return em->derivedCage;
2274 }
2275
2276 DerivedMesh *editmesh_get_derived_cage(Scene *scene, Object *obedit, EditMesh *em, CustomDataMask dataMask)
2277 {
2278         /* if there's no derived mesh or the last data mask used doesn't include
2279          * the data we need, rebuild the derived mesh
2280          */
2281         if(!em->derivedCage ||
2282            (em->lastDataMask & dataMask) != dataMask)
2283                 editmesh_build_data(scene, obedit, em, dataMask);
2284
2285         return em->derivedCage;
2286 }
2287
2288 DerivedMesh *editmesh_get_derived_base(Object *obedit, EditMesh *em)
2289 {
2290         return getEditMeshDerivedMesh(em, obedit, NULL);
2291 }
2292
2293
2294 /* ********* For those who don't grasp derived stuff! (ton) :) *************** */
2295
2296 static void make_vertexcosnos__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
2297 {
2298         float *vec = userData;
2299         
2300         vec+= 6*index;
2301
2302         /* check if we've been here before (normal should not be 0) */
2303         if(vec[3] || vec[4] || vec[5]) return;
2304
2305         VECCOPY(vec, co);
2306         vec+= 3;
2307         if(no_f) {
2308                 VECCOPY(vec, no_f);
2309         }
2310         else {
2311                 VECCOPY(vec, no_s);
2312         }
2313 }
2314
2315 /* always returns original amount me->totvert of vertices and normals, but fully deformed and subsurfered */
2316 /* this is needed for all code using vertexgroups (no subsurf support) */
2317 /* it stores the normals as floats, but they can still be scaled as shorts (32767 = unit) */
2318 /* in use now by vertex/weight paint and particle generating */
2319
2320 float *mesh_get_mapped_verts_nors(Scene *scene, Object *ob)
2321 {
2322         Mesh *me= ob->data;
2323         DerivedMesh *dm;
2324         float *vertexcosnos;
2325         
2326         /* lets prevent crashing... */
2327         if(ob->type!=OB_MESH || me->totvert==0)
2328                 return NULL;
2329         
2330         dm= mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
2331         vertexcosnos= MEM_callocN(6*sizeof(float)*me->totvert, "vertexcosnos map");
2332         
2333         if(dm->foreachMappedVert) {
2334                 dm->foreachMappedVert(dm, make_vertexcosnos__mapFunc, vertexcosnos);
2335         }
2336         else {
2337                 float *fp= vertexcosnos;
2338                 int a;
2339                 
2340                 for(a=0; a< me->totvert; a++, fp+=6) {
2341                         dm->getVertCo(dm, a, fp);
2342                         dm->getVertNo(dm, a, fp+3);
2343                 }
2344         }
2345         
2346         dm->release(dm);
2347         return vertexcosnos;
2348 }
2349
2350 /* ********* crazyspace *************** */
2351
2352 int editmesh_get_first_deform_matrices(Scene *scene, Object *ob, EditMesh *em, float (**deformmats)[3][3], float (**deformcos)[3])
2353 {
2354         ModifierData *md;
2355         DerivedMesh *dm;
2356         int i, a, numleft = 0, numVerts = 0;
2357         int cageIndex = modifiers_getCageIndex(scene, ob, NULL, 1);
2358         float (*defmats)[3][3] = NULL, (*deformedVerts)[3] = NULL;
2359
2360         modifiers_clearErrors(ob);
2361
2362         dm = NULL;
2363         md = modifiers_getVirtualModifierList(ob);
2364
2365         /* compute the deformation matrices and coordinates for the first
2366            modifiers with on cage editing that are enabled and support computing
2367            deform matrices */
2368         for(i = 0; md && i <= cageIndex; i++, md = md->next) {
2369                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
2370
2371                 if(!editmesh_modifier_is_enabled(scene, md, dm))
2372                         continue;
2373
2374                 if(mti->type==eModifierTypeType_OnlyDeform && mti->deformMatricesEM) {
2375                         if(!defmats) {
2376                                 dm= getEditMeshDerivedMesh(em, ob, NULL);
2377                                 deformedVerts= editmesh_getVertexCos(em, &numVerts);
2378                                 defmats= MEM_callocN(sizeof(*defmats)*numVerts, "defmats");
2379
2380                                 for(a=0; a<numVerts; a++)
2381                                         unit_m3(defmats[a]);
2382                         }
2383
2384                         mti->deformMatricesEM(md, ob, em, dm, deformedVerts, defmats,
2385                                 numVerts);
2386                 }
2387                 else
2388                         break;
2389         }
2390
2391         for(; md && i <= cageIndex; md = md->next, i++)
2392                 if(editmesh_modifier_is_enabled(scene, md, dm) && modifier_isCorrectableDeformed(md))
2393                         numleft++;
2394
2395         if(dm)
2396                 dm->release(dm);
2397         
2398         *deformmats= defmats;
2399         *deformcos= deformedVerts;
2400
2401         return numleft;
2402 }
2403
2404 /* ******************* GLSL ******************** */
2405
2406 void DM_add_tangent_layer(DerivedMesh *dm)
2407 {
2408         /* mesh vars */
2409         MTFace *mtface, *tf;
2410         MFace *mface, *mf;
2411         MVert *mvert, *v1, *v2, *v3, *v4;
2412         MemArena *arena= NULL;
2413         VertexTangent **vtangents= NULL;
2414         float (*orco)[3]= NULL, (*tangent)[3];
2415         float *uv1, *uv2, *uv3, *uv4, *vtang;
2416         float fno[3], tang[3], uv[4][2];
2417         int i, j, len, mf_vi[4], totvert, totface;
2418
2419         if(CustomData_get_layer_index(&dm->faceData, CD_TANGENT) != -1)
2420                 return;
2421
2422         /* check we have all the needed layers */
2423         totvert= dm->getNumVerts(dm);
2424         totface= dm->getNumFaces(dm);
2425
2426         mvert= dm->getVertArray(dm);
2427         mface= dm->getFaceArray(dm);
2428         mtface= dm->getFaceDataArray(dm, CD_MTFACE);
2429
2430         if(!mtface) {
2431                 orco= dm->getVertDataArray(dm, CD_ORCO);
2432                 if(!orco)
2433                         return;
2434         }
2435         
2436         /* create tangent layer */
2437         DM_add_face_layer(dm, CD_TANGENT, CD_CALLOC, NULL);
2438         tangent= DM_get_face_data_layer(dm, CD_TANGENT);
2439         
2440         /* allocate some space */
2441         arena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
2442         BLI_memarena_use_calloc(arena);
2443         vtangents= MEM_callocN(sizeof(VertexTangent*)*totvert, "VertexTangent");
2444         
2445         /* sum tangents at connected vertices */
2446         for(i=0, tf=mtface, mf=mface; i < totface; mf++, tf++, i++) {
2447                 v1= &mvert[mf->v1];
2448                 v2= &mvert[mf->v2];
2449                 v3= &mvert[mf->v3];
2450
2451                 if (mf->v4) {
2452                         v4= &mvert[mf->v4];
2453                         normal_quad_v3( fno,v4->co, v3->co, v2->co, v1->co);
2454                 }
2455                 else {
2456                         v4= NULL;
2457                         normal_tri_v3( fno,v3->co, v2->co, v1->co);
2458                 }
2459                 
2460                 if(mtface) {
2461                         uv1= tf->uv[0];
2462                         uv2= tf->uv[1];
2463                         uv3= tf->uv[2];
2464                         uv4= tf->uv[3];
2465                 }
2466                 else {
2467                         uv1= uv[0]; uv2= uv[1]; uv3= uv[2]; uv4= uv[3];
2468                         map_to_sphere( &uv[0][0], &uv[0][1],orco[mf->v1][0], orco[mf->v1][1], orco[mf->v1][2]);
2469                         map_to_sphere( &uv[1][0], &uv[1][1],orco[mf->v2][0], orco[mf->v2][1], orco[mf->v2][2]);
2470                         map_to_sphere( &uv[2][0], &uv[2][1],orco[mf->v3][0], orco[mf->v3][1], orco[mf->v3][2]);
2471                         if(v4)
2472                                 map_to_sphere( &uv[3][0], &uv[3][1],orco[mf->v4][0], orco[mf->v4][1], orco[mf->v4][2]);
2473                 }
2474                 
2475                 tangent_from_uv(uv1, uv2, uv3, v1->co, v2->co, v3->co, fno, tang);
2476                 sum_or_add_vertex_tangent(arena, &vtangents[mf->v1], tang, uv1);
2477                 sum_or_add_vertex_tangent(arena, &vtangents[mf->v2], tang, uv2);
2478                 sum_or_add_vertex_tangent(arena, &vtangents[mf->v3], tang, uv3);
2479                 
2480                 if(mf->v4) {
2481                         v4= &mvert[mf->v4];
2482                         
2483                         tangent_from_uv(uv1, uv3, uv4, v1->co, v3->co, v4->co, fno, tang);
2484                         sum_or_add_vertex_tangent(arena, &vtangents[mf->v1], tang, uv1);
2485                         sum_or_add_vertex_tangent(arena, &vtangents[mf->v3], tang, uv3);
2486                         sum_or_add_vertex_tangent(arena, &vtangents[mf->v4], tang, uv4);
2487                 }
2488         }
2489         
2490         /* write tangent to layer */
2491         for(i=0, tf=mtface, mf=mface; i < totface; mf++, tf++, i++, tangent+=4) {
2492                 len= (mf->v4)? 4 : 3; 
2493                 
2494                 if(mtface) {
2495                         uv1= tf->uv[0];
2496                         uv2= tf->uv[1];
2497                         uv3= tf->uv[2];
2498                         uv4= tf->uv[3];
2499                 }
2500                 else {
2501                         uv1= uv[0]; uv2= uv[1]; uv3= uv[2]; uv4= uv[3];
2502                         map_to_sphere( &uv[0][0], &uv[0][1],orco[mf->v1][0], orco[mf->v1][1], orco[mf->v1][2]);
2503                         map_to_sphere( &uv[1][0], &uv[1][1],orco[mf->v2][0], orco[mf->v2][1], orco[mf->v2][2]);
2504                         map_to_sphere( &uv[2][0], &uv[2][1],orco[mf->v3][0], orco[mf->v3][1], orco[mf->v3][2]);
2505                         if(len==4)
2506                                 map_to_sphere( &uv[3][0], &uv[3][1],orco[mf->v4][0], orco[mf->v4][1], orco[mf->v4][2]);
2507                 }
2508                 
2509                 mf_vi[0]= mf->v1;
2510                 mf_vi[1]= mf->v2;
2511                 mf_vi[2]= mf->v3;
2512                 mf_vi[3]= mf->v4;
2513                 
2514                 for(j=0; j<len; j++) {
2515                         vtang= find_vertex_tangent(vtangents[mf_vi[j]], mtface ? tf->uv[j] : uv[j]);
2516
2517                         VECCOPY(tangent[j], vtang);
2518                         normalize_v3(tangent[j]);
2519                 }
2520         }
2521         
2522         BLI_memarena_free(arena);
2523         MEM_freeN(vtangents);
2524 }
2525
2526 void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, DMVertexAttribs *attribs)
2527 {
2528         CustomData *vdata, *fdata, *tfdata = NULL;
2529         int a, b, layer;
2530
2531         /* From the layers requested by the GLSL shader, figure out which ones are
2532          * actually available for this derivedmesh, and retrieve the pointers */
2533
2534         memset(attribs, 0, sizeof(DMVertexAttribs));
2535
2536         vdata = &dm->vertData;
2537         fdata = &dm->faceData;
2538
2539         /* ugly hack, editmesh derivedmesh doesn't copy face data, this way we
2540          * can use offsets instead */
2541         if(dm->release == emDM_release)
2542                 tfdata = &((EditMeshDerivedMesh*)dm)->em->fdata;
2543         else
2544                 tfdata = fdata;
2545
2546         /* add a tangent layer if necessary */
2547         for(b = 0; b < gattribs->totlayer; b++)
2548                 if(gattribs->layer[b].type == CD_TANGENT)
2549                         if(CustomData_get_layer_index(fdata, CD_TANGENT) == -1)
2550                                 DM_add_tangent_layer(dm);
2551
2552         for(b = 0; b < gattribs->totlayer; b++) {
2553                 if(gattribs->layer[b].type == CD_MTFACE) {
2554                         /* uv coordinates */
2555                         if(gattribs->layer[b].name[0])
2556                                 layer = CustomData_get_named_layer_index(tfdata, CD_MTFACE,
2557                                         gattribs->layer[b].name);
2558                         else
2559                                 layer = CustomData_get_active_layer_index(tfdata, CD_MTFACE);
2560
2561                         if(layer != -1) {
2562                                 a = attribs->tottface++;
2563
2564                                 attribs->tface[a].array = tfdata->layers[layer].data;
2565                                 attribs->tface[a].emOffset = tfdata->layers[layer].offset;
2566                                 attribs->tface[a].glIndex = gattribs->layer[b].glindex;
2567                         }
2568                 }
2569                 else if(gattribs->layer[b].type == CD_MCOL) {
2570                         /* vertex colors */
2571                         if(gattribs->layer[b].name[0])
2572                                 layer = CustomData_get_named_layer_index(tfdata, CD_MCOL,
2573                                         gattribs->layer[b].name);
2574                         else
2575                                 layer = CustomData_get_active_layer_index(tfdata, CD_MCOL);
2576
2577                         if(layer != -1) {
2578                                 a = attribs->totmcol++;
2579
2580                                 attribs->mcol[a].array = tfdata->layers[layer].data;
2581                                 attribs->mcol[a].emOffset = tfdata->layers[layer].offset;
2582                                 attribs->mcol[a].glIndex = gattribs->layer[b].glindex;
2583                         }
2584                 }
2585                 else if(gattribs->layer[b].type == CD_TANGENT) {
2586                         /* tangents */
2587                         layer = CustomData_get_layer_index(fdata, CD_TANGENT);
2588
2589                         if(layer != -1) {
2590                                 attribs->tottang = 1;
2591
2592                                 attribs->tang.array = fdata->layers[layer].data;
2593                                 attribs->tang.emOffset = fdata->layers[layer].offset;
2594                                 attribs->tang.glIndex = gattribs->layer[b].glindex;
2595                         }
2596                 }
2597                 else if(gattribs->layer[b].type == CD_ORCO) {
2598                         /* original coordinates */
2599                         layer = CustomData_get_layer_index(vdata, CD_ORCO);
2600
2601                         if(layer != -1) {
2602                                 attribs->totorco = 1;
2603
2604                                 attribs->orco.array = vdata->layers[layer].data;
2605                                 attribs->orco.emOffset = vdata->layers[layer].offset;
2606                                 attribs->orco.glIndex = gattribs->layer[b].glindex;
2607                         }
2608                 }
2609         }
2610 }
2611