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
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
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
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
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
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
00324 T[0]=t*t*t;T[1]=t*t;T[2]=t;T[3]=1;
00325
00326
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
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
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
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
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
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
00392
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
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
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
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
00488 MC_double_vector vt=relativ_position();
00489
00490
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
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
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
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
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
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
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
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
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
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
00836
00837
00838
00839
00840
00841
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
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
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
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
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
01037
01038 for(int k_loop=0;k_loop<3*N;++k_loop)
01039 {
01040
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
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
01065 c1=0.5*(c1+c2);
01066 c2=c1;
01067 }
01068
01069 return c1;
01070
01071 }
01072
01073 }