bsurface.cpp

00001 #include <config.h>
00002 #include <fstream>
00003 
00004 #ifdef _WINDOWS
00005 # include <windows.h>
00006 # include <GL/gl.h>
00007 #else
00008 # include <qgl.h>
00009 #endif
00010 
00011 #include <cmath>
00012 
00013 // for Windows
00014 #ifdef _WINDOWS
00015 # include <float.h>
00016 # define isinf(x) (_finite(x) == 0)
00017 # define isnan(x) _isnan(x)
00018 #endif
00019 
00020 #include "bsurface.h"
00021 
00022 using util::Vector;
00023 using util::Matrix;
00024 
00025 using std::ifstream;
00026 using std::ofstream;
00027 #define C_SEG 20
00028 #define C_SCALE 0.01
00029 #define d_step 0.01
00030 #define l_step 0.1
00031 #define MRES_OFF 0.01
00032 #define MIN_HEIGHT 10
00033 #define MIN_WIDTH 10
00034 
00035 #define err_tol 0.000001
00036 #define max_it 20
00037 #define inner_loop_max_it 100
00038 
00039 using std::cout;
00040 using std::endl;
00041 
00042 namespace util
00043 {
00044 
00045 namespace Shapes
00046 {
00047 
00048 void BSplineSurface::Load(const char* fnm, double scale, int TextureId, int divU, int divV)
00049 {
00050   _TextureId=TextureId;
00051   _scale=scale;
00052   _divU=divU;
00053   _divV=divV;
00054   LoadPatch(fnm);
00055   precomputed=false;
00056 }
00057 
00058 void BSplineSurface::Reread()
00059 {
00060   _divU = _divV = -1;
00061   LoadPatch(_fname.c_str());
00062   precomputed=false;
00063 }
00064 
00065 void BSplineSurface::BoundingBox(double &x1,double &y1, double &z1, double &x2, double &y2, double &z2) 
00066 {
00067   x1=x2=Control_points[0][0][0][0];
00068   y1=y2=Control_points[0][0][0][1];
00069   z1=z2=Control_points[0][0][0][2];
00070 
00071   for (unsigned int i=0; i<Control_points[0].size(); i++)
00072     for (unsigned int j=0; j<Control_points[0][0].size(); j++) {
00073                 
00074       if(Control_points[0][i][j][0]<x1)
00075         x1=Control_points[0][i][j][0];
00076 
00077       if(Control_points[0][i][j][1]<y1)
00078         y1=Control_points[0][i][j][1];
00079 
00080       if(Control_points[0][i][j][2]<z1)
00081         z1=Control_points[0][i][j][2];
00082 
00083       if(Control_points[0][i][j][0]>x2)
00084         x2=Control_points[0][i][j][0];
00085 
00086       if(Control_points[0][i][j][1]>y2)
00087         y2=Control_points[0][i][j][1];
00088 
00089       if(Control_points[0][i][j][2]>z2)
00090         z2=Control_points[0][i][j][2];
00091     }
00092 }
00093   
00094 void BSplineSurface::Transform(Matrix3d M,double x, double y, double z)
00095 {
00096   Point3d D;
00097   D[0]=x;
00098   D[1]=y;
00099   D[2]=z;
00100 
00101   for (unsigned int i=0; i<Control_points[0].size(); i++)
00102     for (unsigned int j=0; j<Control_points[0][0].size(); j++) {
00103             
00104 
00105       Control_points[0][i][j]=M*(Control_points[0][i][j]);
00106       Control_points[0][i][j]=Control_points[0][i][j]+D;
00107     }
00108 
00109   precomputed=false;
00110 }
00111 
00112 void BSplineSurface::Draw(int uDiv, int vDiv)
00113 {
00114   if(!precomputed)
00115     Precompute(uDiv,vDiv);
00116   //const double du = 1.0/uDiv*(n_u-degree);
00117   //const double dv = 1.0/vDiv*(n_v-degree);
00118 
00119 
00120   for (int i=0; i<_divU; ++i) {
00121     const double u1 = 1.0*i/uDiv;
00122     const double u2 = 1.0*(i+1)/uDiv;
00123 
00124     if(!s_mesh)
00125       glBegin(GL_TRIANGLES);
00126 
00127     for (int j=0; j<_divV; ++j) {
00128       bool flip=false;
00129       int id1 = PtId(i, j);
00130       int id2 = PtId(i+1,j);
00131       int id3 = PtId(i+1,j+1);
00132       int id4 = PtId(i,j+1);
00133       const double v1 = 1.0*j/vDiv;
00134       const double v2 = 1.0*(j+1)/vDiv;
00135 
00136 
00137 
00138                   
00139       if(s_mesh)
00140         glBegin(GL_LINES);
00141 
00142           if(contraction){
00143             if( psurf && _ctract[id4]<0)
00144               glColor3f(0.8*(-_ctract[id4]/(-c_min))+0.2,0.2,0.2);
00145             else
00146               glColor3f(0.2,0.8*(_ctract[id4]/(c_max))+0.2,0.2);
00147           }
00148     
00149       glTexCoord2d(u1, v2);
00150       glNormal3d(_nrml[id4][0],_nrml[id4][1],_nrml[id4][2]);
00151       glVertex3d(_vrtx[id4][0],_vrtx[id4][1],_vrtx[id4][2]);
00152                 
00153 
00154           if(contraction){
00155             if( psurf && _ctract[id1]<0)
00156               glColor3f(0.8*(-_ctract[id1]/(-c_min))+0.2,0.2,0.2);
00157             else
00158               glColor3f(0.2,0.8*(_ctract[id1]/(c_max))+0.2,0.2);
00159           }
00160 
00161  
00162       glTexCoord2d(u1, v1);
00163       glNormal3d(_nrml[id1][0],_nrml[id1][1],_nrml[id1][2]);
00164       glVertex3d(_vrtx[id1][0],_vrtx[id1][1],_vrtx[id1][2]);
00165 
00166       
00167       if(_nrml[id4]*_nrml[id2]>_nrml[id3]*_nrml[id1]) {
00168 
00169           if(contraction){
00170             if( psurf && _ctract[id2]<0)
00171               glColor3f(0.8*(-_ctract[id2]/(-c_min))+0.2,0.2,0.2);
00172             else
00173               glColor3f(0.2,0.8*(_ctract[id2]/(c_max))+0.2,0.2);
00174           }
00175 
00176 
00177         flip=true;
00178         glTexCoord2d(u2, v1);
00179         glNormal3d(_nrml[id2][0],_nrml[id2][1],_nrml[id2][2]);
00180         glVertex3d(_vrtx[id2][0],_vrtx[id2][1],_vrtx[id2][2]);
00181                     
00182         if(s_mesh) {
00183 
00184           
00185           if(contraction){
00186             if( psurf && _ctract[id4]<0)
00187               glColor3f(0.8*(-_ctract[id4]/(-c_min))+0.2,0.2,0.2);
00188             else
00189               glColor3f(0.2,0.8*(_ctract[id4]/(c_max))+0.2,0.2);
00190           }
00191 
00192 
00193           glTexCoord2d(u1, v2);
00194           glNormal3d(_nrml[id4][0],_nrml[id4][1],_nrml[id4][2]);
00195           glVertex3d(_vrtx[id4][0],_vrtx[id4][1],_vrtx[id4][2]);
00196         }
00197                 
00198 
00199         
00200           if(contraction){
00201             if( psurf && _ctract[id4]<0)
00202               glColor3f(0.8*(-_ctract[id4]/(-c_min))+0.2,0.2,0.2);
00203             else
00204               glColor3f(0.2,0.8*(_ctract[id4]/(c_max))+0.2,0.2);
00205           }
00206 
00207     
00208         glTexCoord2d(u1, v2);
00209         glNormal3d(_nrml[id4][0],_nrml[id4][1],_nrml[id4][2]);
00210         glVertex3d(_vrtx[id4][0],_vrtx[id4][1],_vrtx[id4][2]);
00211                     
00212       } else {
00213 
00214 
00215           if(contraction){
00216             if( psurf && _ctract[id3]<0)
00217               glColor3f(0.8*(-_ctract[id3]/(-c_min))+0.2,0.2,0.2);
00218             else
00219               glColor3f(0.2,0.8*(_ctract[id3]/(c_max))+0.2,0.2);
00220           }
00221 
00222 
00223         glTexCoord2d(u2, v2);
00224         glNormal3d(_nrml[id3][0],_nrml[id3][1],_nrml[id3][2]);
00225         glVertex3d(_vrtx[id3][0],_vrtx[id3][1],_vrtx[id3][2]);
00226                     
00227         if(s_mesh) {
00228 
00229           if(contraction){
00230             if( psurf && _ctract[id4]<0)
00231               glColor3f(0.8*(-_ctract[id4]/(-c_min))+0.2,0.2,0.2);
00232             else
00233               glColor3f(0.2,0.8*(_ctract[id4]/(c_max))+0.2,0.2);
00234           }
00235 
00236 
00237           glTexCoord2d(u1, v2);
00238           glNormal3d(_nrml[id4][0],_nrml[id4][1],_nrml[id4][2]);
00239           glVertex3d(_vrtx[id4][0],_vrtx[id4][1],_vrtx[id4][2]);
00240         }                         
00241 
00242 
00243           if(contraction){
00244             if( psurf && _ctract[id1]<0)
00245               glColor3f(0.8*(-_ctract[id1]/(-c_min))+0.2,0.2,0.2);
00246             else
00247               glColor3f(0.2,0.8*(_ctract[id1]/(c_max))+0.2,0.2);
00248           }
00249 
00250 
00251         glTexCoord2d(u1, v1);
00252         glNormal3d(_nrml[id1][0],_nrml[id1][1],_nrml[id1][2]);
00253         glVertex3d(_vrtx[id1][0],_vrtx[id1][1],_vrtx[id1][2]);
00254       }
00255 
00256 
00257           if(contraction){
00258             if( psurf && _ctract[id2]<0)
00259               glColor3f(0.8*(-_ctract[id2]/(-c_min))+0.2,0.2,0.2);
00260             else
00261               glColor3f(0.2,0.8*(_ctract[id2]/(c_max))+0.2,0.2);
00262           }
00263 
00264 
00265       glTexCoord2d(u2, v1);
00266       glNormal3d(_nrml[id2][0],_nrml[id2][1],_nrml[id2][2]);
00267       glVertex3d(_vrtx[id2][0],_vrtx[id2][1],_vrtx[id2][2]);
00268  
00269 
00270           if(contraction){
00271             if( psurf && _ctract[id3]<0)
00272               glColor3f(0.8*(-_ctract[id3]/(-c_min))+0.2,0.2,0.2);
00273             else
00274               glColor3f(0.2,0.8*(_ctract[id3]/(c_max))+0.2,0.2);
00275           }
00276 
00277 
00278 
00279       glTexCoord2d(u2, v2);
00280       glNormal3d(_nrml[id3][0],_nrml[id3][1],_nrml[id3][2]);
00281       glVertex3d(_vrtx[id3][0],_vrtx[id3][1],_vrtx[id3][2]);
00282                   
00283       if(s_mesh) {
00284 
00285         if(flip) {
00286 
00287           if(contraction){
00288             if( psurf && _ctract[id4]<0)
00289               glColor3f(0.8*(-_ctract[id4]/(-c_min))+0.2,0.2,0.2);
00290             else
00291               glColor3f(0.2,0.8*(_ctract[id4]/(c_max))+0.2,0.2);
00292           }
00293 
00294 
00295           glTexCoord2d(u1, v2);
00296           glNormal3d(_nrml[id4][0],_nrml[id4][1],_nrml[id4][2]);
00297           glVertex3d(_vrtx[id4][0],_vrtx[id4][1],_vrtx[id4][2]);
00298         } else {
00299 
00300 
00301           if(contraction){
00302             if( psurf && _ctract[id1]<0)
00303               glColor3f(0.8*(-_ctract[id1]/(-c_min))+0.2,0.2,0.2);
00304             else
00305               glColor3f(0.2,0.8*(_ctract[id1]/(c_max))+0.2,0.2);
00306           }
00307 
00308 
00309           glTexCoord2d(u1, v1);
00310           glNormal3d(_nrml[id1][0],_nrml[id1][1],_nrml[id1][2]);
00311           glVertex3d(_vrtx[id1][0],_vrtx[id1][1],_vrtx[id1][2]);
00312         }
00313         glEnd();
00314       }
00315       }
00316     glEnd();
00317     }
00318 
00319 
00320 
00321 
00322 
00323 /*
00324 // draw normals
00325 {
00326 GLprimitive lns(GL_LINES);
00327 for (int i=0; i<_vrtx.size(); ++i)
00328 {
00329 Point3d v = _vrtx[i];
00330 glVertex3d(v[0],v[1],v[2]);
00331 v = v+_nrml[i]*0.2;
00332 glVertex3d(v[0],v[1],v[2]);
00333 }
00334 }
00335 */
00336 }
00337 
00338 void BSplineSurface::Precompute(int uDiv, int vDiv)
00339 {
00340   unsigned int newsize = (uDiv+1)*(vDiv+1);
00341   if (_vrtx.size() != newsize) {
00342     _vrtx.resize(newsize);
00343     _nrml.resize(newsize);
00344     //This should only be resized if contraction is being visualized
00345     _ctract.resize(newsize);
00346   }
00347   _divU = uDiv;
00348   _divV = vDiv;
00349 
00350   const double du = 1.0/uDiv*(n_u-degree);
00351   const double dv = 1.0/vDiv*(n_v-degree);
00352   c_min=c_max=0;
00353   for (int i=0; i<=_divU; ++i) {
00354     const double u = 3.0+i*du;
00355     for (int j=0; j<=_divV; ++j) {
00356       const int id = PtId(i, j);
00357       const double v = 3.0+j*dv;
00358       _vrtx[id] = Eval(u, v);
00359       _nrml[id] = NormalEval(u, v);
00360       if( psurf ){
00361         _ctract[id]=HasContracted(psurf, u, v);
00362         if(_ctract[id]<c_min)
00363           c_min=_ctract[id];
00364         if(_ctract[id]>c_max)
00365           c_max=_ctract[id];
00366         
00367 
00368       }
00369       else
00370         _ctract[id]=0;
00371     }
00372   }
00373   if(c_max>fabs(c_min))
00374     c_min=-c_max;
00375   else
00376     c_max=-c_min;
00377   precomputed=true;
00378 }
00379 
00380 BSplineSurface::BSplineSurface() : _TextureId(-1)
00381 {
00382   degree=3;
00383   wireframe=true;
00384   n_u=MIN_HEIGHT;
00385   n_v=MIN_WIDTH;
00386   selected[0]=selected[1]=selected_level=0;
00387   periodic=false;
00388   Reset(n_u,n_v);
00389   lines=true;
00390   u_prec=l_step;
00391   v_prec=l_step;
00392   
00393   poly_line[0]=1.0;
00394   poly_line[1]=1.0;
00395 
00396   s_mesh=false;
00397   disp_normal=false;
00398   disp_c_mesh=true;
00399   contraction=false;
00400   precomputed=false;
00401   c_min=0;
00402   c_max=0;
00403   psurf=NULL;
00404 }
00405 
00406 BSplineSurface::~BSplineSurface()
00407 {
00408 }
00409 
00410 BSplineSurface::BSplineSurface(const BSplineSurface &B)
00411 {
00412   _TextureId=B._TextureId;
00413   _scale=B._scale;
00414   _divU=B._divU;
00415   _divV=B._divV;
00416   if(B.precomputed) {
00417   _vrtx=B._vrtx;
00418   _nrml=B._nrml;
00419   precomputed=B.precomputed;
00420   }
00421   else
00422     precomputed=false;
00423 
00424   wireframe=true;
00425 
00426   degree=3;
00427   wireframe=true;
00428   n_u=B.n_u;
00429   n_v=B.n_v;
00430   selected[0]=selected[1]=selected_level=0;
00431   periodic=false;
00432   Reset(n_u,n_v);
00433   lines=true;
00434   contraction = B.contraction;
00435   psurf = B.psurf;
00436 
00437   for(unsigned int i=0;i<Control_points[0].size();i++)
00438     for(unsigned int j=0;j<Control_points[0][0].size();j++)
00439       Control_points[0][i][j]=B.Control_points[0][i][j];
00440 }
00441 
00442 bool BSplineSurface::SavePatch(const char *fname)
00443 {
00444   bool saved=false;
00445 
00446   ofstream File;
00447 
00448   File.open(fname);
00449   
00450   File<<n_u<<" ";
00451 
00452   File<<n_v<<std::endl;
00453   
00454   File<<3<<std::endl; 
00455 
00456   for(int i=0;i<n_u;i++) {
00457     for(int j=0;j<n_v;j++) {
00458 
00459       File<<Control_points[0][i][j][0]<<" "<<Control_points[0][i][j][1]<<" "<<Control_points[0][i][j][2]<<std::endl;
00460 
00461     }
00462   }
00463   return saved;
00464 }
00465 
00466 bool BSplineSurface::LoadPatch(const char *fname)
00467 {
00468   bool loaded=false;
00469   int degree;
00470   ifstream File;
00471 
00472   File.open(fname);
00473   _f_name=fname;
00474 
00475   File>>n_u;
00476   File>>n_v;
00477   File>>degree;
00478 
00479   if(degree!=3)
00480     std::cout<<"Warning: "<<fname<<" is not a cubic patch"<<std::endl;
00481 
00482   Reset(n_u,n_v);
00483 
00484   for(int i=0;i<n_u;i++) {
00485     for(int j=0;j<n_v;j++) {
00486 
00487       File>>Control_points[0][i][j][0]>>Control_points[0][i][j][1]>>Control_points[0][i][j][2];
00488 
00489     }
00490   }
00491   return loaded;
00492 }
00493 
00494 void BSplineSurface::Reset(int u, int v)
00495 {
00496   vector<Point3d >*c_points;
00497   vector< vector<Point3d > > *cc_points;
00498 
00499   n_u=u;
00500   n_v=v;
00501   footprint.clear();
00502   int *cv=new int[4];
00503   footprint.push_back(cv);
00504 
00505   selected[0]=selected[1]=0;
00506   selected_level=0;
00507   selected_region.clear();
00508   //delete existing points
00509   Control_points.clear();
00510 
00511   Details.clear();
00512 
00513   cc_points= new vector< vector<Point3d > >;
00514 
00515   Point3d p;
00516 
00517   for(int i=0;i<u;i++) {
00518     c_points = new vector< Point3d >;
00519     for(int j=0;j<v;j++) {
00520     
00521       p[0]=(float)i/u-0.5+err_tol;
00522       p[1]=(float)j/v-0.5+err_tol;
00523       p[2]=0;
00524 
00525       c_points->push_back(p);
00526       //      weights[i].push_back(w);
00527     }
00528     cc_points->push_back(*c_points);
00529     delete c_points;
00530   }
00531   Control_points.push_back(*cc_points);
00532 
00533   delete cc_points;
00534 
00535   //  Control_points.push_back(c_points);
00536 }
00537 
00538 
00539 float BSplineSurface::HasContracted(BSplineSurface * b, float u, float v){
00540 
00541   Point3d pu= PartialU(u,v);
00542   Point3d bpu= b->PartialU(u,v);
00543   Point3d pv= PartialV(u,v);
00544   Point3d bpv= b->PartialV(u,v);
00545 
00546   pu=pu ^ pv;
00547   bpu=bpu ^ bpv;
00548   float ret=(pu.norm()/bpu.norm());
00549   ret-=1;
00550 
00551   //  std::cout<< pu.norm()<<" "<<bpu.norm()<<std::endl;
00552   return ret;
00553 }
00554 
00555 void BSplineSurface::HalveU()
00556 {
00557   vector< Point3d > temp;
00558 
00559   Point3d val;
00560 
00561   vector< vector< Point3d >  > c_points;
00562   vector< vector< Point3d >  > d_points;
00563   int *cr=new int[4];
00564 
00565   if( (Control_points[Control_points.size()-1].size()+3 )/2 >=MIN_HEIGHT) {
00566 
00567     footprint.push_back(cr);
00568     val=val*0;
00569 
00570     for(unsigned int j=0;j<Control_points[Control_points.size()-1][0].size();j++)
00571       temp.push_back(val);
00572     
00573     for(unsigned int i=0;i<( Control_points[Control_points.size()-1].size()+3)/2;i++) {
00574       c_points.push_back(temp);
00575       d_points.push_back(temp);
00576     }
00577 
00578     Control_points.push_back(c_points);
00579     Details.push_back(d_points);
00580 
00581     for(unsigned int i=0;i<footprint.size();i++) {
00582 
00583       footprint[i][1]=footprint[i][3]=10000000;
00584       footprint[i][0]=footprint[i][2]=-1;
00585 
00586     }  
00587     footprint[footprint.size()-2][1]=0;
00588     footprint[footprint.size()-2][0]=
00589                       (int)Control_points[Control_points.size()-2].size()-1;
00590     footprint[footprint.size()-2][3]=0;
00591     footprint[footprint.size()-2][2]=
00592                       (int)Control_points[Control_points.size()-2][0].size()-1;
00593   
00594     footprint[footprint.size()-1][1]=0;
00595     footprint[footprint.size()-1][0]=
00596                       (int)Control_points[Control_points.size()-1].size()-1;
00597     footprint[footprint.size()-1][3]=0;
00598     footprint[footprint.size()-1][2]=
00599                       (int)Control_points[Control_points.size()-1][0].size()-1;
00600 
00601     //  Calc_PreImage(0,0,Control_points.size()-2);
00602     UpdateFootprint();
00603   }
00604 }
00605 
00606 void BSplineSurface::DoubleV()
00607 {
00608   vector< Point3d > temp;
00609 
00610   Point3d val;
00611   int line_size;
00612   vector< vector< Point3d >  > c_points;
00613   vector< vector< Point3d >  > d_points;
00614   int *cr=new int[4];
00615 
00616   footprint.push_back(cr);
00617 
00618   for(unsigned int k=0;k<Control_points[0].size();k++) {
00619 
00620     temp.clear();
00621     
00622     temp.push_back(Control_points[0][k][0]);
00623 
00624     val=Control_points[0][k][0]*(1.0/2.0)
00625       +Control_points[0][k][1]*(1.0/2.0);
00626 
00627     temp.push_back(val);
00628 
00629     val=Control_points[0][k][1]*(3.0/4.0)
00630       +Control_points[0][k][2]*(1.0/4.0);
00631 
00632     temp.push_back(val);
00633 
00634     val=Control_points[0][k][1]*(3.0/16.0)
00635       +Control_points[0][k][2]*(11.0/16.0)
00636       +Control_points[0][k][3]*(1.0/8.0);
00637 
00638     temp.push_back(val);
00639 
00640     val=Control_points[0][k][2]*(1.0/2.0)
00641       +Control_points[0][k][3]*(1.0/2.0);
00642 
00643     temp.push_back(val);
00644 
00645     line_size= (int)Control_points[0][k].size()-1;
00646     
00647     for(int i=3;i<line_size-2;i++) {
00648       val=Control_points[0][k][i-1]*(1.0/8.0)
00649         +Control_points[0][k][i]*(3.0/4.0)
00650         +Control_points[0][k][i+1]*(1.0/8.0);
00651       
00652       temp.push_back(val);
00653 
00654       //Changed here and in doubleU
00655       //   if((i+1)<(line_size-2)) {
00656       val= Control_points[0][k][i]*(1.0/2.0)
00657         +Control_points[0][k][i+1]*(1.0/2.0);
00658       temp.push_back(val);
00659 
00660       //      }
00661     }
00662     //    val=Control_points[0][k][line_size-2]*(1.0/2.0)
00663     //  +Control_points[0][k][line_size-3]*(1.0/2.0);
00664 
00665     //    temp.push_back(val);
00666     
00667     val=Control_points[0][k][line_size-1]*(3.0/16.0)
00668       +Control_points[0][k][line_size-2]*(11.0/16.0)
00669       +Control_points[0][k][line_size-3]*(1.0/8.0);
00670 
00671     temp.push_back(val);
00672 
00673     val=Control_points[0][k][line_size-2]*(1.0/4.0)
00674       +Control_points[0][k][line_size-1]*(3.0/4.0);
00675 
00676     temp.push_back(val);
00677 
00678     val=Control_points[0][k][line_size]*(1.0/2.0)
00679       +Control_points[0][k][line_size-1]*(1.0/2.0);
00680 
00681     temp.push_back(val);
00682 
00683     temp.push_back(Control_points[0][k][line_size]);
00684 
00685     c_points.push_back(temp);
00686     //Control_points[0][k]=temp;
00687 
00688   }
00689   Control_points.insert(Control_points.begin(),c_points);
00690   n_v=(int)Control_points[0][0].size();
00691   n_u=(int)Control_points[0].size();
00692   temp.clear();
00693   val=val*0;
00694 
00695   for(int i=0;i<n_v;i++)
00696     temp.push_back(val);
00697 
00698   for(int i=0;i<n_u;i++)
00699     d_points.push_back(temp);
00700 
00701   Details.insert(Details.begin(),d_points);
00702 
00703   for(unsigned int i=0;i<footprint.size();i++) {
00704 
00705     footprint[i][1]=footprint[i][3]=10000000;
00706     footprint[i][0]=footprint[i][2]=-1;
00707 
00708   }
00709   CalcPreImage(selected[0],selected[1],selected_level);
00710   //std::cout<<Control_points[0][0].size()<<std::endl;
00711 }
00712 
00713 void BSplineSurface::HalveV()
00714 {
00715   vector< Point3d > temp;
00716 
00717   Point3d val;
00718 
00719   vector< vector< Point3d >  > c_points;
00720   vector< vector< Point3d >  > d_points;
00721   int *cr=new int[4];
00722 
00723   if( (Control_points[Control_points.size()-1][0].size()+3) /2 >=MIN_WIDTH) {
00724     footprint.push_back(cr);
00725     val=val*0;
00726 
00727     for(unsigned int i=0;i<( Control_points[Control_points.size()-1][0].size()+3)/2;i++)
00728       temp.push_back(val);
00729     
00730     for(unsigned int j=0;j<Control_points[Control_points.size()-1].size();j++) {
00731       c_points.push_back(temp);
00732       d_points.push_back(temp);
00733     }
00734 
00735     Control_points.push_back(c_points);
00736     Details.push_back(d_points);
00737 
00738     for(unsigned int i=0;i<footprint.size();i++) {
00739       footprint[i][1]=footprint[i][3]=10000000;
00740       footprint[i][0]=footprint[i][2]=-1;
00741     }  
00742 
00743     footprint[footprint.size()-2][1]=0;
00744     footprint[footprint.size()-2][0]=
00745                       (int)Control_points[Control_points.size()-2].size()-1;
00746     footprint[footprint.size()-2][3]=0;
00747     footprint[footprint.size()-2][2]=
00748                       (int)Control_points[Control_points.size()-2][0].size()-1;
00749   
00750     footprint[footprint.size()-1][1]=0;
00751     footprint[footprint.size()-1][0]=
00752                       (int)Control_points[Control_points.size()-1].size()-1;
00753     footprint[footprint.size()-1][3]=0;
00754     footprint[footprint.size()-1][2]=
00755                       (int)Control_points[Control_points.size()-1][0].size()-1;
00756 
00757     //  Calc_PreImage(0,0,Control_points.size()-2);
00758     UpdateFootprint();
00759   }
00760 }
00761 
00762 
00763 void BSplineSurface::DoubleU() {
00764  vector< Point3d > temp;
00765  vector< vector< Point3d > >temp_grid;
00766  vector< vector< Point3d > > c_points;
00767  vector< vector< Point3d >  > d_points;
00768   int *cr=new int[4];
00769 
00770   footprint.push_back(cr);
00771 
00772   Point3d val;
00773   int line_size;
00774 
00775   for(unsigned int k=0;k<Control_points[0][0].size();k++) {
00776 
00777     temp.clear();
00778 
00779     temp.push_back(Control_points[0][0][k]);
00780 
00781     val=Control_points[0][0][k]*(1.0/2.0)
00782       +Control_points[0][1][k]*(1.0/2.0);
00783 
00784     temp.push_back(val);
00785 
00786     val=Control_points[0][1][k]*(3.0/4.0)
00787       +Control_points[0][2][k]*(1.0/4.0);
00788 
00789     temp.push_back(val);
00790 
00791     val=Control_points[0][1][k]*(3.0/16.0)
00792       +Control_points[0][2][k]*(11.0/16.0)
00793       +Control_points[0][3][k]*(1.0/8.0);
00794 
00795     temp.push_back(val);
00796 
00797     //    val=Control_points[0][2][k]*(1.0/2.0)
00798     //  +Control_points[0][3][k]*(1.0/2.0);
00799 
00800     //temp.push_back(val);
00801 
00802     line_size=(int)Control_points[0].size()-1;
00803     
00804     for(int i=2;i<line_size-3;i++) {
00805       val= Control_points[0][i][k]*(1.0/2.0)
00806         +Control_points[0][i+1][k]*(1.0/2.0);
00807       temp.push_back(val);
00808 
00809       val=Control_points[0][i][k]*(1.0/8.0)
00810         +Control_points[0][i+1][k]*(3.0/4.0)
00811         +Control_points[0][i+2][k]*(1.0/8.0);
00812       
00813       temp.push_back(val);
00814 
00815       //  if((i)<(line_size-2)) {
00816       //    }
00817     }
00818     val=Control_points[0][line_size-2][k]*(1.0/2.0)
00819       +Control_points[0][line_size-3][k]*(1.0/2.0);
00820 
00821     temp.push_back(val);
00822     
00823     val=Control_points[0][line_size-1][k]*(3.0/16.0)
00824       +Control_points[0][line_size-2][k]*(11.0/16.0)
00825       +Control_points[0][line_size-3][k]*(1.0/8.0);
00826 
00827     temp.push_back(val);
00828 
00829     val=Control_points[0][line_size-2][k]*(1.0/4.0)
00830       +Control_points[0][line_size-1][k]*(3.0/4.0);
00831 
00832     temp.push_back(val);
00833 
00834     val=Control_points[0][line_size][k]*(1.0/2.0)
00835       +Control_points[0][line_size-1][k]*(1.0/2.0);
00836 
00837     temp.push_back(val);
00838 
00839     temp.push_back(Control_points[0][line_size][k]);
00840 
00841 
00842     temp_grid.push_back(temp);
00843     //    Control_points[0][k]=temp;
00844   }
00845 
00846   //Control_points[0].clear();
00847 
00848   for(unsigned int i=0;i<temp_grid[0].size();i++) {
00849     temp.clear();
00850     for(unsigned int j=0;j<temp_grid.size();j++) {
00851       temp.push_back(temp_grid[j][i]);
00852     }
00853     c_points.push_back(temp);
00854   }
00855 
00856   Control_points.insert(Control_points.begin(),c_points);
00857 
00858   temp.clear();
00859   val=val*0;
00860 
00861   n_v=(int)Control_points[0][0].size();
00862   n_u=(int)Control_points[0].size();
00863 
00864   for(int i=0;i<n_v;i++)
00865     temp.push_back(val);
00866 
00867   for(int i=0;i<n_u;i++)
00868     d_points.push_back(temp);
00869 
00870   Details.insert(Details.begin(),d_points);
00871 
00872   for(unsigned int i=0;i<footprint.size();i++) {
00873     footprint[i][1]=footprint[i][3]=10000000;
00874     footprint[i][0]=footprint[i][2]=-1;
00875   }
00876   CalcPreImage(selected[0],selected[1],selected_level);
00877 }
00878 
00879 void BSplineSurface::DisplayControlPoints(Matrix3d A,Point3d trans)
00880 {
00881   Point3d t;
00882   glColor3dv(unsel_point);
00883   int k=selected_level;
00884 
00885 
00886   for(unsigned int i=0;i<Control_points[k].size();i++) {
00887     for(unsigned int j=0;j<Control_points[k][0].size();j++) {
00888       if(k==selected_level) {
00889         t=Control_points[selected_level][i][j];
00890         t[2]=-t[2]+k*(MRES_OFF);
00891         t=A*t;
00892         t[2]=0;
00893         t=t+trans;
00894         if(i!=selected[0] || j!=selected[1])
00895           DrawCircle(t[0],t[1],t[2],0.7);
00896           //CallBackCircle(t[0],t[1],t[2],0.7);
00897         else {
00898           glColor3dv(sel_point);;
00899           DrawCircle(t[0],t[1],t[2],1.0);
00900           //CallBackCircle(t[0],t[1],t[2],1.0);
00901           glColor3dv(unsel_point);
00902         }
00903       } else {
00904         t=Control_points[k][i][j];
00905         t[2]=-t[2]+k*(MRES_OFF);
00906         t=A*t;
00907         t[2]=0;
00908         t=t+trans;
00909         glColor3d(0.8*(k/Control_points.size()),0.8*(k/Control_points.size()),0.8*(k/Control_points.size()));
00910         DrawCircle(t[0],t[1],t[2],0.3);
00911         //CallBackCircle(t[0],t[1],t[2],0.3);
00912         glColor3dv(unsel_point);
00913       }
00914     }
00915   }
00916 //  }
00917 
00918   for(unsigned int i=0;i<selected_region.size();i++) {
00919     t=Control_points[selected_level][selected_region[i][0]][selected_region[i][1]];
00920     t[2]=-t[2]+k*(MRES_OFF);
00921     t=A*t;
00922     t[2]=0.01;
00923     t=t+trans;
00924     glColor3dv(sel_point);;
00925     DrawCircle(t[0],t[1],t[2],1.0);
00926     //CallBackCircle(t[0],t[1],t[2],0.7);
00927     glColor3dv(unsel_point);
00928   }
00929 
00930   if(disp_c_mesh){
00931 
00932   glBegin(GL_LINES);
00933   for(unsigned int i=0;i<Control_points[k].size();i++) {
00934     for(unsigned int j=0;j<Control_points[k][0].size();j++) {
00935       if(i!=Control_points[k].size()-1){
00936         t=Control_points[k][i][j];
00937         t[2]=-t[2]+k*(MRES_OFF);
00938         t=A*t;
00939         t[2]=0;
00940         t=t+trans;
00941         glVertex3d(t[0],t[1],t[2]);
00942 
00943         t=Control_points[k][i+1][j];
00944         t[2]=-t[2]+k*(MRES_OFF);
00945         t=A*t;
00946         t[2]=0;
00947         t=t+trans;
00948         glVertex3d(t[0],t[1],t[2]);
00949 
00950 
00951       }
00952       if(j!=Control_points[k][0].size()-1){
00953         t=Control_points[k][i][j];
00954         t[2]=-t[2]+k*(MRES_OFF);
00955         t=A*t;
00956         t[2]=0;
00957         t=t+trans;
00958         glVertex3d(t[0],t[1],t[2]);
00959 
00960         t=Control_points[k][i][j+1];
00961         t[2]=-t[2]+k*(MRES_OFF);
00962         t=A*t;
00963         t[2]=0;
00964         t=t+trans;
00965         glVertex3d(t[0],t[1],t[2]);
00966 
00967       }
00968 
00969     }
00970 
00971   }
00972   glEnd();
00973   }
00974 
00975 }
00976 
00977 void BSplineSurface::DrawCircle(double x, double y, double z, double weight) {
00978   glBegin(GL_TRIANGLES);
00979   for(double i=0;i<C_SEG;i++) {
00980     glVertex3d( x+ sqrt(weight)*C_SCALE*cos(2*3.14159*(i/C_SEG)),y
00981                                   + sqrt(weight)*C_SCALE*sin(2*3.14159*(i/C_SEG)),z);
00982     glVertex3d( x+ sqrt(weight)*C_SCALE*cos(2*3.14159*((i+1)/C_SEG)),y
00983                                   + sqrt(weight)*C_SCALE*sin(2*3.14159*((i+1)/C_SEG)),z);
00984     glVertex3d(x,y,z);
00985   }
00986   glEnd();
00987 }
00988 
00989 /*
00990 void BSplineSurface::CallBackCircle(double x, double y, double z, double weight) {
00991   
00992   glTranslatef(-x,-y,-z);
00993   glScalef(weight,weight,weight);
00994 
00995   glCallList(circ);
00996 
00997   glScalef(1/weight,1/weight,1/weight);
00998  glTranslatef(x,y,z);
00999   
01000 
01001 }
01002 */
01003 
01004 void BSplineSurface::DisplaySurface()
01005 {
01006   Point3d u_val,u_val2,u_val3,u_val4;
01007   Point3d n_val,n_val2,n_val3,n_val4;
01008   glLineWidth(1.0);
01009   //   int e_u=0;
01010 
01011   //  vector<vector< Point3d > >temp = Control_points[0];
01012   //Control_points[0]=Control_points[selected_level];
01013 
01014   n_u=(int)Control_points[0].size();
01015   n_v=(int)Control_points[0][0].size();
01016 
01017   //   std::cout<<n_u<<" "<<n_v<<std::endl;
01018   if(wireframe) {
01019     if(n_u>1) {  
01020 
01021 
01022         glColor3dv(poly_line);    
01023 
01024     
01025       for(double i=3;i<= (n_u+d_step) && n_u>1 ; i+=u_prec*((double)n_u-(double)degree)) {
01026         glBegin(GL_LINE_STRIP);
01027         for(double j=3;j<= (n_v+d_step) && n_v>1 ; j+=d_step*((double)n_v-(double)degree)) {
01028           if(contraction){
01029             if( psurf && HasContracted(psurf,i,j))
01030               glColor3f(0.5,0.0,0.0);
01031             else
01032               glColor3f(0.0,0.5,0.0);
01033           }
01034 
01035           u_val= Eval(i,j);
01036           glVertex3d(u_val[0],u_val[1],u_val[2]);
01037         }
01038         glEnd();
01039       }
01040 
01041       for(double i=3;i<= (n_v+d_step) && n_v>1 ; i+=v_prec*((double)n_v-(double)degree)) {
01042         glBegin(GL_LINE_STRIP);
01043         for(double j=3;j<= (n_u+d_step) && n_u>1 ; j+=d_step*((double)n_u-(double)degree)) {
01044           if(contraction){
01045             if( psurf && HasContracted(psurf,i,j))
01046               glColor3f(0.5,0.0,0.0);
01047             else
01048               glColor3f(0.0,0.5,0.0);
01049           }
01050 
01051 
01052           u_val= Eval(j,i);
01053           glVertex3d(u_val[0],u_val[1],u_val[2]);
01054         }
01055         glEnd();
01056       }
01057     }
01058   } else {
01059     if(n_u>1) {  
01060       //   glColor3d(0.2,0.2,0.2);
01061       if(s_mesh)
01062         glBegin(GL_TRIANGLES);
01063 
01064       for(double i=3;i<= (n_u) && n_u>1 ; i+=u_prec/5.0*((double)n_u-(double)degree)) {
01065         for(double j=3; j<=(n_v) && n_v>1 ; j+=v_prec/5.0*((double)n_v-(double)degree)) {
01066           u_val= Eval(i,j);
01067           n_val=NormalEval(i,j);
01068 
01069           u_val2= Eval(i+u_prec/5.0*(n_u-degree),j);
01070           n_val2=NormalEval(i+u_prec/5.0*(n_u-degree),j);
01071 
01072           n_val3=NormalEval(i,j+v_prec/5.0*(n_v-degree));
01073           u_val3= Eval(i,j+v_prec/5.0*(n_v-degree));
01074 
01075           u_val4= Eval(i+u_prec/5.0*(n_u-degree),j+v_prec/5.0
01076                                                            * (n_v-degree));
01077           n_val4=NormalEval(i+u_prec/5.0*(n_u-degree),j+v_prec/5.0
01078                                                            * (n_v-degree));
01079 
01080           if(contraction){
01081             if( psurf && HasContracted(psurf,i,j))
01082               glColor3f(0.5,0.0,0.0);
01083             else
01084               glColor3f(0.0,0.5,0.0);
01085           }
01086 
01087 
01088           if(n_val2*n_val3 > n_val*n_val4 ) {
01089             if(!s_mesh)
01090               glBegin(GL_LINE_STRIP);
01091 
01092             glNormal3d(n_val[0],n_val[1],n_val[2]);
01093             glVertex3d(u_val[0],u_val[1],u_val[2]);
01094 
01095             glNormal3d(n_val2[0],n_val2[1],n_val2[2]);
01096             glVertex3d(u_val2[0],u_val2[1],u_val2[2]);
01097 
01098             glNormal3d(n_val3[0],n_val3[1],n_val3[2]);  
01099             glVertex3d(u_val3[0],u_val3[1],u_val3[2]);
01100 
01101             if(!s_mesh) {
01102               glNormal3d(n_val[0],n_val[1],n_val[2]);
01103               glVertex3d(u_val[0],u_val[1],u_val[2]);
01104             }
01105 
01106             if(!s_mesh) {
01107               glEnd();
01108               glBegin(GL_LINE_STRIP);
01109 
01110             }
01111             glNormal3d(n_val4[0],n_val4[1],n_val4[2]);
01112             glVertex3d(u_val4[0],u_val4[1],u_val4[2]);
01113 
01114             //  u_val= eval(i,j+l_step/5.0*(n_v+degree));
01115             //n_val=normal_eval(i,j+l_step/5.0*(n_v+degree));
01116             glNormal3d(n_val3[0],n_val3[1],n_val3[2]);  
01117             glVertex3d(u_val3[0],u_val3[1],u_val3[2]);
01118 
01119             //  u_val= eval(i+l_step/5.0*(n_u+degree),j);
01120             //n_val=normal_eval(i+l_step/5.0*(n_u+degree),j);
01121             glNormal3d(n_val2[0],n_val2[1],n_val2[2]);
01122             glVertex3d(u_val2[0],u_val2[1],u_val2[2]);
01123 
01124             if(!s_mesh) {
01125               glNormal3d(n_val4[0],n_val4[1],n_val4[2]);
01126               glVertex3d(u_val4[0],u_val4[1],u_val4[2]);
01127               glEnd();
01128             }
01129           } else {
01130             if(!s_mesh) {
01131               glBegin(GL_LINE_STRIP);
01132             }
01133 
01134             glNormal3d(n_val[0],n_val[1],n_val[2]);
01135             glVertex3d(u_val[0],u_val[1],u_val[2]);
01136 
01137             glNormal3d(n_val2[0],n_val2[1],n_val2[2]);
01138             glVertex3d(u_val2[0],u_val2[1],u_val2[2]);
01139 
01140             glNormal3d(n_val4[0],n_val4[1],n_val4[2]);
01141             glVertex3d(u_val4[0],u_val4[1],u_val4[2]);
01142 
01143             if(!s_mesh) {
01144               glNormal3d(n_val[0],n_val[1],n_val[2]);
01145               glVertex3d(u_val[0],u_val[1],u_val[2]);
01146               glEnd();
01147               glBegin(GL_LINE_STRIP);
01148             }
01149 
01150             glNormal3d(n_val4[0],n_val4[1],n_val4[2]);
01151             glVertex3d(u_val4[0],u_val4[1],u_val4[2]);
01152 
01153             glNormal3d(n_val3[0],n_val3[1],n_val3[2]);  
01154             glVertex3d(u_val3[0],u_val3[1],u_val3[2]);
01155 
01156             glNormal3d(n_val[0],n_val[1],n_val[2]);
01157             glVertex3d(u_val[0],u_val[1],u_val[2]);
01158 
01159             if(!s_mesh) {
01160               glNormal3d(n_val4[0],n_val4[1],n_val4[2]);
01161               glVertex3d(u_val4[0],u_val4[1],u_val4[2]);
01162               glEnd();
01163             }
01164           }
01165         }
01166       }
01167       glEnd();      
01168     }
01169   }
01170 
01171 //  std::cout<<e_u<<std::endl;
01172   glDisable(GL_LIGHTING);
01173   if(disp_normal) { 
01174     glBegin(GL_LINES);
01175 
01176     for(double i=1;i< (n_u+degree-1-u_prec/2.0*(n_u+degree)) && n_u>1 ; i+=u_prec/2.0*((double)n_u-(double)degree)) {
01177       for(double j=1;j< (n_v+degree-1-v_prec/2.0*(n_v+degree)) && n_v>1 ; j+=v_prec/2.0*((double)n_v+(double)degree)) {
01178 
01179         Point3d pos;
01180         Point3d nrml;
01181 
01182         pos=Eval(i,j);
01183         glColor3f(1.0,0.0,0.0);
01184         nrml=NormalEval(i,j);
01185 
01186         if(i==n_u && j==n_v)
01187           glColor3f(0.0,1.0,0.0);
01188         glVertex3d(pos[0],pos[1],pos[2]);
01189         pos=pos+nrml*0.05;
01190 
01191         glVertex3d(pos[0],pos[1],pos[2]);
01192       }
01193     }
01194     glEnd();
01195   }
01196     glEnable(GL_LIGHTING);
01197   
01198   glColor3dv(sel_point);
01199   glLineWidth(3.0);
01200   //  RenderSupport(selected[0],selected[1],selected_level);
01201   
01202   //  Render_Footprint();
01203   glLineWidth(1.0);
01204   //  Control_points[0]=temp;
01205   n_u=(int)Control_points[0].size();
01206   n_v=(int)Control_points[0][0].size();
01207   }
01208 
01209 
01210 void BSplineSurface::UpdateFootprint()
01211 {
01212   unsigned int line_size;
01213   //vector< vector< Point3d > > prior_to_subdivision=Control_points[0];  
01214 
01215   for(int i=selected_level-1;i>=0;i--) {
01216     if(Control_points[i].size()>Control_points[i+1].size()) {
01217       //      for(int j=footprint[i][3];j<=footprint[i][2];j++) {
01218       //for(int k=footprint[i][1];k<=footprint[i][0];k++) {
01219 
01220       for(unsigned int j=0;j<Control_points[i][0].size();j++) {
01221         for(unsigned int k=0;k<=Control_points[i].size();k++) {
01222           if(k<5) {
01223             if(k==0)
01224               Control_points[i][0][j]=Control_points[i+1][0][j];
01225             
01226             if(k==1) {
01227               Control_points[i][1][j]=Control_points[i+1][0][j]*(1.0/2.0)
01228                 +Control_points[i+1][1][j]*(1.0/2.0)
01229                 +Details[i][0][j];
01230             }
01231             if(k==2)
01232               Control_points[i][2][j]=Control_points[i+1][1][j]*(3.0/4.0)
01233                 +Control_points[i+1][2][j]*(1.0/4.0)
01234                 +Details[i][0][j]*(-2033.0/3000.0)
01235                 +Details[i][1][j]*(-49.0/152.0);
01236             
01237             if(k==3)
01238               Control_points[i][3][j]=Control_points[i+1][1][j]*(3.0/16.0)
01239                 +Control_points[i+1][2][j]*(11.0/16.0)
01240                 +Control_points[i+1][3][j]*(1.0/8.0)
01241                 +Details[i][0][j]*(2137.0/12000.0)
01242                 +Details[i][1][j]*(-289.0/608.0)
01243                 +Details[i][2][j]*(-23.0/208.0);
01244             
01245             if(k==4) {
01246               Control_points[i][4][j]=Control_points[i+1][2][j]*(1.0/2.0)
01247                 +Control_points[i+1][3][j]*(1.0/2.0)
01248                 +Details[i][0][j]*(139.0/500.0)
01249                 +Details[i][1][j]*1.0
01250                 +Details[i][2][j]*(-23.0/52.0);
01251             }
01252           } else {
01253             line_size=(int)Control_points[i].size()-1;
01254             unsigned int lsize2=(int)Control_points[i+1].size()-1;          
01255             if( k<line_size-4) {
01256               //              for(;k<line_size-4 && k<footprint[i][0];k++) {
01257               for(;k<line_size-4;k++) {
01258                 if(k%2==1) {   
01259                   Control_points[i][k][j]= Control_points[i+1][(k)/2][j]*(1.0/8.0)
01260                     +Control_points[i+1][(k)/2+1][j]*(3.0/4.0)
01261                     +Control_points[i+1][(k)/2+2][j]*(1.0/8.0);
01262                 } else {
01263                   Control_points[i][k][j]= Control_points[i+1][(k)/2][j]*(1.0/2.0)
01264                     +Control_points[i+1][(k)/2+1][j]*(1.0/2.0);
01265                 }
01266                 if(k<=7 || line_size-k<=7 ) {
01267                   if(k==5) {
01268                     Control_points[i][k][j]=Control_points[i][k][j]
01269                        +Details[i][0][j]*(139.0/2000.0)
01270                       +Details[i][1][j]*(-347.0/912.0)
01271                       +Details[i][2][j]*(-63.0/208.0)
01272                       +Details[i][3][j]*(-23.0/208.0);
01273 
01274                   } else if(k==6) {
01275                     Control_points[i][k][j]=Control_points[i][k][j]
01276                       +Details[i][1][j]*(-115.0/228.0)
01277                       +Details[i][2][j]*1.0
01278                       +Details[i][3][j]*(-23.0/52.0);
01279                     
01280                   } else if(k==7) {
01281                     Control_points[i][k][j]=Control_points[i][k][j]
01282                       +Details[i][1][j]*(-115.0/912.0)
01283                       +Details[i][2][j]*(-63.0/208.0)
01284                       +Details[i][3][j]*(-63.0/208.0)
01285                       +Details[i][4][j]*(-23.0/208.0);
01286 
01287                   } else if(k==line_size-7)
01288                     Control_points[i][k][j]=Control_points[i][k][j]
01289                       +Details[i][lsize2-4][j]*(-115.0/912.0)
01290                       +Details[i][lsize2-5][j]*(-63.0/208.0)
01291                       +Details[i][lsize2-6][j]*(-63.0/208.0)
01292                       +Details[i][lsize2-7][j]*(-23.0/208.0);
01293 
01294                   else if(k==line_size-6)
01295                     Control_points[i][k][j]=Control_points[i][k][j]
01296                       +Details[i][lsize2-4][j]*(-115.0/228.0)
01297                       +Details[i][lsize2-5][j]*1.0
01298                       +Details[i][lsize2-6][j]*(-23.0/52.0);
01299 
01300                   else if(k==line_size-5)
01301                     Control_points[i][k][j]=Control_points[i][k][j]
01302                       +Details[i][lsize2-3][j]*(139.0/2000.0)
01303                       +Details[i][lsize2-4][j]*(-347.0/912.0)
01304                       +Details[i][lsize2-5][j]*(-63.0/208.0)
01305                       +Details[i][lsize2-6][j]*(-23.0/208.0);
01306 
01307                 } else if(k%2==0)
01308                   Control_points[i][k][j]=Control_points[i][k][j]
01309                     +Details[i][(k-4)/2][j]*(-23.0/52.0)
01310                     +Details[i][(k-4)/2+1][j]*1.0
01311                     +Details[i][(k-4)/2+2][j]*(-23.0/52.0);
01312 
01313                 else
01314                   Control_points[i][k][j]=Control_points[i][k][j]
01315                     +Details[i][(k-4)/2][j]*(-23.0/208.0)
01316                     +Details[i][(k-4)/2+1][j]*(-63.0/208.0)
01317                     +Details[i][(k-4)/2+2][j]*(-63.0/208.0)
01318                     +Details[i][(k-4)/2+3][j]*(-23.0/208.0);
01319               }
01320             }
01321             if(k>=line_size-4) {
01322               if(k==line_size-4)
01323                 Control_points[i][line_size-4][j]=Control_points[i+1][lsize2-2][j]*(1.0/2.0)
01324                   +Control_points[i+1][lsize2-3][j]*(1.0/2.0)
01325                   +Details[i][lsize2-3][j]*(139.0/500.0)
01326                   +Details[i][lsize2-4][j]*1.0
01327                   +Details[i][lsize2-5][j]*(-23.0/52.0);
01328               
01329               if(k==line_size-3)
01330                 Control_points[i][line_size-3][j]=Control_points[i+1][lsize2-1][j]*(3.0/16.0)
01331                   +Control_points[i+1][lsize2-2][j]*(11.0/16.0)
01332                   +Control_points[i+1][lsize2-3][j]*(1.0/8.0)
01333                   +Details[i][lsize2-3][j]*(2137.0/12000.0)
01334                   +Details[i][lsize2-4][j]*(-289.0/608.0)
01335                   +Details[i][lsize2-5][j]*(-23.0/208.0);
01336               
01337               if(k==line_size-2)
01338                 Control_points[i][line_size-2][j]=Control_points[i+1][lsize2-1][j]*(3.0/4.0)
01339                   +Control_points[i+1][lsize2-2][j]*(1.0/4.0)
01340                   +Details[i][lsize2-3][j]*(-2033.0/3000.0)
01341                   +Details[i][lsize2-4][j]*(-49.0/152.0);
01342               
01343               if(k==line_size-1)
01344                 Control_points[i][line_size-1][j]=Control_points[i+1][lsize2][j]*(1.0/2.0)
01345                   +Control_points[i+1][lsize2-1][j]*(1.0/2.0)
01346                   +Details[i][lsize2-3][j];
01347               
01348               if(k==line_size)
01349                 Control_points[i][line_size][j]=Control_points[i+1][lsize2][j];
01350             }
01351           }
01352         }
01353       }
01354     } else {
01355       for(unsigned int j=0;j<Control_points[i].size();j++) {
01356         for(unsigned int k=0;k<=Control_points[i][0].size();k++) {
01357           //      for(int j=footprint[i][1];j<=footprint[i][0];j++) {
01358           //for(int k=footprint[i][3];k<=footprint[i][2];k++) {
01359           
01360           unsigned int lsize2=(int)Control_points[i+1][0].size()-1;               
01361           if(k<5) {
01362             if(k==0)
01363               Control_points[i][j][0]=Control_points[i+1][j][0]*1.0;
01364             
01365             if(k==1)
01366               Control_points[i][j][1]=Control_points[i+1][j][0]*(1.0/2.0)
01367                 +Control_points[i+1][j][1]*(1.0/2.0)
01368                 +Details[i][j][0];
01369             
01370             if(k==2)
01371               Control_points[i][j][2]=Control_points[i+1][j][1]*(3.0/4.0)
01372                 +Control_points[i+1][j][2]*(1.0/4.0)
01373                 +Details[i][j][0]*(-2033.0/3000.0)
01374                 +Details[i][j][1]*(-49.0/152.0);
01375             
01376             if(k==3)
01377               Control_points[i][j][3]=Control_points[i+1][j][1]*(3.0/16.0)
01378                 +Control_points[i+1][j][2]*(11.0/16.0)
01379                 +Control_points[i+1][j][3]*(1.0/8.0)
01380                 +Details[i][j][0]*(2137.0/12000.0)
01381                 +Details[i][j][1]*(-289.0/608.0)
01382                 +Details[i][j][2]*(-23.0/208.0);
01383             
01384             if(k==4)
01385               Control_points[i][j][4]=Control_points[i+1][j][2]*(1.0/2.0)
01386                 +Control_points[i+1][j][3]*(1.0/2.0)
01387                 +Details[i][j][0]*(139.0/500.0)
01388                 +Details[i][j][1]*1.0
01389                 +Details[i][j][2]*(-23.0/52.0);
01390 
01391           } else {
01392             
01393             line_size=(int)Control_points[i][0].size()-1;
01394 
01395             if( k<line_size-4) {
01396               for(;k<line_size-4;k++) {
01397                 //            for(;k<line_size-4 && k<footprint[i][2];k++) {
01398                 if(k%2) {   
01399                   Control_points[i][j][k]= Control_points[i+1][j][(k)/2]*(1.0/8.0)
01400                     +Control_points[i+1][j][(k)/2+1]*(3.0/4.0)
01401                     +Control_points[i+1][j][(k)/2+2]*(1.0/8.0);
01402                 }
01403                 else{
01404                   Control_points[i][j][k]= Control_points[i+1][j][(k)/2]*(1.0/2.0)
01405                     +Control_points[i+1][j][(k)/2+1]*(1.0/2.0);
01406                 }
01407                 if(k<=7 || k>=line_size-7 ) {
01408                   if(k==5) {
01409                     Control_points[i][j][k]=Control_points[i][j][k]
01410                        +Details[i][j][0]*(139.0/2000.0)
01411                       +Details[i][j][1]*(-347.0/912.0)
01412                       +Details[i][j][2]*(-63.0/208.0)
01413                       +Details[i][j][3]*(-23.0/208.0);
01414                     
01415                   } else if(k==6) {
01416                     Control_points[i][j][k]=Control_points[i][j][k]
01417                       +Details[i][j][1]*(-115.0/228.0)
01418                       +Details[i][j][2]*1.0
01419                       +Details[i][j][3]*(-23.0/52.0);
01420                   }
01421 
01422                   else if(k==7) {
01423                     Control_points[i][j][k]=Control_points[i][j][k]
01424                       +Details[i][j][1]*(-115.0/912.0)
01425                       +Details[i][j][2]*(-63.0/208.0)
01426                       +Details[i][j][3]*(-63.0/208.0)
01427                       +Details[i][j][4]*(-23.0/208.0);
01428                     
01429                   } else if(k==line_size-7)
01430                     Control_points[i][j][k]=Control_points[i][j][k]
01431                       +Details[i][j][lsize2-4]*(-115.0/912.0)
01432                       +Details[i][j][lsize2-5]*(-63.0/208.0)
01433                       +Details[i][j][lsize2-6]*(-63.0/208.0)
01434                       +Details[i][j][lsize2-7]*(-23.0/208.0);
01435 
01436                   else if(k==line_size-6)
01437                     Control_points[i][j][k]=Control_points[i][j][k]
01438                       +Details[i][j][lsize2-4]*(-115.0/228.0)
01439                       +Details[i][j][lsize2-5]*1.0
01440                       +Details[i][j][lsize2-6]*(-23.0/52.0);
01441 
01442                   else if(k==line_size-5)
01443                     Control_points[i][j][k]=Control_points[i][j][k]
01444                       +Details[i][j][lsize2-3]*(139.0/2000.0)
01445                       +Details[i][j][lsize2-4]*(-347.0/912.0)
01446                       +Details[i][j][lsize2-5]*(-63.0/208.0)
01447                       +Details[i][j][lsize2-6]*(-23.0/208.0);
01448                 } else if(k%2==0)
01449                   Control_points[i][j][k]=Control_points[i][j][k]
01450                     +Details[i][j][(k-4)/2]*(-23.0/52.0)
01451                     +Details[i][j][(k-4)/2+1]*1.0
01452                     +Details[i][j][(k-4)/2+2]*(-23.0/52.0);
01453                 else
01454                   Control_points[i][j][k]=Control_points[i][j][k]
01455                     +Details[i][j][(k-4)/2]*(-23.0/208.0)
01456                     +Details[i][j][(k-4)/2+1]*(-63.0/208.0)
01457                     +Details[i][j][(k-4)/2+2]*(-63.0/208.0)
01458                     +Details[i][j][(k-4)/2+3]*(-23.0/208.0);
01459               }
01460             }
01461             if(k>=line_size-4) {
01462               if(k==line_size-4)
01463                 Control_points[i][j][line_size-4]=Control_points[i+1][j][lsize2-2]*(1.0/2.0)
01464                   +Control_points[i+1][j][lsize2-3]*(1.0/2.0)
01465                   +Details[i][j][lsize2-3]*(139.0/500.0)
01466                   +Details[i][j][lsize2-4]*1.0
01467                   +Details[i][j][lsize2-5]*(-23.0/52.0);
01468               
01469               if(k==line_size-3)
01470               Control_points[i][j][line_size-3]=Control_points[i+1][j][lsize2-1]*(3.0/16.0)
01471                 +Control_points[i+1][j][lsize2-2]*(11.0/16.0)
01472                 +Control_points[i+1][j][lsize2-3]*(1.0/8.0)
01473                 +Details[i][j][lsize2-3]*(2137.0/12000.0)
01474                 +Details[i][j][lsize2-4]*(-289.0/608.0)
01475                 +Details[i][j][lsize2-5]*(-23.0/208.0);
01476               
01477               if(k==line_size-2)
01478                 Control_points[i][j][line_size-2]=Control_points[i+1][j][lsize2-1]*(3.0/4.0)
01479                   +Control_points[i+1][j][lsize2-2]*(1.0/4.0)
01480                   +Details[i][j][lsize2-3]*(-2033.0/3000.0)
01481                   +Details[i][j][lsize2-4]*(-49.0/152.0);
01482               
01483               if(k==line_size-1)
01484                 Control_points[i][j][line_size-1]=Control_points[i+1][j][lsize2]*(1.0/2.0)
01485                   +Control_points[i+1][j][lsize2-1]*(1.0/2.0)
01486                   +Details[i][j][lsize2-3];
01487               
01488               if(k==line_size)
01489                 Control_points[i][j][line_size]=Control_points[i+1][j][lsize2];       
01490             }
01491           }
01492         }
01493       }
01494     }
01495   }
01496   for(unsigned int i=selected_level+1;i<Control_points.size();i++) {
01497     if(Control_points[i].size()<Control_points[i-1].size()) {
01498       unsigned int line_size=(int)Control_points[i].size()-1;
01499       for(unsigned int j=0;j<Control_points[i][0].size();j++) {
01500         for(unsigned int k=0;k<=Control_points[i].size();k++) {
01501           //      for(int j=footprint[i][3];j<=footprint[i][2];j++) {
01502           //for(int k=footprint[i][1];k<=footprint[i][0];k++) {
01503           unsigned int l2=(int)Control_points[i-1].size()-1;
01504 
01505           //      std::cout<<Details.size()<<" "<<Control_points[i-1][0].size()<<" "<<Control_points[0][0].size()<<std::endl;
01506           if(k==0) {
01507             Control_points[i][0][j]=Control_points[i-1][0][j];
01508 
01509             Details[i-1][0][j]=Control_points[i-1][0][j]*(-45.0/139.0)
01510               +Control_points[i-1][1][j]*(90.0/139.0)
01511               +Control_points[i-1][2][j]*(-135.0/278.0)
01512               +Control_points[i-1][3][j]*(30.0/139.0)
01513               +Control_points[i-1][4][j]*(-15.0/278.0);
01514           }
01515           if(k==1) {
01516             Control_points[i][1][j]=Control_points[i-1][0][j]*(-49.0/139.0)
01517               +Control_points[i-1][1][j]*(98.0/139.0)
01518               +Control_points[i-1][2][j]*(135.0/139.0)
01519               +Control_points[i-1][3][j]*(-60.0/139.0)
01520               +Control_points[i-1][4][j]*(15.0/139.0);
01521 
01522             Details[i-1][1][j]=Control_points[i-1][2][j]*(57.0/490.0)
01523               +Control_points[i-1][3][j]*(-114.0/245.0)
01524               +Control_points[i-1][4][j]*(171.0/245.0)
01525               +Control_points[i-1][5][j]*(-114.0/245.0)
01526               +Control_points[i-1][6][j]*(57.0/490.0);
01527 
01528           }
01529           if(k==2) {
01530             Control_points[i][2][j]=Control_points[i-1][0][j]*(9.0/50.0)
01531               +Control_points[i-1][1][j]*(-9.0/25.0)
01532               +Control_points[i-1][2][j]*(-2.0/25.0)
01533               +Control_points[i-1][3][j]*(32.0/25.0)
01534               +Control_points[i-1][4][j]*(43.0/100.0)       
01535               +Control_points[i-1][5][j]*(-3.0/5.0)
01536               +Control_points[i-1][6][j]*(3.0/20.0);
01537         
01538             
01539             Details[i-1][2][j]=Control_points[i-1][4][j]*(13.0/98.0)
01540               +Control_points[i-1][5][j]*(-26.0/49.0)
01541               +Control_points[i-1][6][j]*(39.0/49.0)
01542               +Control_points[i-1][7][j]*(-26.0/49.0)
01543               +Control_points[i-1][8][j]*(13.0/98.0);
01544           }
01545           
01546           if(k>=3 && k<=line_size-3) {
01547             unsigned int band_start=(k-3)*2+2;
01548 
01549             Control_points[i][k][j]=Control_points[i-1][band_start][j]*(23.0/196.0)
01550               +Control_points[i-1][band_start+1][j]*(-23.0/49.0)
01551               +Control_points[i-1][band_start+2][j]*(9.0/28.0)
01552               +Control_points[i-1][band_start+3][j]*(52.0/49.0)
01553               +Control_points[i-1][band_start+4][j]*(9.0/28.0)
01554               +Control_points[i-1][band_start+5][j]*(-23.0/49.0)
01555               +Control_points[i-1][band_start+6][j]*(23.0/196.0);
01556            
01557             //if(k<line_size/2)
01558             if(2*k<l2-8) {
01559 
01560             Details[i-1][k][j]=Control_points[i-1][2*k][j]*(13.0/98.0)
01561               +Control_points[i-1][2*k+1][j]*(-26.0/49.0)
01562               +Control_points[i-1][2*k+2][j]*(39.0/49.0)
01563               +Control_points[i-1][2*k+3][j]*(-26.0/49.0)
01564               +Control_points[i-1][2*k+4][j]*(13.0/98.0);
01565 
01566             //      std::cout<<line_size-k<<std::endl;
01567             }
01568             
01569             /*      else
01570               Details[i-1][k][j]=Control_points[i-1][2*k-4][j]*(13.0/98.0)
01571                 +Control_points[i-1][2*k+1-4][j]*(-26.0/49.0)
01572                 +Control_points[i-1][2*k+2-4][j]*(39.0/49.0)
01573                 +Control_points[i-1][2*k+3-4][j]*(-26.0/49.0)
01574                 +Control_points[i-1][2*k+4-4][j]*(13.0/98.0);
01575             */
01576           }
01577 
01578           if(k==line_size-2) {
01579 
01580             Control_points[i][line_size-2][j]=Control_points[i-1][l2][j]*(9.0/50.0)
01581               +Control_points[i-1][l2-1][j]*(-9.0/25.0)
01582               +Control_points[i-1][l2-2][j]*(-2.0/25.0)
01583               +Control_points[i-1][l2-3][j]*(32.0/25.0)
01584               +Control_points[i-1][l2-4][j]*(43.0/100.0)            
01585               +Control_points[i-1][l2-5][j]*(-3.0/5.0)
01586               +Control_points[i-1][l2-6][j]*(3.0/20.0);
01587             //      std::cout<<l2-8<<" "<<2*(k-1)<<" "<<l2<<std::endl;
01588                     
01589             Details[i-1][line_size-5][j]=Control_points[i-1][l2-4][j]*(13.0/98.0)
01590               +Control_points[i-1][l2-5][j]*(-26.0/49.0)
01591               +Control_points[i-1][l2-6][j]*(39.0/49.0)
01592               +Control_points[i-1][l2-7][j]*(-26.0/49.0)
01593               +Control_points[i-1][l2-8][j]*(13.0/98.0);
01594           }
01595           if(k==line_size-1) {
01596             Control_points[i][line_size-1][j]=Control_points[i-1][l2][j]*(-49.0/139.0)
01597               +Control_points[i-1][l2-1][j]*(98.0/139.0)
01598               +Control_points[i-1][l2-2][j]*(135.0/139.0)
01599               +Control_points[i-1][l2-3][j]*(-60.0/139.0)
01600               +Control_points[i-1][l2-4][j]*(15.0/139.0);
01601 
01602             Details[i-1][line_size-4][j]=Control_points[i-1][l2-2][j]*(57.0/490.0)
01603               +Control_points[i-1][l2-3][j]*(-114.0/245.0)
01604               +Control_points[i-1][l2-4][j]*(171.0/245.0)
01605               +Control_points[i-1][l2-5][j]*(-114.0/245.0)
01606               +Control_points[i-1][l2-6][j]*(57.0/490.0);
01607           }
01608             
01609           if(k==line_size) {
01610             Control_points[i][line_size][j]=Control_points[i-1][l2][j]; 
01611             Details[i-1][line_size-3][j]=Control_points[i-1][l2][j]*(-45.0/139.0)
01612               +Control_points[i-1][l2-1][j]*(90.0/139.0)
01613               +Control_points[i-1][l2-2][j]*(-135.0/278.0)
01614               +Control_points[i-1][l2-3][j]*(30.0/139.0)
01615               +Control_points[i-1][l2-4][j]*(-15.0/278.0);
01616           }
01617         }
01618       }
01619     } else {
01620       unsigned int line_size=(int)Control_points[i][0].size()-1;      
01621 
01622       for(unsigned int j=0;j<Control_points[i].size();j++) {
01623         for(unsigned int k=0;k<=Control_points[i][0].size();k++) {
01624           //      for(int j=footprint[i][1];j<=footprint[i][0];j++) {
01625           //for(int k=footprint[i][3];k<=footprint[i][2];k++) {
01626           unsigned int l2=(int)Control_points[i-1][0].size()-1;
01627 
01628           if(k==0) {
01629             //      std::cout<<i<<" "<<j<<" "<<k<<std::endl;
01630             //std::cout<<Control_points.size()<<" "<<Control_points[i-1].size()<<" "<<Control_points[i-1][0].size()<<std::endl;
01631 
01632             Control_points[i][j][0]=Control_points[i-1][j][0];
01633 
01634             Details[i-1][j][0]=Control_points[i-1][j][0]*(-45.0/139.0)
01635               +Control_points[i-1][j][1]*(90.0/139.0)
01636               +Control_points[i-1][j][2]*(-135.0/278.0)
01637               +Control_points[i-1][j][3]*(30.0/139.0)
01638               +Control_points[i-1][j][4]*(-15.0/278.0);
01639           }
01640           if(k==1) {
01641             Control_points[i][j][1]=Control_points[i-1][j][0]*(-49.0/139.0)
01642               +Control_points[i-1][j][1]*(98.0/139.0)
01643               +Control_points[i-1][j][2]*(135.0/139.0)
01644               +Control_points[i-1][j][3]*(-60.0/139.0)
01645               +Control_points[i-1][j][4]*(15.0/139.0);
01646               
01647             Details[i-1][j][1]=Control_points[i-1][j][2]*(57.0/490.0)
01648               +Control_points[i-1][j][3]*(-114.0/245.0)
01649               +Control_points[i-1][j][4]*(171.0/245.0)
01650               +Control_points[i-1][j][5]*(-114.0/245.0)
01651               +Control_points[i-1][j][6]*(57.0/490.0);
01652           }
01653           if(k==2) {
01654             Control_points[i][j][2]=Control_points[i-1][j][0]*(9.0/50.0)
01655               +Control_points[i-1][j][1]*(-9.0/25.0)
01656               +Control_points[i-1][j][2]*(-2.0/25.0)
01657               +Control_points[i-1][j][3]*(32.0/25.0)
01658               +Control_points[i-1][j][4]*(43.0/100.0)       
01659               +Control_points[i-1][j][5]*(-3.0/5.0)
01660               +Control_points[i-1][j][6]*(3.0/20.0);
01661 
01662             Details[i-1][j][2]=Control_points[i-1][j][4]*(13.0/98.0)
01663               +Control_points[i-1][j][5]*(-26.0/49.0)
01664               +Control_points[i-1][j][6]*(39.0/49.0)
01665               +Control_points[i-1][j][7]*(-26.0/49.0)
01666               +Control_points[i-1][j][8]*(13.0/98.0);
01667           }
01668           
01669           if(k>=3 && k<=line_size-3) {
01670             unsigned int band_start=(k-3)*2+2;
01671 
01672             Control_points[i][j][k]=Control_points[i-1][j][band_start]*(23.0/196.0)
01673               +Control_points[i-1][j][band_start+1]*(-23.0/49.0)
01674               +Control_points[i-1][j][band_start+2]*(9.0/28.0)
01675               +Control_points[i-1][j][band_start+3]*(52.0/49.0)
01676               +Control_points[i-1][j][band_start+4]*(9.0/28.0)
01677               +Control_points[i-1][j][band_start+5]*(-23.0/49.0)
01678               +Control_points[i-1][j][band_start+6]*(23.0/196.0);
01679             //      std::cout<<band_start+6<<std::endl;
01680             // std::cout<<l2<<std::endl;
01681 
01682             if(2*k<l2-8) {          
01683              Details[i-1][j][k]=Control_points[i-1][j][2*k]*(13.0/98.0)
01684               +Control_points[i-1][j][2*k+1]*(-26.0/49.0)
01685               +Control_points[i-1][j][2*k+2]*(39.0/49.0)
01686               +Control_points[i-1][j][2*k+3]*(-26.0/49.0)
01687               +Control_points[i-1][j][2*k+4]*(13.0/98.0);
01688             }
01689           }
01690        
01691           if(k==line_size-2) {
01692             Control_points[i][j][line_size-2]=Control_points[i-1][j][l2]*(9.0/50.0)
01693               +Control_points[i-1][j][l2-1]*(-9.0/25.0)
01694               +Control_points[i-1][j][l2-2]*(-2.0/25.0)
01695               +Control_points[i-1][j][l2-3]*(32.0/25.0)
01696               +Control_points[i-1][j][l2-4]*(43.0/100.0)            
01697               +Control_points[i-1][j][l2-5]*(-3.0/5.0)
01698               +Control_points[i-1][j][l2-6]*(3.0/20.0);
01699    
01700             Details[i-1][j][line_size-5]=Control_points[i-1][j][l2-4]*(13.0/98.0)
01701               +Control_points[i-1][j][l2-5]*(-26.0/49.0)
01702               +Control_points[i-1][j][l2-6]*(39.0/49.0)
01703               +Control_points[i-1][j][l2-7]*(-26.0/49.0)
01704               +Control_points[i-1][j][l2-8]*(13.0/98.0);
01705           }
01706           if(k==line_size-1) {
01707             Control_points[i][j][line_size-1]=Control_points[i-1][j][l2]*(-49.0/139.0)
01708               +Control_points[i-1][j][l2-1]*(98.0/139.0)
01709               +Control_points[i-1][j][l2-2]*(135.0/139.0)
01710               +Control_points[i-1][j][l2-3]*(-60.0/139.0)
01711               +Control_points[i-1][j][l2-4]*(15.0/139.0);
01712 
01713             Details[i-1][j][line_size-4]=Control_points[i-1][j][l2-2]*(57.0/490.0)
01714               +Control_points[i-1][j][l2-3]*(-114.0/245.0)
01715               +Control_points[i-1][j][l2-4]*(171.0/245.0)
01716               +Control_points[i-1][j][l2-5]*(-114.0/245.0)
01717               +Control_points[i-1][j][l2-6]*(57.0/490.0);             
01718           }
01719             
01720           if(k==line_size) {
01721             Control_points[i][j][line_size]=Control_points[i-1][j][l2]; 
01722             
01723             Details[i-1][j][line_size-3]=Control_points[i-1][j][l2]*(-45.0/139.0)
01724               +Control_points[i-1][j][l2-1]*(90.0/139.0)
01725               +Control_points[i-1][j][l2-2]*(-135.0/278.0)
01726               +Control_points[i-1][j][l2-3]*(30.0/139.0)
01727               +Control_points[i-1][j][l2-4]*(-15.0/278.0);
01728 
01729           }
01730         }
01731       }
01732     }
01733   }  
01734 }
01735 
01736 /*
01737 void BSplineSurface::Update_position(int i, int j, int level) {
01738 
01739   if(Control_points[level].size()<Control_points[level-1].size()) {
01740 
01741     if(i==0) {
01742 
01743       Control_points[level][0][j]=Control_points[level+1][i][j];
01744       Control_points[level][1][j]=Control_points[level+1][1][j]*(1.0/2.0)
01745         +Control_points[level][1][j]*(1.0/2.0);
01746 
01747     } else if(i==1) {
01748     } else if(i==2) {
01749     } else if(i>=3 && i<(Control_points[level].size()-3)) {
01750     } else {
01751       int l=Control_points[level].size()-1;
01752       int l2=Control_points[level-1].size()-1;
01753     if(i==l) {
01754     } else if(i==l-1) {
01755     } else if(i==l-2) {
01756     } else {
01757       if(j==0) {
01758         RenderSupport(i ,0 , level-1);
01759         RenderSupport(i ,1 , level-1);
01760       } else if(j==1) {
01761         RenderSupport(i,1, level-1);
01762         RenderSupport(i,2, level-1);
01763         RenderSupport(i,3, level-1);
01764       } else if(j==2) {
01765         RenderSupport(i,2,level-1);
01766         RenderSupport(i,3,level-1);
01767         RenderSupport(i,4,level-1);
01768         RenderSupport(i,5,level-1);
01769       } else if(j>=3 && j<(Control_points[level][0].size()-3)) {
01770         RenderSupport(i,2*(j-3)+3,level-1);
01771         RenderSupport(i,2*(j-3)+4,level-1);
01772         RenderSupport(i,2*(j-3)+5,level-1);
01773         RenderSupport(i,2*(j-3)+6,level-1);
01774         RenderSupport(i,2*(j-3)+7,level-1);
01775       } else{
01776         int l=Control_points[level][0].size()-1;
01777         int l2=Control_points[level-1][0].size()-1;
01778       if(j==l) {
01779         RenderSupport(i ,l2 , level-1);
01780         RenderSupport(i,l2-1 , level-1);
01781       } else if(j==l-1) {
01782         RenderSupport(i,l2-1, level-1);
01783         RenderSupport(i,l2-2, level-1);
01784         RenderSupport(i,l2-3, level-1);
01785       } else if(j==l-2) {
01786         RenderSupport(i,l2-2,level-1);
01787         RenderSupport(i,l2-3,level-1);
01788         RenderSupport(i,l2-4,level-1);
01789         RenderSupport(i,l2-5,level-1);
01790       }
01791     }
01792   }
01793 }
01794 */
01795 
01796 void BSplineSurface::CalcPreImage(int i, int j, unsigned int level) 
01797 {
01798   if(i>footprint[level][0])
01799     footprint[level][0]=i;
01800   if(i<footprint[level][1])
01801     footprint[level][1]=i;
01802   if(j>footprint[level][2])
01803     footprint[level][2]=j;
01804   if(j<footprint[level][3])
01805     footprint[level][3]=j;
01806 
01807   if(level<Control_points.size()-1) {
01808     if(Control_points[level].size()>Control_points[level+1].size()) {
01809       int line_size=(int)Control_points[level].size()-1;
01810       if(i==0) {
01811         CalcPreImage(0,j,level+1);
01812         CalcPreImage(2,j,level+1);
01813       }
01814 
01815       if(i==1) {
01816         CalcPreImage(0,j,level+1);
01817         CalcPreImage(2,j,level+1);
01818       }
01819 
01820       if(i==2) {
01821         CalcPreImage(0,j,level+1);
01822         CalcPreImage(3,j, level+1);
01823       }
01824 
01825       if(i>2 && i<line_size-2) {
01826         if(i>6)
01827           CalcPreImage(i/2-(i+1)%2,j,level+1);
01828         else
01829           CalcPreImage(0,j,level+1);
01830         CalcPreImage(i/2+3,j,level+1);
01831       }
01832 
01833       int l2=(int)Control_points[level+1].size()-1;
01834 
01835       if(i==line_size) {
01836         CalcPreImage(l2,j,level+1);
01837         CalcPreImage(l2-2,j,level+1);
01838       }
01839 
01840       if(i==line_size-1) {
01841         CalcPreImage(l2-2,j,level+1);
01842         CalcPreImage(l2-1,j,level+1);
01843       }
01844 
01845       if(i==line_size-2) {
01846         CalcPreImage(l2-3,j, level+1);
01847         CalcPreImage(l2-1,j,level+1);
01848       }
01849     } else {
01850       int line_size=(int)Control_points[level][0].size()-1;
01851 
01852       if(j==0) {
01853         CalcPreImage(i,0,level+1);
01854         CalcPreImage(i,2,level+1);
01855       }
01856 
01857       if(j==1) {
01858         CalcPreImage(i,1,level+1);
01859         CalcPreImage(i,2,level+1);
01860       }
01861 
01862       if(j==2) {
01863         CalcPreImage(i,1,level+1);
01864         CalcPreImage(i,3, level+1);
01865       }
01866 
01867       if(j>2 && j<line_size-2) {
01868         CalcPreImage(i,j/2-(j+1)%2,level+1);
01869         CalcPreImage(i,j/2+2,level+1);
01870       }
01871 
01872       int l2=(int)Control_points[level+1][0].size()-1;
01873 
01874       if(j==line_size) {
01875         CalcPreImage(i,l2-2,level+1);
01876         CalcPreImage(i,l2,level+1);
01877       }
01878 
01879       if(j==line_size-1) {
01880         CalcPreImage(i,l2-2,level+1);
01881         CalcPreImage(i,l2-1,level+1);
01882       }
01883 
01884       if(j==line_size-2) {
01885         CalcPreImage(i,l2-3, level+1);
01886         CalcPreImage(i,l2-1,level+1);
01887       }
01888     }
01889   }
01890 }
01891 
01892 void BSplineSurface::CalcFootprint(unsigned int i,unsigned int j,unsigned int level) {
01893 
01894   if((int)i>footprint[level][0])
01895     footprint[level][0]=(int)i;
01896   if((int)i<footprint[level][1])
01897     footprint[level][1]=(int)i;
01898   if((int)j>footprint[level][2])
01899     footprint[level][2]=(int)j;
01900   if((int)j<footprint[level][3])
01901     footprint[level][3]=(int)j;
01902 
01903   if(level) {
01904     if(Control_points[level].size()<Control_points[level-1].size()) {
01905       if(i==0) {
01906           CalcFootprint(0 ,j , level-1);
01907           CalcFootprint(1 ,j , level-1);
01908 
01909       } else if(i==1) {
01910           CalcFootprint(1,j,level-1);
01911           CalcFootprint(3,j, level-1);
01912 
01913       } else if(i==2) {
01914         CalcFootprint(2,j,level-1);
01915         CalcFootprint(5,j,level-1);
01916 
01917       } else if(i>=3 && i<(Control_points[level].size()-3)) {
01918         CalcFootprint(2*(i-3)+3,j,level-1);
01919         CalcFootprint(2*(i-3)+7,j,level-1);
01920 
01921       } else {
01922         unsigned int l=(int)Control_points[level].size()-1;
01923         unsigned int l2=(int)Control_points[level-1].size()-1;
01924 
01925         if(i==l) {
01926           CalcFootprint(l2 ,j , level-1);
01927           CalcFootprint(l2-1 ,j , level-1);
01928 
01929         } else if(i==l-1) {
01930           CalcFootprint(l2-1,j, level-1);
01931           CalcFootprint(l2-3,j, level-1);
01932 
01933         } else if(i==l-2) {
01934           CalcFootprint(l2-2,j,level-1);
01935           CalcFootprint(l2-5,j,level-1);
01936         }      
01937       }
01938     } else {
01939       if(j==0) {
01940         CalcFootprint(i ,0 , level-1);
01941         CalcFootprint(i ,1 , level-1);
01942 
01943       } else if(j==1) {
01944         CalcFootprint(i,1, level-1);
01945         CalcFootprint(i,3, level-1);
01946 
01947       } else if(j==2) {
01948         CalcFootprint(i,2,level-1);
01949         CalcFootprint(i,5,level-1);
01950 
01951       } else if(j>=3 && j<(Control_points[level][0].size()-3)) {
01952         CalcFootprint(i,2*(j-3)+3,level-1);
01953         CalcFootprint(i,2*(j-3)+7,level-1);
01954 
01955       } else {
01956         unsigned int l=(int)Control_points[level][0].size()-1;
01957         unsigned int l2=(int)Control_points[level-1][0].size()-1;
01958 
01959         if(j==l) {
01960           CalcFootprint(i ,l2 , level-1);
01961           CalcFootprint(i,l2-1 , level-1);
01962         
01963         } else if(j==l-1) {
01964           CalcFootprint(i,l2-1, level-1);
01965           CalcFootprint(i,l2-3, level-1);
01966 
01967         } else if(j==l-2) {
01968           CalcFootprint(i,l2-2,level-1);
01969           CalcFootprint(i,l2-5,level-1);
01970         }
01971       }
01972     }
01973   }
01974 }
01975 
01976 void BSplineSurface::RenderFootprint() {
01977 
01978   for(unsigned int i=0;i<footprint.size();i++) {
01979     RenderLine( footprint[i][0],footprint[i][2] ,i,footprint[i][0] ,footprint[i][3] ,i);
01980     RenderLine( footprint[i][0],footprint[i][2] ,i,footprint[i][1] ,footprint[i][2] ,i);
01981     RenderLine( footprint[i][1],footprint[i][2] ,i,footprint[i][1] ,footprint[i][3] ,i);
01982     RenderLine( footprint[i][0],footprint[i][3] ,i,footprint[i][1] ,footprint[i][3] ,i);
01983   }
01984 }
01985 
01986 void BSplineSurface::RenderSupport(unsigned int i,unsigned int j,unsigned int level) 
01987 {
01988   if(level) {
01989     if(Control_points[level].size()<Control_points[level-1].size()) {
01990       if(i==0) {
01991         RenderLine(i,j,level,0,j,level-1);
01992         RenderSupport(0 ,j , level-1);
01993         RenderLine(i,j,level,1,j,level-1);
01994         RenderSupport(1 ,j , level-1);
01995 
01996       } else if(i==1) {
01997         RenderLine(i,j,level,1,j,level-1);
01998         RenderSupport(1,j, level-1);
01999         RenderLine(i,j,level,2,j,level-1);
02000         RenderSupport(2,j, level-1);
02001         RenderLine(i,j,level,3,j,level-1);
02002         RenderSupport(3,j, level-1);
02003 
02004       } else if(i==2) {
02005         RenderLine(i,j,level,2,j,level-1);
02006         RenderSupport(2,j,level-1);
02007         RenderLine(i,j,level,3,j,level-1);
02008         RenderSupport(3,j,level-1);
02009         RenderLine(i,j,level,4,j,level-1);
02010         RenderSupport(4,j,level-1);
02011         RenderLine(i,j,level,5,j,level-1);
02012         RenderSupport(5,j,level-1);
02013 
02014       } else if(i>=3 && i<(Control_points[level].size()-3)) {
02015         RenderLine(i,j,level,2*(i-3)+3,j,level-1);
02016         RenderSupport(2*(i-3)+3,j,level-1);
02017         RenderLine(i,j,level,2*(i-3)+4,j,level-1);
02018         RenderSupport(2*(i-3)+4,j,level-1);
02019         RenderLine(i,j,level,2*(i-3)+5,j,level-1);
02020         RenderSupport(2*(i-3)+5,j,level-1);
02021         RenderLine(i,j,level,2*(i-3)+6,j,level-1);
02022         RenderSupport(2*(i-3)+6,j,level-1);
02023         RenderLine(i,j,level,2*(i-3)+7,j,level-1);
02024         RenderSupport(2*(i-3)+7,j,level-1);
02025 
02026       } else {
02027         unsigned int l=(int)Control_points[level].size()-1;
02028         unsigned int l2=(int)Control_points[level-1].size()-1;
02029         if(i==l) {
02030           RenderLine(i,j,level,l2,j,level-1);
02031           RenderSupport(l2 ,j , level-1);
02032           RenderLine(i,j,level,l2-1,j,level-1);
02033           RenderSupport(l2-1 ,j , level-1);
02034         
02035         } else if(i==l-1) {
02036           RenderLine(i,j,level,l2-1,j,level-1);
02037           RenderSupport(l2-1,j, level-1);
02038           RenderLine(i,j,level,l2-2,j,level-1);
02039           RenderSupport(l2-2,j, level-1);
02040           RenderLine(i,j,level,l2-3,j,level-1);
02041           RenderSupport(l2-3,j, level-1);
02042 
02043         } else if(i==l-2) {
02044           RenderLine(i,j,level,l2-2,j,level-1);
02045           RenderSupport(l2-2,j,level-1);
02046           RenderLine(i,j,level,l2-3,j,level-1);
02047           RenderSupport(l2-3,j,level-1);
02048           RenderLine(i,j,level,l2-4,j,level-1);
02049           RenderSupport(l2-4,j,level-1);
02050           RenderLine(i,j,level,l2-5,j,level-1);
02051           RenderSupport(l2-5,j,level-1);
02052         }
02053       }
02054     } else {
02055       if(j==0) {
02056         RenderLine(i,j,level,i,0,level-1);
02057         RenderSupport(i ,0 , level-1);
02058         RenderLine(i,j,level,i,1,level-1);
02059         RenderSupport(i ,1 , level-1);
02060 
02061       } else if(j==1) {
02062         RenderLine(i,j,level,i,1,level-1);
02063         RenderSupport(i,1, level-1);
02064         RenderLine(i,j,level,i,2,level-1);
02065         RenderSupport(i,2, level-1);
02066         RenderLine(i,j,level,i,3,level-1);
02067         RenderSupport(i,3, level-1);
02068         
02069       } else if(j==2) {
02070         RenderLine(i,j,level,i,2,level-1);
02071         RenderSupport(i,2,level-1);
02072         RenderLine(i,j,level,i,3,level-1);
02073         RenderSupport(i,3,level-1);
02074         RenderLine(i,j,level,i,4,level-1);
02075         RenderSupport(i,4,level-1);
02076         RenderLine(i,j,level,i,5,level-1);
02077         RenderSupport(i,5,level-1);
02078 
02079       } else if(j>=3 && j<(Control_points[level][0].size()-3)) {
02080         RenderLine(i,j,level,i,2*(j-3)+3,level-1);
02081         RenderSupport(i,2*(j-3)+3,level-1);
02082         RenderLine(i,j,level,i,2*(j-3)+4,level-1);
02083         RenderSupport(i,2*(j-3)+4,level-1);
02084         RenderLine(i,j,level,i,2*(j-3)+5,level-1);
02085         RenderSupport(i,2*(j-3)+5,level-1);
02086         RenderLine(i,j,level,i,2*(j-3)+6,level-1);
02087         RenderSupport(i,2*(j-3)+6,level-1);
02088         RenderLine(i,j,level,i,2*(j-3)+7,level-1);
02089         RenderSupport(i,2*(j-3)+7,level-1);
02090 
02091       } else {
02092         unsigned int l=(int)Control_points[level][0].size()-1;
02093         unsigned int l2=(int)Control_points[level-1][0].size()-1;
02094 
02095         if(j==l) {
02096           RenderLine(i,j,level,i,l2,level-1);
02097           RenderSupport(i ,l2 , level-1);
02098           RenderLine(i,j,level,i,l2-1,level-1);
02099           RenderSupport(i,l2-1 , level-1);
02100 
02101         } else if(j==l-1) {
02102           RenderLine(i,j,level,i,l2-1,level-1);
02103           RenderSupport(i,l2-1, level-1);
02104           RenderLine(i,j,level,i,l2-2,level-1);
02105           RenderSupport(i,l2-2, level-1);
02106           RenderLine(i,j,level,i,l2-3,level-1);
02107           RenderSupport(i,l2-3, level-1);
02108         } else if(j==l-2) {
02109           RenderLine(i,j,level,i,l2-2,level-1);
02110           RenderSupport(i,l2-2,level-1);
02111           RenderLine(i,j,level,i,l2-3,level-1);
02112           RenderSupport(i,l2-3,level-1);
02113           RenderLine(i,j,level,i,l2-4,level-1);
02114           RenderSupport(i,l2-4,level-1);
02115           RenderLine(i,j,level,i,l2-5,level-1);
02116           RenderSupport(i,l2-5,level-1);
02117         }
02118       }
02119     }
02120   }
02121 }
02122 
02123 void BSplineSurface::RenderLine(int i1, int j1, int level1, int i2, int j2, int level2) 
02124 {
02125   glBegin(GL_LINES);
02126 
02127   glVertex3d(Control_points[level1][i1][j1][0],Control_points[level1][i1][j1][1],
02128                                            Control_points[level1][i1][j1][2]-(level1)*(MRES_OFF));
02129   glVertex3d(Control_points[level2][i2][j2][0],Control_points[level2][i2][j2][1],
02130                                            Control_points[level2][i2][j2][2]-(level2)*(MRES_OFF));
02131 
02132   glEnd();
02133 }
02134 
02135 
02136 void BSplineSurface::SelectPoint(Point3d n, Matrix3d A,Point3d trans) 
02137 {
02138   Point3d t;
02139 
02140   double dis=1000;
02141 
02142   for(unsigned int i=0;i<Control_points[selected_level].size();i++) {
02143     for(unsigned int j=0;j<Control_points[selected_level][0].size();j++) {
02144       t=Control_points[selected_level][i][j];
02145       t[2]=-t[2]+(selected_level)*(MRES_OFF);
02146       t=A*t;
02147       t[2]=0;
02148       t=t+trans;
02149       if( (n-t).norm()<dis) {
02150         dis=(n-t).norm();
02151         selected[0]=i;
02152         selected[1]=j;
02153       }
02154     }
02155   }
02156 
02157   for(unsigned int i=0;i<footprint.size();i++) {
02158     footprint[i][1]=footprint[i][3]=10000000;
02159     footprint[i][0]=footprint[i][2]=-1;
02160     footprint[i][1]=footprint[i][3]=0;
02161     footprint[i][0]=(int)Control_points[i].size()-1;
02162     footprint[i][2]=(int)Control_points[i][0].size()-1;
02163   }
02164   CalcFootprint(selected[0],selected[1],selected_level);
02165   CalcPreImage(selected[0],selected[1],selected_level);
02166 
02167   UpdateFootprint();
02168 }
02169 
02170 
02171 void BSplineSurface::MovePoint(Point3d n, Matrix3d A,Point3d trans) 
02172 {
02173   Point3d t;
02174 
02175   t=Control_points[selected_level][selected[0]][selected[1]];
02176   t[2]=-t[2]+(selected_level)*(MRES_OFF);
02177   t=A*t;
02178   t[0]=n[0]-trans[0];
02179   t[1]=n[1]-trans[1];
02180   t=(~A)*t;
02181   //potential problem
02182   t[2]=-t[2]+(selected_level)*(MRES_OFF);;
02183   Control_points[selected_level][selected[0]][selected[1]]=t;
02184 
02185   UpdateFootprint();
02186 }
02187   
02188 
02189 /*
02190 void BSplineSurface::set_level_rev(int i) 
02191 {
02192 }
02193 */
02194 
02195 bool BSplineSurface::EditLevel(unsigned int i) 
02196 {
02197   bool valid=true;
02198 
02199   if(i<Control_points.size())
02200     selected_level=i;
02201   else
02202     valid=false;
02203 
02204   selected[0]=0;
02205   selected[1]=0;
02206 
02207   for(unsigned int i=0;i<footprint.size();i++) {
02208 
02209     footprint[i][1]=footprint[i][3]=100000000;
02210     footprint[i][0]=footprint[i][2]=-1;
02211 
02212   }
02213 
02214   CalcFootprint(selected[0],selected[1],selected_level);
02215   CalcPreImage(selected[0],selected[1],selected_level);
02216   
02217   selected_region.clear();
02218   return valid;
02219 }
02220 
02221 Point3d BSplineSurface::Eval(double u, double v) const 
02222 {
02223   std::vector<Point3d> p_v(4);
02224   //Point3d p_v[4];
02225 
02226   if(u>(n_u))
02227     u=n_u;
02228 
02229   if(u<degree)
02230     u=degree;
02231 
02232   if(v>(n_v))
02233     v=n_v;
02234 
02235   if(v<degree)
02236     v=degree;
02237 
02238   int delta=(int)v;
02239 
02240   if(!periodic) {
02241     int i=0;
02242     for(;i<=degree && (delta-i)<=0;i++) 
02243       p_v[i]=EvalU(u,0);
02244 
02245     for(;i<=degree && (delta-i)<n_v;i++)
02246       p_v[i]=EvalU(u,delta-i);
02247 
02248     int t=n_v-1;
02249     for(;i<=degree;i++)
02250       p_v[i]=EvalU(u,t);
02251 
02252   } else {
02253     for(int i=0;i<=degree;i++) 
02254     {
02255       p_v[i]=EvalU(u,(delta-i+n_v)%(n_v));
02256     }
02257   }
02258 
02259   for(int i=degree+1; i>=2;i--) {
02260     double omega;
02261     double ind=delta;
02262     int j=0;
02263 
02264     for(;j<=i-1 && (i-1+ind>=n_v);j++,ind--) {
02265       if(n_v-ind>0 && v-ind>0)
02266         omega= (v-ind)/(n_v-ind);
02267       else
02268         omega=0;
02269 
02270       p_v[j]=p_v[j]*omega + p_v[j+1]*(1-omega);
02271 
02272     }
02273 
02274     for(;j<=i-1 ; j++, ind--){
02275       if((i-1+ind-(degree))<=0 || v-degree<=0){
02276         omega=0;
02277       }
02278       else if(ind<(degree)){
02279         omega= (v-(degree))/(i-1+ind-(degree));
02280       }
02281       else
02282         omega = (v-ind)/(i-1);
02283 
02284       p_v[j]=p_v[j]*omega + p_v[j+1]*(1-omega);
02285 
02286     }
02287   }
02288   return p_v[0];
02289 }
02290 
02291 Point3d BSplineSurface::EvalU(double u, int m) const 
02292 {
02293   std::vector<Point3d> p_u(4);
02294   //Point3d p_u[4];
02295   int delta=(int)u;
02296 
02297 
02298   /*
02299      if(!periodic) {
02300      int i=0;
02301      for(;i<=degree && (delta-i)<=0;i++) 
02302      p_u[i]=Control_points[0][0][m];
02303 
02304      for(;i<=degree && (delta-i)<n_u;i++)
02305      p_u[i]=Control_points[0][delta-i][m];
02306 
02307      int t=n_u-1;
02308      for(;i<=degree;i++)
02309      p_u[i]=Control_points[0][t][m];
02310 
02311      } else {
02312      for(int i=0;i<=degree;i++) 
02313      p_u[i]=Control_points[0][(delta-i+n_u)%(n_u)][m];
02314      }
02315 
02316 
02317      for(int i=degree+1; i>=2;i--) {
02318      double ind=delta;
02319 
02320      for(int j=0;j<=i-1;j++) {
02321 
02322      double omega = (u-ind)/(i-1);
02323 
02324      if((i-1+ind-(degree))<=0 || u-(degree)<=0)
02325      omega=0;
02326      else if(ind<(degree))
02327      omega= (u-(degree))/(i-1+ind-(degree));
02328      else if(i-1+ind>=n_u) {
02329      if(n_u-ind>0 && u-ind>0)
02330      omega= (u-ind)/(n_u-ind);
02331      else
02332      omega=0;
02333      }
02334      p_u[j]=p_u[j]*omega + p_u[j+1]*(1-omega);
02335      ind=ind-1;
02336      }
02337      }
02338 
02339 
02340      old_p=p_u[0];
02341      */
02342 
02343   if(!periodic) {
02344     int i=0;
02345     for(;i<=degree && (delta-i)<=0;i++) 
02346       p_u[i]=Control_points[0][0][m];
02347 
02348     for(;i<=degree && (delta-i)<n_u;i++)
02349       p_u[i]=Control_points[0][delta-i][m];
02350 
02351     int t=n_u-1;
02352     for(;i<=degree;i++)
02353       p_u[i]=Control_points[0][t][m];
02354 
02355   } else {
02356     for(int i=0;i<=degree;i++) 
02357       p_u[i]=Control_points[0][(delta-i+n_u)%(n_u)][m];
02358   }
02359 
02360 
02361   for(int i=degree+1; i>=2;i--) {
02362     double omega;
02363     double ind=delta;
02364     int j=0;
02365 
02366     for(;j<=i-1 && (i-1+ind>=n_u);j++,ind--) {
02367       if(n_u-ind>0 && u-ind>0)
02368         omega= (u-ind)/(n_u-ind);
02369       else
02370         omega=0;
02371 
02372       p_u[j]=p_u[j]*omega + p_u[j+1]*(1-omega);
02373 
02374     }
02375 
02376 
02377     for(;j<=i-1 ; j++, ind--){
02378       if((i-1+ind-(degree))<=0 || u-degree<=0){
02379         omega=0;
02380       }
02381       else if(ind<(degree)){
02382         omega= (u-(degree))/(i-1+ind-(degree));
02383       }
02384       else
02385         omega = (u-ind)/(i-1);
02386 
02387       p_u[j]=p_u[j]*omega + p_u[j+1]*(1-omega);
02388 
02389     }
02390 
02391 
02392   }  
02393 
02394   //  if( p_u[0][0]!=old_p[0] &&p_u[0][1]!=old_p[1] &&p_u[0][2]!=old_p[2] )
02395   //  std::cout<<"no go ufo"<<std::endl;
02396 
02397 
02398   return p_u[0];
02399 }
02400 
02401 void BSplineSurface::SelectRegion(vector<Point3d > s_reg, Matrix3d A,Point3d trans) 
02402 {
02403   selected_region.clear();
02404   //  selected_bb[0]=selected_bb[2]=-1;
02405   //selected_bb[1]=selected_bb[3]=10000000;
02406 
02407   selected_bb[0]=selected_bb[2]=0;
02408   selected_bb[1]=selected_bb[3]=0;
02409   
02410   if(s_reg.size()>1) {
02411     for(unsigned int i=0; i<Control_points[selected_level].size();i++) {
02412       for(unsigned int j=0; j<Control_points[selected_level][0].size();j++) {
02413     
02414         int *index=new int[2];
02415         index[0]=i;
02416         index[1]=j;
02417 
02418         Point3d p=Control_points[selected_level][i][j];
02419 
02420         p[2]=-p[2];
02421         p=A*p;
02422         p[2]=0;
02423         p=p+trans;
02424         if(InsideContour(s_reg,p))
02425           selected_region.push_back(index);
02426       }
02427     }
02428   }
02429 }
02430 
02431 /*
02432 void BSplineSurface::RotateRegion(Point2d c_rot, double theta, double r_dis , Matrix3d A) {
02433 
02434   double dis;
02435   double r_theta;
02436   Matrix3d R(3,3);
02437   Point2d proj;
02438 
02439   if(theta>M_PI)
02440     theta=theta-2*M_PI;
02441 
02442   if(theta<-M_PI)
02443     theta=theta+2*M_PI;
02444 
02445   for(unsigned int i=0;i<selected_region.size();i++) {
02446     Point3d p = Control_points[selected_level][selected_region[i][0]][selected_region[i][1]];
02447 
02448     p[2]=-p[2];
02449     p=A*p;
02450 
02451     dis= sqrt( (c_rot[0]-p[0])*(c_rot[0]-p[0])  + (c_rot[1]-p[1])*(c_rot[1]-p[1])  );
02452 
02453     p[0]-=c_rot[0];
02454     p[1]-=c_rot[1];
02455     
02456     if(dis>r_dis)
02457       r_theta=theta;
02458     else{
02459       dis=(dis/r_dis);
02460       dis=dis*dis-2*dis;
02461       r_theta=-dis*theta;
02462     }
02463 
02464     R.RotateZ(r_theta);
02465 
02466     p=R*p;
02467 
02468     p[0]+=c_rot[0];
02469     p[1]+=c_rot[1];
02470 
02471     p=(~A)*p;
02472 
02473     p[2]=-p[2];
02474 
02475     ControlPoints[selected_level][selected_region[i][0]][selected_region[i][1]]=p;
02476   }
02477 
02478   for(unsigned int i=0;i<footprint.size();i++) {
02479     footprint[i][1]=footprint[i][3]=10000000;
02480     footprint[i][0]=footprint[i][2]=-1;
02481     footprint[i][1]=footprint[i][3]=0;
02482     footprint[i][0]=Control_points[i].size()-1;
02483     footprint[i][2]=Control_points[i][0].size()-1;
02484   }
02485 
02486   Calc_Footprint(selected_bb[0],selected_bb[1],selected_level);
02487   Calc_PreImage(selected_bb[0],selected_bb[1],selected_level);
02488 
02489   Calc_Footprint(selected_bb[0],selected_bb[3],selected_level);
02490   Calc_PreImage(selected_bb[0],selected_bb[3],selected_level);
02491 
02492   Calc_Footprint(selected_bb[2],selected_bb[1],selected_level);
02493   Calc_PreImage(selected_bb[2],selected_bb[1],selected_level);
02494 
02495   Calc_Footprint(selected_bb[2],selected_bb[3],selected_level);
02496   Calc_PreImage(selected_bb[2],selected_bb[3],selected_level);
02497 
02498   Update_Footprint();
02499 }
02500 */
02501 
02502 bool BSplineSurface::InsideContour(vector< Point3d > shape, Point3d p) {
02503 
02504   bool inside=false;
02505   for(unsigned int i=0;i<shape.size()-2;i++) {
02506     if( (shape[i][1]-p[1])*(shape[i+1][1]-p[1])<=0  || shape[i+1][1]==p[1]) {
02507       if(shape[i][0]<=p[0] && shape[i+1][0]<=p[0]) {
02508         inside=!inside;
02509 
02510       } else if( (shape[i][0]-p[0])*(shape[i+1][0]-p[0])<=0  || shape[i+1][0]==p[0]) {
02511         double t=(p[1]-shape[i][1])/(shape[i+1][1]-shape[i][1]);
02512         if( (t*(shape[i+1][0] - shape[i][0])+shape[i][0])<=p[0]) {
02513           inside=!inside;
02514         }
02515       }
02516     }
02517   }
02518   if( (shape[shape.size()-1][1]-p[1])*(shape[0][1]-p[1])<0 || shape[0][1]==p[1]) {
02519     if(shape[shape.size()-1][0]<=p[0] && shape[0][0]<=p[0]) {
02520       inside=!inside;
02521 
02522     } else if( (shape[shape.size()-1][0]-p[0])*(shape[0][0]-p[0])<0 || shape[0][0]==p[0]) {
02523       double t=(p[1]-shape[shape.size()-1][1])/(shape[0][1]-shape[shape.size()-1][1]);
02524 
02525       if((t*(shape[0][0] - shape[shape.size()-1][0])+shape[shape.size()-1][0])<=p[0]) {
02526         inside=!inside;
02527           
02528       }
02529     }
02530   }
02531   return inside;
02532 }
02533 
02534 void BSplineSurface::MoveRegion(Point3d dis) 
02535 {
02536   for(unsigned int i=0;i<selected_region.size();i++)
02537     Control_points[selected_level][selected_region[i][0]][selected_region[i][1]] = 
02538             Control_points[selected_level][selected_region[i][0]][selected_region[i][1]]+dis;
02539 
02540   for(unsigned int i=0;i<footprint.size();i++) {
02541     footprint[i][1]=footprint[i][3]=10000000;
02542     footprint[i][0]=footprint[i][2]=-1;
02543     footprint[i][1]=footprint[i][3]=0;
02544     footprint[i][0]=(int)Control_points[i].size()-1;
02545     footprint[i][2]=(int)Control_points[i][0].size()-1;
02546   }
02547   CalcFootprint(selected_bb[0],selected_bb[1],selected_level);
02548   CalcPreImage(selected_bb[0],selected_bb[1],selected_level);
02549 
02550   CalcFootprint(selected_bb[0],selected_bb[3],selected_level);
02551   CalcPreImage(selected_bb[0],selected_bb[3],selected_level);
02552 
02553   CalcFootprint(selected_bb[2],selected_bb[1],selected_level);
02554   CalcPreImage(selected_bb[2],selected_bb[1],selected_level);
02555 
02556   CalcFootprint(selected_bb[2],selected_bb[3],selected_level);
02557   CalcPreImage(selected_bb[2],selected_bb[3],selected_level);
02558 
02559   UpdateFootprint();
02560 }
02561 
02562 Point3d BSplineSurface::NormalEval(double u, double v) const 
02563 {
02564   Point3d p_u;
02565   Point3d p_v;
02566 
02567   if(u>(n_u))
02568     u=n_u;
02569 
02570   if(u<3)
02571     u=3;
02572 
02573   if(v>(n_v))
02574     v=n_v;
02575 
02576   if(v<3)
02577     v=3;
02578 
02579   if(u>5.0)
02580     p_u=(Eval(u,v)-Eval(u-0.05,v))*(1.0/0.05);
02581   else
02582     p_u=(Eval(u+0.05,v)-Eval(u,v))*(1.0/0.05);
02583 
02584   if(v>5.0)
02585     p_v=(Eval(u,v)-Eval(u,v-0.05))*(1.0/0.05);
02586   else
02587     p_v=(Eval(u,v+0.05)-Eval(u,v))*(1.0/0.05);
02588 
02589   p_u=p_u*(1/p_u.norm());
02590   p_v=p_v*(1/p_v.norm());
02591 
02592   p_u=p_u.cross(p_v);
02593 
02594   float l=p_u.norm();
02595   /*
02596   if(l<0.1){
02597     // std::cout<<l<<std::endl;
02598     //std::cout<<u<<" "<<v<<std::endl;
02599     //std::cout<<n_u<<" "<<n_v<<std::endl;
02600     glColor3f(0.0,1.0,0.0);
02601     float delta=0.05/sqrt(2);
02602   if(u>5.0 && v>5.0)
02603     p_u=(Eval(u,v)-Eval(u-delta,v-delta))*(1.0/0.05);
02604   else if(u>5.0 )
02605     p_u=(Eval(u,v+delta)-Eval(u-delta,v))*(1.0/0.05);
02606   else if(v>5.0)
02607     p_u=(Eval(u+delta,v)-Eval(u,v-delta))*(1.0/0.05);
02608   else
02609     p_u=(Eval(u+delta,v+delta)-Eval(u,v))*(1.0/0.05);    
02610   p_u=p_u*1/(p_u.norm());
02611   p_u=p_u.Cross(p_v);
02612   l=p_u.norm();
02613 
02614   }
02615   */
02616   p_u=p_u*(1/l);
02617 
02618   //if(u==n_u || v==n_v)
02619   //  std::cout<<l<<std::endl;
02620 
02621   /*
02622   if(isnan(p_u[0])||isinf(p_u[0])) {
02623      std::cout<<u<<" "<<v<<std::endl;
02624      std::cout<<(n_u+degree-1)<<" "<<(n_v+degree-1)<<std::endl;
02625   }
02626   */
02627 
02628 
02629 
02630   return p_u;
02631 }
02632 
02633 BSplineSurface& BSplineSurface::operator=(const BSplineSurface& B) 
02634 {
02635   _TextureId = B._TextureId;
02636   _scale = B._scale;
02637   _divU=B._divU;
02638   _divV=B._divV;
02639   _vrtx=B._vrtx;
02640   _nrml=B._nrml;
02641   _f_name=B._f_name;
02642 
02643   if(B.precomputed) {
02644   _vrtx=B._vrtx;
02645   _nrml=B._nrml;
02646   precomputed=B.precomputed;
02647   }
02648   else
02649     precomputed=false;
02650 
02651   Reset(B.n_u,B.n_v);
02652 
02653   for(int i=0;i<n_u;i++)
02654     for(int j=0;j<n_v;j++)
02655       Control_points[0][i][j]=B.Control_points[0][i][j];
02656 
02657   return *this;
02658 }
02659 
02660 BSplineSurface BSplineSurface::operator+(const BSplineSurface& B) 
02661 {
02662   BSplineSurface A1=(*this);
02663   BSplineSurface A2=B;
02664   BSplineSurface P;
02665 
02666   while(A1.n_u<A2.n_u)
02667     A1.DoubleU();
02668 
02669   while(A2.n_u<A1.n_u)
02670     A2.DoubleU();
02671 
02672   while(A1.n_v<A2.n_v)
02673     A1.DoubleV();
02674 
02675   while(A2.n_v<A1.n_v)
02676     A2.DoubleV();
02677 
02678   P.Reset(A1.n_u,A1.n_v);
02679 
02680   for(int i=0;i<P.n_u;i++)
02681     for(int j=0;j<P.n_v;j++)
02682       P.Control_points[0][i][j]=A1.Control_points[0][i][j]+A2.Control_points[0][i][j];
02683 
02684   return P;
02685 }
02686 
02687 BSplineSurface BSplineSurface::operator-(const BSplineSurface& B) 
02688 {
02689   BSplineSurface A1=(*this);
02690   BSplineSurface A2=B;
02691   BSplineSurface P;
02692 
02693   while(A1.n_u<A2.n_u)
02694     A1.DoubleU();
02695 
02696   while(A2.n_u<A1.n_u)
02697     A2.DoubleU();
02698 
02699   while(A1.n_v<A2.n_v)
02700     A1.DoubleV();
02701 
02702   while(A2.n_v<A1.n_v)
02703     A2.DoubleV();
02704 
02705   P.Reset(A1.n_u,A1.n_v);
02706 
02707   for(int i=0;i<P.n_u;i++)
02708     for(int j=0;j<P.n_v;j++)
02709       P.Control_points[0][i][j]=A1.Control_points[0][i][j]-A2.Control_points[0][i][j];
02710 
02711   return P;
02712 }
02713 
02714 BSplineSurface BSplineSurface::operator*(const double c) 
02715 {
02716   BSplineSurface P=(*this);
02717 
02718   P.Reset(n_u,n_v);
02719 
02720   for(int i=0;i<n_u;i++)
02721     for(int j=0;j<n_v;j++)
02722       P.Control_points[0][i][j]=Control_points[0][i][j]*c;
02723 
02724   return P;
02725 }
02726 
02727 
02728 void BSplineSurface::SetColors(double c1[3],double c2[3],double c3[3]) 
02729 {
02730   for(int i=0;i<3;i++) {
02731     sel_point[i]=c1[i];
02732     unsel_point[i]=c2[i];
02733     poly_line[i]=c3[i];
02734   }
02735 }
02736 
02737 Point3d BSplineSurface::PartialU(double u, double v) const
02738 {
02739   Point3d p_u,Eu1,Eu2;
02740   Point2d u1,u2;
02741   
02742   u1[0]=u2[0]=u;
02743   u1[1]=u2[1]=v;
02744 
02745   u1[0]-=5*err_tol;
02746   u2[0]+=5*err_tol;
02747   Eu1=Eval(u1[0],u1[1]);
02748   Eu2=Eval(u2[0],u2[1]);
02749 
02750   if(u1[0]<3.0)
02751     u1[0]=3.0;
02752 
02753   if(u2[0]>(n_u))
02754     u2[0]=(n_u);
02755 
02756   p_u=(Eu2-Eu1)*(1.0/(fabs(u1[0]-u2[0])));
02757 
02758   return p_u;
02759 }
02760 
02761 Point3d BSplineSurface::PartialV(double u, double v) const
02762 {
02763 
02764   Point3d p_v,Ev1,Ev2;
02765   Point2d v1,v2;
02766   
02767   v1[0]=v2[0]=u;
02768   v1[1]=v2[1]=v;
02769 
02770   v1[1]-=5*err_tol;
02771   v2[1]+=5*err_tol;
02772   Ev1=Eval(v1[0],v1[1]);
02773   Ev2=Eval(v2[0],v2[1]);
02774 
02775   if(v1[1]<3.0)
02776     v1[1]=3.0;
02777 
02778   if(v2[1]>(n_u))
02779     v2[1]=(n_u);
02780 
02781   p_v=(Ev2-Ev1)*(1.0/(fabs(v1[1]-v2[1])));
02782 
02783   return p_v;
02784 
02785 }
02786 
02787 bool  BSplineSurface::PointInversion(Point2d &surf_p, Point2d p0, Point3d cp) const 
02788 {
02789  
02790 
02791   Point2d u1,u2;
02792   Point3d Eu1,Eu2;
02793   Point2d v1,v2;
02794   Point3d Ev1,Ev2;
02795   Point2d p=p0;
02796   Point2d prev_step;
02797   Point3d Esurf_p;
02798 
02799   double dis=1000;
02800   double count=0;
02801   double du,dv;
02802 
02803 
02804  
02805   surf_p=p0;
02806   Esurf_p=Eval(surf_p[0],surf_p[1]);
02807 
02808   while(fabs(dis-(cp-Esurf_p).norm())>err_tol && count<max_it) {
02809     count++;
02810     dis=(cp-Esurf_p).norm();
02811 
02812   if(surf_p[0]<3)
02813     surf_p[0]=3;
02814 
02815   if(surf_p[0]>(n_u))
02816     surf_p[0]=(n_u);
02817 
02818 
02819   if(surf_p[1]<3)
02820     surf_p[1]=3;
02821 
02822   if(surf_p[1]>(n_v))
02823     surf_p[1]=(n_v);
02824 
02825 
02826   
02827 
02828     u1=surf_p;
02829     u2=surf_p; 
02830     u1[0]-=5*err_tol;
02831     u2[0]+=5*err_tol;
02832     Eu1=Eval(u1[0],u1[1]);
02833     Eu2=Eval(u2[0],u2[1]);
02834 
02835     Point3d Fu= Eu2-Eu1;
02836     Fu= Fu*(1/Fu.norm());
02837 
02838     if(u1[0]<3.0)
02839       u1[0]=3.0;
02840 
02841     if(u2[0]>(n_u))
02842       u2[0]=(n_u);
02843 
02844 
02845 
02846     
02847     v1=surf_p;
02848     v2=surf_p;
02849     v1[1]-=5*err_tol;
02850     v2[1]+=5*err_tol;
02851     Ev1=Eval(v1[0],v1[1]);
02852     Ev2=Eval(v2[0],v2[1]);
02853    
02854     if(v1[1]<3.0)
02855       v1[1]=3.0;
02856 
02857     if(v2[1]>(n_v))
02858       v2[1]=(n_v);
02859 
02860 
02861 
02862     Point3d Fv= Ev2-Ev1;
02863     Fv= Fv*(1/Fv.norm());
02864 
02865     float c=1;//Fv.Cross(Fu).norm();
02866     
02867     
02868     du=-( (cp-Esurf_p-Fu*(fabs(u2[0]-u1[0]))*c).norm() - (cp-Esurf_p).norm() )/(fabs(u2[0]-u1[0]));
02869     dv=-( (cp-Esurf_p-Fv*(fabs(v2[1]-v1[1]))*c).norm() - (cp-Esurf_p).norm() )/(fabs(v2[1]-v1[1]));
02870 
02871     
02872     /*    
02873     du=( (cp-Eu1).norm() - (cp-Eu2).norm() )/(fabs(u2[0]-u1[0]));
02874     dv=( (cp-Ev1).norm() - (cp-Ev2).norm() )/(fabs(v2[1]-v1[1]));
02875     */
02876 
02877 
02878 
02879       double step=0.01;
02880       int search_steps=0;
02881     while( step > err_tol && search_steps<inner_loop_max_it) {
02882       search_steps++;
02883       
02884       Point2d temp=surf_p;
02885 
02886         temp[0]+=step*du;
02887         temp[1]+=step*dv;
02888 
02889         if(temp[0]<3)
02890           temp[0]=3;
02891 
02892         if(temp[0]>(n_u))
02893           temp[0]=(n_u);
02894 
02895 
02896         if(temp[1]<3)
02897           temp[1]=3;
02898 
02899         if(temp[1]>(n_v))
02900           temp[1]=(n_v);
02901 
02902 
02903 
02904       Point3d Etemp=Eval(temp[0],temp[1]);
02905 
02906       if( (Etemp-cp).norm()<(Esurf_p-cp).norm()) {
02907         step*=7.1;//1.3;
02908         surf_p=temp;
02909 
02910         Esurf_p=Etemp;
02911 
02912       } else
02913         step/=6.7;//1.5;
02914     }
02915 
02916   
02917 
02918   }
02919   if(surf_p[0]<3)
02920     surf_p[0]=3;
02921 
02922   if(surf_p[0]>(n_u))
02923     surf_p[0]=(n_u);
02924 
02925 
02926   if(surf_p[1]<3)
02927     surf_p[1]=3;
02928 
02929   if(surf_p[1]>(n_v))
02930     surf_p[1]=(n_v);
02931 
02932   //  std::cout<<count<<std::endl;
02933 
02934   if(count>=max_it)
02935     return false;
02936   else
02937     return true;
02938 
02939 
02940  /*
02941   Point2d u1,u2;
02942   Point3d Eu1,Eu2;
02943   Point2d v1,v2;
02944   Point3d Ev1,Ev2;
02945   Point2d p=p0;
02946   Point3d Esurf_p;
02947 
02948   double dis=1000;
02949   double count=0;
02950   double du,dv;
02951 
02952   surf_p=p0;
02953   Esurf_p=Eval(surf_p[0],surf_p[1]);
02954 
02955   while(fabs(dis-(cp-Esurf_p).norm())>err_tol && count<max_it) {
02956     count++;
02957     dis=(cp-Esurf_p).norm();
02958   
02959 
02960     u1=surf_p;
02961     u2=surf_p; 
02962     u1[0]-=5*err_tol;
02963     u2[0]+=5*err_tol;
02964     Eu1=Eval(u1[0],u1[1]);
02965     Eu2=Eval(u2[0],u2[1]);
02966 
02967     if(u1[0]<3.0)
02968       u1[0]=3.0;
02969 
02970     if(u2[0]>(n_u))
02971       u2[0]=(n_u);
02972 
02973     du=( (cp-Eu1).norm() - (cp-Eu2).norm() )/(fabs(u2[0]-u1[0]))*(n_u);
02974 
02975     v1=surf_p;
02976     v2=surf_p;
02977     v1[1]-=5*err_tol;
02978     v2[1]+=5*err_tol;
02979     Ev1=Eval(v1[0],v1[1]);
02980     Ev2=Eval(v2[0],v2[1]);
02981    
02982     if(v1[1]<3.0)
02983       v1[1]=3.0;
02984 
02985     if(v2[1]>(n_v))
02986       v2[1]=(n_v);
02987 
02988     dv=( (cp-Ev1).norm() - (cp-Ev2).norm() )/(fabs(v2[1]-v1[1]))*n_v;
02989 
02990     int i=0;
02991 
02992     
02993     double step=0.01;
02994 
02995     while( step > err_tol ) {
02996       i=!i;
02997       Point2d temp=surf_p;
02998       if(((int)count)%2==0){
02999       if(i==0)
03000         temp[0]+=step*du;
03001       else
03002         temp[1]+=step*dv;
03003       }
03004       else{
03005         temp[0]+=step*du;
03006         temp[1]+=step*dv;
03007       }
03008 
03009       Point3d Etemp=Eval(temp[0],temp[1]);
03010 
03011       if( (Etemp-cp).norm()<(Esurf_p-cp).norm()) {
03012         step*=1.11;
03013         surf_p=temp;
03014 
03015         Esurf_p=Etemp;
03016 
03017       } else
03018         step/=2.0;
03019     }
03020     
03021   }
03022   if(surf_p[0]<3)
03023     surf_p[0]=3;
03024 
03025   if(surf_p[0]>(n_u))
03026     surf_p[0]=(n_u);
03027 
03028 
03029   if(surf_p[1]<3)
03030     surf_p[1]=3;
03031 
03032   if(surf_p[1]>(n_v))
03033     surf_p[1]=(n_v);
03034 
03035   if(count>=max_it)
03036     return false;
03037   else
03038     return true;
03039 
03040   */
03041 
03042 }
03043 
03044 Point3d BSplineSurface::EvalN(double u, double v) const 
03045 {
03046   return Eval(ConvertU(u),ConvertV(v));  
03047 }
03048 
03049 Point3d  BSplineSurface::NormalEvalN(double u, double v) const 
03050 {
03051   return NormalEval(ConvertU(u),ConvertV(v));  
03052 } 
03053 
03054 Point3d  BSplineSurface::PartialUN(double u, double v) const 
03055 {
03056   return PartialU(ConvertU(u),ConvertV(v));  
03057 }
03058 
03059 Point3d  BSplineSurface::PartialVN(double u, double v) const 
03060 {
03061   return PartialU(ConvertU(u),ConvertV(v));    
03062 }
03063 
03064 Point3d BSplineSurface::ContourEval(double u) const 
03065 {
03066   Point3d p;
03067   Point2d k;
03068 
03069   k=ContourInverse(u);
03070   p=EvalN(k[0],k[1]);
03071 
03072   /*
03073   if(u<=0.25)
03074     p=eval_N(0.05,u/0.25*0.90+0.05);
03075   else if(u<=0.5)
03076     p=eval_N((u-0.25)/0.25*0.90+0.05,0.95);
03077   else if(u<=0.75)
03078     p=eval_N(0.95,0.95-(u-0.5)/0.25*0.90);
03079   else
03080     p=eval_N(0.95-(u-0.75)/0.25*0.90,0.05);
03081   */
03082   return p;
03083 }
03084 
03085 Point2d BSplineSurface::ContourInverse(double u) const 
03086 {
03087   Point2d k;
03088   u = fmod(u,1.0);
03089 
03090   if(u<=0.25) {
03091     k[0]=0.00;
03092     k[1]=u/0.25;
03093   }
03094   else if(u<=0.5) {
03095     k[0]=(u-0.25)/0.25;
03096     k[1]=1.0;
03097   }
03098   else if(u<=0.75) {
03099     k[0]=1.0;
03100     k[1]=1.0-(u-0.5)/0.25;;
03101   }
03102   else{
03103     k[0]=1.0-(u-0.75)/0.25;
03104     k[1]=0.0;
03105   }
03106 
03107   /*
03108   k=k*0.9;
03109   k[0]+=0.05;
03110   k[1]+=0.05;
03111   */
03112   return k;
03113 }
03114 
03115 bool BSplineSurface::PointInversionN(Point2d &surf_p, Point2d p0, Point3d q) const 
03116 {
03117   bool error;
03118   surf_p[0]=ConvertU(surf_p[0]);
03119   surf_p[1]=ConvertV(surf_p[1]);
03120 
03121   p0[0]=ConvertU(p0[0]);
03122   p0[1]=ConvertV(p0[1]);
03123 
03124   error = PointInversion(surf_p,p0,q);
03125 
03126   surf_p[0]= (surf_p[0]-3.0)/(n_u-degree);
03127   surf_p[1]= (surf_p[1]-3.0)/(n_v-degree);
03128 
03129   return error;
03130 };
03131 
03132 double BSplineSurface::ConvertU(double u)  const{
03133   return (u*(n_u-degree) )+3.0;
03134 }
03135 
03136 double BSplineSurface::ConvertV(double v)  const{
03137   return (v*(n_v-degree) )+3.0;
03138 }
03139 
03140 BSplineSurface BSplineSurface::Interpolate(const BSplineSurface &BS1, const BSplineSurface &BS2, 
03141                                                       double alpha, int num_rows, int num_cols) const {
03142   BSplineSurface interpolated=BS1;
03143   BSplineSurface s1=BS1;
03144   BSplineSurface s2=BS2;
03145 
03146   s1.Resize(num_rows,num_cols);
03147   s2.Resize(num_rows,num_cols);
03148 
03149   interpolated=s1*(1-alpha) + s2*(alpha);
03150   return interpolated;
03151 }
03152 
03153 unsigned int BSplineSurface::LowestResDim(int i) {
03154   //assert i<2
03155   if(i==0)
03156    return (int)Control_points[(int)Control_points.size()-1].size();
03157 
03158   if(i==1)
03159    return (int)Control_points[(int)Control_points.size()-1][0].size();
03160 
03161   return 0;
03162 }
03163 
03164 BSplineSurface  BSplineSurface::LowestRes() 
03165 {
03166   BSplineSurface l_res=(*this);
03167   int k=(int)Control_points.size()-1;
03168   l_res.Reset(LowestResDim(0),LowestResDim(1));
03169 
03170   for(int i=0;i<l_res.n_u;i++)
03171     for(int j=0;j<l_res.n_v;j++) 
03172       l_res.Control_points[0][i][j]=Control_points[k][i][j];
03173 
03174   return l_res;
03175 }
03176 
03177 void BSplineSurface::Resize(unsigned int num_rows,unsigned int num_cols) 
03178 {
03179   if(num_rows<LowestResDim(0) || num_cols<LowestResDim(1) ) {
03180 
03181     while(num_rows<LowestResDim(0) && num_rows>=MIN_HEIGHT)
03182       HalveU();
03183     while(num_cols<LowestResDim(1) && num_cols>=MIN_WIDTH)
03184       HalveV();
03185 
03186     (*this)=LowestRes();
03187 
03188   }
03189 
03190   if(num_rows>Control_points[0].size() || num_cols>Control_points[0][0].size() ) {
03191     while(num_rows>=2*Control_points[0].size()-3 )
03192       DoubleU();
03193     while(num_cols>=2*Control_points[0][0].size()-3 )
03194       DoubleV();
03195   }
03196 
03197   //std::cout<<dimU()<<" "<<dimV()<<std::endl;
03198 }
03199 
03200 } // namespace Shapes
03201 
03202 } // namespace util
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Fri May 31 15:37:52 2013 for VVE by  doxygen 1.6.3