MC_curve.cpp

Go to the documentation of this file.
00001 
00002 #include <MC_v4d.hpp>
00003 #include <MC_int_vector.hpp>
00004 #include <MC_matrix.hpp>
00005 #include <MC_int_pair_unique.hpp>
00006 #include <MC_segment.hpp>
00007 #include <MC_double_vector_vector.hpp>
00008 #include <MC_string_helper.hpp>
00009 
00010 #include <fstream>
00011 
00012 #include <MC_curve.hpp>
00013 #include <map>
00014 
00015 
00016 
00017 namespace mesh_conv
00018 {
00019 
00020 
00021     MC_curve::MC_curve():MC_v3d_vector(){}
00022     MC_curve::MC_curve(const MC_v3d& v0):MC_v3d_vector(v0){}
00023     MC_curve::MC_curve(const MC_v3d& v0,const MC_v3d& v1):MC_v3d_vector(v0,v1){}
00024     MC_curve::MC_curve(const MC_v3d& v0,const MC_v3d& v1,const MC_v3d& v2):MC_v3d_vector(v0,v1,v2){}
00025     MC_curve::MC_curve(const MC_v3d& v0,const MC_v3d& v1,const MC_v3d& v2,const MC_v3d& v3):MC_v3d_vector(v0,v1,v2,v3){}
00026     MC_curve::MC_curve(const MC_v3d& v0,const MC_v3d& v1,const MC_v3d& v2,const MC_v3d& v3,const MC_v3d& v4):MC_v3d_vector(v0,v1,v2,v3,v4){}
00027     MC_curve::MC_curve(const MC_v3d_vector& vec)
00028             :MC_v3d_vector(vec){}
00029     MC_curve::MC_curve(const MC_curve& vec)
00030             :MC_v3d_vector(static_cast<MC_v3d_vector>(vec)){}
00031     MC_curve::MC_curve(const MC_double_vector& x_vector,const MC_double_vector& y_vector,const MC_double_vector& z_vector)
00032             :MC_v3d_vector(x_vector,y_vector,z_vector){}
00033 
00034 
00035     MC_curve MC_curve::read_lin(std::istream& stream)
00036     {
00037         MC_curve curve;
00038 
00039         MC_v3d_vector coords;
00040         std::string buffer;
00041 
00042         while(stream.good()==true)
00043         {
00044             stream>>buffer;
00045             if(stream.good()==true)
00046             {
00047                 if(buffer.compare("v")==0)
00048                 {
00049                     MC_v3d x; stream>>x[0]; stream>>x[1]; stream>>x[2];
00050                     coords.add(x);
00051                 }
00052                 else if(buffer.compare("s")==0)
00053                 {
00054                     int u0=-1,u1=-1;
00055                     stream>>u0; stream>>u1;
00056                     if(u0-1<0 || u1-1<0 || u0-1>=coords.size() || u1-1>=coords.size())
00057                     {std::cout<<"Error in MC_curve::load_lin(stream), size is not correct ("<<u0<<","<<u1<<") ; and coords size is "<<coords.size()<<std::endl;exit(-1);}
00058 
00059                     if(curve.size()>0 && (coords[u0-1]-curve[curve.size()-1]).norm()>0.00001)
00060                     {std::cout<<"Something strange in Curve_3D::load_lin(stream), doesn't seems to be one line"<<std::endl;}
00061 
00062                     if(curve.size()==0)
00063                         curve.add(coords[u0-1]);
00064 
00065                     curve.add(coords[u1-1]);
00066 
00067                 }
00068             }
00069         }
00070 
00071         if(curve.size()<=0)
00072         {std::cout<<"Something strange in Curve_3D::load_lin(stream), line is empty"<<std::endl;}
00073 
00074         return curve;
00075     }
00076 
00077 //    MC_curve MC_curve::read_vect_curve(std::istream& stream)
00078 //    {
00079 //
00080 //        MC_curve curve;
00081 //
00082 //        MC_v3d_vector coords;
00083 //        std::string buffer;
00084 //        const int SIZE_BUFFER=2048;
00085 //        char c_buffer[SIZE_BUFFER]={'\0'};
00086 //
00087 //        while(stream.good()==true)
00088 //        {
00089 //            stream>>buffer;
00090 //            if(buffer.compare("VECT")==0)
00091 //            {
00092 //
00093 //                while(stream.good()==true)
00094 //                {
00095 //                    stream>>buffer;
00096 //                    if(stream.good()==true)
00097 //                    {
00098 //
00099 //                        // jump comments
00100 //                        if(buffer[0]=='#')
00101 //                            stream.getline(c_buffer,SIZE_BUFFER);
00102 //
00103 //                        // check if only one line
00104 //                        else if(buffer[0]!='1')
00105 //                        {std::cout<<"Error in MC_curve::load_vect(stream), more than one line "<<buffer<<std::endl;exit(-1);}
00106 //                        else
00107 //                        {
00108 //                            // get number of vertices color ...
00109 //                            int N_total_vertices=0,N_total_color=0,N_vertices,N_color=0;
00110 //                            stream>>N_total_vertices;
00111 //                            stream>>N_total_color;
00112 //                            stream>>N_vertices;
00113 //                            stream>>N_color;
00114 //
00115 //
00116 //                            if(N_total_vertices!=N_vertices)
00117 //                            {std::cout<<"Error in Curve_3D::load_vect(stream), N_total_vertices!=N_vertices ("<<N_total_vertices<<","<<N_vertices<<") for only one line"<<std::endl;exit(-1);}
00118 //
00119 //                            for(int k=0;k<N_vertices;k++)
00120 //                            {
00121 //                                MC_v3d x;
00122 //                                for(int k_dim=0;k_dim<3;k_dim++)
00123 //                                    stream>>x[k_dim];
00124 //                                curve.add(x);
00125 //                            }
00126 //                            for(int k=0;k<N_color;k++)
00127 //                            {
00128 //                                MC_v4d useless_color;
00129 //                                for(int k_dim=0;k_dim<4;k_dim++)
00130 //                                    stream>>useless_color[k_dim];
00131 //                            }
00132 //                        }
00133 //                    }
00134 //                }
00135 //
00136 //            }
00137 //        }
00138 //
00139 //
00140 //        return curve;
00141 //    }
00142 
00143     double MC_curve::length() const
00144     {
00145         double L=0.0;
00146         int N=size();
00147         for(int k=0;k<N-1;++k)
00148             L += (v[k+1]-v[k]).norm();
00149         return L;
00150     }
00151 
00152     std::pair <MC_curve,bool> MC_curve::unclosed() const
00153     {
00154         if(size()<2)
00155         {std::cout<<"Error in MC_curve::unclosed(), size()="<<size()<<std::endl;exit(-1);}
00156 
00157         MC_curve res;
00158         if(last()==first())
00159             return std::pair <MC_curve,bool> ((*this)(MC_int_vector::linspace(0,size()-2)),true);
00160         else
00161             return std::pair <MC_curve,bool> (*this,false);
00162     }
00163     std::pair <MC_curve,bool> MC_curve::closed() const
00164     {
00165         if(size()<2)
00166         {std::cout<<"Error in MC_curve::closed(), size()="<<size()<<std::endl;exit(-1);}
00167 
00168         MC_curve res;
00169         if(last()!=first())
00170             return std::pair <MC_curve,bool> ((*this)<<first(),true);
00171         else
00172             return std::pair <MC_curve,bool> (*this,false);
00173     }
00174 
00175     MC_curve::MC_curve(const std::list<MC_v3d>& input)
00176     {
00177         resize(input.size());
00178         std::list <MC_v3d> :: const_iterator it,it_end=input.end();
00179         int k=0;
00180         for(it=input.begin();it!=it_end;++it,++k)
00181             v[k]=*it;
00182     }
00183 
00184 
00185     MC_curve MC_curve::build_circle(const double& R,const int& N,const MC_v3d& normal)
00186     {
00187 #define PI 3.14159
00188 
00189         MC_curve circle(N);
00190 
00191         double epsilon=0.0001;
00192         if(normal.norm()<epsilon)
00193         {std::cout<<"Error in MC_curve::build_circle(...), normal is null"<<std::endl;exit(-1);}
00194 
00195         MC_v3d axis_1 = normal.cross(MC_v3d(1,0,0));
00196         if(axis_1.norm()<epsilon)
00197         {
00198             axis_1 = normal.cross(MC_v3d(0,1,0));
00199             if(axis_1.norm()<epsilon)
00200             {std::cout<<"Error in MC_mesh_index_vector::build_disc, something weird"<<std::endl; exit(-1);}
00201         }
00202         axis_1 = axis_1.normalized();
00203         MC_v3d axis_2 = (axis_1.cross(normal)).normalized();
00204 
00205         // vertices
00206         for(int k_radius=0;k_radius<N;k_radius++)
00207         {
00208             double theta = 2*PI*double(k_radius)/double(N);
00209             circle[k_radius]=R*sin(theta)*axis_1 + R*cos(theta)*axis_2;
00210         }
00211         return circle;
00212     }
00213     MC_curve MC_curve::build_ellipsoid(const double& R1,const double& R2,const int& N,const MC_v3d& e0,const MC_v3d& e1,const double& theta_1,const double& theta_2)
00214     {
00215         MC_curve c(N);
00216         for(int k=0;k<N;k++)
00217         {
00218             double theta=theta_1+k/double(N)*(theta_2-theta_1);
00219             c[k]=MC_v3d(R1*cos(theta),R2*sin(theta),0.0);
00220         }
00221 
00222         if(e0.norm()>0.0001 && e1.norm()>0.0001)
00223         {
00224             MC_v3d u0=e0.normalized();
00225             MC_v3d u1=e1.normalized();
00226             if( abs(u0.dot(u1))>0.0001 )
00227             {std::cout<<"Error in MC_curve::get_ellipsoid() e0 not perp to e1 :"<<u0<<","<<u1<<std::endl;exit(-1);}
00228 
00229             MC_v3d u2=u0.cross(u1);
00230             MC_matrix R(u0,u1,u2);
00231             for(int k=0;k<N;k++)
00232                 c(k)=R*c(k);
00233         }
00234 
00235         return c;
00236     }
00237     MC_curve MC_curve::build_heart(const double& R,const int& N)
00238     {
00239         double Rx=1,Ry=1;double Lx=2*Rx,Ly=3;
00240 
00241         MC_curve heart;
00242         MC_curve circle_0,circle_1;
00243         MC_curve line_0,line_1;
00244 
00245 
00246         line_0=MC_curve::build_line(MC_v3d(0,0,0),MC_v3d(Lx,Ly,0),N);
00247         circle_0 = build_ellipsoid(Rx,Ry,N,MC_v3d(),MC_v3d(),0.0,PI);circle_0=circle_0+MC_v3d(Lx-Rx,Ly,0);
00248         circle_1 = circle_0+MC_v3d(-2*Rx,0,0);
00249         line_1=MC_curve::build_line(MC_v3d(-Lx,Ly,0),MC_v3d(0,0,0),N);
00250 
00251         heart.add(line_0);heart.add(circle_0);heart.add(circle_1);heart.add(line_1);
00252         heart = heart*R;
00253 
00254         heart=heart-heart.barycenter();
00255 
00256         return heart;
00257     }
00258     MC_curve MC_curve::build_line(const MC_v3d& X0,const MC_v3d& X1,const int& N)
00259     {
00260         MC_curve line=MC_curve::zeros(N);
00261         for(int k=0;k<N;++k)
00262         {
00263             double alpha = static_cast<double>(k)/static_cast<double>(N-1);
00264             line[k]=(1-alpha)*X0+alpha*X1;
00265         }
00266         return line;
00267     }
00268     MC_curve MC_curve::build_B_spline(const MC_curve& control_polygon,const int& N_subdiv)
00269     {
00270         MC_curve spline;
00271         MC_matrix M(4,4);
00272         M(0,0)=-1;M(1,0)= 3;M(2,0)=-3;M(3,0)= 1;
00273         M(0,1)= 3;M(1,1)=-6;M(2,1)= 0;M(3,1)= 4;
00274         M(0,2)=-3;M(1,2)= 3;M(2,2)= 3;M(3,2)= 1;
00275         M(0,3)= 1;M(1,3)= 0;M(2,3)= 0;M(3,3)= 0;
00276         M/=6.0;
00277 
00278 
00279 
00280         int k_t=0;
00281         int k=0;
00282         if(control_polygon.size()<4)
00283         {std::cout<<"Warning MC_curve::build_B_spline(), must be at least 4 control points"<<std::endl;return control_polygon;}
00284 
00285         int N=control_polygon.size();
00286         MC_double_vector Px,Py,Pz;
00287         MC_double_vector T=MC_double_vector::zeros(4);
00288         double t=0.0;
00289         int k_section=0;
00290 
00291         double Sx=0.0,Sy=0.0,Sz=0.0;
00292 
00293         MC_double_vector temp_x,temp_y,temp_z;
00294         for(k_section=0;k_section<N-3;k_section++)
00295         {
00296             // polygon
00297             Px.resize(0);Py.resize(0);Pz.resize(0);
00298 
00299             Px.add(control_polygon[k_section+0][0]);
00300             Px.add(control_polygon[k_section+1][0]);
00301             Px.add(control_polygon[k_section+2][0]);
00302             Px.add(control_polygon[k_section+3][0]);
00303 
00304             Py.add(control_polygon[k_section+0][1]);
00305             Py.add(control_polygon[k_section+1][1]);
00306             Py.add(control_polygon[k_section+2][1]);
00307             Py.add(control_polygon[k_section+3][1]);
00308 
00309             Pz.add(control_polygon[k_section+0][2]);
00310             Pz.add(control_polygon[k_section+1][2]);
00311             Pz.add(control_polygon[k_section+2][2]);
00312             Pz.add(control_polygon[k_section+3][2]);
00313 
00314 
00315             //kernel
00316             temp_x = M*Px;
00317             temp_y = M*Py;
00318             temp_z = M*Pz;
00319 
00320             for(k_t=0;k_t<N_subdiv;k_t++)
00321             {
00322                 t = double(k_t)/double(N_subdiv);
00323                 // time
00324                 T[0]=t*t*t;T[1]=t*t;T[2]=t;T[3]=1;
00325 
00326                 // spline
00327                 Sx=0;Sy=0;Sz=0;
00328                 for(k=0;k<4;k++)
00329                 {
00330                     Sx += T[k]*temp_x[k];
00331                     Sy += T[k]*temp_y[k];
00332                     Sz += T[k]*temp_z[k];
00333                 }
00334 
00335                 spline.add(MC_v3d(Sx,Sy,Sz));
00336             }
00337         }
00338 
00339         return spline;
00340     }
00341     MC_v3d_vector MC_curve::diff_forward() const
00342     {
00343 
00344         int N=size();
00345 
00346         //special case
00347         if(N==1)
00348             return MC_v3d_vector(MC_v3d(0,0,0));
00349         if(N==2)
00350             return MC_v3d_vector(v[1]-v[0],v[1]-v[0]);
00351 
00352         MC_v3d_vector diff(N);;
00353         for(int k=0;k<N-1;++k)
00354             diff[k]=v[k+1]-v[k];
00355 
00356         //last one
00357         diff[N-1]=v[N-1]-v[N-2];
00358 
00359         return diff;
00360     }
00361     MC_v3d_vector MC_curve::diff_forward_close() const
00362     {
00363         int N=size();
00364 
00365         //special case
00366         if(N==1)
00367             return MC_v3d_vector(MC_v3d(0,0,0));
00368         if(N==2)
00369             return MC_v3d_vector(v[1]-v[0],v[0]-v[1]);
00370 
00371         MC_v3d_vector diff(N);;
00372         for(int k=0;k<N-1;++k)
00373             diff[k]=v[k+1]-v[k];
00374 
00375         //last one
00376         diff[N-1]=v[0]-v[N-1];
00377 
00378         return diff;
00379     }
00380 
00381 
00382     std::pair<MC_curve,std::pair<std::vector<std::pair <MC_int_pair_unique,MC_double_vector> >,MC_double_vector> > MC_curve::sample_linear(const double& d_L) const
00383     {
00384 
00385         //tune the sampling to fine a correct number of iteration
00386         double total_length=length();
00387         double N_theory = total_length/d_L;
00388         int N_real=static_cast<int>(N_theory+1);
00389         MC_double_vector t_sampling=MC_double_vector::sample(0,1,N_real);
00390 
00391         //std::cout<<"t_sampling "<<N_real<<" | "<<t_sampling<<std::endl;
00392         //samples
00393         std::pair <MC_v3d_vector,std::vector<std::pair<MC_int_pair_unique,MC_double_vector> > > sampling=value(t_sampling);
00394 
00395         return std::make_pair(sampling.first,std::make_pair(sampling.second,t_sampling));
00396 
00397 //
00398 //        std::pair <MC_curve,std::vector <std::pair<MC_int_pair_unique,MC_double_vector> > >res;
00399 //        //Curve_3D new_curve;
00400 //
00401 //        int N=size();
00402 //        // resample each segment
00403 //        for(int k=0;k<N-1;k++)
00404 //        {
00405 //            int k2=k+1;
00406 //            MC_segment s((*this)(k),(*this)(k2));
00407 //            while(k2<N-1 && s.length()<d_L)
00408 //            {
00409 //                k2++;
00410 //                if(k2<N-1)
00411 //                    s=MC_segment((*this)(k),(*this)(k2));
00412 //            }
00413 //
00414 //
00415 //            std::pair <MC_curve,MC_double_vector> temp=MC_segment((*this)(k),(*this)(k2)).linear_sampling_intervals(d_L);
00416 //
00417 //            //std::cout<<"kk : "<<k<<" ! "<<temp.first<<std::endl;
00418 //            if(k==0)//add everything
00419 //                res.first.add(temp.first);
00420 //            else
00421 //                res.first.add(temp.first(MC_int_vector::linspace(1,temp.first.size()-1)));
00422 //
00423 //
00424 //            // now check the t values
00425 //            std::pair <MC_int_pair_unique,MC_double_vector> t_vals;
00426 //            t_vals.first=MC_int_pair_unique(k,k2);
00427 //            for(int k3=0;k3<temp.first.size();k3++)
00428 //            {
00429 //                if((k3==0 && k==0) || (k3!=0 && k!=0))
00430 //                    t_vals.second.add(temp.second[k3]);
00431 //            }
00432 //            res.second.push_back(t_vals);
00433 //
00434 //            k=k2-1;
00435 //        }
00436 //        return res;
00437     }
00438 
00439     std::vector <MC_segment> MC_curve::segment() const
00440     {
00441         int N=size();
00442         std::vector <MC_segment> seg(N-1);
00443         for(int k=0;k<N-1;++k)
00444             seg[k]=MC_segment((*this)(k),(*this)(k+1));
00445         return seg;
00446     }
00447     MC_double_vector MC_curve::relativ_position() const
00448     {
00449         if(size()==0)
00450         {std::cout<<"Error in MC_curve::relativ_position(), size=0"<<std::endl;exit(-1);}
00451         if(size()==1)
00452             return MC_double_vector(0.0);
00453         if(size()==2)
00454             return MC_double_vector(0.0,1.0);
00455 
00456         int N=size();
00457         std::vector <MC_segment> seg=segment();
00458         double length_total=length();
00459         MC_double_vector t_relativ=MC_double_vector::zeros(N);t_relativ[0]=0.0;
00460         double length_cumulativ=0.0;
00461         for(int k=0;k<N-1;++k)
00462         {
00463             length_cumulativ+=seg[k].length();
00464             t_relativ[k+1]=length_cumulativ/length_total;
00465         }
00466         return t_relativ;
00467     }
00468     std::pair <MC_v3d,std::pair<MC_int_pair_unique,double> > MC_curve::value(const double& t) const
00469     {
00470         double epsilon=0.00001;
00471         int N=size();
00472 
00473         if(t<0 || t>1)
00474         {std::cout<<"Error in MC_curve::value("<<t<<"), value must be in [0,1]"<<std::endl;exit(-1);}
00475 
00476         if(size()==0)
00477         {std::cout<<"Error in MC_curve::value("<<t<<"), size=0"<<std::endl;exit(-1);}
00478         if(size()==1)
00479             return std::make_pair((*this)[0],std::make_pair(MC_int_pair_unique(0,0),0));
00480 
00481         //special cases
00482         if(fabs(t)<epsilon)
00483             return std::make_pair(first(),std::make_pair(MC_int_pair_unique(0,1),0));
00484         if(fabs(t-1.0)<epsilon)
00485             return std::make_pair(last(),std::make_pair(MC_int_pair_unique(N-2,N-1),1));
00486 
00487         //get the relative position of the vertices
00488         MC_double_vector vt=relativ_position();
00489 
00490         //get the surrounding vertices
00491         int closest_inferior=-1;
00492         for(int k=1;closest_inferior==-1 && k<N;++k)
00493         {
00494             if(fabs(t-vt[k])<epsilon)
00495                 return std::make_pair((*this)[k],std::make_pair(MC_int_pair_unique(k-1,k),1.0));
00496             if(t>vt[k-1] && t<vt[k])
00497                 closest_inferior=k-1;
00498         }
00499 
00500         // now linear interpolation
00501         double t0=vt[closest_inferior];
00502         double t1=vt[closest_inferior+1];
00503         MC_v3d y0=(*this)[closest_inferior];
00504         MC_v3d y1=(*this)[closest_inferior+1];
00505 
00506         double alpha=(t-t0)/(t1-t0);
00507         MC_v3d y= (1-alpha)*y0+alpha*y1;
00508 
00509         return std::make_pair(y,std::make_pair(MC_int_pair_unique(closest_inferior,closest_inferior+1),alpha));
00510 
00511     }
00512     std::pair <MC_v3d_vector,std::vector<std::pair<MC_int_pair_unique,MC_double_vector> > > MC_curve::value(const MC_double_vector& t) const
00513     {
00514         std::vector <std::pair <MC_int_pair_unique,MC_double_vector> > index_segment(t.size());
00515         MC_v3d_vector y=MC_v3d_vector::zeros(t.size());
00516 
00517         int N=t.size();
00518         for(int k=0;k<N;++k)
00519         {
00520             std::pair <MC_v3d,std::pair <MC_int_pair_unique,double> > temp=value(t[k]);
00521             y[k]=temp.first;
00522             index_segment[k].first=temp.second.first;
00523             index_segment[k].second=temp.second.second;
00524         }
00525         return make_pair(y,index_segment);
00526     }
00527 
00528     std::pair <MC_v3d,double> MC_curve::value(const int& k_segment,const double& _relative_position) const
00529     {
00530         int N=size();
00531         if(k_segment>=N-1 || k_segment<0)
00532         {std::cout<<"Error in MC_curve::value("<<k_segment<<","<<_relative_position<<"). k_segment is not correct for a curve of size "<<N<<std::endl;exit(-1);}
00533         MC_segment s((*this)[k_segment],(*this)[k_segment+1]);
00534         MC_v3d x=s.value(_relative_position);
00535 
00536         MC_double_vector relativ=relativ_position();
00537         double r=relativ[k_segment]*(1-_relative_position)+relativ[k_segment+1]*_relative_position;
00538 
00539         return std::make_pair(x,r);
00540     }
00541     std::pair <MC_v3d_vector,MC_double_vector> MC_curve::value(const MC_int_vector& k_segment,const MC_double_vector& _relative_position) const
00542     {
00543         std::vector <MC_segment> s=segment();
00544         MC_double_vector relativ=relativ_position();
00545 
00546         int N_in=k_segment.size();
00547         int N_curve=size();
00548         if(k_segment.size()!=_relative_position.size())
00549         {std::cout<<"Error in MC_curve::value("<<k_segment<<","<<_relative_position<<"), size are not compatible ("<<k_segment.size()<<"!="<<_relative_position.size()<<")"<<std::endl;exit(-1);}
00550 
00551         MC_v3d_vector x=MC_v3d_vector::zeros(N_in);
00552         MC_double_vector t=MC_double_vector::zeros(N_in);
00553         for(int k=0;k<N_in;++k)
00554         {
00555             int current_seg=k_segment[k];
00556             if(current_seg==N_curve-1 && std::fabs(_relative_position[k])<1e-4)
00557             {x[k]=last(); t[k]=1.0;}
00558             else if(current_seg<0 || current_seg>=N_curve-1)
00559             {std::cout<<"Error in MC_curve::value(), at entry "<<k<<"/"<<N_in<<", value is not correct: "<<current_seg<<", for curve size="<<N_curve<<std::endl;exit(-1);}
00560             else
00561             {
00562                 x[k]=s[current_seg].value(_relative_position[k]);
00563                 t[k]=relativ[current_seg]*(1-_relative_position[k])+relativ[current_seg+1]*_relative_position[k];
00564             }
00565         }
00566 
00567         return std::make_pair(x,t);
00568     }
00569 
00570     MC_curve MC_curve::build_square(const int& N)
00571     {
00572         MC_curve square;
00573         for(int k=0;k<N-1;++k)
00574         {
00575             double alpha=static_cast<double>(k)/static_cast<double>(N-1);
00576             MC_v3d x=MC_v3d(alpha,0,0);
00577             square.add(x);
00578         }
00579         for(int k=0;k<N-1;++k)
00580         {
00581             double alpha=static_cast<double>(k)/static_cast<double>(N-1);
00582             MC_v3d x=MC_v3d(1,alpha,0);
00583             square.add(x);
00584         }
00585         for(int k=0;k<N-1;++k)
00586         {
00587             double alpha=static_cast<double>(k)/static_cast<double>(N-1);
00588             MC_v3d x=MC_v3d(1-alpha,1,0);
00589             square.add(x);
00590         }
00591         for(int k=0;k<N-1;++k)
00592         {
00593             double alpha=static_cast<double>(k)/static_cast<double>(N-1);
00594             MC_v3d x=MC_v3d(0,1-alpha,0);
00595             square.add(x);
00596         }
00597         return square;
00598     }
00599 
00600 
00601     std::pair <MC_v3d,std::pair<int,double> > MC_curve::closest_point(const MC_v3d& x) const
00602     {
00603 
00604         std::vector <MC_segment> s=segment();
00605         if(s.size()<=1)
00606         {
00607             std::cout<<"Warning, MC_curve::closest_point, curve is empty"<<std::endl;
00608             return std::make_pair(MC_v3d(-1,-1,-1),std::make_pair(-1,-1));
00609         }
00610         MC_v3d saved_closest=s[0].closest_point(x);
00611         double min_dist=(saved_closest-x).norm();
00612         std::pair<int,double> param_to_save;
00613         param_to_save.first=0;
00614         param_to_save.second=s[0].relative_position(saved_closest);
00615 
00616         for(unsigned int k=1;k<s.size();++k)
00617         {
00618             MC_v3d current_closest=s[k].closest_point(x);
00619             //std::cout<< k <<" "<<s[k]<<std::endl;
00620             double current_distance=(current_closest-x).norm();
00621             if(current_distance<min_dist)
00622             {
00623                 min_dist=current_distance;
00624 
00625                 saved_closest=current_closest;
00626                 param_to_save.first=k;
00627                 param_to_save.second=s[k].relative_position(current_closest);
00628 
00629             }
00630         }
00631 
00632         return std::make_pair(saved_closest,param_to_save);
00633     }
00634 
00635     MC_curve::MC_curve(const MC_segment& seg):MC_v3d_vector(seg[0],seg[1])
00636     {}
00637 
00638     MC_v3d MC_curve::barycenter() const
00639     {
00640         MC_v3d barycenter;
00641         double total_length=length();
00642 
00643         for(int k=0,N=size();k<N-1;++k)
00644         {
00645             MC_segment seg=MC_segment((*this)[k],(*this)[k+1]);
00646             double L=seg.length();
00647 
00648             MC_v3d p=0.5*(seg[1]+seg[0]);
00649 
00650             barycenter += L*p;
00651         }
00652         barycenter/=total_length;
00653         return barycenter;
00654     }
00655 
00656     MC_curve MC_curve::skinning(const MC_curve& skeleton_old,const MC_curve& skeleton_new) const
00657     {
00658         if(skeleton_old.size()!=skeleton_new.size())
00659         {std::cout<<"Error in MC_curve::skinning, skeleton does not have the same size"<<std::endl;exit(-1);}
00660 
00661 
00662         //weights
00663         int N=skeleton_new.size();
00664         int N_current=size();
00665 
00666         std::vector<MC_segment> segment_old=skeleton_old.segment();
00667         std::vector<MC_segment> segment_new=skeleton_new.segment();
00668 
00669         MC_double_vector_vector w;w.resize(N_current);
00670         MC_v3d_vector detail=MC_v3d_vector::zeros(N_current);
00671 
00672         for(int k=0;k<N_current;++k)
00673         {
00674             w[k].resize(N-1);
00675             for(int k2=0;k2<N-1;++k2)
00676             {
00677                 MC_v3d closest=segment_old[k2].closest_point(v[k]);
00678                 w[k][k2]=(closest-v[k]).norm();
00679             }
00680             //normalize
00681             w[k]=w[k]/MC_double_vector::sum(w[k]);
00682         }
00683 
00684 
00685         std::pair<MC_int_vector,MC_double_vector> barycentric;
00686         for(int k=0;k<N_current;++k)
00687         {
00688             std::pair<MC_v3d,std::pair<int,double> > bar = skeleton_old.closest_point(v[k]);
00689             barycentric.first.add(bar.second.first);
00690             barycentric.second.add(bar.second.second);
00691             detail[k]=-(bar.first-v[k]);
00692         }
00693 
00694 
00695         std::vector<MC_matrix> R(N);
00696         for(int k=0;k<N-1;++k)
00697         {
00698             MC_v3d x0=segment_old[k][0];
00699             MC_v3d x1=segment_old[k][1];
00700 
00701             MC_v3d y0=segment_new[k][0];
00702             MC_v3d y1=segment_new[k][1];
00703 
00704             MC_v3d u0=x1-x0;
00705             MC_v3d u1=y1-y0;
00706 
00707             R[k]=MC_matrix::rotation_axis_to_axis(u0,u1);
00708         }
00709         std::vector<MC_matrix> T(N_current);
00710         for(int k=0;k<N_current;++k)
00711         {
00712             T[k]=MC_matrix(3);
00713             for(int k2=0;k2<N-1;++k2)
00714                 T[k]+=w[k][k2]*R[k2].inverted();
00715         }
00716 
00717         MC_curve curve_new=skeleton_new.value(barycentric.first,barycentric.second).first;
00718         for(int k=0;k<N_current;++k)
00719             curve_new[k] += T[k]*detail[k];
00720 
00721         return curve_new;
00722     }
00723 
00724     void MC_curve::write_vect(std::ostream& stream,const std::vector<MC_curve>& v_curve,const MC_v3d_vector& _v_color)
00725     {
00726         if(stream.good()!=true)
00727         {std::cout<<"Error in MC_curve::write_vect(), ostream is not correct for writing"<<std::endl;exit(-1);}
00728 
00729         if(static_cast<unsigned int>(v_curve.size())!=static_cast<unsigned int>(_v_color.size()) && _v_color.size()!=0)
00730         {std::cout<<"Error in MC_curve::write_vect(), v_curve and v_color have non coherent size "<<v_curve.size()<<"!="<<_v_color.size()<<std::endl;exit(-1);}
00731 
00732         MC_v3d_vector v_color=_v_color;
00733         if(_v_color.size()==0)
00734             v_color=MC_v3d_vector::zeros(v_curve.size());
00735 
00736         unsigned int N=v_curve.size();
00737         unsigned int counter_vertices=0;
00738         for(unsigned int k=0;k<N;++k)
00739             counter_vertices+=v_curve[k].size();
00740 
00741         //header
00742         stream<<"VECT"<<std::endl;
00743         stream<<v_curve.size()<<" "<<counter_vertices<<" "<<v_color.size()<<std::endl;
00744         for(unsigned int k=0;k<N;++k)
00745             stream<<v_curve[k].size()<<" ";
00746         stream<<std::endl;
00747         for(unsigned int k=0;k<N;++k)
00748             stream<<"1"<<" ";
00749         stream<<std::endl<<std::endl;
00750 
00751         //vertices
00752         for(unsigned int k=0;k<N;++k)
00753         {
00754             const MC_curve& curve_current=v_curve[k];
00755             int N_current=curve_current.size();
00756             for(int kc=0;kc<N_current;++kc)
00757                 stream<<curve_current[kc][0]<<" "<<curve_current[kc][1]<<" "<<curve_current[kc][2]<<"  ";
00758             stream<<std::endl;
00759         }
00760         stream<<std::endl;
00761 
00762         //color
00763         for(unsigned int k=0;k<N;++k)
00764         {
00765             const MC_v3d& current_color=v_color[k];
00766             stream<<current_color[0]<<" "<<current_color[1]<<" "<<current_color[2]<<" 1"<<std::endl;
00767         }
00768 
00769     }
00770     void MC_curve::write_vect(const std::string& filename,const std::vector<MC_curve>& v_curve,const MC_v3d_vector& v_color)
00771     {
00772         std::ofstream fid(filename.c_str(),std::ios::out);
00773         if(fid.good()!=true)
00774         {std::cout<<"Error in MC_curve::write_vect(), cannot open file "<<filename<<std::endl;exit(-1);}
00775         write_vect(fid,v_curve,v_color);
00776         fid.close();
00777     }
00778 
00779     void MC_curve::write_vect(const std::string& filename) const
00780     {
00781         std::vector<MC_curve> v_c;v_c.push_back(*this);
00782         write_vect(filename,v_c);
00783     }
00784 
00785      std::pair<std::vector<MC_curve>,MC_v3d_vector> MC_curve::read_vect(std::istream& stream)
00786      {
00787          if(stream.good()!=true)
00788          {std::cout<<"Error in MC_curve::read_vect(), stream is not open"<<std::endl;exit(-1);}
00789 
00790          std::vector<MC_curve> v_curve;
00791          MC_v3d_vector v_color;
00792 
00793          std::string buffer;
00794          //read header
00795          bool is_loop=true;
00796          while(stream.good() && is_loop==true)
00797          {
00798              std::getline(stream,buffer);
00799              if(buffer.length()>0
00800                 && buffer[0]!='#'
00801                 && buffer.find("VECT")!=std::string::npos)
00802                  is_loop=false;
00803          }
00804          if(stream.good()==false && is_loop==true)
00805          {std::cout<<"ERROR in MC_io_off::read_off(istream), cannot find OFF header"<<std::endl;exit(-1);}
00806 
00807 
00808          unsigned int N_polyline=0;
00809          unsigned int N_vertex=0;
00810          unsigned int N_color=0;
00811 
00812          is_loop=true;
00813          //read N_polyline, N_vertex, N_color
00814          while(stream.good() && is_loop==true)
00815          {
00816              std::getline(stream,buffer);
00817              if(buffer.length()>0 && buffer[0]!='#')
00818              {
00819                  std::vector <std::string> token=MC_string_converter::delete_empty(MC_string_tokenizer::tokenize(buffer));
00820                  if(token.size()>=3)
00821                  {
00822                      bool polyline_converted=false;
00823                      bool vertex_converted=false;
00824                      bool color_converted=false;
00825                      N_polyline  = MC_string_converter::value_of<unsigned int>(token[0],&polyline_converted);
00826                      N_vertex = MC_string_converter::value_of<unsigned int>(token[1],&vertex_converted);
00827                      N_color    = MC_string_converter::value_of<unsigned int>(token[2],&color_converted);
00828 
00829                      if(polyline_converted==true && vertex_converted==true && color_converted==true)
00830                          is_loop=false;
00831                  }
00832              }
00833          }
00834 
00835 //         if(N_polyline<=0)
00836 //         {
00837 //             std::vector<MC_curve> v_empty;
00838 //             return std::make_pair(v_empty,MC_v3d_vector());
00839 //         }
00840 
00841          //read size
00842          MC_int_vector polyline_size=MC_int_vector::zeros(N_polyline);
00843          is_loop=true;
00844          while(stream.good() && is_loop==true)
00845          {
00846              std::getline(stream,buffer);
00847              if(buffer.length()>0 && buffer[0]!='#')
00848              {
00849                  std::vector <std::string> token=MC_string_converter::delete_empty(MC_string_tokenizer::tokenize(buffer));
00850                  if(token.size()>=N_polyline)
00851                  {
00852                      for(unsigned int k=0;k<N_polyline;++k)
00853                      {
00854                          bool polysize_converted=false;
00855                          polyline_size[k]=MC_string_converter::value_of<unsigned int>(token[k],&polysize_converted);
00856                          if(polysize_converted==true)
00857                              is_loop=false;
00858                      }
00859                  }
00860                  else
00861                  {std::cout<<"Error in MC_curve::read_vect(), inconsistent vect size: expected "<<N_polyline<<" entries while reading "<<buffer<<std::endl; exit(-1);}
00862              }
00863          }
00864 
00865          //read color
00866          MC_int_vector color_index=MC_int_vector::zeros(N_polyline);
00867          is_loop=true;
00868          while(stream.good() && is_loop==true)
00869          {
00870              std::getline(stream,buffer);
00871              if(buffer.length()>0 && buffer[0]!='#')
00872              {
00873                  std::vector <std::string> token=MC_string_converter::delete_empty(MC_string_tokenizer::tokenize(buffer));
00874                  if(token.size()>=N_polyline)
00875                  {
00876                      for(unsigned int k=0;k<N_polyline;++k)
00877                      {
00878                          bool color_converted=false;
00879                          color_index[k]=MC_string_converter::value_of<unsigned int>(token[k],&color_converted);
00880                          if(color_converted==true)
00881                              is_loop=false;
00882                      }
00883                  }
00884                  else
00885                  {std::cout<<"Error in MC_curve::read_vect(), inconsistent color size: expected "<<N_polyline<<" entries while reading "<<buffer<<std::endl; exit(-1);}
00886              }
00887          }
00888 
00889 
00890          //read vertices
00891          v_curve.resize(N_polyline);
00892          for(unsigned int k_poly=0;k_poly<N_polyline;++k_poly)
00893          {
00894              v_curve[k_poly].resize(polyline_size[k_poly]);
00895 
00896              if(stream.good()==false)
00897              {std::cout<<"Error in MC_curve::read_vect() at polyline"<<k_poly<<" EOF found"<<std::endl;exit(-1);}
00898 
00899              std::getline(stream,buffer);
00900              if(buffer.size()>0 && buffer[0]!='#')
00901              {
00902                  std::vector<std::string> v_token=MC_string_converter::delete_empty(MC_string_tokenizer::tokenize(buffer));
00903                  if(v_token.size()<3*static_cast<unsigned int>(polyline_size[k_poly]))
00904                  {std::cout<<"Error in MC_curve::read_vect(), something wrong at polyline "<<k_poly<<", size of token="<<v_token.size()<<", "<<buffer<<std::endl;exit(-1);}
00905 
00906 
00907                  for(int k_vertex=0,N_vertex=polyline_size[k_poly];k_vertex<N_vertex;++k_vertex)
00908                  {
00909 
00910                      bool converted_x0=false,converted_x1=false,converted_x2=false;
00911                      double x0=MC_string_converter::value_of<double>(v_token[3*k_vertex+0],&converted_x0);
00912                      double x1=MC_string_converter::value_of<double>(v_token[3*k_vertex+1],&converted_x1);
00913                      double x2=MC_string_converter::value_of<double>(v_token[3*k_vertex+2],&converted_x2);
00914 
00915                      if(converted_x0==false || converted_x1==false || converted_x2==false)
00916                      {std::cout<<"Something wrong in MC_curve::read_vect(), cannot convert at vertex "<<k_vertex<<", of polyline "<<k_poly<<" : "<<buffer<<std::endl;exit(-1);}
00917 
00918                      v_curve[k_poly][k_vertex]=MC_v3d(x0,x1,x2);
00919                  }
00920              }
00921              else
00922                  --k_poly;
00923          }
00924 
00925          //read color
00926          v_color.resize(N_polyline);
00927          for(unsigned int k_poly=0;k_poly<N_polyline;++k_poly)
00928          {
00929              if(color_index[k_poly]==0)
00930              {
00931                  if(k_poly>0)
00932                      v_color[k_poly]=v_color[k_poly-1];
00933                  else
00934                  {std::cout<<"Error in MC_curve::read_vect(), something wrong in reading the first color: no color"<<std::endl;exit(-1);}
00935              }
00936              else
00937              {
00938                  is_loop=true;
00939                  //read the actual entry
00940                  while(stream.good() && is_loop==true)
00941                  {
00942                      std::getline(stream,buffer);
00943                      if(buffer.length()>0 && buffer[0]!='#')
00944                      {
00945                          std::vector <std::string> token=MC_string_converter::delete_empty(MC_string_tokenizer::tokenize(buffer));
00946                          if(token.size()>=3)
00947                          {
00948                              bool r_converted=false,g_converted=false,b_converted=false;
00949                              double r=MC_string_converter::value_of<double>(token[0],&r_converted);
00950                              double g=MC_string_converter::value_of<double>(token[1],&g_converted);
00951                              double b=MC_string_converter::value_of<double>(token[2],&b_converted);
00952 
00953 
00954                              if(r_converted==false || g_converted==false || b_converted==false)
00955                              {std::cout<<"Something wrong in MC_curve::read_vect(), cannot convert at color at polyline "<<k_poly<<" : "<<buffer<<std::endl;exit(-1);}
00956 
00957                              v_color[k_poly]=MC_v3d(r,g,b);
00958                              is_loop=false;
00959 
00960                          }
00961                          else
00962                          {std::cout<<"Error in MC_curve::read_vect(), inconsistent color size: expected "<<3<<" entries while reading "<<buffer<<std::endl; exit(-1);}
00963                      }
00964                  }
00965              }
00966          }
00967 
00968 
00969 
00970          return std::make_pair(v_curve,v_color);
00971 
00972      }
00973 
00974      std::pair<std::vector<MC_curve>,MC_v3d_vector> MC_curve::read_vect(const std::string& filename)
00975      {
00976          std::ifstream ifile(filename.c_str(),std::ios::in);
00977          if(ifile.good()!=true)
00978          {std::cout<<"Error in MC_curve::read_vect("<<filename<<"), cannot open the file"<<std::endl;exit(-1);}
00979 
00980          std::pair<std::vector<MC_curve>,MC_v3d_vector> input=read_vect(ifile);
00981 
00982          ifile.close();
00983          return input;
00984      }
00985      MC_curve MC_curve::read_vect_curve(std::istream& stream)
00986      {
00987          std::pair<std::vector<MC_curve>,MC_v3d_vector> input=read_vect(stream);
00988          if(input.first.size()<1)
00989          {std::cout<<"Error in MC_curve::read_vect_curve(), no curve found"<<std::endl;exit(-1);}
00990          return input.first[0];
00991      }
00992      MC_curve MC_curve::read_vect_curve(const std::string& filename)
00993      {
00994          std::ifstream ifile(filename.c_str(),std::ios::in);
00995          if(ifile.good()!=true)
00996          {std::cout<<"Error in MC_curve::read_vect("<<filename<<"), cannot open the file"<<std::endl;exit(-1);}
00997 
00998          MC_curve input=read_vect_curve(ifile);
00999 
01000          ifile.close();
01001          return input;
01002      }
01003      std::pair<MC_v3d_vector,MC_double_vector> MC_curve::value_t(const MC_double_vector t) const
01004      {
01005          MC_int_vector k_seg=MC_int_vector::zeros(t.size());
01006          MC_double_vector t_seg=MC_double_vector::zeros(t.size());
01007 
01008          for(int k=0,N=t.size();k<N;++k)
01009          {
01010              k_seg[k]=static_cast<int>(t[k]);
01011              t_seg[k]=t[k]-k_seg[k];
01012          }
01013          return value(k_seg,t_seg);
01014      }
01015      MC_curve MC_curve::isometric_deformation(const MC_int_vector& constraint_index,const MC_v3d_vector& constraint_position,const MC_curve& original_curve,const double& blending_factor) const
01016      {
01017          MC_curve c=*this;
01018          MC_double_vector L=MC_v3d_vector::norm(original_curve.diff_forward_close());
01019 
01020          int N=size();
01021 
01022          MC_curve c1=*this;
01023          MC_curve c2=*this;
01024 
01025          std::map<int,MC_v3d> constraint_map;
01026          for(int k=0,N_constraint=constraint_index.size();k<N_constraint;++k)
01027              constraint_map.insert(std::make_pair(constraint_index[k],constraint_position[k]));
01028          std::map<int,MC_v3d>::const_iterator constraint_end=constraint_map.end();
01029 
01030          for(std::map<int,MC_v3d>::const_iterator it=constraint_map.begin();it!=constraint_end;++it)
01031          {
01032              c1[it->first]=it->second;
01033              c2[it->first]=it->second;
01034          }
01035 
01036          //iteration loop
01037 
01038          for(int k_loop=0;k_loop<3*N;++k_loop)
01039          {
01040              //forward
01041              for(int k=0;k<N;++k)
01042              {
01043                  std::map<int,MC_v3d>::const_iterator it_current=constraint_map.find(k);
01044                  if(it_current==constraint_end)
01045                  {
01046                      MC_v3d dir0=(original_curve[k]-original_curve[(k-1+N)%N]).normalized();
01047                      MC_v3d dir=(c1[k]-c1[(k-1+N)%N]).normalized();
01048                      dir=(dir+blending_factor*dir0).normalized();
01049                      c1[k] = c1[(k-1+N)%N] + L[k]*dir;
01050                  }
01051              }
01052              //backward
01053              for(int k=N-1;k>=0;--k)
01054              {
01055                  std::map<int,MC_v3d>::const_iterator it_current=constraint_map.find(k);
01056                  if(it_current==constraint_end)
01057                  {
01058                      MC_v3d dir0=(original_curve[k]-original_curve[(k+1)%N]).normalized();
01059                      MC_v3d dir=(c2[k]-c2[(k+1)%N]).normalized();
01060                      dir=(dir+blending_factor*dir0).normalized();
01061                      c2[k] = c2[(k+1)%N] + L[k]*dir;
01062                  }
01063              }
01064              //average
01065              c1=0.5*(c1+c2);
01066              c2=c1;
01067          }
01068 
01069          return c1;
01070 
01071      }
01072 
01073  }

Generated on Sun Apr 18 20:24:47 2010 by  doxygen 1.6.1