Blender V2.61 - r43446

displist.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00019  * All rights reserved.
00020  *
00021  * The Original Code is: all of this file.
00022  *
00023  * Contributor(s): none yet.
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00033 #include <math.h>
00034 #include <stdio.h>
00035 #include <string.h>
00036 
00037 #include "MEM_guardedalloc.h"
00038 
00039 #include "DNA_curve_types.h"
00040 #include "DNA_meshdata_types.h"
00041 #include "DNA_scene_types.h"
00042 #include "DNA_object_types.h"
00043 #include "DNA_material_types.h"
00044 
00045 #include "BLI_blenlib.h"
00046 #include "BLI_math.h"
00047 #include "BLI_editVert.h"
00048 #include "BLI_scanfill.h"
00049 #include "BLI_utildefines.h"
00050 
00051 #include "BKE_global.h"
00052 #include "BKE_displist.h"
00053 #include "BKE_cdderivedmesh.h"
00054 #include "BKE_object.h"
00055 #include "BKE_mball.h"
00056 #include "BKE_material.h"
00057 #include "BKE_curve.h"
00058 #include "BKE_key.h"
00059 #include "BKE_anim.h"
00060 #include "BKE_font.h"
00061 #include "BKE_lattice.h"
00062 #include "BKE_modifier.h"
00063 
00064 #include "BLO_sys_types.h" // for intptr_t support
00065 
00066 extern Material defmaterial;    /* material.c */
00067 
00068 static void boundbox_displist(Object *ob);
00069 
00070 void free_disp_elem(DispList *dl)
00071 {
00072     if(dl) {
00073         if(dl->verts) MEM_freeN(dl->verts);
00074         if(dl->nors) MEM_freeN(dl->nors);
00075         if(dl->index) MEM_freeN(dl->index);
00076         if(dl->col1) MEM_freeN(dl->col1);
00077         if(dl->col2) MEM_freeN(dl->col2);
00078         if(dl->bevelSplitFlag) MEM_freeN(dl->bevelSplitFlag);
00079         MEM_freeN(dl);
00080     }
00081 }
00082 
00083 void freedisplist(ListBase *lb)
00084 {
00085     DispList *dl;
00086 
00087     dl= lb->first;
00088     while(dl) {
00089         BLI_remlink(lb, dl);
00090         free_disp_elem(dl);
00091         dl= lb->first;
00092     }
00093 }
00094 
00095 DispList *find_displist_create(ListBase *lb, int type)
00096 {
00097     DispList *dl;
00098     
00099     dl= lb->first;
00100     while(dl) {
00101         if(dl->type==type) return dl;
00102         dl= dl->next;
00103     }
00104 
00105     dl= MEM_callocN(sizeof(DispList), "find_disp");
00106     dl->type= type;
00107     BLI_addtail(lb, dl);
00108 
00109     return dl;
00110 }
00111 
00112 DispList *find_displist(ListBase *lb, int type)
00113 {
00114     DispList *dl;
00115     
00116     dl= lb->first;
00117     while(dl) {
00118         if(dl->type==type) return dl;
00119         dl= dl->next;
00120     }
00121 
00122     return NULL;
00123 }
00124 
00125 int displist_has_faces(ListBase *lb)
00126 {
00127     DispList *dl;
00128     for(dl= lb->first; dl; dl= dl->next) {
00129         if ELEM3(dl->type, DL_INDEX3, DL_INDEX4, DL_SURF)
00130             return 1;
00131     }
00132     return 0;
00133 }
00134 
00135 void copy_displist(ListBase *lbn, ListBase *lb)
00136 {
00137     DispList *dln, *dl;
00138     
00139     freedisplist(lbn);
00140     
00141     dl= lb->first;
00142     while(dl) {
00143         
00144         dln= MEM_dupallocN(dl);
00145         BLI_addtail(lbn, dln);
00146         dln->verts= MEM_dupallocN(dl->verts);
00147         dln->nors= MEM_dupallocN(dl->nors);
00148         dln->index= MEM_dupallocN(dl->index);
00149         dln->col1= MEM_dupallocN(dl->col1);
00150         dln->col2= MEM_dupallocN(dl->col2);
00151 
00152         if(dl->bevelSplitFlag)
00153             dln->bevelSplitFlag= MEM_dupallocN(dl->bevelSplitFlag);
00154 
00155         dl= dl->next;
00156     }
00157 }
00158 
00159 void addnormalsDispList(ListBase *lb)
00160 {
00161     DispList *dl = NULL;
00162     float *vdata, *ndata, nor[3];
00163     float *v1, *v2, *v3, *v4;
00164     float *n1, *n2, *n3, *n4;
00165     int a, b, p1, p2, p3, p4;
00166 
00167 
00168     dl= lb->first;
00169     
00170     while(dl) {
00171         if(dl->type==DL_INDEX3) {
00172             if(dl->nors==NULL) {
00173                 dl->nors= MEM_callocN(sizeof(float)*3, "dlnors");
00174                 if(dl->verts[2] < 0.0f) dl->nors[2]= -1.0f;
00175                 else dl->nors[2]= 1.0f;
00176             }
00177         }
00178         else if(dl->type==DL_SURF) {
00179             if(dl->nors==NULL) {
00180                 dl->nors= MEM_callocN(sizeof(float)*3*dl->nr*dl->parts, "dlnors");
00181                 
00182                 vdata= dl->verts;
00183                 ndata= dl->nors;
00184                 
00185                 for(a=0; a<dl->parts; a++) {
00186                     
00187                     if (surfindex_displist(dl, a, &b, &p1, &p2, &p3, &p4)==0)
00188                         break;
00189     
00190                     v1= vdata+ 3*p1; 
00191                     n1= ndata+ 3*p1;
00192                     v2= vdata+ 3*p2; 
00193                     n2= ndata+ 3*p2;
00194                     v3= vdata+ 3*p3; 
00195                     n3= ndata+ 3*p3;
00196                     v4= vdata+ 3*p4; 
00197                     n4= ndata+ 3*p4;
00198                     
00199                     for(; b<dl->nr; b++) {
00200     
00201                         normal_quad_v3( nor,v1, v3, v4, v2);
00202     
00203                         add_v3_v3(n1, nor);
00204                         add_v3_v3(n2, nor);
00205                         add_v3_v3(n3, nor);
00206                         add_v3_v3(n4, nor);
00207     
00208                         v2= v1; v1+= 3;
00209                         v4= v3; v3+= 3;
00210                         n2= n1; n1+= 3;
00211                         n4= n3; n3+= 3;
00212                     }
00213                 }
00214                 a= dl->parts*dl->nr;
00215                 v1= ndata;
00216                 while(a--) {
00217                     normalize_v3(v1);
00218                     v1+= 3;
00219                 }
00220             }
00221         }
00222         dl= dl->next;
00223     }
00224 }
00225 
00226 void count_displist(ListBase *lb, int *totvert, int *totface)
00227 {
00228     DispList *dl;
00229     
00230     dl= lb->first;
00231     while(dl) {
00232         
00233         switch(dl->type) {
00234             case DL_SURF:
00235                 *totvert+= dl->nr*dl->parts;
00236                 *totface+= (dl->nr-1)*(dl->parts-1);
00237                 break;
00238             case DL_INDEX3:
00239             case DL_INDEX4:
00240                 *totvert+= dl->nr;
00241                 *totface+= dl->parts;
00242                 break;
00243             case DL_POLY:
00244             case DL_SEGM:
00245                 *totvert+= dl->nr*dl->parts;
00246         }
00247         
00248         dl= dl->next;
00249     }
00250 }
00251 
00252 int surfindex_displist(DispList *dl, int a, int *b, int *p1, int *p2, int *p3, int *p4)
00253 {
00254     if((dl->flag & DL_CYCL_V)==0 && a==(dl->parts)-1) {
00255         return 0;
00256     }
00257     
00258     if(dl->flag & DL_CYCL_U) {
00259         (*p1)= dl->nr*a;
00260         (*p2)= (*p1)+ dl->nr-1;
00261         (*p3)= (*p1)+ dl->nr;
00262         (*p4)= (*p2)+ dl->nr;
00263         (*b)= 0;
00264     } else {
00265         (*p2)= dl->nr*a;
00266         (*p1)= (*p2)+1;
00267         (*p4)= (*p2)+ dl->nr;
00268         (*p3)= (*p1)+ dl->nr;
00269         (*b)= 1;
00270     }
00271     
00272     if( (dl->flag & DL_CYCL_V) && a==dl->parts-1) {
00273         (*p3)-= dl->nr*dl->parts;
00274         (*p4)-= dl->nr*dl->parts;
00275     }
00276     
00277     return 1;
00278 }
00279 
00280 /* ****************** make displists ********************* */
00281 
00282 static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase, int forRender)
00283 {
00284     Nurb *nu;
00285     DispList *dl;
00286     BezTriple *bezt, *prevbezt;
00287     BPoint *bp;
00288     float *data;
00289     int a, len, resolu;
00290     
00291     nu= nubase->first;
00292     while(nu) {
00293         if(nu->hide==0) {
00294             
00295             if(forRender && cu->resolu_ren!=0)
00296                 resolu= cu->resolu_ren;
00297             else
00298                 resolu= nu->resolu;
00299             
00300             if(!check_valid_nurb_u(nu));
00301             else if(nu->type == CU_BEZIER) {
00302                 
00303                 /* count */
00304                 len= 0;
00305                 a= nu->pntsu-1;
00306                 if(nu->flagu & CU_NURB_CYCLIC) a++;
00307 
00308                 prevbezt= nu->bezt;
00309                 bezt= prevbezt+1;
00310                 while(a--) {
00311                     if(a==0 && (nu->flagu & CU_NURB_CYCLIC)) bezt= nu->bezt;
00312                     
00313                     if(prevbezt->h2==HD_VECT && bezt->h1==HD_VECT) len++;
00314                     else len+= resolu;
00315                     
00316                     if(a==0 && (nu->flagu & CU_NURB_CYCLIC)==0) len++;
00317                     
00318                     prevbezt= bezt;
00319                     bezt++;
00320                 }
00321                 
00322                 dl= MEM_callocN(sizeof(DispList), "makeDispListbez");
00323                 /* len+1 because of 'forward_diff_bezier' function */
00324                 dl->verts= MEM_callocN( (len+1)*3*sizeof(float), "dlverts");
00325                 BLI_addtail(dispbase, dl);
00326                 dl->parts= 1;
00327                 dl->nr= len;
00328                 dl->col= nu->mat_nr;
00329                 dl->charidx= nu->charidx;
00330 
00331                 data= dl->verts;
00332 
00333                 if(nu->flagu & CU_NURB_CYCLIC) {
00334                     dl->type= DL_POLY;
00335                     a= nu->pntsu;
00336                 }
00337                 else {
00338                     dl->type= DL_SEGM;
00339                     a= nu->pntsu-1;
00340                 }
00341                 
00342                 prevbezt= nu->bezt;
00343                 bezt= prevbezt+1;
00344                 
00345                 while(a--) {
00346                     if(a==0 && dl->type== DL_POLY) bezt= nu->bezt;
00347                     
00348                     if(prevbezt->h2==HD_VECT && bezt->h1==HD_VECT) {
00349                         copy_v3_v3(data, prevbezt->vec[1]);
00350                         data+= 3;
00351                     }
00352                     else {
00353                         int j;
00354                         for(j=0; j<3; j++) {
00355                             forward_diff_bezier(    prevbezt->vec[1][j],
00356                                                     prevbezt->vec[2][j],
00357                                                     bezt->vec[0][j],
00358                                                     bezt->vec[1][j],
00359                                                     data+j, resolu, 3*sizeof(float));
00360                         }
00361                         
00362                         data+= 3*resolu;
00363                     }
00364                     
00365                     if(a==0 && dl->type==DL_SEGM) {
00366                         copy_v3_v3(data, bezt->vec[1]);
00367                     }
00368                     
00369                     prevbezt= bezt;
00370                     bezt++;
00371                 }
00372             }
00373             else if(nu->type == CU_NURBS) {
00374                 len= (resolu*SEGMENTSU(nu));
00375                 
00376                 dl= MEM_callocN(sizeof(DispList), "makeDispListsurf");
00377                 dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
00378                 BLI_addtail(dispbase, dl);
00379                 dl->parts= 1;
00380                 
00381                 dl->nr= len;
00382                 dl->col= nu->mat_nr;
00383                 dl->charidx = nu->charidx;
00384 
00385                 data= dl->verts;
00386                 if(nu->flagu & CU_NURB_CYCLIC) dl->type= DL_POLY;
00387                 else dl->type= DL_SEGM;
00388                 makeNurbcurve(nu, data, NULL, NULL, NULL, resolu, 3*sizeof(float));
00389             }
00390             else if(nu->type == CU_POLY) {
00391                 len= nu->pntsu;
00392                 dl= MEM_callocN(sizeof(DispList), "makeDispListpoly");
00393                 dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
00394                 BLI_addtail(dispbase, dl);
00395                 dl->parts= 1;
00396                 dl->nr= len;
00397                 dl->col= nu->mat_nr;
00398                 dl->charidx = nu->charidx;
00399 
00400                 data= dl->verts;
00401                 if(nu->flagu & CU_NURB_CYCLIC) dl->type= DL_POLY;
00402                 else dl->type= DL_SEGM;
00403                 
00404                 a= len;
00405                 bp= nu->bp;
00406                 while(a--) {
00407                     copy_v3_v3(data, bp->vec);
00408                     bp++;
00409                     data+= 3;
00410                 }
00411             }
00412         }
00413         nu= nu->next;
00414     }
00415 }
00416 
00417 
00418 void filldisplist(ListBase *dispbase, ListBase *to, int flipnormal)
00419 {
00420     EditVert *eve, *v1, *vlast;
00421     EditFace *efa;
00422     DispList *dlnew=NULL, *dl;
00423     float *f1;
00424     int colnr=0, charidx=0, cont=1, tot, a, *index, nextcol= 0;
00425     intptr_t totvert;
00426     
00427     if(dispbase==NULL) return;
00428     if(dispbase->first==NULL) return;
00429 
00430     while(cont) {
00431         cont= 0;
00432         totvert= 0;
00433         nextcol= 0;
00434         
00435         dl= dispbase->first;
00436         while(dl) {
00437     
00438             if(dl->type==DL_POLY) {
00439                 if(charidx<dl->charidx) cont= 1;
00440                 else if(charidx==dl->charidx) { /* character with needed index */
00441                     if(colnr==dl->col) {
00442                         /* make editverts and edges */
00443                         f1= dl->verts;
00444                         a= dl->nr;
00445                         eve= v1= NULL;
00446                         
00447                         while(a--) {
00448                             vlast= eve;
00449 
00450                             eve= BLI_addfillvert(f1);
00451                             totvert++;
00452 
00453                             if(vlast==NULL) v1= eve;
00454                             else {
00455                                 BLI_addfilledge(vlast, eve);
00456                             }
00457                             f1+=3;
00458                         }
00459 
00460                         if(eve!=NULL && v1!=NULL) {
00461                             BLI_addfilledge(eve, v1);
00462                         }
00463                     } else if (colnr<dl->col) {
00464                         /* got poly with next material at current char */
00465                         cont= 1;
00466                         nextcol= 1;
00467                     }
00468                 }
00469             }
00470             dl= dl->next;
00471         }
00472         
00473         if(totvert && (tot= BLI_edgefill(0))) { // XXX (obedit && obedit->actcol)?(obedit->actcol-1):0)) {
00474             if(tot) {
00475                 dlnew= MEM_callocN(sizeof(DispList), "filldisplist");
00476                 dlnew->type= DL_INDEX3;
00477                 dlnew->col= colnr;
00478                 dlnew->nr= totvert;
00479                 dlnew->parts= tot;
00480 
00481                 dlnew->index= MEM_mallocN(tot*3*sizeof(int), "dlindex");
00482                 dlnew->verts= MEM_mallocN(totvert*3*sizeof(float), "dlverts");
00483                 
00484                 /* vert data */
00485                 f1= dlnew->verts;
00486                 totvert= 0;
00487                 eve= fillvertbase.first;
00488                 while(eve) {
00489                     copy_v3_v3(f1, eve->co);
00490                     f1+= 3;
00491     
00492                     /* index number */
00493                     eve->tmp.l = totvert;
00494                     totvert++;
00495                     
00496                     eve= eve->next;
00497                 }
00498                 
00499                 /* index data */
00500                 efa= fillfacebase.first;
00501                 index= dlnew->index;
00502                 while(efa) {
00503                     index[0]= (intptr_t)efa->v1->tmp.l;
00504                     index[1]= (intptr_t)efa->v2->tmp.l;
00505                     index[2]= (intptr_t)efa->v3->tmp.l;
00506 
00507                     if(flipnormal)
00508                         SWAP(int, index[0], index[2]);
00509                     
00510                     index+= 3;
00511                     efa= efa->next;
00512                 }
00513             }
00514 
00515             BLI_addhead(to, dlnew);
00516             
00517         }
00518         BLI_end_edgefill();
00519 
00520         if(nextcol) {
00521             /* stay at current char but fill polys with next material */
00522             colnr++;
00523         } else {
00524             /* switch to next char and start filling from first material */
00525             charidx++;
00526             colnr= 0;
00527         }
00528     }
00529     
00530     /* do not free polys, needed for wireframe display */
00531     
00532 }
00533 
00534 static void bevels_to_filledpoly(Curve *cu, ListBase *dispbase)
00535 {
00536     ListBase front, back;
00537     DispList *dl, *dlnew;
00538     float *fp, *fp1;
00539     int a, dpoly;
00540     
00541     front.first= front.last= back.first= back.last= NULL;
00542     
00543     dl= dispbase->first;
00544     while(dl) {
00545         if(dl->type==DL_SURF) {
00546             if( (dl->flag & DL_CYCL_V) && (dl->flag & DL_CYCL_U)==0 ) {
00547                 if( (cu->flag & CU_BACK) && (dl->flag & DL_BACK_CURVE) ) {
00548                     dlnew= MEM_callocN(sizeof(DispList), "filldisp");
00549                     BLI_addtail(&front, dlnew);
00550                     dlnew->verts= fp1= MEM_mallocN(sizeof(float)*3*dl->parts, "filldisp1");
00551                     dlnew->nr= dl->parts;
00552                     dlnew->parts= 1;
00553                     dlnew->type= DL_POLY;
00554                     dlnew->col= dl->col;
00555                     dlnew->charidx = dl->charidx;
00556                     
00557                     fp= dl->verts;
00558                     dpoly= 3*dl->nr;
00559                     
00560                     a= dl->parts;
00561                     while(a--) {
00562                         copy_v3_v3(fp1, fp);
00563                         fp1+= 3;
00564                         fp+= dpoly;
00565                     }
00566                 }
00567                 if( (cu->flag & CU_FRONT) && (dl->flag & DL_FRONT_CURVE) ) {
00568                     dlnew= MEM_callocN(sizeof(DispList), "filldisp");
00569                     BLI_addtail(&back, dlnew);
00570                     dlnew->verts= fp1= MEM_mallocN(sizeof(float)*3*dl->parts, "filldisp1");
00571                     dlnew->nr= dl->parts;
00572                     dlnew->parts= 1;
00573                     dlnew->type= DL_POLY;
00574                     dlnew->col= dl->col;
00575                     dlnew->charidx= dl->charidx;
00576                     
00577                     fp= dl->verts+3*(dl->nr-1);
00578                     dpoly= 3*dl->nr;
00579                     
00580                     a= dl->parts;
00581                     while(a--) {
00582                         copy_v3_v3(fp1, fp);
00583                         fp1+= 3;
00584                         fp+= dpoly;
00585                     }
00586                 }
00587             }
00588         }
00589         dl= dl->next;
00590     }
00591 
00592     filldisplist(&front, dispbase, 1);
00593     filldisplist(&back, dispbase, 0);
00594     
00595     freedisplist(&front);
00596     freedisplist(&back);
00597 
00598     filldisplist(dispbase, dispbase, 0);
00599     
00600 }
00601 
00602 static void curve_to_filledpoly(Curve *cu, ListBase *UNUSED(nurb), ListBase *dispbase)
00603 {
00604     if(cu->flag & CU_3D) return;
00605 
00606     if(dispbase->first && ((DispList*) dispbase->first)->type==DL_SURF) {
00607         bevels_to_filledpoly(cu, dispbase);
00608     }
00609     else {
00610         filldisplist(dispbase, dispbase, 0);
00611     }
00612 }
00613 
00614 /* taper rules:
00615   - only 1 curve
00616   - first point left, last point right
00617   - based on subdivided points in original curve, not on points in taper curve (still)
00618 */
00619 float calc_taper(Scene *scene, Object *taperobj, int cur, int tot)
00620 {
00621     DispList *dl;
00622     
00623     if(taperobj==NULL || taperobj->type!=OB_CURVE) return 1.0;
00624     
00625     dl= taperobj->disp.first;
00626     if(dl==NULL) {
00627         makeDispListCurveTypes(scene, taperobj, 0);
00628         dl= taperobj->disp.first;
00629     }
00630     if(dl) {
00631         float fac= ((float)cur)/(float)(tot-1);
00632         float minx, dx, *fp;
00633         int a;
00634         
00635         /* horizontal size */
00636         minx= dl->verts[0];
00637         dx= dl->verts[3*(dl->nr-1)] - minx;
00638         if(dx > 0.0f) {
00639         
00640             fp= dl->verts;
00641             for(a=0; a<dl->nr; a++, fp+=3) {
00642                 if( (fp[0]-minx)/dx >= fac) {
00643                     /* interpolate with prev */
00644                     if(a>0) {
00645                         float fac1= (fp[-3]-minx)/dx;
00646                         float fac2= (fp[0]-minx)/dx;
00647                         if(fac1!=fac2)
00648                             return fp[1]*(fac1-fac)/(fac1-fac2) + fp[-2]*(fac-fac2)/(fac1-fac2);
00649                     }
00650                     return fp[1];
00651                 }
00652             }
00653             return fp[-2];  // last y coord
00654         }
00655     }
00656     
00657     return 1.0;
00658 }
00659 
00660 void makeDispListMBall(Scene *scene, Object *ob)
00661 {
00662     if(!ob || ob->type!=OB_MBALL) return;
00663 
00664     // XXX: mball stuff uses plenty of global variables
00665     //      while this is unchanged updating during render is unsafe
00666     if(G.rendering) return;
00667 
00668     freedisplist(&(ob->disp));
00669 
00670     if(ob->type==OB_MBALL) {
00671         if(ob==find_basis_mball(scene, ob)) {
00672             metaball_polygonize(scene, ob, &ob->disp);
00673             tex_space_mball(ob);
00674 
00675             object_deform_mball(ob, &ob->disp);
00676         }
00677     }
00678     
00679     boundbox_displist(ob);
00680 }
00681 
00682 void makeDispListMBall_forRender(Scene *scene, Object *ob, ListBase *dispbase)
00683 {
00684     metaball_polygonize(scene, ob, dispbase);
00685     tex_space_mball(ob);
00686     
00687     object_deform_mball(ob, dispbase);
00688 }
00689 
00690 static ModifierData *curve_get_tesselate_point(Scene *scene, Object *ob, int forRender, int editmode)
00691 {
00692     ModifierData *md = modifiers_getVirtualModifierList(ob);
00693     ModifierData *preTesselatePoint;
00694     int required_mode;
00695 
00696     if(forRender) required_mode = eModifierMode_Render;
00697     else required_mode = eModifierMode_Realtime;
00698 
00699     if(editmode) required_mode |= eModifierMode_Editmode;
00700 
00701     preTesselatePoint = NULL;
00702     for (; md; md=md->next) {
00703         ModifierTypeInfo *mti = modifierType_getInfo(md->type);
00704 
00705         if (!modifier_isEnabled(scene, md, required_mode)) continue;
00706         if (mti->type == eModifierTypeType_Constructive) return preTesselatePoint;
00707 
00708         if (ELEM3(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_MeshDeform)) {
00709             preTesselatePoint = md;
00710 
00711             /* this modifiers are moving point of tesselation automatically
00712                (some of them even can't be applied on tesselated curve), set flag
00713                for incformation button in modifier's header */
00714             md->mode |= eModifierMode_ApplyOnSpline;
00715         } else if(md->mode&eModifierMode_ApplyOnSpline) {
00716             preTesselatePoint = md;
00717         }
00718     }
00719 
00720     return preTesselatePoint;
00721 }
00722 
00723 static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, float (**originalVerts_r)[3], float (**deformedVerts_r)[3], int *numVerts_r)
00724 {
00725     ModifierData *md = modifiers_getVirtualModifierList(ob);
00726     ModifierData *preTesselatePoint;
00727     Curve *cu= ob->data;
00728     ListBase *nurb= BKE_curve_nurbs(cu);
00729     int numVerts = 0;
00730     int editmode = (!forRender && cu->editnurb);
00731     float (*originalVerts)[3] = NULL;
00732     float (*deformedVerts)[3] = NULL;
00733     float *keyVerts= NULL;
00734     int required_mode;
00735 
00736     if(forRender) required_mode = eModifierMode_Render;
00737     else required_mode = eModifierMode_Realtime;
00738 
00739     preTesselatePoint = curve_get_tesselate_point(scene, ob, forRender, editmode);
00740     
00741     if(editmode) required_mode |= eModifierMode_Editmode;
00742 
00743     if(cu->editnurb==NULL) {
00744         keyVerts= do_ob_key(scene, ob);
00745 
00746         if(keyVerts) {
00747             /* split coords from key data, the latter also includes
00748                tilts, which is passed through in the modifier stack.
00749                this is also the reason curves do not use a virtual
00750                shape key modifier yet. */
00751             deformedVerts= curve_getKeyVertexCos(cu, nurb, keyVerts);
00752             originalVerts= MEM_dupallocN(deformedVerts);
00753         }
00754     }
00755     
00756     if (preTesselatePoint) {
00757         for (; md; md=md->next) {
00758             ModifierTypeInfo *mti = modifierType_getInfo(md->type);
00759 
00760             md->scene= scene;
00761             
00762             if ((md->mode & required_mode) != required_mode) continue;
00763             if (mti->isDisabled && mti->isDisabled(md, forRender)) continue;
00764             if (mti->type!=eModifierTypeType_OnlyDeform) continue;
00765 
00766             if (!deformedVerts) {
00767                 deformedVerts = curve_getVertexCos(cu, nurb, &numVerts);
00768                 originalVerts = MEM_dupallocN(deformedVerts);
00769             }
00770 
00771             mti->deformVerts(md, ob, NULL, deformedVerts, numVerts, forRender, editmode);
00772 
00773             if (md==preTesselatePoint)
00774                 break;
00775         }
00776     }
00777 
00778     if (deformedVerts)
00779         curve_applyVertexCos(cu, nurb, deformedVerts);
00780     if (keyVerts) /* these are not passed through modifier stack */
00781         curve_applyKeyVertexTilts(cu, nurb, keyVerts);
00782 
00783     if(keyVerts)
00784         MEM_freeN(keyVerts);
00785 
00786     *originalVerts_r = originalVerts;
00787     *deformedVerts_r = deformedVerts;
00788     *numVerts_r = numVerts;
00789 }
00790 
00791 static float (*displist_get_allverts (ListBase *dispbase, int *totvert))[3]
00792 {
00793     DispList *dl;
00794     float (*allverts)[3], *fp;
00795 
00796     *totvert= 0;
00797 
00798     for (dl=dispbase->first; dl; dl=dl->next)
00799         *totvert+= (dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr;
00800 
00801     allverts= MEM_mallocN((*totvert)*sizeof(float)*3, "displist_get_allverts allverts");
00802     fp= (float*)allverts;
00803     for (dl=dispbase->first; dl; dl=dl->next) {
00804         int offs= 3 * ((dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr);
00805         memcpy(fp, dl->verts, sizeof(float) * offs);
00806         fp+= offs;
00807     }
00808 
00809     return allverts;
00810 }
00811 
00812 static void displist_apply_allverts(ListBase *dispbase, float (*allverts)[3])
00813 {
00814     DispList *dl;
00815     float *fp;
00816 
00817     fp= (float*)allverts;
00818     for (dl=dispbase->first; dl; dl=dl->next) {
00819         int offs= 3 * ((dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr);
00820         memcpy(dl->verts, fp, sizeof(float) * offs);
00821         fp+= offs;
00822     }
00823 }
00824 
00825 static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispbase,
00826     DerivedMesh **derivedFinal, int forRender, float (*originalVerts)[3], float (*deformedVerts)[3])
00827 {
00828     ModifierData *md = modifiers_getVirtualModifierList(ob);
00829     ModifierData *preTesselatePoint;
00830     Curve *cu= ob->data;
00831     ListBase *nurb= BKE_curve_nurbs(cu);
00832     int required_mode = 0, totvert = 0;
00833     int editmode = (!forRender && cu->editnurb);
00834     DerivedMesh *dm= NULL, *ndm;
00835     float (*vertCos)[3] = NULL;
00836 
00837     if(forRender) required_mode = eModifierMode_Render;
00838     else required_mode = eModifierMode_Realtime;
00839 
00840     preTesselatePoint = curve_get_tesselate_point(scene, ob, forRender, editmode);
00841     
00842     if(editmode) required_mode |= eModifierMode_Editmode;
00843 
00844     if (preTesselatePoint) {
00845         md = preTesselatePoint->next;
00846     }
00847 
00848     if (derivedFinal && *derivedFinal) {
00849         (*derivedFinal)->release (*derivedFinal);
00850     }
00851 
00852     for (; md; md=md->next) {
00853         ModifierTypeInfo *mti = modifierType_getInfo(md->type);
00854 
00855         md->scene= scene;
00856 
00857         if ((md->mode & required_mode) != required_mode) continue;
00858         if (mti->isDisabled && mti->isDisabled(md, forRender)) continue;
00859 
00860         if (mti->type == eModifierTypeType_OnlyDeform ||
00861                 (mti->type == eModifierTypeType_DeformOrConstruct && !dm)) {
00862             if (dm) {
00863                 if (!vertCos) {
00864                     totvert = dm->getNumVerts(dm);
00865                     vertCos = MEM_mallocN(sizeof(*vertCos) * totvert, "dfmv");
00866                     dm->getVertCos(dm, vertCos);
00867                 }
00868 
00869                 mti->deformVerts(md, ob, dm, vertCos, totvert, forRender, editmode);
00870             } else {
00871                 if (!vertCos) {
00872                     vertCos= displist_get_allverts(dispbase, &totvert);
00873                 }
00874 
00875                 mti->deformVerts(md, ob, NULL, vertCos, totvert, forRender, editmode);
00876             }
00877         } else {
00878             if (!derivedFinal) {
00879                 /* makeDisplistCurveTypes could be used for beveling, where derived mesh */
00880                 /* is totally unnecessary, so we could stop modifiers applying */
00881                 /* when we found constructive modifier but derived mesh is unwanted result */
00882                 break;
00883             }
00884 
00885             if (dm) {
00886                 if (vertCos) {
00887                     DerivedMesh *tdm = CDDM_copy(dm);
00888                     dm->release(dm);
00889                     dm = tdm;
00890 
00891                     CDDM_apply_vert_coords(dm, vertCos);
00892                     CDDM_calc_normals(dm);
00893                 }
00894             } else {
00895                 if (vertCos) {
00896                     displist_apply_allverts(dispbase, vertCos);
00897                 }
00898 
00899                 if (ELEM(ob->type, OB_CURVE, OB_FONT) && (cu->flag & CU_DEFORM_FILL)) {
00900                     curve_to_filledpoly(cu, nurb, dispbase);
00901                 }
00902 
00903                 dm= CDDM_from_curve_customDB(ob, dispbase);
00904 
00905                 CDDM_calc_normals(dm);
00906             }
00907 
00908             if (vertCos) {
00909                 /* Vertex coordinates were applied to necessary data, could free it */
00910                 MEM_freeN(vertCos);
00911                 vertCos= NULL;
00912             }
00913 
00914             ndm = mti->applyModifier(md, ob, dm, forRender, editmode);
00915 
00916             if (ndm) {
00917                 /* Modifier returned a new derived mesh */
00918 
00919                 if (dm && dm != ndm) /* Modifier  */
00920                     dm->release (dm);
00921                 dm = ndm;
00922             }
00923         }
00924     }
00925 
00926     if (vertCos) {
00927         if (dm) {
00928             DerivedMesh *tdm = CDDM_copy(dm);
00929             dm->release(dm);
00930             dm = tdm;
00931 
00932             CDDM_apply_vert_coords(dm, vertCos);
00933             CDDM_calc_normals(dm);
00934             MEM_freeN(vertCos);
00935         } else {
00936             displist_apply_allverts(dispbase, vertCos);
00937             MEM_freeN(vertCos);
00938             vertCos= NULL;
00939         }
00940     }
00941 
00942     if (derivedFinal) {
00943         (*derivedFinal) = dm;
00944     }
00945 
00946     if (deformedVerts) {
00947         curve_applyVertexCos(ob->data, nurb, originalVerts);
00948         MEM_freeN(originalVerts);
00949         MEM_freeN(deformedVerts);
00950     }
00951 }
00952 
00953 static void displist_surf_indices(DispList *dl)
00954 {
00955     int a, b, p1, p2, p3, p4;
00956     int *index;
00957     
00958     dl->totindex= 0;
00959     
00960     index=dl->index= MEM_mallocN( 4*sizeof(int)*(dl->parts+1)*(dl->nr+1), "index array nurbs");
00961     
00962     for(a=0; a<dl->parts; a++) {
00963         
00964         if (surfindex_displist(dl, a, &b, &p1, &p2, &p3, &p4)==0)
00965             break;
00966         
00967         for(; b<dl->nr; b++, index+=4) {    
00968             index[0]= p1;
00969             index[1]= p2;
00970             index[2]= p4;
00971             index[3]= p3;
00972             
00973             dl->totindex++;
00974             
00975             p2= p1; p1++;
00976             p4= p3; p3++;
00977 
00978         }
00979     }
00980     
00981 }
00982 
00983 static DerivedMesh *create_orco_dm(Scene *scene, Object *ob)
00984 {
00985     DerivedMesh *dm;
00986     ListBase disp= {NULL, NULL};
00987 
00988     /* OrcoDM should be created from underformed disp lists */
00989     makeDispListCurveTypes_forOrco(scene, ob, &disp);
00990     dm= CDDM_from_curve_customDB(ob, &disp);
00991 
00992     freedisplist(&disp);
00993 
00994     return dm;
00995 }
00996 
00997 static void add_orco_dm(Scene *scene, Object *ob, DerivedMesh *dm, DerivedMesh *orcodm)
00998 {
00999     float (*orco)[3], (*layerorco)[3];
01000     int totvert, a;
01001     Curve *cu= ob->data;
01002 
01003     totvert= dm->getNumVerts(dm);
01004 
01005     if(orcodm) {
01006         orco= MEM_callocN(sizeof(float)*3*totvert, "dm orco");
01007 
01008         if(orcodm->getNumVerts(orcodm) == totvert)
01009             orcodm->getVertCos(orcodm, orco);
01010         else
01011             dm->getVertCos(dm, orco);
01012     }
01013     else {
01014         orco= (float(*)[3])make_orco_curve(scene, ob);
01015     }
01016 
01017     for(a=0; a<totvert; a++) {
01018         float *co = orco[a];
01019         co[0] = (co[0]-cu->loc[0])/cu->size[0];
01020         co[1] = (co[1]-cu->loc[1])/cu->size[1];
01021         co[2] = (co[2]-cu->loc[2])/cu->size[2];
01022     }
01023 
01024     if((layerorco = DM_get_vert_data_layer(dm, CD_ORCO))) {
01025         memcpy(layerorco, orco, sizeof(float)*totvert);
01026         MEM_freeN(orco);
01027     }
01028     else
01029         DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, orco);
01030 }
01031 
01032 static void curve_calc_orcodm(Scene *scene, Object *ob, DerivedMesh *derivedFinal, int forRender)
01033 {
01034     /* this function represents logic of mesh's orcodm calculation */
01035     /* for displist-based objects */
01036 
01037     ModifierData *md = modifiers_getVirtualModifierList(ob);
01038     ModifierData *preTesselatePoint;
01039     Curve *cu= ob->data;
01040     int required_mode;
01041     int editmode = (!forRender && cu->editnurb);
01042     DerivedMesh *ndm, *orcodm= NULL;
01043 
01044     if(forRender) required_mode = eModifierMode_Render;
01045     else required_mode = eModifierMode_Realtime;
01046 
01047     preTesselatePoint = curve_get_tesselate_point(scene, ob, forRender, editmode);
01048 
01049     if(editmode) required_mode |= eModifierMode_Editmode;
01050 
01051     if (preTesselatePoint) {
01052         md = preTesselatePoint->next;
01053     }
01054 
01055     for (; md; md=md->next) {
01056         ModifierTypeInfo *mti = modifierType_getInfo(md->type);
01057 
01058         md->scene= scene;
01059 
01060         if ((md->mode & required_mode) != required_mode) continue;
01061         if (mti->isDisabled && mti->isDisabled(md, forRender)) continue;
01062         if (mti->type!=eModifierTypeType_Constructive) continue;
01063 
01064         if(!orcodm)
01065             orcodm= create_orco_dm(scene, ob);
01066 
01067         ndm = mti->applyModifier(md, ob, orcodm, forRender, 0);
01068 
01069         if(ndm) {
01070             /* if the modifier returned a new dm, release the old one */
01071             if(orcodm && orcodm != ndm) {
01072                 orcodm->release(orcodm);
01073             }
01074             orcodm = ndm;
01075         }
01076     }
01077 
01078     /* add an orco layer if needed */
01079     add_orco_dm(scene, ob, derivedFinal, orcodm);
01080 
01081     if(orcodm)
01082         orcodm->release(orcodm);
01083 }
01084 
01085 void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase,
01086     DerivedMesh **derivedFinal, int forRender, int forOrco)
01087 {
01088     ListBase *nubase;
01089     Nurb *nu;
01090     Curve *cu = ob->data;
01091     DispList *dl;
01092     float *data;
01093     int len;
01094     int numVerts;
01095     float (*originalVerts)[3];
01096     float (*deformedVerts)[3];
01097 
01098     if(!forRender && cu->editnurb)
01099         nubase= curve_editnurbs(cu);
01100     else
01101         nubase= &cu->nurb;
01102 
01103     if(!forOrco)
01104         curve_calc_modifiers_pre(scene, ob, forRender, &originalVerts, &deformedVerts, &numVerts);
01105 
01106     for (nu=nubase->first; nu; nu=nu->next) {
01107         if(forRender || nu->hide==0) {
01108             int resolu= nu->resolu, resolv= nu->resolv;
01109 
01110             if(forRender){
01111                 if(cu->resolu_ren) resolu= cu->resolu_ren;
01112                 if(cu->resolv_ren) resolv= cu->resolv_ren;
01113             }
01114 
01115             if(nu->pntsv==1) {
01116                 len= SEGMENTSU(nu)*resolu;
01117 
01118                 dl= MEM_callocN(sizeof(DispList), "makeDispListsurf");
01119                 dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
01120 
01121                 BLI_addtail(dispbase, dl);
01122                 dl->parts= 1;
01123                 dl->nr= len;
01124                 dl->col= nu->mat_nr;
01125                 dl->charidx= nu->charidx;
01126 
01127                 /* dl->rt will be used as flag for render face and */
01128                 /* CU_2D conflicts with R_NOPUNOFLIP */
01129                 dl->rt= nu->flag & ~CU_2D;
01130 
01131                 data= dl->verts;
01132                 if(nu->flagu & CU_NURB_CYCLIC) dl->type= DL_POLY;
01133                 else dl->type= DL_SEGM;
01134 
01135                 makeNurbcurve(nu, data, NULL, NULL, NULL, resolu, 3*sizeof(float));
01136             }
01137             else {
01138                 len= (nu->pntsu*resolu) * (nu->pntsv*resolv);
01139                 
01140                 dl= MEM_callocN(sizeof(DispList), "makeDispListsurf");
01141                 dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
01142                 BLI_addtail(dispbase, dl);
01143 
01144                 dl->col= nu->mat_nr;
01145                 dl->charidx= nu->charidx;
01146 
01147                 /* dl->rt will be used as flag for render face and */
01148                 /* CU_2D conflicts with R_NOPUNOFLIP */
01149                 dl->rt= nu->flag & ~CU_2D;
01150 
01151                 data= dl->verts;
01152                 dl->type= DL_SURF;
01153 
01154                 dl->parts= (nu->pntsu*resolu);  /* in reverse, because makeNurbfaces works that way */
01155                 dl->nr= (nu->pntsv*resolv);
01156                 if(nu->flagv & CU_NURB_CYCLIC) dl->flag|= DL_CYCL_U;    /* reverse too! */
01157                 if(nu->flagu & CU_NURB_CYCLIC) dl->flag|= DL_CYCL_V;
01158 
01159                 makeNurbfaces(nu, data, 0, resolu, resolv);
01160                 
01161                 /* gl array drawing: using indices */
01162                 displist_surf_indices(dl);
01163             }
01164         }
01165     }
01166 
01167     /* make copy of 'undeformed" displist for texture space calculation
01168        actually, it's not totally undeformed -- pre-tesselation modifiers are
01169        already applied, thats how it worked for years, so keep for compatibility (sergey) */
01170     copy_displist(&cu->disp, dispbase);
01171 
01172     if (!forRender) {
01173         tex_space_curve(cu);
01174     }
01175 
01176     if(!forOrco)
01177         curve_calc_modifiers_post(scene, ob, dispbase, derivedFinal,
01178             forRender, originalVerts, deformedVerts);
01179 }
01180 
01181 static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispbase,
01182     DerivedMesh **derivedFinal, int forRender, int forOrco)
01183 {
01184     Curve *cu = ob->data;
01185 
01186     /* we do allow duplis... this is only displist on curve level */
01187     if(!ELEM3(ob->type, OB_SURF, OB_CURVE, OB_FONT)) return;
01188 
01189     if(ob->type==OB_SURF) {
01190         makeDispListSurf(scene, ob, dispbase, derivedFinal, forRender, forOrco);
01191     }
01192     else if (ELEM(ob->type, OB_CURVE, OB_FONT)) {
01193         ListBase dlbev;
01194         ListBase *nubase;
01195         float (*originalVerts)[3];
01196         float (*deformedVerts)[3];
01197         int numVerts;
01198 
01199         nubase= BKE_curve_nurbs(cu);
01200 
01201         BLI_freelistN(&(cu->bev));
01202 
01203         if(cu->path) free_path(cu->path);
01204         cu->path= NULL;
01205 
01206         if(ob->type==OB_FONT) BKE_text_to_curve(G.main, scene, ob, 0);
01207 
01208         if(!forOrco) curve_calc_modifiers_pre(scene, ob, forRender, &originalVerts, &deformedVerts, &numVerts);
01209 
01210         makeBevelList(ob);
01211 
01212         /* If curve has no bevel will return nothing */
01213         makebevelcurve(scene, ob, &dlbev, forRender);
01214 
01215         /* no bevel or extrude, and no width correction? */
01216         if (!dlbev.first && cu->width==1.0f) {
01217             curve_to_displist(cu, nubase, dispbase, forRender);
01218         } else {
01219             float widfac= cu->width - 1.0f;
01220             BevList *bl= cu->bev.first;
01221             Nurb *nu= nubase->first;
01222 
01223             for (; bl && nu; bl=bl->next,nu=nu->next) {
01224                 DispList *dl;
01225                 float *fp1, *data;
01226                 BevPoint *bevp;
01227                 int a,b;
01228 
01229                 if (bl->nr) { /* blank bevel lists can happen */
01230 
01231                     /* exception handling; curve without bevel or extrude, with width correction */
01232                     if(dlbev.first==NULL) {
01233                         dl= MEM_callocN(sizeof(DispList), "makeDispListbev");
01234                         dl->verts= MEM_callocN(3*sizeof(float)*bl->nr, "dlverts");
01235                         BLI_addtail(dispbase, dl);
01236 
01237                         if(bl->poly!= -1) dl->type= DL_POLY;
01238                         else dl->type= DL_SEGM;
01239 
01240                         if(dl->type==DL_SEGM) dl->flag = (DL_FRONT_CURVE|DL_BACK_CURVE);
01241 
01242                         dl->parts= 1;
01243                         dl->nr= bl->nr;
01244                         dl->col= nu->mat_nr;
01245                         dl->charidx= nu->charidx;
01246 
01247                         /* dl->rt will be used as flag for render face and */
01248                         /* CU_2D conflicts with R_NOPUNOFLIP */
01249                         dl->rt= nu->flag & ~CU_2D;
01250 
01251                         a= dl->nr;
01252                         bevp= (BevPoint *)(bl+1);
01253                         data= dl->verts;
01254                         while(a--) {
01255                             data[0]= bevp->vec[0]+widfac*bevp->sina;
01256                             data[1]= bevp->vec[1]+widfac*bevp->cosa;
01257                             data[2]= bevp->vec[2];
01258                             bevp++;
01259                             data+=3;
01260                         }
01261                     }
01262                     else {
01263                         DispList *dlb;
01264 
01265                         for (dlb=dlbev.first; dlb; dlb=dlb->next) {
01266     
01267                             /* for each part of the bevel use a separate displblock */
01268                             dl= MEM_callocN(sizeof(DispList), "makeDispListbev1");
01269                             dl->verts= data= MEM_callocN(3*sizeof(float)*dlb->nr*bl->nr, "dlverts");
01270                             BLI_addtail(dispbase, dl);
01271     
01272                             dl->type= DL_SURF;
01273                             
01274                             dl->flag= dlb->flag & (DL_FRONT_CURVE|DL_BACK_CURVE);
01275                             if(dlb->type==DL_POLY) dl->flag |= DL_CYCL_U;
01276                             if(bl->poly>=0) dl->flag |= DL_CYCL_V;
01277                             
01278                             dl->parts= bl->nr;
01279                             dl->nr= dlb->nr;
01280                             dl->col= nu->mat_nr;
01281                             dl->charidx= nu->charidx;
01282 
01283                             /* dl->rt will be used as flag for render face and */
01284                             /* CU_2D conflicts with R_NOPUNOFLIP */
01285                             dl->rt= nu->flag & ~CU_2D;
01286 
01287                             dl->bevelSplitFlag= MEM_callocN(sizeof(*dl->col2)*((bl->nr+0x1F)>>5), "bevelSplitFlag");
01288     
01289                             /* for each point of poly make a bevel piece */
01290                             bevp= (BevPoint *)(bl+1);
01291                             for(a=0; a<bl->nr; a++,bevp++) {
01292                                 float fac=1.0;
01293                                 if (cu->taperobj==NULL) {
01294                                     if ( (cu->bevobj!=NULL) || !((cu->flag & CU_FRONT) || (cu->flag & CU_BACK)) )
01295                                         fac = bevp->radius;
01296                                 } else {
01297                                     fac = calc_taper(scene, cu->taperobj, a, bl->nr);
01298                                 }
01299 
01300                                 if (bevp->split_tag) {
01301                                     dl->bevelSplitFlag[a>>5] |= 1<<(a&0x1F);
01302                                 }
01303     
01304                                     /* rotate bevel piece and write in data */
01305                                 fp1= dlb->verts;
01306                                 for (b=0; b<dlb->nr; b++,fp1+=3,data+=3) {
01307                                     if(cu->flag & CU_3D) {
01308                                         float vec[3];
01309     
01310                                         vec[0]= fp1[1]+widfac;
01311                                         vec[1]= fp1[2];
01312                                         vec[2]= 0.0;
01313 
01314                                         mul_qt_v3(bevp->quat, vec);
01315 
01316                                         data[0]= bevp->vec[0] + fac*vec[0];
01317                                         data[1]= bevp->vec[1] + fac*vec[1];
01318                                         data[2]= bevp->vec[2] + fac*vec[2];
01319                                     }
01320                                     else {
01321                                         data[0]= bevp->vec[0] + fac*(widfac+fp1[1])*bevp->sina;
01322                                         data[1]= bevp->vec[1] + fac*(widfac+fp1[1])*bevp->cosa;
01323                                         data[2]= bevp->vec[2] + fac*fp1[2];
01324                                     }
01325                                 }
01326                             }
01327                             
01328                             /* gl array drawing: using indices */
01329                             displist_surf_indices(dl);
01330                         }
01331                     }
01332                 }
01333 
01334             }
01335             freedisplist(&dlbev);
01336         }
01337 
01338         if (!(cu->flag & CU_DEFORM_FILL)) {
01339             curve_to_filledpoly(cu, nubase, dispbase);
01340         }
01341 
01342         if(cu->flag & CU_PATH) calc_curvepath(ob);
01343 
01344         /* make copy of 'undeformed" displist for texture space calculation
01345            actually, it's not totally undeformed -- pre-tesselation modifiers are
01346            already applied, thats how it worked for years, so keep for compatibility (sergey) */
01347         copy_displist(&cu->disp, dispbase);
01348 
01349         if (!forRender) {
01350             tex_space_curve(cu);
01351         }
01352 
01353         if(!forOrco) curve_calc_modifiers_post(scene, ob, dispbase, derivedFinal, forRender, originalVerts, deformedVerts);
01354 
01355         if (cu->flag & CU_DEFORM_FILL && !ob->derivedFinal) {
01356             curve_to_filledpoly(cu, nubase, dispbase);
01357         }
01358     }
01359 }
01360 
01361 void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco)
01362 {
01363     Curve *cu= ob->data;
01364     ListBase *dispbase;
01365 
01366     /* The same check for duplis as in do_makeDispListCurveTypes.
01367        Happens when curve used for constraint/bevel was converted to mesh.
01368        check there is still needed for render displist and orco displists. */
01369     if(!ELEM3(ob->type, OB_SURF, OB_CURVE, OB_FONT)) return;
01370 
01371     freedisplist(&(ob->disp));
01372     dispbase= &(ob->disp);
01373     freedisplist(dispbase);
01374 
01375     /* free displist used for textspace */
01376     freedisplist(&cu->disp);
01377 
01378     do_makeDispListCurveTypes(scene, ob, dispbase, &ob->derivedFinal, 0, forOrco);
01379 
01380     if (ob->derivedFinal) {
01381         DM_set_object_boundbox (ob, ob->derivedFinal);
01382     } else {
01383         boundbox_displist (ob);
01384 
01385         /* if there is no derivedMesh, object's boundbox is unneeded */
01386         if (ob->bb) {
01387             MEM_freeN(ob->bb);
01388             ob->bb= NULL;
01389         }
01390     }
01391 }
01392 
01393 void makeDispListCurveTypes_forRender(Scene *scene, Object *ob, ListBase *dispbase,
01394     DerivedMesh **derivedFinal, int forOrco)
01395 {
01396     do_makeDispListCurveTypes(scene, ob, dispbase, derivedFinal, 1, forOrco);
01397 }
01398 
01399 void makeDispListCurveTypes_forOrco(struct Scene *scene, struct Object *ob, struct ListBase *dispbase)
01400 {
01401     do_makeDispListCurveTypes(scene, ob, dispbase, NULL, 1, 1);
01402 }
01403 
01404 /* add Orco layer to the displist object which has got derived mesh and return orco */
01405 float *makeOrcoDispList(Scene *scene, Object *ob, DerivedMesh *derivedFinal, int forRender)
01406 {
01407     float *orco;
01408 
01409     if (derivedFinal == NULL)
01410         derivedFinal= ob->derivedFinal;
01411 
01412     if (!derivedFinal->getVertDataArray(derivedFinal, CD_ORCO)) {
01413         curve_calc_orcodm(scene, ob, derivedFinal, forRender);
01414     }
01415 
01416     orco= derivedFinal->getVertDataArray(derivedFinal, CD_ORCO);
01417 
01418     if(orco) {
01419         orco= MEM_dupallocN(orco);
01420     }
01421 
01422     return orco;
01423 }
01424 
01425 /* this is confusing, there's also min_max_object, appplying the obmat... */
01426 static void boundbox_displist(Object *ob)
01427 {
01428     BoundBox *bb=NULL;
01429     float min[3], max[3];
01430     DispList *dl;
01431     float *vert;
01432     int a, tot=0;
01433     
01434     INIT_MINMAX(min, max);
01435 
01436     if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
01437         Curve *cu= ob->data;
01438         int doit= 0;
01439 
01440         if(cu->bb==NULL) cu->bb= MEM_callocN(sizeof(BoundBox), "boundbox");
01441         bb= cu->bb;
01442         
01443         dl= ob->disp.first;
01444 
01445         while (dl) {
01446             if(dl->type==DL_INDEX3) tot= dl->nr;
01447             else tot= dl->nr*dl->parts;
01448             
01449             vert= dl->verts;
01450             for(a=0; a<tot; a++, vert+=3) {
01451                 doit= 1;
01452                 DO_MINMAX(vert, min, max);
01453             }
01454 
01455             dl= dl->next;
01456         }
01457         
01458         if(!doit) {
01459             /* there's no geometry in displist, use zero-sized boundbox */
01460             zero_v3(min);
01461             zero_v3(max);
01462         }
01463         
01464     }
01465     
01466     if(bb) {
01467         boundbox_set_from_min_max(bb, min, max);
01468     }
01469 }
01470