MC_mesh_index_vector.cpp

Go to the documentation of this file.
00001 
00002 #include <MC_mesh_index_vector.hpp>
00003 
00004 #include <MC_segment.hpp>
00005 #include <MC_polygon.hpp>
00006 #include <MC_triangle.hpp>
00007 #include <MC_matrix.hpp>
00008 #include <MC_int_vector.hpp>
00009 #include <MC_int_vector_vector.hpp>
00010 #include <MC_int_pair.hpp>
00011 #include <MC_double_vector_vector.hpp>
00012 #include <MC_io_off.hpp>
00013 #include <MC_helper_stl.hpp>
00014 #include <MC_string_helper.hpp>
00015 
00016 #include <MC_io_off.hpp>
00017 #include <MC_io_obj.hpp>
00018 #include <MC_int_pair.hpp>
00019 
00020 #include <sstream>
00021 
00022 
00023 #include <map>
00024 #include <set>
00025 #include <vector>
00026 
00027 
00028 
00029 
00030 
00031 namespace mesh_conv
00032 {
00033 
00034 
00035     MC_mesh_index_vector::MC_mesh_index_vector(){}
00036 
00037     int MC_mesh_index_vector::polygon_number() const {return connectivity_mesh.size();}
00038     int MC_mesh_index_vector::vertex_number() const {return point_set_mesh.size();}
00039 
00040 
00041     MC_mesh_index_vector& MC_mesh_index_vector::add_vertex(const MC_v3d& v) {point_set_mesh.add(v); return *this;}
00042     MC_mesh_index_vector& MC_mesh_index_vector::add_connectivity_index(const MC_int_vector& c) {connectivity_mesh.add(c); return *this;}
00043 
00044 
00045     MC_connectivity_index& MC_mesh_index_vector::connectivity() {return connectivity_mesh;}
00046     const MC_connectivity_index& MC_mesh_index_vector::connectivity() const {return connectivity_mesh;}
00047     MC_v3d_vector& MC_mesh_index_vector::point_set() {return point_set_mesh;}
00048     const MC_v3d_vector& MC_mesh_index_vector::point_set() const {return point_set_mesh;}
00049 
00050     int MC_mesh_index_vector::polygon_size(const int& k_polygon) const
00051     {
00052         //check size
00053         if( k_polygon<0 || k_polygon>=connectivity_mesh.size() )
00054         {std::cout<<"Error in MC_mesh_index_vector::polygon_size("<<k_polygon<<"), with connectivity size="<<connectivity_mesh.size()<<std::endl;exit(-1);}
00055 
00056         return connectivity_mesh[k_polygon].size();
00057     }
00058     MC_polygon MC_mesh_index_vector::get_polygon(const int& k_index) const
00059     {
00060         //check size
00061         if( k_index<0 || k_index>=connectivity_mesh.size() )
00062         {std::cout<<"Error in MC_mesh_index_vector::polygon_size("<<k_index<<"), with connectivity size="<<connectivity_mesh.size()<<std::endl;exit(-1);}
00063         return point_set_mesh(connectivity_mesh[k_index]);
00064     }
00065 
00066     MC_mesh_index_vector MC_mesh_index_vector::build_cube()
00067     {
00068         MC_v3d_vector points = MC_v3d_vector(MC_v3d(0,0,0))<<
00069                                MC_v3d(1,0,0)<<
00070                                MC_v3d(1,1,0)<<
00071                                MC_v3d(0,1,0)<<
00072                                MC_v3d(1,0,1)<<
00073                                MC_v3d(1,1,1)<<
00074                                MC_v3d(0,1,1)<<
00075                                MC_v3d(0,0,1);
00076 
00077         MC_connectivity_index conn = MC_connectivity_index(MC_int_vector(0,1,2,3))<<
00078                                      MC_int_vector(1,4,5,2)<<
00079                                      MC_int_vector(2,5,6,3)<<
00080                                      MC_int_vector(3,6,7,0)<<
00081                                      MC_int_vector(0,7,4,1)<<
00082                                      MC_int_vector(6,5,4,7);
00083 
00084         //std::cout<<conn<<std::endl;
00085 
00086         return MC_mesh_index_vector(points,conn);
00087     }
00088 
00089     MC_mesh_index_vector::MC_mesh_index_vector(const MC_v3d_vector& _point_set,const MC_connectivity_index& _connectivity)
00090     {point_set_mesh=_point_set;connectivity_mesh=_connectivity;}
00091     MC_mesh_index_vector::MC_mesh_index_vector(const std::pair<MC_v3d_vector,MC_connectivity_index>& _mesh)
00092     {*this=MC_mesh_index_vector(_mesh.first,_mesh.second);}
00093 
00094     MC_mesh_index_vector operator+(const MC_mesh_index_vector& vec,const MC_v3d& to_add)
00095     {return MC_mesh_index_vector(vec.point_set()+to_add,vec.connectivity());}
00096     MC_mesh_index_vector operator-(const MC_mesh_index_vector& vec,const MC_v3d& to_sub)
00097     {return MC_mesh_index_vector(vec.point_set()-to_sub,vec.connectivity());}
00098     MC_mesh_index_vector operator+(const MC_mesh_index_vector& vec,const MC_v3d_vector& to_add)
00099     {return MC_mesh_index_vector(vec.point_set()+to_add,vec.connectivity());}
00100     MC_mesh_index_vector operator-(const MC_mesh_index_vector& vec,const MC_v3d_vector& to_sub)
00101     {return MC_mesh_index_vector(vec.point_set()-to_sub,vec.connectivity());}
00102     MC_mesh_index_vector operator*(const MC_mesh_index_vector& vec,const double& to_mult)
00103     {return MC_mesh_index_vector(vec.point_set()*to_mult,vec.connectivity());}
00104     MC_mesh_index_vector operator*(const double& to_mult,const MC_mesh_index_vector& vec)
00105     {return vec*to_mult;}
00106     MC_mesh_index_vector operator/(const MC_mesh_index_vector& vec,const double& to_subdiv)
00107     {return MC_mesh_index_vector(vec.point_set()/to_subdiv,vec.connectivity());}
00108 
00109     MC_mesh_index_vector& MC_mesh_index_vector::operator+=(const MC_v3d& to_add)
00110     {point_set_mesh+=to_add;return *this;}
00111     MC_mesh_index_vector& MC_mesh_index_vector::operator-=(const MC_v3d& to_sub)
00112     {point_set_mesh-=to_sub;return *this;}
00113     MC_mesh_index_vector& MC_mesh_index_vector::operator+=(const MC_v3d_vector& to_add)
00114     {point_set_mesh+=to_add;return *this;}
00115     MC_mesh_index_vector& MC_mesh_index_vector::operator-=(const MC_v3d_vector& to_sub)
00116     {point_set_mesh-=to_sub;return *this;}
00117     MC_mesh_index_vector& MC_mesh_index_vector::operator*=(const double& to_mult)
00118     {point_set_mesh*=to_mult;return *this;}
00119     MC_mesh_index_vector& MC_mesh_index_vector::operator/=(const double& to_subdiv)
00120     {point_set_mesh/=to_subdiv;return *this;}
00121 
00122     MC_mesh_index_vector operator*(const MC_matrix& M,const MC_mesh_index_vector& mesh)
00123     {return MC_mesh_index_vector(M*mesh.point_set(),mesh.connectivity());}
00124     MC_mesh_index_vector& MC_mesh_index_vector::operator*=(const MC_matrix& M)
00125     {point_set_mesh*=M;return *this;}
00126 
00127     MC_v3d_vector MC_mesh_index_vector::normal_vertex() const
00128     {
00129 
00130 
00131         MC_v3d_vector v_n(point_set().size());
00132         if(static_cast<int>(connectivity().star().size())!=point_set().size())
00133         {std::cout<<"Error in MC_v3d_vector MC_mesh_index_vector::normal_vertex(), one star has size "<<connectivity_mesh.star().size()<<", with "<<point_set_mesh.size()<<" vertices, probably need to compute one star"<<std::endl;exit(-1);}
00134         std::map<int,std::set<int> > star = connectivity().star();
00135 
00136         std::map<int,std::set<int> > :: const_iterator it=star.begin();
00137         std::map<int,std::set<int> > :: const_iterator it_end=star.end();
00138         for(;it!=it_end;++it)
00139         {
00140 
00141             int current_vertex=it->first;
00142             std::set <int> :: const_iterator it_poly=it->second.begin();
00143             std::set <int> :: const_iterator it_poly_end=it->second.end();
00144             for(;it_poly!=it_poly_end;++it_poly)
00145             {
00146                 int current_poly=*it_poly;
00147                 MC_v3d n=MC_polygon(point_set()(connectivity()(current_poly))).normal();
00148                 v_n[current_vertex]+=n;
00149             }
00150         }
00151 
00152         v_n=v_n.normalized();
00153         return v_n;
00154     }
00155 
00156 
00157     MC_v3d_vector MC_mesh_index_vector::normal_vertex(const MC_v3d_vector& point_set_mesh,const MC_connectivity_index& connectivity_mesh)
00158     {
00159 
00160         MC_v3d_vector v_n(point_set_mesh.size());
00161         if(static_cast<int>(connectivity_mesh.star().size())!=point_set_mesh.size())
00162         {std::cout<<"Error in MC_v3d_vector MC_mesh_index_vector::normal_vertex(MC_v3d_vector,MC_connectivity_index), one star has size "<<connectivity_mesh.star().size()<<", with "<<point_set_mesh.size()<<" vertices, probably need to compute one star"<<std::endl;exit(-1);}
00163         std::map<int,std::set<int> > star = connectivity_mesh.star();
00164 
00165         std::map<int,std::set<int> > :: const_iterator it=star.begin();
00166         std::map<int,std::set<int> > :: const_iterator it_end=star.end();
00167         for(;it!=it_end;++it)
00168         {
00169 
00170             int current_vertex=it->first;
00171             std::set <int> :: const_iterator it_poly=it->second.begin();
00172             std::set <int> :: const_iterator it_poly_end=it->second.end();
00173             for(;it_poly!=it_poly_end;++it_poly)
00174             {
00175                 int current_poly=*it_poly;
00176                 MC_v3d n=MC_polygon(point_set_mesh(connectivity_mesh(current_poly))).normal();
00177                 v_n[current_vertex]+=n;
00178             }
00179         }
00180 
00181 //        for(int k=0;k<v_n.size();++k)
00182 //            if(v_n[k].norm()<0.0001)
00183 //                std::cout<<k<<", "<<v_n[k]<<std::endl;
00184 
00185         v_n=v_n.normalized();
00186 
00187         return v_n;
00188     }
00189     MC_double_vector MC_mesh_index_vector::normal_vertex(const MC_double_vector& point_set_mesh,const MC_connectivity_index& connectivity_mesh)
00190     {
00191         MC_double_vector v_n=MC_double_vector::zeros(point_set_mesh.size());
00192         if(static_cast<int>(connectivity_mesh.star().size())!=point_set_mesh.size()/3)
00193         {std::cout<<"Error in MC_v3d_vector MC_mesh_index_vector::normal_vertex(MC_v3d_vector,MC_connectivity_index), one star has size "<<connectivity_mesh.star().size()<<", with "<<point_set_mesh.size()<<" vertices, probably need to compute one star"<<std::endl;exit(-1);}
00194         std::map<int,std::set<int> > star = connectivity_mesh.star();
00195 
00196         std::map<int,std::set<int> > :: const_iterator it=star.begin();
00197         std::map<int,std::set<int> > :: const_iterator it_end=star.end();
00198         for(;it!=it_end;++it)
00199         {
00200 
00201 
00202             int current_vertex=it->first;
00203             std::set <int> :: const_iterator it_poly=it->second.begin();
00204             std::set <int> :: const_iterator it_poly_end=it->second.end();
00205             for(;it_poly!=it_poly_end;++it_poly)
00206             {
00207                 int current_poly=*it_poly;
00208                 MC_int_vector index=connectivity_mesh(current_poly);int N_index=index.size();
00209                 MC_polygon p;
00210                 for(int k=0;k<N_index;++k)
00211                     p.add(MC_v3d(point_set_mesh(3*index(k)+0),point_set_mesh(3*index(k)+1),point_set_mesh(3*index(k)+2)));
00212                 MC_v3d n=p.normal();
00213 
00214                 for(int k_dim=0;k_dim<3;++k_dim)
00215                     v_n[3*current_vertex+k_dim]+=n[k_dim];
00216             }
00217         }
00218 
00219         //int N_v=point_set_mesh.size()/3;
00220         double epsilon=0.00000001;
00221         for(int k=0;k<point_set_mesh.size()/3;++k)
00222         {
00223             MC_v3d temp(v_n(3*k+0),v_n(3*k+1),v_n(3*k+2));
00224             double nn=temp.norm();
00225             if(nn>epsilon)
00226             {v_n(3*k+0)/=nn;v_n(3*k+1)/=nn;v_n(3*k+2)/=nn;}
00227             else
00228             {v_n(3*k+0)=1;v_n(3*k+1)=0;v_n(3*k+2)=0;}
00229         }
00230         return v_n;
00231     }
00232 
00233     MC_v3d_vector MC_mesh_index_vector::normal_polygon() const
00234     {
00235         int N_poly=polygon_number();
00236         MC_v3d_vector n=MC_v3d_vector::zeros(N_poly);
00237         for(int k=0;k<N_poly;++k)
00238             n[k]=get_polygon(k).normal();
00239         return n;
00240     }
00241 
00242 
00243     MC_mesh_index_vector MC_mesh_index_vector::build_icosahedron()
00244     {
00245         double p = 0.5*(1+powf(5,0.5));
00246         double f = 1.0/powf(float(1.0+p*p),0.5f);
00247 
00248         //vertices
00249         MC_v3d_vector icosahedron_vertex=MC_v3d_vector(MC_v3d( p, 1, 0))
00250                                          <<MC_v3d(-p, 1, 0)
00251                                          <<MC_v3d( p,-1, 0)
00252                                          <<MC_v3d(-p,-1, 0)
00253                                          <<MC_v3d( 1, 0, p)
00254                                          <<MC_v3d( 1, 0,-p)
00255                                          <<MC_v3d(-1, 0, p)
00256                                          <<MC_v3d(-1, 0,-p)
00257                                          <<MC_v3d( 0, p, 1)
00258                                          <<MC_v3d( 0,-p, 1)
00259                                          <<MC_v3d( 0, p,-1)
00260                                          <<MC_v3d( 0,-p,-1) ;
00261 
00262 
00263         icosahedron_vertex*=f;
00264 
00265 
00266         //triangulation
00267         MC_connectivity_index icosahedron_tri=MC_connectivity_index(MC_int_vector(0, 8, 4))
00268                                               <<MC_int_vector( 0, 5,10)
00269                                               <<MC_int_vector( 2, 4, 9)
00270                                               <<MC_int_vector( 2,11, 5)
00271                                               <<MC_int_vector( 1, 6, 8)
00272                                               <<MC_int_vector( 1,10, 7)
00273                                               <<MC_int_vector( 3, 9, 6)
00274                                               <<MC_int_vector( 3, 7,11)
00275                                               <<MC_int_vector( 0,10, 8)
00276                                               <<MC_int_vector( 1, 8,10)
00277                                               <<MC_int_vector( 2, 9,11)
00278                                               <<MC_int_vector( 3,11, 9)
00279                                               <<MC_int_vector( 4, 2, 0)
00280                                               <<MC_int_vector( 5, 0, 2)
00281                                               <<MC_int_vector( 6, 1, 3)
00282                                               <<MC_int_vector( 7, 3, 1)
00283                                               <<MC_int_vector( 8, 6, 4)
00284                                               <<MC_int_vector( 9, 4, 6)
00285                                               <<MC_int_vector(10, 5, 7)
00286                                               <<MC_int_vector(11, 7, 5) ;
00287 
00288 
00289         return MC_mesh_index_vector(icosahedron_vertex,icosahedron_tri);
00290     }
00291 
00292     MC_mesh_index_vector MC_mesh_index_vector::subdivide_mid_edge_unchanged_boundary(const std::set<MC_int_pair,MC_int_pair_less>& allowed_edge) const
00293     {
00294         std::set<MC_int_pair,MC_int_pair_less>::const_iterator allowed_edge_end=allowed_edge.end();
00295 
00296         MC_mesh_index_vector new_mesh;
00297         new_mesh.point_set()=point_set();
00298 
00299 
00300         std::set <int> s=connectivity_mesh.boundary_polygon();
00301         std::set <MC_int_pair,MC_int_pair_less> bnd=connectivity_mesh.boundary();
00302         std::set <int> bnd_poly=connectivity_mesh.boundary_polygon();
00303 
00304         std::map <MC_int_pair,int,MC_int_pair_less> newly_added_vertices;
00305 
00306         MC_v3d_vector vertex=point_set_mesh;
00307         int N_polygon=polygon_number();
00308         for(int k=0;k<N_polygon;++k)
00309         {
00310             MC_int_vector poly=connectivity_mesh(k);
00311             std::pair<std::vector <MC_polygon>,std::pair<MC_mesh_index_vector,std::pair<MC_int_vector,MC_int_vector> > > current_poly;
00312             if(bnd_poly.find(k)==bnd_poly.end())//classical subdivision
00313                 current_poly=get_polygon(k).subdivide_mid_edge();
00314             else
00315             {
00316                 MC_int_vector constraint_edge;
00317                 int poly_size=poly.size();
00318                 for(int k_poly=0;k_poly<poly_size;++k_poly)
00319                 {
00320                     MC_int_pair current_edge(poly[k_poly],poly[(k_poly+1)%poly_size]);
00321                     if(bnd.find(current_edge)!=bnd.end())
00322                     {
00323                         std::set<MC_int_pair,MC_int_pair_less>::const_iterator temp_it=allowed_edge.find(current_edge);
00324                         if(temp_it==allowed_edge_end)
00325                             constraint_edge.add(k_poly);
00326                     }
00327                 }
00328                 current_poly=get_polygon(k).subdivide_mid_edge(constraint_edge);
00329             }
00330 
00331 
00332 
00333             // goes back to global mesh
00334             MC_mesh_index_vector local_mesh=current_poly.second.first;
00335             MC_int_vector extra_vertices=current_poly.second.second.first;
00336             MC_int_vector edge_of_extra_vertices=current_poly.second.second.second;
00337 
00338 
00339 
00340 
00341             std::map <int,int> extra_local_to_global;
00342             for(int k_edge=0;k_edge<edge_of_extra_vertices.size();++k_edge)
00343             {
00344                 MC_int_pair index_edge_local(edge_of_extra_vertices[k_edge],(edge_of_extra_vertices[k_edge]+1)%poly.size());
00345                 MC_int_pair index_edge_global(poly(index_edge_local[0]),poly(index_edge_local[1]));
00346 
00347                 std::pair <std::map<MC_int_pair,int,MC_int_pair_less>::iterator,bool> insert_it=newly_added_vertices.insert(std::make_pair(index_edge_global,new_mesh.point_set().size()));
00348                 if(insert_it.second==true)
00349                 {
00350                     extra_local_to_global[extra_vertices[k_edge]]=new_mesh.point_set().size();
00351                     new_mesh.point_set().add(local_mesh.point_set()[extra_vertices[k_edge]]);
00352                 }
00353                 else
00354                     extra_local_to_global[extra_vertices[k_edge]]=insert_it.first->second;
00355             }
00356 
00357             for(int k_new_poly=0;k_new_poly<local_mesh.polygon_number();++k_new_poly)
00358             {
00359                 MC_int_vector local_poly=local_mesh.connectivity()(k_new_poly);
00360                 MC_int_vector global_poly;
00361                 for(int k_new_poly_vertex=0;k_new_poly_vertex<local_poly.size();++k_new_poly_vertex)
00362                 {
00363                     int u=local_poly[k_new_poly_vertex];
00364                     if(u<poly.size())//old vertices
00365                         global_poly.add(poly[u]);
00366                     else
00367                         global_poly.add(extra_local_to_global[u]);
00368 
00369                 }
00370                 new_mesh.connectivity().add(global_poly);
00371             }
00372         }
00373         return new_mesh;
00374     }
00375 
00376 
00377 
00378     MC_mesh_index_vector MC_mesh_index_vector::subdivide_barycenter_mid_edge_unchanged_boundary(const std::set<MC_int_pair,MC_int_pair_less>& allowed_edge) const
00379     {
00380         MC_mesh_index_vector new_mesh;
00381         new_mesh.point_set()=point_set();
00382 
00383 
00384         std::set <int> s=connectivity_mesh.boundary_polygon();
00385         std::set <MC_int_pair,MC_int_pair_less> bnd=connectivity_mesh.boundary();
00386         std::set <int> bnd_poly=connectivity_mesh.boundary_polygon();
00387 
00388         std::map <MC_int_pair,int,MC_int_pair_less> newly_added_vertices;
00389 
00390         MC_v3d_vector vertex=point_set_mesh;
00391         int N_polygon=polygon_number();
00392         for(int k=0;k<N_polygon;++k)
00393         {
00394             MC_int_vector poly=connectivity_mesh(k);
00395             std::pair<std::vector <MC_polygon>,std::pair<MC_mesh_index_vector,std::pair<MC_int_vector,MC_int_vector> > > current_poly;
00396             if(bnd_poly.find(k)==bnd_poly.end())//classical subdivision
00397                 current_poly=get_polygon(k).subdivide_barycenter_mid_edge();
00398             else
00399             {
00400                 MC_int_vector constraint_edge;
00401                 int poly_size=poly.size();
00402                 for(int k_poly=0;k_poly<poly_size;++k_poly)
00403                 {
00404                     MC_int_pair current_edge(poly[k_poly],poly[(k_poly+1)%poly_size]);
00405                     if(bnd.find(current_edge)!=bnd.end())
00406                         if(allowed_edge.find(current_edge)==allowed_edge.end())
00407                             constraint_edge.add(k_poly);
00408                 }
00409                 current_poly=get_polygon(k).subdivide_barycenter_mid_edge(constraint_edge);
00410             }
00411 
00412 
00413 
00414             // goes back to global mesh
00415             MC_mesh_index_vector local_mesh=current_poly.second.first;
00416             MC_int_vector extra_vertices=current_poly.second.second.first;
00417             MC_int_vector edge_of_extra_vertices=current_poly.second.second.second;
00418 
00419 
00420 
00421 
00422 
00423             std::map <int,int> extra_local_to_global;
00424 
00425             //add the barycenter
00426             extra_local_to_global[poly.size()]=new_mesh.point_set().size();
00427             new_mesh.point_set().add(local_mesh.point_set()[poly.size()]);
00428 
00429             for(int k_edge=0;k_edge<edge_of_extra_vertices.size();++k_edge)
00430             {
00431                 MC_int_pair index_edge_local(edge_of_extra_vertices[k_edge],(edge_of_extra_vertices[k_edge]+1)%poly.size());
00432                 MC_int_pair index_edge_global(poly(index_edge_local[0]),poly(index_edge_local[1]));
00433 
00434 
00435                 std::pair <std::map<MC_int_pair,int,MC_int_pair_less>::iterator,bool> insert_it=newly_added_vertices.insert(std::make_pair(index_edge_global,new_mesh.point_set().size()));
00436                 if(insert_it.second==true)
00437                 {
00438                     extra_local_to_global[extra_vertices[k_edge]]=new_mesh.point_set().size();
00439                     new_mesh.point_set().add(local_mesh.point_set()[extra_vertices[k_edge]]);
00440                 }
00441                 else
00442                     extra_local_to_global[extra_vertices[k_edge]]=insert_it.first->second;
00443             }
00444 
00445 
00446 
00447             for(int k_new_poly=0;k_new_poly<local_mesh.polygon_number();++k_new_poly)
00448             {
00449                 MC_int_vector local_poly=local_mesh.connectivity()(k_new_poly);
00450                 MC_int_vector global_poly;
00451                 for(int k_new_poly_vertex=0;k_new_poly_vertex<local_poly.size();++k_new_poly_vertex)
00452                 {
00453                     int u=local_poly[k_new_poly_vertex];
00454                     if(u<poly.size())//old vertices
00455                         global_poly.add(poly[u]);
00456                     else
00457                         global_poly.add(extra_local_to_global[u]);
00458 
00459                 }
00460                 new_mesh.connectivity().add(global_poly);
00461             }
00462         }
00463         return new_mesh;
00464     }
00465 
00466 
00467     MC_mesh_index_vector MC_mesh_index_vector::subdivide_mixed_mid_edge_unchanged_boundary(const std::set<MC_int_pair,MC_int_pair_less>& allowed_edge) const
00468     {
00469         MC_mesh_index_vector new_mesh;
00470         new_mesh.point_set()=point_set();
00471 
00472 
00473         std::set <int> s=connectivity_mesh.boundary_polygon();
00474         std::set <MC_int_pair,MC_int_pair_less> bnd=connectivity_mesh.boundary();
00475         std::set <int> bnd_poly=connectivity_mesh.boundary_polygon();
00476 
00477         std::map <MC_int_pair,int,MC_int_pair_less> newly_added_vertices;
00478 
00479         MC_v3d_vector vertex=point_set_mesh;
00480         int N_polygon=polygon_number();
00481         for(int k=0;k<N_polygon;++k)
00482         {
00483             MC_int_vector poly=connectivity_mesh(k);
00484             std::pair<std::vector <MC_polygon>,std::pair<MC_mesh_index_vector,std::pair<MC_int_vector,MC_int_vector> > > current_poly;
00485             if(bnd_poly.find(k)==bnd_poly.end())//classical subdivision
00486                 current_poly=get_polygon(k).subdivide_mixed_mid_edge();
00487             else
00488             {
00489                 MC_int_vector constraint_edge;
00490                 int poly_size=poly.size();
00491                 for(int k_poly=0;k_poly<poly_size;++k_poly)
00492                 {
00493                     MC_int_pair current_edge(poly[k_poly],poly[(k_poly+1)%poly_size]);
00494                     if(bnd.find(current_edge)!=bnd.end())
00495                         if(allowed_edge.find(current_edge)==allowed_edge.end())
00496                             constraint_edge.add(k_poly);
00497                 }
00498                 current_poly=get_polygon(k).subdivide_mixed_mid_edge(constraint_edge);
00499             }
00500 
00501 
00502 
00503             // goes back to global mesh
00504             MC_mesh_index_vector local_mesh=current_poly.second.first;
00505             MC_int_vector extra_vertices=current_poly.second.second.first;
00506             MC_int_vector edge_of_extra_vertices=current_poly.second.second.second;
00507 
00508 
00509 
00510 
00511 
00512             std::map <int,int> extra_local_to_global;
00513 
00514             //add the barycenter
00515             if(poly.size()!=3)
00516             {
00517                 extra_local_to_global[poly.size()]=new_mesh.point_set().size();
00518                 new_mesh.point_set().add(local_mesh.point_set()[poly.size()]);
00519             }
00520 
00521             for(int k_edge=0;k_edge<edge_of_extra_vertices.size();++k_edge)
00522             {
00523                 MC_int_pair index_edge_local(edge_of_extra_vertices[k_edge],(edge_of_extra_vertices[k_edge]+1)%poly.size());
00524                 MC_int_pair index_edge_global(poly(index_edge_local[0]),poly(index_edge_local[1]));
00525 
00526 
00527                 std::pair <std::map<MC_int_pair,int,MC_int_pair_less>::iterator,bool> insert_it=newly_added_vertices.insert(std::make_pair(index_edge_global,new_mesh.point_set().size()));
00528                 if(insert_it.second==true)
00529                 {
00530                     extra_local_to_global[extra_vertices[k_edge]]=new_mesh.point_set().size();
00531                     new_mesh.point_set().add(local_mesh.point_set()[extra_vertices[k_edge]]);
00532                 }
00533                 else
00534                     extra_local_to_global[extra_vertices[k_edge]]=insert_it.first->second;
00535             }
00536 
00537 
00538 
00539             for(int k_new_poly=0;k_new_poly<local_mesh.polygon_number();++k_new_poly)
00540             {
00541                 MC_int_vector local_poly=local_mesh.connectivity()(k_new_poly);
00542                 MC_int_vector global_poly;
00543                 for(int k_new_poly_vertex=0;k_new_poly_vertex<local_poly.size();++k_new_poly_vertex)
00544                 {
00545                     int u=local_poly[k_new_poly_vertex];
00546                     if(u<poly.size())//old vertices
00547                         global_poly.add(poly[u]);
00548                     else
00549                         global_poly.add(extra_local_to_global[u]);
00550 
00551                 }
00552                 new_mesh.connectivity().add(global_poly);
00553             }
00554         }
00555         return new_mesh;
00556     }
00557 
00558 
00559 
00560 
00561     MC_mesh_index_vector MC_mesh_index_vector::subdivide_mid_edge() const
00562     {
00563 
00564 
00565         //the subdivided Mesh
00566         MC_mesh_index_vector mesh2;
00567 
00568         //MC_int_vector_vector index_mid_point(vertex_number); //the index of the mid point
00569         //MC_int_vector_vector already_existing_mid_point(vertex_number); //the already existing edges
00570 
00571         std::vector <std::map <int,int> > index_mid_point(vertex_number());
00572 
00573 
00574         //first add the old vertices
00575         mesh2.point_set()=point_set_mesh;
00576 
00577         // record the mid_points first
00578         int current_vertex=vertex_number();
00579         int N_polygon=polygon_number();
00580         for(int k_polygon=0;k_polygon<N_polygon;k_polygon++)
00581         {
00582             MC_int_vector index_poly=connectivity_mesh[k_polygon];
00583             int size_polygon=index_poly.size();
00584             for(int k_edge=0;k_edge<size_polygon;++k_edge)
00585             {
00586                 int index_v0=index_poly[k_edge];
00587                 int index_v1=index_poly[(k_edge+1)%size_polygon];
00588 
00589                 if( index_mid_point[index_v0].find(index_v1)==index_mid_point[index_v0].end() )
00590                 {
00591                     // connectivity save
00592                     index_mid_point[index_v0].insert(std::pair <int,int> (index_v1,current_vertex) );
00593                     index_mid_point[index_v1].insert(std::pair <int,int> (index_v0,current_vertex) );
00594 
00595                     // the geometrical mid_point
00596                     mesh2.point_set().add(0.5*(point_set_mesh(index_v0)+point_set_mesh(index_v1)));
00597 
00598                     current_vertex++;
00599                 }
00600             }
00601         }
00602 
00603         // connectivity now
00604         for(int k_polygon=0;k_polygon<N_polygon;++k_polygon)
00605         {
00606             // the triangles/mid_edges-barycenter
00607             MC_int_vector index_poly=connectivity_mesh[k_polygon];
00608             int size_polygon=index_poly.size();
00609 
00610             for(int k_edge=0;k_edge<size_polygon;++k_edge)
00611             {
00612                 int index_v0  = index_poly(k_edge);
00613                 int index_v1  = index_poly((k_edge+1)%size_polygon);
00614                 int index_vm1 = index_poly((k_edge+size_polygon-1)%size_polygon);
00615 
00616                 int  index_mid  = index_mid_point[index_v0].find(index_v1)->second;
00617                 int  index_mid2 = index_mid_point[index_v0].find(index_vm1)->second;
00618 
00619                 mesh2.connectivity().add(MC_int_vector(index_v0,index_mid,index_mid2));
00620             }
00621 
00622             //add the non triangular part linking every barycenters
00623             MC_int_vector temp_poly;
00624             for(int k_edge=0;k_edge<size_polygon;++k_edge)
00625             {
00626                 int index_v0  = index_poly(k_edge);
00627                 int index_v1  = index_poly((k_edge+1)%size_polygon);
00628 
00629                 int index_mid = index_mid_point[index_v0].find(index_v1)->second;
00630                 temp_poly.add(index_mid);
00631             }
00632             mesh2.connectivity().add(temp_poly);
00633         }
00634 
00635         return mesh2;
00636     }
00637 
00638 
00639     MC_mesh_index_vector MC_mesh_index_vector::subdivide_barycenter_mid_edge() const
00640     {
00641 
00642 
00643         //the subdivided Mesh
00644         MC_mesh_index_vector mesh2;
00645 
00646         //MC_int_vector_vector index_mid_point(vertex_number); //the index of the mid point
00647         //MC_int_vector_vector already_existing_mid_point(vertex_number); //the already existing edges
00648 
00649         std::vector <std::map <int,int> > index_mid_point(vertex_number());
00650         std::map <int,int> barycenter_map;
00651 
00652         //first add the old vertices
00653         mesh2.point_set()=point_set_mesh;
00654 
00655         // record the mid_points first
00656         int current_vertex=vertex_number();
00657         int N_polygon=polygon_number();
00658         for(int k_polygon=0;k_polygon<N_polygon;k_polygon++)
00659         {
00660             MC_int_vector index_poly=connectivity_mesh[k_polygon];
00661             int size_polygon=index_poly.size();
00662             for(int k_edge=0;k_edge<size_polygon;++k_edge)
00663             {
00664                 int index_v0=index_poly[k_edge];
00665                 int index_v1=index_poly[(k_edge+1)%size_polygon];
00666 
00667                 if( index_mid_point[index_v0].find(index_v1)==index_mid_point[index_v0].end() )
00668                 {
00669                     // connectivity save
00670                     index_mid_point[index_v0].insert(std::pair <int,int> (index_v1,current_vertex) );
00671                     index_mid_point[index_v1].insert(std::pair <int,int> (index_v0,current_vertex) );
00672 
00673                     // the geometrical mid_point
00674                     mesh2.point_set().add(0.5*(point_set_mesh(index_v0)+point_set_mesh(index_v1)));
00675 
00676                     current_vertex++;
00677                 }
00678             }
00679 
00680             // add the barycenter
00681             barycenter_map.insert(std::pair<int,int>(k_polygon,current_vertex++));
00682             mesh2.point_set().add(MC_v3d_vector::sum(mesh2.point_set()(index_poly))/size_polygon);
00683         }
00684 
00685         // connectivity now
00686         for(int k_polygon=0;k_polygon<N_polygon;++k_polygon)
00687         {
00688             // the triangles/mid_edges-barycenter
00689             MC_int_vector index_poly=connectivity_mesh[k_polygon];
00690             int size_polygon=index_poly.size();
00691 
00692             int index_barycenter=barycenter_map.find(k_polygon)->second;
00693             for(int k_edge=0;k_edge<size_polygon;++k_edge)
00694             {
00695                 int index_v0  = index_poly(k_edge);
00696                 int index_v1  = index_poly((k_edge+1)%size_polygon);
00697                 int index_vm1 = index_poly((k_edge+size_polygon-1)%size_polygon);
00698 
00699                 int  index_mid  = index_mid_point[index_v0].find(index_v1)->second;
00700                 int  index_mid2 = index_mid_point[index_v0].find(index_vm1)->second;
00701 
00702 
00703                 mesh2.connectivity().add(MC_int_vector(index_v0,index_mid,index_barycenter,index_mid2));
00704             }
00705         }
00706 
00707         return mesh2;
00708     }
00709 
00710     MC_mesh_index_vector MC_mesh_index_vector::build_sphere(const int& N_subdiv)
00711     {
00712         MC_mesh_index_vector new_sphere;
00713         new_sphere = MC_mesh_index_vector::build_icosahedron();
00714 
00715         int k=0;
00716         int N_vertices_1=0,N_vertices_2=0;
00717 
00718         //for every subdivision project on the unit sphere
00719         for(int k_subdiv=0;k_subdiv<N_subdiv;k_subdiv++)
00720         {
00721             N_vertices_1 = new_sphere.vertex_number();
00722             new_sphere=new_sphere.subdivide_mid_edge();
00723             N_vertices_2=new_sphere.vertex_number();
00724             for(k=N_vertices_1;k<N_vertices_2;k++)
00725                 new_sphere.point_set()[k]=new_sphere.point_set()[k].normalized();
00726         }
00727         new_sphere.connectivity().update_neighbors();
00728         return new_sphere;
00729     }
00730 
00731     MC_mesh_index_vector MC_mesh_index_vector::build_quad_sphere(const int& N_subdiv)
00732     {
00733         MC_mesh_index_vector new_sphere;
00734         new_sphere = (MC_mesh_index_vector::build_cube()-0.5*MC_v3d(1,1,1))*2/sqrt(3);
00735 
00736         int k=0;
00737         int N_vertices_1=0,N_vertices_2=0;
00738 
00739         //for every subdivision project on the unit sphere
00740         for(int k_subdiv=0;k_subdiv<N_subdiv;k_subdiv++)
00741         {
00742             N_vertices_1 = new_sphere.vertex_number();
00743             new_sphere=new_sphere.subdivide_barycenter_mid_edge();
00744             N_vertices_2=new_sphere.vertex_number();
00745             for(k=N_vertices_1;k<N_vertices_2;k++)
00746                 new_sphere.point_set()[k]=new_sphere.point_set()[k].normalized();
00747         }
00748         return new_sphere;
00749 
00750     }
00751 
00752     MC_mesh_index_vector MC_mesh_index_vector::build_parametric_sphere(const int& N_1,const int& N_2)
00753     {
00754         MC_mesh_index_vector new_sphere;
00755 #define PI 3.14159
00756 
00757         int k1=0,k2=0;
00758         double u1=0.0,u2=0.0;
00759         for(k1=0;k1<N_1;k1++)
00760         {
00761             u1=double(k1+1)/double(N_1+1);
00762             for(k2=0;k2<N_2;k2++)
00763             {
00764                 u2=double(k2)/double(N_2);
00765 
00766                 new_sphere.add_vertex(MC_v3d(sin(PI*u1)*cos(2*PI*u2),sin(PI*u1)*sin(2*PI*u2),cos(PI*u1)));
00767                 if(k1<N_1-1)
00768                     new_sphere.connectivity().add(MC_int_vector(k2         +N_2*k1 ,
00769                                                                 (k2+1)%N_2 +N_2*k1 ,
00770                                                                 (k2+1)%N_2 +N_2*( (k1+1)%N_1 ),
00771                                                                 k2         +N_2*( (k1+1)%N_1 )));
00772             }
00773         }
00774 
00775         //starting and ending point
00776         new_sphere.point_set().add(MC_v3d(0,0,1));
00777         new_sphere.point_set().add(MC_v3d(0,0,-1));
00778 
00779 
00780         //do triangle for the two extremities
00781         for(k2=0;k2<N_2;k2++)
00782         {
00783             new_sphere.connectivity().add(MC_int_vector(
00784                     N_1*N_2,
00785                     k2,
00786                     (k2+1)%N_2
00787                     ));
00788             new_sphere.connectivity().add(MC_int_vector(
00789                     N_1*N_2+1,
00790                     k2+N_2*(N_1-1),
00791                     (k2+1)%N_2+N_2*(N_1-1)
00792                     ));
00793         }
00794 
00795         return new_sphere;
00796     }
00797 
00798     MC_mesh_index_vector MC_mesh_index_vector::build_torus(const double& R0,const double& R1,const int& N_1,const int& N_2)
00799     {
00800 
00801         MC_mesh_index_vector new_torus;
00802 #define PI 3.14159
00803 
00804         int k1=0,k2=0;
00805         double u1=0.0,u2=0.0;
00806         for(k1=0;k1<N_1;k1++)
00807         {
00808             u1=double(k1)/double(N_1);
00809             for(k2=0;k2<N_2;k2++)
00810             {
00811                 u2=double(k2)/double(N_2);
00812 
00813                 new_torus.point_set().add(MC_v3d(
00814                         (R0+R1*cos(u1*2*PI))*cos(u2*2*PI),
00815                         (R0+R1*cos(u1*2*PI))*sin(u2*2*PI),
00816                         R1*sin(u1*2*PI)
00817                         ));
00818 
00819                 new_torus.connectivity().add(MC_int_vector(
00820                         k2         +N_2*k1 ,
00821                         (k2+1)%N_2 +N_2*k1 ,
00822                         (k2+1)%N_2 +N_2*( (k1+1)%N_1 ),
00823                         k2         +N_2*( (k1+1)%N_1 )));
00824             }
00825         }
00826 
00827         return new_torus;
00828 
00829     }
00830 
00831 
00832 
00833     MC_mesh_index_vector MC_mesh_index_vector::build_closed_cylinder(const int& N1,const int& N2,const bool& is_closed)
00834     {
00835           MC_mesh_index_vector cylinder;
00836 
00837 
00838           double u1=0.0,u2=0.0;
00839           int k1=0,k2=0;
00840           for(k1=0;k1<N1;k1++)
00841           {
00842               u1 = double(k1)/double(N1-1);
00843               for(k2=0;k2<N2;k2++)
00844               {
00845                   u2 = double(k2)/double(N2);
00846                   cylinder.point_set().add(MC_v3d(u1,cos(2*PI*u2),sin(2*PI*u2)));
00847               }
00848           }
00849 
00850           for(k1=0;k1<N1-1;k1++)
00851               for(k2=0;k2<N2;k2++)
00852                   cylinder.connectivity().add(MC_int_vector( k2+0     + N2*k1+0,
00853                                                                (k2+1)%N2 + N2*k1+0,
00854                                                                (k2+1)%N2 + N2*(k1+1),
00855                                                                k2+0     + N2*(k1+1)));
00856 
00857 
00858           if(is_closed==true)
00859           {
00860               // to close the cylinder
00861               cylinder.add_vertex(MC_v3d(0,0,0));
00862               cylinder.add_vertex(MC_v3d(1,0,0));
00863 
00864               MC_int_vector closing;
00865               for(k2=0;k2<N2;++k2)
00866                   cylinder.add_connectivity_index(MC_int_vector(k2,N2*N1,(k2+1)%N2));
00867               for(k2=0;k2<N2;++k2)
00868                   cylinder.add_connectivity_index(MC_int_vector(N2*N1+1,N2*(N1-1)+k2,N2*(N1-1)+(k2+1)%N2));
00869           }
00870 
00871           return cylinder;
00872 
00873     }
00874 
00875     MC_mesh_index_vector MC_mesh_index_vector::build_cone(const int& N_radius,const int& N_face)
00876     {
00877 
00878 #define PI 3.14159
00879 
00880         //special cone
00881         if(N_radius==4 && N_face==2)
00882         {
00883             MC_mesh_index_vector cone;
00884             cone.point_set()=MC_v3d_vector(MC_v3d(1,1,0))<<MC_v3d(1,-1,0)<<MC_v3d(-1,-1,0)<<MC_v3d(-1,1,0)<<MC_v3d(0,0,1);
00885             cone.connectivity().add(MC_int_vector(0,3,2,1));
00886             cone.connectivity().add(MC_int_vector(0,1,4));
00887             cone.connectivity().add(MC_int_vector(1,2,4));
00888             cone.connectivity().add(MC_int_vector(2,3,4));
00889             cone.connectivity().add(MC_int_vector(3,0,4));
00890 
00891             return cone;
00892         }
00893 
00894         MC_mesh_index_vector cone;
00895 
00896         // add the two extreme points
00897         cone.add_vertex(MC_v3d(0,0,0));
00898         cone.add_vertex(MC_v3d(0,0,1));
00899 
00900         // vertices
00901         double r=1.0/(N_face-1);
00902         for(int k=0;k<N_radius;k++)
00903         {
00904             double alpha = 2*PI*double(k)/double(N_radius);
00905             MC_v3d x=MC_v3d(r*cos(alpha),r*sin(alpha),0.0);
00906             cone.add_vertex(x);
00907         }
00908         //base of cone
00909         for(int k2=1;k2<N_face;k2++)
00910         {
00911             double r=double(k2)/double(N_face-1);
00912             for(int k=0;k<N_radius;k++)
00913             {
00914                 double alpha = 2*PI*double(k)/double(N_radius);
00915                 MC_v3d x = MC_v3d(r*cos(alpha),r*sin(alpha),0.0);
00916                 cone.add_vertex(x);
00917             }
00918         }
00919         //triangle cone
00920         for(int k2=1;k2<N_face-1;k2++)
00921         {
00922             double r=double(N_face-1-k2)/double(N_face-1);
00923             double h=double(k2)/double(N_face-1);
00924             for(int k=0;k<N_radius;k++)
00925             {
00926                 double alpha = 2*PI*double(k)/double(N_radius);
00927                 MC_v3d x=MC_v3d(r*cos(alpha),r*sin(alpha),h);
00928                 cone.add_vertex(x);
00929             }
00930         }
00931 
00932 
00933         // connectivity
00934         for(int k=0;k<N_radius;k++)
00935             cone.add_connectivity_index(MC_int_vector(0,(k+1)%N_radius+2,k+2));
00936         for(int k2=1;k2<N_face-1;k2++)
00937         {
00938             for(int k=0;k<N_radius;k++)
00939             {
00940                 cone.add_connectivity_index(MC_int_vector((k+0)  +(k2+0)*N_radius+2,
00941                                                (k+1)%N_radius+(k2+0)*N_radius+2,
00942                                                (k+1)%N_radius+(k2+1)*N_radius+2,
00943                                                (k+0)  +(k2+1)*N_radius+2));
00944             }
00945         }
00946 
00948         for(int k2=0;k2<N_face-2;k2++)
00949             for(int k=0;k<N_radius;k++)
00950             {
00951             cone.add_connectivity_index(MC_int_vector((k+0)  +(k2+0)*N_radius+N_radius*(N_face-1)+2,
00952                                            (k+1)%N_radius+(k2+0)*N_radius+N_radius*(N_face-1)+2,
00953                                            (k+1)%N_radius+(k2+1)*N_radius+N_radius*(N_face-1)+2,
00954                                            (k+0)  +(k2+1)*N_radius+N_radius*(N_face-1)+2));
00955         }
00956 
00958         for(int k=0;k<N_radius;k++)
00959         {
00960             cone.add_connectivity_index(MC_int_vector( k+N_radius*(N_face-2)+N_radius*(N_face-1)+2,
00961                                             (k+1)%N_radius+N_radius*(N_face-2)+N_radius*(N_face-1)+2,
00962                                             1));
00963         }
00964 
00965 
00966 
00967         return cone;
00968     }
00969 
00970     MC_mesh_index_vector MC_mesh_index_vector::build_disc(const MC_v3d& center,const MC_v3d& normal,const double& radius,const int& N_radius,const int& N_interior)
00971     {
00972         double epsilon=0.0001;
00973         if(normal.norm()<epsilon)
00974         {std::cout<<"Error in MC_mesh_index_vector::build_disc(...), normal is null"<<std::endl;exit(-1);}
00975 
00976         MC_v3d axis_1 = normal.cross(MC_v3d(1,0,0));
00977         if(axis_1.norm()<epsilon)
00978         {
00979             axis_1 = normal.cross(MC_v3d(0,1,0));
00980             if(axis_1.norm()<epsilon)
00981             {std::cout<<"Error in MC_mesh_index_vector::build_disc, something weird"<<std::endl; exit(-1);}
00982         }
00983 
00984         axis_1 = axis_1.normalized();
00985         MC_v3d axis_2 = (axis_1.cross(normal)).normalized();
00986 
00987         MC_mesh_index_vector disc;
00988 
00989         // vertices
00990         disc.add_vertex(center);
00991         for(int k_radius=0;k_radius<N_radius;k_radius++)
00992         {
00993             double theta = 2*PI*double(k_radius)/double(N_radius);
00994             for(int k_interior=1;k_interior<N_interior;k_interior++)
00995             {
00996                 double r=radius*double(k_interior)/double(N_interior-1);
00997 
00998                 MC_v3d current=r*cos(theta)*axis_1 + r*sin(theta)*axis_2;
00999                 disc.add_vertex(center+current);
01000             }
01001         }
01002 
01003 
01004         // connectivity
01005         for(int k_radius=0;k_radius<N_radius;k_radius++)
01006         {
01007             for(int k_interior=0;k_interior<N_interior-1;k_interior++)
01008             {
01009                 if(k_interior==0)
01010                     disc.add_connectivity_index(MC_int_vector( 0,k_radius*(N_interior-1)+1,((k_radius+1)%N_radius)*(N_interior-1)+1 ));
01011                 else
01012                     disc.add_connectivity_index(MC_int_vector((k_interior-1+0)+(k_radius+0)*(N_interior-1)+1,
01013                                                               (k_interior-1+1)+(k_radius+0)*(N_interior-1)+1,
01014                                                               (k_interior-1+1)+((k_radius+1)%N_radius)*(N_interior-1)+1,
01015                                                               (k_interior-1+0)+((k_radius+1)%N_radius)*(N_interior-1)+1 ));
01016             }
01017         }
01018 
01019 
01020         return disc;
01021     }
01022 
01023     MC_mesh_index_vector MC_mesh_index_vector::build_arrow(const MC_segment& dir,const double& radius_cylinder,const int& N_cylinder,const int& N_shape_cylinder,const double& radius_cone,const double& length_cone,const int& N_cone,const int& N_shape_cone)
01024     {
01025 
01026         // protection against singularity
01027         double epsilon=0.0001;
01028 
01029         MC_mesh_index_vector arrow;
01030         MC_v3d V_intermediate = dir.unit_vector()*(dir.length()-length_cone);
01031 
01032         MC_mesh_index_vector cylinder = MC_mesh_index_vector::build_closed_cylinder(N_shape_cylinder,N_cylinder);
01033         cylinder.point_set().scale(MC_v3d(V_intermediate.norm(),radius_cylinder,radius_cylinder));
01034 
01035         MC_matrix R=MC_matrix::identity(3);
01036         if(dir.unit_vector().cross(MC_v3d(1,0,0)).norm()>epsilon)
01037             R=MC_matrix::rotation_axis_to_axis(MC_v3d(1,0,0),dir.unit_vector());
01038         cylinder = R*cylinder;
01039 
01040         MC_mesh_index_vector cone = MC_mesh_index_vector::build_cone(N_cone,N_shape_cone);
01041         cone.point_set().scale(MC_v3d(radius_cone,radius_cone,length_cone));
01042 
01043         R=MC_matrix::identity(3);
01044         if(dir.unit_vector().cross(MC_v3d(0,0,1)).norm()>epsilon)
01045             R=MC_matrix::rotation_axis_to_axis(MC_v3d(0,0,1),dir.unit_vector()+MC_v3d(epsilon,0,0));
01046         cone=R*cone+V_intermediate;
01047 
01048 
01049         arrow = cone<<cylinder;
01050         arrow+=dir[0];
01051 
01052         return arrow;
01053 
01054 
01055     }
01056 
01057     MC_mesh_index_vector operator<<(const MC_mesh_index_vector& vec0,const MC_mesh_index_vector& vec1)
01058     {
01059         MC_mesh_index_vector new_vec;
01060 
01061         new_vec.point_set()=vec0.point_set()<<vec1.point_set();
01062         new_vec.connectivity()=vec0.connectivity()<<(vec1.connectivity()+vec0.vertex_number());
01063 
01064         return new_vec;
01065     }
01066 
01067 
01068     MC_mesh_index_vector& MC_mesh_index_vector::concatenation(const MC_mesh_index_vector& vec1)
01069     {
01070         int N_vertex=point_set().size();
01071         point_set().add(vec1.point_set());
01072         connectivity().add(vec1.connectivity()+N_vertex);
01073         return *this;
01074     }
01075 
01076     std::pair <std::vector <MC_curve>,MC_int_vector_vector> MC_mesh_index_vector::boundary_curve() const
01077     {
01078         // get the boundary index
01079         MC_int_vector_vector full_index(MC_int_vector::connected_component(connectivity_mesh.boundary()));
01080 
01081         // fill the curves
01082         int N=full_index.size();
01083         std::vector <MC_curve> full_curve(N);
01084         for(int k=0;k<N;++k)
01085             full_curve[k]=point_set_mesh(full_index(k));
01086 
01087         return std::pair <std::vector <MC_curve>,MC_int_vector_vector> (full_curve,full_index);
01088 
01089     }
01090 
01091 
01092     std::vector <MC_curve> MC_mesh_index_vector::plane_intersection(const MC_v3d& n,const MC_v3d& x0) const
01093     {
01094         std::vector <MC_curve> curves;
01095         int k_polygon=0,N_polygon=polygon_number();
01096 
01097         std::vector <MC_segment> s;int type=-1;
01098         MC_v3d_vector temp;
01099         //check every intersection for every polygons
01100         //store the intersection in an unordered vector of Segment
01101         for(k_polygon=0;k_polygon<N_polygon;k_polygon++)
01102         {
01103             //check the intersection
01104             temp = get_polygon(k_polygon).plane_intersection(n,x0,&type);
01105 
01106             if(type==1 || type==3)
01107             {
01108                // std::cout<<k_polygon<<" ! "<<temp<<std::endl;
01109                 s.push_back(MC_segment(temp[0],temp[1]));
01110             }
01111         }
01112 
01113 
01114         //avoid the identical segments
01115         std::vector<MC_segment> s2=s;
01116         s.clear();
01117         for(int k=0,N=s2.size();k<N;++k)
01118         {
01119             bool is_unique=true;
01120             for(int k2=0;is_unique==true && k2<s.size();++k2)
01121             {
01122                 if( (s2[k][0]==s[k2][0] && s2[k][1]==s[k2][1])
01123                     ||
01124                     (s2[k][1]==s[k2][0] && s2[k][0]==s[k2][1])
01125                     )
01126                     is_unique=false;
01127             }
01128             if(is_unique==true)
01129                 s.push_back(s2[k]);
01130         }
01131 
01132 
01133 
01134 
01135         int segment_number=s.size();
01136         if(segment_number==0)
01137             return curves;
01138 
01139 
01140         // now order the segments in curve
01141         MC_int_vector is_segment_added;
01142         is_segment_added.resize(segment_number);
01143 
01144         std::list <MC_v3d> current_curve;
01145         //MC_curve current_curve;
01146         current_curve.push_back(s[0][0]);
01147         current_curve.push_back(s[0][1]);
01148         is_segment_added[0]=1;
01149 
01150 //        std::cout<<segment_number<<std::endl;
01151 //        for(int k=0;k<segment_number;++k)
01152 //            std::cout<<s[k]<<std::endl;
01153 
01154         int k_segment=-1,is_addition=1;
01155         while(is_addition==1)//as long as there is segment to add
01156         {
01157             //check if there is at least one added segment during the whole pass
01158             is_addition=0;
01159 
01160             //add forward
01161             for(k_segment=0;k_segment<segment_number;k_segment++){
01162                 if(is_segment_added[k_segment]==0)
01163                 {
01164                     if(s[k_segment][0]==current_curve.back())
01165                     {current_curve.push_back(s[k_segment][1]);is_segment_added[k_segment]=1;is_addition=1;}
01166                     else if(s[k_segment][1]==current_curve.back())
01167                     {current_curve.push_back(s[k_segment][0]);is_segment_added[k_segment]=1;is_addition=1;}
01168                 }
01169             }
01170             //add back
01171             for(k_segment=0;k_segment<segment_number;k_segment++){
01172                 if(is_segment_added[k_segment]==0)
01173                 {
01174                     if(s[k_segment][0]==current_curve.front())
01175                     {current_curve.push_front(s[k_segment][1]);is_segment_added[k_segment]=1;is_addition=1;}
01176                     else if(s[k_segment][1]==current_curve.front())
01177                     {current_curve.push_front(s[k_segment][0]);is_segment_added[k_segment]=1;is_addition=1;}
01178                 }
01179             }
01180 
01181                 //if there is no added segment, it might be non-connected cases
01182                 if(is_addition==0)
01183                 {
01184                     // add this curve to the vector
01185                     curves.push_back(current_curve);
01186                     current_curve.clear();
01187 
01188                     //check if every segment has been added
01189                     for(k_segment=0;is_addition==0 && k_segment<segment_number;k_segment++){
01190                         if(is_segment_added[k_segment]==0)//Then add it in the next curve
01191                         {
01192                             is_addition=1;
01193                             current_curve.push_back(s[k_segment][0]);current_curve.push_back(s[k_segment][1]);
01194                             is_segment_added[k_segment]=1;
01195                         }
01196                     }
01197                 }
01198 
01199 
01200         }
01201         return curves;
01202     }
01203 
01204     MC_mesh_index_vector MC_mesh_index_vector::half_space_intersection(const MC_v3d& n,const MC_v3d& x0,int *type) const
01205     {
01206 
01207         int k_polygon=0;
01208         int N_polygon=polygon_number();
01209 
01210         std::vector <MC_polygon> polygon_soup;
01211 
01212         if(type!=0)
01213             *type = 0;
01214         MC_polygon p; int t=0;
01215         MC_polygon q;
01216 
01217         //cut every polygon
01218         for(k_polygon=0;k_polygon<N_polygon;++k_polygon)
01219         {
01220             p = get_polygon(k_polygon);
01221             q = p.half_space_intersection(n,x0,&t);
01222 
01223             if(t!=2)//add the polygon and build the connectivity
01224                 polygon_soup.push_back(q);
01225             if(t!=0)//at least one polygon is cutted
01226                 if(type!=0)
01227                     *type=1;
01228 
01229 
01230         }
01231 
01232         MC_mesh_index_vector new_mesh=polygon_soup;
01233 
01234         if(new_mesh.vertex_number()==0)//no more mesh at all
01235             if(type!=0)
01236                 *type=2;
01237 
01238 
01239         return new_mesh;
01240     }
01241 
01242     std::pair<MC_mesh_index_vector,std::pair<MC_int_vector_vector,MC_int_vector_vector> > MC_mesh_index_vector::added_polygon_soup(const std::vector<MC_polygon> poly_soup) const
01243     {
01244         MC_mesh_index_vector current_mesh=*this;
01245         std::map <MC_v3d,int,MC_v3d_less> v_3d_map = point_set().to_map();
01246 
01247         std::pair <MC_int_vector_vector,MC_int_vector_vector> res;
01248         std::pair <MC_int_vector,MC_int_vector> temp;
01249 
01250         int N_poly=poly_soup.size();
01251         for(int k=0;k<N_poly;k++)
01252         {
01253             bool is_added=true;
01254             MC_polygon p=poly_soup[k];
01255             if(p.is_degenerated()==true)
01256             {
01257                 std::pair <MC_polygon,std::pair<bool,bool> > up=p.undegenerated();
01258                 if(up.second.second==false)
01259                     is_added=false;
01260                 else
01261                     p=up.first;
01262             }
01263             if(is_added==true)
01264             {
01265                 temp=current_mesh.add_unique_polygon(p,&v_3d_map);
01266                 res.first.add(temp.first); res.second.add(temp.second);
01267             }
01268         }
01269 
01270         return std::pair<MC_mesh_index_vector,std::pair<MC_int_vector_vector,MC_int_vector_vector> > (current_mesh,res);
01271     }
01272 
01273     std::pair <MC_int_vector,MC_int_vector> MC_mesh_index_vector::add_unique_polygon(const MC_polygon& polygon,std::map <MC_v3d,int,MC_v3d_less>* map_vertices)
01274     {
01275         MC_int_vector index_polygon;
01276         MC_int_vector is_new;
01277 
01278 
01279         std::map <MC_v3d,int,MC_v3d_less> :: iterator it;
01280 
01281         int N_polygon=polygon.size();
01282         for(int k=0;k<N_polygon;++k)
01283         {
01284             std::pair<std::map <MC_v3d,int,MC_v3d_less>::iterator ,bool> it=map_vertices->insert(std::pair<MC_v3d,int>(polygon[k],vertex_number()));
01285 
01286             if(it.second==true)
01287             {
01288                 point_set().add(polygon[k]);
01289                 index_polygon.add(vertex_number()-1);
01290                 is_new.add(1);
01291             }
01292             else //already exists
01293             {
01294                 index_polygon.add(it.first->second);
01295                 is_new.add(0);
01296             }
01297         }
01298 
01299         connectivity().add(index_polygon);
01300         return std::pair < MC_int_vector , MC_int_vector > (index_polygon,is_new);
01301     }
01302 
01303     MC_mesh_index_vector::MC_mesh_index_vector(const std::vector<MC_polygon> poly_soup)
01304     {
01305         *this=this->added_polygon_soup(poly_soup).first;
01306     }
01307 
01308     std::pair <MC_v3d_vector,std::pair <MC_int_vector,MC_double_vector> > MC_mesh_index_vector::segment_intersection(const MC_segment& s) const
01309     {
01310         MC_int_vector intersected_polygon;
01311         MC_double_vector segment_coord;
01312         MC_v3d_vector inter;
01313         int N=polygon_number();
01314         MC_polygon p;
01315         int type=0;
01316         for(int k=0;k<N;k++)
01317         {
01318             p=get_polygon(k);
01319             MC_v3d i = p.segment_intersection(s,&type);
01320 
01321             if(type==1 || type==2 || type==3)
01322             {
01323                 inter.add(i);
01324                 intersected_polygon.add(k);
01325 
01326                 bool is_alignated=false;
01327                 segment_coord.add(s.relative_position(i,&is_alignated));
01328                 if(is_alignated==false)
01329                 {std::cout<<"Something wrong in MC_mesh_index_vector::segment_intersection()"<<std::endl;exit(-1);}
01330             }
01331         }
01332 
01333         // ordonate the intersection from begining to end of the curve
01334         std::map <double,int> map_order=segment_coord.to_map();
01335         std::map <double,int>::const_iterator it=map_order.begin(),it_end=map_order.end();
01336 
01337         std::pair <MC_v3d_vector,std::pair <MC_int_vector,MC_double_vector> > res;
01338         for(;it!=it_end;++it)
01339         {
01340             int index=it->second;
01341             res.first.add(inter[index]);
01342             res.second.first.add(intersected_polygon[index]);
01343             res.second.second.add(segment_coord[index]);
01344         }
01345 
01346         return res;
01347     }
01348 
01349     std::pair <MC_int_vector,std::pair <MC_v3d_vector,std::pair <MC_int_vector,MC_double_vector> > >
01350             MC_mesh_index_vector::segment_intersection(const std::vector <MC_mesh_index_vector>& v_mesh,const MC_segment& s)
01351     {
01352         std::vector <std::pair <MC_v3d_vector,std::pair <MC_int_vector,MC_double_vector> > > v_inter;
01353         int N=v_mesh.size();
01354 
01355         //keep all the data intersection from the data
01356         for(int k=0;k<N;++k)
01357             v_inter.push_back(v_mesh[k].segment_intersection(s));
01358 
01359         // merge everything now
01360         MC_int_vector temp_index;
01361         MC_v3d_vector temp_inter;
01362         MC_int_vector temp_poly;
01363         MC_double_vector temp_relative;
01364         for(int k=0;k<N;++k)
01365         {
01366             if(v_inter[k].first.size()>0)
01367             {
01368                 temp_index.add(MC_int_vector::zeros(v_inter[k].first.size())+k);
01369                 temp_inter.add(v_inter[k].first);
01370                 temp_poly.add(v_inter[k].second.first);
01371                 temp_relative.add(v_inter[k].second.second);
01372             }
01373         }
01374 
01375 
01376         // ordonate it
01377         std::pair <MC_double_vector,MC_int_vector> ind=temp_relative.sort();
01378 
01379         std::pair <MC_int_vector,std::pair <MC_v3d_vector,std::pair <MC_int_vector,MC_double_vector> > > res;
01380         res.first=temp_index(ind.second);
01381         res.second.first=temp_inter(ind.second);
01382         res.second.second.first=temp_poly(ind.second);
01383         res.second.second.second=ind.first;
01384 
01385         return res;
01386     }
01387     MC_mesh_index_vector MC_mesh_index_vector::sweep_surface(const MC_curve& _c,const MC_curve& _pattern,const int& N_subdiv,const bool& is_closed,const MC_v3d_vector& e1)
01388     {
01389 
01390         MC_curve c=_c.value_t(MC_double_vector::linspace(0,_c.size()-1, 1.0/static_cast<double>(N_subdiv-1)) ).first;
01391 
01392         bool is_given_tangent=(c.size()==e1.size());
01393 
01394         MC_curve pattern=_pattern;
01395         if(pattern.size()==0)
01396             pattern=MC_curve::build_circle(0.1,8,MC_v3d(0,0,1));
01397 
01398         int N_curve=c.size();
01399         int k_curve=0;
01400 
01401         MC_mesh_index_vector sweep;
01402         int N_pattern=pattern.size();
01403 
01404 
01405         MC_v3d_vector normal=c.diff_forward();
01406 
01407 
01408         // first rotation to the normal to the curve
01409         MC_matrix R0    =MC_matrix::identity(3);
01410         MC_matrix R0_old=MC_matrix::identity(3);
01411         //second rotation to avoid the twist
01412         MC_matrix R1    =MC_matrix::identity(3);
01413         MC_matrix R1_old=MC_matrix::identity(3);
01414 
01415         //the pattern during transformation
01416         MC_curve temp_pattern;
01417         int k_pattern=0;
01418 
01419 
01420 
01421         MC_v3d ez(0,0,1),ex(1,0,0),ey(0,1,0);
01422         MC_v3d e0x,e1x,e1y,e0p;
01423         for(k_curve=0;k_curve<N_curve;++k_curve)
01424         {
01425             //******************************//
01426             // Rotation
01427             //******************************//
01428 
01429 
01430             //first rotate to be aligned with the normal
01431             R0_old=R0;
01432             R0=MC_matrix::rotation_axis_to_axis(ez,normal[k_curve]);
01433             temp_pattern = R0*pattern;
01434 
01435 
01436             //second, avoid the twist
01437             if(is_given_tangent==false)
01438             {
01439                 if(k_curve>=1)
01440                 {
01441 
01442                     e0x = R1_old*R0_old*ex;
01443 
01444                     e1x = R0*ex;
01445                     e1y = R0*ey;
01446 
01447                     e0p = (e0x.dot(e1x))*e1x+(e0x.dot(e1y))*e1y;
01448 
01449 
01450 
01451                     // how to rotate the new projection ex to the old one
01452                     R1=MC_matrix::rotation_axis_to_axis(e1x,e0p);
01453                     temp_pattern = R1*temp_pattern;
01454 
01455                 }
01456             }
01457             else
01458             {
01459                 e1x = R0*ex;
01460                 R1=MC_matrix::rotation_axis_to_axis(e1x,e1[k_curve]);
01461                 temp_pattern = R1*temp_pattern;
01462             }
01463 
01464 
01465             //translate to the position of the curve
01466             temp_pattern=temp_pattern+c[k_curve];
01467 
01468 
01469             //save the old transformation
01470             R0_old=R0;R1_old=R1;
01471 
01472 
01473 
01474 
01475             //******************************//
01476             // set up the Mesh
01477             //******************************//
01478 
01479 
01481             sweep.point_set().add(temp_pattern);
01482 
01484             if(k_curve<N_curve-1)
01485             {
01486                 for(k_pattern=0;k_pattern<N_pattern-1;k_pattern++)
01487                 {
01488                     sweep.connectivity().add(MC_int_vector(k_pattern+N_pattern*(k_curve),
01489                                                            k_pattern+N_pattern*(k_curve+1),
01490                                                            k_pattern+1+N_pattern*(k_curve+1),
01491                                                            k_pattern+1+N_pattern*(k_curve)
01492                                                            ));
01493                 }
01494                 //close the pattern
01495                 sweep.connectivity().add(MC_int_vector(k_pattern+N_pattern*(k_curve),
01496                                                        k_pattern+N_pattern*(k_curve+1),
01497                                                        0+N_pattern*(k_curve+1),
01498                                                        0+N_pattern*(k_curve)
01499                                                        ));
01500             }
01501 
01502 
01503 
01504         }
01505 
01506 
01507 
01508 
01509 
01510 
01511 
01512         if(is_closed==true)
01513         {
01514 
01515               int k_subdiv=0;
01516               double s=0.0;
01517               int offset=0;
01518 
01519               R0    =MC_matrix::identity(3);
01520               R0_old=MC_matrix::identity(3);
01521               R1    =MC_matrix::identity(3);
01522               R1_old=MC_matrix::identity(3);
01523 
01524 
01525               MC_v3d barycenter;
01526               for(k_curve=0;k_curve<N_curve;k_curve++)
01527               {
01528 
01529                   //first rotate to be aligned with the normal
01530                   R0_old=R0;
01531                   R0=MC_matrix::rotation_axis_to_axis(ez,normal[k_curve]);
01532                   temp_pattern = R0*pattern;
01533 
01534                   //second, avoid the twist
01535                   if(is_given_tangent==false)
01536                   {
01537                       if(k_curve>=1)
01538                       {
01539                           e0x = R1_old*R0_old*ex;
01540 
01541                           e1x = R0*ex;
01542                           e1y = R0*ey;
01543 
01544                           e0p = (e0x.dot(e1x))*e1x+(e0x.dot(e1y))*e1y;
01545 
01546                           // how to rotate the new projection ex to the old one
01547                           R1=MC_matrix::rotation_axis_to_axis(e1x,e0p);
01548                           temp_pattern = R1*temp_pattern;
01549                       }
01550                   }
01551                   else
01552                   {
01553                       e1x = R0*ex;
01554                       R1=MC_matrix::rotation_axis_to_axis(e1x,e1[k_curve]);
01555                       temp_pattern = R1*temp_pattern;
01556                   }
01557 
01558                   //save the old transformation
01559                   R0_old=R0;R1_old=R1;
01560 
01561 
01562 
01563                   //******************************//
01564                   // set up the Mesh
01565                   //******************************//
01566 
01567 
01569                   if(k_curve==0 || k_curve==N_curve-1)
01570                   {
01571                       if(k_curve==0)
01572                           offset=N_curve*N_pattern;
01573                       if(k_curve==N_curve-1)
01574                           offset=N_curve*N_pattern+(N_subdiv-1)*N_pattern+1;//+1 due to the barycenter
01575                       for(k_subdiv=0;k_subdiv<N_subdiv-1;k_subdiv++)
01576                       {
01577                           s = double(k_subdiv+1)/double(N_subdiv+1);
01578                           sweep.point_set().add((1-s)*temp_pattern+c[k_curve]);
01579 
01580                           // add the quadrilateral faces
01581                           if(k_subdiv<N_subdiv-2)
01582                               for(k_pattern=0;k_pattern<N_pattern;k_pattern++)
01583                               {
01584                               if(k_curve==0)
01585                                   sweep.connectivity().add(MC_int_vector(offset + k_pattern  +N_pattern*(k_subdiv  ),
01586                                                                          offset + (k_pattern+1)%N_pattern+N_pattern*(k_subdiv  ),
01587                                                                          offset + (k_pattern+1)%N_pattern+N_pattern*(k_subdiv+1),
01588                                                                          offset + k_pattern  +N_pattern*(k_subdiv+1)
01589                                                                          ));
01590                               else//to be manifold
01591                                   sweep.connectivity().add(MC_int_vector(offset + k_pattern  +N_pattern*(k_subdiv  ),
01592                                                                          offset + k_pattern  +N_pattern*(k_subdiv+1),
01593                                                                          offset + (k_pattern+1)%N_pattern+N_pattern*(k_subdiv+1),
01594                                                                          offset + (k_pattern+1)%N_pattern+N_pattern*(k_subdiv  )
01595                                                                          ));
01596                           }
01597                       }
01598                       //close with the boundaries
01599                       for(k_pattern=0;k_pattern<N_pattern;k_pattern++)
01600                       {
01601                           if(k_curve==0)
01602                               sweep.connectivity().add(MC_int_vector(k_pattern                        +N_pattern*k_curve,
01603                                                                      (k_pattern+1)%N_pattern          +N_pattern*k_curve,
01604                                                                      offset + (k_pattern+1)%N_pattern                   ,
01605                                                                      offset + k_pattern
01606                                                                      ));
01607                           else//to be manifold
01608                               sweep.connectivity().add(MC_int_vector(k_pattern                        +N_pattern*k_curve,
01609                                                                      offset + k_pattern                                 ,
01610                                                                      offset + (k_pattern+1)%N_pattern                   ,
01611                                                                      (k_pattern+1)%N_pattern          +N_pattern*k_curve
01612                                                                      ));
01613                       }
01614 
01615                       //Now close with the midpoint
01616                       barycenter = (temp_pattern+c[k_curve]).barycenter();
01617 
01618                       // add the barycenter
01619                       sweep.add_vertex(barycenter);
01620 
01621                       //now close the surface
01622                       for(k_pattern=0;k_pattern<N_pattern;k_pattern++)
01623                       {
01624                           if(k_curve==0)
01625                               sweep.connectivity().add(MC_int_vector(offset + k_pattern + N_pattern*(N_subdiv-2),
01626                                                                      offset + (k_pattern+1)%N_pattern + N_pattern*(N_subdiv-2),
01627                                                                      offset + N_pattern*(N_subdiv-1)
01628                                                                      ));
01629                           else//to be a manifold mesh
01630                               sweep.connectivity().add(MC_int_vector(offset + k_pattern + N_pattern*(N_subdiv-2),
01631                                                                      offset + N_pattern*(N_subdiv-1),
01632                                                                      offset + (k_pattern+1)%N_pattern + N_pattern*(N_subdiv-2)
01633                                                                      ));
01634                       }
01635                   }
01636               }
01637 
01638           }
01639 
01640 
01641 
01642         return sweep;
01643     }
01644     double MC_mesh_index_vector::volume() const
01645     {
01646         double vol=0.0;
01647         int N_polygon=polygon_number();
01648         for(int k_polygon=0;k_polygon<N_polygon;++k_polygon)
01649         {
01650             MC_int_vector index_polygon=connectivity()(k_polygon);
01651             int N_vertex=index_polygon.size();
01652             int N_tri=N_vertex-2;
01653             for(int k_tri=0;k_tri<N_tri;++k_tri)
01654             {
01655                 MC_v3d x0=point_set()(index_polygon[0]);
01656                 MC_v3d x1=point_set()(index_polygon[k_tri+1]);
01657                 MC_v3d x2=point_set()(index_polygon[k_tri+2]);
01658 
01659                 vol+= (x0[2]+x1[2]+x2[2])*
01660                       ((x1[0]-x0[0])*(x2[1]-x0[1])-(x1[1]-x0[1])*(x2[0]-x0[0]));
01661             }
01662         }
01663         vol/=6.0;
01664         return vol;
01665     }
01666     MC_v3d_vector MC_mesh_index_vector::volume_gradient() const
01667     {
01668         int N_vertex=vertex_number();
01669         MC_v3d_vector grad(N_vertex);
01670         int N_polygon=polygon_number();
01671 
01672         for(int k_polygon=0;k_polygon<N_polygon;++k_polygon)
01673         {
01674             MC_int_vector index_polygon=connectivity()(k_polygon);
01675             int N_vertex=index_polygon.size();
01676             int N_tri=N_vertex-2;
01677             for(int k_tri=0;k_tri<N_tri;++k_tri)
01678             {
01679                 int index_0=index_polygon[0];
01680                 int index_1=index_polygon[k_tri+1];
01681                 int index_2=index_polygon[k_tri+2];
01682 
01683                 MC_v3d x0=point_set()(index_0);
01684                 MC_v3d x1=point_set()(index_1);
01685                 MC_v3d x2=point_set()(index_2);
01686 
01687                 grad[index_0][0] += 0.5* (x0[2]+x1[2]+x2[2]) * (x1[1]-x2[1]) * 1/3.0;
01688                 grad[index_1][0] += 0.5* (x0[2]+x1[2]+x2[2]) * (x2[1]-x0[1]) * 1/3.0;
01689                 grad[index_2][0] += 0.5* (x0[2]+x1[2]+x2[2]) * (x0[1]-x1[1]) * 1/3.0;
01690 
01691                 grad[index_0][1] += 0.5* (x0[2]+x1[2]+x2[2]) * (x2[0]-x1[0]) * 1/3.0;
01692                 grad[index_1][1] += 0.5* (x0[2]+x1[2]+x2[2]) * (x0[0]-x2[0]) * 1/3.0;
01693                 grad[index_2][1] += 0.5* (x0[2]+x1[2]+x2[2]) * (x1[0]-x0[0]) * 1/3.0;
01694 
01695                 grad[index_0][2] += 0.5*(x1[0]*x2[1]-x1[0]*x0[1]-x0[0]*x2[1]-x1[1]*x2[0]+x1[1]*x0[0]+x0[1]*x2[0]) * 1/3.0;
01696                 grad[index_1][2] += 0.5*(x1[0]*x2[1]-x1[0]*x0[1]-x0[0]*x2[1]-x1[1]*x2[0]+x1[1]*x0[0]+x0[1]*x2[0]) * 1/3.0;
01697                 grad[index_2][2] += 0.5*(x1[0]*x2[1]-x1[0]*x0[1]-x0[0]*x2[1]-x1[1]*x2[0]+x1[1]*x0[0]+x0[1]*x2[0]) * 1/3.0;
01698             }
01699         }
01700 
01701         return grad;
01702     }
01703 
01704 
01705 
01706 
01707     MC_mesh_index_vector MC_mesh_index_vector::build_square(const int& N_1,const int& N_2)
01708     {
01709 
01710         MC_mesh_index_vector mesh;
01711 
01712         for(int k_1=0;k_1<N_1+2;++k_1){
01713             double alpha_1=static_cast<double>(k_1)/static_cast<double>(N_1+1);
01714             for(int k_2=0;k_2<N_2+2;++k_2){
01715                 double alpha_2=static_cast<double>(k_2)/static_cast<double>(N_2+1);
01716                 mesh.point_set().add(MC_v3d(alpha_1,alpha_2,0.0));
01717             }
01718         }
01719 
01720         for(int k_1=0;k_1<N_1+2-1;++k_1){
01721             for(int k_2=0;k_2<N_2+2-1;++k_2){
01722                 mesh.connectivity().add(MC_int_vector((k_1+0)*(N_2+2)+(k_2+0),
01723                                                       (k_1+0)*(N_2+2)+(k_2+1),
01724                                                       (k_1+1)*(N_2+2)+(k_2+1),
01725                                                       (k_1+1)*(N_2+2)+(k_2+0)));
01726             }
01727         }
01728 
01729         return mesh;
01730     }
01731 
01732 
01733 
01734 
01735 
01736 
01737 
01738 
01739 
01740 
01741 
01742 
01743     MC_double_vector_vector MC_mesh_index_vector::barycentric_coordinates(const MC_mesh_index_vector& mesh,const MC_v3d_vector& vertices,const MC_int_vector& belonging_polygon)
01744     {
01745         if(belonging_polygon.size()!=vertices.size())
01746         {std::cout<<"Error in MC_mesh_index_vector::barycentric_coordinates(), size are not compatible"<<std::endl;exit(-1);}
01747 
01748         int N=vertices.size();
01749         int N_poly=mesh.polygon_number();
01750         MC_double_vector_vector bar=MC_double_vector_vector::empty(N);
01751         for(int k=0;k<N;++k)
01752         {
01753             int index_poly=belonging_polygon(k);
01754             if(index_poly<0 || index_poly>N_poly)
01755             {std::cout<<"Error in MC_mesh_index_vector::barycentric_coordinates() at index k="<<k<<"/"<<N<<" not correct with N_polygon="<<N_poly<<std::endl;exit(-1);}
01756             bar[k]=mesh.get_polygon(index_poly).barycentric_coordinates(vertices[k]);
01757         }
01758         return bar;
01759     }
01760 
01761 
01762 
01763     std::pair <std::pair<MC_mesh_index_vector,MC_mesh_index_vector>,std::pair<MC_int_vector,MC_int_vector> > MC_mesh_index_vector::delete_polygon(const std::set<int> index_to_delete) const
01764     {
01765         int N_poly=polygon_number();
01766 
01767         std::set <int> :: const_iterator index_to_delete_end=index_to_delete.end();
01768 
01769         std::map <int,int> map_interior;
01770         std::map <int,int> map_exterior;
01771 
01772         MC_v3d_vector point_set_interior;
01773         MC_v3d_vector point_set_exterior;
01774         MC_connectivity_index connectivity_exterior;
01775         MC_connectivity_index connectivity_interior;
01776 
01777         MC_int_vector correspondance_interior;
01778         MC_int_vector correspondance_exterior;
01779 
01780         for(int k_poly=0;k_poly<N_poly;++k_poly)
01781         {
01782             MC_int_vector current_poly_index=connectivity()(k_poly);
01783             int N_current=current_poly_index.size();
01784             if(index_to_delete.find(k_poly)==index_to_delete_end) //do not delete
01785             {
01786                 MC_int_vector exterior_polygon_index=MC_int_vector::zeros(N_current);
01787                 for(int k_current=0;k_current<N_current;++k_current)
01788                 {
01789                     std::pair<std::map<int,int>::iterator,bool> inserted_exterior=map_exterior.insert(std::make_pair(current_poly_index[k_current],map_exterior.size()));
01790                     if(inserted_exterior.second==true)//new index
01791                     {
01792                         exterior_polygon_index[k_current]=map_exterior.size()-1;
01793                         point_set_exterior.add(point_set()(current_poly_index[k_current]));
01794                         correspondance_exterior.add(current_poly_index[k_current]);
01795                     }
01796                     else //already existing vertex
01797                         exterior_polygon_index[k_current]=inserted_exterior.first->second;
01798                 }
01799                 connectivity_exterior.add(exterior_polygon_index);
01800             }
01801             else //index to delete
01802             {
01803                 MC_int_vector interior_polygon_index=MC_int_vector::zeros(N_current);
01804                 for(int k_current=0;k_current<N_current;++k_current)
01805                 {
01806                     std::pair<std::map<int,int>::iterator,bool> inserted_interior=map_interior.insert(std::make_pair(current_poly_index[k_current],map_interior.size()));
01807                     if(inserted_interior.second==true)//new index
01808                     {
01809                         interior_polygon_index[k_current]=map_interior.size()-1;
01810                         point_set_interior.add(point_set()(current_poly_index[k_current]));
01811                         correspondance_interior.add(current_poly_index[k_current]);
01812                     }
01813                     else //already existing vertex
01814                         interior_polygon_index[k_current]=inserted_interior.first->second;
01815                 }
01816                 connectivity_interior.add(interior_polygon_index);
01817             }
01818         }
01819 
01820         return std::make_pair(std::make_pair(MC_mesh_index_vector(point_set_exterior,connectivity_exterior),MC_mesh_index_vector(point_set_interior,connectivity_interior)),std::make_pair(correspondance_exterior,correspondance_interior));
01821     }
01822 
01823 
01824 
01825 
01826 
01827     std::pair<std::pair<MC_mesh_index_vector,MC_mesh_index_vector>,std::pair<MC_int_vector,MC_int_vector> > MC_mesh_index_vector::delete_vertex(const std::set<int> index_to_delete) const
01828     {
01829 
01830         MC_mesh_index_vector mesh_deleted;
01831         std::map<int,int> map_vertex_deleted;
01832         std::map<int,int> :: iterator map_vertex_deleted_end=map_vertex_deleted.end();
01833         MC_int_vector correspondance_deleted;
01834 
01835         MC_mesh_index_vector mesh_undeleted;
01836         std::map<int,int> map_vertex_undeleted;
01837         std::map<int,int> :: iterator map_vertex_undeleted_end=map_vertex_undeleted.end();
01838         MC_int_vector correspondance_undeleted;
01839 
01840         int N_polygon=polygon_number();
01841         std::set<int> ::const_iterator it_index_to_delete_end=index_to_delete.end();
01842         for(int k_polygon=0;k_polygon<N_polygon;++k_polygon)
01843         {
01844             MC_int_vector current_polygon=connectivity()(k_polygon);
01845             int N_vertex=current_polygon.size();
01846 
01847             bool is_deleted_polygon=false;
01848             for(int k_vertex=0;k_vertex<N_vertex;++k_vertex)
01849                 if(index_to_delete.find(current_polygon[k_vertex])!=it_index_to_delete_end)
01850                     is_deleted_polygon=true;
01851 
01852             //add the polygon in the deleted part
01853             if(is_deleted_polygon==true)
01854             {
01855                 MC_int_vector temp_index;
01856                 for(int k_vertex=0;k_vertex<N_vertex;++k_vertex)
01857                 {
01858                     std::pair<std::map<int,int>::iterator,bool> it=map_vertex_deleted.insert(std::make_pair(current_polygon[k_vertex],map_vertex_deleted.size()));
01859                     if(it.second==true)
01860                     {
01861                         mesh_deleted.point_set().add(point_set()(current_polygon[k_vertex]));
01862                         correspondance_deleted.add(it.first->first);
01863                     }
01864                     temp_index.add(it.first->second);
01865                 }
01866                 mesh_deleted.connectivity().add(temp_index);
01867             }
01868             //add the polygon in the resulting part
01869             else
01870             {
01871                 MC_int_vector temp_index;
01872                 for(int k_vertex=0;k_vertex<N_vertex;++k_vertex)
01873                 {
01874 
01875                     std::pair<std::map<int,int>::iterator,bool> it=map_vertex_undeleted.insert(std::make_pair(current_polygon[k_vertex],map_vertex_undeleted.size()));
01876                     if(it.second==true)
01877                     {
01878                         mesh_undeleted.point_set().add(point_set()(current_polygon[k_vertex]));
01879                         correspondance_undeleted.add(it.first->first);
01880                     }
01881                     temp_index.add(it.first->second);
01882                 }
01883                 mesh_undeleted.connectivity().add(temp_index);
01884             }
01885         }
01886 
01887 
01888         return std::make_pair(std::make_pair(mesh_undeleted,mesh_deleted),std::make_pair(correspondance_undeleted,correspondance_deleted));
01889 
01890     }
01891 
01892     std::pair<std::pair<MC_mesh_index_vector,MC_mesh_index_vector>,std::pair<MC_int_vector,MC_int_vector> > MC_mesh_index_vector::delete_boundary_polygon() const
01893     {
01894         std::set<int> border_polygon=connectivity_mesh.boundary_polygon();
01895         return delete_polygon(border_polygon);
01896     }
01897 
01898 
01899 
01900     std::vector<MC_polygon> MC_mesh_index_vector::get_polygon() const
01901     {
01902 
01903         int N=polygon_number();
01904         std::vector<MC_polygon> v_poly(N);
01905         for(int k=0;k<N;++k)
01906             v_poly[k]=get_polygon(k);
01907         return v_poly;
01908     }
01909 
01910     MC_mesh_index_vector MC_mesh_index_vector::subdivide_mid_edge_unchanged_boundary() const
01911     {
01912         std::set<MC_int_pair,MC_int_pair_less> s;
01913         return subdivide_mid_edge_unchanged_boundary(s);
01914     }
01915     MC_mesh_index_vector MC_mesh_index_vector::subdivide_barycenter_mid_edge_unchanged_boundary() const
01916     {
01917         std::set<MC_int_pair,MC_int_pair_less> s;
01918         return subdivide_barycenter_mid_edge_unchanged_boundary(s);
01919     }
01920     MC_mesh_index_vector MC_mesh_index_vector::subdivide_mixed_mid_edge_unchanged_boundary() const
01921     {
01922         std::set<MC_int_pair,MC_int_pair_less> s;
01923         return subdivide_mixed_mid_edge_unchanged_boundary(s);
01924     }
01925 
01926     MC_mesh_index_vector MC_mesh_index_vector::subdivide_mixed_mid_edge(const std::set<int>& polygon_to_subdivide) const
01927     {
01928         std::set<MC_int_pair,MC_int_pair_less> s;
01929         return subdivide_mixed_mid_edge(polygon_to_subdivide,s);
01930     }
01931     MC_mesh_index_vector MC_mesh_index_vector::subdivide_mixed_mid_edge(const std::set<int>& polygon_to_subdivide,const std::set<MC_int_pair,MC_int_pair_less>& allowed_edge) const
01932     {
01933 
01934         MC_v3d_vector new_mesh_vector=point_set();
01935         MC_connectivity_index new_mesh_connectivity=connectivity().delete_index(MC_int_vector(polygon_to_subdivide)).first;
01936         MC_mesh_index_vector new_mesh(new_mesh_vector,new_mesh_connectivity);
01937 
01938         std::pair <std::pair<MC_mesh_index_vector,MC_mesh_index_vector>,std::pair<MC_int_vector,MC_int_vector> > splitted=delete_polygon(polygon_to_subdivide);
01939 
01940         std::map <int,int> new_to_original=splitted.second.second.to_map();
01941         std::map <int,int> original_to_new=MC_helper_stl::reverse_map(new_to_original);
01942 
01943         std::set<MC_int_pair,MC_int_pair_less> new_allowed_edge;
01944         for(std::set<MC_int_pair,MC_int_pair_less>::const_iterator
01945             it=allowed_edge.begin(),
01946             it_end=allowed_edge.end();
01947         it!=it_end;++it)
01948             new_allowed_edge.insert(MC_int_pair(new_to_original[(*it)[0]],new_to_original[(*it)[1]]));
01949 
01950         MC_mesh_index_vector subdivided=splitted.first.second.subdivide_mixed_mid_edge_unchanged_boundary(new_allowed_edge);
01951         int N_vertex_old=splitted.first.second.point_set().size();
01952         int N_vertex_new=subdivided.point_set().size();
01953 
01954 
01955 
01956         for(int k=N_vertex_old;k<N_vertex_new;++k)
01957             new_mesh.point_set().add(subdivided.point_set()(k));
01958         int N_subdivided_poly=subdivided.polygon_number();
01959         for(int k=0;k<N_subdivided_poly;++k)
01960         {
01961             MC_int_vector new_poly=subdivided.connectivity()(k);
01962             int N_new_poly=new_poly.size();
01963             MC_int_vector new_poly_in_full_coordinate=MC_int_vector::zeros(N_new_poly);
01964             for(int k_index=0;k_index<N_new_poly;++k_index)
01965             {
01966                 int u=new_poly[k_index];
01967                 if(u<N_vertex_old)
01968                     new_poly_in_full_coordinate[k_index]=splitted.second.second(u);
01969                 else
01970                     new_poly_in_full_coordinate[k_index]=(u-N_vertex_old)+point_set().size();
01971             }
01972             new_mesh.connectivity().add(new_poly_in_full_coordinate);
01973         }
01974 
01975         new_mesh.connectivity().build_ring().build_star();
01976 
01977         return new_mesh;
01978     }
01979     std::pair <MC_int_vector,MC_int_vector> MC_mesh_index_vector::polygons_inside_sphere(const MC_v3d& center,const double& radius) const
01980     {
01981         MC_int_vector index_inside,index_outside;
01982         for(int k_polygon=0,N_polygon=polygon_number();k_polygon<N_polygon;++k_polygon)
01983         {
01984             bool is_inside=false;
01985             MC_int_vector poly=connectivity()(k_polygon);
01986             for(int k=0,N=poly.size();is_inside==false&&k<N;++k)
01987             {
01988                 if( (point_set()(poly[k])-center).norm()<=radius)
01989                 {
01990                     is_inside=true;
01991                     index_inside.add(k_polygon);
01992 
01993                 }
01994             }
01995             if(is_inside==false)
01996                 index_outside.add(k_polygon);
01997         }
01998         return std::make_pair(index_inside,index_outside);
01999     }
02000 
02001     MC_mesh_index_vector MC_mesh_index_vector::laplacian_smoothing(const double& lambda,const int& steps,const bool& is_boundary_preserving) const
02002     {
02003 
02004         if(steps==0)
02005             return *this;
02006 
02007         MC_mesh_index_vector new_mesh=*this;
02008 
02009         //ring need to be computed
02010         std::map<int,std::set<int> > r=connectivity().ring();
02011 
02012         std::set<int> bnd=connectivity().boundary_vertex();
02013 
02014 
02015         for(int k_step=0;k_step<steps;++k_step)
02016         {
02017             MC_v3d_vector temp=MC_v3d_vector::zeros(vertex_number());
02018             for(int k_vertex=0,N_vertex=vertex_number();k_vertex<N_vertex;++k_vertex)
02019             {
02020                 MC_v3d x=new_mesh.point_set()(k_vertex);
02021 
02022                 if(is_boundary_preserving==false ||
02023                    (is_boundary_preserving==true && bnd.find(k_vertex)==bnd.end()) )
02024                 {//not a boundary vertex
02025 
02026                     MC_v3d bar;
02027                     std::set<int> current_ring=r[k_vertex];
02028                     for(std::set<int>::const_iterator it=current_ring.begin(),it_end=current_ring.end();it!=it_end;++it)
02029                         bar += new_mesh.point_set()(*it);
02030 
02031                     if(current_ring.size()>0)
02032                         bar/=current_ring.size();
02033 
02034                     temp[k_vertex]=(1-lambda)*x+lambda*bar;
02035                 }
02036                 else//boundary
02037                     temp[k_vertex]=x;
02038             }
02039             new_mesh.point_set()=temp;
02040         }
02041 
02042         return new_mesh;
02043     }
02044 
02045     MC_mesh_index_vector MC_mesh_index_vector::load_mesh_file(const std::string& filename)
02046     {
02047         MC_mesh_index_vector mesh;
02048 
02049         //get extension
02050         std::vector<std::string> token=MC_string_tokenizer::tokenize(filename,".");
02051         std::string extension=token[token.size()-1];
02052 
02053         if(extension.find("off")!=std::string::npos)
02054             mesh=MC_io_off::read_off_file(filename);
02055         else if(extension.find("obj")!=std::string::npos)
02056             mesh=MC_io_obj::read_obj_file(filename);
02057         else
02058             std::cout<<"Warning in MC_mesh_index_vector::load_mesh_file("<<filename<<"), extension "<<extension<<" not recognized"<<std::endl;
02059 
02060         return mesh;
02061     }
02062 
02063     double MC_mesh_index_vector::area() const
02064     {
02065         double a=0.0;
02066         for(int k=0,N=polygon_number();k<N;++k)
02067         {
02068             MC_int_vector poly=connectivity_mesh(k);
02069 
02070             MC_v3d x0=point_set_mesh(poly[0]);
02071             for(int k_tri=0,N_pol=poly.size();k_tri<N_pol-2;++k_tri)
02072             {
02073                 MC_v3d x1=point_set_mesh(poly[k_tri+1]);
02074                 MC_v3d x2=point_set_mesh(poly[k_tri+2]);
02075 
02076                 double C0=(x2[1]-x0[1])*(x1[2]-x0[2])-(x2[2]-x0[2])*(x1[1]-x0[1]);
02077                 double C1=(x2[2]-x0[2])*(x1[0]-x0[0])-(x2[0]-x0[0])*(x1[2]-x0[2]);
02078                 double C2=(x2[0]-x0[0])*(x1[1]-x0[1])-(x2[1]-x0[1])*(x1[0]-x0[0]);
02079 
02080                 double u=sqrt(C0*C0+C1*C1+C2*C2);
02081 
02082                 a+=0.5*u;
02083             }
02084         }
02085         return a;
02086     }
02087 
02088     MC_v3d_vector MC_mesh_index_vector::area_gradient() const
02089     {
02090         MC_v3d_vector grad=MC_v3d_vector::zeros(vertex_number());
02091 
02092         for(int k=0,N=polygon_number();k<N;++k)
02093         {
02094             MC_int_vector poly=connectivity_mesh(k);
02095 
02096             MC_v3d x0=point_set_mesh(poly[0]);
02097             int index_0=poly[0];
02098             for(int k_tri=0,N_pol=poly.size();k_tri<N_pol-2;++k_tri)
02099             {
02100                 MC_v3d x1=point_set_mesh(poly[k_tri+1]);
02101                 MC_v3d x2=point_set_mesh(poly[k_tri+2]);
02102 
02103 
02104                 int index_1=poly[k_tri+1];
02105                 int index_2=poly[k_tri+2];
02106 
02107                 double C0=(x2[1]-x0[1])*(x1[2]-x0[2])-(x2[2]-x0[2])*(x1[1]-x0[1]);
02108                 double C1=(x2[2]-x0[2])*(x1[0]-x0[0])-(x2[0]-x0[0])*(x1[2]-x0[2]);
02109                 double C2=(x2[0]-x0[0])*(x1[1]-x0[1])-(x2[1]-x0[1])*(x1[0]-x0[0]);
02110 
02111                 double u=sqrt(C0*C0+C1*C1+C2*C2);
02112 
02113 
02114                 grad[index_0][0] +=  ( (x1[2]-x2[2])*C1 + (x2[1]-x1[1])*C2 )/(2*u);
02115                 grad[index_0][1] +=  ( (x2[2]-x1[2])*C0 + (x1[0]-x2[0])*C2 )/(2*u);
02116                 grad[index_0][2] +=  ( (x1[1]-x2[1])*C0 + (x2[0]-x1[0])*C1 )/(2*u);
02117 
02118                 grad[index_1][0] +=  ( (x2[2]-x0[2])*C1 + (x0[1]-x2[1])*C2 )/(2*u);
02119                 grad[index_1][1] +=  ( (x0[2]-x2[2])*C0 + (x2[0]-x0[0])*C2 )/(2*u);
02120                 grad[index_1][2] +=  ( (x2[1]-x0[1])*C0 + (x0[0]-x2[0])*C1 )/(2*u);
02121 
02122                 grad[index_2][0] +=  ( (x0[2]-x1[2])*C1 + (x1[1]-x0[1])*C2 )/(2*u);
02123                 grad[index_2][1] +=  ( (x1[2]-x0[2])*C0 + (x0[0]-x1[0])*C2 )/(2*u);
02124                 grad[index_2][2] +=  ( (x0[1]-x1[1])*C0 + (x1[0]-x0[0])*C1 )/(2*u);
02125             }
02126         }
02127 
02128         return grad;
02129     }
02130 
02131 
02132     MC_mesh_index_vector MC_mesh_index_vector::build_ball_point_set(const MC_v3d_vector& v,const double& radius,const int& N_subdiv)
02133     {
02134         MC_mesh_index_vector sph=MC_mesh_index_vector::build_sphere(N_subdiv)*radius;
02135         MC_mesh_index_vector visu_point_set;
02136         for(int k=0,N=v.size();k<N;++k)
02137             visu_point_set.concatenation(sph+v[k]);
02138         return visu_point_set;
02139     }
02140 
02141     double MC_mesh_index_vector::average_edge_length() const
02142     {
02143         int counter=0;
02144         double avg_length=0.0;
02145         for(int k=0,N=polygon_number();k<N;++k)
02146         {
02147             MC_int_vector index=connectivity()(k);
02148             for(int k_v=0,N_v=index.size();k_v<N_v;++k_v)
02149             {
02150                 avg_length += ( point_set()(index(k_v))-point_set()(index( (k_v+1)%N_v )) ).norm();
02151                 ++counter;
02152             }
02153         }
02154         return avg_length/static_cast<double>(counter);
02155     }
02156 
02157     MC_mesh_index_vector MC_mesh_index_vector::get_polygon_mesh() const
02158     {
02159         MC_mesh_index_vector exploded;
02160         for(int k=0,N=polygon_number();k<N;++k)
02161         {
02162             MC_polygon p=get_polygon(k);
02163             exploded.connectivity().add(MC_int_vector::linspace(0,p.size()-1)+exploded.vertex_number());
02164             exploded.point_set().add(p);
02165         }
02166         return exploded;
02167     }
02168 
02169 
02170 
02171 
02172     MC_mesh_index_vector MC_mesh_index_vector::build_wireframe(const MC_mesh_index_vector& mesh,const double& radius_cylinder,const int& N_circular,const int& N_subdiv_edges)
02173     {
02174         std::set<MC_int_pair,MC_int_pair_less> already_created_edge;
02175 
02176         MC_curve pattern=MC_curve::build_circle(radius_cylinder,N_circular);
02177         MC_mesh_index_vector wireframe;
02178 
02179         for(int k=0,N=mesh.polygon_number();k<N;++k)
02180         {
02181             MC_int_vector poly=mesh.connectivity()(k);
02182             for(int k2=0,N_poly=poly.size();k2<N_poly;++k2)
02183             {
02184                 int index_0=poly[k2];
02185                 int index_1=poly[(k2+1)%N_poly];
02186 
02187                 if(already_created_edge.insert(MC_int_pair(index_0,index_1)).second==true)
02188                 {
02189                     MC_v3d x0=mesh.point_set()(poly[k2]);
02190                     MC_v3d x1=mesh.point_set()(poly[(k2+1)%N_poly]);
02191 
02192                     MC_curve c=MC_curve::build_line(x0,x1,N_subdiv_edges);
02193 
02194                     MC_mesh_index_vector sweep=MC_mesh_index_vector::sweep_surface(c,pattern,2,false);
02195                     wireframe.concatenation(sweep);
02196                 }
02197             }
02198         }
02199 
02200         return wireframe;
02201     }
02202 
02203     MC_matrix MC_mesh_index_vector::inertia() const
02204     {
02205         MC_matrix J(3);
02206         for(int k=0,N=polygon_number();k<N;++k)
02207         {
02208             std::vector<MC_triangle> tri=MC_triangle::triangulate(get_polygon(k));
02209             for(int k_tri=0,N_tri=tri.size();k_tri<N_tri;++k_tri)
02210                 J+=tri[k_tri].inertia();
02211         }
02212 
02213         return J;
02214     }
02215 
02216     MC_mesh_index_vector MC_mesh_index_vector::build_sphere_point_set(const MC_v3d_vector& position,const double& radius,const unsigned int& N_subdiv)
02217     {
02218         MC_mesh_index_vector sph=radius*MC_mesh_index_vector::build_sphere(N_subdiv);
02219         MC_mesh_index_vector v_sph;
02220         for(int k=0,N=position.size();k<N;++k)
02221             v_sph.concatenation(sph+position[k]);
02222 
02223         return v_sph;
02224     }
02225 
02226 
02227 
02228     MC_curve MC_mesh_index_vector::intersection_curve(const MC_mesh_index_vector& mesh,const MC_segment& s)
02229     {
02230         //get the normal plane
02231         MC_v3d_vector normal_mesh=mesh.get_polygon(0).normal();
02232         MC_v3d_vector normal_plane=(s[1]-s[0]).normalized().cross(normal_mesh).normalized();
02233 
02234 
02235         //get the set of curve by intersecting the mesh with a plane
02236         std::vector <MC_curve> curve_inter_plane=mesh.plane_intersection(normal_plane,s[0]);
02237 
02238 
02239 
02240         MC_io_off::write_off_file("mesh_to_cut.off",mesh);
02241         std::vector<MC_segment> v_s;v_s.push_back(s);
02242         MC_io_off::write_off_file("line_in_mesh.off",MC_mesh_index_vector::build_segment(v_s,0.005,10));
02243 
02244          std::cout<<" ! "<<curve_inter_plane.size()<<std::endl;
02245 
02246         std::cout<<"-- "<<curve_inter_plane[0]<<std::endl;;
02247         //std::cout<<normal_mesh<<" "<<s<<curve_inter_plane.size()<<std::endl;
02248         if(curve_inter_plane.size()<1)
02249         {std::cout<<"Something strange in MC_mesh_index_vector::intersection_curve()"<<std::endl;exit(-1);}
02250 
02251         return curve_inter_plane[0];
02252 
02253     }
02254 
02255     MC_mesh_index_vector MC_mesh_index_vector::build_segment(const std::vector<MC_segment>& v_seg,const double& radius,const double& N_circular)
02256     {
02257         MC_curve pattern=MC_curve::build_circle(radius,N_circular);
02258         MC_mesh_index_vector wireframe;
02259         unsigned int N_subdiv_edges=2;
02260         for(int k=0,N=v_seg.size();k<N;++k)
02261         {
02262             const MC_v3d& x0=v_seg[k][0];
02263             const MC_v3d& x1=v_seg[k][1];
02264 
02265             MC_curve c=MC_curve::build_line(x0,x1,N_subdiv_edges);
02266             MC_mesh_index_vector sweep=MC_mesh_index_vector::sweep_surface(c,pattern,8,false);
02267             wireframe.concatenation(sweep);
02268         }
02269         return wireframe;
02270     }
02271 
02272     MC_mesh_index_vector MC_mesh_index_vector::texture_convert_planar_xy(const MC_mesh_index_vector& mesh)
02273     {
02274 
02275         MC_v3d_vector texture_coord=mesh.point_set();
02276         texture_coord=texture_coord.scaled_to_unit_and_center().first;//+MC_v3d(0.5,0.5,0.0);
02277         return MC_mesh_index_vector(texture_coord,mesh.connectivity());
02278     }
02279     MC_mesh_index_vector MC_mesh_index_vector::texture_convert_planar_xy_same_connectivity(const MC_mesh_index_vector& mesh_tex,const MC_mesh_index_vector& mesh_ref)
02280     {
02281         MC_v3d_vector new_texture;
02282         MC_mesh_index_vector tex=texture_convert_planar_xy(mesh_tex);
02283         for(unsigned int k_poly=0,N_poly=mesh_ref.polygon_number();k_poly<N_poly;++k_poly)
02284             for(unsigned int k=0,N=mesh_ref.connectivity()[k_poly].size();k<N;++k)
02285                 new_texture.set( mesh_ref.connectivity()[k_poly][k],tex.point_set()(tex.connectivity()[k_poly][k]) );
02286         tex=MC_mesh_index_vector(new_texture,mesh_ref.connectivity());
02287         return tex;
02288     }
02289 
02290     std::pair<MC_mesh_index_vector,std::pair<MC_int_vector_vector,MC_int_vector_vector> > MC_mesh_index_vector::build_from_polygon_soup(const std::vector<MC_polygon> poly_soup)
02291     {
02292         MC_mesh_index_vector m;
02293         return m.added_polygon_soup(poly_soup);
02294     }
02295 
02296     MC_mesh_index_vector MC_mesh_index_vector::build_square(const int& N1,const int& N2,const MC_v3d& tangent_1,const MC_v3d& tangent_2,const MC_v3d& center,const double& L1,const double& L2)
02297     {
02298         MC_mesh_index_vector m=build_square(N1,N2);
02299 
02300         //center
02301         m.point_set() += MC_v3d(-0.5,-0.5,0.0);
02302 
02303         //scale
02304         m.point_set()=m.point_set().scale(MC_v3d(L1,L2,1.0));
02305 
02306 
02307 
02308         //rotate
02309         MC_matrix R1=MC_matrix::rotation_axis_to_axis(MC_v3d(1,0,0),tangent_1);
02310         MC_matrix R2=MC_matrix::rotation_axis_to_axis(R1*MC_v3d(0,1,0),tangent_2);
02311         m=R2*R1*m;
02312 
02313         //translate
02314         m.point_set() += center;
02315 
02316         return m;
02317     }
02318 
02319 }

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