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