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