pm_overlayer.h

来自「CGAL is a collaborative effort of severa」· C头文件 代码 · 共 795 行 · 第 1/2 页

H
795
字号
  Output_from_plane_maps Out(*this,&PI[0],&PI[1],From);  pm_overlay_sweep SOS(Seg_it_pair(Segments.begin(),Segments.end()),Out,K);  SOS.sweep();  create_face_objects(Out);  CGAL_NEF_TRACEN("transfering marks");  Face_iterator f = this->faces_begin(); assoc_info(f);  for (i=0; i<2; ++i) mark(f,i) = PI[i].mark(PI[i].faces_begin());  Vertex_iterator v, vend = this->vertices_end();  for (v = this->vertices_begin(); v != vend; ++v) {    CGAL_NEF_TRACEN("mark at "<<PV(v));    Halfedge_handle e_below = halfedge_below(v);    Mark m_below[2];    if ( e_below != Halfedge_handle() ) {      for (int i=0; i<2; ++i) {        m_below[i] = incident_mark(e_below,i);       }    } else { // e_below does not exist      for (int i=0; i<2; ++i)         m_below[i] = PI[i].mark(PI[i].faces_begin());    }    for (i=0; i<2; ++i)       if ( supp_halfedge(v,i) != Halfedge_const_handle() ) {        mark(v,i) = PI[i].mark(supp_halfedge(v,i));      } else if ( supp_vertex(v,i) != Vertex_const_handle() ) {        mark(v,i) = PI[i].mark(supp_vertex(v,i));      } else {        mark(v,i) = m_below[i];      }    if ( is_isolated(v) ) continue;    Halfedge_around_vertex_circulator       e(first_out_edge(v)), hend(e);    CGAL_For_all(e,hend) {      if ( is_forward(e) ) {        CGAL_NEF_TRACEN("   halfedge "<<PE(e));        Halfedge_const_handle ei;        bool supported;        for (int i=0; i<2; ++i) {          supported = ( supp_halfedge(e,i) != Halfedge_const_handle() );          if ( supported ) {            ei = supp_halfedge(e,i);            CGAL_NEF_TRACEN("   supp halfedge "<<i<<" "<<PE(ei));            incident_mark(twin(e),i) =               PI[i].mark(PI[i].face(PI[i].twin(ei)));            mark(e,i) = PI[i].mark(ei);            incident_mark(e,i) = m_below[i] =              PI[i].mark(PI[i].face(ei));          } else { // no support from input PI[i]            incident_mark(twin(e),i) = mark(e,i) = incident_mark(e,i) =               m_below[i];          }        }      } else break;    }  }  for (f = ++this->faces_begin(); f != this->faces_end(); ++f) { // skip first face    assoc_info(f);    for (i=0; i<2; ++i) mark(f,i) = incident_mark(halfedge(f),i);  }}template <typename Selection>void select(Selection& predicate) const/*{\Mop sets the marks of all objects according to the selectionpredicate |predicate|. |Selection| has to be a function object typewith a function operator\\ [[Mark operator()(Mark m0, Mark m1)]]\\ Foreach object |u| of |P| enriched by the marks of the supporting objectsaccording to the previous procedure |subdivide|, after this operation|\Mvar.mark(u) = predicate ( \Mvar.mark(u,0),\Mvar.mark(u,1) )|. Theadditional marks are invalidated afterwards. }*/{   Vertex_iterator vit = this->vertices_begin(),                  vend = this->vertices_end();  for( ; vit != vend; ++vit) {    mark(vit) = predicate(mark(vit,0),mark(vit,1));    discard_info(vit);   }  Halfedge_iterator hit = this->halfedges_begin(),                    hend = this->halfedges_end();  for(; hit != hend; ++(++hit)) {    mark(hit) = predicate(mark(hit,0),mark(hit,1));    discard_info(hit);  }  Face_iterator fit = this->faces_begin(),                fend = this->faces_end();  for(; fit != fend; ++fit) {    mark(fit) = predicate(mark(fit,0),mark(fit,1));    discard_info(fit);  }}template <typename Keep_edge>void simplify(const Keep_edge& keep) const/*{\Mop simplifies the structure of |P| according to the marks ofits objects. An edge |e| separating two faces |f1| and |f2| and equalmarks |mark(e) == mark(f1) == mark(f2)| is removed and the faces areunified.  An isolated vertex |v| in a face |f| with |mark(v)==mark(f)|is removed.  A vertex |v| with outdegree two, two collinear out-edges|e1|,|e2| and equal marks |mark(v) == mark(e1) == mark(e2)| is removedand the edges are unified. The data accessor |keep| requires the functioncall operator\\[[bool operator()(Halfedge_handle e)]]\\that allows toavoid the simplification for edge pairs referenced by |e|.}*/{  CGAL_NEF_TRACEN("simplifying");   typedef typename CGAL::Union_find<Face_handle>::handle Union_find_handle;  CGAL::Unique_hash_map< Face_iterator, Union_find_handle> Pitem;  CGAL::Union_find<Face_handle> unify_faces;  Face_iterator f, fend = this->faces_end();  for (f = this->faces_begin(); f!= fend; ++f) {      Pitem[f] = unify_faces.make_set(f);     clear_face_cycle_entries(f);  }  Halfedge_iterator e = this->halfedges_begin(), en,                    eend = this->halfedges_end();  for(; en=e, ++(++en), e != eend; e=en) {     if ( keep(e) ) continue;    if ( mark(e) == mark(face(e)) &&         mark(e) == mark(face(twin(e))) ) {        CGAL_NEF_TRACEN("deleting "<<PE(e));      if ( !unify_faces.same_set(Pitem[face(e)],                                 Pitem[face(twin(e))]) ) {        unify_faces.unify_sets( Pitem[face(e)],                                Pitem[face(twin(e))] );        CGAL_NEF_TRACEN("unioning disjoint faces");      }      if ( is_closed_at_source(e) )       set_face(source(e),face(e));      if ( is_closed_at_source(twin(e)) ) set_face(target(e),face(e));      delete_halfedge_pair(e);    }  }  CGAL::Unique_hash_map<Halfedge_handle,bool> linked(false);  for (e = this->halfedges_begin(); e != eend; ++e) {    if ( linked[e] ) continue;    Halfedge_around_face_circulator hfc(e),hend(hfc);    Halfedge_handle e_min = e;    Face_handle f = *(unify_faces.find(Pitem[face(e)]));    CGAL_For_all(hfc,hend) {      set_face(hfc,f);      if ( K.compare_xy(point(target(hfc)), point(target(e_min))) < 0 )        e_min = hfc;      linked[hfc]=true;    }    Point p1 = point(source(e_min)),          p2 = point(target(e_min)),          p3 = point(target(next(e_min)));    if ( K.orientation(p1,p2,p3) > 0 ) set_halfedge(f,e_min); // outer    else set_hole(f,e_min); // store as inner  }  Vertex_iterator v, vn, vend = this->vertices_end();  for(v = this->vertices_begin(); v != vend; v=vn) { CGAL_NEF_TRACEN("at vertex "<<PV(v));    vn=v; ++vn;    if ( is_isolated(v) ) {      if ( mark(v) == mark(face(v)) ) delete_vertex_only(v);      else set_isolated_vertex(face(v),v);     } else { // v not isolated      Halfedge_handle e2 = first_out_edge(v), e1 = previous(e2);      Point p1 = point(source(e1)), p2 = point(v),             p3 = point(target(e2));      if ( has_outdeg_two(v) &&           mark(v) == mark(e1) && mark(v) == mark(e2) &&           (K.orientation(p1,p2,p3) == 0) )         merge_halfedge_pairs_at_target(e1);     }  }  Face_iterator fn;  for (f = this->faces_begin(); f != fend; f=fn) {    fn=f; ++fn;    Union_find_handle pit = Pitem[f];    if ( unify_faces.find(pit) != pit ) delete_face(f);  }}struct vertex_info {  Mark                  m[2];  Vertex_const_handle   v_supp[2];  Halfedge_const_handle e_supp[2];  Halfedge_handle       e_below;  vertex_info()   { v_supp[0]=v_supp[1]=Vertex_const_handle();     e_supp[0]=e_supp[1]=Halfedge_const_handle(); }  LEDA_MEMORY(vertex_info)};void assoc_info(Vertex_handle v) const{ geninfo<vertex_info>::create(info(v)); }void discard_info(Vertex_handle v) const{ geninfo<vertex_info>::clear(info(v)); }vertex_info& ginfo(Vertex_handle v) const{ return geninfo<vertex_info>::access(info(v)); }Mark& mark(Vertex_handle v, int i) const{ return ginfo(v).m[i]; }Vertex_const_handle& supp_vertex(Vertex_handle v, int i) const{ return ginfo(v).v_supp[i]; }Halfedge_const_handle& supp_halfedge(Vertex_handle v, int i) const{ return ginfo(v).e_supp[i]; }Halfedge_handle& halfedge_below(Vertex_handle v) const{ return ginfo(v).e_below; }struct halfedge_info {  Mark                  m[2];  Mark                  mf[2];  Halfedge_const_handle e_supp[2];  bool                  forw;  halfedge_info()  { m[0]=m[1]=mf[0]=mf[1]=Mark();     e_supp[0]=e_supp[1]=Halfedge_const_handle();     forw=false; }  LEDA_MEMORY(halfedge_info)};void assoc_info(Halfedge_handle e)  const{ geninfo<halfedge_info>::create(info(e));   geninfo<halfedge_info>::create(info(twin(e))); }void discard_info(Halfedge_handle e)  const{ geninfo<halfedge_info>::clear(info(e));   geninfo<halfedge_info>::clear(info(twin(e))); }halfedge_info& ginfo(Halfedge_handle e)  const{ return geninfo<halfedge_info>::access(info(e)); }Mark& mark(Halfedge_handle e, int i)  const// uedge information we store in the smaller one { if (&*e < &*(twin(e))) return ginfo(e).m[i];   else                   return ginfo(twin(e)).m[i]; }Halfedge_const_handle& supp_halfedge(Halfedge_handle e, int i) const// uedge information we store in the smaller one { if (&*e < &*(twin(e))) return ginfo(e).e_supp[i];   else                   return ginfo(twin(e)).e_supp[i]; }Mark& incident_mark(Halfedge_handle e, int i)  const// biedge information we store in the halfedge{ return ginfo(e).mf[i]; }bool& is_forward(Halfedge_handle e) const// biedge information we store in the halfedge{ return ginfo(e).forw; }struct face_info {  Mark m[2];  face_info() { m[0]=m[1]=Mark(); }  LEDA_MEMORY(face_info)};void assoc_info(Face_handle f)  const{ geninfo<face_info>::create(info(f)); }void discard_info(Face_handle f)  const{ geninfo<face_info>::clear(info(f)); }face_info& ginfo(Face_handle f)  const{ return geninfo<face_info>::access(info(f)); }Mark& mark(Face_handle f, int i)  const{ return ginfo(f).m[i]; }void clear_associated_info_of_all_objects() const {  Vertex_iterator vit;  for (vit = this->vertices_begin(); vit != this->vertices_end(); ++vit)    discard_info(vit);  Halfedge_iterator hit;  for (hit = this->halfedges_begin(); hit != this->halfedges_end(); ++hit)     discard_info(hit);  Face_iterator fit;  for (fit = this->faces_begin(); fit != this->faces_end(); ++fit)     discard_info(fit);}template <typename Below_info>void create_face_objects(const Below_info& D) const{  CGAL_NEF_TRACEN("create_face_objects()");  CGAL::Unique_hash_map<Halfedge_handle,int> FaceCycle(-1);  std::vector<Halfedge_handle>  MinimalHalfedge;  int i=0;  Halfedge_iterator e, eend = this->halfedges_end();  for (e=this->halfedges_begin(); e != eend; ++e) {    if ( FaceCycle[e] >= 0 ) continue; // already assigned    Halfedge_around_face_circulator hfc(e),hend(hfc);    Halfedge_handle e_min = e;    CGAL_NEF_TRACE("face cycle "<<i<<"\n");    CGAL_For_all(hfc,hend) {      FaceCycle[hfc]=i; // assign face cycle number      if ( K.compare_xy(point(target(hfc)), point(target(e_min))) < 0 )        e_min = hfc;      CGAL_NEF_TRACE(PE(hfc));    }     CGAL_NEF_TRACEN("");    MinimalHalfedge.push_back(e_min); ++i;  }  Face_handle f_outer = this->new_face();  for (int j=0; j<i; ++j) {    Halfedge_handle e = MinimalHalfedge[j];      CGAL_NEF_TRACEN("  face cycle "<<j);CGAL_NEF_TRACEN("  minimal halfedge "<<PE(e));    Point p1 = point(source(e)),           p2 = point(target(e)),           p3 = point(target(next(e)));    if ( K.left_turn(p1,p2,p3) ) { // left_turn => outer face cycle        CGAL_NEF_TRACEN("  creating new face object");      Face_handle f = this->new_face();      link_as_outer_face_cycle(f,e);    }  }  for (e = this->halfedges_begin(); e != eend; ++e) {    if ( face(e) != Face_handle() ) continue;    CGAL_NEF_TRACEN("linking hole "<<PE(e));    Face_handle f = determine_face(e,MinimalHalfedge,FaceCycle,D);    link_as_hole(f,e);  }  Vertex_iterator v, v_end = this->vertices_end();  for (v = this->vertices_begin(); v != v_end; ++v) {    if ( !is_isolated(v) ) continue;    Halfedge_handle e_below = D.halfedge_below(v);    if ( e_below == Halfedge_handle() )       link_as_isolated_vertex(f_outer,v);    else      link_as_isolated_vertex(face(e_below),v);      }}template <typename Below_info>Face_handle determine_face(Halfedge_handle e,   const std::vector<Halfedge_handle>& MinimalHalfedge,  const CGAL::Unique_hash_map<Halfedge_handle,int>& FaceCycle,  const Below_info& D) const{ CGAL_NEF_TRACEN("determine_face "<<PE(e));  Halfedge_handle e_min = MinimalHalfedge[FaceCycle[e]];  Halfedge_handle e_below = D.halfedge_below(target(e_min));  if ( e_below == Halfedge_handle() ) // below is nirwana    return this->faces_begin();  Face_handle f = face(e_below);  if (f != Face_handle()) return f; // has face already  f = determine_face(e_below, MinimalHalfedge, FaceCycle,D);  link_as_hole(f,e_below);  return f;}Segment segment(const Const_decorator& N,                 Halfedge_const_handle e) const{ return K.construct_segment(    N.point(N.source(e)),N.point(N.target(e))); }Segment segment(const Const_decorator& N,                 Vertex_const_handle v) const{ Point p = N.point(v);   return K.construct_segment(p,p); }bool is_forward_edge(const Const_decorator& N,                      Halfedge_const_iterator hit) const{ Point p1 = N.point(N.source(hit));  Point p2 = N.point(N.target(hit));  return (K.compare_xy(p1,p2) < 0); }void assert_type_precondition() const{ typename PM_decorator_::Point p1; Point p2;  assert_equal_types(p1,p2); }}; // PM_overlayer<PM_decorator_,Geometry_>CGAL_END_NAMESPACE#endif // CGAL_PM_OVERLAYER_H

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?