Initial revision
[blender.git] / source / blender / blenkernel / intern / displist.c
1
2 /*  displist.c      GRAPHICS
3  * 
4  *  
5  *  maart 95
6  * 
7  * $Id$
8  *
9  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version. The Blender
15  * Foundation also sells licenses for use in proprietary software under
16  * the Blender License.  See http://www.blender.org/BL/ for information
17  * about this.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software Foundation,
26  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27  *
28  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
29  * All rights reserved.
30  *
31  * The Original Code is: all of this file.
32  *
33  * Contributor(s): none yet.
34  *
35  * ***** END GPL/BL DUAL LICENSE BLOCK *****
36  */
37 #include <math.h>
38 #include <stdio.h>
39 #include <string.h>
40
41 #ifdef WIN32
42 #include "BLI_winstuff.h"
43 #endif
44 #include "MEM_guardedalloc.h"
45
46 #include "nla.h" /* For __NLA: Please do not remove yet */
47
48 #include "IMB_imbuf_types.h"
49
50 #include "DNA_texture_types.h"
51 #include "DNA_meta_types.h"
52 #include "DNA_curve_types.h"
53 #include "DNA_listBase.h"
54 #include "DNA_lamp_types.h"
55 #include "DNA_object_types.h"
56 #include "DNA_mesh_types.h"
57 #include "DNA_scene_types.h"
58 #include "DNA_image_types.h"
59 #include "DNA_material_types.h"
60 #include "DNA_view3d_types.h"
61 #include "DNA_lattice_types.h"
62
63 #include "BLI_blenlib.h"
64 #include "BLI_arithb.h"
65 #include "BLI_editVert.h"
66
67 #include "BKE_bad_level_calls.h"
68 #include "BKE_utildefines.h"
69 #include "BKE_global.h"
70 #include "BKE_displist.h"
71 #include "BKE_object.h"
72 #include "BKE_world.h"
73 #include "BKE_mesh.h"
74 #include "BKE_effect.h"
75 #include "BKE_mball.h"
76 #include "BKE_material.h"
77 #include "BKE_curve.h"
78 #include "BKE_anim.h"
79 #include "BKE_screen.h"
80 #include "BKE_texture.h"
81 #include "BKE_library.h"
82 #include "BKE_font.h"
83 #include "BKE_lattice.h"
84 #include "BKE_scene.h"
85 #include "BKE_subsurf.h"
86
87 /***/
88
89 typedef struct _FastLamp FastLamp;
90 struct _FastLamp {
91         FastLamp *next;
92         
93         short type, mode, lay, rt;
94         float co[3];
95         float vec[3];
96         float dist, distkw, att1, att2, spotsi, spotbl, r, g, b;
97 };
98
99 /***/
100
101 static FastLamp *fastlamplist= NULL;
102 static float fviewmat[4][4];
103
104 static void displistmesh_free(DispListMesh *dlm) {
105         // also check on mvert and mface, can be NULL after decimator (ton)
106         if( dlm->mvert) MEM_freeN(dlm->mvert);
107         if (dlm->mface) MEM_freeN(dlm->mface);
108         if (dlm->mcol) MEM_freeN(dlm->mcol);
109         if (dlm->tface) MEM_freeN(dlm->tface);
110         MEM_freeN(dlm);
111 }
112
113 static DispListMesh *displistmesh_copy(DispListMesh *odlm) {
114         DispListMesh *ndlm= MEM_dupallocN(odlm);
115         ndlm->mvert= MEM_dupallocN(odlm->mvert);
116         ndlm->mface= MEM_dupallocN(odlm->mface);
117         if (odlm->mcol) ndlm->mcol= MEM_dupallocN(odlm->mcol);
118         if (odlm->tface) ndlm->tface= MEM_dupallocN(odlm->tface);
119         
120         return ndlm;
121 }
122
123 void free_disp_elem(DispList *dl)
124 {
125         if(dl) {
126                 if(dl->verts) MEM_freeN(dl->verts);
127                 if(dl->nors) MEM_freeN(dl->nors);
128                 if(dl->index) MEM_freeN(dl->index);
129                 if(dl->col1) MEM_freeN(dl->col1);
130                 if(dl->col2) MEM_freeN(dl->col2);
131                 if(dl->mesh) displistmesh_free(dl->mesh);
132                 MEM_freeN(dl);
133         }
134 }
135
136 void freedisplist(ListBase *lb)
137 {
138         DispList *dl;
139
140         dl= lb->first;
141         while(dl) {
142                 BLI_remlink(lb, dl);
143                 free_disp_elem(dl);
144                 dl= lb->first;
145         }
146 }
147
148 void free_displist_by_type(ListBase *lb, int type) 
149 {
150         DispList *dl;
151         
152         for (dl= lb->first; dl; ) {
153                 DispList *next= dl->next;
154                 
155                 if (dl->type==type) {
156                         BLI_remlink(lb, dl);
157                         free_disp_elem(dl);
158                 }
159                 
160                 dl= next;
161         }       
162 }
163
164 DispList *find_displist_create(ListBase *lb, int type)
165 {
166         DispList *dl;
167         
168         dl= lb->first;
169         while(dl) {
170                 if(dl->type==type) return dl;
171                 dl= dl->next;
172         }
173
174         dl= MEM_callocN(sizeof(DispList), "find_disp");
175         dl->type= type;
176         BLI_addtail(lb, dl);
177
178         return dl;
179 }
180
181 DispList *find_displist(ListBase *lb, int type)
182 {
183         DispList *dl;
184         
185         dl= lb->first;
186         while(dl) {
187                 if(dl->type==type) return dl;
188                 dl= dl->next;
189         }
190
191         return 0;
192 }
193
194 void copy_displist(ListBase *lbn, ListBase *lb)
195 {
196         DispList *dln, *dl;
197         
198         lbn->first= lbn->last= 0;
199         
200         dl= lb->first;
201         while(dl) {
202                 
203                 dln= MEM_dupallocN(dl);
204                 BLI_addtail(lbn, dln);
205                 dln->verts= MEM_dupallocN(dl->verts);
206                 dln->nors= MEM_dupallocN(dl->nors);
207                 dln->index= MEM_dupallocN(dl->index);
208                 dln->col1= MEM_dupallocN(dl->col1);
209                 dln->col2= MEM_dupallocN(dl->col2);
210                 if (dl->mesh)
211                         dln->mesh= displistmesh_copy(dl->mesh);
212                 
213                 dl= dl->next;
214         }
215 }
216
217 static void initfastshade(void)
218 {
219         Base *base;
220         Object *ob;
221         Lamp *la;
222         FastLamp *fl;
223         float mat[4][4];
224
225         R.vlr= 0;
226         
227         init_render_world();
228         
229         if(fastlamplist) return;
230         if(G.scene->camera==0) G.scene->camera= scene_find_camera(G.scene);
231         if(G.scene->camera==0) return;
232
233         /* uit roteerscene gejat */
234         where_is_object(G.scene->camera);
235         Mat4CpyMat4(R.viewinv, G.scene->camera->obmat);
236         Mat4Ortho(R.viewinv);
237         Mat4Invert(fviewmat, R.viewinv);
238
239
240         /* initrendertexture(); */
241
242         base= G.scene->base.first;
243         while(base) {
244                 ob= base->object;
245                 if( ob->type==OB_LAMP && (base->lay & G.scene->lay)) {
246                         
247                         Mat4MulMat4(mat, ob->obmat, fviewmat);
248                         
249                         la= ob->data;
250                         fl= MEM_mallocN(sizeof(FastLamp), "initfastshade2");
251
252                         fl->next= fastlamplist;
253                         fastlamplist= fl;
254
255                         fl->type= la->type;
256                         fl->mode= la->mode;
257                         fl->lay= base->lay;
258                         
259                         fl->vec[0]= mat[2][0];
260                         fl->vec[1]= mat[2][1];
261                         fl->vec[2]= mat[2][2];
262                         Normalise(fl->vec);
263                         
264                         fl->co[0]= mat[3][0];
265                         fl->co[1]= mat[3][1];
266                         fl->co[2]= mat[3][2];
267
268                         fl->dist= la->dist;
269                         fl->distkw= fl->dist*fl->dist;
270                         fl->att1= la->att1;
271                         fl->att2= la->att2;
272
273                         fl->spotsi= (float)cos( M_PI*la->spotsize/360.0 );
274                         fl->spotbl= (1.0f-fl->spotsi)*la->spotblend;
275         
276                         fl->r= la->energy*la->r;
277                         fl->g= la->energy*la->g;
278                         fl->b= la->energy*la->b;
279                 }
280                 
281                 if(base->next==0 && G.scene->set && base==G.scene->base.last) base= G.scene->set->base.first;
282                 else base= base->next;
283         }
284 }
285
286
287 void freefastshade()
288 {
289         while (fastlamplist) {
290                 FastLamp *fl= fastlamplist;
291                 fastlamplist= fl->next;
292                 
293                 MEM_freeN(fl);
294         }
295 }
296
297
298 static void fastshade(float *co, float *nor, float *orco, Material *ma, char *col1, char *col2, char *vertcol)
299 {
300         FastLamp *fl;
301         float i, t, inp, soft, inpr, inpg, inpb, isr=0, isg=0, isb=0, lv[3], lampdist, ld;
302         float inpr1, inpg1, inpb1, isr1=0, isg1=0, isb1=0;
303         int a, back;
304
305         if(ma==0) return;
306         R.mat= ma;
307         R.matren= ma->ren;
308         ma= R.matren;
309
310         if(ma->mode & MA_VERTEXCOLP) {
311                 if(vertcol) {
312                         ma->r= vertcol[3]/255.0;
313                         ma->g= vertcol[2]/255.0;
314                         ma->b= vertcol[1]/255.0;
315                 }
316         }
317         
318         if(ma->texco) {
319                 VECCOPY(R.lo, orco);
320                 VECCOPY(R.vn, nor);
321                 
322                 if(ma->texco & TEXCO_GLOB) {
323                         VECCOPY(R.gl, R.lo);
324                 }
325                 if(ma->texco & TEXCO_WINDOW) {
326                         VECCOPY(R.winco, R.lo);
327                 }
328                 if(ma->texco & TEXCO_STICKY) {
329                         VECCOPY(R.sticky, R.lo);
330                 }
331                 if(ma->texco & TEXCO_UV) {
332                         VECCOPY(R.uv, R.lo);
333                 }
334                 if(ma->texco & TEXCO_OBJECT) {
335                         VECCOPY(R.co, R.lo);
336                 }
337                 if(ma->texco & TEXCO_NORM) {
338                         VECCOPY(R.orn, R.vn);
339                 }
340                 if(ma->texco & TEXCO_REFL) {
341                         
342                         inp= 2.0*(R.vn[2]);
343                         R.ref[0]= (inp*R.vn[0]);
344                         R.ref[1]= (inp*R.vn[1]);
345                         R.ref[2]= (-1.0+inp*R.vn[2]);
346                 }
347
348                 if(ma->mode & MA_VERTEXCOLP) {
349                         R.mat->r= ma->r;
350                         R.mat->g= ma->g;
351                         R.mat->b= ma->b;
352                 }
353                 do_material_tex();
354         }
355
356         if(ma->mode & MA_SHLESS) {
357                 if(vertcol && (ma->mode & (MA_VERTEXCOL+MA_VERTEXCOLP))== MA_VERTEXCOL ) {
358                         col1[3]= vertcol[3]*ma->r;
359                         col1[2]= vertcol[2]*ma->g;
360                         col1[1]= vertcol[1]*ma->b;
361                 }
362                 else {
363                         col1[3]= (255.0*ma->r);
364                         col1[2]= (255.0*ma->g);
365                         col1[1]= (255.0*ma->b);
366                 }
367                 if(col2) {
368                         col2[3]= col1[3];
369                         col2[2]= col1[2];
370                         col2[1]= col1[1];
371                 }
372                 return;
373         }
374
375         if( vertcol && (ma->mode & (MA_VERTEXCOL+MA_VERTEXCOLP))== MA_VERTEXCOL ) {
376                 inpr= inpr1= ma->emit+vertcol[3]/255.0;
377                 inpg= inpg1= ma->emit+vertcol[2]/255.0;
378                 inpb= inpb1= ma->emit+vertcol[1]/255.0;
379         }
380         else {
381                 inpr= inpg= inpb= inpr1= inpg1= inpb1= ma->emit;
382         }
383         
384         /* col[0]= (255.0*ma->r); */
385         /* col[1]= (255.0*ma->g); */
386         /* col[2]= (255.0*ma->b); */
387
388         for (fl= fastlamplist; fl; fl= fl->next) {
389                 /* if(fl->mode & LA_LAYER) if((fl->lay & ma->lay)==0) continue; */
390
391                 if(fl->type==LA_SUN || fl->type==LA_HEMI) {
392                         VECCOPY(lv, fl->vec);
393                         lampdist= 1.0;
394                 }
395                 else {
396                         lv[0]= fl->co[0] - co[0];
397                         lv[1]= fl->co[1] - co[1];
398                         lv[2]= fl->co[2] - co[2];
399                         ld= sqrt(lv[0]*lv[0]+lv[1]*lv[1]+lv[2]*lv[2]);
400                         lv[0]/=ld;
401                         lv[1]/=ld;
402                         lv[2]/=ld;
403
404                         if(fl->mode & LA_QUAD) {
405                                 t= 1.0;
406                                 if(fl->att1>0.0)
407                                         t= fl->dist/(fl->dist+fl->att1*ld);
408                                 if(fl->att2>0.0)
409                                         t*= fl->distkw/(fl->distkw+fl->att2*ld*ld);
410
411                                 lampdist= t;
412                         }
413                         else {
414                                 lampdist= (fl->dist/(fl->dist+ld));
415                         }
416
417                         if(fl->mode & LA_SPHERE) {
418                                 t= fl->dist - ld;
419                                 if(t<0.0) continue;
420                                 
421                                 t/= fl->dist;
422                                 lampdist*= (t);
423                         }
424                 }
425
426                 if(fl->type==LA_SPOT) {
427                         inp= lv[0]*fl->vec[0]+lv[1]*fl->vec[1]+lv[2]*fl->vec[2];
428                         if(inp<fl->spotsi) continue;
429                         else {
430                                 t= inp-fl->spotsi;
431                                 i= 1.0;
432                                 soft= 1.0;
433                                 if(t<fl->spotbl && fl->spotbl!=0.0) {
434                                         /* zachte gebied */
435                                         i= t/fl->spotbl;
436                                         t= i*i;
437                                         soft= (3.0*t-2.0*t*i);
438                                         inp*= soft;
439                                 }
440
441                                 lampdist*=inp;
442                         }
443                 }
444
445                 inp= nor[0]*lv[0]+ nor[1]*lv[1]+ nor[2]*lv[2];
446
447                 back= 0;
448                 if(inp<0.0) {
449                         back= 1;
450                         inp= -inp;
451                 }
452                 inp*= lampdist*ma->ref;
453
454                 if(back==0) {
455                         inpr+= inp*fl->r;
456                         inpg+= inp*fl->g;
457                         inpb+= inp*fl->b;
458                 } else if(col2) {
459                         inpr1+= inp*fl->r;
460                         inpg1+= inp*fl->g;
461                         inpb1+= inp*fl->b;
462                 }
463                 if(ma->spec) {
464                         
465                         lv[2]+= 1.0;
466                         Normalise(lv);
467                         t= nor[0]*lv[0]+nor[1]*lv[1]+nor[2]*lv[2];
468                         if(t>0) {
469                                 t= ma->spec*lampdist*RE_Spec(t, ma->har);
470                                 if(back==0) {
471                                         isr+= t*(fl->r * ma->specr);
472                                         isg+= t*(fl->g * ma->specg);
473                                         isb+= t*(fl->b * ma->specb);
474                                 }
475                                 else if(col2) {
476                                         isr1+= t*(fl->r * ma->specr);
477                                         isg1+= t*(fl->g * ma->specg);
478                                         isb1+= t*(fl->b * ma->specb);
479                                 }
480                         }
481                 }
482
483         }
484
485         a= 256*(inpr*ma->r + ma->ambr +isr);
486         if(a>255) col1[3]= 255; 
487         else col1[3]= a;
488         a= 256*(inpg*ma->g + ma->ambg +isg);
489         if(a>255) col1[2]= 255; 
490         else col1[2]= a;
491         a= 256*(inpb*ma->b + ma->ambb +isb);
492         if(a>255) col1[1]= 255; 
493         else col1[1]= a;
494
495         if(col2) {
496                 a= 256*(inpr1*ma->r + ma->ambr +isr1);
497                 if(a>255) col2[3]= 255; 
498                 else col2[3]= a;
499                 a= 256*(inpr1*ma->g + ma->ambg +isg1);
500                 if(a>255) col2[2]= 255; 
501                 else col2[2]= a;
502                 a= 256*(inpr1*ma->b + ma->ambb +isb1);
503                 if(a>255) col2[1]= 255; 
504                 else col2[1]= a;
505         }
506
507 }
508
509 void addnormalsDispList(Object *ob, ListBase *lb)
510 {
511         DispList *dl = NULL;
512         Mesh *me;
513         MVert *ve1, *ve2, *ve3, *ve4;
514         MFace *mface;
515         float *vdata, *ndata, nor[3];
516         float *v1, *v2, *v3, *v4;
517         float *n1, *n2, *n3, *n4;
518         int a, b, p1, p2, p3, p4;
519
520         
521         if(ob->type==OB_MESH) {
522                 
523                 me= get_mesh(ob);
524                 
525                 if (mesh_uses_displist(me)) {
526                         DispList *dl= find_displist(&me->disp, DL_MESH);
527                         
528                         if (dl && !dl->nors) {
529                                 DispListMesh *dlm= dl->mesh;
530                                 int i;
531                                 
532                                 dl->nors= MEM_mallocN(sizeof(*dl->nors)*3*dlm->totface, "meshnormals");
533                                 
534                                 for (i=0; i<dlm->totface; i++) {
535                                         MFaceInt *mf= &dlm->mface[i];
536                                         float *no= &dl->nors[i*3];
537                                         
538                                         if (mf->v3) {
539                                                 if (mf->v4)
540                                                         CalcNormFloat4(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, dlm->mvert[mf->v4].co, no);
541                                                 else
542                                                         CalcNormFloat(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, no);
543                                         }
544                                 }
545                         }
546                 } else {
547                         if(me->totface==0) return;
548                         
549                         if(me->disp.first==0) {
550                                 dl= MEM_callocN(sizeof(DispList), "meshdisp");
551                                 dl->type= DL_NORS;
552                                 dl->parts= 1;
553                                 dl->nr= me->totface;
554                                 BLI_addtail(&me->disp, dl);
555                         }
556                         
557                         if(dl->nors==0) {
558                                 dl->nors= MEM_mallocN(sizeof(float)*3*me->totface, "meshnormals");
559                                 n1= dl->nors;
560                                 mface= me->mface;
561                                 a= me->totface;
562                                 while(a--) {
563                                         if(mface->v3) {
564                                                 ve1= me->mvert+mface->v1;
565                                                 ve2= me->mvert+mface->v2;
566                                                 ve3= me->mvert+mface->v3;
567                                                 ve4= me->mvert+mface->v4;
568                                                 
569                                                 if(mface->v4) CalcNormFloat4(ve1->co, ve2->co, ve3->co, ve4->co, n1);
570                                                 else CalcNormFloat(ve1->co, ve2->co, ve3->co, n1);
571                                         }
572                                         n1+= 3;
573                                         mface++;
574                                 }
575                         }
576                 }
577
578                 return;
579         }
580
581         dl= lb->first;
582         
583         while(dl) {
584                 if(dl->type==DL_INDEX3) {
585                         if(dl->nors==0) {
586                                 dl->nors= MEM_callocN(sizeof(float)*3, "dlnors");
587                                 if(dl->verts[2]<0.0) dl->nors[2]= -1.0;
588                                 else dl->nors[2]= 1.0;
589                         }
590                 }
591                 else if(dl->type==DL_SURF) {
592                         if(dl->nors==0) {
593                                 dl->nors= MEM_callocN(sizeof(float)*3*dl->nr*dl->parts, "dlnors");
594                                 
595                                 vdata= dl->verts;
596                                 ndata= dl->nors;
597                                 
598                                 for(a=0; a<dl->parts; a++) {
599         
600                                         DL_SURFINDEX(dl->flag & 1, dl->flag & 2, dl->nr, dl->parts);
601         
602                                         v1= vdata+ 3*p1; 
603                                         n1= ndata+ 3*p1;
604                                         v2= vdata+ 3*p2; 
605                                         n2= ndata+ 3*p2;
606                                         v3= vdata+ 3*p3; 
607                                         n3= ndata+ 3*p3;
608                                         v4= vdata+ 3*p4; 
609                                         n4= ndata+ 3*p4;
610                                         
611                                         for(; b<dl->nr; b++) {
612         
613                                                 CalcNormFloat4(v1, v3, v4, v2, nor);
614         
615                                                 VecAddf(n1, n1, nor);
616                                                 VecAddf(n2, n2, nor);
617                                                 VecAddf(n3, n3, nor);
618                                                 VecAddf(n4, n4, nor);
619         
620                                                 v2= v1; v1+= 3;
621                                                 v4= v3; v3+= 3;
622                                                 n2= n1; n1+= 3;
623                                                 n4= n3; n3+= 3;
624                                         }
625                                 }
626                                 a= dl->parts*dl->nr;
627                                 v1= ndata;
628                                 while(a--) {
629                                         Normalise(v1);
630                                         v1+= 3;
631                                 }
632                         }
633                 }
634                 dl= dl->next;
635         }
636 }
637
638
639 void shadeDispList(Object *ob)
640 {
641         MFace *mface;
642         MVert *mvert;
643         DispList *dl, *dlob, *dldeform;
644         Material *ma = NULL;
645         Mesh *me;
646         Curve *cu;
647 /*      extern Material defmaterial;     *//* initrender.c, already in bad lev calls*/
648         float *orco, imat[3][3], tmat[4][4], mat[4][4], vec[3], xn, yn, zn;
649         float *fp, *nor, n1[3];
650         unsigned int *col1, *col2, *vertcol;
651         int a, lastmat= -1, need_orco = 0;
652
653         if(ob->flag & OB_FROMDUPLI) return;
654         initfastshade();
655
656         Mat4MulMat4(mat, ob->obmat, fviewmat);
657         
658         Mat4Invert(tmat, mat);
659         Mat3CpyMat4(imat, tmat);
660         
661         /* we halen de dl_verts eruit, deform info */
662         dldeform= find_displist(&ob->disp, DL_VERTS);
663         if(dldeform) BLI_remlink(&ob->disp, dldeform);
664         
665         /* Metaballs hebben de standaard displist aan het Object zitten */
666         if(ob->type!=OB_MBALL) freedisplist(&ob->disp);
667
668         if((R.flag & R_RENDERING)==0) {
669                 need_orco= 0;
670                 for(a=0; a<ob->totcol; a++) {
671                         ma= give_current_material(ob, a+1);
672                         if(ma) {
673                                 init_render_material(ma);
674                                 if(ma->ren->texco & TEXCO_ORCO) need_orco= 1;
675                         }
676                 }
677         }
678         if(ob->type==OB_MESH) {
679                 
680                 me= ob->data;
681                 
682                 if (mesh_uses_displist(me)) {
683                         if (need_orco) {
684                                 make_orco_displist_mesh(ob, me->subdiv);
685                                 orco= me->orco;
686                         }
687
688                         dl= me->disp.first;
689                         while(dl) {
690                                 if(dl->type==DL_MESH) {
691                                         DispListMesh *dlm= dl->mesh;
692                                         int i;
693                                         
694                                         dlob= MEM_callocN(sizeof(DispList), "displistshade");
695                                         BLI_addtail(&ob->disp, dlob);
696                                         dlob->type= DL_VERTCOL;
697                                 
698                                         dlob->col1= MEM_mallocN(sizeof(*dlob->col1)*dlm->totface*4, "col1");
699                                         if (me->flag & ME_TWOSIDED)
700                                                 dlob->col2= MEM_mallocN(sizeof(*dlob->col2)*dlm->totface*4, "col1");
701                                         
702                                         for (i=0; i<dlm->totface; i++) {
703                                                 MFaceInt *mf= &dlm->mface[i];
704
705                                                 if (mf->v3) {
706                                                         int j, vidx[4], nverts= mf->v4?4:3;
707                                                         unsigned int *col1base= &dlob->col1[i*4];
708                                                         unsigned int *col2base= dlob->col2?&dlob->col2[i*4]:NULL;
709                                                         MCol *mcolbase= dlm->mcol?&dlm->mcol[i*4]:NULL;
710                                                         float nor[3];
711                                                         
712                                                         ma= give_current_material(ob, mf->mat_nr+1);
713                                                         if(ma==0) ma= &defmaterial;
714                                                         
715                                                         vidx[0]= mf->v1;
716                                                         vidx[1]= mf->v2;
717                                                         vidx[2]= mf->v3;
718                                                         vidx[3]= mf->v4;
719
720                                                         if (mf->v4)
721                                                                 CalcNormFloat4(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, dlm->mvert[mf->v4].co, nor);
722                                                         else
723                                                                 CalcNormFloat(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, nor);
724
725                                                         n1[0]= imat[0][0]*nor[0]+imat[0][1]*nor[1]+imat[0][2]*nor[2];
726                                                         n1[1]= imat[1][0]*nor[0]+imat[1][1]*nor[1]+imat[1][2]*nor[2];
727                                                         n1[2]= imat[2][0]*nor[0]+imat[2][1]*nor[1]+imat[2][2]*nor[2];
728                                                         Normalise(n1);
729
730                                                         for (j=0; j<nverts; j++) {
731                                                                 MVert *mv= &dlm->mvert[vidx[j]];
732                                                                 unsigned int *col1= &col1base[j];
733                                                                 unsigned int *col2= col2base?&col2base[j]:NULL;
734                                                                 MCol *mcol= mcolbase?&mcolbase[j]:NULL;
735                                                                 
736                                                                 VECCOPY(vec, mv->co);
737                                                                 Mat4MulVecfl(mat, vec);
738                                                         
739                                                                 if (need_orco && orco)
740                                                                         fastshade(vec, n1, &orco[vidx[j]*3], ma, (char *)col1, (char*)col2, (char*) mcol);
741                                                                 else
742                                                                         fastshade(vec, n1, mv->co, ma, (char *)col1, (char*)col2, (char*) mcol);
743                                                         }
744                                                 }
745                                         }
746                                 }
747                                 dl= dl->next;
748                         }
749                         
750                         if (need_orco && orco) {
751                                 MEM_freeN(me->orco);
752                                 me->orco= NULL;
753                         }
754                 }
755                 else if(me->totvert>0) {
756                 
757                         if(me->orco==0 && need_orco) {
758                                 make_orco_mesh(me);
759                         }
760                         orco= me->orco;
761                         /* ms= me->msticky; */
762                         
763                         dl= me->disp.first;
764                         if(dl==0 || dl->nors==0) addnormalsDispList(ob, &me->disp);
765                         dl= me->disp.first;
766                         if(dl==0 || dl->nors==0) return;
767                         nor= dl->nors;
768                         
769                         dl= MEM_callocN(sizeof(DispList), "displistshade");
770                         BLI_addtail(&ob->disp, dl);
771                         dl->type= DL_VERTCOL;
772                         col1= dl->col1= MEM_mallocN(4*sizeof(int)*me->totface, "col1");
773                         col2= 0;
774                         if(me->tface) tface_to_mcol(me);
775                         vertcol= (unsigned int *)me->mcol;
776                         
777                         if( me->flag & ME_TWOSIDED) {
778                                 col2= dl->col2= MEM_mallocN(4*sizeof(int)*me->totface, "col2");
779                         }
780                         
781                         /* even geen puno's */
782                         mvert= me->mvert;
783                         a= me->totvert;
784                         while(FALSE || a--) {
785                                 
786                                 VECCOPY(vec, mvert->co);
787                                 Mat4MulVecfl(mat, vec);
788                                 
789                                 xn= mvert->no[0]; 
790                                 yn= mvert->no[1]; 
791                                 zn= mvert->no[2];
792                                 
793                                 /* transpose ! */
794                                 n1[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
795                                 n1[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
796                                 n1[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
797                                 Normalise(n1);
798                                 
799                                 mvert++;
800                         }               
801                         
802                         mface= me->mface;
803                         a= me->totface;
804                         while(a--) {
805                                 
806                                 if(mface->v3) {
807                                 
808                                         /* transpose ! */
809                                         n1[0]= imat[0][0]*nor[0]+imat[0][1]*nor[1]+imat[0][2]*nor[2];
810                                         n1[1]= imat[1][0]*nor[0]+imat[1][1]*nor[1]+imat[1][2]*nor[2];
811                                         n1[2]= imat[2][0]*nor[0]+imat[2][1]*nor[1]+imat[2][2]*nor[2];
812                                         Normalise(n1);
813                                         
814                                         if(lastmat!=mface->mat_nr) {
815                                                 ma= give_current_material(ob, mface->mat_nr+1);
816                                                 if(ma==0) ma= &defmaterial;
817                                                 lastmat= mface->mat_nr;
818                                         }
819                                         
820                                         mvert= me->mvert+mface->v1;
821                                         VECCOPY(vec, mvert->co);
822                                         Mat4MulVecfl(mat, vec);
823                                         
824                                         if(orco)  fastshade(vec, n1, orco+3*mface->v1, ma, (char *)col1, (char *)col2, (char *)vertcol);
825                                         else fastshade(vec, n1, mvert->co, ma, (char *)col1, (char *)col2, (char *)vertcol);
826                                         col1++;
827                                         if(vertcol) vertcol++; 
828                                         if(col2) col2++;
829                                         
830                                         mvert= me->mvert+mface->v2;
831                                         VECCOPY(vec, mvert->co);
832                                         Mat4MulVecfl(mat, vec);
833                                         
834                                         if(orco)  fastshade(vec, n1, orco+3*mface->v2, ma, (char *)col1, (char *)col2, (char *)vertcol);
835                                         else fastshade(vec, n1, mvert->co, ma, (char *)col1, (char *)col2, (char *)vertcol);
836                                         col1++;
837                                         if(vertcol) vertcol++; 
838                                         if(col2) col2++;
839                                         
840                                         mvert= me->mvert+mface->v3;
841                                         VECCOPY(vec, mvert->co);
842                                         Mat4MulVecfl(mat, vec);
843                                         
844                                         if(orco)  fastshade(vec, n1, orco+3*mface->v3, ma, (char *)col1, (char *)col2, (char *)vertcol);
845                                         else fastshade(vec, n1, mvert->co, ma, (char *)col1, (char *)col2, (char *)vertcol);
846                                         col1++;
847                                         if(vertcol) vertcol++; 
848                                         if(col2) col2++;
849                                         
850                                         if(mface->v4) {
851                                                 mvert= me->mvert+mface->v4;
852                                                 VECCOPY(vec, mvert->co);
853                                                 Mat4MulVecfl(mat, vec);
854                                                 
855                                                 if(orco)  fastshade(vec, n1, orco+3*mface->v4, ma, (char *)col1, (char *)col2, (char *)vertcol);
856                                                 else fastshade(vec, n1, mvert->co, ma, (char *)col1, (char *)col2, (char *)vertcol);
857                                         }
858                                         col1++;
859                                         if(vertcol) vertcol++; 
860                                         if(col2) col2++;
861                                                 
862                                 }
863                                 else {
864                                         col1+=4;
865                                         if(vertcol) vertcol+=4; 
866                                         if(col2) col2+=4;
867                                 }
868         
869                                 nor+= 3;
870                                 mface++;
871                         }
872                         
873                         if(me->orco) {
874                                 MEM_freeN(me->orco);
875                                 me->orco= 0;
876                         }
877                         if(me->tface) {
878                                 MEM_freeN(me->mcol);
879                                 me->mcol= 0;
880                         }
881                 }
882         }
883         else if ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT) {
884         
885                 /* nu hebben we wel de normalen nodig */
886                 cu= ob->data;
887                 dl= cu->disp.first;
888                 
889                 while(dl) {
890                         dlob= MEM_callocN(sizeof(DispList), "displistshade");
891                         BLI_addtail(&ob->disp, dlob);
892                         dlob->type= DL_VERTCOL;
893                         dlob->parts= dl->parts;
894                         dlob->nr= dl->nr;
895                         
896                         if(dl->type==DL_INDEX3) {
897                                 col1= dlob->col1= MEM_mallocN(sizeof(int)*dl->nr, "col1");
898                         }
899                         else {
900                                 col1= dlob->col1= MEM_mallocN(sizeof(int)*dl->parts*dl->nr, "col1");
901                         }
902                         
903                 
904                         ma= give_current_material(ob, dl->col+1);
905                         if(ma==0) ma= &defmaterial;
906
907                         if(dl->type==DL_INDEX3) {
908                                 if(dl->nors) {
909                                         /* er is maar 1 normaal */
910                                         n1[0]= imat[0][0]*dl->nors[0]+imat[0][1]*dl->nors[1]+imat[0][2]*dl->nors[2];
911                                         n1[1]= imat[1][0]*dl->nors[0]+imat[1][1]*dl->nors[1]+imat[1][2]*dl->nors[2];
912                                         n1[2]= imat[2][0]*dl->nors[0]+imat[2][1]*dl->nors[1]+imat[2][2]*dl->nors[2];
913                                         Normalise(n1);
914                                         
915                                         fp= dl->verts;
916                                         
917                                         a= dl->nr;              
918                                         while(a--) {
919                                                 VECCOPY(vec, fp);
920                                                 Mat4MulVecfl(mat, vec);
921                                                 
922                                                 fastshade(vec, n1, fp, ma, (char *)col1, 0, 0);
923                                                 
924                                                 fp+= 3; col1++;
925                                         }
926                                 }
927                         }
928                         else if(dl->type==DL_SURF) {
929                                 if(dl->nors) {
930                                         a= dl->nr*dl->parts;
931                                         fp= dl->verts;
932                                         nor= dl->nors;
933                                         
934                                         while(a--) {
935                                                 VECCOPY(vec, fp);
936                                                 Mat4MulVecfl(mat, vec);
937                                                 
938                                                 n1[0]= imat[0][0]*nor[0]+imat[0][1]*nor[1]+imat[0][2]*nor[2];
939                                                 n1[1]= imat[1][0]*nor[0]+imat[1][1]*nor[1]+imat[1][2]*nor[2];
940                                                 n1[2]= imat[2][0]*nor[0]+imat[2][1]*nor[1]+imat[2][2]*nor[2];
941                                                 Normalise(n1);
942                         
943                                                 fastshade(vec, n1, fp, ma, (char *)col1, 0, 0);
944                                                 
945                                                 fp+= 3; nor+= 3; col1++;
946                                         }
947                                 }
948                         }
949                         dl= dl->next;
950                 }
951         }
952         else if(ob->type==OB_MBALL) {
953                 /* normalen zijn er al */
954                 dl= ob->disp.first;
955                 
956                 while(dl) {
957                         
958                         if(dl->type==DL_INDEX4) {
959                                 if(dl->nors) {
960                                         
961                                         if(dl->col1) MEM_freeN(dl->col1);
962                                         col1= dl->col1= MEM_mallocN(sizeof(int)*dl->nr, "col1");
963                         
964                                         ma= give_current_material(ob, dl->col+1);
965                                         if(ma==0) ma= &defmaterial;
966         
967                                         fp= dl->verts;
968                                         nor= dl->nors;
969                                         
970                                         a= dl->nr;              
971                                         while(a--) {
972                                                 VECCOPY(vec, fp);
973                                                 Mat4MulVecfl(mat, vec);
974                                                 
975                                                 /* transpose ! */
976                                                 n1[0]= imat[0][0]*nor[0]+imat[0][1]*nor[1]+imat[0][2]*nor[2];
977                                                 n1[1]= imat[1][0]*nor[0]+imat[1][1]*nor[1]+imat[1][2]*nor[2];
978                                                 n1[2]= imat[2][0]*nor[0]+imat[2][1]*nor[1]+imat[2][2]*nor[2];
979                                                 Normalise(n1);
980                                         
981                                                 fastshade(vec, n1, fp, ma, (char *)col1, 0, 0);
982                                                 
983                                                 fp+= 3; col1++; nor+= 3;
984                                         }
985                                 }
986                         }
987                         dl= dl->next;
988                 }
989         }
990         
991         if((R.flag & R_RENDERING)==0) {
992                 for(a=0; a<ob->totcol; a++) {
993                         ma= give_current_material(ob, a+1);
994                         if(ma) end_render_material(ma);
995                 }
996         }
997
998         /* deze was er tijdelijk uitgehaald */
999         if(dldeform) BLI_addtail(&ob->disp, dldeform);
1000 }
1001
1002 void reshadeall_displist(void)
1003 {
1004         DispList *dldeform;
1005         Base *base;
1006         Object *ob;
1007         
1008         freefastshade();
1009         
1010         base= G.scene->base.first;
1011         while(base) {
1012                 if(base->lay & G.scene->lay) {
1013                         
1014                         ob= base->object;
1015                         
1016                         /* we halen de dl_verts eruit, deform info */
1017                         dldeform= find_displist(&ob->disp, DL_VERTS);
1018                         if(dldeform) BLI_remlink(&ob->disp, dldeform);
1019                         
1020                         /* Metaballs hebben de standaard displist aan het Object zitten */
1021                         if(ob->type==OB_MBALL) shadeDispList(ob);
1022                         else freedisplist(&ob->disp);
1023                         
1024                         if(dldeform) BLI_addtail(&ob->disp, dldeform);
1025                 }
1026                 base= base->next;
1027         }
1028 }
1029
1030 void count_displist(ListBase *lb, int *totvert, int *totface)
1031 {
1032         DispList *dl;
1033         
1034         dl= lb->first;
1035         while(dl) {
1036                 
1037                 switch(dl->type) {
1038                 case DL_SURF:
1039                         *totvert+= dl->nr*dl->parts;
1040                         *totface+= (dl->nr-1)*(dl->parts-1);
1041                         break;
1042                 case DL_INDEX3:
1043                 case DL_INDEX4:
1044                         *totvert+= dl->nr;
1045                         *totface+= dl->parts;
1046                         break;
1047                 case DL_POLY:
1048                 case DL_SEGM:
1049                         *totvert+= dl->nr*dl->parts;
1050                 }
1051                 
1052                 dl= dl->next;
1053         }
1054 }
1055
1056 static void curve_to_displist(ListBase *nubase, ListBase *dispbase)
1057 {
1058         Nurb *nu;
1059         DispList *dl;
1060         BezTriple *bezt, *prevbezt;
1061         BPoint *bp;
1062         float *data, *v1, *v2;
1063         int a, len;
1064         
1065         nu= nubase->first;
1066         
1067         while(nu) {
1068                 if(nu->hide==0) {
1069                         if((nu->type & 7)==CU_BEZIER) {
1070                                 
1071                                 /* tellen */
1072                                 len= 0;
1073                                 a= nu->pntsu-1;
1074                                 if(nu->flagu & 1) a++;
1075
1076                                 prevbezt= nu->bezt;
1077                                 bezt= prevbezt+1;
1078                                 while(a--) {
1079                                         if(a==0 && (nu->flagu & 1)) bezt= nu->bezt;
1080                                         
1081                                         if(prevbezt->h2==HD_VECT && bezt->h1==HD_VECT) len++;
1082                                         else len+= nu->resolu;
1083                                         
1084                                         if(a==0 && (nu->flagu & 1)==0) len++;
1085                                         
1086                                         prevbezt= bezt;
1087                                         bezt++;
1088                                 }
1089                                 
1090                                 dl= MEM_callocN(sizeof(DispList), "makeDispListbez");
1091                                 /* len+1 i.v.m. maakbez */
1092                                 dl->verts= MEM_callocN( (len+1)*3*sizeof(float), "dlverts");
1093                                 BLI_addtail(dispbase, dl);
1094                                 dl->parts= 1;
1095                                 dl->nr= len;
1096                                 dl->col= nu->mat_nr;
1097
1098                                 data= dl->verts;
1099
1100                                 if(nu->flagu & 1) {
1101                                         dl->type= DL_POLY;
1102                                         a= nu->pntsu;
1103                                 }
1104                                 else {
1105                                         dl->type= DL_SEGM;
1106                                         a= nu->pntsu-1;
1107                                 }
1108                                 
1109                                 prevbezt= nu->bezt;
1110                                 bezt= prevbezt+1;
1111                                 
1112                                 while(a--) {
1113                                         if(a==0 && dl->type== DL_POLY) bezt= nu->bezt;
1114                                         
1115                                         if(prevbezt->h2==HD_VECT && bezt->h1==HD_VECT) {
1116                                                 VECCOPY(data, prevbezt->vec[1]);
1117                                                 data+= 3;
1118                                         }
1119                                         else {
1120                                                 v1= prevbezt->vec[1];
1121                                                 v2= bezt->vec[0];
1122                                                 maakbez(v1[0], v1[3], v2[0], v2[3], data, nu->resolu);
1123                                                 maakbez(v1[1], v1[4], v2[1], v2[4], data+1, nu->resolu);
1124                                                 if((nu->type & 8)==0)
1125                                                         maakbez(v1[2], v1[5], v2[2], v2[5], data+2, nu->resolu);
1126                                                 data+= 3*nu->resolu;
1127                                         }
1128                                         
1129                                         if(a==0 && dl->type==DL_SEGM) {
1130                                                 VECCOPY(data, bezt->vec[1]);
1131                                         }
1132                                         
1133                                         prevbezt= bezt;
1134                                         bezt++;
1135                                 }
1136                         }
1137                         else if((nu->type & 7)==CU_NURBS) {
1138                                 len= nu->pntsu*nu->resolu;
1139                                 dl= MEM_callocN(sizeof(DispList), "makeDispListsurf");
1140                                 dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
1141                                 BLI_addtail(dispbase, dl);
1142                                 dl->parts= 1;
1143                                 dl->nr= len;
1144                                 dl->col= nu->mat_nr;
1145
1146                                 data= dl->verts;
1147                                 if(nu->flagu & 1) dl->type= DL_POLY;
1148                                 else dl->type= DL_SEGM;
1149                                 makeNurbcurve(nu, data, 3);
1150                         }
1151                         else if((nu->type & 7)==CU_POLY) {
1152                                 len= nu->pntsu;
1153                                 dl= MEM_callocN(sizeof(DispList), "makeDispListpoly");
1154                                 dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
1155                                 BLI_addtail(dispbase, dl);
1156                                 dl->parts= 1;
1157                                 dl->nr= len;
1158                                 dl->col= nu->mat_nr;
1159
1160                                 data= dl->verts;
1161                                 if(nu->flagu & 1) dl->type= DL_POLY;
1162                                 else dl->type= DL_SEGM;
1163                                 
1164                                 a= len;
1165                                 bp= nu->bp;
1166                                 while(a--) {
1167                                         VECCOPY(data, bp->vec);
1168                                         bp++;
1169                                         data+= 3;
1170                                 }
1171                         }
1172                 }
1173                 nu= nu->next;
1174         }
1175 }
1176
1177
1178 static void filldisplist(ListBase *dispbase, ListBase *to)
1179 {
1180         EditVert *eve, *v1, *vlast;
1181         EditVlak *evl;
1182         DispList *dlnew=0, *dl;
1183         float *f1;
1184         int colnr=0, cont=1, tot, a, *index;
1185         long totvert;
1186         
1187         if(dispbase==0) return;
1188         if(dispbase->first==0) return;
1189
1190         /* tijd= clock(); */
1191         /* bit-wise and comes after == .... so this doesn't work...  */
1192 /*      if(G.f & G_PLAYANIM == 0) waitcursor(1); */
1193         if( !(G.f & G_PLAYANIM) ) waitcursor(1);
1194
1195         while(cont) {
1196                 cont= 0;
1197                 totvert=0;
1198                 
1199                 dl= dispbase->first;
1200                 while(dl) {
1201         
1202                         if(dl->type==DL_POLY) {
1203                                 if(colnr<dl->col) cont= 1;
1204                                 else if(colnr==dl->col) {
1205                         
1206                                         colnr= dl->col;
1207                 
1208                                         /* editverts en edges maken */
1209                                         f1= dl->verts;
1210                                         a= dl->nr;
1211                                         eve= v1= 0;
1212                                         
1213                                         while(a--) {
1214                                                 vlast= eve;
1215                                                 
1216                                                 eve= BLI_addfillvert(f1);
1217                                                 totvert++;
1218                                                 
1219                                                 if(vlast==0) v1= eve;
1220                                                 else {
1221                                                         BLI_addfilledge(vlast, eve);
1222                                                 }
1223                                                 f1+=3;
1224                                         }
1225                                 
1226                                         if(eve!=0 && v1!=0) {
1227                                                 BLI_addfilledge(eve, v1);
1228                                         }
1229                                 }
1230                         }
1231                         dl= dl->next;
1232                 }
1233                 
1234                 /* to make edgefill work 
1235                 G.obedit can be 0 on file load */
1236                 if (G.obedit) {
1237                         BLI_setScanFillObjectRef(G.obedit);
1238                         BLI_setScanFillColourRef(&G.obedit->actcol);
1239                 }
1240
1241                 if(totvert && BLI_edgefill(0)!=0) {
1242
1243                         /* vlakken tellen */
1244                         tot= 0;
1245                         evl= fillvlakbase.first;
1246                         while(evl) {
1247                                 tot++;
1248                                 evl= evl->next;
1249                         }
1250
1251                         if(tot) {
1252                                 dlnew= MEM_callocN(sizeof(DispList), "filldisplist");
1253                                 dlnew->type= DL_INDEX3;
1254                                 dlnew->col= colnr;
1255                                 dlnew->nr= totvert;
1256                                 dlnew->parts= tot;
1257
1258                                 dlnew->index= MEM_mallocN(tot*3*sizeof(int), "dlindex");
1259                                 dlnew->verts= MEM_mallocN(totvert*3*sizeof(float), "dlverts");
1260                                 
1261                                 /* vertdata */
1262                                 f1= dlnew->verts;
1263                                 totvert= 0;
1264                                 eve= fillvertbase.first;
1265                                 while(eve) {
1266                                         VECCOPY(f1, eve->co);
1267                                         f1+= 3;
1268         
1269                                         /* indexnummer */
1270                                         eve->vn= (EditVert *)totvert;
1271                                         totvert++;
1272                                         
1273                                         eve= eve->next;
1274                                 }
1275                                 
1276                                 /* indexdata */
1277                                 evl= fillvlakbase.first;
1278                                 index= dlnew->index;
1279                                 while(evl) {
1280                                         index[0]= (long)evl->v1->vn;
1281                                         index[1]= (long)evl->v2->vn;
1282                                         index[2]= (long)evl->v3->vn;
1283                                         
1284                                         index+= 3;
1285                                         evl= evl->next;
1286                                 }
1287                         }
1288
1289                         BLI_addhead(to, dlnew);
1290                         
1291                 }
1292                 BLI_end_edgefill();
1293
1294                 colnr++;
1295         }
1296         
1297         /* poly's niet vrijgeven. nodig voor wireframe display */
1298         
1299         /* same as above ... */
1300 /*      if(G.f & G_PLAYANIM == 0) waitcursor(0); */
1301         if( !(G.f & G_PLAYANIM) ) waitcursor(0);
1302         /* printf("time: %d\n",(clock()-tijd)/1000); */
1303
1304 }
1305
1306 static void bevels_to_filledpoly(Curve *cu, ListBase *dispbase)
1307 {
1308         ListBase front, back;
1309         DispList *dl, *dlnew;
1310         float *fp, *fp1;
1311         int a, dpoly;
1312         
1313         front.first= front.last= back.first= back.last= 0;
1314         
1315         if(cu->flag & CU_3D) return;
1316         if( (cu->flag & (CU_FRONT+CU_BACK))==0 ) return;
1317         
1318         dl= dispbase->first;
1319         while(dl) {
1320                 if(dl->type==DL_SURF) {
1321                         if(dl->flag==2) {
1322                                 if(cu->flag & CU_BACK) {
1323                                         dlnew= MEM_callocN(sizeof(DispList), "filldisp");
1324                                         BLI_addtail(&front, dlnew);
1325                                         dlnew->verts= fp1= MEM_mallocN(sizeof(float)*3*dl->parts, "filldisp1");
1326                                         dlnew->nr= dl->parts;
1327                                         dlnew->parts= 1;
1328                                         dlnew->type= DL_POLY;
1329                                         dlnew->col= dl->col;
1330                                         
1331                                         fp= dl->verts;
1332                                         dpoly= 3*dl->nr;
1333                                         
1334                                         a= dl->parts;
1335                                         while(a--) {
1336                                                 VECCOPY(fp1, fp);
1337                                                 fp1+= 3;
1338                                                 fp+= dpoly;
1339                                         }
1340                                 }
1341                                 if(cu->flag & CU_FRONT) {
1342                                         dlnew= MEM_callocN(sizeof(DispList), "filldisp");
1343                                         BLI_addtail(&back, dlnew);
1344                                         dlnew->verts= fp1= MEM_mallocN(sizeof(float)*3*dl->parts, "filldisp1");
1345                                         dlnew->nr= dl->parts;
1346                                         dlnew->parts= 1;
1347                                         dlnew->type= DL_POLY;
1348                                         dlnew->col= dl->col;
1349                                         
1350                                         fp= dl->verts+3*(dl->nr-1);
1351                                         dpoly= 3*dl->nr;
1352                                         
1353                                         a= dl->parts;
1354                                         while(a--) {
1355                                                 VECCOPY(fp1, fp);
1356                                                 fp1+= 3;
1357                                                 fp+= dpoly;
1358                                         }
1359                                 }
1360                         }
1361                 }
1362                 dl= dl->next;
1363         }
1364
1365         filldisplist(&front, dispbase);
1366         filldisplist(&back, dispbase);
1367         
1368         freedisplist(&front);
1369         freedisplist(&back);
1370
1371         filldisplist(dispbase, dispbase);
1372         
1373 }
1374
1375 void curve_to_filledpoly(Curve *cu, ListBase *dispbase)
1376 {
1377         DispList *dl;
1378         Nurb *nu;
1379                 
1380         dl= dispbase->first;
1381         
1382         if(cu->flag & CU_3D) return;
1383         
1384         nu= cu->nurb.first;
1385         while(nu) {
1386                 if(nu->flagu & CU_CYCLIC) break;
1387                 nu= nu->next;
1388         }
1389         if(nu==0) return;
1390
1391         if(dl->type==DL_SURF) bevels_to_filledpoly(cu, dispbase);
1392         else {
1393                 if(cu->flag & CU_FRONT) filldisplist(dispbase, dispbase);
1394         }
1395 }
1396
1397
1398 static int dl_onlyzero= 0;
1399
1400 void set_displist_onlyzero(int val)
1401 {
1402         dl_onlyzero= val;
1403 }
1404
1405 void makeDispList(Object *ob)
1406 {
1407         Mesh *me;
1408         Nurb *nu;
1409         Curve *cu;
1410         BPoint *bp;
1411         ListBase dlbev, *dispbase;
1412         DispList *dl, *dlb;
1413         BevList *bl;
1414         BevPoint *bevp;
1415         float *data, *fp1, widfac, vec[3];
1416         int len, a, b, draw=0;
1417
1418         if(ob==0) return;
1419         if(ob->flag & OB_FROMDUPLI) return;
1420         freedisplist(&(ob->disp));
1421
1422         if(ob->type==OB_MESH) {
1423                 me= ob->data;
1424
1425                 freedisplist(&(me->disp));
1426
1427                 tex_space_mesh(ob->data);
1428
1429                 object_deform(ob);      
1430
1431                 if(ob->effect.first) object_wave(ob);
1432                 
1433                 if ((me->flag & ME_SUBSURF) && me->subdiv>0) {
1434                         if (ob==G.obedit)
1435                                 subsurf_make_editmesh(ob);
1436                         else
1437                                 subsurf_make_mesh(ob, me->subdiv);
1438                 }
1439         }
1440         else if(ob->type==OB_MBALL) {
1441                 ob= find_basis_mball(ob);
1442                 
1443                 metaball_polygonize(ob);
1444                 tex_space_mball(ob);
1445         }
1446         else if(ob->type==OB_SURF) {
1447                 
1448                 draw= ob->dt;
1449                 cu= ob->data;
1450                 dispbase= &(cu->disp);
1451                 if(dl_onlyzero && dispbase->first) return;
1452                 freedisplist(dispbase);
1453                 
1454                 if(ob==G.obedit) nu= editNurb.first;
1455                 else nu= cu->nurb.first;
1456
1457                 while(nu) {
1458                         if(nu->hide==0) {
1459                                 if(nu->pntsv==1) {
1460                                         if(draw==0) len= nu->pntsu;
1461                                         else len= nu->pntsu*nu->resolu;
1462                                         
1463                                         dl= MEM_callocN(sizeof(DispList), "makeDispListsurf");
1464                                         dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
1465                                         
1466                                         BLI_addtail(dispbase, dl);
1467                                         dl->parts= 1;
1468                                         dl->nr= len;
1469                                         dl->col= nu->mat_nr;
1470
1471                                         data= dl->verts;
1472                                         if(nu->flagu & 1) dl->type= DL_POLY;
1473                                         else dl->type= DL_SEGM;
1474                                         
1475                                         if(draw==0) {
1476                                                 bp= nu->bp;
1477                                                 while(len--) {
1478                                                         VECCOPY(data, bp->vec);
1479                                                         bp++;
1480                                                         data+= 3;
1481                                                 }
1482                                         }
1483                                         else makeNurbcurve(nu, data, 3);
1484                                 }
1485                                 else {
1486                                         if(draw==0 && ob==G.obedit) ;
1487                                         else {
1488                                                 if(draw==0) len= nu->pntsu*nu->pntsv;
1489                                                 else len= nu->resolu*nu->resolv;
1490                                                 
1491                                                 dl= MEM_callocN(sizeof(DispList), "makeDispListsurf");
1492                                                 dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
1493                                                 BLI_addtail(dispbase, dl);
1494         
1495                                                 if(draw==0) {
1496                                                         dl->parts= nu->pntsv;
1497                                                         dl->nr= nu->pntsu;
1498                                                         if(nu->flagu & 1) dl->flag|= 1;
1499                                                         if(nu->flagv & 1) dl->flag|= 2;
1500                                                 }
1501                                                 else {
1502                                                         dl->parts= nu->resolu;  /* andersom want makeNurbfaces gaat zo */
1503                                                         dl->nr= nu->resolv;
1504                                                         if(nu->flagv & 1) dl->flag|= 1; /* ook andersom ! */
1505                                                         if(nu->flagu & 1) dl->flag|= 2;
1506                                                 }
1507                                                 dl->col= nu->mat_nr;
1508         
1509                                                 data= dl->verts;
1510                                                 dl->type= DL_SURF;
1511                                                 
1512                                                 if(draw==0) {
1513                                                         bp= nu->bp;
1514                                                         while(len--) {
1515                                                                 VECCOPY(data, bp->vec);
1516                                                                 bp++;
1517                                                                 data+= 3;
1518                                                         }
1519                                                 }
1520                                                 else makeNurbfaces(nu, data);
1521                                         }
1522                                 }
1523                         }
1524                         nu= nu->next;
1525                 }
1526                 
1527                 tex_space_curve(cu);
1528                 
1529                 if(ob!=G.obedit) object_deform(ob);
1530         }
1531         else if ELEM(ob->type, OB_CURVE, OB_FONT) {
1532                 
1533                 draw= ob->dt;
1534                 cu= ob->data;
1535                 dispbase= &(cu->disp);
1536                 if(dl_onlyzero && dispbase->first) return;
1537                 freedisplist(dispbase);
1538                 
1539                 if(cu->path) free_path(cu->path);
1540                 cu->path= 0;
1541                 
1542                 BLI_freelistN(&(cu->bev));
1543                 
1544                 if(ob==G.obedit) {
1545                         if(ob->type==OB_CURVE) curve_to_displist(&editNurb, dispbase);
1546                         else curve_to_displist(&cu->nurb, dispbase);
1547                         if(cu->flag & CU_PATH) makeBevelList(ob);
1548                 }
1549                 else if(cu->ext1==0.0 && cu->ext2==0.0 && cu->bevobj==0 && cu->width==1.0) {
1550                         curve_to_displist(&cu->nurb, dispbase);
1551                         if(cu->flag & CU_PATH) makeBevelList(ob);
1552                 }
1553                 else {
1554                         
1555                         makeBevelList(ob);
1556
1557                         dlbev.first= dlbev.last= 0;
1558                         if(cu->ext1!=0.0 || cu->ext2!=0.0 || cu->bevobj) {
1559                                 if(ob->dt!=0) makebevelcurve(ob, &dlbev);
1560                         }
1561
1562                         /* met bevellist werken */
1563                         widfac= cu->width-1.0;
1564                         bl= cu->bev.first;
1565                         nu= cu->nurb.first;
1566                         while(bl) {
1567                                 if(dlbev.first==0) {
1568                                         dl= MEM_callocN(sizeof(DispList), "makeDispListbev");
1569                                         dl->verts= MEM_callocN(3*sizeof(float)*bl->nr, "dlverts");
1570                                         BLI_addtail(dispbase, dl);
1571                                         if(bl->poly!= -1) dl->type= DL_POLY;
1572                                         else dl->type= DL_SEGM;
1573                                         dl->parts= 1;
1574                                         dl->nr= bl->nr;
1575                                         dl->col= nu->mat_nr;
1576
1577                                         a= dl->nr;
1578                                         bevp= (BevPoint *)(bl+1);
1579                                         data= dl->verts;
1580                                         while(a--) {
1581                                                 data[0]= bevp->x+widfac*bevp->sina;
1582                                                 data[1]= bevp->y+widfac*bevp->cosa;
1583                                                 data[2]= bevp->z;
1584                                                 bevp++;
1585                                                 data+=3;
1586                                         }
1587                                 }
1588                                 else {
1589                                         /* voor iedere stuk van de bevel een aparte dispblok maken */
1590                                         dlb= dlbev.first;
1591                                         while(dlb) {
1592                                                 dl= MEM_callocN(sizeof(DispList), "makeDispListbev1");
1593                                                 dl->verts= MEM_callocN(3*sizeof(float)*dlb->nr*bl->nr, "dlverts");
1594                                                 BLI_addtail(dispbase, dl);
1595                                                 /* dl->type= dlb->type; */
1596
1597                                                 dl->type= DL_SURF;
1598                                                 dl->flag= 0;
1599                                                 if(dlb->type==DL_POLY) dl->flag++;
1600                                                 if(bl->poly>=0) dl->flag+=2;
1601
1602                                                 dl->parts= bl->nr;
1603                                                 dl->nr= dlb->nr;
1604                                                 dl->col= nu->mat_nr;
1605
1606                                                 data= dl->verts;
1607                                                 bevp= (BevPoint *)(bl+1);
1608                                                 a= bl->nr;
1609                                                 while(a--) {    /* voor ieder punt van poly een bevelstuk maken */
1610
1611                                                         /* roteer bevelstuk en schrijf in data */
1612                                                         fp1= dlb->verts;
1613                                                         b= dlb->nr;
1614
1615                                                         while(b--) {
1616                                                                 if(cu->flag & CU_3D) {
1617                                                                 
1618                                                                         vec[0]= fp1[1]+widfac;
1619                                                                         vec[1]= fp1[2];
1620                                                                         vec[2]= 0.0;
1621                                                                         
1622                                                                         Mat3MulVecfl(bevp->mat, vec);
1623                                                                         
1624                                                                         data[0]= bevp->x+ vec[0];
1625                                                                         data[1]= bevp->y+ vec[1];
1626                                                                         data[2]= bevp->z+ vec[2];
1627                                                                 }
1628                                                                 else {
1629                                                                         data[0]= bevp->x+ (fp1[1]+widfac)*bevp->sina;
1630                                                                         data[1]= bevp->y+ (fp1[1]+widfac)*bevp->cosa;
1631                                                                         data[2]= bevp->z+ fp1[2];
1632                                                                 }
1633
1634                                                                 data+=3;
1635                                                                 fp1+=3;
1636                                                         }
1637
1638                                                         bevp++;
1639                                                 }
1640
1641                                                 dlb= dlb->next;
1642                                         }
1643                                 }
1644
1645                                 bl= bl->next;
1646                                 nu= nu->next;
1647                         }
1648
1649                         if(cu->ext1!=0.0 || cu->ext2!=0.0 || cu->bevobj) {
1650                                 freedisplist(&dlbev);
1651                         }
1652                 }
1653
1654                 if(ob!=G.obedit) object_deform(ob);
1655
1656                 tex_space_curve(cu);
1657
1658         }
1659 }
1660
1661
1662 /*******************************/
1663 /*****       OUTLINE       *****/
1664 /*******************************/
1665
1666 typedef struct Sample{
1667         short x, y;
1668 } Sample;
1669
1670 typedef struct Segment{
1671         /* coordinaten */
1672         struct Segment * next, * prev;
1673         float co[2];
1674 } Segment;
1675
1676
1677
1678 static int dflt_in_out(struct ImBuf * ibuf, int x, int y)
1679 {
1680         unsigned char * rect;
1681         
1682         if (ibuf == 0) return (0);
1683         if (x < 0 || y < 0 || x >= ibuf->x || y >= ibuf->y || ibuf->rect == 0) return (-1);
1684         
1685         rect = (unsigned char *) (ibuf->rect + (y * ibuf->x) + x);
1686         if (rect[0] > 0x81) return (1);
1687         return(0);
1688 }
1689
1690
1691 static Sample * outline(struct ImBuf * ibuf,
1692                                  int (*in_or_out)(struct ImBuf *, int, int))
1693 {
1694         static int dirs[8][2] = {
1695                 {-1,  0}, {-1,  1},     {0,  1}, {1,  1}, 
1696                 {1,  0}, {1, -1}, {0, -1}, {-1, -1}
1697         };
1698         
1699         int dir, x, y, in, i;
1700         int count, sampcount;
1701         int startx = 0, starty = 0;
1702         Sample * samp, * oldsamp;
1703         
1704         /* wat erin gaat:
1705          * 1 - plaatje waarvan outline berekent moet worden, 
1706          * 2 - pointer naar functie die bepaalt welke pixel in of uit is
1707          */
1708         
1709         if (ibuf == 0) return (0);
1710         if (ibuf->rect == 0) return (0);
1711         
1712         if (in_or_out == 0) in_or_out = dflt_in_out;
1713         in = in_or_out(ibuf, 0, 0);
1714         
1715         /* zoek naar eerste overgang en ga van daar uit 'zoeken' */     
1716         for (y = 0; y < ibuf->y; y++) {
1717                 for (x = 0; x < ibuf->x; x++) {
1718                         if (in_or_out(ibuf, x, y) != in) {
1719                                 /* eerste 'andere' punt gevonden !! */
1720                                 
1721                                 if (x != startx) dir = 0;
1722                                 else dir = 6;
1723                                 
1724                                 startx = x; starty = y;
1725                                 count = 1;
1726                                 sampcount = 2000;
1727                                 samp = MEM_mallocN(sampcount * sizeof(Sample), "wire_samples");
1728                                 
1729                                 do{
1730                                         samp[count].x = x; samp[count].y = y;
1731                                         count++;
1732                                         
1733                                         if (count >= sampcount) {
1734                                                 oldsamp = samp;
1735                                                 samp = MEM_mallocN(2 * sampcount * sizeof(Sample), "wire_samples");
1736                                                 memcpy(samp, oldsamp, sampcount * sizeof(Sample));
1737                                                 sampcount *= 2;
1738                                                 MEM_freeN(oldsamp);
1739                                         }
1740                                         
1741                                         i = 0;
1742                                         while(in_or_out(ibuf, x + dirs[dir][0], y + dirs[dir][1]) == in) {
1743                                                 dir = (dir + 1) & 0x7;
1744                                                 if (i++ == 9) break;
1745                                         }
1746                                         
1747                                         if (i >= 8) {
1748                                                 /* dit moet een losse punt geweest zijn */
1749                                                 break;
1750                                         }
1751                                         
1752                                         x += dirs[dir][0];
1753                                         y += dirs[dir][1];
1754                                         dir = (dir - 3) & 0x7;
1755                                 } while(x != startx || y != starty);
1756                                 
1757                                 if (i >= 8) {
1758                                         /* losse punten patch */
1759                                         MEM_freeN(samp);
1760                                 } else {
1761                                         count = count - 1;
1762                                         samp[0].x = count >> 16;
1763                                         samp[0].y = count;
1764                                         return(samp);
1765                                 }
1766                         }
1767                 }
1768         }
1769         /* printf("geen overgang \n"); */
1770         return(0);
1771 }
1772
1773
1774
1775 /*******************************/
1776 /*****      WIREFRAME      *****/
1777 /*******************************/
1778
1779
1780 static float DistToLine2D(short *v1, short *v2, short *v3)   /* met formule van Hesse :GEEN LIJNSTUK! */
1781 {
1782         float a[2],deler;
1783
1784         a[0] = v2[1]-v3[1];
1785         a[1] = v3[0]-v2[0];
1786         deler = sqrt(a[0]*a[0]+a[1]*a[1]);
1787         if(deler == 0.0) return 0;
1788
1789         return fabs((v1[0]-v2[0])*a[0]+(v1[1]-v2[1])*a[1])/deler;
1790
1791 }
1792
1793 static float ComputeMaxShpError(Sample *samp, int first, int last, int *splitPoint)
1794     /* samp:  Array of digitized points */
1795     /* first, last:  Indices defining region    */
1796     /* splitpoint:  Point of maximum error      */
1797 {
1798     int         i;
1799     float       maxDist;                                /*  Maximum error               */
1800     float       dist;                                   /*  Current error               */
1801  
1802     *splitPoint = (last - first + 1) / 2;
1803     maxDist = 0.0;
1804         
1805     for (i = first + 1; i < last; i++) {                                
1806                 dist = DistToLine2D((short *)(samp+i), (short *)(samp+first), (short *)(samp+last));
1807
1808                 if (dist >= maxDist) {
1809                 maxDist = dist;
1810                 *splitPoint = i;
1811                 }
1812     }
1813
1814     return (maxDist);
1815 }
1816
1817
1818 static void FitPoly(Sample *samp, int first, int last, float shperr, ListBase *seglist)
1819     /* Samp: Array of digitized points */
1820     /* first,last: Indices of first and last pts in region */
1821     /* spherr: User-defined error squared          */
1822 {
1823     Segment     * seg;                          /* Control points segment*/
1824     float       maxError;                       /*  Maximum fitting error        */
1825     int         splitPoint;                     /*  Point to split point set at  */
1826     int         nPts;                           /*  Number of points in subset  */
1827         
1828     nPts = last - first + 1;
1829
1830     /*  Use heuristic if region only has two points in it */
1831
1832         seg = MEM_mallocN(sizeof(Segment), "wure_segment");
1833
1834         seg->co[0] = samp[first].x;
1835         seg->co[1] = samp[first].y;
1836         
1837     if (nPts == 2) {
1838                 BLI_addtail(seglist, seg);
1839                 return;
1840     }
1841
1842         maxError = ComputeMaxShpError(samp, first, last, &splitPoint);
1843         if (maxError < shperr) {
1844                 BLI_addtail(seglist, seg);
1845                 return;
1846         }
1847         
1848     /* Fitting failed -- split at max error point and fit recursively */
1849         
1850     FitPoly(samp, first, splitPoint, shperr, seglist);
1851     FitPoly(samp, splitPoint, last, shperr, seglist);
1852         
1853         MEM_freeN(seg);
1854 }
1855
1856
1857 static void ibuf2wire(ListBase * wireframe, struct ImBuf * ibuf)
1858 {
1859         int count;
1860         Sample * samp;
1861         
1862         /* eerst een lijst met samples maken */
1863         
1864         samp = outline(ibuf, 0);
1865         if (samp == 0) return;
1866         
1867         count = (samp[0].x << 16) + samp[0].y;
1868         if (count) FitPoly(samp, 1, count, 1.0, wireframe); /* was 3.0. Frank */
1869
1870         MEM_freeN(samp);
1871 }
1872
1873
1874
1875 void imagestodisplist(void)
1876 {
1877         Base *base;
1878         Object *ob;
1879         Material *ma;
1880         Tex *tex;
1881         Mesh *me;
1882         ListBase _wireframe, *wireframe;
1883         DispList *dl;
1884         Segment *seg;
1885         float *data, xfac, yfac, xsi, ysi, vec[3];
1886         int tot;
1887         
1888         _wireframe.first= 0;
1889         _wireframe.last= 0;
1890         wireframe = &_wireframe;
1891         
1892         init_render_textures();
1893         
1894         base= G.scene->base.first;
1895         while(base) {
1896                 if(( (base->flag & SELECT) && (base->lay & G.scene->lay) ) ) {
1897                         if( base->object->type==OB_MESH) {
1898                                 ob= base->object;
1899                                 me= ob->data;
1900                                 
1901                                 ma= give_current_material(ob, 1);
1902         
1903                                 if(ma && ma->mtex[0] && ma->mtex[0]->tex) {
1904                                         tex= ma->mtex[0]->tex;
1905                                         
1906                                         /* dit zorgt voor correct laden van nieuwe imbufs */
1907                                         externtex(ma->mtex[0], vec);
1908                                         
1909                                         if(tex->type==TEX_IMAGE && tex->ima && tex->ima->ibuf) {                                
1910                                                 
1911                                                 ob->dtx |= OB_DRAWIMAGE;
1912                                                 
1913                                                 ibuf2wire(wireframe, tex->ima->ibuf);
1914
1915                                                 tot= 0;
1916                                                 seg = wireframe->first;
1917                                                 while (seg) {
1918                                                         tot++;
1919                                                         seg = seg->next;
1920                                                 }
1921         
1922                                                 if(tot) {
1923                                                         freedisplist(&(ob->disp));
1924
1925                                                         dl= MEM_callocN(sizeof(DispList), "makeDispListimage");
1926                                                         dl->verts= MEM_callocN(3*sizeof(float)*tot, "dlverts");
1927                                                         
1928                                                         BLI_addtail(&(ob->disp), dl);
1929                                                         dl->type= DL_POLY;
1930                                                         dl->parts= 1;
1931                                                         dl->nr= tot;
1932                                                         
1933                                                         xsi= 0.5*(tex->ima->ibuf->x);
1934                                                         ysi= 0.5*(tex->ima->ibuf->y);
1935                                                         xfac= me->size[0]/xsi;
1936                                                         yfac= me->size[1]/ysi;
1937                                                                                                 
1938                                                         data= dl->verts;
1939                                                         seg = wireframe->first;
1940                                                         while (seg) {
1941                                                                 data[0]= xfac*(seg->co[0]-xsi);
1942                                                                 data[1]= yfac*(seg->co[1]-ysi);
1943                                                                 data+= 3;
1944                                                                 seg = seg->next;
1945                                                         }
1946                                                         BLI_freelistN(wireframe);
1947                                                 }
1948                                         }
1949                                 }
1950                         }
1951                 }
1952                 base= base->next;
1953         }
1954         
1955         end_render_textures();
1956         
1957         allqueue(REDRAWVIEW3D, 0);
1958 }
1959
1960 /* on frame change */
1961
1962 void test_all_displists(void)
1963 {
1964         Base *base;
1965         Object *ob;
1966         unsigned int lay;
1967         
1968         /* background */        
1969         lay= G.scene->lay;
1970         
1971         base= G.scene->base.first;
1972         while(base) {
1973                 if(base->lay & lay) {
1974                         ob= base->object;
1975                         
1976
1977                         if(ob->type==OB_MBALL && ob->ipo) {
1978                                 // find metaball object holding the displist
1979                                 // WARNING: if more metaballs have IPO's the displist
1980                                 // is recalculated to often...
1981
1982                                 if(ob->disp.first == NULL) {
1983                                         ob= find_basis_mball(ob);
1984                                 }
1985
1986                                 makeDispList(ob);
1987                         }
1988                         else if(ob->parent) {
1989
1990                                 if (ob->parent->type == OB_LATTICE)
1991                                         makeDispList(ob);
1992                                 else if ((ob->parent->type == OB_IKA) && (ob->partype == PARSKEL))
1993                                         makeDispList(ob);
1994 #ifdef __NLA
1995                                 else if ((ob->parent->type==OB_ARMATURE) && (ob->partype == PARSKEL))
1996                                         makeDispList(ob);
1997                                 
1998 #endif
1999                         }
2000
2001                         if ELEM(ob->type, OB_CURVE, OB_SURF) {
2002                                 if(ob!=G.obedit) {
2003                                         if( ((Curve *)(ob->data))->key ) makeDispList(ob);
2004                                 }
2005                         }
2006                         else if(ob->type==OB_FONT) {
2007                                 Curve *cu= ob->data;
2008                                 if(cu->textoncurve) {
2009                                         if( ((Curve *)cu->textoncurve->data)->key ) {
2010                                                 text_to_curve(ob, 0);
2011                                                 makeDispList(ob);
2012                                         }
2013                                 }
2014                         }
2015                         else if(ob->type==OB_MESH) {
2016                                 if(ob->effect.first) object_wave(ob);
2017                                 if(ob!=G.obedit) {
2018                                         if( ((Mesh *)(ob->data))->key ) makeDispList(ob);
2019                                 }
2020                         }
2021
2022                 }
2023                 if(base->next==0 && G.scene->set && base==G.scene->base.last) base= G.scene->set->base.first;
2024                 else base= base->next;
2025         }
2026 }
2027
2028
2029 void boundbox_displist(Object *ob)
2030 {
2031         BoundBox *bb=0;
2032         float min[3], max[3];
2033         DispList *dl;
2034         float *vert;
2035         int a, tot=0;
2036         
2037         INIT_MINMAX(min, max);
2038
2039         if(ob->type==OB_MESH) {
2040                 Mesh *me= ob->data;
2041
2042                 dl= find_displist(&ob->disp, DL_VERTS);
2043                 if(!dl) return;
2044
2045                 if(me->bb==0) me->bb= MEM_callocN(sizeof(BoundBox), "boundbox");        
2046                 bb= me->bb;
2047
2048                 vert= dl->verts;
2049                 for(a=0; a<dl->nr; a++, vert+=3) {
2050                         DO_MINMAX(vert, min, max);
2051                 }
2052         }
2053         else if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
2054                 Curve *cu= ob->data;
2055
2056                 if(cu->bb==0) cu->bb= MEM_callocN(sizeof(BoundBox), "boundbox");        
2057                 bb= cu->bb;
2058                 
2059                 dl= cu->disp.first;
2060
2061                 while (dl) {
2062                         if(dl->type==DL_INDEX3 || dl->type==DL_INDEX3) tot= dl->nr;
2063                         else tot= dl->nr*dl->parts;
2064                         
2065                         vert= dl->verts;
2066                         for(a=0; a<tot; a++, vert+=3) {
2067                                 DO_MINMAX(vert, min, max);
2068                         }
2069
2070                         dl= dl->next;
2071                 }
2072         }
2073         
2074         if(bb) {
2075                 bb->vec[0][0]=bb->vec[1][0]=bb->vec[2][0]=bb->vec[3][0]= min[0];
2076                 bb->vec[4][0]=bb->vec[5][0]=bb->vec[6][0]=bb->vec[7][0]= max[0];
2077                 
2078                 bb->vec[0][1]=bb->vec[1][1]=bb->vec[4][1]=bb->vec[5][1]= min[1];
2079                 bb->vec[2][1]=bb->vec[3][1]=bb->vec[6][1]=bb->vec[7][1]= max[1];
2080         
2081                 bb->vec[0][2]=bb->vec[3][2]=bb->vec[4][2]=bb->vec[7][2]= min[2];
2082                 bb->vec[1][2]=bb->vec[2][2]=bb->vec[5][2]=bb->vec[6][2]= max[2];
2083         }
2084 }
2085