00001
00002
00003 #include <MC_int_pair.hpp>
00004
00005 #include <MC_connectivity_index.hpp>
00006 #include <MC_double_vector.hpp>
00007
00008 namespace mesh_conv
00009 {
00010
00011 MC_connectivity_index::MC_connectivity_index() :MC_int_vector_vector(){}
00012 MC_connectivity_index::MC_connectivity_index(const MC_int_vector& v0) :MC_int_vector_vector(v0){}
00013 MC_connectivity_index::MC_connectivity_index(const MC_int_vector& v0,const MC_int_vector& v1) :MC_int_vector_vector(v0,v1){}
00014 MC_connectivity_index::MC_connectivity_index(const MC_int_vector& v0,const MC_int_vector& v1,const MC_int_vector& v2) :MC_int_vector_vector(v0,v1,v2) {}
00015 MC_connectivity_index::MC_connectivity_index(const MC_int_vector& v0,const MC_int_vector& v1,const MC_int_vector& v2,const MC_int_vector& v3) :MC_int_vector_vector(v0,v1,v2,v3) {}
00016 MC_connectivity_index::MC_connectivity_index(const MC_int_vector_vector& v0)
00017 :MC_int_vector_vector(v0)
00018 {update_neighbors();}
00019 MC_connectivity_index::MC_connectivity_index(const MC_connectivity_index& v0) :MC_int_vector_vector(v0)
00020 {
00021 if(v0.ring_1.size()==0 || v0.star_1.size()==0)
00022 update_neighbors();
00023 else
00024 {ring_1=v0.ring_1;star_1=v0.star_1;}
00025 }
00026
00027 MC_connectivity_index& MC_connectivity_index::build_ring()
00028 {
00029 ring_1.clear();
00030
00031 int N_polygon=size();
00032 for(int k_polygon=0;k_polygon<N_polygon;++k_polygon)
00033 {
00034 MC_int_vector poly_index=(*this)[k_polygon];
00035 int N_poly=poly_index.size();
00036 for(int k=0;k<N_poly;++k)
00037 {
00038 int u0=poly_index[k];
00039 int u1=poly_index[(k+1)%N_poly];
00040
00041
00042 std::map<int,std::set <int> > :: iterator it_1=ring_1.find(u0);
00043 if(it_1==ring_1.end())
00044 it_1=ring_1.insert(std::pair<int,std::set<int> >(u0,std::set<int>())).first;
00045 it_1->second.insert(u1);
00046
00047
00048 std::map<int,std::set <int> > ::iterator it_2=ring_1.find(u1);
00049 if(it_2==ring_1.end())
00050 it_2=ring_1.insert(std::pair<int,std::set<int> >(u1,std::set <int>() )).first;
00051 it_2->second.insert(u0);
00052
00053 }
00054 }
00055 return *this;
00056 }
00057 const std::map<int,std::set<int> >& MC_connectivity_index::ring() const
00058 {return ring_1;}
00059
00060 MC_connectivity_index& MC_connectivity_index::build_star()
00061 {
00062 star_1.clear();
00063 int N_polygon=size();
00064 for(int k_polygon=0;k_polygon<N_polygon;++k_polygon)
00065 {
00066 MC_int_vector poly_index=(*this)[k_polygon];
00067 int N_poly=poly_index.size();
00068 for(int k=0;k<N_poly;++k)
00069 {
00070 std::map<int,std::set<int> > :: iterator it=star_1.find(poly_index[k]);
00071 if(it==star_1.end())
00072 it=star_1.insert(std::pair<int,std::set<int> > (poly_index[k],std::set<int>() )).first;
00073 it->second.insert(k_polygon);
00074 }
00075 }
00076 return *this;
00077
00078 }
00079
00080 const std::map<int,std::set<int> >& MC_connectivity_index::star() const
00081 {return star_1;}
00082
00083 MC_connectivity_index& MC_connectivity_index::update_neighbors()
00084 {
00085 if(size()<20000)
00086 {
00087 build_ring();
00088 build_star();
00089 }
00090
00091
00092 return *this;
00093 }
00094
00095 std::set <MC_int_pair,MC_int_pair_less> MC_connectivity_index::boundary() const
00096 {
00097 std::vector <std::set <int> > index_edge;
00098 int N_polygon=size();
00099 for(int k_polygon=0;k_polygon<N_polygon;++k_polygon)
00100 {
00101 MC_int_vector index_polygon=(*this)[k_polygon];
00102 int size_polygon=index_polygon.size();
00103 for(int k_edge=0;k_edge<size_polygon;++k_edge)
00104 {
00105 int v0=index_polygon[k_edge];
00106 int v1=index_polygon[(k_edge+1)%size_polygon];
00107
00108 int u0=std::min(v0,v1),u1=std::max(v0,v1);
00109 if(u0>=static_cast <int> (index_edge.size()))
00110 {
00111 index_edge.resize(u0+1);
00112 index_edge[u0].insert(u1);
00113 }
00114 else
00115 {
00116 std::set <int> :: iterator it;
00117 it=index_edge[u0].find(u1);
00118 if(it!=index_edge[u0].end())
00119 index_edge[u0].erase(it);
00120 else
00121 index_edge[u0].insert(u1);
00122 }
00123
00124 }
00125 }
00126
00127
00128 std::set <MC_int_pair,MC_int_pair_less> boundary_edge;
00129 int N_vertex=index_edge.size();
00130 for(int k_vertex=0;k_vertex<N_vertex;++k_vertex)
00131 if(index_edge[k_vertex].size()>0)
00132 {
00133 std::set <int> :: const_iterator it;
00134 std::set <int> :: const_iterator it_end=index_edge[k_vertex].end();
00135 for(it=index_edge[k_vertex].begin();it!=it_end;++it)
00136 boundary_edge.insert(MC_int_pair(k_vertex,*it));
00137 }
00138
00139 return boundary_edge;
00140 }
00141
00142 std::set<int> MC_connectivity_index::used_vertex() const
00143 {
00144 std::set <int> vertices;
00145 int N=size();
00146 for(int k_poly=0;k_poly<N;++k_poly)
00147 {
00148 MC_int_vector pol=(*this)[k_poly];
00149 int N_vertex=pol.size();
00150 for(int k_vertex=0;k_vertex<N_vertex;++k_vertex)
00151 vertices.insert(pol[k_vertex]);
00152 }
00153 return vertices;
00154
00155 }
00156
00157 bool MC_connectivity_index::is_triangle_only() const
00158 {
00159 int N=size();
00160 for(int k_poly=0;k_poly<N;++k_poly)
00161 if((*this)[k_poly].size()!=3)
00162 return false;
00163 return true;
00164 }
00165
00166 std::set<int> MC_connectivity_index::boundary_vertex() const
00167 {
00168 std::set <MC_int_pair,MC_int_pair_less> bnd=boundary();
00169 std::set <MC_int_pair,MC_int_pair_less> :: const_iterator it_bnd=bnd.begin();
00170 std::set <MC_int_pair,MC_int_pair_less> :: const_iterator it_bnd_end=bnd.end();
00171
00172 std::set<int> index_boundary;
00173 for(;it_bnd!=it_bnd_end;++it_bnd)
00174 for(int k_dim=0;k_dim<2;++k_dim)
00175 index_boundary.insert((*it_bnd)[k_dim]);
00176
00177 return index_boundary;
00178 }
00179 std::set<int> MC_connectivity_index::boundary_polygon() const
00180 {
00181 std::map<int,std::set<int> > ::const_iterator it_star;
00182 std::map<int,std::set<int> > ::const_iterator it_star_end=star_1.end();
00183
00184 std::set<int> set_bnd_polygon;
00185
00186 MC_int_vector vertex_bnd=boundary_vertex();
00187 int N_vertex_bnd=vertex_bnd.size();
00188 for(int k_vertex=0;k_vertex<N_vertex_bnd;++k_vertex)
00189 {
00190 it_star=star_1.find(vertex_bnd(k_vertex));
00191 if(it_star==it_star_end)
00192 {std::cout<<"Error in MC_connectivity_index::boundary_polygon(), cannot find vertex"<<vertex_bnd(k_vertex)<<", at k="<<k_vertex<<" for star_1.size()="<<star_1.size()<<std::endl;exit(-1);}
00193
00194 std::set<int> current_neigh=it_star->second;
00195 set_bnd_polygon.insert(current_neigh.begin(),current_neigh.end());
00196 }
00197
00198 return set_bnd_polygon;
00199 }
00200
00201 MC_connectivity_index MC_connectivity_index::triangulated() const
00202 {
00203 MC_connectivity_index connectivity_triangle;
00204 for(int k=0,N=size();k<N;++k)
00205 {
00206 MC_int_vector poly=(*this)(k);
00207 if(poly.size()>3)
00208 {
00209 for(int k_v=0,N_tri=poly.size()-2;k_v<N_tri;++k_v)
00210 connectivity_triangle.add(MC_int_vector(poly[0],poly[k_v+1],poly[k_v+2]));
00211 }
00212 else
00213 connectivity_triangle.add(poly);
00214 }
00215
00216 return connectivity_triangle;
00217 }
00218
00219 MC_connectivity_index MC_connectivity_index::fliped_polygon() const
00220 {
00221 MC_connectivity_index new_connectivity;new_connectivity.resize(size());
00222 for(int k=0,N=size();k<N;++k)
00223 {
00224 MC_int_vector current=(*this)[k];
00225 new_connectivity[k]=current(MC_int_vector::linspace(current.size()-1,0,-1));
00226 }
00227 return new_connectivity;
00228 }
00229
00230 std::map<int,std::set<int> > MC_connectivity_index::polygon_neighbors() const
00231 {
00232 std::map<int,std::set<int> > neigh;
00233 std::map<int,std::set<int> > s=star();
00234
00235 for(int k=0,N=size();k<N;++k)
00236 {
00237 MC_int_vector index_polygon=(*this)(k);
00238
00239 for(int k_v=0,N_v=index_polygon.size();k_v<N_v;++k_v)
00240 {
00241 std::set <int> current_neighbors=s[index_polygon[k_v]];
00242 current_neighbors.erase(k);
00243
00244 std::map<int,std::set<int> > ::iterator it=neigh.find(k);
00245 if(it==neigh.end())
00246 neigh.insert(std::make_pair(k,current_neighbors));
00247 else
00248 {
00249 for(std::set<int>::iterator it_2=current_neighbors.begin(),it_2_end=current_neighbors.end();it_2!=it_2_end;++it_2)
00250 {
00251 it->second.insert(*it_2);
00252 }
00253 }
00254 }
00255
00256 }
00257 return neigh;
00258 }
00259
00260 MC_int_vector MC_connectivity_index::triangle_propagation_using_vertex_field(const MC_int_vector& seed_vertices,const MC_double_vector& field_per_vertex,const double& threshold,const std::set<int>& invalidated_triangle) const
00261 {
00262 if(static_cast<int>(star_1.size())!=field_per_vertex.size())
00263 {std::cout<<"Error in MC_connectivity_index::triangle_propagation_using_vertex_field(), size problem with star_1 size: "<<star_1.size()<<std::endl;exit(-1);}
00264
00265 if(static_cast<int>(ring_1.size())!=field_per_vertex.size())
00266 {std::cout<<"Error in MC_connectivity_index::triangle_propagation_using_vertex_field(), size problem with ring_1 size: "<<ring_1.size()<<std::endl;exit(-1);}
00267
00268
00269 std::set<int> selected_triangle;
00270
00271 std::set<int> selected_vertices;
00272 std::set<int> vertices_to_treat=seed_vertices.to_set();
00273
00274
00275 do
00276 {
00277 int current_vertex=*vertices_to_treat.begin();
00278 vertices_to_treat.erase(vertices_to_treat.begin());
00279
00280
00281 bool is_forbidden_triangle=false;
00282 const std::set<int>& current_star=star_1.find(current_vertex)->second;
00283 for(std::set<int>::const_iterator it_star=current_star.begin(),it_star_end=current_star.end();it_star!=it_star_end;++it_star)
00284 {
00285 if(invalidated_triangle.find(*it_star)!=invalidated_triangle.end())
00286 {
00287 is_forbidden_triangle=true;break;
00288 }
00289 }
00290
00291 if(is_forbidden_triangle==false)
00292 {
00293 if(field_per_vertex[current_vertex]<threshold)
00294 selected_vertices.insert(current_vertex);
00295
00296 const std::set<int>& current_neighbors=ring_1.find(current_vertex)->second;
00297 for(std::set<int>::const_iterator it=current_neighbors.begin(),it_end=current_neighbors.end();it!=it_end;++it)
00298 {
00299 if(field_per_vertex[*it]<threshold && selected_vertices.find(*it)==selected_vertices.end() && invalidated_triangle.find(*it)==invalidated_triangle.end())
00300 vertices_to_treat.insert(*it);
00301 }
00302 }
00303
00304 }while(vertices_to_treat.size()>0);
00305
00306 for(std::set<int>::const_iterator it=selected_vertices.begin(),it_end=selected_vertices.end();it!=it_end;++it)
00307 {
00308 const std::set<int>& tri_neighbors=star_1.find(*it)->second;
00309 for(std::set<int>::const_iterator it_tri=tri_neighbors.begin(),it_tri_end=tri_neighbors.end();it_tri!=it_tri_end;++it_tri)
00310 selected_triangle.insert(*it_tri);
00311 }
00312
00313 return MC_int_vector(selected_triangle);
00314 }
00315
00316 std::set<MC_int_pair,MC_int_pair_less> MC_connectivity_index::edges() const
00317 {
00318 std::set<MC_int_pair,MC_int_pair_less> e;
00319 for(int k=0,N=size();k<N;++k)
00320 {
00321 const MC_int_vector& poly=(*this)(k);
00322 int N_poly=poly.size();
00323
00324 for(int k_v=0;k_v<N_poly;++k_v)
00325 e.insert(MC_int_pair(poly[k_v],poly[(k_v+1)%N_poly]));
00326 }
00327 return e;
00328 }
00329
00330
00331 }