surface_mesher_regular_edges.h

来自「很多二维 三维几何计算算法 C++ 类库」· C头文件 代码 · 共 343 行

H
343
字号
// Copyright (c) 2003-2006  INRIA Sophia-Antipolis (France).// All rights reserved.//// This file is part of CGAL (www.cgal.org); you may redistribute it under// the terms of the Q Public License version 1.0.// See the file LICENSE.QPL distributed with CGAL.//// Licensees holding a valid commercial license may use this file in// accordance with the commercial license agreement provided with the software.//// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.//// $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.3-branch/Surface_mesher/include/CGAL/Surface_mesher/Surface_mesher_regular_edges.h $// $Id: Surface_mesher_regular_edges.h 36704 2007-02-28 18:22:28Z lrineau $////// Author(s)     : Steve Oudot, David Rey, Mariette Yvinec, Laurent Rineau, Andreas Fabri#ifndef CGAL_SURFACE_MESHER_REGULAR_EDGES_H#define CGAL_SURFACE_MESHER_REGULAR_EDGES_H#include <CGAL/Surface_mesher/Surface_mesher.h>#include <CGAL/utility.h>#include <CGAL/circulator.h>#include <set>namespace CGAL {  namespace Surface_mesher {  template <    class C2T3,    class Surface,    class SurfaceMeshTraits,    class Criteria,    bool withBoundary = false    >  class Surface_mesher_regular_edges_base    : public Surface_mesher_base<C2T3, Surface, SurfaceMeshTraits, Criteria>  {    public:      typedef Surface_mesher_base<C2T3, Surface, SurfaceMeshTraits, Criteria> SMB ;      typedef C2T3 C2t3;      typedef typename C2T3::Triangulation Tr;      typedef typename Tr::Geom_traits GT;      typedef typename GT::FT FT;      typedef typename Tr::Point Point;      typedef typename Tr::Facet Facet;      typedef typename Tr::Edge Edge;      typedef typename Tr::Cell_handle Cell_handle;      typedef typename Tr::Vertex_handle Vertex_handle;      typedef std::pair<Vertex_handle, Vertex_handle> EdgeVV;      typedef typename Triangulation_mesher_level_traits_3<Tr>::Zone Zone;      typedef std::list<Edge> Edges;      typedef std::list<Facet> Facets;      typedef Const_circulator_from_container<Facets> Facet_circulator;      typedef typename Tr::Finite_edges_iterator Finite_edges_iterator;  protected:    mutable std::set <std::pair <Vertex_handle, Vertex_handle> > bad_edges;    mutable bool bad_edges_initialized;    protected:      // computes and return an ordered pair of Vertex      EdgeVV make_edgevv(const Vertex_handle vh1,			 const Vertex_handle vh2) const {	if (vh1 < vh2) {	  return std::make_pair(vh1, vh2);	}	else {	  return std::make_pair(vh2, vh1);	}      }      // computes and returns the Edge type object from the EdgeVV object      // use tr.is_edge(...)      Edge edgevv_to_edge(const EdgeVV& arete) const {    	Vertex_handle sommet1 = arete.first;    	Vertex_handle sommet2 = arete.second;    	Cell_handle c;	int index1, index2;	SMB::tr.is_edge(sommet1, sommet2, c, index1, index2);    	return make_triple( c, index1, index2 );      }      // computes and returns the EdgeVV type object from the Edge object      EdgeVV edge_to_edgevv(const Edge& arete) const {	return make_edgevv(arete.first->vertex(arete.second),			   arete.first->vertex(arete.third) );      }      // computes and returns the list of Edges in a given Facet side      Edges edges_in_facet(const Facet& cote) const {	Edges loe;	Cell_handle c = cote.first;	int i = cote.second;	for (int j = 0; j < 3; j++) {	  for (int k = j + 1; k < 4; k++) {	    if ( (i != j) && (i != k) ){	      loe.push_back(make_triple(c, j, k));	    }	  }	}	return loe;      }        FT compute_distance_to_facet_center(const Facet& f,					const Vertex_handle v) const {      const Point& fcenter = f.first->get_facet_surface_center(f.second);      const Point& vpoint = v->point();      return SMB::tr.geom_traits().compute_squared_distance_3_object()(fcenter,								  vpoint );    }      Facet biggest_incident_facet_in_complex(const Edge& arete) const {	// Find the first facet in the incident facets        // of the edge which is in the Complex	// use the list of incident facets in the complex	Facet_circulator fcirc = SMB::c2t3.incident_facets(arete);	Facet first_facet = *fcirc;	Facet biggest_facet = first_facet;	for (++fcirc;	     (*fcirc != first_facet) &&	       (*fcirc != SMB::mirror_facet(first_facet));	     ++fcirc) {	  Vertex_handle fev = edge_to_edgevv(arete).first;	  // is the current facet bigger than the current biggest one	  if ( compute_distance_to_facet_center(*fcirc, fev) >	       compute_distance_to_facet_center(biggest_facet,                                                fev) ) {	    biggest_facet = *fcirc;	  }	  else { // @TODO: il ne faut pas aller voir des deux cotes: c'est		 // le meme centre de facet!!!	    Facet autre_cote = SMB::mirror_facet(*fcirc);	    // is the current facet bigger than the current biggest one	    if ( compute_distance_to_facet_center(autre_cote, fev) >		 compute_distance_to_facet_center(biggest_facet, fev) ) {	      biggest_facet = autre_cote;	    }	  }	}	return biggest_facet;      }      ///////////////////////      // For before_insertion      // Actions to perform on a facet inside the conflict zone      void handle_facet_inside_conflict_zone (const Facet& f) {	Facet cote = f;	Facet autre_cote = SMB::mirror_facet(cote);	if ( SMB::c2t3.face_status(cote) !=	     C2t3::NOT_IN_COMPLEX ) {	  Edges loe = edges_in_facet(cote);	  // foreach edge of cote	  for ( typename Edges::iterator eit = loe.begin();		eit != loe.end();		++eit) {	    bad_edges.erase( edge_to_edgevv(*eit) );	  }	}      }      // Action to perform on a facet on the boundary of the conflict zone      void handle_facet_on_boundary_of_conflict_zone (const Facet& f) {	// perform the same operations as for an internal facet	handle_facet_inside_conflict_zone (f);      }    public:      Surface_mesher_regular_edges_base(C2T3& c2t3,                                        const Surface& surface,                                        const SurfaceMeshTraits& mesh_traits,                                        const Criteria& criteria)        : SMB(c2t3, surface, mesh_traits, criteria),          bad_edges_initialized(false)    {#ifdef CGAL_SURFACE_MESHER_DEBUG_CONSTRUCTORS      std::cerr << "CONS: Surface_mesher_regular_edges_base";      if(withBoundary)        std::cerr << " (with boundaries)\n";      else        std::cerr << " (without boundary)\n";#endif    }    // Initialization function    void initialize_bad_edges() const {#ifdef CGAL_SURFACE_MESHER_VERBOSE      std::cerr << "\r             \rscanning edges ";      if(withBoundary)        std::cerr << "(boundaries allowed)";      std::cerr << "...\n";#endif      int n = 0;      for (Finite_edges_iterator eit = SMB::tr.finite_edges_begin(); eit !=	     SMB::tr.finite_edges_end(); ++eit) {	if ( (SMB::c2t3.face_status(*eit)	      == C2t3::SINGULAR) ||	     ( (!withBoundary) &&	       (SMB::c2t3.face_status(*eit)		== C2t3::BOUNDARY) ) ) {	  bad_edges.insert( edge_to_edgevv(*eit) );          ++n;	}      }      bad_edges_initialized = true;#ifdef CGAL_SURFACE_MESHER_VERBOSE	std::cerr << "   -> found " << n << " bad edges\n";#endif    }    void scan_triangulation_impl() {      SMB::scan_triangulation_impl();#ifdef CGAL_SURFACE_MESHER_VERBOSE      std::cerr << "scanning edges (lazy)" << std::endl;#endif    }    // Tells whether there remain elements to refine    bool no_longer_element_to_refine_impl() const {      if(SMB::no_longer_element_to_refine_impl())      {        if( ! bad_edges_initialized )          initialize_bad_edges();        return bad_edges.empty();      }      return false;    }    // Returns the next element to refine    Facet get_next_element_impl() {      if (!SMB::no_longer_element_to_refine_impl()) {	return SMB::get_next_element_impl();      }      else {        CGAL_assertion(bad_edges_initialized);	Edge first_bad_edge = edgevv_to_edge(*(bad_edges.begin()));	return biggest_incident_facet_in_complex(first_bad_edge);      }    }    void before_insertion_impl(const Facet&, const Point& s,			       Zone& zone) {      if( bad_edges_initialized )      {        for (typename Zone::Facets_iterator fit =               zone.internal_facets.begin();             fit != zone.internal_facets.end();             ++fit)          handle_facet_inside_conflict_zone (*fit);        for (typename Zone::Facets_iterator fit =               zone.boundary_facets.begin(); fit !=               zone.boundary_facets.end(); ++fit)          handle_facet_on_boundary_of_conflict_zone (*fit);      }      SMB::before_insertion_impl(Facet(), s, zone);    }    void after_insertion_impl(const Vertex_handle v) {      SMB::after_insertion_impl(v);      if( ! bad_edges_initialized )        return;      // search for incident facets around v      Facets facets;      SMB::tr.incident_facets (v, std::back_inserter(facets));      // foreach f in star(v)      for (typename Facets::iterator fit = facets.begin();	   fit != facets.end();	   ++fit) {	Facet cote = *fit;	Edges loe = edges_in_facet(cote);	// foreach edge of cote	for ( typename Edges::iterator eit = loe.begin();	      eit != loe.end();	      ++eit ) {	  // test if edge is in Complex	  if ( SMB::c2t3.face_status(*eit)	       != C2t3::NOT_IN_COMPLEX ) {	    // test if edge is not regular to store it as a "bad_edge"	    // e.g. more than or equal to 3 incident facets (SINGULAR)	    // or less than or equal to 1	    // (BOUNDARY only, because ISOLATED is NA)	    // This test is not efficient because	    // edges are tried to be inserted several times	    // TODO one day: test if the edge is still singular	    if ( (SMB::c2t3.face_status(*eit)		  == C2t3::SINGULAR) ||		 ( (!withBoundary) &&		   (SMB::c2t3.face_status(*eit)		    == C2t3::BOUNDARY) ) ) {	      bad_edges.insert( edge_to_edgevv(*eit) );	    }	    else {	      bad_edges.erase( edge_to_edgevv(*eit) ); // @TODO: pourquoi?!	    }	  }	}      }    }    std::string debug_info() const    {      std::stringstream s;      s << SMB::debug_info() << "," << bad_edges.size();      return s.str();    }    static std::string debug_info_header()    {      return SMB::debug_info_header() + "," + "number of bad edges";    }  };  // end Surface_mesher_regular_edges_base  }  // end namespace Surface_mesher}  // end namespace CGAL#endif // CGAL_SURFACE_MESHER_REGULAR_EDGES_H

⌨️ 快捷键说明

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