00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
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
00201 triangulated_index.push_back(index0);
00202 triangulated_index.push_back(index1);
00203 triangulated_index.push_back(index2);
00204
00205
00206
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
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
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
00299 for(k_index=0;k_index<k_access0;k_index++)
00300 index_polygon_2.push_back(index_polygon[k_index]);
00301
00302
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
00308 index_polygon_2.push_back(-1);
00309
00310
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
00318 index_polygon=index_polygon_2;
00319
00320
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
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
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
00364 index_polygon=index_polygon_2;
00365
00366
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
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
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]=='#')
00409 fgets(buffer,sizeof(buffer),fid);
00410 }
00411
00412
00413 fscanf(fid,"%s",buffer);
00414 while(buffer[0]=='#')
00415 {
00416 fgets(buffer,sizeof(buffer),fid);
00417 fscanf(fid,"%s",buffer);
00418 }
00419
00420
00421 int N_vertex=0,N_polygon=0;
00422 N_vertex=atoi(buffer);
00423 fscanf(fid,"%d",&N_polygon);
00424 fgets(buffer,sizeof(buffer),fid);
00425
00426
00427 int k_vertex=0;
00428 for(k_vertex=0;k_vertex<N_vertex;k_vertex++)
00429 {
00430 fgets(buffer,sizeof(buffer),fid);
00431 if(buffer[0]=='#')
00432 k_vertex--;
00433 }
00434
00435
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
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
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
00493 fprintf(fid,"%d ",current_size);
00494
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
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
00535 set.write_off_type(filename);
00536
00537
00538 write_off_type(filename);
00539
00540
00541
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
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
00616 for(k_polygon=0;k_polygon<N_polygon;k_polygon++)
00617 {
00618
00619 compared_polygon=get_index_of_polygon(k_polygon);
00620
00621
00622 count=0;
00623
00624 if(N_poly==int(compared_polygon.size()))
00625 {
00626
00627 for(k_poly=0;k_poly<N_poly;k_poly++)
00628
00629 for(k_to_compare=0;k_to_compare<int(compared_polygon.size());k_to_compare++)
00630
00631 if(polygon[k_poly]==compared_polygon[k_to_compare])
00632 count++;
00633 }
00634 if(count==N_poly)
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
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
00789 return edges[k_index_edge];
00790
00791 }
00792
00793
00794 int Connectivity::build_edges()
00795 {
00796
00797
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
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
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
00828 if(find_current_edge_slow(ind[0],ind[1])!=-1)
00829 {printf("Warning, edge [%d,%d] is duplicated, not a manifold mesh\n",ind[0],ind[1]);return -1;}
00830
00831
00832
00833
00834
00835
00836 index_edges.push_back(edges.size());
00837
00838
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)
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
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
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
00862 index_edges.push_back(-1);
00863 }
00864
00865
00866
00867
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
00880 ind[0] = get_index(k_polygon,k_vertex);
00881 ind[1] = get_index(k_polygon,(k_vertex+1)%N_vertex);
00882
00883
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
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
00892 current_e = get_edge(k_polygon,k_vertex);
00893
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
00909
00910
00911 }
00912 }
00913
00914
00915
00916
00917
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
00948 if(vertex_index_0==e.get_index_0() && vertex_index_1==e.get_index_1())
00949 return k_edge;
00950 }
00951
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
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
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
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
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
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
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
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
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
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
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
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
01132 do
01133 {
01134
01135
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
01148 correct_polygon[first_polygon_not_correct]=1;
01149 reccursive_connect_manifold_polygons(first_polygon_not_correct,&correct_polygon);
01150 }
01151
01152
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
01175
01176
01177 for(k_vertex_current=0;k_vertex_current<N_vertex_current;k_vertex_current++)
01178 {
01179
01180
01181
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
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
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
01205 (*correct_polygon)[k_polygon]=1;
01206
01207 reccursive_connect_manifold_polygons(k_polygon,correct_polygon);
01208 }
01209
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
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
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
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];
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':
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)
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
01400 {
01401 fgets(buffer,sizeof(buffer),fid);
01402
01403
01404 }
01405 break;
01406 }
01407 }
01408
01409
01410
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
01434 fprintf(fid,"f ");
01435
01436
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
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
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
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
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
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
01534
01535 TiXmlNode* polylist_node=NULL;
01536 polylist_node=mesh_node->FirstChild("polylist");
01537 while(polylist_node!=NULL)
01538 {
01539
01540 load_polylist_connectivity(polylist_node,filename);
01541
01542 polylist_node=polylist_node->NextSiblingElement("polylist");
01543 };
01544
01545
01546
01547
01548
01549 TiXmlNode* triangles_node=NULL;
01550 triangles_node=mesh_node->FirstChild("triangles");
01551 while(triangles_node!=NULL)
01552 {
01553
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
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
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
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
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
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
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
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
01726 std::string full_string = vcount_node->FirstChild()->ToText()->ValueStr();
01727
01728
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()));
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
01775 fscanf(fid,"%s",buffer);
01776 while(buffer[0]=='#')
01777 {
01778 fgets(buffer,sizeof(buffer),fid);
01779 fscanf(fid,"%s",buffer);
01780 }
01781
01782
01783 int N_vertex=0,N_polygon=0;
01784 N_vertex=atoi(buffer);
01785 fscanf(fid,"%d",&N_polygon);
01786 fgets(buffer,sizeof(buffer),fid);
01787
01788
01789 int k_vertex=0;
01790 for(k_vertex=0;k_vertex<N_vertex;k_vertex++)
01791 {
01792 fgets(buffer,sizeof(buffer),fid);
01793 if(buffer[0]=='#')
01794 k_vertex--;
01795 }
01796
01797
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
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
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
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
01859 fprintf(fid,"%d ",current_size);
01860
01861 for(k_index=0;k_index<current_size;k_index++)
01862 fprintf(fid,"%d ",get_index(k_polygon,k_index));
01863
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 }