00001
00002 #include <MC_triangle.hpp>
00003 #include <MC_segment.hpp>
00004 #include <MC_int_vector.hpp>
00005 #include <MC_matrix.hpp>
00006 #include <MC_int_pair.hpp>
00007 #include <MC_mesh_index_vector.hpp>
00008
00009 #include <MC_polygon.hpp>
00010
00011
00012 namespace mesh_conv
00013 {
00014 bool MC_polygon::is_planar() const
00015 {
00016
00017 int N=size();
00018 if(N<3)
00019 {std::cout<<"Error in MC_polygon::is_planar(), size is "<<N<<"<3"<<std::endl;exit(-1);}
00020 MC_v3d n=normal();
00021
00022 double tol=0.0001;
00023 for(int k=1;k<N;k++)
00024 if( fabs((v[k]-v[0]).dot(n))>tol )
00025 return false;
00026 return true;
00027 }
00028
00029 MC_v3d MC_polygon::normal() const
00030 {
00031 int N=size();
00032 if(N<3)
00033 {std::cout<<"Error in MC_polygon::normal(), size is "<<N<<"<3"<<std::endl;exit(-1);}
00034
00035 MC_v3d n;
00036 for(int k=0;k<N-2;k++)
00037 {
00038 MC_v3d v0,v1;
00039 v0=(v[k+1]-v[k]).normalized();
00040 v1=(v[k+2]-v[k]).normalized();
00041 n+=v0.cross(v1);
00042 }
00043
00044 double nn=n.norm();
00045
00046 double epsilon=0.000000001;
00047 if(nn<epsilon)
00048 {
00049
00050 return MC_v3d(0,0,1);}
00051 n/=nn;
00052 return n;
00053 }
00054
00055 MC_v3d MC_polygon::barycenter() const
00056 {return MC_v3d_vector::sum(v)/size();}
00057
00058 MC_polygon::MC_polygon()
00059 :MC_v3d_vector()
00060 {}
00061 MC_polygon::MC_polygon(const MC_v3d& v0,const MC_v3d& v1,const MC_v3d& v2)
00062 :MC_v3d_vector(v0,v1,v2)
00063 {}
00064 MC_polygon::MC_polygon(const MC_v3d& v0,const MC_v3d& v1,const MC_v3d& v2,const MC_v3d& v3)
00065 :MC_v3d_vector(v0,v1,v2,v3)
00066 {}
00067 MC_polygon::MC_polygon(const MC_v3d& v0,const MC_v3d& v1,const MC_v3d& v2,const MC_v3d& v3,const MC_v3d& v4)
00068 :MC_v3d_vector(v0,v1,v2,v3,v4)
00069 {}
00070
00071 MC_polygon::MC_polygon(const MC_v3d_vector& vec)
00072 :MC_v3d_vector(vec)
00073 {}
00074 MC_polygon::MC_polygon(const std::vector <MC_v3d>& vec)
00075 :MC_v3d_vector(vec)
00076 {}
00077 MC_polygon::MC_polygon(const MC_polygon& p)
00078 :MC_v3d_vector(p)
00079 {v=p.v;}
00080
00081 MC_v3d MC_polygon::closest_point(const MC_v3d& x,int *type) const
00082 {
00083
00084
00085 if(size()<=2)
00086 {std::cout<<"MC_polygon::closest_point(), polygon size is not ok ["<<size()<<"]"<<std::endl;exit(-1);}
00087
00088 double epsilon=0.0001;
00089 MC_v3d n = normal();
00090
00091
00092 MC_v3d projection=x-((x-v[0]).dot(n))*n;
00093
00094
00095 std::vector <MC_triangle> triangles=MC_triangle::triangulate(*this);
00096
00097
00098 for(unsigned int k=0;k<triangles.size();k++)
00099 {
00100 if(triangles[k].is_inside(projection)==1)
00101 {
00102 if(type!=0)
00103 *type=0;
00104 return projection;
00105 }
00106 }
00107
00108
00109
00110 MC_v3d x0,x1,closest;MC_segment s;double L=0.0,L_min=9999.9;
00111 int closest_edge=-1;
00112 for(int k=0;k<size();k++)
00113 {
00114
00115 x0 = v[k];
00116 x1 = v[(k+1)%size()];
00117 s=MC_segment(x0,x1);
00118
00119 L = s.distance_to_point(projection);
00120 if(L<L_min)
00121 {
00122 closest = s.closest_point(projection);
00123 closest_edge = k;
00124 L_min=L;
00125 }
00126 }
00127
00128 if(type!=0)
00129 *type = 1;
00130
00131 for(int k=0;k<size();k++)
00132 if( (closest-v[k]).norm() < epsilon)
00133 if(type!=0)
00134 *type=2;
00135 return closest;
00136 }
00137
00138 MC_v3d_vector MC_polygon::plane_intersection(const MC_v3d& n,const MC_v3d& x0,int *type,MC_int_vector *type_edge) const
00139 {
00140 std::cout<<"enter plane intersection"<<std::endl;
00141
00142 MC_v3d_vector intersections;
00143
00144
00145
00146 std::vector <MC_segment> s;
00147 MC_v3d_vector inter;
00148 if(type_edge!=0)
00149 type_edge->resize(size());
00150 MC_int_vector temp_type_edge=MC_int_vector::zeros(size());
00151
00152 for(int k=0;k<size();k++)
00153 {
00154 s.push_back(segment(k));
00155 inter.add(s[k].plane_intersection(n,x0,&temp_type_edge[k]));
00156
00157 std::cout<<temp_type_edge[k]<<" :"<<inter.last()<<std::endl;
00158 if(type_edge!=0)
00159 (*type_edge)[k]=temp_type_edge[k];
00160 }
00161
00162
00163
00164 int is_intersection=0;
00165 for(int k=0;is_intersection==0 && k<size();k++)
00166 if(temp_type_edge[k]!=0)
00167 is_intersection=1;
00168 if(is_intersection==0)
00169 {
00170 if(type!=0)
00171 *type=0;
00172 return intersections;
00173 }
00174
00175
00176
00177 int is_two_intersection=0;
00178 int k_vertex=-1;
00179 for(int k=0;is_two_intersection==0 && k<size();k++)
00180 {
00181 if( temp_type_edge[k]==1 || temp_type_edge[k]==2) is_two_intersection=1;
00182 if( temp_type_edge[k]==2) k_vertex=k;
00183 }
00184
00185 if(is_two_intersection==0)
00186 {
00187 if(k_vertex==-1)
00188 {
00189
00190 if(type!=0)
00191 *type=0;
00192 return intersections;exit(-1);}
00193 if(type!=0)
00194 *type=2;
00195 intersections.add(v[k_vertex]); return intersections;
00196 }
00197
00198
00199
00200
00201 int k_1=0,k_2=0;
00202 for(k_1=0;k_1<size();k_1++){
00203 for(k_2=k_1+1;k_2<size();k_2++){
00204 if( (temp_type_edge[k_1]==1 || temp_type_edge[k_1]==2) &&
00205 (temp_type_edge[k_2]==1 || temp_type_edge[k_2]==2) &&
00206 (inter[k_1]!=inter[k_2])
00208 )
00209 {
00210 if(type!=0)
00211 *type=1;
00212 intersections.add(inter[k_1]);
00213 intersections.add(inter[k_2]);
00214
00215
00216
00217 return intersections;
00218 }
00219 }
00220 }
00221
00222
00223
00224 if(type!=0)
00225 *type=0;
00226 return intersections;
00227
00228 }
00229
00230
00231 MC_segment MC_polygon::segment(const int& edge_number) const
00232 {
00233 int N=size();
00234 if(edge_number<0 || edge_number>N)
00235 {std::cout<<"MC_triangle::segment("<<edge_number<<"),_k_edge has to be between 0 and "<<size()<<std::endl;exit(-1);}
00236
00237 return MC_segment(v[edge_number],v[(edge_number+1)%N]);
00238 }
00239
00240 MC_polygon MC_polygon::half_space_intersection(const MC_v3d& n,const MC_v3d& x0,int *type) const
00241 {
00242
00243 MC_v3d_vector intersection;
00244 int type_edges=0;
00245 intersection = plane_intersection(n,x0,&type_edges);
00246
00247
00248
00249
00250 MC_polygon new_polygon;
00251 if(type_edges!=1)
00252 {
00253 if(((*this)[0]-x0).dot(n)<0)
00254 {
00255
00256 if(type!=0)
00257 *type=2;
00258 new_polygon.add(MC_v3d(-1.0,-1.0,-1.0));
00259 return new_polygon;
00260 }
00261 else
00262 {
00263
00264 if(type!=0)
00265 *type=0;
00266 return *this;
00267 }
00268 }
00269
00270
00271
00272 if(type!=0)
00273 *type=1;
00274 MC_segment s(intersection[0],intersection[1]);
00275 MC_v3d old_normal=normal();
00276
00277
00278
00279
00280
00281 int k=0;
00282 while(((*this)[k]-x0).dot(n)<0)
00283 k++;
00284 int k_2=k;
00285
00286 int added_line=0;
00287 do
00288 {
00289 if( ((*this)[k_2]-x0).dot(n)>0 )
00290 new_polygon.add((*this)[k_2]);
00291 else if(added_line==0)
00292 {
00293
00294 if( ((s[1]-s[0]).cross(s[0]-(*this)[(k_2-1)<0?size()-1:k_2-1])).dot(old_normal)<0)
00295 {new_polygon.add(s[0]);new_polygon.add(s[1]);}
00296 else{new_polygon.add(s[1]);new_polygon.add(s[0]);}
00297 added_line=1;
00298 }
00299 k_2=(k_2+1)%size();
00300 }while(k_2!=k);
00301
00302 return new_polygon;
00303 }
00304
00305 MC_v3d MC_polygon::segment_intersection(const MC_segment& s,int *type) const
00306 {
00307 std::vector <MC_triangle> v_t = MC_triangle::triangulate(*this);
00308 int N=v_t.size();
00309 for(int k=0;k<N;k++)
00310 {
00311 int temp_type=0;
00312 MC_v3d i=v_t[k].segment_intersection(s,&temp_type);
00313
00314 if(type!=0)
00315 *type=temp_type;
00316
00317 if(temp_type==1 || temp_type==2 || temp_type==3)
00318 if(is_inside(i)==1)
00319 return i;
00320 }
00321
00322 if(type!=0)
00323 *type=0;
00324 return MC_v3d(0,0,0);
00325 }
00326
00327 bool MC_polygon::is_inside(const MC_v3d& x) const
00328 {
00329 std::vector <MC_triangle> t = MC_triangle::triangulate(*this);
00330 int N=t.size();
00331 for(int k=0;k<N;k++)
00332 if(t[k].is_inside(x)==true)
00333 return true;
00334 return false;
00335 }
00336 bool MC_polygon::is_outside(const MC_v3d& _x) const
00337 {return !is_inside(_x);}
00338
00339 std::pair <MC_v3d,std::pair<int,std::pair<int,double> > > MC_polygon::projected_direction(const MC_v3d& c0,const MC_v3d& _d,const MC_int_vector& forbidden_edge) const
00340 {
00341
00342
00343 int type=0,sub_type=0;double relative=0.0;
00344
00345 MC_v3d d=_d.normalized();
00346 double epsilon=0.00001;
00347
00348
00349 MC_matrix R=MC_matrix::rotation_axis_to_axis(normal(),MC_v3d(0,0,1));
00350
00351 bool is_intersected=false;
00352 MC_v3d intersection;
00353
00354 MC_polygon poly_2d=R*(*this);
00355 MC_v3d c0_2d=MC_v3d(R*c0);
00356 MC_v3d d_2d=MC_v3d(R*d);
00357
00358
00359
00360 double a=d_2d[1],b=-d_2d[0],c=a*c0_2d[0]+b*c0_2d[1];
00361
00362
00363 int N=size();
00364 for(int k_seg=0;k_seg<N;k_seg++)
00365 {
00366 if(forbidden_edge.find(k_seg)==-1)
00367 {
00368
00369 MC_v3d c_x0=poly_2d[k_seg];
00370 MC_v3d c_x1=poly_2d[(k_seg+1)%N];
00371
00372 double n_segment=(c_x0-c_x1).norm();
00373
00374 MC_v3d d_c=c_x1-c_x0;
00375
00376 double ra=d_c[1],rb=-d_c[0],rc=ra*c_x0[0]+rb*c_x0[1];
00377 double det=rb*a-b*ra;
00378
00379 if(abs(det)>epsilon)
00380 {
00381 double xi=(rb*c-rc*b)/det;
00382 double yi=(rc*a-ra*c)/det;
00383
00384
00385 if( (xi-c0_2d[0])*d_2d[0]+(yi-c0_2d[1])*d_2d[1] >0 )
00386 {
00387
00388
00389 double proj=(xi-c_x0[0])*(c_x1[0]-c_x0[0])+(yi-c_x0[1])*(c_x1[1]-c_x0[1]);
00390 double n_xi=pow((xi-c_x0[0])*(xi-c_x0[0])+(yi-c_x0[1])*(yi-c_x0[1]),0.5);
00391
00392 if(proj>=epsilon && n_xi<=n_segment)
00393 {
00394
00395
00396 if(is_intersected==false || (is_intersected==true && (intersection-c0).norm()>
00397 pow((xi-c0_2d[0])*(xi-c0_2d[0])+(yi-c0_2d[1])*(yi-c0_2d[0]),0.5) ) )
00398 {
00399 is_intersected = true;
00400 intersection = MC_v3d(R.inverted()*MC_v3d(xi,yi,c0_2d[2]));
00401
00402
00403 if(proj<epsilon)
00404 {type=0; sub_type=k_seg; relative=0.0;}
00405 else if(abs(proj-1)<epsilon)
00406 {type=0; sub_type=(k_seg+1)%N; relative=0.0;}
00407 else
00408 {type=1; sub_type=k_seg;
00409 if(n_segment<epsilon)
00410 relative=0.0;
00411 else
00412 relative=n_xi/n_segment;
00413 }
00414 }
00415 }
00416 }
00417 }
00418 }
00419 }
00420
00421 if(is_intersected==false)
00422 {intersection=MC_v3d(-1,-1,-1);type=-1;sub_type=-1;relative=0.0;}
00423
00424
00425 std::pair <MC_v3d,std::pair<int,std::pair<int,double> > > res;
00426 res.first=intersection;
00427 res.second.first=type;
00428 res.second.second.first=sub_type;
00429 res.second.second.second=relative;
00430 return res;
00431
00432 }
00433
00434 MC_double_vector MC_polygon::barycentric_coordinates(const MC_v3d& p) const
00435 {
00436 int N=size();
00437 MC_double_vector bar=MC_double_vector::zeros(N);
00438
00439
00440 MC_int_vector pos=position(p);
00441
00442 if(pos[0]==3)
00443 {std::cout<<"Warning in Polygon::barycentric_coordinates("<<p<<") is not in polygon"<<std::endl;return bar;}
00444 if(pos[0]==2)
00445 {bar[pos[1]]=1.0;return bar;}
00446 if(pos[0]==1)
00447 {
00448 double alpha=segment(pos[1]).relative_position(p);
00449 bar[pos[1]] = 1-alpha;
00450 bar[(pos[1]+1)%N] = alpha;
00451
00452 return bar;
00453 }
00454
00455
00456 for(int k=0;k<N;k++)
00457 {
00458 int kp=k-1<0?N-1:k-1;
00459 int kn=(k+1)%N;
00460
00461 double dist2=(p-v[k]).dot(p-v[k]);
00462 bar[k]=(MC_v3d::cotan(p-v[k],v[kp]-v[k])+MC_v3d::cotan(p-v[k],v[kn]-v[k]))/dist2;
00463 }
00464
00465 bar/=MC_double_vector::sum(bar);
00466 return bar;
00467 }
00468
00469
00470 MC_int_vector MC_polygon::position(const MC_v3d& x) const
00471 {
00472 double epsilon=0.0001;
00473 int N=size();
00474 for(int k=0;k<N;k++)
00475 if( (x-v[k]).norm()<epsilon )
00476 return MC_int_vector (2,k);
00477 if(is_outside(x)==1)
00478 return MC_int_vector (3,-1);
00479 for(int k=0;k<N;k++)
00480 if(segment(k).is_belonging(x)==1)
00481 return MC_int_vector (1,k);
00482
00483 return MC_int_vector (0,-1);
00484 }
00485
00486 std::vector <MC_polygon> MC_polygon::subdivide_mid_edge_no_constraint() const
00487 {
00488
00489 MC_v3d_vector mid_points;
00490
00491 mid_points.resize(size());
00492
00493 int k=0,N_mid_points=size();
00494 for(k=0;k<N_mid_points;k++)
00495 mid_points[k]=0.5*(v[k]+v[(k+1)%N_mid_points]);
00496
00497
00498 std::vector <MC_polygon> new_polygon;
00499
00500 new_polygon.resize(N_mid_points+1);
00501
00502
00503 for(k=0;k<N_mid_points;k++)
00504 {
00505 new_polygon[k]=MC_polygon(mid_points[k],v[k],mid_points[k-1>=0?k-1:N_mid_points-1]);
00506 }
00507
00508 for(k=0;k<N_mid_points;k++)
00509 new_polygon[N_mid_points].add(mid_points[k]);
00510
00511
00512 return new_polygon;
00513 }
00514 std::vector <MC_polygon> MC_polygon::subdivide_barycenter_mid_edge_no_constraint() const
00515 {
00516
00517 MC_v3d barycenter;
00518
00519
00520 MC_v3d_vector mid_points;
00521
00522
00523 mid_points.resize(size());
00524
00525 int k=0,N_mid_points=size();
00526 for(k=0;k<N_mid_points;k++)
00527 {
00528 mid_points[k]=0.5*(v[k]+v[(k+1)%N_mid_points]);
00529 barycenter+=v[k];
00530 }
00531 barycenter/=double(N_mid_points);
00532
00533 std::vector <MC_polygon> new_polygon(N_mid_points);
00534
00535 for(k=0;k<N_mid_points;k++)
00536 {
00537 new_polygon[k].add(v[k]);
00538 new_polygon[k].add(mid_points[k]);
00539 new_polygon[k].add(barycenter);
00540 new_polygon[k].add(mid_points[k-1>=0?k-1:N_mid_points-1]);
00541 }
00542
00543 return new_polygon;
00544
00545 }
00546
00547
00548 std::pair<std::vector <MC_polygon>,std::pair<MC_mesh_index_vector,std::pair<MC_int_vector,MC_int_vector> > > MC_polygon::subdivide_mid_edge(const MC_int_vector& constraint_edges) const
00549 {
00550
00551 if(constraint_edges.size()==0)
00552 {
00553 MC_mesh_index_vector m;
00554 MC_int_vector extra_index=MC_int_vector::linspace(size(),2*size()-1);
00555 MC_int_vector edge=MC_int_vector::linspace(0,size()-1);
00556
00557 m.point_set()=v;
00558 int N=size();
00559 for(int k=0;k<N;++k)
00560 {
00561 MC_v3d x_middle=0.5*(v[k]+v[(k+1)%N]);
00562 m.point_set().add(x_middle);
00563 }
00564
00565 for(int k=0;k<N;++k)
00566 m.connectivity().add(MC_int_vector( (k+1)%N,N+(k+N+1)%N,N+k ));
00567
00568 m.connectivity().add(MC_int_vector::linspace(0,N-1)+N);
00569
00570
00571 return std::make_pair(m.get_polygon(),std::make_pair(m,std::make_pair(extra_index,edge) ) );
00572 }
00573 if(static_cast<int>(constraint_edges.to_set().size())==size()-1)
00574 {
00575
00576 MC_int_pair non_subdivided_edge;
00577 int N=size();
00578 for(int k=0;k<N;++k)
00579 if(constraint_edges.find(k)==-1)
00580 non_subdivided_edge=MC_int_pair(k,(k+1)%N);
00581 MC_v3d x_middle=0.5*(v[non_subdivided_edge[0]]+v[non_subdivided_edge[1]]);
00582
00583 MC_int_vector extra_index(size());
00584 MC_int_vector edge=non_subdivided_edge[0];
00585
00586 MC_mesh_index_vector m;
00587 m.point_set()=v;
00588 m.point_set().add(x_middle);
00589
00590 std::vector <MC_polygon> v_polygon;
00591 for(int k=0;k<N;++k)
00592 {
00593 if(k!=non_subdivided_edge[0])
00594 {
00595 MC_int_pair edge(k,(k+1)%N);
00596 v_polygon.push_back(MC_polygon(v[edge[0]],v[edge[1]],x_middle));
00597
00598 m.connectivity().add(MC_int_vector(edge[0],edge[1],size()));
00599 }
00600 }
00601 return std::make_pair(v_polygon,std::make_pair(m,std::make_pair(extra_index,edge) ) );
00602 }
00603
00604
00605 MC_mesh_index_vector m;
00606 m.point_set()=v;
00607
00608 MC_int_vector new_index_contour;
00609 int N=size();
00610 int k_new=0;
00611 MC_int_vector extra_index;
00612 MC_int_vector edge;
00613 for(int k=0;k<N;++k)
00614 {
00615 new_index_contour.add(k);
00616 if(constraint_edges.find(k)==-1)
00617 {
00618 extra_index.add(N+k_new);
00619 edge.add(k);
00620 new_index_contour.add(N+k_new);
00621
00622 m.point_set().add(0.5*(v[k]+v[(k+1)%N]));
00623 k_new++;
00624 }
00625 }
00626 if(extra_index.size()==0)
00627 {
00628 m.connectivity()=MC_int_vector::linspace(0,size()-1);
00629
00630 return std::make_pair(m.get_polygon(),std::make_pair(m,std::make_pair(extra_index,edge) ) );
00631 }
00632
00633
00634
00635 int N_new_points=m.point_set().size();
00636 int k_current=new_index_contour.find(extra_index[0]);
00637 int k_current0=k_current;
00638 MC_int_vector temp_poly=MC_int_vector(new_index_contour[k_current]);
00639
00640 k_current=(k_current+1)%N_new_points;
00641 while(k_current!=k_current0)
00642 {
00643 temp_poly.add(new_index_contour[k_current]);
00644 if(extra_index.find(new_index_contour[k_current])!=-1)
00645 {
00646 m.connectivity().add(temp_poly);
00647 temp_poly.resize(0);
00648 temp_poly.add(new_index_contour[k_current]);
00649 }
00650 k_current=(k_current+1)%N_new_points;
00651 }
00652 temp_poly.add(new_index_contour[k_current0]);
00653 m.connectivity().add(temp_poly);
00654
00655 if(extra_index.size()>=3)
00656 m.connectivity().add(extra_index);
00657
00658 return std::make_pair(m.get_polygon(),std::make_pair(m,std::make_pair(extra_index,edge) ) );
00659 }
00660 std::pair<std::vector <MC_polygon>,std::pair<MC_mesh_index_vector,std::pair<MC_int_vector,MC_int_vector> > > MC_polygon::subdivide_barycenter_mid_edge(const MC_int_vector& constraint_edges) const
00661 {
00662
00663 MC_mesh_index_vector m;
00664 MC_int_vector extra_index;
00665 MC_int_vector edge;
00666
00667
00668 if(constraint_edges.size()==0)
00669 {
00670 extra_index=MC_int_vector::linspace(size()+1,2*size());
00671 edge=MC_int_vector::linspace(0,size()-1);
00672
00673 m.point_set()=MC_v3d_vector(v)<<barycenter();
00674 int N=size();
00675 for(int k=0;k<N;++k)
00676 {
00677 MC_v3d x_middle=0.5*(v[k]+v[(k+1)%N]);
00678 m.point_set().add(x_middle);
00679 m.connectivity().add(MC_int_vector(N+1+(k+N+1)%N,N,N+1+k,(k+1)%N));
00680 }
00681
00682 return std::make_pair(m.get_polygon(),std::make_pair(m,std::make_pair(extra_index,edge) ) );
00683 }
00684
00685
00686
00687 MC_v3d bar=barycenter();
00688 m.point_set().add(v).add(bar);
00689 int N=size();
00690
00691 MC_v3d_vector mid_point;
00692 MC_int_vector map_index_middle=MC_int_vector::zeros(N);int counter=0;
00693 for(int k=0;k<N;k++)
00694 {
00695 if(constraint_edges.find(k)==-1)
00696 {
00697 MC_v3d x=0.5*(v[k]+v[(k+1)%N]);
00698 mid_point.add(x);
00699 m.point_set().add(x);
00700 extra_index.add(N+1+counter);
00701 edge.add(k);
00702
00703 map_index_middle[k]=counter++;
00704
00705 }
00706 else
00707 {
00708 mid_point.add(MC_v3d(-1,-1,-1));
00709 map_index_middle[k]=-1;
00710 }
00711 }
00712
00713 MC_polygon temp;
00714 for(int k=0;k<N;k++)
00715 {
00716
00717 if(constraint_edges.find(k)==-1 && constraint_edges.find((k-1)<0?N-1:k-1)==-1)
00718 m.connectivity().add(MC_int_vector(k,N+1+map_index_middle[k],N,N+1+map_index_middle[k-1>=0?k-1:map_index_middle.size()-1]));
00719
00720 else if(constraint_edges.find(k)!=-1 && constraint_edges.find((k-1)<0?N-1:k-1)==-1)
00721 {
00722 m.connectivity().add(MC_int_vector(k,N,N+1+map_index_middle[k-1>=0?k-1:map_index_middle.size()-1]));
00723 m.connectivity().add(MC_int_vector(k,(k+1)%N,N));
00724 }
00725
00726 else if(constraint_edges.find(k)==-1 && constraint_edges.find((k-1)<0?N-1:k-1)!=-1)
00727 m.connectivity().add(MC_int_vector(k,N+1+map_index_middle[k],N));
00728
00729 else if(constraint_edges.find(k)!=-1 && constraint_edges.find((k-1)<0?N-1:k-1)!=-1)
00730 m.connectivity().add(MC_int_vector(k,(k+1)%N,N));
00731 }
00732 return std::make_pair(m.get_polygon(),std::make_pair(m,std::make_pair(extra_index,edge) ) );
00733
00734 }
00735 std::pair<std::vector <MC_polygon>,std::pair<MC_mesh_index_vector,std::pair<MC_int_vector,MC_int_vector> > > MC_polygon::subdivide_mixed_mid_edge(const MC_int_vector& constraint_edges) const
00736 {
00737 if(size()<3)
00738 {std::cout<<"Error in MC_polygon::subdivide_mixed_mid_edge(), polygon has size "<<size()<<std::endl;exit(-1);}
00739 if(size()==3)
00740 return subdivide_mid_edge(constraint_edges);
00741 else
00742 return subdivide_barycenter_mid_edge(constraint_edges);
00743 }
00744
00745 bool MC_polygon::is_degenerated() const
00746 {
00747 std::set <MC_v3d,MC_v3d_less> set_poly;
00748 int N=size();
00749 for(int k=0;k<N;k++)
00750 if(set_poly.insert(v[k]).second==false)
00751 return true;
00752 return false;
00753 }
00754
00755 std::pair<MC_polygon,std::pair<bool,bool> > MC_polygon::undegenerated() const
00756 {
00757 std::set <MC_v3d,MC_v3d_less> set_poly;
00758 int N=size();
00759 std::pair <MC_polygon,std::pair <bool,bool> > new_pol(MC_polygon(),std::pair<bool,bool>(true,true));
00760 for(int k=0;k<N;k++)
00761 if(set_poly.insert(v[k]).second==true)
00762 new_pol.first.add(v[k]);
00763 else
00764 new_pol.second.first=false;
00765
00766 if(new_pol.first.size()>=3)
00767 new_pol.second.second=true;
00768 else
00769 new_pol.second.second=false;
00770
00771
00772 return new_pol;
00773 }
00774
00775
00776
00777
00778
00779
00780
00781
00782 }