Fix #21761: Curve+"Fill deformed"+modifier ( not all)= not rendered
[blender.git] / source / blender / blenkernel / intern / displist.c
1 /*  displist.c
2  * 
3  * 
4  * $Id$
5  *
6  * ***** BEGIN GPL LICENSE BLOCK *****
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * The Original Code is: all of this file.
26  *
27  * Contributor(s): none yet.
28  *
29  * ***** END GPL LICENSE BLOCK *****
30  */
31
32 #include <math.h>
33 #include <stdio.h>
34 #include <string.h>
35
36 #include "MEM_guardedalloc.h"
37
38
39 #include "DNA_curve_types.h"
40 #include "DNA_meshdata_types.h"
41 #include "DNA_scene_types.h"
42 #include "DNA_material_types.h"
43
44 #include "BLI_blenlib.h"
45 #include "BLI_math.h"
46 #include "BLI_editVert.h"
47
48 #include "BKE_global.h"
49 #include "BKE_displist.h"
50 #include "BKE_cdderivedmesh.h"
51 #include "BKE_object.h"
52 #include "BKE_mball.h"
53 #include "BKE_material.h"
54 #include "BKE_curve.h"
55 #include "BKE_key.h"
56 #include "BKE_anim.h"
57 #include "BKE_font.h"
58 #include "BKE_lattice.h"
59 #include "BKE_modifier.h"
60
61 #include "RE_pipeline.h"
62 #include "RE_shader_ext.h"
63
64 #include "BLO_sys_types.h" // for intptr_t support
65
66
67 static void boundbox_displist(Object *ob);
68
69 void free_disp_elem(DispList *dl)
70 {
71         if(dl) {
72                 if(dl->verts) MEM_freeN(dl->verts);
73                 if(dl->nors) MEM_freeN(dl->nors);
74                 if(dl->index) MEM_freeN(dl->index);
75                 if(dl->col1) MEM_freeN(dl->col1);
76                 if(dl->col2) MEM_freeN(dl->col2);
77                 if(dl->bevelSplitFlag) MEM_freeN(dl->bevelSplitFlag);
78                 MEM_freeN(dl);
79         }
80 }
81
82 void freedisplist(ListBase *lb)
83 {
84         DispList *dl;
85
86         dl= lb->first;
87         while(dl) {
88                 BLI_remlink(lb, dl);
89                 free_disp_elem(dl);
90                 dl= lb->first;
91         }
92 }
93
94 DispList *find_displist_create(ListBase *lb, int type)
95 {
96         DispList *dl;
97         
98         dl= lb->first;
99         while(dl) {
100                 if(dl->type==type) return dl;
101                 dl= dl->next;
102         }
103
104         dl= MEM_callocN(sizeof(DispList), "find_disp");
105         dl->type= type;
106         BLI_addtail(lb, dl);
107
108         return dl;
109 }
110
111 DispList *find_displist(ListBase *lb, int type)
112 {
113         DispList *dl;
114         
115         dl= lb->first;
116         while(dl) {
117                 if(dl->type==type) return dl;
118                 dl= dl->next;
119         }
120
121         return 0;
122 }
123
124 int displist_has_faces(ListBase *lb)
125 {
126         DispList *dl;
127         for(dl= lb->first; dl; dl= dl->next) {
128                 if ELEM3(dl->type, DL_INDEX3, DL_INDEX4, DL_SURF)
129                         return 1;
130         }
131         return 0;
132 }
133
134 void copy_displist(ListBase *lbn, ListBase *lb)
135 {
136         DispList *dln, *dl;
137         
138         lbn->first= lbn->last= 0;
139         
140         dl= lb->first;
141         while(dl) {
142                 
143                 dln= MEM_dupallocN(dl);
144                 BLI_addtail(lbn, dln);
145                 dln->verts= MEM_dupallocN(dl->verts);
146                 dln->nors= MEM_dupallocN(dl->nors);
147                 dln->index= MEM_dupallocN(dl->index);
148                 dln->col1= MEM_dupallocN(dl->col1);
149                 dln->col2= MEM_dupallocN(dl->col2);
150                 
151                 dl= dl->next;
152         }
153 }
154
155 void addnormalsDispList(Object *ob, ListBase *lb)
156 {
157         DispList *dl = NULL;
158         float *vdata, *ndata, nor[3];
159         float *v1, *v2, *v3, *v4;
160         float *n1, *n2, *n3, *n4;
161         int a, b, p1, p2, p3, p4;
162
163
164         dl= lb->first;
165         
166         while(dl) {
167                 if(dl->type==DL_INDEX3) {
168                         if(dl->nors==NULL) {
169                                 dl->nors= MEM_callocN(sizeof(float)*3, "dlnors");
170                                 if(dl->verts[2]<0.0) dl->nors[2]= -1.0;
171                                 else dl->nors[2]= 1.0;
172                         }
173                 }
174                 else if(dl->type==DL_SURF) {
175                         if(dl->nors==NULL) {
176                                 dl->nors= MEM_callocN(sizeof(float)*3*dl->nr*dl->parts, "dlnors");
177                                 
178                                 vdata= dl->verts;
179                                 ndata= dl->nors;
180                                 
181                                 for(a=0; a<dl->parts; a++) {
182                                         
183                                         if (surfindex_displist(dl, a, &b, &p1, &p2, &p3, &p4)==0)
184                                                 break;
185         
186                                         v1= vdata+ 3*p1; 
187                                         n1= ndata+ 3*p1;
188                                         v2= vdata+ 3*p2; 
189                                         n2= ndata+ 3*p2;
190                                         v3= vdata+ 3*p3; 
191                                         n3= ndata+ 3*p3;
192                                         v4= vdata+ 3*p4; 
193                                         n4= ndata+ 3*p4;
194                                         
195                                         for(; b<dl->nr; b++) {
196         
197                                                 normal_quad_v3( nor,v1, v3, v4, v2);
198         
199                                                 add_v3_v3v3(n1, n1, nor);
200                                                 add_v3_v3v3(n2, n2, nor);
201                                                 add_v3_v3v3(n3, n3, nor);
202                                                 add_v3_v3v3(n4, n4, nor);
203         
204                                                 v2= v1; v1+= 3;
205                                                 v4= v3; v3+= 3;
206                                                 n2= n1; n1+= 3;
207                                                 n4= n3; n3+= 3;
208                                         }
209                                 }
210                                 a= dl->parts*dl->nr;
211                                 v1= ndata;
212                                 while(a--) {
213                                         normalize_v3(v1);
214                                         v1+= 3;
215                                 }
216                         }
217                 }
218                 dl= dl->next;
219         }
220 }
221
222 void count_displist(ListBase *lb, int *totvert, int *totface)
223 {
224         DispList *dl;
225         
226         dl= lb->first;
227         while(dl) {
228                 
229                 switch(dl->type) {
230                         case DL_SURF:
231                                 *totvert+= dl->nr*dl->parts;
232                                 *totface+= (dl->nr-1)*(dl->parts-1);
233                                 break;
234                         case DL_INDEX3:
235                         case DL_INDEX4:
236                                 *totvert+= dl->nr;
237                                 *totface+= dl->parts;
238                                 break;
239                         case DL_POLY:
240                         case DL_SEGM:
241                                 *totvert+= dl->nr*dl->parts;
242                 }
243                 
244                 dl= dl->next;
245         }
246 }
247
248 int surfindex_displist(DispList *dl, int a, int *b, int *p1, int *p2, int *p3, int *p4)
249 {
250         if((dl->flag & DL_CYCL_V)==0 && a==(dl->parts)-1) {
251                 return 0;
252         }
253         
254         if(dl->flag & DL_CYCL_U) {
255                 (*p1)= dl->nr*a;
256                 (*p2)= (*p1)+ dl->nr-1;
257                 (*p3)= (*p1)+ dl->nr;
258                 (*p4)= (*p2)+ dl->nr;
259                 (*b)= 0;
260         } else {
261                 (*p2)= dl->nr*a;
262                 (*p1)= (*p2)+1;
263                 (*p4)= (*p2)+ dl->nr;
264                 (*p3)= (*p1)+ dl->nr;
265                 (*b)= 1;
266         }
267         
268         if( (dl->flag & DL_CYCL_V) && a==dl->parts-1) {                     \
269                 (*p3)-= dl->nr*dl->parts;                                   \
270                 (*p4)-= dl->nr*dl->parts;                                   \
271         }
272         
273         return 1;
274 }
275
276 /* ***************************** shade displist. note colors now are in rgb(a) order ******************** */
277
278 /* create default shade input... save cpu cycles with ugly global */
279 /* XXXX bad code warning: local ShadeInput initialize... */
280 static ShadeInput shi;
281 static void init_fastshade_shadeinput(Render *re)
282 {
283         memset(&shi, 0, sizeof(ShadeInput));
284         shi.lay= RE_GetScene(re)->lay;
285         shi.view[2]= -1.0f;
286         shi.passflag= SCE_PASS_COMBINED;
287         shi.combinedflag= -1;
288 }
289
290 static Render *fastshade_get_render(Scene *scene)
291 {
292         // XXX 2.5: this crashes combined with previewrender
293         // due to global R so disabled for now
294 #if 0
295         /* XXX ugly global still, but we can't do preview while rendering */
296         if(G.rendering==0) {
297                 
298                 Render *re= RE_GetRender("_Shade View_", RE_SLOT_DEFAULT);
299                 if(re==NULL) {
300                         re= RE_NewRender("_Shade View_", RE_SLOT_DEFAULT);
301                 
302                         RE_Database_Baking(re, scene, 0, 0);    /* 0= no faces */
303                 }
304                 return re;
305         }
306 #endif
307         
308         return NULL;
309 }
310
311 /* called on file reading */
312 void fastshade_free_render(void)
313 {
314         Render *re= RE_GetRender("_Shade View_", RE_SLOT_DEFAULT);
315         
316         if(re) {
317                 RE_Database_Free(re);
318                 RE_FreeRender(re);
319         }
320 }
321
322 static int fastshade_customdata_layer_num(int n, int active)
323 {   
324         /* make the active layer the first */
325         if (n == active) return 0;
326         else if (n < active) return n+1;
327         else return n;
328 }
329
330 static void fastshade_customdata(CustomData *fdata, int a, int j, Material *ma)
331 {
332         CustomDataLayer *layer;
333         MTFace *mtface;
334         int index, n, needuv= ma->texco & TEXCO_UV;
335         char *vertcol;
336
337         shi.totuv= 0;
338         shi.totcol= 0;
339
340         for(index=0; index<fdata->totlayer; index++) {
341                 layer= &fdata->layers[index];
342                 
343                 if(needuv && layer->type == CD_MTFACE && shi.totuv < MAX_MTFACE) {
344                         n= fastshade_customdata_layer_num(shi.totuv, layer->active_rnd);
345                         mtface= &((MTFace*)layer->data)[a];
346
347                         shi.uv[shi.totuv].uv[0]= 2.0f*mtface->uv[j][0]-1.0f;
348                         shi.uv[shi.totuv].uv[1]= 2.0f*mtface->uv[j][1]-1.0f;
349                         shi.uv[shi.totuv].uv[2]= 1.0f;
350
351                         shi.uv[shi.totuv].name= layer->name;
352                         shi.totuv++;
353                 }
354                 else if(layer->type == CD_MCOL && shi.totcol < MAX_MCOL) {
355                         n= fastshade_customdata_layer_num(shi.totcol, layer->active_rnd);
356                         vertcol= (char*)&((MCol*)layer->data)[a*4 + j];
357
358                         shi.col[shi.totcol].col[0]= ((float)vertcol[3])/255.0f;
359                         shi.col[shi.totcol].col[1]= ((float)vertcol[2])/255.0f;
360                         shi.col[shi.totcol].col[2]= ((float)vertcol[1])/255.0f;
361
362                         shi.col[shi.totcol].name= layer->name;
363                         shi.totcol++;
364                 }
365         }
366
367         if(needuv && shi.totuv == 0)
368                 VECCOPY(shi.uv[0].uv, shi.lo);
369
370         if(shi.totcol)
371                 VECCOPY(shi.vcol, shi.col[0].col);
372 }
373
374 static void fastshade(float *co, float *nor, float *orco, Material *ma, char *col1, char *col2)
375 {
376         ShadeResult shr;
377         int a;
378         
379         VECCOPY(shi.co, co);
380         shi.vn[0]= -nor[0];
381         shi.vn[1]= -nor[1];
382         shi.vn[2]= -nor[2];
383         VECCOPY(shi.vno, shi.vn);
384         VECCOPY(shi.facenor, shi.vn);
385         
386         if(ma->texco) {
387                 VECCOPY(shi.lo, orco);
388                 
389                 if(ma->texco & TEXCO_GLOB) {
390                         VECCOPY(shi.gl, shi.lo);
391                 }
392                 if(ma->texco & TEXCO_WINDOW) {
393                         VECCOPY(shi.winco, shi.lo);
394                 }
395                 if(ma->texco & TEXCO_STICKY) {
396                         VECCOPY(shi.sticky, shi.lo);
397                 }
398                 if(ma->texco & TEXCO_OBJECT) {
399                         VECCOPY(shi.co, shi.lo);
400                 }
401                 if(ma->texco & TEXCO_NORM) {
402                         VECCOPY(shi.orn, shi.vn);
403                 }
404                 if(ma->texco & TEXCO_REFL) {
405                         float inp= 2.0*(shi.vn[2]);
406                         shi.ref[0]= (inp*shi.vn[0]);
407                         shi.ref[1]= (inp*shi.vn[1]);
408                         shi.ref[2]= (-1.0+inp*shi.vn[2]);
409                 }
410         }
411         
412         shi.mat= ma;    /* set each time... node shaders change it */
413         RE_shade_external(NULL, &shi, &shr);
414         
415         a= 256.0f*(shr.combined[0]);
416         col1[0]= CLAMPIS(a, 0, 255);
417         a= 256.0f*(shr.combined[1]);
418         col1[1]= CLAMPIS(a, 0, 255);
419         a= 256.0f*(shr.combined[2]);
420         col1[2]= CLAMPIS(a, 0, 255);
421         
422         if(col2) {
423                 shi.vn[0]= -shi.vn[0];
424                 shi.vn[1]= -shi.vn[1];
425                 shi.vn[2]= -shi.vn[2];
426                 
427                 shi.mat= ma;    /* set each time... node shaders change it */
428                 RE_shade_external(NULL, &shi, &shr);
429                 
430                 a= 256.0f*(shr.combined[0]);
431                 col2[0]= CLAMPIS(a, 0, 255);
432                 a= 256.0f*(shr.combined[1]);
433                 col2[1]= CLAMPIS(a, 0, 255);
434                 a= 256.0f*(shr.combined[2]);
435                 col2[2]= CLAMPIS(a, 0, 255);
436         }
437 }
438
439 static void init_fastshade_for_ob(Render *re, Object *ob, int *need_orco_r, float mat[4][4], float imat[3][3])
440 {
441         float tmat[4][4];
442         float amb[3]= {0.0f, 0.0f, 0.0f};
443         int a;
444         
445         /* initialize globals in render */
446         RE_shade_external(re, NULL, NULL);
447
448         /* initialize global here */
449         init_fastshade_shadeinput(re);
450         
451         RE_DataBase_GetView(re, tmat);
452         mul_m4_m4m4(mat, ob->obmat, tmat);
453         
454         invert_m4_m4(tmat, mat);
455         copy_m3_m4(imat, tmat);
456         if(ob->transflag & OB_NEG_SCALE) mul_m3_fl(imat, -1.0);
457         
458         if (need_orco_r) *need_orco_r= 0;
459         for(a=0; a<ob->totcol; a++) {
460                 Material *ma= give_current_material(ob, a+1);
461                 if(ma) {
462                         init_render_material(ma, 0, amb);
463
464                         if(ma->texco & TEXCO_ORCO) {
465                                 if (need_orco_r) *need_orco_r= 1;
466                         }
467                 }
468         }
469 }
470
471 static void end_fastshade_for_ob(Object *ob)
472 {
473         int a;
474         
475         for(a=0; a<ob->totcol; a++) {
476                 Material *ma= give_current_material(ob, a+1);
477                 if(ma)
478                         end_render_material(ma);
479         }
480 }
481
482
483 static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, unsigned int **col1_r, unsigned int **col2_r)
484 {
485         Mesh *me= ob->data;
486         DerivedMesh *dm;
487         MVert *mvert;
488         MFace *mface;
489         unsigned int *col1, *col2;
490         float *orco, *vnors, *nors, imat[3][3], mat[4][4], vec[3];
491         int a, i, need_orco, totface, totvert;
492         CustomDataMask dataMask = CD_MASK_BAREMESH | CD_MASK_MCOL
493                                                           | CD_MASK_MTFACE | CD_MASK_NORMAL;
494
495
496         init_fastshade_for_ob(re, ob, &need_orco, mat, imat);
497
498         if(need_orco)
499                 dataMask |= CD_MASK_ORCO;
500
501         if (onlyForMesh)
502                 dm = mesh_get_derived_deform(RE_GetScene(re), ob, dataMask);
503         else
504                 dm = mesh_get_derived_final(RE_GetScene(re), ob, dataMask);
505         
506         mvert = dm->getVertArray(dm);
507         mface = dm->getFaceArray(dm);
508         nors = dm->getFaceDataArray(dm, CD_NORMAL);
509         totvert = dm->getNumVerts(dm);
510         totface = dm->getNumFaces(dm);
511         orco= dm->getVertDataArray(dm, CD_ORCO);
512
513         if (onlyForMesh) {
514                 col1 = *col1_r;
515                 col2 = NULL;
516         } else {
517                 *col1_r = col1 = MEM_mallocN(sizeof(*col1)*totface*4, "col1");
518
519                 if (col2_r && (me->flag & ME_TWOSIDED))
520                         col2 = MEM_mallocN(sizeof(*col2)*totface*4, "col2");
521                 else
522                         col2 = NULL;
523                 
524                 if (col2_r) *col2_r = col2;
525         }
526
527                 /* vertexnormals */
528         vnors= MEM_mallocN(totvert*3*sizeof(float), "vnors disp");
529         for (a=0; a<totvert; a++) {
530                 MVert *mv = &mvert[a];
531                 float *vn= &vnors[a*3];
532                 float xn= mv->no[0]; 
533                 float yn= mv->no[1]; 
534                 float zn= mv->no[2];
535                 
536                         /* transpose ! */
537                 vn[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
538                 vn[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
539                 vn[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
540                 normalize_v3(vn);
541         }               
542
543         for (i=0; i<totface; i++) {
544                 extern Material defmaterial;    /* material.c */
545                 MFace *mf= &mface[i];
546                 Material *ma= give_current_material(ob, mf->mat_nr+1);
547                 int j, vidx[4], nverts= mf->v4?4:3;
548                 unsigned char *col1base= (unsigned char*) &col1[i*4];
549                 unsigned char *col2base= (unsigned char*) (col2?&col2[i*4]:NULL);
550                 float nor[3], n1[3];
551                 
552                 if(ma==NULL) ma= &defmaterial;
553                 
554                 vidx[0]= mf->v1;
555                 vidx[1]= mf->v2;
556                 vidx[2]= mf->v3;
557                 vidx[3]= mf->v4;
558
559                 if (nors) {
560                         VECCOPY(nor, &nors[i*3]);
561                 } else {
562                         if (mf->v4)
563                                 normal_quad_v3( nor,mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co);
564                         else
565                                 normal_tri_v3( nor,mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co);
566                 }
567
568                 n1[0]= imat[0][0]*nor[0]+imat[0][1]*nor[1]+imat[0][2]*nor[2];
569                 n1[1]= imat[1][0]*nor[0]+imat[1][1]*nor[1]+imat[1][2]*nor[2];
570                 n1[2]= imat[2][0]*nor[0]+imat[2][1]*nor[1]+imat[2][2]*nor[2];
571                 normalize_v3(n1);
572
573                 for (j=0; j<nverts; j++) {
574                         MVert *mv= &mvert[vidx[j]];
575                         char *col1= (char*)&col1base[j*4];
576                         char *col2= (char*)(col2base?&col2base[j*4]:NULL);
577                         float *vn = (mf->flag & ME_SMOOTH)?&vnors[3*vidx[j]]:n1;
578                         
579                         VECCOPY(vec, mv->co);
580                         mul_m4_v3(mat, vec);
581                         vec[0]+= 0.001*vn[0];
582                         vec[1]+= 0.001*vn[1];
583                         vec[2]+= 0.001*vn[2];
584
585                         fastshade_customdata(&dm->faceData, i, j, ma);
586                         fastshade(vec, vn, orco?&orco[vidx[j]*3]:mv->co, ma, col1, col2);
587                 }
588         } 
589         MEM_freeN(vnors);
590
591         dm->release(dm);
592
593         end_fastshade_for_ob(ob);
594 }
595
596 void shadeMeshMCol(Scene *scene, Object *ob, Mesh *me)
597 {
598         Render *re= fastshade_get_render(scene);
599         int a;
600         char *cp;
601         unsigned int *mcol= (unsigned int*)me->mcol;
602         
603         if(re) {
604                 mesh_create_shadedColors(re, ob, 1, &mcol, NULL);
605                 me->mcol= (MCol*)mcol;
606
607                 /* swap bytes */
608                 for(cp= (char *)me->mcol, a= 4*me->totface; a>0; a--, cp+=4) {
609                         SWAP(char, cp[0], cp[3]);
610                         SWAP(char, cp[1], cp[2]);
611                 }
612         }
613 }
614
615 /* has base pointer, to check for layer */
616 /* called from drawobject.c */
617 void shadeDispList(Scene *scene, Base *base)
618 {
619         Object *ob= base->object;
620         DispList *dl, *dlob;
621         Material *ma = NULL;
622         Curve *cu;
623         Render *re;
624         float imat[3][3], mat[4][4], vec[3];
625         float *fp, *nor, n1[3];
626         unsigned int *col1;
627         int a, need_orco;
628         
629         re= fastshade_get_render(scene);
630         if(re==NULL)
631                 return;
632         
633         dl = find_displist(&ob->disp, DL_VERTCOL);
634         if (dl) {
635                 BLI_remlink(&ob->disp, dl);
636                 free_disp_elem(dl);
637         }
638
639         if(ob->type==OB_MESH) {
640                 dl= MEM_callocN(sizeof(DispList), "displistshade");
641                 dl->type= DL_VERTCOL;
642
643                 mesh_create_shadedColors(re, ob, 0, &dl->col1, &dl->col2);
644
645                 /* add dl to ob->disp after mesh_create_shadedColors, because it
646                    might indirectly free ob->disp */
647                 BLI_addtail(&ob->disp, dl);
648         }
649         else {
650
651                 init_fastshade_for_ob(re, ob, &need_orco, mat, imat);
652                 
653                 if (ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
654                 
655                         /* now we need the normals */
656                         cu= ob->data;
657                         dl= cu->disp.first;
658                         
659                         while(dl) {
660                                 extern Material defmaterial;    /* material.c */
661                                 
662                                 dlob= MEM_callocN(sizeof(DispList), "displistshade");
663                                 BLI_addtail(&ob->disp, dlob);
664                                 dlob->type= DL_VERTCOL;
665                                 dlob->parts= dl->parts;
666                                 dlob->nr= dl->nr;
667                                 
668                                 if(dl->type==DL_INDEX3) {
669                                         col1= dlob->col1= MEM_mallocN(sizeof(int)*dl->nr, "col1");
670                                 }
671                                 else {
672                                         col1= dlob->col1= MEM_mallocN(sizeof(int)*dl->parts*dl->nr, "col1");
673                                 }
674                                 
675                         
676                                 ma= give_current_material(ob, dl->col+1);
677                                 if(ma==NULL) ma= &defmaterial;
678                                 
679                                 if(dl->type==DL_INDEX3) {
680                                         if(dl->nors) {
681                                                 /* there's just one normal */
682                                                 n1[0]= imat[0][0]*dl->nors[0]+imat[0][1]*dl->nors[1]+imat[0][2]*dl->nors[2];
683                                                 n1[1]= imat[1][0]*dl->nors[0]+imat[1][1]*dl->nors[1]+imat[1][2]*dl->nors[2];
684                                                 n1[2]= imat[2][0]*dl->nors[0]+imat[2][1]*dl->nors[1]+imat[2][2]*dl->nors[2];
685                                                 normalize_v3(n1);
686                                                 
687                                                 fp= dl->verts;
688                                                 
689                                                 a= dl->nr;              
690                                                 while(a--) {
691                                                         VECCOPY(vec, fp);
692                                                         mul_m4_v3(mat, vec);
693                                                         
694                                                         fastshade(vec, n1, fp, ma, (char *)col1, NULL);
695                                                         
696                                                         fp+= 3; col1++;
697                                                 }
698                                         }
699                                 }
700                                 else if(dl->type==DL_SURF) {
701                                         if(dl->nors) {
702                                                 a= dl->nr*dl->parts;
703                                                 fp= dl->verts;
704                                                 nor= dl->nors;
705                                                 
706                                                 while(a--) {
707                                                         VECCOPY(vec, fp);
708                                                         mul_m4_v3(mat, vec);
709                                                         
710                                                         n1[0]= imat[0][0]*nor[0]+imat[0][1]*nor[1]+imat[0][2]*nor[2];
711                                                         n1[1]= imat[1][0]*nor[0]+imat[1][1]*nor[1]+imat[1][2]*nor[2];
712                                                         n1[2]= imat[2][0]*nor[0]+imat[2][1]*nor[1]+imat[2][2]*nor[2];
713                                                         normalize_v3(n1);
714                                 
715                                                         fastshade(vec, n1, fp, ma, (char *)col1, NULL);
716                                                         
717                                                         fp+= 3; nor+= 3; col1++;
718                                                 }
719                                         }
720                                 }
721                                 dl= dl->next;
722                         }
723                 }
724                 else if(ob->type==OB_MBALL) {
725                         /* there are normals already */
726                         dl= ob->disp.first;
727                         
728                         while(dl) {
729                                 
730                                 if(dl->type==DL_INDEX4) {
731                                         if(dl->nors) {
732                                                 extern Material defmaterial;    /* material.c */
733                                                 
734                                                 if(dl->col1) MEM_freeN(dl->col1);
735                                                 col1= dl->col1= MEM_mallocN(sizeof(int)*dl->nr, "col1");
736                                 
737                                                 ma= give_current_material(ob, dl->col+1);
738                                                 if(ma==NULL) ma= &defmaterial;
739                                                 
740                                                 fp= dl->verts;
741                                                 nor= dl->nors;
742                                                 
743                                                 a= dl->nr;              
744                                                 while(a--) {
745                                                         VECCOPY(vec, fp);
746                                                         mul_m4_v3(mat, vec);
747                                                         
748                                                         /* transpose ! */
749                                                         n1[0]= imat[0][0]*nor[0]+imat[0][1]*nor[1]+imat[0][2]*nor[2];
750                                                         n1[1]= imat[1][0]*nor[0]+imat[1][1]*nor[1]+imat[1][2]*nor[2];
751                                                         n1[2]= imat[2][0]*nor[0]+imat[2][1]*nor[1]+imat[2][2]*nor[2];
752                                                         normalize_v3(n1);
753                                                 
754                                                         fastshade(vec, n1, fp, ma, (char *)col1, NULL);
755                                                         
756                                                         fp+= 3; col1++; nor+= 3;
757                                                 }
758                                         }
759                                 }
760                                 dl= dl->next;
761                         }
762                 }
763                 
764                 end_fastshade_for_ob(ob);
765         }
766 }
767
768 /* frees render and shade part of displists */
769 /* note: dont do a shade again, until a redraw happens */
770 void reshadeall_displist(Scene *scene)
771 {
772         Base *base;
773         Object *ob;
774         
775         fastshade_free_render();
776         
777         for(base= scene->base.first; base; base= base->next) {
778                 ob= base->object;
779
780                 if(ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL))
781                         freedisplist(&ob->disp);
782
783                 if(base->lay & scene->lay) {
784                         /* Metaballs have standard displist at the Object */
785                         if(ob->type==OB_MBALL) shadeDispList(scene, base);
786                 }
787         }
788 }
789
790 /* ****************** make displists ********************* */
791
792 static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase)
793 {
794         Nurb *nu;
795         DispList *dl;
796         BezTriple *bezt, *prevbezt;
797         BPoint *bp;
798         float *data;
799         int a, len, resolu;
800         
801         nu= nubase->first;
802         while(nu) {
803                 if(nu->hide==0) {
804                         
805                         if(G.rendering && cu->resolu_ren!=0) 
806                                 resolu= cu->resolu_ren;
807                         else
808                                 resolu= nu->resolu;
809                         
810                         if(!check_valid_nurb_u(nu));
811                         else if(nu->type == CU_BEZIER) {
812                                 
813                                 /* count */
814                                 len= 0;
815                                 a= nu->pntsu-1;
816                                 if(nu->flagu & CU_NURB_CYCLIC) a++;
817
818                                 prevbezt= nu->bezt;
819                                 bezt= prevbezt+1;
820                                 while(a--) {
821                                         if(a==0 && (nu->flagu & CU_NURB_CYCLIC)) bezt= nu->bezt;
822                                         
823                                         if(prevbezt->h2==HD_VECT && bezt->h1==HD_VECT) len++;
824                                         else len+= resolu;
825                                         
826                                         if(a==0 && (nu->flagu & CU_NURB_CYCLIC)==0) len++;
827                                         
828                                         prevbezt= bezt;
829                                         bezt++;
830                                 }
831                                 
832                                 dl= MEM_callocN(sizeof(DispList), "makeDispListbez");
833                                 /* len+1 because of 'forward_diff_bezier' function */
834                                 dl->verts= MEM_callocN( (len+1)*3*sizeof(float), "dlverts");
835                                 BLI_addtail(dispbase, dl);
836                                 dl->parts= 1;
837                                 dl->nr= len;
838                                 dl->col= nu->mat_nr;
839                                 dl->charidx= nu->charidx;
840
841                                 data= dl->verts;
842
843                                 if(nu->flagu & CU_NURB_CYCLIC) {
844                                         dl->type= DL_POLY;
845                                         a= nu->pntsu;
846                                 }
847                                 else {
848                                         dl->type= DL_SEGM;
849                                         a= nu->pntsu-1;
850                                 }
851                                 
852                                 prevbezt= nu->bezt;
853                                 bezt= prevbezt+1;
854                                 
855                                 while(a--) {
856                                         if(a==0 && dl->type== DL_POLY) bezt= nu->bezt;
857                                         
858                                         if(prevbezt->h2==HD_VECT && bezt->h1==HD_VECT) {
859                                                 VECCOPY(data, prevbezt->vec[1]);
860                                                 data+= 3;
861                                         }
862                                         else {
863                                                 int j;
864                                                 for(j=0; j<3; j++) {
865                                                         forward_diff_bezier(    prevbezt->vec[1][j],
866                                                                                                         prevbezt->vec[2][j],
867                                                                                                         bezt->vec[0][j],
868                                                                                                         bezt->vec[1][j],
869                                                                                                         data+j, resolu, 3*sizeof(float));
870                                                 }
871                                                 
872                                                 data+= 3*resolu;
873                                         }
874                                         
875                                         if(a==0 && dl->type==DL_SEGM) {
876                                                 VECCOPY(data, bezt->vec[1]);
877                                         }
878                                         
879                                         prevbezt= bezt;
880                                         bezt++;
881                                 }
882                         }
883                         else if(nu->type == CU_NURBS) {
884                                 len= (resolu*SEGMENTSU(nu));
885                                 
886                                 dl= MEM_callocN(sizeof(DispList), "makeDispListsurf");
887                                 dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
888                                 BLI_addtail(dispbase, dl);
889                                 dl->parts= 1;
890                                 
891                                 dl->nr= len;
892                                 dl->col= nu->mat_nr;
893                                 dl->charidx = nu->charidx;
894
895                                 data= dl->verts;
896                                 if(nu->flagu & CU_NURB_CYCLIC) dl->type= DL_POLY;
897                                 else dl->type= DL_SEGM;
898                                 makeNurbcurve(nu, data, NULL, NULL, resolu, 3*sizeof(float));
899                         }
900                         else if(nu->type == CU_POLY) {
901                                 len= nu->pntsu;
902                                 dl= MEM_callocN(sizeof(DispList), "makeDispListpoly");
903                                 dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
904                                 BLI_addtail(dispbase, dl);
905                                 dl->parts= 1;
906                                 dl->nr= len;
907                                 dl->col= nu->mat_nr;
908                                 dl->charidx = nu->charidx;
909
910                                 data= dl->verts;
911                                 if(nu->flagu & CU_NURB_CYCLIC) dl->type= DL_POLY;
912                                 else dl->type= DL_SEGM;
913                                 
914                                 a= len;
915                                 bp= nu->bp;
916                                 while(a--) {
917                                         VECCOPY(data, bp->vec);
918                                         bp++;
919                                         data+= 3;
920                                 }
921                         }
922                 }
923                 nu= nu->next;
924         }
925 }
926
927
928 void filldisplist(ListBase *dispbase, ListBase *to)
929 {
930         EditVert *eve, *v1, *vlast;
931         EditFace *efa;
932         DispList *dlnew=0, *dl;
933         float *f1;
934         int colnr=0, charidx=0, cont=1, tot, a, *index;
935         intptr_t totvert;
936         
937         if(dispbase==0) return;
938         if(dispbase->first==0) return;
939
940         while(cont) {
941                 cont= 0;
942                 totvert=0;
943                 
944                 dl= dispbase->first;
945                 while(dl) {
946         
947                         if(dl->type==DL_POLY) {
948                                 if(charidx<dl->charidx) cont= 1;
949                                 else if(charidx==dl->charidx) {
950                         
951                                         colnr= dl->col;
952                                         charidx= dl->charidx;
953                 
954                                         /* make editverts and edges */
955                                         f1= dl->verts;
956                                         a= dl->nr;
957                                         eve= v1= 0;
958                                         
959                                         while(a--) {
960                                                 vlast= eve;
961                                                 
962                                                 eve= BLI_addfillvert(f1);
963                                                 totvert++;
964                                                 
965                                                 if(vlast==0) v1= eve;
966                                                 else {
967                                                         BLI_addfilledge(vlast, eve);
968                                                 }
969                                                 f1+=3;
970                                         }
971                                 
972                                         if(eve!=0 && v1!=0) {
973                                                 BLI_addfilledge(eve, v1);
974                                         }
975                                 }
976                         }
977                         dl= dl->next;
978                 }
979                 
980                 if(totvert && BLI_edgefill(0, 0)) { // XXX (obedit && obedit->actcol)?(obedit->actcol-1):0)) {
981
982                         /* count faces  */
983                         tot= 0;
984                         efa= fillfacebase.first;
985                         while(efa) {
986                                 tot++;
987                                 efa= efa->next;
988                         }
989
990                         if(tot) {
991                                 dlnew= MEM_callocN(sizeof(DispList), "filldisplist");
992                                 dlnew->type= DL_INDEX3;
993                                 dlnew->col= colnr;
994                                 dlnew->nr= totvert;
995                                 dlnew->parts= tot;
996
997                                 dlnew->index= MEM_mallocN(tot*3*sizeof(int), "dlindex");
998                                 dlnew->verts= MEM_mallocN(totvert*3*sizeof(float), "dlverts");
999                                 
1000                                 /* vert data */
1001                                 f1= dlnew->verts;
1002                                 totvert= 0;
1003                                 eve= fillvertbase.first;
1004                                 while(eve) {
1005                                         VECCOPY(f1, eve->co);
1006                                         f1+= 3;
1007         
1008                                         /* index number */
1009                                         eve->tmp.l = totvert;
1010                                         totvert++;
1011                                         
1012                                         eve= eve->next;
1013                                 }
1014                                 
1015                                 /* index data */
1016                                 efa= fillfacebase.first;
1017                                 index= dlnew->index;
1018                                 while(efa) {
1019                                         index[0]= (intptr_t)efa->v1->tmp.l;
1020                                         index[1]= (intptr_t)efa->v2->tmp.l;
1021                                         index[2]= (intptr_t)efa->v3->tmp.l;
1022                                         
1023                                         index+= 3;
1024                                         efa= efa->next;
1025                                 }
1026                         }
1027
1028                         BLI_addhead(to, dlnew);
1029                         
1030                 }
1031                 BLI_end_edgefill();
1032
1033                 charidx++;
1034         }
1035         
1036         /* do not free polys, needed for wireframe display */
1037         
1038 }
1039
1040 static void bevels_to_filledpoly(Curve *cu, ListBase *dispbase)
1041 {
1042         ListBase front, back;
1043         DispList *dl, *dlnew;
1044         float *fp, *fp1;
1045         int a, dpoly;
1046         
1047         front.first= front.last= back.first= back.last= 0;
1048         
1049         dl= dispbase->first;
1050         while(dl) {
1051                 if(dl->type==DL_SURF) {
1052                         if( (dl->flag & DL_CYCL_V) && (dl->flag & DL_CYCL_U)==0 ) {
1053                                 if( (cu->flag & CU_BACK) && (dl->flag & DL_BACK_CURVE) ) {
1054                                         dlnew= MEM_callocN(sizeof(DispList), "filldisp");
1055                                         BLI_addtail(&front, dlnew);
1056                                         dlnew->verts= fp1= MEM_mallocN(sizeof(float)*3*dl->parts, "filldisp1");
1057                                         dlnew->nr= dl->parts;
1058                                         dlnew->parts= 1;
1059                                         dlnew->type= DL_POLY;
1060                                         dlnew->col= dl->col;
1061                                         dlnew->charidx = dl->charidx;
1062                                         
1063                                         fp= dl->verts;
1064                                         dpoly= 3*dl->nr;
1065                                         
1066                                         a= dl->parts;
1067                                         while(a--) {
1068                                                 VECCOPY(fp1, fp);
1069                                                 fp1+= 3;
1070                                                 fp+= dpoly;
1071                                         }
1072                                 }
1073                                 if( (cu->flag & CU_FRONT) && (dl->flag & DL_FRONT_CURVE) ) {
1074                                         dlnew= MEM_callocN(sizeof(DispList), "filldisp");
1075                                         BLI_addtail(&back, dlnew);
1076                                         dlnew->verts= fp1= MEM_mallocN(sizeof(float)*3*dl->parts, "filldisp1");
1077                                         dlnew->nr= dl->parts;
1078                                         dlnew->parts= 1;
1079                                         dlnew->type= DL_POLY;
1080                                         dlnew->col= dl->col;
1081                                         dlnew->charidx= dl->charidx;
1082                                         
1083                                         fp= dl->verts+3*(dl->nr-1);
1084                                         dpoly= 3*dl->nr;
1085                                         
1086                                         a= dl->parts;
1087                                         while(a--) {
1088                                                 VECCOPY(fp1, fp);
1089                                                 fp1+= 3;
1090                                                 fp+= dpoly;
1091                                         }
1092                                 }
1093                         }
1094                 }
1095                 dl= dl->next;
1096         }
1097
1098         filldisplist(&front, dispbase);
1099         filldisplist(&back, dispbase);
1100         
1101         freedisplist(&front);
1102         freedisplist(&back);
1103
1104         filldisplist(dispbase, dispbase);
1105         
1106 }
1107
1108 static void curve_to_filledpoly(Curve *cu, ListBase *nurb, ListBase *dispbase)
1109 {
1110         if(cu->flag & CU_3D) return;
1111
1112         if(dispbase->first && ((DispList*) dispbase->first)->type==DL_SURF) {
1113                 bevels_to_filledpoly(cu, dispbase);
1114         }
1115         else {
1116                 filldisplist(dispbase, dispbase);
1117         }
1118 }
1119
1120 /* taper rules:
1121   - only 1 curve
1122   - first point left, last point right
1123   - based on subdivided points in original curve, not on points in taper curve (still)
1124 */
1125 float calc_taper(Scene *scene, Object *taperobj, int cur, int tot)
1126 {
1127         Curve *cu;
1128         DispList *dl;
1129         
1130         if(taperobj==NULL) return 1.0;
1131         
1132         cu= taperobj->data;
1133         dl= cu->disp.first;
1134         if(dl==NULL) {
1135                 makeDispListCurveTypes(scene, taperobj, 0);
1136                 dl= cu->disp.first;
1137         }
1138         if(dl) {
1139                 float fac= ((float)cur)/(float)(tot-1);
1140                 float minx, dx, *fp;
1141                 int a;
1142                 
1143                 /* horizontal size */
1144                 minx= dl->verts[0];
1145                 dx= dl->verts[3*(dl->nr-1)] - minx;
1146                 if(dx>0.0) {
1147                 
1148                         fp= dl->verts;
1149                         for(a=0; a<dl->nr; a++, fp+=3) {
1150                                 if( (fp[0]-minx)/dx >= fac) {
1151                                         /* interpolate with prev */
1152                                         if(a>0) {
1153                                                 float fac1= (fp[-3]-minx)/dx;
1154                                                 float fac2= (fp[0]-minx)/dx;
1155                                                 if(fac1!=fac2)
1156                                                         return fp[1]*(fac1-fac)/(fac1-fac2) + fp[-2]*(fac-fac2)/(fac1-fac2);
1157                                         }
1158                                         return fp[1];
1159                                 }
1160                         }
1161                         return fp[-2];  // last y coord
1162                 }
1163         }
1164         
1165         return 1.0;
1166 }
1167
1168 void makeDispListMBall(Scene *scene, Object *ob)
1169 {
1170         if(!ob || ob->type!=OB_MBALL) return;
1171
1172         freedisplist(&(ob->disp));
1173         
1174         if(ob->type==OB_MBALL) {
1175                 if(ob==find_basis_mball(scene, ob)) {
1176                         metaball_polygonize(scene, ob);
1177                         tex_space_mball(ob);
1178
1179                         object_deform_mball(ob);
1180                 }
1181         }
1182         
1183         boundbox_displist(ob);
1184 }
1185
1186 static ModifierData *curve_get_tesselate_point(Scene *scene, Object *ob, int forRender, int editmode)
1187 {
1188         ModifierData *md = modifiers_getVirtualModifierList(ob);
1189         ModifierData *preTesselatePoint;
1190         int required_mode;
1191
1192         if(forRender) required_mode = eModifierMode_Render;
1193         else required_mode = eModifierMode_Realtime;
1194
1195         if(editmode) required_mode |= eModifierMode_Editmode;
1196
1197         preTesselatePoint = NULL;
1198         for (; md; md=md->next) {
1199                 if (!modifier_isEnabled(scene, md, required_mode)) continue;
1200
1201                 if (ELEM3(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_MeshDeform)) {
1202                         preTesselatePoint  = md;
1203                 }
1204         }
1205
1206         return preTesselatePoint;
1207 }
1208
1209 static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, float (**originalVerts_r)[3], float (**deformedVerts_r)[3], int *numVerts_r)
1210 {
1211         ModifierData *md = modifiers_getVirtualModifierList(ob);
1212         ModifierData *preTesselatePoint;
1213         Curve *cu= ob->data;
1214         ListBase *nurb= cu->editnurb?cu->editnurb:&cu->nurb;
1215         int numVerts = 0;
1216         int editmode = (!forRender && cu->editnurb);
1217         float (*originalVerts)[3] = NULL;
1218         float (*deformedVerts)[3] = NULL;
1219         float *keyVerts= NULL;
1220         int required_mode;
1221
1222         if(forRender) required_mode = eModifierMode_Render;
1223         else required_mode = eModifierMode_Realtime;
1224
1225         preTesselatePoint = curve_get_tesselate_point(scene, ob, forRender, editmode);
1226         
1227         if(editmode) required_mode |= eModifierMode_Editmode;
1228
1229         if(cu->editnurb==NULL) {
1230                 keyVerts= do_ob_key(scene, ob);
1231
1232                 if(keyVerts) {
1233                         /* split coords from key data, the latter also includes
1234                            tilts, which is passed through in the modifier stack.
1235                            this is also the reason curves do not use a virtual
1236                            shape key modifier yet. */
1237                         deformedVerts= curve_getKeyVertexCos(cu, nurb, keyVerts);
1238                         originalVerts= MEM_dupallocN(deformedVerts);
1239                 }
1240         }
1241         
1242         if (preTesselatePoint) {
1243                 for (; md; md=md->next) {
1244                         ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1245
1246                         md->scene= scene;
1247                         
1248                         if ((md->mode & required_mode) != required_mode) continue;
1249                         if (mti->isDisabled && mti->isDisabled(md, forRender)) continue;
1250                         if (mti->type!=eModifierTypeType_OnlyDeform) continue;
1251
1252                         if (!deformedVerts) {
1253                                 deformedVerts = curve_getVertexCos(cu, nurb, &numVerts);
1254                                 originalVerts = MEM_dupallocN(deformedVerts);
1255                         }
1256
1257                         mti->deformVerts(md, ob, NULL, deformedVerts, numVerts, forRender, editmode);
1258
1259                         if (md==preTesselatePoint)
1260                                 break;
1261                 }
1262         }
1263
1264         if (deformedVerts)
1265                 curve_applyVertexCos(cu, nurb, deformedVerts);
1266         if (keyVerts) /* these are not passed through modifier stack */
1267                 curve_applyKeyVertexTilts(cu, nurb, keyVerts);
1268
1269         if(keyVerts)
1270                 MEM_freeN(keyVerts);
1271
1272         *originalVerts_r = originalVerts;
1273         *deformedVerts_r = deformedVerts;
1274         *numVerts_r = numVerts;
1275 }
1276
1277 static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispbase,
1278         DerivedMesh **derivedFinal, int forRender, float (*originalVerts)[3], float (*deformedVerts)[3])
1279 {
1280         ModifierData *md = modifiers_getVirtualModifierList(ob);
1281         ModifierData *preTesselatePoint;
1282         Curve *cu= ob->data;
1283         ListBase *nurb= cu->editnurb?cu->editnurb:&cu->nurb;
1284         DispList *dl;
1285         int required_mode;
1286         int editmode = (!forRender && cu->editnurb);
1287         DerivedMesh *dm= NULL, *ndm;
1288         float (*dmDeformedVerts)[3] = NULL;
1289         int numVerts;
1290
1291         if(forRender) required_mode = eModifierMode_Render;
1292         else required_mode = eModifierMode_Realtime;
1293
1294         preTesselatePoint = curve_get_tesselate_point(scene, ob, forRender, editmode);
1295         
1296         if(editmode) required_mode |= eModifierMode_Editmode;
1297
1298         if (preTesselatePoint) {
1299                 md = preTesselatePoint->next;
1300         }
1301
1302         if (*derivedFinal) {
1303                 (*derivedFinal)->release (*derivedFinal);
1304         }
1305
1306         for (; md; md=md->next) {
1307                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1308
1309                 md->scene= scene;
1310
1311                 if ((md->mode & required_mode) != required_mode) continue;
1312                 if (mti->isDisabled && mti->isDisabled(md, forRender)) continue;
1313
1314                 if(md->type==eModifierType_Curve && !dm) {
1315                         /* need to put all verts in 1 block for curve deform */
1316                         float *allverts = NULL, *fp;
1317                         int totvert= 0;
1318
1319                         for (dl=dispbase->first; dl; dl=dl->next)
1320                                 totvert+= (dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr;
1321
1322                         fp= allverts= MEM_mallocN(totvert*sizeof(float)*3, "temp vert");
1323                         for (dl=dispbase->first; dl; dl=dl->next) {
1324                                 int offs= 3 * ((dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr);
1325                                 memcpy(fp, dl->verts, sizeof(float) * offs);
1326                                 fp+= offs;
1327                         }
1328
1329                         mti->deformVerts(md, ob, NULL, (float(*)[3]) allverts, totvert, forRender, editmode);
1330
1331                         if (allverts) {
1332                                 fp= allverts;
1333                                 for (dl=dispbase->first; dl; dl=dl->next) {
1334                                         int offs= 3 * ((dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr);
1335                                         memcpy(dl->verts, fp, sizeof(float) * offs);
1336                                         fp+= offs;
1337                                 }
1338                                 MEM_freeN(allverts);
1339                         }
1340                 } else if (mti->type == eModifierTypeType_OnlyDeform ||
1341                                 (mti->type == eModifierTypeType_DeformOrConstruct && !dm)) {
1342                         if (dm) {
1343                                 if (!dmDeformedVerts) {
1344                                         numVerts = dm->getNumVerts(dm);
1345                                         dmDeformedVerts =
1346                                                 MEM_mallocN(sizeof(*dmDeformedVerts) * numVerts, "dfmv");
1347                                         dm->getVertCos(dm, dmDeformedVerts);
1348                                 }
1349
1350                                 mti->deformVerts(md, ob, dm, dmDeformedVerts, numVerts, forRender, editmode);
1351                         } else {
1352                                 for (dl=dispbase->first; dl; dl=dl->next) {
1353                                         mti->deformVerts(md, ob, dm, (float(*)[3]) dl->verts, (dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr, forRender, editmode);
1354                                 }
1355                         }
1356                 } else {
1357                         if (dm) {
1358                                 if (dmDeformedVerts) {
1359                                         DerivedMesh *tdm = CDDM_copy(dm);
1360                                         dm->release(dm);
1361                                         dm = tdm;
1362
1363                                         CDDM_apply_vert_coords(dm, dmDeformedVerts);
1364                                         CDDM_calc_normals(dm);
1365                                 }
1366                         } else {
1367                                 if (ELEM(ob->type, OB_CURVE, OB_FONT) && (cu->flag & CU_DEFORM_FILL)) {
1368                                         curve_to_filledpoly(cu, nurb, dispbase);
1369                                 }
1370
1371                                 dm= CDDM_from_curve_customDB(ob, dispbase);
1372
1373                                 if(dmDeformedVerts) {
1374                                         CDDM_apply_vert_coords(dm, dmDeformedVerts);
1375                                         CDDM_calc_normals(dm);
1376                                 }
1377
1378                                 CDDM_calc_normals(dm);
1379                         }
1380
1381                         ndm = mti->applyModifier(md, ob, dm, forRender, editmode);
1382
1383                         if (ndm) {
1384                                 /* Modifier returned a new derived mesh */
1385
1386                                 if (dm && dm != ndm) /* Modifier  */
1387                                         dm->release (dm);
1388                                 dm = ndm;
1389
1390                                 if (dmDeformedVerts) {
1391                                         MEM_freeN(dmDeformedVerts);
1392                                         dmDeformedVerts= NULL;
1393                                 }
1394                         }
1395                 }
1396         }
1397
1398         if(dm && dmDeformedVerts) {
1399                 DerivedMesh *tdm = CDDM_copy(dm);
1400                 dm->release(dm);
1401                 dm = tdm;
1402
1403                 CDDM_apply_vert_coords(dm, dmDeformedVerts);
1404                 CDDM_calc_normals(dm);
1405                 MEM_freeN(dmDeformedVerts);
1406         }
1407
1408         (*derivedFinal) = dm;
1409
1410         if (deformedVerts) {
1411                 curve_applyVertexCos(ob->data, nurb, originalVerts);
1412                 MEM_freeN(originalVerts);
1413                 MEM_freeN(deformedVerts);
1414         }
1415 }
1416
1417 static void displist_surf_indices(DispList *dl)
1418 {
1419         int a, b, p1, p2, p3, p4;
1420         int *index;
1421         
1422         dl->totindex= 0;
1423         
1424         index=dl->index= MEM_mallocN( 4*sizeof(int)*(dl->parts+1)*(dl->nr+1), "index array nurbs");
1425         
1426         for(a=0; a<dl->parts; a++) {
1427                 
1428                 if (surfindex_displist(dl, a, &b, &p1, &p2, &p3, &p4)==0)
1429                         break;
1430                 
1431                 for(; b<dl->nr; b++, index+=4) {        
1432                         index[0]= p1;
1433                         index[1]= p2;
1434                         index[2]= p4;
1435                         index[3]= p3;
1436                         
1437                         dl->totindex++;
1438                         
1439                         p2= p1; p1++;
1440                         p4= p3; p3++;
1441
1442                 }
1443         }
1444         
1445 }
1446
1447 static DerivedMesh *create_orco_dm(Scene *scene, Object *ob)
1448 {
1449         DerivedMesh *dm;
1450         ListBase disp= {NULL, NULL};
1451
1452         /* OrcoDM should be created from underformed disp lists */
1453         makeDispListCurveTypes_forOrco(scene, ob, &disp);
1454         dm= CDDM_from_curve_customDB(ob, &disp);
1455
1456         freedisplist(&disp);
1457
1458         return dm;
1459 }
1460
1461 static void add_orco_dm(Scene *scene, Object *ob, DerivedMesh *dm, DerivedMesh *orcodm)
1462 {
1463         float (*orco)[3], (*layerorco)[3];
1464         int totvert, a;
1465         Curve *cu= ob->data;
1466
1467         totvert= dm->getNumVerts(dm);
1468
1469         if(orcodm) {
1470                 orco= MEM_callocN(sizeof(float)*3*totvert, "dm orco");
1471
1472                 if(orcodm->getNumVerts(orcodm) == totvert)
1473                         orcodm->getVertCos(orcodm, orco);
1474                 else
1475                         dm->getVertCos(dm, orco);
1476         }
1477         else {
1478                 orco= (float(*)[3])make_orco_curve(scene, ob);
1479         }
1480
1481         for(a=0; a<totvert; a++) {
1482                 float *co = orco[a];
1483                 co[0] = (co[0]-cu->loc[0])/cu->size[0];
1484                 co[1] = (co[1]-cu->loc[1])/cu->size[1];
1485                 co[2] = (co[2]-cu->loc[2])/cu->size[2];
1486         }
1487
1488         if((layerorco = DM_get_vert_data_layer(dm, CD_ORCO))) {
1489                 memcpy(layerorco, orco, sizeof(float)*totvert);
1490                 MEM_freeN(orco);
1491         }
1492         else
1493                 DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, orco);
1494 }
1495
1496 static void curve_calc_orcodm(Scene *scene, Object *ob, DerivedMesh *derivedFinal, int forRender)
1497 {
1498         /* this function represents logic of mesh's orcodm calculation */
1499         /* for displist-based objects */
1500
1501         ModifierData *md = modifiers_getVirtualModifierList(ob);
1502         ModifierData *preTesselatePoint;
1503         Curve *cu= ob->data;
1504         int required_mode;
1505         int editmode = (!forRender && cu->editnurb);
1506         DerivedMesh *ndm, *orcodm= NULL;
1507
1508         if(forRender) required_mode = eModifierMode_Render;
1509         else required_mode = eModifierMode_Realtime;
1510
1511         preTesselatePoint = curve_get_tesselate_point(scene, ob, forRender, editmode);
1512
1513         if(editmode) required_mode |= eModifierMode_Editmode;
1514
1515         if (preTesselatePoint) {
1516                 md = preTesselatePoint->next;
1517         }
1518
1519         for (; md; md=md->next) {
1520                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1521
1522                 md->scene= scene;
1523
1524                 if ((md->mode & required_mode) != required_mode) continue;
1525                 if (mti->isDisabled && mti->isDisabled(md, forRender)) continue;
1526                 if (mti->type!=eModifierTypeType_Constructive) continue;
1527
1528                 if(!orcodm)
1529                         orcodm= create_orco_dm(scene, ob);
1530
1531                 ndm = mti->applyModifier(md, ob, orcodm, forRender, 0);
1532
1533                 if(ndm) {
1534                         /* if the modifier returned a new dm, release the old one */
1535                         if(orcodm && orcodm != ndm) {
1536                                 orcodm->release(orcodm);
1537                         }
1538                         orcodm = ndm;
1539                 }
1540         }
1541
1542         /* add an orco layer if needed */
1543         add_orco_dm(scene, ob, derivedFinal, orcodm);
1544
1545         if(orcodm)
1546                 orcodm->release(orcodm);
1547 }
1548
1549 void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase,
1550         DerivedMesh **derivedFinal, int forRender, int forOrco)
1551 {
1552         ListBase *nubase;
1553         Nurb *nu;
1554         Curve *cu = ob->data;
1555         DispList *dl;
1556         float *data;
1557         int len;
1558         int numVerts;
1559         float (*originalVerts)[3];
1560         float (*deformedVerts)[3];
1561                 
1562         if(!forRender && cu->editnurb)
1563                 nubase= cu->editnurb;
1564         else
1565                 nubase= &cu->nurb;
1566
1567         if(!forOrco)
1568                 curve_calc_modifiers_pre(scene, ob, forRender, &originalVerts, &deformedVerts, &numVerts);
1569
1570         for (nu=nubase->first; nu; nu=nu->next) {
1571                 if(forRender || nu->hide==0) {
1572                         if(nu->pntsv==1) {
1573                                 len= SEGMENTSU(nu)*nu->resolu;
1574                                 
1575                                 dl= MEM_callocN(sizeof(DispList), "makeDispListsurf");
1576                                 dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
1577                                 
1578                                 BLI_addtail(dispbase, dl);
1579                                 dl->parts= 1;
1580                                 dl->nr= len;
1581                                 dl->col= nu->mat_nr;
1582                                 dl->charidx= nu->charidx;
1583                                 dl->rt= nu->flag;
1584                                 
1585                                 data= dl->verts;
1586                                 if(nu->flagu & CU_NURB_CYCLIC) dl->type= DL_POLY;
1587                                 else dl->type= DL_SEGM;
1588                                 
1589                                 makeNurbcurve(nu, data, NULL, NULL, nu->resolu, 3*sizeof(float));
1590                         }
1591                         else {
1592                                 len= (nu->pntsu*nu->resolu) * (nu->pntsv*nu->resolv);
1593                                 
1594                                 dl= MEM_callocN(sizeof(DispList), "makeDispListsurf");
1595                                 dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
1596                                 BLI_addtail(dispbase, dl);
1597
1598                                 dl->col= nu->mat_nr;
1599                                 dl->charidx= nu->charidx;
1600                                 dl->rt= nu->flag;
1601                                 
1602                                 data= dl->verts;
1603                                 dl->type= DL_SURF;
1604                                 
1605                                 dl->parts= (nu->pntsu*nu->resolu);      /* in reverse, because makeNurbfaces works that way */
1606                                 dl->nr= (nu->pntsv*nu->resolv);
1607                                 if(nu->flagv & CU_NURB_CYCLIC) dl->flag|= DL_CYCL_U;    /* reverse too! */
1608                                 if(nu->flagu & CU_NURB_CYCLIC) dl->flag|= DL_CYCL_V;
1609
1610                                 makeNurbfaces(nu, data, 0);
1611                                 
1612                                 /* gl array drawing: using indices */
1613                                 displist_surf_indices(dl);
1614                         }
1615                 }
1616         }
1617
1618         if (!forRender) {
1619                 tex_space_curve(cu);
1620         }
1621
1622         if(!forOrco)
1623                 curve_calc_modifiers_post(scene, ob, dispbase, derivedFinal,
1624                         forRender, originalVerts, deformedVerts);
1625 }
1626
1627 static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispbase,
1628         DerivedMesh **derivedFinal, int forRender, int forOrco)
1629 {
1630         Curve *cu = ob->data;
1631
1632         /* we do allow duplis... this is only displist on curve level */
1633         if(!ELEM3(ob->type, OB_SURF, OB_CURVE, OB_FONT)) return;
1634
1635         if(ob->type==OB_SURF) {
1636                 makeDispListSurf(scene, ob, dispbase, derivedFinal, forRender, forOrco);
1637         }
1638         else if (ELEM(ob->type, OB_CURVE, OB_FONT)) {
1639                 ListBase dlbev;
1640                 ListBase *nubase;
1641                 float (*originalVerts)[3];
1642                 float (*deformedVerts)[3];
1643                 int numVerts;
1644
1645                 if(cu->editnurb)
1646                         nubase= cu->editnurb;
1647                 else
1648                         nubase= &cu->nurb;
1649
1650                 BLI_freelistN(&(cu->bev));
1651
1652                 if(cu->path) free_path(cu->path);
1653                 cu->path= NULL;
1654
1655                 if(ob->type==OB_FONT) BKE_text_to_curve(scene, ob, 0);
1656
1657                 if(!forOrco) curve_calc_modifiers_pre(scene, ob, forRender, &originalVerts, &deformedVerts, &numVerts);
1658
1659                 makeBevelList(ob);
1660
1661                 /* If curve has no bevel will return nothing */
1662                 makebevelcurve(scene, ob, &dlbev);
1663
1664                 /* no bevel or extrude, and no width correction? */
1665                 if (!dlbev.first && cu->width==1.0f) {
1666                         curve_to_displist(cu, nubase, dispbase);
1667                 } else {
1668                         float widfac= cu->width-1.0;
1669                         BevList *bl= cu->bev.first;
1670                         Nurb *nu= nubase->first;
1671
1672                         for (; bl && nu; bl=bl->next,nu=nu->next) {
1673                                 DispList *dl;
1674                                 float *fp1, *data;
1675                                 BevPoint *bevp;
1676                                 int a,b;
1677                                 
1678                                 if (bl->nr) { /* blank bevel lists can happen */
1679                                         
1680                                         /* exception handling; curve without bevel or extrude, with width correction */
1681                                         if(dlbev.first==NULL) {
1682                                                 dl= MEM_callocN(sizeof(DispList), "makeDispListbev");
1683                                                 dl->verts= MEM_callocN(3*sizeof(float)*bl->nr, "dlverts");
1684                                                 BLI_addtail(dispbase, dl);
1685                                                 
1686                                                 if(bl->poly!= -1) dl->type= DL_POLY;
1687                                                 else dl->type= DL_SEGM;
1688                                                 
1689                                                 if(dl->type==DL_SEGM) dl->flag = (DL_FRONT_CURVE|DL_BACK_CURVE);
1690                                                 
1691                                                 dl->parts= 1;
1692                                                 dl->nr= bl->nr;
1693                                                 dl->col= nu->mat_nr;
1694                                                 dl->charidx= nu->charidx;
1695                                                 dl->rt= nu->flag;
1696                                                 
1697                                                 a= dl->nr;
1698                                                 bevp= (BevPoint *)(bl+1);
1699                                                 data= dl->verts;
1700                                                 while(a--) {
1701                                                         data[0]= bevp->vec[0]+widfac*bevp->sina;
1702                                                         data[1]= bevp->vec[1]+widfac*bevp->cosa;
1703                                                         data[2]= bevp->vec[2];
1704                                                         bevp++;
1705                                                         data+=3;
1706                                                 }
1707                                         }
1708                                         else {
1709                                                 DispList *dlb;
1710                                                 
1711                                                 for (dlb=dlbev.first; dlb; dlb=dlb->next) {
1712         
1713                                                                 /* for each part of the bevel use a separate displblock */
1714                                                         dl= MEM_callocN(sizeof(DispList), "makeDispListbev1");
1715                                                         dl->verts= data= MEM_callocN(3*sizeof(float)*dlb->nr*bl->nr, "dlverts");
1716                                                         BLI_addtail(dispbase, dl);
1717         
1718                                                         dl->type= DL_SURF;
1719                                                         
1720                                                         dl->flag= dlb->flag & (DL_FRONT_CURVE|DL_BACK_CURVE);
1721                                                         if(dlb->type==DL_POLY) dl->flag |= DL_CYCL_U;
1722                                                         if(bl->poly>=0) dl->flag |= DL_CYCL_V;
1723                                                         
1724                                                         dl->parts= bl->nr;
1725                                                         dl->nr= dlb->nr;
1726                                                         dl->col= nu->mat_nr;
1727                                                         dl->charidx= nu->charidx;
1728                                                         dl->rt= nu->flag;
1729                                                         dl->bevelSplitFlag= MEM_callocN(sizeof(*dl->col2)*((bl->nr+0x1F)>>5), "col2");
1730                                                         bevp= (BevPoint *)(bl+1);
1731         
1732                                                                 /* for each point of poly make a bevel piece */
1733                                                         bevp= (BevPoint *)(bl+1);
1734                                                         for(a=0; a<bl->nr; a++,bevp++) {
1735                                                                 float fac=1.0;
1736                                                                 if (cu->taperobj==NULL) {
1737                                                                         if ( (cu->bevobj!=NULL) || !((cu->flag & CU_FRONT) || (cu->flag & CU_BACK)) )
1738                                                                                 fac = bevp->radius;
1739                                                                 } else {
1740                                                                         fac = calc_taper(scene, cu->taperobj, a, bl->nr);
1741                                                                 }
1742                                                                 
1743                                                                 if (bevp->split_tag) {
1744                                                                         dl->bevelSplitFlag[a>>5] |= 1<<(a&0x1F);
1745                                                                 }
1746         
1747                                                                         /* rotate bevel piece and write in data */
1748                                                                 fp1= dlb->verts;
1749                                                                 for (b=0; b<dlb->nr; b++,fp1+=3,data+=3) {
1750                                                                         if(cu->flag & CU_3D) {
1751                                                                                 float vec[3];
1752         
1753                                                                                 vec[0]= fp1[1]+widfac;
1754                                                                                 vec[1]= fp1[2];
1755                                                                                 vec[2]= 0.0;
1756                                                                                 
1757                                                                                 mul_qt_v3(bevp->quat, vec);
1758                                                                                 
1759                                                                                 data[0]= bevp->vec[0] + fac*vec[0];
1760                                                                                 data[1]= bevp->vec[1] + fac*vec[1];
1761                                                                                 data[2]= bevp->vec[2] + fac*vec[2];
1762                                                                         }
1763                                                                         else {
1764                                                                                 data[0]= bevp->vec[0] + fac*(widfac+fp1[1])*bevp->sina;
1765                                                                                 data[1]= bevp->vec[1] + fac*(widfac+fp1[1])*bevp->cosa;
1766                                                                                 data[2]= bevp->vec[2] + fac*fp1[2];
1767                                                                         }
1768                                                                 }
1769                                                         }
1770                                                         
1771                                                         /* gl array drawing: using indices */
1772                                                         displist_surf_indices(dl);
1773                                                 }
1774                                         }
1775                                 }
1776
1777                         }
1778                         freedisplist(&dlbev);
1779                 }
1780
1781                 if (!(cu->flag & CU_DEFORM_FILL)) {
1782                         curve_to_filledpoly(cu, nubase, dispbase);
1783                 }
1784
1785                 if(cu->flag & CU_PATH) calc_curvepath(ob);
1786
1787                  if (!forRender) {
1788                          tex_space_curve(cu);
1789                  }
1790
1791                 if(!forOrco) curve_calc_modifiers_post(scene, ob, dispbase, derivedFinal, forRender, originalVerts, deformedVerts);
1792
1793                 if (cu->flag & CU_DEFORM_FILL && !ob->derivedFinal) {
1794                         curve_to_filledpoly(cu, nubase, dispbase);
1795                 }
1796         }
1797 }
1798
1799 void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco)
1800 {
1801         Curve *cu = ob->data;
1802         ListBase *dispbase;
1803
1804         freedisplist(&(ob->disp));
1805         dispbase= &(cu->disp);
1806         freedisplist(dispbase);
1807
1808         do_makeDispListCurveTypes(scene, ob, dispbase, &ob->derivedFinal, 0, forOrco);
1809
1810         if (ob->derivedFinal) {
1811                 DM_set_object_boundbox (ob, ob->derivedFinal);
1812         } else {
1813                 boundbox_displist (ob);
1814         }
1815 }
1816
1817 void makeDispListCurveTypes_forRender(Scene *scene, Object *ob, ListBase *dispbase,
1818         DerivedMesh **derivedFinal, int forOrco)
1819 {
1820         do_makeDispListCurveTypes(scene, ob, dispbase, derivedFinal, 1, forOrco);
1821 }
1822
1823 void makeDispListCurveTypes_forOrco(struct Scene *scene, struct Object *ob, struct ListBase *dispbase)
1824 {
1825         do_makeDispListCurveTypes(scene, ob, dispbase, NULL, 1, 1);
1826 }
1827
1828 /* add Orco layer to the displist object which has got derived mesh and return orco */
1829 float *makeOrcoDispList(Scene *scene, Object *ob, DerivedMesh *derivedFinal, int forRender) {
1830         float *orco;
1831
1832         if (derivedFinal == NULL)
1833                 derivedFinal= ob->derivedFinal;
1834
1835         if (!derivedFinal->getVertDataArray(derivedFinal, CD_ORCO)) {
1836                 curve_calc_orcodm(scene, ob, derivedFinal, forRender);
1837         }
1838
1839         orco= derivedFinal->getVertDataArray(derivedFinal, CD_ORCO);
1840
1841         if(orco) {
1842                 orco= MEM_dupallocN(orco);
1843         }
1844
1845         return orco;
1846 }
1847
1848 void imagestodisplist(void)
1849 {
1850         /* removed */
1851 }
1852
1853 /* this is confusing, there's also min_max_object, appplying the obmat... */
1854 static void boundbox_displist(Object *ob)
1855 {
1856         BoundBox *bb=0;
1857         float min[3], max[3];
1858         DispList *dl;
1859         float *vert;
1860         int a, tot=0;
1861         
1862         INIT_MINMAX(min, max);
1863
1864         if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
1865                 Curve *cu= ob->data;
1866                 int doit= 0;
1867
1868                 if(cu->bb==0) cu->bb= MEM_callocN(sizeof(BoundBox), "boundbox");
1869                 bb= cu->bb;
1870                 
1871                 dl= cu->disp.first;
1872
1873                 while (dl) {
1874                         if(dl->type==DL_INDEX3) tot= dl->nr;
1875                         else tot= dl->nr*dl->parts;
1876                         
1877                         vert= dl->verts;
1878                         for(a=0; a<tot; a++, vert+=3) {
1879                                 doit= 1;
1880                                 DO_MINMAX(vert, min, max);
1881                         }
1882
1883                         dl= dl->next;
1884                 }
1885                 
1886                 if(!doit) {
1887                         min[0] = min[1] = min[2] = -1.0f;
1888                         max[0] = max[1] = max[2] = 1.0f;
1889                 }
1890                 
1891         }
1892         
1893         if(bb) {
1894                 boundbox_set_from_min_max(bb, min, max);
1895         }
1896 }
1897