8f92a0a0d680e7a21867daf61e9f029845ea7b8d
[blender.git] / source / blender / blenkernel / intern / displist.c
1 /*  displist.c
2  * 
3  * 
4  * $Id$
5  *
6  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version. The Blender
12  * Foundation also sells licenses for use in proprietary software under
13  * the Blender License.  See http://www.blender.org/BL/ for information
14  * about this.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  *
25  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
26  * All rights reserved.
27  *
28  * The Original Code is: all of this file.
29  *
30  * Contributor(s): none yet.
31  *
32  * ***** END GPL/BL DUAL LICENSE BLOCK *****
33  */
34
35 #include <math.h>
36 #include <stdio.h>
37 #include <string.h>
38
39 #include "MEM_guardedalloc.h"
40
41 #include "IMB_imbuf_types.h"
42
43 #include "DNA_texture_types.h"
44 #include "DNA_meta_types.h"
45 #include "DNA_curve_types.h"
46 #include "DNA_effect_types.h"
47 #include "DNA_listBase.h"
48 #include "DNA_lamp_types.h"
49 #include "DNA_object_types.h"
50 #include "DNA_object_force.h"
51 #include "DNA_mesh_types.h"
52 #include "DNA_meshdata_types.h"
53 #include "DNA_modifier_types.h"
54 #include "DNA_scene_types.h"
55 #include "DNA_image_types.h"
56 #include "DNA_material_types.h"
57 #include "DNA_view3d_types.h"
58 #include "DNA_lattice_types.h"
59 #include "DNA_key_types.h"
60
61 #include "BLI_blenlib.h"
62 #include "BLI_arithb.h"
63 #include "BLI_editVert.h"
64 #include "BLI_edgehash.h"
65
66 #include "BKE_bad_level_calls.h"
67 #include "BKE_utildefines.h"
68 #include "BKE_global.h"
69 #include "BKE_displist.h"
70 #include "BKE_deform.h"
71 #include "BKE_DerivedMesh.h"
72 #include "BKE_object.h"
73 #include "BKE_world.h"
74 #include "BKE_mesh.h"
75 #include "BKE_effect.h"
76 #include "BKE_mball.h"
77 #include "BKE_material.h"
78 #include "BKE_curve.h"
79 #include "BKE_key.h"
80 #include "BKE_anim.h"
81 #include "BKE_screen.h"
82 #include "BKE_texture.h"
83 #include "BKE_library.h"
84 #include "BKE_font.h"
85 #include "BKE_lattice.h"
86 #include "BKE_scene.h"
87 #include "BKE_subsurf.h"
88 #include "BKE_modifier.h"
89
90 #include "RE_pipeline.h"
91 #include "RE_shader_ext.h"
92
93
94 static void boundbox_displist(Object *ob);
95
96 void displistmesh_free(DispListMesh *dlm) 
97 {
98         // also check on mvert and mface, can be NULL after decimator (ton)
99         if (!dlm->dontFreeVerts && dlm->mvert) MEM_freeN(dlm->mvert);
100         if (!dlm->dontFreeNors && dlm->nors) MEM_freeN(dlm->nors);
101         if (!dlm->dontFreeOther) {
102                 if (dlm->medge) MEM_freeN(dlm->medge);
103                 if (dlm->mface) MEM_freeN(dlm->mface);
104                 if (dlm->mcol) MEM_freeN(dlm->mcol);
105                 if (dlm->tface) MEM_freeN(dlm->tface);
106         }
107         MEM_freeN(dlm);
108 }
109
110 DispListMesh *displistmesh_copy(DispListMesh *odlm) 
111 {
112         DispListMesh *ndlm= MEM_dupallocN(odlm);
113         ndlm->mvert= MEM_dupallocN(odlm->mvert);
114         if (odlm->medge) ndlm->medge= MEM_dupallocN(odlm->medge);
115         ndlm->mface= MEM_dupallocN(odlm->mface);
116         if (odlm->nors) ndlm->nors = MEM_dupallocN(odlm->nors);
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 DispListMesh *displistmesh_copyShared(DispListMesh *odlm) 
124 {
125         DispListMesh *ndlm= MEM_dupallocN(odlm);
126         ndlm->dontFreeNors = ndlm->dontFreeOther = ndlm->dontFreeVerts = 1;
127         
128         return ndlm;
129 }
130
131 void displistmesh_to_mesh(DispListMesh *dlm, Mesh *me) 
132 {
133                 /* We assume, rather courageously, that any
134                  * shared data came from the mesh itself and so
135                  * we can ignore the dlm->dontFreeOther flag.
136                  */
137
138         if (me->mvert && dlm->mvert!=me->mvert) MEM_freeN(me->mvert);
139         if (me->mface && dlm->mface!=me->mface) MEM_freeN(me->mface);
140         if (me->tface && dlm->tface!=me->tface) MEM_freeN(me->tface);
141         if (me->mcol && dlm->mcol!=me->mcol) MEM_freeN(me->mcol);
142         if (me->medge && dlm->medge!=me->medge) MEM_freeN(me->medge);
143
144         me->tface = NULL;
145         me->mcol = NULL;
146         me->medge = NULL;
147
148         if (dlm->totvert!=me->totvert) {
149                 if (me->msticky) MEM_freeN(me->msticky);
150                 me->msticky = NULL;
151
152                 if (me->dvert) free_dverts(me->dvert, me->totvert);
153                 me->dvert = NULL;
154
155                 if(me->key) me->key->id.us--;
156                 me->key = NULL;
157         }
158
159         me->totface= dlm->totface;
160         me->totvert= dlm->totvert;
161         me->totedge= 0;
162
163         me->mvert= dlm->mvert;
164         me->mface= dlm->mface;
165         if (dlm->tface)
166                 me->tface= dlm->tface;
167         if (dlm->mcol)
168                 me->mcol= dlm->mcol;
169
170         if(dlm->medge) {
171                 me->totedge= dlm->totedge;
172                 me->medge= dlm->medge;
173         }
174
175         if (dlm->nors && !dlm->dontFreeNors) MEM_freeN(dlm->nors);
176
177         MEM_freeN(dlm);
178 }
179
180 void free_disp_elem(DispList *dl)
181 {
182         if(dl) {
183                 if(dl->verts) MEM_freeN(dl->verts);
184                 if(dl->nors) MEM_freeN(dl->nors);
185                 if(dl->index) MEM_freeN(dl->index);
186                 if(dl->col1) MEM_freeN(dl->col1);
187                 if(dl->col2) MEM_freeN(dl->col2);
188                 if(dl->bevelSplitFlag) MEM_freeN(dl->bevelSplitFlag);
189                 MEM_freeN(dl);
190         }
191 }
192
193 void freedisplist(ListBase *lb)
194 {
195         DispList *dl;
196
197         dl= lb->first;
198         while(dl) {
199                 BLI_remlink(lb, dl);
200                 free_disp_elem(dl);
201                 dl= lb->first;
202         }
203 }
204
205 DispList *find_displist_create(ListBase *lb, int type)
206 {
207         DispList *dl;
208         
209         dl= lb->first;
210         while(dl) {
211                 if(dl->type==type) return dl;
212                 dl= dl->next;
213         }
214
215         dl= MEM_callocN(sizeof(DispList), "find_disp");
216         dl->type= type;
217         BLI_addtail(lb, dl);
218
219         return dl;
220 }
221
222 DispList *find_displist(ListBase *lb, int type)
223 {
224         DispList *dl;
225         
226         dl= lb->first;
227         while(dl) {
228                 if(dl->type==type) return dl;
229                 dl= dl->next;
230         }
231
232         return 0;
233 }
234
235 int displist_has_faces(ListBase *lb)
236 {
237         DispList *dl;
238         
239         dl= lb->first;
240         while(dl) {
241                 if ELEM3(dl->type, DL_INDEX3, DL_INDEX4, DL_SURF)
242                         return 1;
243                 dl= dl->next;
244         }
245         return 0;
246 }
247
248 void copy_displist(ListBase *lbn, ListBase *lb)
249 {
250         DispList *dln, *dl;
251         
252         lbn->first= lbn->last= 0;
253         
254         dl= lb->first;
255         while(dl) {
256                 
257                 dln= MEM_dupallocN(dl);
258                 BLI_addtail(lbn, dln);
259                 dln->verts= MEM_dupallocN(dl->verts);
260                 dln->nors= MEM_dupallocN(dl->nors);
261                 dln->index= MEM_dupallocN(dl->index);
262                 dln->col1= MEM_dupallocN(dl->col1);
263                 dln->col2= MEM_dupallocN(dl->col2);
264                 
265                 dl= dl->next;
266         }
267 }
268
269 void addnormalsDispList(Object *ob, ListBase *lb)
270 {
271         DispList *dl = NULL;
272         float *vdata, *ndata, nor[3];
273         float *v1, *v2, *v3, *v4;
274         float *n1, *n2, *n3, *n4;
275         int a, b, p1, p2, p3, p4;
276
277
278         dl= lb->first;
279         
280         while(dl) {
281                 if(dl->type==DL_INDEX3) {
282                         if(dl->nors==0) {
283                                 dl->nors= MEM_callocN(sizeof(float)*3, "dlnors");
284                                 if(dl->verts[2]<0.0) dl->nors[2]= -1.0;
285                                 else dl->nors[2]= 1.0;
286                         }
287                 }
288                 else if(dl->type==DL_SURF) {
289                         if(dl->nors==0) {
290                                 dl->nors= MEM_callocN(sizeof(float)*3*dl->nr*dl->parts, "dlnors");
291                                 
292                                 vdata= dl->verts;
293                                 ndata= dl->nors;
294                                 
295                                 for(a=0; a<dl->parts; a++) {
296         
297                                         DL_SURFINDEX(dl->flag & DL_CYCL_U, dl->flag & DL_CYCL_V, dl->nr, dl->parts);
298         
299                                         v1= vdata+ 3*p1; 
300                                         n1= ndata+ 3*p1;
301                                         v2= vdata+ 3*p2; 
302                                         n2= ndata+ 3*p2;
303                                         v3= vdata+ 3*p3; 
304                                         n3= ndata+ 3*p3;
305                                         v4= vdata+ 3*p4; 
306                                         n4= ndata+ 3*p4;
307                                         
308                                         for(; b<dl->nr; b++) {
309         
310                                                 CalcNormFloat4(v1, v3, v4, v2, nor);
311         
312                                                 VecAddf(n1, n1, nor);
313                                                 VecAddf(n2, n2, nor);
314                                                 VecAddf(n3, n3, nor);
315                                                 VecAddf(n4, n4, nor);
316         
317                                                 v2= v1; v1+= 3;
318                                                 v4= v3; v3+= 3;
319                                                 n2= n1; n1+= 3;
320                                                 n4= n3; n3+= 3;
321                                         }
322                                 }
323                                 a= dl->parts*dl->nr;
324                                 v1= ndata;
325                                 while(a--) {
326                                         Normalise(v1);
327                                         v1+= 3;
328                                 }
329                         }
330                 }
331                 dl= dl->next;
332         }
333 }
334
335 void count_displist(ListBase *lb, int *totvert, int *totface)
336 {
337         DispList *dl;
338         
339         dl= lb->first;
340         while(dl) {
341                 
342                 switch(dl->type) {
343                         case DL_SURF:
344                                 *totvert+= dl->nr*dl->parts;
345                                 *totface+= (dl->nr-1)*(dl->parts-1);
346                                 break;
347                         case DL_INDEX3:
348                         case DL_INDEX4:
349                                 *totvert+= dl->nr;
350                                 *totface+= dl->parts;
351                                 break;
352                         case DL_POLY:
353                         case DL_SEGM:
354                                 *totvert+= dl->nr*dl->parts;
355                 }
356                 
357                 dl= dl->next;
358         }
359 }
360
361
362 /* ***************************** shade displist ******************** */
363
364 /* create default shade input... save cpu cycles with ugly global */
365 static ShadeInput shi;
366 static void init_fastshade_shadeinput(void)
367 {
368         
369         memset(&shi, 0, sizeof(ShadeInput));
370         shi.lay= G.scene->lay;
371         shi.view[2]= -1.0f;
372 }
373
374 static Render *fastshade_get_render(void)
375 {
376         Render *re= RE_GetRender("_Shade View_");
377         if(re==NULL) {
378                 re= RE_NewRender("_Shade View_");
379         
380                 RE_Database_Shaded(re, G.scene);
381         }
382         return re;
383 }
384
385 /* called on file reading */
386 void fastshade_free_render(void)
387 {
388         Render *re= RE_GetRender("_Shade View_");
389         
390         if(re) {
391                 RE_Database_Free(re);
392                 RE_FreeRender(re);
393         }
394 }
395
396 static void fastshade(float *co, float *nor, float *orco, Material *ma, char *col1, char *col2, char *vertcol)
397 {
398         ShadeResult shr;
399         int a;
400         
401         if(vertcol) {
402                 shi.vcol[0]= ((float)vertcol[3])/255.0f;
403                 shi.vcol[1]= ((float)vertcol[2])/255.0f;
404                 shi.vcol[2]= ((float)vertcol[1])/255.0f;
405         }
406         
407         VECCOPY(shi.co, co);
408         shi.vn[0]= -nor[0];
409         shi.vn[1]= -nor[1];
410         shi.vn[2]= -nor[2];
411         VECCOPY(shi.vno, shi.vn);
412         
413         if(ma->texco) {
414                 VECCOPY(shi.lo, orco);
415                 
416                 if(ma->texco & TEXCO_GLOB) {
417                         VECCOPY(shi.gl, shi.lo);
418                 }
419                 if(ma->texco & TEXCO_WINDOW) {
420                         VECCOPY(shi.winco, shi.lo);
421                 }
422                 if(ma->texco & TEXCO_STICKY) {
423                         VECCOPY(shi.sticky, shi.lo);
424                 }
425                 if(ma->texco & TEXCO_UV) {
426                         VECCOPY(shi.uv, shi.lo);
427                 }
428                 if(ma->texco & TEXCO_OBJECT) {
429                         VECCOPY(shi.co, shi.lo);
430                 }
431                 if(ma->texco & TEXCO_NORM) {
432                         VECCOPY(shi.orn, shi.vn);
433                 }
434                 if(ma->texco & TEXCO_REFL) {
435                         float inp= 2.0*(shi.vn[2]);
436                         shi.ref[0]= (inp*shi.vn[0]);
437                         shi.ref[1]= (inp*shi.vn[1]);
438                         shi.ref[2]= (-1.0+inp*shi.vn[2]);
439                 }
440         }
441         
442         shi.mat= ma;    /* set each time... node shaders change it */
443         RE_shade_external(NULL, &shi, &shr);
444         
445         VECADD(shr.combined, shr.diff, shr.spec);
446         
447         a= 256.0f*(shr.combined[0]);
448         col1[3]= CLAMPIS(a, 0, 255);
449         a= 256.0f*(shr.combined[1]);
450         col1[2]= CLAMPIS(a, 0, 255);
451         a= 256.0f*(shr.combined[2]);
452         col1[1]= CLAMPIS(a, 0, 255);
453         
454         if(col2) {
455                 shi.vn[0]= -shi.vn[0];
456                 shi.vn[1]= -shi.vn[1];
457                 shi.vn[2]= -shi.vn[2];
458                 
459                 shi.mat= ma;    /* set each time... node shaders change it */
460                 RE_shade_external(NULL, &shi, &shr);
461                 
462                 VECADD(shr.combined, shr.diff, shr.spec);
463                 
464                 a= 256.0f*(shr.combined[0]);
465                 col2[3]= CLAMPIS(a, 0, 255);
466                 a= 256.0f*(shr.combined[1]);
467                 col2[2]= CLAMPIS(a, 0, 255);
468                 a= 256.0f*(shr.combined[2]);
469                 col2[1]= CLAMPIS(a, 0, 255);
470         }
471 }
472
473 static void init_fastshade_for_ob(Render *re, Object *ob, int *need_orco_r, float mat[4][4], float imat[3][3])
474 {
475         float tmat[4][4];
476         float amb[3]= {0.0f, 0.0f, 0.0f};
477         int a;
478         
479         /* initialize globals in render */
480         RE_shade_external(re, NULL, NULL);
481
482         /* initialize global here */
483         init_fastshade_shadeinput();
484         
485         RE_DataBase_GetView(re, tmat);
486         Mat4MulMat4(mat, ob->obmat, tmat);
487         
488         Mat4Invert(tmat, mat);
489         Mat3CpyMat4(imat, tmat);
490         if(ob->transflag & OB_NEG_SCALE) Mat3MulFloat((float *)imat, -1.0);
491         
492         if (need_orco_r) *need_orco_r= 0;
493         for(a=0; a<ob->totcol; a++) {
494                 Material *ma= give_current_material(ob, a+1);
495                 if(ma) {
496                         init_render_material(ma, 0, amb);
497
498                         if(ma->texco & TEXCO_ORCO) {
499                                 if (need_orco_r) *need_orco_r= 1;
500                         }
501                 }
502         }
503 }
504
505 static void end_fastshade_for_ob(Object *ob)
506 {
507         int a;
508         
509         for(a=0; a<ob->totcol; a++) {
510                 Material *ma= give_current_material(ob, a+1);
511                 if(ma)
512                         end_render_material(ma);
513         }
514 }
515
516
517 static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, unsigned int **col1_r, unsigned int **col2_r)
518 {
519         Mesh *me= ob->data;
520         int dmNeedsFree;
521         DerivedMesh *dm;
522         DispListMesh *dlm;
523         unsigned int *col1, *col2;
524         float *orco, *vnors, imat[3][3], mat[4][4], vec[3];
525         int a, i, need_orco;
526
527         init_fastshade_for_ob(re, ob, &need_orco, mat, imat);
528
529         if (need_orco) {
530                 orco = mesh_create_orco(ob);
531         } else {
532                 orco = NULL;
533         }
534
535         if (onlyForMesh) {
536                 dm = mesh_get_derived_deform(ob, &dmNeedsFree);
537         } else {
538                 dm = mesh_get_derived_final(ob, &dmNeedsFree);
539         }
540         dlm= dm->convertToDispListMesh(dm, 1);
541
542         col1 = MEM_mallocN(sizeof(*col1)*dlm->totface*4, "col1");
543         if (col2_r && (me->flag & ME_TWOSIDED)) {
544                 col2 = MEM_mallocN(sizeof(*col2)*dlm->totface*4, "col1");
545         } else {
546                 col2 = NULL;
547         }
548         
549         *col1_r = col1;
550         if (col2_r) *col2_r = col2;
551
552                 /* vertexnormals */
553         vnors= MEM_mallocN(dlm->totvert*3*sizeof(float), "vnors disp");
554         for (a=0; a<dlm->totvert; a++) {
555                 MVert *mv = &dlm->mvert[a];
556                 float *vn= &vnors[a*3];
557                 float xn= mv->no[0]; 
558                 float yn= mv->no[1]; 
559                 float zn= mv->no[2];
560                 
561                         /* transpose ! */
562                 vn[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
563                 vn[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
564                 vn[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
565                 Normalise(vn);
566         }               
567
568         for (i=0; i<dlm->totface; i++) {
569                 MFace *mf= &dlm->mface[i];
570                 int j, vidx[4], nverts= mf->v4?4:3;
571                 unsigned char *col1base= (unsigned char*) &col1[i*4];
572                 unsigned char *col2base= (unsigned char*) (col2?&col2[i*4]:NULL);
573                 unsigned char *mcolbase;
574                 Material *ma= give_current_material(ob, mf->mat_nr+1);
575                 float nor[3], n1[3];
576                 
577                 if(ma==NULL) ma= &defmaterial;
578                 
579                 if (dlm->tface) {
580                         mcolbase = (unsigned char*) dlm->tface[i].col;
581                 } else if (dlm->mcol) {
582                         mcolbase = (unsigned char*) &dlm->mcol[i*4];
583                 } else {
584                         mcolbase = NULL;
585                 }
586
587                 vidx[0]= mf->v1;
588                 vidx[1]= mf->v2;
589                 vidx[2]= mf->v3;
590                 vidx[3]= mf->v4;
591
592                 if (dlm->nors) {
593                         VECCOPY(nor, &dlm->nors[i*3]);
594                 } else {
595                         if (mf->v4)
596                                 CalcNormFloat4(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, dlm->mvert[mf->v4].co, nor);
597                         else
598                                 CalcNormFloat(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, nor);
599                 }
600
601                 n1[0]= imat[0][0]*nor[0]+imat[0][1]*nor[1]+imat[0][2]*nor[2];
602                 n1[1]= imat[1][0]*nor[0]+imat[1][1]*nor[1]+imat[1][2]*nor[2];
603                 n1[2]= imat[2][0]*nor[0]+imat[2][1]*nor[1]+imat[2][2]*nor[2];
604                 Normalise(n1);
605
606                 for (j=0; j<nverts; j++) {
607                         MVert *mv= &dlm->mvert[vidx[j]];
608                         unsigned char *col1= &col1base[j*4];
609                         unsigned char *col2= col2base?&col2base[j*4]:NULL;
610                         unsigned char *mcol= mcolbase?&mcolbase[j*4]:NULL;
611                         float *vn = (mf->flag & ME_SMOOTH)?&vnors[3*vidx[j]]:n1;
612
613                         VECCOPY(vec, mv->co);
614                         Mat4MulVecfl(mat, vec);
615                         fastshade(vec, vn, orco?&orco[vidx[j]*3]:mv->co, ma, col1, col2, mcol);
616                 }
617         } 
618         MEM_freeN(vnors);
619         displistmesh_free(dlm);
620
621         if (orco) {
622                 MEM_freeN(orco);
623         }
624
625         if (dmNeedsFree) dm->release(dm);
626
627         end_fastshade_for_ob(ob);
628 }
629
630 void shadeMeshMCol(Object *ob, Mesh *me)
631 {
632         Render *re= fastshade_get_render();
633         mesh_create_shadedColors(re, ob, 1, (unsigned int**)&me->mcol, NULL);
634 }
635
636 /* has base pointer, to check for layer */
637 /* called from drawobject.c */
638 void shadeDispList(Base *base)
639 {
640         Object *ob= base->object;
641         DispList *dl, *dlob;
642         Material *ma = NULL;
643         Curve *cu;
644         Render *re;
645         float imat[3][3], mat[4][4], vec[3];
646         float *fp, *nor, n1[3];
647         unsigned int *col1;
648         int a, need_orco;
649         
650         re= fastshade_get_render();
651         
652         dl = find_displist(&ob->disp, DL_VERTCOL);
653         if (dl) {
654                 BLI_remlink(&ob->disp, dl);
655                 free_disp_elem(dl);
656         }
657
658         if(ob->type==OB_MESH) {
659                 dl= MEM_callocN(sizeof(DispList), "displistshade");
660                 BLI_addtail(&ob->disp, dl);
661                 dl->type= DL_VERTCOL;
662
663                 mesh_create_shadedColors(re, ob, 0, &dl->col1, &dl->col2);
664         }
665         else {
666
667                 init_fastshade_for_ob(re, ob, &need_orco, mat, imat);
668                 
669                 if ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT) {
670                 
671                         /* now we need the normals */
672                         cu= ob->data;
673                         dl= cu->disp.first;
674                         
675                         while(dl) {
676                                 dlob= MEM_callocN(sizeof(DispList), "displistshade");
677                                 BLI_addtail(&ob->disp, dlob);
678                                 dlob->type= DL_VERTCOL;
679                                 dlob->parts= dl->parts;
680                                 dlob->nr= dl->nr;
681                                 
682                                 if(dl->type==DL_INDEX3) {
683                                         col1= dlob->col1= MEM_mallocN(sizeof(int)*dl->nr, "col1");
684                                 }
685                                 else {
686                                         col1= dlob->col1= MEM_mallocN(sizeof(int)*dl->parts*dl->nr, "col1");
687                                 }
688                                 
689                         
690                                 ma= give_current_material(ob, dl->col+1);
691                                 if(ma==NULL) ma= &defmaterial;
692                                 
693                                 if(dl->type==DL_INDEX3) {
694                                         if(dl->nors) {
695                                                 /* there's just one normal */
696                                                 n1[0]= imat[0][0]*dl->nors[0]+imat[0][1]*dl->nors[1]+imat[0][2]*dl->nors[2];
697                                                 n1[1]= imat[1][0]*dl->nors[0]+imat[1][1]*dl->nors[1]+imat[1][2]*dl->nors[2];
698                                                 n1[2]= imat[2][0]*dl->nors[0]+imat[2][1]*dl->nors[1]+imat[2][2]*dl->nors[2];
699                                                 Normalise(n1);
700                                                 
701                                                 fp= dl->verts;
702                                                 
703                                                 a= dl->nr;              
704                                                 while(a--) {
705                                                         VECCOPY(vec, fp);
706                                                         Mat4MulVecfl(mat, vec);
707                                                         
708                                                         fastshade(vec, n1, fp, ma, (char *)col1, 0, 0);
709                                                         
710                                                         fp+= 3; col1++;
711                                                 }
712                                         }
713                                 }
714                                 else if(dl->type==DL_SURF) {
715                                         if(dl->nors) {
716                                                 a= dl->nr*dl->parts;
717                                                 fp= dl->verts;
718                                                 nor= dl->nors;
719                                                 
720                                                 while(a--) {
721                                                         VECCOPY(vec, fp);
722                                                         Mat4MulVecfl(mat, vec);
723                                                         
724                                                         n1[0]= imat[0][0]*nor[0]+imat[0][1]*nor[1]+imat[0][2]*nor[2];
725                                                         n1[1]= imat[1][0]*nor[0]+imat[1][1]*nor[1]+imat[1][2]*nor[2];
726                                                         n1[2]= imat[2][0]*nor[0]+imat[2][1]*nor[1]+imat[2][2]*nor[2];
727                                                         Normalise(n1);
728                                 
729                                                         fastshade(vec, n1, fp, ma, (char *)col1, 0, 0);
730                                                         
731                                                         fp+= 3; nor+= 3; col1++;
732                                                 }
733                                         }
734                                 }
735                                 dl= dl->next;
736                         }
737                 }
738                 else if(ob->type==OB_MBALL) {
739                         /* there are normals already */
740                         dl= ob->disp.first;
741                         
742                         while(dl) {
743                                 
744                                 if(dl->type==DL_INDEX4) {
745                                         if(dl->nors) {
746                                                 
747                                                 if(dl->col1) MEM_freeN(dl->col1);
748                                                 col1= dl->col1= MEM_mallocN(sizeof(int)*dl->nr, "col1");
749                                 
750                                                 ma= give_current_material(ob, dl->col+1);
751                                                 if(ma==NULL) ma= &defmaterial;
752                                                 
753                                                 fp= dl->verts;
754                                                 nor= dl->nors;
755                                                 
756                                                 a= dl->nr;              
757                                                 while(a--) {
758                                                         VECCOPY(vec, fp);
759                                                         Mat4MulVecfl(mat, vec);
760                                                         
761                                                         /* transpose ! */
762                                                         n1[0]= imat[0][0]*nor[0]+imat[0][1]*nor[1]+imat[0][2]*nor[2];
763                                                         n1[1]= imat[1][0]*nor[0]+imat[1][1]*nor[1]+imat[1][2]*nor[2];
764                                                         n1[2]= imat[2][0]*nor[0]+imat[2][1]*nor[1]+imat[2][2]*nor[2];
765                                                         Normalise(n1);
766                                                 
767                                                         fastshade(vec, n1, fp, ma, (char *)col1, 0, 0);
768                                                         
769                                                         fp+= 3; col1++; nor+= 3;
770                                                 }
771                                         }
772                                 }
773                                 dl= dl->next;
774                         }
775                 }
776                 
777                 end_fastshade_for_ob(ob);
778         }
779 }
780
781 /* frees render and shade part of displists */
782 void reshadeall_displist(void)
783 {
784         Base *base;
785         Object *ob;
786         
787         fastshade_free_render();
788         
789         for(base= G.scene->base.first; base; base= base->next) {
790                 ob= base->object;
791                 freedisplist(&ob->disp);
792                 if(base->lay & G.scene->lay) {
793                         /* Metaballs have standard displist at the Object */
794                         if(ob->type==OB_MBALL) shadeDispList(base);
795                 }
796         }
797 }
798
799 /* ****************** make displists ********************* */
800
801 static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase)
802 {
803         Nurb *nu;
804         DispList *dl;
805         BezTriple *bezt, *prevbezt;
806         BPoint *bp;
807         float *data, *v1, *v2;
808         int a, len, resolu;
809         
810         nu= nubase->first;
811         while(nu) {
812                 if(nu->hide==0) {
813                         
814                         if(G.rendering && cu->resolu_ren!=0) 
815                                 resolu= cu->resolu_ren;
816                         else
817                                 resolu= nu->resolu;
818                         
819                         if((nu->type & 7)==CU_BEZIER) {
820                                 
821                                 /* count */
822                                 len= 0;
823                                 a= nu->pntsu-1;
824                                 if(nu->flagu & CU_CYCLIC) a++;
825
826                                 prevbezt= nu->bezt;
827                                 bezt= prevbezt+1;
828                                 while(a--) {
829                                         if(a==0 && (nu->flagu & CU_CYCLIC)) bezt= nu->bezt;
830                                         
831                                         if(prevbezt->h2==HD_VECT && bezt->h1==HD_VECT) len++;
832                                         else len+= resolu;
833                                         
834                                         if(a==0 && (nu->flagu & CU_CYCLIC)==0) len++;
835                                         
836                                         prevbezt= bezt;
837                                         bezt++;
838                                 }
839                                 
840                                 dl= MEM_callocN(sizeof(DispList), "makeDispListbez");
841                                 /* len+1 because of 'forward_diff_bezier' function */
842                                 dl->verts= MEM_callocN( (len+1)*3*sizeof(float), "dlverts");
843                                 BLI_addtail(dispbase, dl);
844                                 dl->parts= 1;
845                                 dl->nr= len;
846                                 dl->col= nu->mat_nr;
847                                 dl->charidx= nu->charidx;
848
849                                 data= dl->verts;
850
851                                 if(nu->flagu & 1) {
852                                         dl->type= DL_POLY;
853                                         a= nu->pntsu;
854                                 }
855                                 else {
856                                         dl->type= DL_SEGM;
857                                         a= nu->pntsu-1;
858                                 }
859                                 
860                                 prevbezt= nu->bezt;
861                                 bezt= prevbezt+1;
862                                 
863                                 while(a--) {
864                                         if(a==0 && dl->type== DL_POLY) bezt= nu->bezt;
865                                         
866                                         if(prevbezt->h2==HD_VECT && bezt->h1==HD_VECT) {
867                                                 VECCOPY(data, prevbezt->vec[1]);
868                                                 data+= 3;
869                                         }
870                                         else {
871                                                 v1= prevbezt->vec[1];
872                                                 v2= bezt->vec[0];
873                                                 forward_diff_bezier(v1[0], v1[3], v2[0], v2[3], data, resolu, 3);
874                                                 forward_diff_bezier(v1[1], v1[4], v2[1], v2[4], data+1, resolu, 3);
875                                                 forward_diff_bezier(v1[2], v1[5], v2[2], v2[5], data+2, resolu, 3);
876                                                 data+= 3*resolu;
877                                         }
878                                         
879                                         if(a==0 && dl->type==DL_SEGM) {
880                                                 VECCOPY(data, bezt->vec[1]);
881                                         }
882                                         
883                                         prevbezt= bezt;
884                                         bezt++;
885                                 }
886                         }
887                         else if((nu->type & 7)==CU_NURBS) {
888                                 len= nu->pntsu*resolu;
889                                 dl= MEM_callocN(sizeof(DispList), "makeDispListsurf");
890                                 dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
891                                 BLI_addtail(dispbase, dl);
892                                 dl->parts= 1;
893                                 dl->nr= len;
894                                 dl->col= nu->mat_nr;
895                                 dl->charidx = nu->charidx;
896
897                                 data= dl->verts;
898                                 if(nu->flagu & 1) dl->type= DL_POLY;
899                                 else dl->type= DL_SEGM;
900                                 makeNurbcurve(nu, data, resolu, 3);
901                         }
902                         else if((nu->type & 7)==CU_POLY) {
903                                 len= nu->pntsu;
904                                 dl= MEM_callocN(sizeof(DispList), "makeDispListpoly");
905                                 dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
906                                 BLI_addtail(dispbase, dl);
907                                 dl->parts= 1;
908                                 dl->nr= len;
909                                 dl->col= nu->mat_nr;
910                                 dl->charidx = nu->charidx;
911
912                                 data= dl->verts;
913                                 if(nu->flagu & 1) dl->type= DL_POLY;
914                                 else dl->type= DL_SEGM;
915                                 
916                                 a= len;
917                                 bp= nu->bp;
918                                 while(a--) {
919                                         VECCOPY(data, bp->vec);
920                                         bp++;
921                                         data+= 3;
922                                 }
923                         }
924                 }
925                 nu= nu->next;
926         }
927 }
928
929
930 void filldisplist(ListBase *dispbase, ListBase *to)
931 {
932         EditVert *eve, *v1, *vlast;
933         EditFace *efa;
934         DispList *dlnew=0, *dl;
935         float *f1;
936         int colnr=0, charidx=0, cont=1, tot, a, *index;
937         long totvert;
938         
939         if(dispbase==0) return;
940         if(dispbase->first==0) return;
941
942         while(cont) {
943                 cont= 0;
944                 totvert=0;
945                 
946                 dl= dispbase->first;
947                 while(dl) {
948         
949                         if(dl->type==DL_POLY) {
950                                 if(charidx<dl->charidx) cont= 1;
951                                 else if(charidx==dl->charidx) {
952                         
953                                         colnr= dl->col;
954                                         charidx= dl->charidx;
955                 
956                                         /* make editverts and edges */
957                                         f1= dl->verts;
958                                         a= dl->nr;
959                                         eve= v1= 0;
960                                         
961                                         while(a--) {
962                                                 vlast= eve;
963                                                 
964                                                 eve= BLI_addfillvert(f1);
965                                                 totvert++;
966                                                 
967                                                 if(vlast==0) v1= eve;
968                                                 else {
969                                                         BLI_addfilledge(vlast, eve);
970                                                 }
971                                                 f1+=3;
972                                         }
973                                 
974                                         if(eve!=0 && v1!=0) {
975                                                 BLI_addfilledge(eve, v1);
976                                         }
977                                 }
978                         }
979                         dl= dl->next;
980                 }
981                 
982                 if(totvert && BLI_edgefill(0, (G.obedit && G.obedit->actcol)?(G.obedit->actcol-1):0)) {
983
984                         /* count faces  */
985                         tot= 0;
986                         efa= fillfacebase.first;
987                         while(efa) {
988                                 tot++;
989                                 efa= efa->next;
990                         }
991
992                         if(tot) {
993                                 dlnew= MEM_callocN(sizeof(DispList), "filldisplist");
994                                 dlnew->type= DL_INDEX3;
995                                 dlnew->col= colnr;
996                                 dlnew->nr= totvert;
997                                 dlnew->parts= tot;
998
999                                 dlnew->index= MEM_mallocN(tot*3*sizeof(int), "dlindex");
1000                                 dlnew->verts= MEM_mallocN(totvert*3*sizeof(float), "dlverts");
1001                                 
1002                                 /* vert data */
1003                                 f1= dlnew->verts;
1004                                 totvert= 0;
1005                                 eve= fillvertbase.first;
1006                                 while(eve) {
1007                                         VECCOPY(f1, eve->co);
1008                                         f1+= 3;
1009         
1010                                         /* index number */
1011                                         eve->tmp.l = totvert;
1012                                         totvert++;
1013                                         
1014                                         eve= eve->next;
1015                                 }
1016                                 
1017                                 /* index data */
1018                                 efa= fillfacebase.first;
1019                                 index= dlnew->index;
1020                                 while(efa) {
1021                                         index[0]= (long)efa->v1->tmp.l;
1022                                         index[1]= (long)efa->v2->tmp.l;
1023                                         index[2]= (long)efa->v3->tmp.l;
1024                                         
1025                                         index+= 3;
1026                                         efa= efa->next;
1027                                 }
1028                         }
1029
1030                         BLI_addhead(to, dlnew);
1031                         
1032                 }
1033                 BLI_end_edgefill();
1034
1035                 charidx++;
1036         }
1037         
1038         /* do not free polys, needed for wireframe display */
1039         
1040 }
1041
1042 static void bevels_to_filledpoly(Curve *cu, ListBase *dispbase)
1043 {
1044         ListBase front, back;
1045         DispList *dl, *dlnew;
1046         float *fp, *fp1;
1047         int a, dpoly;
1048         
1049         front.first= front.last= back.first= back.last= 0;
1050         
1051         dl= dispbase->first;
1052         while(dl) {
1053                 if(dl->type==DL_SURF) {
1054                         if( (dl->flag & DL_CYCL_V) && (dl->flag & DL_CYCL_U)==0 ) {
1055                                 if( (cu->flag & CU_BACK) && (dl->flag & DL_BACK_CURVE) ) {
1056                                         dlnew= MEM_callocN(sizeof(DispList), "filldisp");
1057                                         BLI_addtail(&front, dlnew);
1058                                         dlnew->verts= fp1= MEM_mallocN(sizeof(float)*3*dl->parts, "filldisp1");
1059                                         dlnew->nr= dl->parts;
1060                                         dlnew->parts= 1;
1061                                         dlnew->type= DL_POLY;
1062                                         dlnew->col= dl->col;
1063                                         dlnew->charidx = dl->charidx;
1064                                         
1065                                         fp= dl->verts;
1066                                         dpoly= 3*dl->nr;
1067                                         
1068                                         a= dl->parts;
1069                                         while(a--) {
1070                                                 VECCOPY(fp1, fp);
1071                                                 fp1+= 3;
1072                                                 fp+= dpoly;
1073                                         }
1074                                 }
1075                                 if( (cu->flag & CU_FRONT) && (dl->flag & DL_FRONT_CURVE) ) {
1076                                         dlnew= MEM_callocN(sizeof(DispList), "filldisp");
1077                                         BLI_addtail(&back, dlnew);
1078                                         dlnew->verts= fp1= MEM_mallocN(sizeof(float)*3*dl->parts, "filldisp1");
1079                                         dlnew->nr= dl->parts;
1080                                         dlnew->parts= 1;
1081                                         dlnew->type= DL_POLY;
1082                                         dlnew->col= dl->col;
1083                                         dlnew->charidx= dl->charidx;
1084                                         
1085                                         fp= dl->verts+3*(dl->nr-1);
1086                                         dpoly= 3*dl->nr;
1087                                         
1088                                         a= dl->parts;
1089                                         while(a--) {
1090                                                 VECCOPY(fp1, fp);
1091                                                 fp1+= 3;
1092                                                 fp+= dpoly;
1093                                         }
1094                                 }
1095                         }
1096                 }
1097                 dl= dl->next;
1098         }
1099
1100         filldisplist(&front, dispbase);
1101         filldisplist(&back, dispbase);
1102         
1103         freedisplist(&front);
1104         freedisplist(&back);
1105
1106         filldisplist(dispbase, dispbase);
1107         
1108 }
1109
1110 void curve_to_filledpoly(Curve *cu, ListBase *nurb, ListBase *dispbase)
1111 {
1112         if(cu->flag & CU_3D) return;
1113
1114         if(dispbase->first && ((DispList*) dispbase->first)->type==DL_SURF) {
1115                 bevels_to_filledpoly(cu, dispbase);
1116         }
1117         else {
1118                 filldisplist(dispbase, dispbase);
1119         }
1120 }
1121
1122 /* taper rules:
1123   - only 1 curve
1124   - first point left, last point right
1125   - based on subdivided points in original curve, not on points in taper curve (still)
1126 */
1127 static float calc_taper(Object *taperobj, int cur, int tot)
1128 {
1129         Curve *cu;
1130         DispList *dl;
1131         
1132         if(taperobj==NULL) return 1.0;
1133         
1134         cu= taperobj->data;
1135         dl= cu->disp.first;
1136         if(dl==NULL) {
1137                 makeDispListCurveTypes(taperobj, 0);
1138                 dl= cu->disp.first;
1139         }
1140         if(dl) {
1141                 float fac= ((float)cur)/(float)(tot-1);
1142                 float minx, dx, *fp;
1143                 int a;
1144                 
1145                 /* horizontal size */
1146                 minx= dl->verts[0];
1147                 dx= dl->verts[3*(dl->nr-1)] - minx;
1148                 if(dx>0.0) {
1149                 
1150                         fp= dl->verts;
1151                         for(a=0; a<dl->nr; a++, fp+=3) {
1152                                 if( (fp[0]-minx)/dx >= fac) {
1153                                         /* interpolate with prev */
1154                                         if(a>0) {
1155                                                 float fac1= (fp[-3]-minx)/dx;
1156                                                 float fac2= (fp[0]-minx)/dx;
1157                                                 if(fac1!=fac2)
1158                                                         return fp[1]*(fac1-fac)/(fac1-fac2) + fp[-2]*(fac-fac2)/(fac1-fac2);
1159                                         }
1160                                         return fp[1];
1161                                 }
1162                         }
1163                         return fp[-2];  // last y coord
1164                 }
1165         }
1166         
1167         return 1.0;
1168 }
1169
1170 void makeDispListMBall(Object *ob)
1171 {
1172         if(!ob || ob->type!=OB_MBALL) return;
1173
1174         freedisplist(&(ob->disp));
1175         
1176         if(ob->type==OB_MBALL) {
1177                 if(ob==find_basis_mball(ob)) {
1178                         metaball_polygonize(ob);
1179                         tex_space_mball(ob);
1180
1181                         object_deform_mball(ob);
1182                 }
1183         }
1184         
1185         boundbox_displist(ob);
1186 }
1187
1188 static ModifierData *curve_get_tesselate_point(Object *ob, int forRender, int editmode)
1189 {
1190         ModifierData *md = modifiers_getVirtualModifierList(ob);
1191         ModifierData *preTesselatePoint;
1192
1193         preTesselatePoint = NULL;
1194         for (; md; md=md->next) {
1195                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1196
1197                 if (!(md->mode&(1<<forRender))) continue;
1198                 if (editmode && !(md->mode&eModifierMode_Editmode)) continue;
1199                 if (mti->isDisabled && mti->isDisabled(md)) continue;
1200
1201                 if (md->type==eModifierType_Hook || md->type==eModifierType_Softbody) {
1202                         preTesselatePoint  = md;
1203                 }
1204         }
1205
1206         return preTesselatePoint;
1207 }
1208
1209 void curve_calc_modifiers_pre(Object *ob, ListBase *nurb, int forRender, float (**originalVerts_r)[3], float (**deformedVerts_r)[3], int *numVerts_r)
1210 {
1211         int editmode = (!forRender && ob==G.obedit);
1212         ModifierData *md = modifiers_getVirtualModifierList(ob);
1213         ModifierData *preTesselatePoint = curve_get_tesselate_point(ob, forRender, editmode);
1214         int numVerts = 0;
1215         float (*originalVerts)[3] = NULL;
1216         float (*deformedVerts)[3] = NULL;
1217
1218         if(ob!=G.obedit && do_ob_key(ob)) {
1219                 deformedVerts = curve_getVertexCos(ob->data, nurb, &numVerts);
1220                 originalVerts = MEM_dupallocN(deformedVerts);
1221         }
1222         
1223         if (preTesselatePoint) {
1224                 for (; md; md=md->next) {
1225                         ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1226
1227                         if (!(md->mode&(1<<forRender))) continue;
1228                         if (editmode && !(md->mode&eModifierMode_Editmode)) continue;
1229                         if (mti->isDisabled && mti->isDisabled(md)) continue;
1230                         if (mti->type!=eModifierTypeType_OnlyDeform) continue;
1231
1232                         if (!deformedVerts) {
1233                                 deformedVerts = curve_getVertexCos(ob->data, nurb, &numVerts);
1234                                 originalVerts = MEM_dupallocN(deformedVerts);
1235                         }
1236                         
1237                         mti->deformVerts(md, ob, NULL, deformedVerts, numVerts);
1238
1239                         if (md==preTesselatePoint)
1240                                 break;
1241                 }
1242         }
1243
1244         if (deformedVerts) {
1245                 curve_applyVertexCos(ob->data, nurb, deformedVerts);
1246         }
1247
1248         *originalVerts_r = originalVerts;
1249         *deformedVerts_r = deformedVerts;
1250         *numVerts_r = numVerts;
1251 }
1252
1253 void curve_calc_modifiers_post(Object *ob, ListBase *nurb, ListBase *dispbase, int forRender, float (*originalVerts)[3], float (*deformedVerts)[3])
1254 {
1255         int editmode = (!forRender && ob==G.obedit);
1256         ModifierData *md = modifiers_getVirtualModifierList(ob);
1257         ModifierData *preTesselatePoint = curve_get_tesselate_point(ob, forRender, editmode);
1258         DispList *dl;
1259
1260         if (preTesselatePoint) {
1261                 md = preTesselatePoint->next;
1262         }
1263
1264         for (; md; md=md->next) {
1265                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1266
1267                 if (!(md->mode&(1<<forRender))) continue;
1268                 if (editmode && !(md->mode&eModifierMode_Editmode)) continue;
1269                 if (mti->isDisabled && mti->isDisabled(md)) continue;
1270                 if (mti->type!=eModifierTypeType_OnlyDeform) continue;
1271
1272                 for (dl=dispbase->first; dl; dl=dl->next) {
1273                         mti->deformVerts(md, ob, NULL, (float(*)[3]) dl->verts, (dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr);
1274                 }
1275         }
1276
1277         if (deformedVerts) {
1278                 curve_applyVertexCos(ob->data, nurb, originalVerts);
1279                 MEM_freeN(originalVerts);
1280                 MEM_freeN(deformedVerts);
1281         }
1282 }
1283
1284 void makeDispListSurf(Object *ob, ListBase *dispbase, int forRender)
1285 {
1286         ListBase *nubase;
1287         Nurb *nu;
1288         Curve *cu = ob->data;
1289         DispList *dl;
1290         float *data;
1291         int len;
1292         int numVerts;
1293         float (*originalVerts)[3];
1294         float (*deformedVerts)[3];
1295                 
1296         if(!forRender && ob==G.obedit) {
1297                 nubase= &editNurb;
1298         }
1299         else {
1300                 nubase= &cu->nurb;
1301         }
1302
1303         curve_calc_modifiers_pre(ob, nubase, forRender, &originalVerts, &deformedVerts, &numVerts);
1304
1305         for (nu=nubase->first; nu; nu=nu->next) {
1306                 if(forRender || nu->hide==0) {
1307                         if(nu->pntsv==1) {
1308                                 len= nu->pntsu*nu->resolu;
1309                                 
1310                                 dl= MEM_callocN(sizeof(DispList), "makeDispListsurf");
1311                                 dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
1312                                 
1313                                 BLI_addtail(dispbase, dl);
1314                                 dl->parts= 1;
1315                                 dl->nr= len;
1316                                 dl->col= nu->mat_nr;
1317                                 dl->charidx= nu->charidx;
1318                                 dl->rt= nu->flag;
1319                                 
1320                                 data= dl->verts;
1321                                 if(nu->flagu & 1) dl->type= DL_POLY;
1322                                 else dl->type= DL_SEGM;
1323                                 
1324                                 makeNurbcurve(nu, data, nu->resolu, 3);
1325                         }
1326                         else {
1327                                 len= nu->resolu*nu->resolv;
1328                                 
1329                                 dl= MEM_callocN(sizeof(DispList), "makeDispListsurf");
1330                                 dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
1331                                 BLI_addtail(dispbase, dl);
1332
1333                                 dl->col= nu->mat_nr;
1334                                 dl->charidx= nu->charidx;
1335                                 dl->rt= nu->flag;
1336                                 
1337                                 data= dl->verts;
1338                                 dl->type= DL_SURF;
1339
1340                                 dl->parts= nu->resolu;  /* in reverse, because makeNurbfaces works that way */
1341                                 dl->nr= nu->resolv;
1342                                 if(nu->flagv & CU_CYCLIC) dl->flag|= DL_CYCL_U; /* reverse too! */
1343                                 if(nu->flagu & CU_CYCLIC) dl->flag|= DL_CYCL_V;
1344
1345                                 makeNurbfaces(nu, data, 0);
1346                         }
1347                 }
1348         }
1349
1350         if (!forRender) {
1351                 tex_space_curve(cu);
1352         }
1353
1354         curve_calc_modifiers_post(ob, nubase, dispbase, forRender, originalVerts, deformedVerts);
1355 }
1356
1357 void makeDispListCurveTypes(Object *ob, int forOrco)
1358 {
1359         Curve *cu = ob->data;
1360         ListBase *dispbase;
1361         
1362         /* we do allow duplis... this is only displist on curve level */
1363         if(!ELEM3(ob->type, OB_SURF, OB_CURVE, OB_FONT)) return;
1364
1365         freedisplist(&(ob->disp));
1366         dispbase= &(cu->disp);
1367         freedisplist(dispbase);
1368         
1369         if(ob->type==OB_SURF) {
1370                 makeDispListSurf(ob, dispbase, 0);
1371         }
1372         else if ELEM(ob->type, OB_CURVE, OB_FONT) {
1373                 ListBase dlbev;
1374                 float (*originalVerts)[3];
1375                 float (*deformedVerts)[3];
1376                 int obedit= (G.obedit && G.obedit->data==ob->data && G.obedit->type==OB_CURVE);
1377                 ListBase *nubase = obedit?&editNurb:&cu->nurb;
1378                 int numVerts;
1379
1380                 BLI_freelistN(&(cu->bev));
1381                 
1382                 if(cu->path) free_path(cu->path);
1383                 cu->path= NULL;
1384                 
1385                 if(ob->type==OB_FONT) text_to_curve(ob, 0);
1386                 
1387                 if(!forOrco) curve_calc_modifiers_pre(ob, nubase, 0, &originalVerts, &deformedVerts, &numVerts);
1388
1389                 makeBevelList(ob);
1390
1391                 /* If curve has no bevel will return nothing */
1392                 makebevelcurve(ob, &dlbev);
1393
1394                 /* no bevel or extrude, and no width correction? */
1395                 if (!dlbev.first && cu->width==1.0f) {
1396                         curve_to_displist(cu, nubase, dispbase);
1397                 } else {
1398                         float widfac= cu->width-1.0;
1399                         BevList *bl= cu->bev.first;
1400                         Nurb *nu= nubase->first;
1401
1402                         for (; bl && nu; bl=bl->next,nu=nu->next) {
1403                                 DispList *dl;
1404                                 float *fp1, *data;
1405                                 BevPoint *bevp;
1406                                 int a,b;
1407                                 
1408                                 /* exception handling; curve without bevel or extrude, with width correction */
1409                                 if(dlbev.first==NULL) {
1410                                         dl= MEM_callocN(sizeof(DispList), "makeDispListbev");
1411                                         dl->verts= MEM_callocN(3*sizeof(float)*bl->nr, "dlverts");
1412                                         BLI_addtail(dispbase, dl);
1413                                         
1414                                         if(bl->poly!= -1) dl->type= DL_POLY;
1415                                         else dl->type= DL_SEGM;
1416                                         
1417                                         if(dl->type==DL_SEGM) dl->flag = (DL_FRONT_CURVE|DL_BACK_CURVE);
1418                                         
1419                                         dl->parts= 1;
1420                                         dl->nr= bl->nr;
1421                                         dl->col= nu->mat_nr;
1422                                         dl->charidx= nu->charidx;
1423                                         dl->rt= nu->flag;
1424                                         
1425                                         a= dl->nr;
1426                                         bevp= (BevPoint *)(bl+1);
1427                                         data= dl->verts;
1428                                         while(a--) {
1429                                                 data[0]= bevp->x+widfac*bevp->sina;
1430                                                 data[1]= bevp->y+widfac*bevp->cosa;
1431                                                 data[2]= bevp->z;
1432                                                 bevp++;
1433                                                 data+=3;
1434                                         }
1435                                 }
1436                                 else {
1437                                         DispList *dlb;
1438                                         
1439                                         for (dlb=dlbev.first; dlb; dlb=dlb->next) {
1440
1441                                                         /* for each part of the bevel use a separate displblock */
1442                                                 dl= MEM_callocN(sizeof(DispList), "makeDispListbev1");
1443                                                 dl->verts= data= MEM_callocN(3*sizeof(float)*dlb->nr*bl->nr, "dlverts");
1444                                                 BLI_addtail(dispbase, dl);
1445
1446                                                 dl->type= DL_SURF;
1447                                                 
1448                                                 dl->flag= dlb->flag & (DL_FRONT_CURVE|DL_BACK_CURVE);
1449                                                 if(dlb->type==DL_POLY) dl->flag |= DL_CYCL_U;
1450                                                 if(bl->poly>=0) dl->flag |= DL_CYCL_V;
1451                                                 
1452                                                 dl->parts= bl->nr;
1453                                                 dl->nr= dlb->nr;
1454                                                 dl->col= nu->mat_nr;
1455                                                 dl->charidx= nu->charidx;
1456                                                 dl->rt= nu->flag;
1457                                                 dl->bevelSplitFlag= MEM_callocN(sizeof(*dl->col2)*((bl->nr+0x1F)>>5), "col2");
1458                                                 bevp= (BevPoint *)(bl+1);
1459
1460                                                         /* for each point of poly make a bevel piece */
1461                                                 bevp= (BevPoint *)(bl+1);
1462                                                 for(a=0; a<bl->nr; a++,bevp++) {
1463                                                         float fac=1.0;
1464                                                         if (cu->taperobj==NULL) {
1465                                                                 if ( (cu->bevobj!=NULL) || !((cu->flag & CU_FRONT) || (cu->flag & CU_BACK)) )
1466                                                                 fac = calc_curve_subdiv_radius(cu, nu, a);
1467                                                         } else {
1468                                                                 fac = calc_taper(cu->taperobj, a, bl->nr);
1469                                                         }
1470                                                         
1471                                                         if (bevp->f1) {
1472                                                                 dl->bevelSplitFlag[a>>5] |= 1<<(a&0x1F);
1473                                                         }
1474
1475                                                                 /* rotate bevel piece and write in data */
1476                                                         fp1= dlb->verts;
1477                                                         for (b=0; b<dlb->nr; b++,fp1+=3,data+=3) {
1478                                                                 if(cu->flag & CU_3D) {
1479                                                                         float vec[3];
1480
1481                                                                         vec[0]= fp1[1]+widfac;
1482                                                                         vec[1]= fp1[2];
1483                                                                         vec[2]= 0.0;
1484                                                                         
1485                                                                         Mat3MulVecfl(bevp->mat, vec);
1486                                                                         
1487                                                                         data[0]= bevp->x+ fac*vec[0];
1488                                                                         data[1]= bevp->y+ fac*vec[1];
1489                                                                         data[2]= bevp->z+ fac*vec[2];
1490                                                                 }
1491                                                                 else {
1492                                                                         data[0]= bevp->x+ fac*(widfac+fp1[1])*bevp->sina;
1493                                                                         data[1]= bevp->y+ fac*(widfac+fp1[1])*bevp->cosa;
1494                                                                         data[2]= bevp->z+ fac*fp1[2];
1495                                                                 }
1496                                                         }
1497                                                 }
1498                                         }
1499                                 }
1500
1501                         }
1502                         freedisplist(&dlbev);
1503                 }
1504
1505                 curve_to_filledpoly(cu, nubase, dispbase);
1506
1507                 if(cu->flag & CU_PATH) calc_curvepath(ob);
1508
1509                 if(!forOrco) curve_calc_modifiers_post(ob, nubase, &cu->disp, 0, originalVerts, deformedVerts);
1510                 tex_space_curve(cu);
1511         }
1512         
1513         boundbox_displist(ob);
1514 }
1515
1516 void imagestodisplist(void)
1517 {
1518         /* removed */
1519 }
1520
1521 /* this is confusing, there's also min_max_object, appplying the obmat... */
1522 static void boundbox_displist(Object *ob)
1523 {
1524         BoundBox *bb=0;
1525         float min[3], max[3];
1526         DispList *dl;
1527         float *vert;
1528         int a, tot=0;
1529         
1530         INIT_MINMAX(min, max);
1531
1532         if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
1533                 Curve *cu= ob->data;
1534                 int doit= 0;
1535
1536                 if(cu->bb==0) cu->bb= MEM_callocN(sizeof(BoundBox), "boundbox");        
1537                 bb= cu->bb;
1538                 
1539                 dl= cu->disp.first;
1540
1541                 while (dl) {
1542                         if(dl->type==DL_INDEX3) tot= dl->nr;
1543                         else tot= dl->nr*dl->parts;
1544                         
1545                         vert= dl->verts;
1546                         for(a=0; a<tot; a++, vert+=3) {
1547                                 doit= 1;
1548                                 DO_MINMAX(vert, min, max);
1549                         }
1550
1551                         dl= dl->next;
1552                 }
1553                 
1554                 if(!doit) {
1555                         min[0] = min[1] = min[2] = -1.0f;
1556                         max[0] = max[1] = max[2] = 1.0f;
1557                 }
1558                 
1559         }
1560         
1561         if(bb) {
1562                 boundbox_set_from_min_max(bb, min, max);
1563         }
1564 }
1565
1566 void displistmesh_add_edges(DispListMesh *dlm)
1567 {
1568         EdgeHash *eh = BLI_edgehash_new();
1569         EdgeHashIterator *ehi;
1570         int i;
1571
1572         for (i=0; i<dlm->totface; i++) {
1573                 MFace *mf = &dlm->mface[i];
1574
1575                 if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
1576                         BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
1577                 if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
1578                         BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
1579                 
1580                 if (mf->v4) {
1581                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
1582                                 BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
1583                         if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
1584                                 BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
1585                 } else {
1586                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
1587                                 BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
1588                 }
1589         }
1590
1591         dlm->totedge = BLI_edgehash_size(eh);
1592         dlm->medge = MEM_callocN(dlm->totedge*sizeof(*dlm->medge), "medge");
1593
1594         ehi = BLI_edgehashIterator_new(eh);
1595         for (i=0; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
1596                 MEdge *med = &dlm->medge[i++];
1597
1598                 BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2);
1599
1600                 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
1601         }
1602         BLI_edgehashIterator_free(ehi);
1603
1604         BLI_edgehash_free(eh, NULL);
1605 }