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