MC_polygon.cpp

Go to the documentation of this file.
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             //std::cout<<"Warning in MC_polygon::normal(), from polygon "<<*this<<", normal is "<<n<<" of norm()="<<nn<<std::endl;
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         // get the projection on the plane
00092         MC_v3d projection=x-((x-v[0]).dot(n))*n;
00093 
00094         // get triangulation
00095         std::vector <MC_triangle> triangles=MC_triangle::triangulate(*this);
00096 
00097         // first, try to find if the projection is inside the polygon (in one of the triangle)
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         // then, the projection is outside the polygon
00109         // find the closest edge
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         //look if the closest point is inside an edge, or a vertex
00131         for(int k=0;k<size();k++)
00132             if( (closest-v[k]).norm() < epsilon) //then it is close to a vertex
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         // First, take every intersection with every segment
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 //std::cout<<"============"<<std::endl;
00162 
00163         // look if there is no intersection that all
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)//no intersection
00169         {
00170             if(type!=0)
00171                 *type=0;
00172             return intersections;
00173         }
00174 
00175 
00176         // look if there is only one vertex in common
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                 //printf("Error in Polygon in plane_intersection, types are not corrects\n");
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         // there is two intersections
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                     //std::cout<<intersections<<std::endl;
00216 
00217                     return intersections;
00218                 }
00219             }
00220         }
00221 
00222 
00223         //else probleme
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         //first take the intersection of the polygon and the plane
00243         MC_v3d_vector intersection;
00244         int type_edges=0;
00245         intersection = plane_intersection(n,x0,&type_edges);
00246 
00247 
00248 
00249         //check if we need to cut or not the polygon
00250         MC_polygon new_polygon;
00251         if(type_edges!=1) // no change or just destroy the polygon
00252         {
00253             if(((*this)[0]-x0).dot(n)<0)//check the orientation of the polygon to the plane
00254             {
00255                 //negative so there is no more polygons
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                 // the polygon is unchanged
00264                 if(type!=0)
00265                     *type=0;
00266                 return *this;
00267             }
00268         }
00269 
00270         //else there is a modification to bring to the polygon
00271 
00272         if(type!=0)
00273             *type=1;
00274         MC_segment s(intersection[0],intersection[1]);
00275         MC_v3d old_normal=normal();
00276 
00277         //first add every points in the correct half space
00278         //(just to be sure that we know the vertex before the line)
00279 
00280         //find the first vertex in half space
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                 // check if the line is in the right sense (we are sure that (*this[k2-1] already exists))
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         //first get the polygon in 2D
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         // direction equation
00359         // c0+t*d => ax+by=c
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)//parallel
00380                 {
00381                     double xi=(rb*c-rc*b)/det;
00382                     double yi=(rc*a-ra*c)/det;
00383 
00384                     //if (xi,yi) in the positive sens
00385                     if( (xi-c0_2d[0])*d_2d[0]+(yi-c0_2d[1])*d_2d[1] >0 )
00386                     {
00387 
00388                         // check if inside
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) //vertex 0
00404                                 {type=0; sub_type=k_seg; relative=0.0;}
00405                                 else if(abs(proj-1)<epsilon) //vertex 1
00406                                 {type=0; sub_type=(k_seg+1)%N; relative=0.0;}
00407                                 else //edge
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)//no intersection (point outside)
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         //check the position
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) // vertex
00445         {bar[pos[1]]=1.0;return bar;}
00446         if(pos[0]==1) // edge
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         //else inside the polygon
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         // the new midpoints
00489         MC_v3d_vector mid_points;
00490         // as much mid point as there is vertices in the polygon
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         // the new polygons
00498         std::vector <MC_polygon> new_polygon;
00499         // size of new_polygon = (old)N_vertex + 1
00500         new_polygon.resize(N_mid_points+1);
00501 
00502         // all triangles excepted the last on linking the mid_points
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         //last one linking every mid_points
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         // the new midpoints
00520         MC_v3d_vector mid_points;
00521 
00522         // as much mid point as there is vertices in the polygon
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         // in case there is no constraint
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             // all triangles excepted the last on linking the mid_points
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             //last one linking every mid_points
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) //only one non subdivided edge
00574         {
00575             //find the non subdivided edge
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         //other case, only link the subdivided part
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         //finish by the connectivity
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)//fill the middle
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         // in case there is no constraint
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             //classical quads
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             // previous ok but new one is a boundary
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             // previous is boundary, but next is ok
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             // not ok, just triangle
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 }

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