Connectivity.cpp

Go to the documentation of this file.
00001 /*
00002 **    Mesh Converter
00003 **    Copyright (C) 2008  Damien Rohmer
00004 **
00005 **    This program is free software: you can redistribute it and/or modify
00006 **    it under the terms of the GNU General Public License as published by
00007 **    the Free Software Foundation, either version 3 of the License, or
00008 **    (at your option) any later version.
00009 **
00010 **   This program is distributed in the hope that it will be useful,
00011 **    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 **    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 **    GNU General Public License for more details.
00014 **
00015 **    You should have received a copy of the GNU General Public License
00016 **    along with this program.  If not, see <http://www.gnu.org/licenses/>.
00017 */
00018 
00019 
00020 
00021 
00022 
00023 #include <Connectivity.h>
00024 
00025 
00026 Connectivity::Connectivity()
00027 {
00028 }
00029 
00030 Connectivity::Connectivity(const Connectivity& c)
00031 {
00032   index_polygon  = c.index_polygon;
00033   size_polygon   = c.size_polygon;
00034   polygon_access = c.polygon_access;
00035   edges          = c.edges;
00036   max_index      = c.max_index;
00037   one_ring       = c.one_ring;
00038   polygon_ring   = c.polygon_ring;
00039 }
00040 
00041 Connectivity::~Connectivity(){destroy();}
00042 
00043 int Connectivity::destroy()
00044 {
00045   index_polygon  . resize(0);
00046   size_polygon   . resize(0);
00047   polygon_access . resize(0);
00048   edges          . resize(0);
00049   one_ring       . resize(0);
00050   polygon_ring   . resize(0);
00051   max_index=-1;
00052 
00053   return 0;
00054 }
00055 
00056 int Connectivity::get_index(int k_index) const
00057 {
00058   if(k_index<0 || k_index>=size_index())
00059     {printf("Error in get_index(%d) with size %d in Connectivity\n",k_index,size_index());exit(-1);}
00060   return index_polygon[k_index];
00061 }
00062 int& Connectivity::get_index(int k_index)
00063 {
00064   if(k_index<0 || k_index>=size_index())
00065     {printf("Error in get_index(%d) with size %d in Connectivity\n",k_index,size_index());exit(-1);}
00066   return index_polygon[k_index];
00067 }
00068 int Connectivity::get_index(int k_polygon,int k_index) const
00069 {
00070   if(k_polygon<0 || k_polygon>=polygon_number())
00071     {printf("Error in get_index, k_polygon(%d) is not correct with size %d in Connectivity\n",k_polygon,polygon_number());exit(-1);}
00072   if(k_index<0 || k_index>=polygon_size(k_polygon))
00073     {printf("Error in get_index, k_index(%d) is not correct for polygon %d in Connectivity. This polygon has size=%d\n",k_index,k_polygon,polygon_size(k_polygon));exit(-1);}
00074   return index_polygon[polygon_access[k_polygon]+k_index];
00075 }
00076 int& Connectivity::get_index(int k_polygon,int k_index)
00077 {
00078   if(k_polygon<0 || k_polygon>=polygon_number())
00079     {printf("Error in get_index, k_polygon(%d) is not correct with size %d in Connectivity\n",k_polygon,polygon_number());exit(-1);}
00080   if(k_index<0 || k_index>=polygon_size(k_polygon))
00081     {printf("Error in get_index, k_index(%d) is not correct for polygon %d in Connectivity. This polygon has size=%d\n",k_index,k_polygon,polygon_size(k_polygon));exit(-1);}
00082   return index_polygon[polygon_access[k_polygon]+k_index];
00083 }
00084 std::vector <int> Connectivity::get_index_of_polygon(int k_polygon) const
00085 {
00086   if(k_polygon<0 || k_polygon>=polygon_number())
00087     {printf("Error in get_index, k_polygon(%d) is not correct with size %d in Connectivity\n",k_polygon,polygon_number());exit(-1);}
00088   std::vector <int> ind;
00089   int k_index=0,N_index=polygon_size(k_polygon);
00090   for(k_index=0;k_index<N_index;k_index++)
00091     ind.push_back(get_index(k_polygon,k_index));
00092   return ind;
00093 }
00094 const int* Connectivity::get_index() const {return &index_polygon[0];}
00095 
00096 
00097 
00098 
00099 
00100 
00101 int Connectivity::size_index() const {return index_polygon.size();}
00102 int Connectivity::polygon_number() const {return size_polygon.size();}
00103 int Connectivity::polygon_size(int k_polygon) const
00104 {
00105   if(k_polygon<0 || k_polygon>=int(size_polygon.size()))
00106     {printf("Error in polygon_size in Connectivity, k_polygon[%d] with size[%d]\n",k_polygon,size_polygon.size());exit(-1);}
00107   return size_polygon[k_polygon];
00108 }
00109 
00110 
00111 
00112 
00113 int Connectivity::get_index_triangulated(int k_index) const
00114 {
00115   if(k_index<0 || k_index>=int(triangulated_index.size()))
00116     {printf("Error in get_index_triangulated in Connectivity, k_index[%d] with size[%d]\n",k_index,triangulated_index.size());exit(-1);}
00117   return triangulated_index[k_index];
00118 }
00119 int& Connectivity::get_index_triangulated(int k_index)
00120 {
00121   if(k_index<0 || k_index>=int(triangulated_index.size()))
00122     {printf("Error in get_index_triangulated in Connectivity, k_index[%d] with size[%d]\n",k_index,triangulated_index.size());exit(-1);}
00123   return triangulated_index[k_index];
00124 }
00125 int Connectivity::get_index_triangulated(int k_triangle,int k_index) const
00126 {
00127   if(k_triangle<0 || 3*k_triangle+2>=int(triangulated_index.size()))
00128     {printf("Error in get_index_triangulated in Connectivity, k_triangle[%d] with size[%d]\n",k_triangle,k_index);exit(-1);}
00129   if(k_index<0 || k_index>=3)
00130     {printf("Error in get_index_triangulated in Connectivity, k_index[%d] should be between 0 and 2\n",k_index);exit(-1);}
00131   return triangulated_index[3*k_triangle+k_index];
00132 }
00133 int& Connectivity::get_index_triangulated(int k_triangle,int k_index)
00134 {
00135  if(k_triangle<0 || 3*k_triangle+2>=int(triangulated_index.size()))
00136     {printf("Error in get_index_triangulated in Connectivity, k_triangle[%d] with size[%d]\n",k_triangle,k_index);exit(-1);}
00137   if(k_index<0 || k_index>=3)
00138     {printf("Error in get_index_triangulated in Connectivity, k_index[%d] should be between 0 and 2\n",k_index);exit(-1);}
00139   return triangulated_index[3*k_triangle+k_index];
00140 }
00141 const int* Connectivity::get_index_triangulated() const
00142 {return &triangulated_index[0];}
00143 int Connectivity::get_triangle_number() const
00144 {
00145   if(triangulated_index.size()%3!=0)
00146     {printf("Error size of triangulated_index [%d] is not multiple of 3\n",triangulated_index.size());exit(-1);}
00147   return triangulated_index.size()/3;
00148 }
00149 
00150 
00151 
00152 
00153 int Connectivity::build_size_and_polygon_access()
00154 {
00155   int k_index=0,N_index=size_index();
00156   int current_size=0,k_polygon=0;
00157 
00158   size_polygon.resize(0);
00159   polygon_access.resize(0);
00160 
00161   //the first polygon start at index 0
00162   polygon_access.push_back(0);
00163   for(k_index=0;k_index<N_index;k_index++)
00164     {
00165       if(index_polygon[k_index]==-1)
00166         {
00167           if(current_size<2)
00168             {printf("Error in build_size_and_polygon_access in Connectivity, polygon_size[%d] is less than 2 at index[%d]\n",current_size,k_index);exit(-1);}
00169           size_polygon.push_back(current_size);
00170           current_size=0;
00171           k_polygon++;
00172         }
00173       else
00174         current_size++;
00175       if(k_index>0 && index_polygon[k_index-1]==-1)
00176         polygon_access.push_back(k_index);
00177 
00178     }
00179   if(index_polygon[N_index-1]!=-1)
00180     {printf("Error index_polygon of size(%d) does not end with -1 [%d]\n",index_polygon.size(),index_polygon[N_index-1]);exit(-1);}
00181   return 0;
00182 }
00183 
00184 int Connectivity::build_triangulated_index()
00185 {
00186   triangulated_index.resize(0);
00187   int k_index=0,N_index;
00188   int k_polygon=0,N_polygon=polygon_number();
00189 
00190   int index0,index1,index2;
00191   for(k_polygon=0;k_polygon<N_polygon;k_polygon++)
00192     {
00193       N_index=polygon_size(k_polygon);
00194       index0=get_index(k_polygon,0);
00195       index1=get_index(k_polygon,1);
00196       for(k_index=2;k_index<N_index;k_index++)
00197         {
00198           index2=get_index(k_polygon,k_index);
00199           
00200           //add the current triangle
00201           triangulated_index.push_back(index0);
00202           triangulated_index.push_back(index1);
00203           triangulated_index.push_back(index2);
00204 
00205           //reorganize the current triangle
00206           //do triangle strip
00207           index1=index2;
00208         }
00209       
00210     }
00211   return 0;
00212 }
00213 
00214 int Connectivity::find_max_index()
00215 {
00216   max_index=-2;
00217   int k_index=0,N_index=size_index();
00218   for(k_index=0;k_index<N_index;k_index++)
00219     if(max_index<get_index(k_index))
00220       max_index=get_index(k_index);
00221   return 0;
00222 }
00223 
00224 int Connectivity::build_all_index()
00225 {
00226   int ok=0;
00227   ok += build_size_and_polygon_access();
00228   ok += build_triangulated_index();
00229   ok += find_max_index();
00230   ok += build_one_ring();
00231   return ok;
00232 }
00233 
00234 
00235 int Connectivity::add_polygon(int index_0,int index_1,int index_2)
00236 {
00237   std::vector <int> polygon;
00238   polygon.push_back(index_0);
00239   polygon.push_back(index_1);
00240   polygon.push_back(index_2);
00241   return add_polygon(polygon);
00242 }
00243 int Connectivity::add_polygon(int index_0,int index_1,int index_2,int index_3)
00244 {
00245   std::vector <int> polygon;
00246   polygon.push_back(index_0);
00247   polygon.push_back(index_1);
00248   polygon.push_back(index_2);
00249   polygon.push_back(index_3);
00250   return add_polygon(polygon);
00251 }
00252 int Connectivity::add_polygon(const std::vector <int>& polygon)
00253 {
00254   int current_size=polygon.size();
00255   if(current_size<3)
00256     {printf("Error polygon size [%d] in add_polygon<3\n",current_size);exit(-1);}
00257 
00258 
00259   //test if the given polygon is correct
00260   int N_poly=polygon.size();
00261   std::vector <int> sorted_poly=polygon;
00262   std::sort(sorted_poly.begin(),sorted_poly.end());
00263   for(int k=0;k<N_poly-1;k++)
00264     if(sorted_poly[k]==sorted_poly[k+1])
00265       {printf("Error polygon given in add_polygon in Connectivity is not correct, two index are the same=degenerated polygon [%d]\n",sorted_poly[k]);}
00266 
00267 
00268 
00269 
00270   int k=0;
00271   for(k=0;k<current_size;k++)
00272     index_polygon.push_back(polygon[k]);
00273 
00274   //add the final -1
00275   index_polygon.push_back(-1);
00276   
00277   return 0;
00278 }
00279 
00280 int Connectivity::add_index(int index)
00281 {
00282   index_polygon.push_back(index);
00283   return 0;
00284 }
00285 
00286 int Connectivity::set_polygon(int k_polygon,const std::vector <int>& polygon)
00287 {
00288 
00289   if(k_polygon<0 || k_polygon>=int(polygon_access.size()))
00290     {printf("Error k_polygon[%d] is not correct in set_polygon in Connectivity (number of polygon: %d)\n",k_polygon,polygon_access.size());exit(-1);}
00291 
00292 
00293   std::vector <int> index_polygon_2;
00294   int k_access0=0;k_access0=polygon_access[k_polygon];
00295   int k_access1=-1;if(k_polygon<int(polygon_access.size())-1){k_access1=polygon_access[k_polygon+1];}
00296   int k_index=0;
00297 
00298   //copy of the first part of the polygon
00299   for(k_index=0;k_index<k_access0;k_index++)
00300     index_polygon_2.push_back(index_polygon[k_index]);
00301 
00302   //then replace the polygon
00303   int N_polygon=0;N_polygon=polygon.size();
00304   if(N_polygon<3){printf("Error polygon size [%d] is <3 in set_polygon(%d) in Connectivity\n",N_polygon,k_polygon);exit(-1);}
00305   for(k_index=0;k_index<N_polygon;k_index++)
00306     index_polygon_2.push_back(polygon[k_index]);
00307   //add the final -1
00308   index_polygon_2.push_back(-1);
00309 
00310   //finally add the other one
00311   if(k_access1!=-1)
00312     {
00313       for(k_index=k_access1;k_index<int(index_polygon.size());k_index++)
00314         index_polygon_2.push_back(index_polygon[k_index]);
00315     }
00316 
00317   //then copy
00318   index_polygon=index_polygon_2;
00319 
00320   //recalculate everything
00321   build_all_index();
00322 
00323   return 0;
00324 }
00325 
00326 
00327 int Connectivity::set_index(int k_polygon,int k_index,int index)
00328 {
00329 
00330   if(k_polygon<0 || k_polygon>=int(polygon_access.size()))
00331     {printf("Error k_polygon[%d] is not correct in set_index in Connectivity (number of polygon: %d)\n",k_polygon,polygon_access.size());exit(-1);}
00332 
00333   if(k_index<0 || k_index>=polygon_size(k_polygon))
00334     {printf("Error k_index[%d] is not correct with size[%d] of polygon[%d]\n",k_index,polygon_size(k_polygon),k_polygon);exit(-1);}
00335 
00336   int current_index=polygon_access[k_polygon]+k_index;
00337   index_polygon[current_index]=index;
00338   return 0;
00339 }
00340 
00341 
00342 int Connectivity::delete_polygon(int k_polygon)
00343 {
00344   if(k_polygon<0 || k_polygon>=int(polygon_access.size()))
00345     {printf("Error k_polygon[%d] is not correct in set_index in Connectivity (number of polygon: %d)\n",k_polygon,polygon_access.size());exit(-1);}
00346 
00347   int k_access0=polygon_access[k_polygon];
00348   int k_access1=-1;if(k_polygon<int(polygon_access.size())-1){k_access1=polygon_access[k_polygon+1];}
00349   int k_index=0;
00350 
00351   //copy until reach the polygon
00352   std::vector <int> index_polygon_2;
00353   for(k_index=0;k_index<k_access0;k_index++)
00354     index_polygon_2.push_back(index_polygon[k_index]);
00355   
00356   //copy the last part
00357   if(k_access1!=-1)
00358     {
00359       for(k_index=k_access1;k_index<int(index_polygon.size());k_index++)
00360         index_polygon_2.push_back(index_polygon[k_index]);
00361     }
00362   
00363   //copy
00364   index_polygon=index_polygon_2;
00365 
00366   //rebuild_index
00367   build_all_index();
00368 
00369   return 0;
00370 }
00371 
00372 int Connectivity::delete_given_polygon(const std::vector <int> polygon)
00373 {
00374   int k_poly_to_delete=find_polygon(polygon);
00375   if(k_poly_to_delete!=-1)
00376     return delete_polygon(k_poly_to_delete);
00377 
00378   //did not find the polygon
00379   return -1;
00380 }
00381 
00382 
00383 
00384 
00385 
00386 
00387 
00388 int Connectivity::load_off_file(const char* filename)
00389 {std::string file=filename;return load_off_file(file);}
00390 int Connectivity::load_off_file(const std::string& filename)
00391 {
00392   destroy();
00393 
00394   #define SIZE_BUFFER 2048
00395   char buffer[SIZE_BUFFER]={'\0'};
00396 
00397   FILE *fid=NULL;
00398   fid=fopen(filename.data(),"r");
00399   if(fid==NULL)
00400     {printf("ERROR loading %s in load_off_file in Connectivity\n",filename.data());exit(-1);}
00401 
00402 
00403   //find OFF or NOFF
00404   while(strcmp(buffer,"OFF")!=0 && strcmp(buffer,"NOFF")!=0)
00405     {
00406       if(fscanf(fid,"%s",buffer)==EOF)
00407         {printf("ERROR file %s is not off file\n",filename.data());exit(-1);}
00408       if(buffer[0]=='#')//comments
00409         fgets(buffer,sizeof(buffer),fid);
00410     }
00411 
00412   //pass comments
00413   fscanf(fid,"%s",buffer);
00414   while(buffer[0]=='#')//comments
00415     {
00416       fgets(buffer,sizeof(buffer),fid);
00417       fscanf(fid,"%s",buffer);
00418     }
00419 
00420   //read Number of polygon
00421   int N_vertex=0,N_polygon=0;
00422   N_vertex=atoi(buffer);//N_vertex
00423   fscanf(fid,"%d",&N_polygon);//N_polygon
00424   fgets(buffer,sizeof(buffer),fid);//read line
00425 
00426   //read vertices
00427   int k_vertex=0;
00428   for(k_vertex=0;k_vertex<N_vertex;k_vertex++)
00429     {
00430       fgets(buffer,sizeof(buffer),fid);//read line
00431       if(buffer[0]=='#')//comments does not count in vertices number
00432         k_vertex--;
00433     }
00434 
00435   //read polygon
00436   int size_poly=0;
00437   int k_polygon=0;
00438   int k_current_polygon=0;
00439   int temp=0;
00440   std::vector <int> v_poly;
00441   for(k_polygon=0;k_polygon<N_polygon;k_polygon++)
00442     {
00443        if(fscanf(fid,"%d",&size_poly)!=1)
00444         {
00445           fscanf(fid,"%s",buffer);
00446           if(buffer[0]!='#')
00447             {printf("ERROR loading polygons in load_off_file %s in Connectivity\n",filename.data());exit(-1);}
00448           else//read line
00449             {
00450               fgets(buffer,sizeof(buffer),fid);
00451               k_polygon--;
00452             }
00453         }
00454       else
00455         {
00456           v_poly.resize(0);
00457           for(k_current_polygon=0;k_current_polygon<size_poly;k_current_polygon++)
00458             {
00459               fscanf(fid,"%d",&temp);
00460               v_poly.push_back(temp);
00461             }
00462           add_polygon(v_poly);
00463         }
00464     }
00465     
00466   if(fclose(fid)!=0)
00467     {printf("ERROR closing %s in load_off_file in Connectivity\n",filename.data());exit(-1);}
00468 
00469 
00470   //build the index
00471   build_all_index();
00472 
00473   return 0;
00474 }
00475 
00476 int Connectivity::write_off_type(const char* filename) const
00477 {std::string file=filename;return write_off_type(file);}
00478 
00479 int Connectivity::write_off_type(const std::string& filename) const
00480 {
00481   FILE *fid=NULL;
00482   fid=fopen(filename.data(),"a");
00483   if(fid==NULL)
00484     {printf("ERROR loading %s in write_off_type in Connectivity\n",filename.data());exit(-1);}
00485 
00486   int k_polygon=0,N_polygon=polygon_number();
00487   int current_size=0,k_index;
00488   for(k_polygon=0;k_polygon<N_polygon;k_polygon++)
00489     {
00490       current_size=polygon_size(k_polygon);
00491 
00492       //write the size of the polygon
00493       fprintf(fid,"%d ",current_size);
00494       //read the polygon
00495       for(k_index=0;k_index<current_size;k_index++)
00496         fprintf(fid,"%d ",get_index(k_polygon,k_index));
00497       fprintf(fid,"\n");
00498     }
00499 
00500   if(fclose(fid)!=0)
00501     {printf("ERROR closing %s in write_off_type in Connectivity\n",filename.data());exit(-1);}
00502 
00503   return 0;
00504 
00505 }
00506 
00507 
00508 
00509 
00510 
00511 
00512 int Connectivity::export_visible_off(const char* filename,const Point_set& set) const
00513 {std::string file=filename;return export_visible_off(file,set);}
00514 int Connectivity::export_visible_off(const std::string& filename,const Point_set& set) const
00515 {
00516 
00517   FILE *fid=NULL;
00518   fid=fopen(filename.data(),"w");
00519   if(fid==NULL)
00520     {printf("ERROR loading %s in export_visible_off in Connectivity\n",filename.data());exit(-1);}
00521 
00522 
00523 
00524   // HEADER
00525   fprintf(fid,"# VISIBLE OFF SCENE CONNECTIVITY\n");
00526   fprintf(fid,"OFF\n");
00527   fprintf(fid,"%d %d 0\n",set.size(),polygon_number());
00528 
00529   if(fclose(fid)!=0)
00530     {printf("ERROR closing %s in export_visible_off in Connectivity\n",filename.data());exit(-1);}
00531   fid=NULL;
00532 
00533 
00534   // export vertex
00535   set.write_off_type(filename);
00536 
00537   // export connectivity
00538   write_off_type(filename);
00539 
00540 
00541   //write EOF
00542   fid=fopen(filename.data(),"a");
00543   if(fid==NULL)
00544     {printf("ERROR loading %s in export_visible_off in Connectivity\n",filename.data());exit(-1);}
00545   fprintf(fid,"#EOF [OK] %s\n",filename.data());
00546   if(fclose(fid)!=0)
00547     {printf("ERROR closing %s in export_visible_off in Connectivity\n",filename.data());exit(-1);}
00548   fid=NULL;
00549 
00550   return 0;
00551 }
00552 
00553 
00554 
00555 
00556 
00557 int Connectivity::operator()(int k_index) const
00558 {
00559   if(k_index<0 || k_index>=size_index())
00560     {printf("Error in operator()(%d) with size %d in Connectivity\n",k_index,size_index());exit(-1);}
00561   return index_polygon[k_index];
00562 }
00563 int Connectivity::operator[](int k_index) const
00564 {
00565   if(k_index<0 || k_index>=size_index())
00566     {printf("Error in operator[](%d) with size %d in Connectivity\n",k_index,size_index());exit(-1);}
00567   return index_polygon[k_index];
00568 }
00569 int& Connectivity::operator()(int k_index)
00570 {
00571   if(k_index<0 || k_index>=size_index())
00572     {printf("Error in operator()(%d) with size %d in Connectivity\n",k_index,size_index());exit(-1);}
00573   return index_polygon[k_index];
00574 }
00575 int& Connectivity::operator[](int k_index)
00576 {
00577   if(k_index<0 || k_index>=size_index())
00578     {printf("Error in operator[](%d) with size %d in Connectivity\n",k_index,size_index());exit(-1);}
00579   return index_polygon[k_index];
00580 }
00581 int Connectivity::operator()(int k_polygon,int k_index) const
00582 {
00583   if(k_polygon<0 || k_polygon>=polygon_number())
00584     {printf("Error in operator(), k_polygon(%d) is not correct with size %d in Connectivity\n",k_polygon,polygon_number());exit(-1);}
00585   if(k_index<0 || k_index>=polygon_size(k_polygon))
00586     {printf("Error in operator(), k_index(%d) is not correct for polygon %d in Connectivity. This polygon has size=%d\n",k_index,k_polygon,polygon_size(k_polygon));exit(-1);}
00587     return index_polygon[polygon_access[k_polygon]+k_index];
00588 }
00589 int& Connectivity::operator()(int k_polygon,int k_index)
00590 {
00591   if(k_polygon<0 || k_polygon>=polygon_number())
00592     {printf("Error in operator(), k_polygon(%d) is not correct with size %d in Connectivity\n",k_polygon,polygon_number());exit(-1);}
00593   if(k_index<0 || k_index>=polygon_size(k_polygon))
00594     {printf("Error in operator(), k_index(%d) is not correct for polygon %d in Connectivity. This polygon has size=%d\n",k_index,k_polygon,polygon_size(k_polygon));exit(-1);}
00595     return index_polygon[polygon_access[k_polygon]+k_index];
00596 }
00597 
00598 
00599 int Connectivity::find_polygon(const std::vector <int>& polygon) const
00600 {
00601   int N_poly=polygon.size();
00602   
00603   //test if the given polygon is correct
00604   std::vector <int> sorted_poly=polygon;
00605   std::sort(sorted_poly.begin(),sorted_poly.end());
00606   for(int k=0;k<N_poly-1;k++)
00607     if(sorted_poly[k]==sorted_poly[k+1])
00608       {printf("Error polygon given in find_polygon in Connectivity is not correct, two index are the same=degenerated polygon [%d]\n",sorted_poly[k]);exit(-1);}
00609   
00610   int N_polygon=polygon_number();
00611   std::vector <int> compared_polygon;
00612   int k_polygon=0;
00613   int count=0,k_poly=0,k_to_compare=0;
00614 
00615   //loop on every polygon of the mesh
00616   for(k_polygon=0;k_polygon<N_polygon;k_polygon++)
00617     {
00618       //get polygon to compare
00619       compared_polygon=get_index_of_polygon(k_polygon);
00620 
00621 
00622       count=0;
00623       //test if size are equal
00624       if(N_poly==int(compared_polygon.size()))
00625         {
00626           //test for every index of the given polygon
00627           for(k_poly=0;k_poly<N_poly;k_poly++)
00628             //test for every index of the current compared polygon
00629             for(k_to_compare=0;k_to_compare<int(compared_polygon.size());k_to_compare++)
00630               //if one index is the same
00631               if(polygon[k_poly]==compared_polygon[k_to_compare])
00632                 count++;
00633         }
00634       if(count==N_poly)//find the polygon
00635         return k_polygon;
00636     }
00637   return -1;
00638 }
00639 
00640 
00641 const Connectivity& Connectivity::operator=(const Connectivity& c)
00642 {
00643   index_polygon      = c.index_polygon;
00644   size_polygon       = c.size_polygon;
00645   polygon_access     = c.polygon_access;
00646   triangulated_index = c.triangulated_index;
00647   edges              = c.edges;
00648   one_ring           = c.one_ring;
00649   polygon_ring       = c.polygon_ring;
00650 
00651   return (*this);
00652 }
00653 
00654 Connectivity operator+(const Connectivity& c1,const Connectivity& c2)
00655 {
00656   Connectivity c;
00657   int N_polygon=0;
00658   int k_polygon=0;
00659 
00660   N_polygon=c1.polygon_number();
00661   for(k_polygon=0;k_polygon<N_polygon;k_polygon++)
00662     c.add_polygon(c1.get_index_of_polygon(k_polygon));
00663 
00664   N_polygon=c2.polygon_number();
00665   for(k_polygon=0;k_polygon<N_polygon;k_polygon++)
00666     c.add_polygon(c2.get_index_of_polygon(k_polygon));
00667 
00668   c.build_all_index();
00669 
00670   return c;
00671 }
00672 
00673 Connectivity operator+(const Connectivity& _c,const std::vector<int> & v)
00674 {
00675   Connectivity c;
00676 
00677   int N_polygon=0;
00678   int k_polygon=0;
00679 
00680   N_polygon=_c.polygon_number();
00681   for(k_polygon=0;k_polygon<N_polygon;k_polygon++)
00682     c.add_polygon(_c.get_index_of_polygon(k_polygon));
00683 
00684   c.add_polygon(v);
00685   c.build_all_index();
00686 
00687   return c;
00688 }
00689 
00690 
00691 Connectivity operator+(const std::vector<int> & v,const Connectivity& _c)
00692 {
00693   Connectivity c;
00694   c = _c+v;
00695   return c;
00696 }
00697 
00698 
00699 Connectivity operator-(const Connectivity& c1,const Connectivity& c2)
00700 {
00701   Connectivity c;
00702   c=c1;
00703 
00704   int k=0;
00705   int N_polygon=c2.polygon_number();
00706   for(k=0;k<N_polygon;k++)
00707     c.delete_given_polygon(c2.get_index_of_polygon(k));
00708   
00709   return c;
00710 }
00711 
00712 Connectivity operator-(const Connectivity& c1,const std::vector<int>& c2)
00713 {
00714   Connectivity c=c1;
00715   c.delete_given_polygon(c2);
00716   return c;
00717 }
00718 
00719 
00720 bool operator==(const Connectivity& c1,const Connectivity& c2)
00721 {
00722 
00723   //must have same dimension first
00724   if(c1.polygon_number()!=c2.polygon_number())
00725     return 0;
00726 
00727   int k_polygon=0;
00728   int N_polygon=c1.polygon_number();
00729   int k_vertex=0,N_vertex=0;
00730   for(k_polygon=0;k_polygon<N_polygon;k_polygon++)
00731     {
00732       if(c1.polygon_size(k_polygon)!=c2.polygon_size(k_polygon))
00733         return 0;
00734 
00735       N_vertex=c1.polygon_size(k_polygon);
00736       for(k_vertex=0;k_vertex<N_vertex;k_vertex++)
00737         if(c1(k_polygon,k_vertex)!=c2(k_polygon,k_vertex))
00738           return 0;
00739     }
00740   return 1;
00741 }
00742 
00743 bool operator!=(const Connectivity& c1,const Connectivity& c2){return !(c1==c2);}
00744 
00745 ostream& operator << (ostream& flux,const Connectivity& c)
00746 {
00747   int k_polygon=0,N_polygon=c.polygon_number();
00748   int k_vertex=0,N_vertex=0;
00749   for(k_polygon=0;k_polygon<N_polygon;k_polygon++)
00750     {
00751       N_vertex=c.polygon_size(k_polygon);
00752       flux<<N_vertex<<" [";
00753       for(k_vertex=0;k_vertex<N_vertex-1;k_vertex++)
00754         cout<<c(k_polygon,k_vertex)<<",";
00755       cout<<c(k_polygon,N_vertex-1)<<"]"<<endl;
00756     }
00757 
00758   return flux;
00759 }
00760 
00761 
00762 Edge Connectivity::get_edge(int k_index) const
00763 {
00764   if(k_index<0 || k_index>=int(edges.size()))
00765     {printf("Error in get_edge[%d] in Connectivity, size=[%d]\n",k_index,edges.size());exit(-1);}
00766   return edges[k_index];
00767 }
00768 
00769 Edge Connectivity::get_edge(int k_polygon,int k_edge) const
00770 {
00771 
00772   if(k_polygon<0 || k_polygon>=polygon_number())
00773     {printf("Error get_edges[%d,%d] in Connectivity, polygon_number=[%d]\n",k_polygon,k_edge,polygon_number());exit(-1);}
00774   if(k_edge<0 || k_edge>=polygon_size(k_polygon))
00775     {printf("Error get_edges[%d,%d] in Connectivity, polygon_size(%d)=%d\n",k_polygon,k_edge,polygon_number(),polygon_size(k_polygon));exit(-1);}
00776   
00777   int k_access = polygon_access[k_polygon];
00778   if(k_access<0 || k_access+k_edge>=int(index_edges.size()))
00779     {printf("k_access+k_edge %d+%d is not correct in get_edges(%d,%d) in Connectivity, index_edges.size()=%d, might not be initialized\n",k_access,k_edge,k_polygon,k_edge,index_edges.size());exit(-1);}
00780   
00781 
00782   int k_index_edge = index_edges[k_access+k_edge];
00783   if(k_index_edge<0 || k_index_edge>=int(edges.size()))
00784     {printf("index_edge[%d]=%d is not correct with edges.size()=%d in get_edges(%d,%d) in Connectivity \n",k_access,k_index_edge,edges.size(),k_polygon,k_edge);exit(-1);}
00785 
00786 
00787 
00788   //return edges[index_edges[polygon_access[k_polygon]+k_edge]];
00789   return edges[k_index_edge];
00790 
00791 }
00792 
00793 
00794 int Connectivity::build_edges()
00795 {
00796 
00797   //destroy edges;
00798   edges        . resize(0);
00799   index_edges  . resize(0);
00800   edges_access . resize(0);
00801 
00802   int k_polygon=0;
00803   int N_polygon=polygon_number();
00804   int k_vertex=0;
00805   int N_vertex=0;
00806 
00807   int edge_index=0;
00808 
00809   int ind[2];
00810 
00811   //******************************//
00812   //Fill the vertex index of the edges
00813   //******************************//
00814   for(k_polygon=0;k_polygon<N_polygon;k_polygon++)
00815     {
00816       N_vertex=polygon_size(k_polygon);
00817       for(k_vertex=0;k_vertex<N_vertex;k_vertex++)
00818         {
00819 
00820 
00821           //get index line
00822           ind[0]=get_index(k_polygon,k_vertex);
00823           ind[1]=get_index(k_polygon,(k_vertex+1)%N_vertex);
00824 
00825           
00826 
00827           //try to find if [ind[1]-ind[2]] has already been declared
00828           if(find_current_edge_slow(ind[0],ind[1])!=-1)//not a manifold mesh
00829             {printf("Warning, edge [%d,%d] is duplicated, not a manifold mesh\n",ind[0],ind[1]);return -1;}
00830 
00831           //****************//    
00832           //add the edge
00833           //****************//
00834           
00835           //add the index_edges pointer
00836           index_edges.push_back(edges.size());
00837           
00838           //set the vertex index and the first face
00839           Edge e;
00840           e.set_index(ind[0],ind[1]);
00841           e.set_face_0(k_polygon);
00842           edges.push_back(e);
00843 
00844           edge_index = find_current_edge_slow(ind[1],ind[0]);
00845           if(edge_index!=-1)//the first face is already set-up
00846             {
00847               if(edge_index<0 || edge_index>=int(edges.size()))
00848                 {printf("Error in build index, something wrong in polygon %d\n",k_polygon);exit(-1);}
00849 
00850               //set the opposite face
00851               edges[edge_index]     . set_face_1(k_polygon);
00852               edges[edges.size()-1] . set_face_1(edges[edge_index].get_face_0());
00853 
00854               //set the half edge
00855               edges[edges.size()-1].set_half_edge(edge_index);
00856               edges[edge_index].set_half_edge(edges.size()-1);
00857             }
00858 
00859 
00860         }
00861       //add separator in index_edges
00862       index_edges.push_back(-1);
00863     }
00864 
00865 
00866   //******************************//
00867   // now set the edges link
00868   //******************************//
00869   int ind_next[2]={0,0};
00870   int ind_previous[2]={0,0};
00871   Edge current_e;
00872   int index_next_e=0,index_previous_e=0;
00873   for(k_polygon=0;k_polygon<N_polygon;k_polygon++)
00874     {
00875       N_vertex=polygon_size(k_polygon);
00876       for(k_vertex=0;k_vertex<N_vertex;k_vertex++)
00877         {
00878 
00879           //current index
00880           ind[0] = get_index(k_polygon,k_vertex);
00881           ind[1] = get_index(k_polygon,(k_vertex+1)%N_vertex);
00882 
00883           //next index
00884           ind_next[0] = get_index(k_polygon,(k_vertex+1)%N_vertex);
00885           ind_next[1] = get_index(k_polygon,(k_vertex+2)%N_vertex);
00886 
00887           //previous index
00888           ind_previous[0] = get_index(k_polygon,(k_vertex-1<0?N_vertex-1:k_vertex-1));
00889           ind_previous[1] = get_index(k_polygon,k_vertex);
00890 
00891           //current edge
00892           current_e  = get_edge(k_polygon,k_vertex);
00893           //get and set next and previous edges
00894           index_next_e     = find_current_edge_slow(ind_next[0],ind_next[1]);
00895           index_previous_e = find_current_edge_slow(ind_previous[0],ind_previous[1]);
00896 
00897 
00898           if(index_next_e==-1 || index_previous_e==-1){printf("Error in build_edge part 2, index are = -1\n");exit(-1);}
00899           if(index_next_e==-1 || index_previous_e==-1){printf("Error in build_edge part 2\n");exit(-1);}
00900 
00901 
00902 
00903 
00904           current_e.set_next_edge(index_next_e);
00905           current_e.set_previous_edge(index_previous_e);
00906           set_edge(k_polygon,k_vertex,current_e);
00907 
00908           //printf("(%d,%d)->%d,(%d,%d)->%d,(%d,%d)->%d (h%d)\n",ind[0],ind[1],index_edges[polygon_access[k_polygon]+k_vertex],ind_previous[0],ind_previous[1],index_previous_e,ind_next[0],ind_next[1],index_next_e,current_e.get_half_edge());
00909           //cout<<current_e<<endl;
00910 
00911         }
00912     }
00913   
00914 
00915 
00916   //******************************//
00917   // now build direct access to edges
00918   //******************************//
00919 
00920   N_vertex=vertex_number();
00921   edges_access.resize(N_vertex);
00922   int k_edge=0,N_edge=edge_number();
00923   Edge e;
00924   for(k_edge=0;k_edge<N_edge;k_edge++)
00925     {
00926       e = get_edge(k_edge);
00927       if(e.get_index_0()<0 || e.get_index_0()>=N_vertex || e.get_index_1()<0|| e.get_index_1()>=N_vertex)
00928         {printf("Error in build direct access in build_edge()\n");}
00929       edges_access[e.get_index_0()].add(k_edge);
00930     }
00931 
00932 
00933 
00934   return 0;
00935 }
00936 
00937 
00938 
00939 int Connectivity::find_current_edge_slow(int vertex_index_0,int vertex_index_1)
00940 {
00941   int N_edge=edges.size();
00942   int k_edge=0;
00943   Edge e;
00944   for(k_edge=0;k_edge<N_edge;k_edge++)
00945     {
00946       e=get_edge(k_edge);
00947       //find vertex (in the right order)
00948       if(vertex_index_0==e.get_index_0() && vertex_index_1==e.get_index_1())
00949         return k_edge;
00950     }
00951   //did not find
00952   return -1;
00953 
00954 }
00955 
00956 std::vector <int> Connectivity::find_all_current_edge_slow(int vertex_index_0,int vertex_index_1)
00957 {
00958   std::vector <int> found_edges;
00959   int N_edge=edges.size();
00960   int k_edge=0;
00961   Edge e;
00962   for(k_edge=0;k_edge<N_edge;k_edge++)
00963     {
00964       e=get_edge(k_edge);
00965       //find vertex (in the right order)
00966       if(vertex_index_0==e.get_index_0() && vertex_index_1==e.get_index_1())
00967         found_edges.push_back(k_edge);
00968     }
00969   //did not find
00970   return found_edges;
00971 }
00972 
00973 
00974 
00975 Edge Connectivity::get_edge_segment(int index_vertex_0,int index_vertex_1) const
00976 {
00977   int N_vertex=edges_access.size();
00978   if(index_vertex_0<0 || index_vertex_0>=N_vertex || index_vertex_1<0 || index_vertex_1>=N_vertex)
00979     {printf("Error in get_edge_segment(%d,%d) in Connectivity edges_access.size()=%d\n",index_vertex_0,index_vertex_1,N_vertex);exit(-1);}
00980   
00981   int N_one_ring = edges_access[index_vertex_0].size();
00982   int k_one_ring=0;
00983 
00984 
00985 
00986   //look for index_vertex_2 in the one ring of the index_vertex_0
00987   Edge e;
00988   for(k_one_ring=0;k_one_ring<N_one_ring;k_one_ring++)
00989     {
00990       e = get_edge(edges_access[index_vertex_0][k_one_ring]);
00991 
00992       //edge is in the right order
00993       if(e.get_index_1()==index_vertex_1)
00994         {
00995           if(e.get_index_0()!=index_vertex_0){printf("Error in edge access in get_edge_segment in Connectivity\n");exit(-1);}
00996           return e;
00997         }
00998 
00999       //edge is in the opposite order
01000       else if(e.get_index_0()==index_vertex_1)
01001         {
01002           if(e.get_index_1()!=index_vertex_0){printf("Error in edge access in get_edge_segment in Connectivity\n");exit(-1);}
01003           return e;
01004         }
01005       
01006     }
01007   
01008   //if not found
01009   Edge o;
01010   return o;
01011     
01012 }
01013 
01014 int Connectivity::edge_number() const{return edges.size();}
01015 
01016 int Connectivity::vertex_number() const{return max_index+1;}
01017 
01018 
01019 int Connectivity::set_edge(int k_index,const Edge& e)
01020 {
01021   if(k_index<0 || k_index>=int(edges.size()))
01022     {printf("Error in set_edge[%d] in Connectivity, size=[%d]\n",k_index,edges.size());exit(-1);}
01023   edges[k_index]=e;
01024   return 0;
01025 }
01026 
01027 int Connectivity::set_edge(int k_polygon,int k_edge,const Edge& e)
01028 {
01029   if(k_polygon<0 || k_polygon>=polygon_number())
01030     {printf("Error set_edges[%d,%d] in Connectivity, polygon_number=[%d]\n",k_polygon,k_edge,polygon_number());exit(-1);}
01031   if(k_edge<0 || k_edge>=polygon_size(k_polygon))
01032     {printf("Error set_edges[%d,%d] in Connectivity, polygon_size(%d)=%d\n",k_polygon,k_edge,polygon_number(),polygon_size(k_polygon));exit(-1);}
01033   
01034   int k_access = polygon_access[k_polygon];
01035   if(k_access<0 || k_access+k_edge>=int(index_edges.size()))
01036     {printf("k_access+k_edge %d+%d is not correct in set_edges(%d,%d) in Connectivity, index_edges.size()=%d, might not be initialized\n",k_access,k_edge,k_polygon,k_edge,index_edges.size());exit(-1);}
01037   
01038   int k_index_edge = index_edges[k_access+k_edge];
01039   if(k_index_edge<0 || k_index_edge>=int(edges.size()))
01040     {printf("index_edge[%d]=%d is not correct with edges.size()=%d in set_edges(%d,%d) in Connectivity \n",k_access,k_index_edge,edges.size(),k_polygon,k_edge);exit(-1);}
01041 
01042   //edges[index_edges[polygon_access[k_polygon]+k_edge]];
01043   edges[k_index_edge]=e;
01044   return 0;
01045 }
01046 
01047 
01048 int Connectivity::build_one_ring()
01049 {
01050 
01051   int k_polygon=0,k_vertex=0,N_vertex=0;
01052   int k_index=0,k_index_2=0;
01053   int N_polygon=0;
01054 
01055   if(max_index<=0)
01056     {printf("Error in build_one_ring, max_index=0\n");exit(-1);}
01057 
01058   one_ring.resize(max_index+1);
01059   polygon_ring.resize(max_index+1);
01060 
01061 
01062   //loop over every vertices
01063   N_polygon=polygon_number();
01064   for(k_polygon=0;k_polygon<N_polygon;k_polygon++)
01065     {
01066       N_vertex=polygon_size(k_polygon);
01067       for(k_vertex=0;k_vertex<N_vertex;k_vertex++)
01068         {
01069           k_index = get_index(k_polygon,k_vertex);
01070 
01071           //add the following vertex
01072           k_index_2 = get_index(k_polygon,(k_vertex+1)%N_vertex);
01073           one_ring[k_index]   . add_unique(k_index_2);
01074           one_ring[k_index_2] . add_unique(k_index);
01075 
01076           //add the previous vertex       
01077           k_index_2 = get_index(k_polygon,(k_vertex-1)<0?N_vertex-1:k_vertex-1);
01078           one_ring[k_index]   . add_unique(k_index_2);
01079           one_ring[k_index_2] . add_unique(k_index);
01080 
01081           // add the polygon_ring
01082           polygon_ring[k_index].add_unique(k_polygon);
01083         }
01084 
01085 
01086     }    
01087 
01088   
01089   return 0;
01090 }
01091 
01092 int_vector Connectivity::get_one_ring(int k_polygon,int k_edge) const
01093 {
01094   int k_index = get_index(k_polygon,k_edge);
01095   if(k_index<0 || k_index>=int(one_ring.size()))
01096     {printf("Error in get_one_ring(%d,%d), size of one_ring=%d\n",k_polygon,k_edge,one_ring.size());exit(-1);}
01097   return one_ring[k_index];
01098 }
01099 int_vector Connectivity::get_one_ring(int k_vertex) const
01100 {
01101   if(k_vertex<0 || k_vertex>=int(one_ring.size()))
01102     {printf("Error in get_one_ring(%d), size of one_ring=%d\n",k_vertex,one_ring.size());exit(-1);}
01103   return one_ring[k_vertex];
01104 }
01105 
01106 int_vector Connectivity::get_polygon_ring(int k_polygon,int k_edge) const
01107 {
01108   int k_index = get_index(k_polygon,k_edge);
01109   if(k_index<0 || k_index>=int(polygon_ring.size()))
01110     {printf("Error in get_polygon_ring(%d,%d), size of polygon_ring=%d\n",k_polygon,k_edge,polygon_ring.size());exit(-1);}
01111   return polygon_ring[k_index];
01112 }
01113 int_vector Connectivity::get_polygon_ring(int k_vertex) const
01114 {
01115   if(k_vertex<0 || k_vertex>=int(polygon_ring.size()))
01116     {printf("Error in get_polygon_ring(%d), size of polygon_ring=%d\n",k_vertex,polygon_ring.size());exit(-1);}
01117   return polygon_ring[k_vertex];
01118 }
01119 
01120 
01121 int Connectivity::build_manifold()
01122 {
01123 
01124   int N_polygon=polygon_number();
01125   std::vector <int> correct_polygon(N_polygon);
01126 
01127   int end_loop=0;
01128   int k=0;
01129   int first_polygon_not_correct=0;
01130 
01131   //redo the entire loop in the case where there is connected parts
01132   do
01133     {
01134 
01135       //find the find index not correct (should be runed as much as there is non-connected parts
01136       first_polygon_not_correct=-1;
01137       k=0;
01138       do
01139         {
01140           if(correct_polygon[k]==0)
01141             first_polygon_not_correct=k;
01142           k++;
01143         }while((k<N_polygon) && (correct_polygon[k-1]==1));
01144 
01145       if(first_polygon_not_correct!=-1)
01146         {
01147           //suppose this first_polygon is true and go ahead
01148           correct_polygon[first_polygon_not_correct]=1;
01149           reccursive_connect_manifold_polygons(first_polygon_not_correct,&correct_polygon);
01150         }
01151 
01152       //every polygons have been passed
01153       else if((first_polygon_not_correct==-1) && (k==N_polygon))
01154         end_loop=1;
01155     }while(end_loop==0);
01156 
01157 
01158 
01159   build_edges();
01160   return 0;
01161 }
01162 
01163 
01164 int Connectivity::reccursive_connect_manifold_polygons(int current_polygon,std::vector <int>* correct_polygon)
01165 {
01166   int k_vertex_current=0;
01167   int N_vertex_current=polygon_size(current_polygon);
01168 
01169   int k_polygon=0;
01170   int N_polygon=polygon_number();
01171   int N_vertex=0;
01172   int k_vertex=0;
01173 
01174   //printf("%d/%d\n",current_polygon,N_polygon);
01175 
01176 
01177   for(k_vertex_current=0;k_vertex_current<N_vertex_current;k_vertex_current++)
01178     {
01179 
01180 
01181       //get the edge
01182       int u0=get_index(current_polygon,k_vertex_current);
01183       int u1=get_index(current_polygon,(k_vertex_current+1)%N_vertex_current);
01184       
01185       
01186       //try to find the same edge
01187       for(k_polygon=0;k_polygon<N_polygon;k_polygon++)
01188         {
01189           if((*correct_polygon)[k_polygon]==0)
01190             {
01191               N_vertex=polygon_size(k_polygon);
01192               for(k_vertex=0;k_vertex<N_vertex;k_vertex++)
01193                 {
01194                   
01195                   //if find the same edge, need to flip the polygon
01196                   if(
01197                      (u0==get_index(k_polygon,0) && u1==get_index(k_polygon,1))
01198                      ||
01199                      (u0==get_index(k_polygon,1) && u1==get_index(k_polygon,2))
01200                      ||
01201                      (u0==get_index(k_polygon,2) && u1==get_index(k_polygon,0)) )
01202                     {
01203                       flip_polygon(k_polygon);
01204                       //printf("flip [%d,%d]-[%d,%d]\n",u0,u1,current_polygon,k_polygon);
01205                       (*correct_polygon)[k_polygon]=1;
01206                       
01207                       reccursive_connect_manifold_polygons(k_polygon,correct_polygon); 
01208                     }
01209                   //if find a correct polygon already good
01210                   else if(
01211                           (u0==get_index(k_polygon,1) && u1==get_index(k_polygon,0))
01212                           ||
01213                           (u0==get_index(k_polygon,2) && u1==get_index(k_polygon,1))
01214                           ||
01215                           (u0==get_index(k_polygon,0) && u1==get_index(k_polygon,2)) )
01216                     {
01217                       //confirm it is good
01218                       (*correct_polygon)[k_polygon]=1;
01219                       reccursive_connect_manifold_polygons(k_polygon,correct_polygon);
01220                     }
01221                 }
01222             }
01223         }
01224       
01225     }
01226 
01227 
01228 
01229 //   std::vector <int> already_flipped(N_polygon);
01230 
01231 //   //******************************//
01232 //   //Loop on every edges
01233 //   //******************************//
01234 //   for(k_polygon=0;k_polygon<N_polygon;k_polygon++)
01235 //     {
01236 //       N_vertex=polygon_size(k_polygon);
01237 //       for(k_vertex=0;k_vertex<N_vertex;k_vertex++)
01238 //      {
01239 //        //get index line
01240 //        ind[0]=get_index(k_polygon,k_vertex);
01241 //        ind[1]=get_index(k_polygon,(k_vertex+1)%N_vertex);
01242 
01243 //        for(k_polygon2=k_polygon+1;k_polygon2<N_polygon;k_polygon2++)
01244 //          {
01245 //            N_vertex2=polygon_size(k_polygon2);
01246 //            for(k_vertex2=0;k_vertex2<N_vertex2;k_vertex2++)
01247 //              {
01248 //                ind2[0]=get_index(k_polygon2,k_vertex2);
01249 //                ind2[1]=get_index(k_polygon2,(k_vertex2+1)%N_vertex2);
01250 
01251 //                if(ind[0]==ind2[0] && ind[1]==ind2[1])
01252 //                  {
01253 //                    printf("[%d,%d] - flipped [%d/%d]\n",ind[0],ind[1],k_polygon,k_polygon2);
01254 
01255 //                    if(already_flipped[k_polygon2]==0)
01256 //                      {
01257 //                        flip_polygon(k_polygon2);
01258 //                        already_flipped[k_polygon2]=1;
01259 //                      }
01260 
01261 //                  }
01262 //              }
01263 //          }
01264 
01265 
01266 
01267 
01268 
01269 
01270 
01271 
01272 
01273 
01274 
01275 
01276 
01277 //        //try to find if [ind[1]-ind[2]] has already been declared
01278 //        other_polygon=find_all_current_edge_slow(ind[0],ind[1]);
01279 //        if(other_polygon.size()>1)//not a manifold mesh
01280 //          {
01281 //            printf("Find non manifold mesh [%d,%d]\n",ind[0],ind[1]);
01282 
01283 //            //printf("%d,%d,%d\n",get_index(other_polygon,0),get_index(other_polygon,1),get_index(other_polygon,2));
01284 //            if(other_polygon[0]!=k_polygon)
01285 //              flip_polygon(other_polygon[0]);
01286 //            else if(flip_polygon(other_polygon[1]!=k_polygon))
01287 //              flip_polygon(other_polygon[1]);
01288 //            //printf("%d,%d,%d\n",get_index(other_polygon,0),get_index(other_polygon,1),get_index(other_polygon,2));
01289 //            //printf("%d,%d,%d\n",get_index(k_polygon,0),get_index(k_polygon,1),get_index(k_polygon,2));
01290 
01291 //            //restart from zero
01292 //            k_vertex=N_vertex;
01293 //            k_polygon=-1;
01294 //            build_edges();
01295 
01296 
01297 //          }
01298 
01299 
01300 
01301 
01302   //rebuild the edges
01303   //build_edges();
01304 
01305   return 0;
01306 }
01307 
01308 
01309 int Connectivity::flip_polygon(int k_polygon)
01310 {
01311 
01312   if(k_polygon<0 || k_polygon>=polygon_number())
01313     {printf("Error in flip_polygon(%d), N_polygon=%d\n",k_polygon,polygon_number());exit(-1);}
01314   
01315   int index=polygon_access[k_polygon];
01316   int size_current_polygon=size_polygon[k_polygon];
01317   const std::vector <int> current_polygon=get_index_of_polygon(k_polygon);
01318   if(int(current_polygon.size())!=size_current_polygon)
01319     {printf("Error in flip_polygon, size are not correct\n");exit(-1);}
01320 
01321   index_polygon[index]=current_polygon[0];
01322   int k_size_polygon=0;
01323 
01324   for(k_size_polygon=1;k_size_polygon<size_current_polygon;k_size_polygon++)
01325     index_polygon[index+k_size_polygon]=current_polygon[size_current_polygon-k_size_polygon];//in the other direction
01326 
01327 
01328   return 0;
01329 }
01330 
01331 int Connectivity::flip_polygon()
01332 {
01333   int k=0;
01334   for(k=0;k<polygon_number();k++)
01335     flip_polygon(k);
01336   return 0;
01337 }
01338 
01339 
01340 
01341 int Connectivity::load_obj_file(const char* filename)
01342 {std::string file=filename;return load_obj_file(file);}
01343 int Connectivity::load_obj_file(const std::string& filename)
01344 {
01345   destroy();
01346 
01347 #define SIZE_BUFFER 2048
01348   char buffer[SIZE_BUFFER]={'\0'};
01349   char buffer2[SIZE_BUFFER]={'\0'};
01350 
01351   FILE *fid=NULL;
01352   fid=fopen(filename.data(),"r");
01353   if(fid==NULL)
01354     {printf("ERROR loading %s in load_obj_file in Connectivity\n",filename.data());exit(-1);}
01355 
01356 
01357   std::vector <int> poly;
01358   int cv=0;
01359   int one=-1;
01360   while(fscanf(fid,"%s",buffer)!=EOF)
01361     {
01362       switch(buffer[0])
01363         {
01364         case 'f': //polygon faces
01365           poly.resize(0);
01366           strcpy(buffer2,"\0");
01367           fscanf(fid,"%s",buffer2);
01368 
01369           if(strstr(buffer2,"//")!=NULL)
01370             {
01371               if(sscanf(buffer2,"%d//%*d",&cv)!=1)
01372                 {printf("Error reading connectivity in %s\n",filename.data());exit(-1);}
01373               poly.push_back(cv+one);
01374               while(fscanf(fid,"%d//%*d",&cv)==1)
01375                 poly.push_back(cv+one);
01376               add_polygon(poly);
01377             }
01378           else if(sscanf(buffer2,"%d/%*d/%*d",&cv)==1)//warning %d/%d passes through it
01379             {
01380               poly.push_back(cv+one);
01381               while(fscanf(fid,"%d/%*d/%*d",&cv)==1)
01382                 poly.push_back(cv+one);
01383               add_polygon(poly);
01384             }
01385           else if(sscanf(buffer2,"%d/%*d",&cv)==1)
01386             {
01387               poly.push_back(cv+one);
01388               while(fscanf(fid,"%d/%*d",&cv)==1)
01389                 poly.push_back(cv+one);
01390               add_polygon(poly);
01391             }
01392           else if(sscanf(buffer2,"%d",&cv)==1)
01393             {
01394               poly.push_back(cv+one);
01395               while(fscanf(fid,"%d",&cv)==1)
01396                 poly.push_back(cv+one);
01397               add_polygon(poly);
01398             }
01399           else //read the whole line
01400             {
01401               fgets(buffer,sizeof(buffer),fid);
01402               //printf("Something wrong reading obj file [%s] at part:
01403               //%s %s\n",filename.data(),buffer,buffer2);exit(-1);}
01404             }
01405           break;
01406         }
01407     }
01408 
01409 
01410   //build the index
01411   build_all_index();
01412 
01413   return 0;
01414 }
01415 
01416 
01417 int Connectivity::write_obj_type(const char* filename) const
01418 {std::string file=filename;return write_obj_type(file);}
01419 int Connectivity::write_obj_type(const std::string& filename) const
01420 {
01421   FILE *fid=NULL;
01422   fid=fopen(filename.data(),"a");
01423   if(fid==NULL)
01424     {printf("ERROR loading %s in write_obj_type in Connectivity\n",filename.data());exit(-1);}
01425   
01426   int k_polygon=0,N_polygon=polygon_number();
01427   int current_size=0,k_index;
01428   int one=+1;
01429   for(k_polygon=0;k_polygon<N_polygon;k_polygon++)
01430     {
01431       current_size=polygon_size(k_polygon);
01432 
01433       //write the type of face
01434       fprintf(fid,"f ");
01435 
01436       //read the polygon
01437       for(k_index=0;k_index<current_size;k_index++)
01438         fprintf(fid,"%d ",get_index(k_polygon,k_index)+one);
01439 
01440       fprintf(fid,"\n");
01441     }
01442 
01443   if(fclose(fid)!=0)
01444     {printf("ERROR closing %s in write_obj_type in Connectivity\n",filename.data());exit(-1);}
01445 
01446 
01447   return 0;
01448 }
01449 
01450 int Connectivity::triangulate()
01451 {
01452   if(triangulated_index.size()%3!=0)
01453     {printf("Error in triangulate() in Connectivity, size of triangulated_index is not multiple of 3 (%d)\n",triangulated_index.size());exit(-1);}
01454 
01455   int k_vertex=0,N_vertex=triangulated_index.size()/3;
01456   index_polygon.resize(0);
01457   for(k_vertex=0;k_vertex<N_vertex;k_vertex++)
01458     add_polygon(triangulated_index[3*k_vertex+0],triangulated_index[3*k_vertex+1],triangulated_index[3*k_vertex+2]);
01459   return build_all_index();
01460 }
01461 
01462 
01463 int Connectivity::load_collada_file(const std::string& filename,const std::string& name)
01464 {
01465   TiXmlDocument doc(filename);
01466   if(!doc.LoadFile())
01467     {
01468       printf("ERROR opening %s\n",filename.data());
01469       cerr << "error #" << doc.ErrorId() << " : " << doc.ErrorDesc() << endl;
01470       exit(-1);
01471     }
01472 
01473 
01474   //find library_geometries
01475   TiXmlHandle root(doc.RootElement());
01476   TiXmlNode *lib_geometry=NULL;lib_geometry=root.ToNode();
01477   if(lib_geometry==NULL)
01478     {printf("Error reading file %s in load_collada_file in Connectivity\n",filename.data());exit(-1);}
01479 
01480 
01481   //go to library_geometries entry
01482   lib_geometry = lib_geometry->FirstChild("library_geometries");
01483 
01484   if(lib_geometry==NULL)
01485     {printf("Error in file %s, cannot find library_geometries in load_collada_file in Connectivity\n",filename.data());exit(-1);}
01486   
01487   
01488   //load all geometries
01489   TiXmlNode *geometry=NULL;
01490   geometry=lib_geometry->FirstChild("geometry");
01491   if(geometry==NULL)
01492     {printf("Error cannot find geometry in file %s in load_collada_file in Connectivity\n",filename.data());exit(-1);}
01493   
01494 
01495   std::string geometry_id;
01496   int is_find=0;
01497   do
01498     {
01499       if(geometry->ToElement()->Attribute("id")==NULL)
01500         {printf("Error in file %s, geometry does not have id \n",filename.data());exit(-1);}
01501       geometry_id = geometry->ToElement()->Attribute("id");
01502       if(geometry_id==name || name=="_ALL_")
01503         {
01504           load_collada_mesh_connectivity(geometry,filename);
01505           if(name!="_ALL_")
01506             is_find=1;
01507         }
01508       geometry=geometry->NextSiblingElement("geometry");
01509     }while(geometry!=NULL && is_find==0);
01510 
01511   if(is_find==0 && name!="_ALL_")
01512     {printf("Error in file %s, no geometry found to load Connectivity with id=\"%s\"\n",filename.data(),name.data());exit(-1);}
01513 
01514   
01515   //rebuild the index
01516   build_all_index();
01517 
01518   return 0; 
01519 }
01520 int Connectivity::load_collada_file(const char* filename,const char* name)
01521 {const std::string file=filename;const std::string geometry_name=name;return load_collada_file(file,geometry_name);}
01522 
01523 int Connectivity::load_collada_mesh_connectivity(TiXmlNode* geometry_node,const std::string& filename)
01524 {
01525   TiXmlNode* mesh_node=NULL;
01526   mesh_node=geometry_node->FirstChild("mesh");
01527   //need to find mesh
01528   if(mesh_node==NULL)
01529     {printf("Error in Connectivity in load_collada_mesh_connectivity for file %s\n",filename.data());exit(-1);}
01530 
01531 
01532   //*************************************//
01533   //try to load every polylist  
01534   //*************************************//
01535   TiXmlNode* polylist_node=NULL;
01536   polylist_node=mesh_node->FirstChild("polylist");
01537   while(polylist_node!=NULL)
01538     {
01539       //there is polylist
01540       load_polylist_connectivity(polylist_node,filename);
01541       
01542       polylist_node=polylist_node->NextSiblingElement("polylist");
01543     };
01544     
01545 
01546   //*************************************//
01547   //try to load every triangles
01548   //*************************************//
01549   TiXmlNode* triangles_node=NULL;
01550   triangles_node=mesh_node->FirstChild("triangles");
01551   while(triangles_node!=NULL)
01552     {
01553       //there is triangles
01554       load_triangles_connectivity(triangles_node,filename);
01555       
01556       triangles_node=triangles_node->NextSiblingElement("triangles");
01557     };
01558     
01559 
01560 
01561   return 0;
01562 }
01563 
01564 
01565 int Connectivity::load_triangles_connectivity(TiXmlNode* triangles,const std::string& filename)
01566 {
01567   //first load every input and check where entry "vertex" to get its offset
01568   TiXmlNode* input_node=NULL;
01569   input_node=triangles->FirstChild("input");
01570   if(input_node==NULL)
01571     {printf("Error in load_triangle_connectivity of file %s, no input entry in the triangles source\n",filename.data());exit(-1);}
01572   
01573   int total_offset=0,vertex_offset=-1;
01574   std::string semantic_string;
01575   while(input_node!=NULL)
01576     {  
01577       if(input_node->ToElement()->Attribute("semantic")==NULL)
01578         {printf("Error in load_triangles_connectivity for file %s, no semantic entry in input of triangles\n",filename.data());exit(-1);}
01579       semantic_string=input_node->ToElement()->Attribute("semantic");
01580       if(semantic_string=="VERTEX" || semantic_string=="vertex" || semantic_string=="Vertex")
01581         {
01582           //get the offset of the input
01583           if(input_node->ToElement()->QueryIntAttribute("offset",&vertex_offset)!=TIXML_SUCCESS)
01584             {printf("Error in load_triangles_connectivity, offset vertex is wrong for file %s in Connectivity\n",filename.data());exit(-1);}
01585         }
01586       total_offset++;
01587       input_node = input_node->NextSiblingElement("input");
01588     };
01589 
01590 
01591   
01592 
01594   TiXmlNode* p_node=NULL;
01595   p_node=triangles->FirstChild("p");
01596   if(p_node==NULL)
01597     {printf("Error, no <p> found in triangles in file %s in Connectivity\n",filename.data());exit(-1);}
01598   std::vector <int> p_entry=load_collada_int_entry(p_node);
01599 
01600   int triangle_count=0;
01601   if(triangles->ToElement()->QueryIntAttribute("count",&triangle_count)!=TIXML_SUCCESS)
01602     {printf("Error in triangles in Connectivity for file %s, no count in triangles\n",filename.data());exit(-1);}
01603 
01604 
01606   std::vector <int> connectivity_array;
01607   int count=0;
01608   for(int k_poly=0;k_poly<triangle_count;k_poly++)
01609     for(int k_vertex=0;k_vertex<3;k_vertex++)
01610       for(int k_offset=0;k_offset<total_offset;k_offset++)
01611         {
01612           if(k_offset==vertex_offset)
01613             connectivity_array.push_back(p_entry[count]);
01614           count++;
01615         }
01616 
01617 
01618 
01620   if(3*triangle_count!=int(connectivity_array.size()))
01621     {printf("Error in file %s in Connectivity, in loading triangle: size(connectivity_array)=%d and given size=3x%d=%d\n",filename.data(),connectivity_array.size(),triangle_count,3*triangle_count);exit(-1);}
01622 
01623   
01624   //add the polygon
01625   std::vector <int> current_polygon;
01626   int k_polygon=0,k_index=0;
01627   count=0;
01628   for(k_polygon=0;k_polygon<triangle_count;k_polygon++)
01629     {
01630       current_polygon.resize(0);
01631       for(k_index=0;k_index<3;k_index++,count++)
01632         current_polygon.push_back(connectivity_array[count]);
01633       add_polygon(current_polygon);
01634     }
01635     
01636 
01637   return 0;
01638 
01639 }
01640 
01641 int Connectivity::load_polylist_connectivity(TiXmlNode* polylist,const std::string& filename)
01642 {
01643   //first load every input and check where entry "vertex" to get its offset
01644   TiXmlNode* input_node=NULL;
01645   input_node=polylist->FirstChild("input");
01646   if(input_node==NULL)
01647     {printf("Error in load_polylist_connectivity of file %s, no input entry in the polylist source\n",filename.data());exit(-1);}
01648   
01649   int total_offset=0,vertex_offset=-1;
01650   std::string semantic_string;
01651   while(input_node!=NULL)
01652     {
01653       if(input_node->ToElement()->Attribute("semantic")==NULL)
01654         {printf("Error in load_polylist_connectivity for file %s, no semantic entry in input of polylist\n",filename.data());exit(-1);}
01655       semantic_string=input_node->ToElement()->Attribute("semantic");
01656       if(semantic_string=="VERTEX" || semantic_string=="vertex" || semantic_string=="Vertex")
01657         {
01658           //get the offset of the input
01659           if(input_node->ToElement()->QueryIntAttribute("offset",&vertex_offset)!=TIXML_SUCCESS)
01660             {printf("Error in load_polylist_connectivity, offset vertex is wrong for file %s in Connectivity\n",filename.data());exit(-1);}
01661         }
01662       total_offset++;
01663       input_node = input_node->NextSiblingElement("input");
01664     };
01665 
01666 
01668   TiXmlNode* vcount_node=NULL;
01669   vcount_node=polylist->FirstChild("vcount");
01670   if(vcount_node==NULL)
01671     {printf("Error, no vcount found in polylist in file %s in Connectivity\n",filename.data());exit(-1);}
01672   std::vector <int> vcount_entry=load_collada_int_entry(vcount_node);
01673 
01674   //check polylist count
01675   int polylist_count=0;
01676   if(polylist->ToElement()->QueryIntAttribute("count",&polylist_count)!=TIXML_SUCCESS)
01677     {printf("Error in polylist in Connectivity for file %s, no count in polylist\n",filename.data());exit(-1);}
01678   if(polylist_count!=int(vcount_entry.size()))
01679     {printf("Error in file %s in Connectivity, in loading polylist: size(vcount)=%d and given size=%d\n",filename.data(),vcount_entry.size(),polylist_count);exit(-1);}
01680 
01681 
01683   TiXmlNode* p_node=NULL;
01684   p_node=polylist->FirstChild("p");
01685   if(p_node==NULL)
01686     {printf("Error, no <p> found in polylist in file %s in Connectivity\n",filename.data());exit(-1);}
01687   std::vector <int> p_entry=load_collada_int_entry(p_node);
01688 
01690   std::vector <int> connectivity_array;
01691   int count=0;
01692   for(int k_poly=0;k_poly<polylist_count;k_poly++)
01693     for(int k_vertex=0;k_vertex<vcount_entry[k_poly];k_vertex++)
01694       for(int k_offset=0;k_offset<total_offset;k_offset++)
01695         {
01696           if(k_offset==vertex_offset)
01697             connectivity_array.push_back(p_entry[count]);
01698           count++;
01699         }
01700   
01701   //add the polygon
01702   std::vector <int> current_polygon;
01703   int k_polygon=0,k_index=0;
01704   count=0;
01705   for(k_polygon=0;k_polygon<polylist_count;k_polygon++)
01706     {
01707       current_polygon.resize(0);
01708       for(k_index=0;k_index<vcount_entry[k_polygon];k_index++,count++)
01709         current_polygon.push_back(connectivity_array[count]);
01710       add_polygon(current_polygon);
01711     }
01712     
01713 
01714   return 0;
01715   
01716 }
01717 
01718 std::vector <int> Connectivity::load_collada_int_entry(TiXmlNode* vcount_node)
01719 {
01720   std::vector <int> vcount_entry;
01721   if(vcount_node==NULL)
01722     {printf("Error in load_collada_vcount_entry in Connectivity, pointer is null\n");exit(-1);}
01723   if(vcount_node->FirstChild()==NULL)
01724     {printf("Error no child in load_collada_vcount_entry in Connectivity\n");exit(-1);}
01725   //convert entry to text
01726   std::string full_string = vcount_node->FirstChild()->ToText()->ValueStr();
01727 
01728   //fill the entry
01729   int k1=0,k0=0;
01730   string X;
01731   do
01732     {
01733       k1= full_string.find(" ",k1+1);
01734       X = full_string.substr(k0,k1-k0);
01735       vcount_entry.push_back(atoi(X.data())); //add index
01736       k0=k1+1;
01737     }while(k1>0);
01738 
01739   return vcount_entry;
01740 } 
01741 
01742 
01743 int Connectivity::load_collada_file(const std::string& filename)
01744 {
01745   int ok=0;
01746   ok += load_collada_file(filename,"_ALL_");
01747   return ok;
01748 }
01749 int Connectivity::load_collada_file(const char* filename)
01750 {std::string file=filename;return load_collada_file(file,"_ALL_");}
01751 
01752 int Connectivity::get_polygon_access(int k_polygon) const
01753 {
01754   if(k_polygon<0 || k_polygon>polygon_number())
01755     {printf("Error in Connectivity in get_polygon_access(%d), polygon_number()=%d\n",k_polygon,polygon_number());exit(-1);}
01756   return polygon_access[k_polygon];
01757 }
01758 
01759 int Connectivity::load_g_file(const char* filename)
01760 {return load_g_file(std::string(filename));}
01761 int Connectivity::load_g_file(const std::string& filename)
01762 {
01763     destroy();
01764 
01765   #define SIZE_BUFFER 2048
01766   char buffer[SIZE_BUFFER]={'\0'};
01767 
01768   FILE *fid=NULL;
01769   fid=fopen(filename.data(),"r");
01770   if(fid==NULL)
01771     {printf("ERROR loading %s in load_g_file in Connectivity\n",filename.data());exit(-1);}
01772 
01773 
01774   //pass comments
01775   fscanf(fid,"%s",buffer);
01776   while(buffer[0]=='#')//comments
01777     {
01778       fgets(buffer,sizeof(buffer),fid);
01779       fscanf(fid,"%s",buffer);
01780     }
01781 
01782   //read Number of polygon
01783   int N_vertex=0,N_polygon=0;
01784   N_vertex=atoi(buffer);//N_vertex
01785   fscanf(fid,"%d",&N_polygon);//N_polygon
01786   fgets(buffer,sizeof(buffer),fid);//read line
01787 
01788   //read vertices
01789   int k_vertex=0;
01790   for(k_vertex=0;k_vertex<N_vertex;k_vertex++)
01791     {
01792       fgets(buffer,sizeof(buffer),fid);//read line
01793       if(buffer[0]=='#')//comments does not count in vertices number
01794         k_vertex--;
01795     }
01796 
01797   //read polygons
01798 
01799   int size_poly=0;
01800   int k_polygon=0;
01801   int k_current_polygon=0;
01802   int temp=0;
01803   std::vector <int> v_poly;
01804   for(k_polygon=0;k_polygon<N_polygon;k_polygon++)
01805     {
01806        if(fscanf(fid,"%d",&size_poly)!=1)
01807         {
01808           fscanf(fid,"%s",buffer);
01809           if(buffer[0]!='#')
01810             {printf("ERROR loading polygons in load_g_file %s in Connectivity\n",filename.data());exit(-1);}
01811           else//read line
01812             {
01813               fgets(buffer,sizeof(buffer),fid);
01814               k_polygon--;
01815             }
01816         }
01817       else
01818         {
01819           v_poly.resize(0);
01820           for(k_current_polygon=0;k_current_polygon<size_poly;k_current_polygon++)
01821             {
01822               fscanf(fid,"%d",&temp);
01823               v_poly.push_back(temp);
01824             }
01825           add_polygon(v_poly);
01826           //read rest of the line
01827           fgets(buffer,sizeof(buffer),fid);
01828         }
01829     }
01830 
01831   if(fclose(fid)!=0)
01832     {printf("ERROR closing %s in load_g_file in Connectivity\n",filename.data());exit(-1);}
01833 
01834   //build the index
01835   build_all_index();
01836 
01837   return 0;
01838 
01839 
01840 }
01841 
01842 int Connectivity::write_g_type(const char* filename) const
01843 {return write_g_type(std::string(filename));}
01844 int Connectivity::write_g_type(const std::string& filename) const
01845 {
01846   FILE *fid=NULL;
01847   fid=fopen(filename.data(),"a");
01848   if(fid==NULL)
01849     {printf("ERROR loading %s in write_g_type in Connectivity\n",filename.data());exit(-1);}
01850 
01851   int k_polygon=0,N_polygon=polygon_number();
01852   int current_size=0,k_index;
01853   Edge e;
01854   for(k_polygon=0;k_polygon<N_polygon;k_polygon++)
01855     {
01856       current_size=polygon_size(k_polygon);
01857 
01858       //write the size of the polygon
01859       fprintf(fid,"%d ",current_size);
01860       //read the polygon
01861       for(k_index=0;k_index<current_size;k_index++)
01862         fprintf(fid,"%d ",get_index(k_polygon,k_index));
01863       //get edge
01864       for(k_index=0;k_index<current_size;k_index++)
01865         {
01866           e = get_edge_segment(get_index(k_polygon,k_index),get_index(k_polygon,(k_index+1)%current_size));
01867           fprintf(fid,"%d ",e.get_face_1());
01868         }
01869 
01870       fprintf(fid,"\n");
01871     }
01872 
01873   if(fclose(fid)!=0)
01874     {printf("ERROR closing %s in write_g_type in Connectivity\n",filename.data());exit(-1);}
01875 
01876   return 0;
01877 }

Generated on Mon Mar 30 16:55:54 2009 by  doxygen 1.5.6