mirror of https://github.com/CGAL/cgal
Refresh the branch Mesh_3-manifold_criterion-lrineau
For the moment, the manifold feature is no longer working. Merge remote-tracking branch 'cgal-dev/Mesh_3-manifold_criterion-lrineau' into Mesh_3-manifold_criterion-lrineau Conflicts: Mesh_3/include/CGAL/Mesh_3/Mesh_complex_3_in_triangulation_3_base.h Mesh_3/include/CGAL/Mesh_3/Mesher_3.h Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h Polyhedron/demo/Polyhedron/Polyhedron_3.cpp Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin.cpp Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin_cgal_code.cpp
This commit is contained in:
commit
e0f8f4f85f
|
|
@ -74,7 +74,7 @@ namespace CGAL {
|
||||||
m.pop_front();
|
m.pop_front();
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove_element(Element& e)
|
void remove_element(const Element& e)
|
||||||
{
|
{
|
||||||
#if CGAL_MESHES_DEBUG_DOUBLE_MAP
|
#if CGAL_MESHES_DEBUG_DOUBLE_MAP
|
||||||
std::cerr << "remove_element(" << &*e << ")\n";
|
std::cerr << "remove_element(" << &*e << ")\n";
|
||||||
|
|
|
||||||
|
|
@ -58,19 +58,35 @@ template <typename C3t3>
|
||||||
struct Dump_c3t3<C3t3, false> {
|
struct Dump_c3t3<C3t3, false> {
|
||||||
void dump_c3t3(const C3t3&, std::string) {
|
void dump_c3t3(const C3t3&, std::string) {
|
||||||
std::cerr << "Warning " << __FILE__ << ":" << __LINE__ << "\n"
|
std::cerr << "Warning " << __FILE__ << ":" << __LINE__ << "\n"
|
||||||
<< " the c3t3 object cannot be dumped because some types are"
|
<< " the c3t3 object of following type:\n"
|
||||||
<< " not streamable:\n";
|
<< typeid(C3t3).name() << std::endl
|
||||||
if(!is_streamable<typename C3t3::Triangulation::Vertex>::value)
|
<< " cannot be dumped because some types are not streamable:\n";
|
||||||
|
if(!is_streamable<typename C3t3::Triangulation::Vertex>::value) {
|
||||||
std::cerr << " - C3t3::Triangulation::Vertex is not streamble\n";
|
std::cerr << " - C3t3::Triangulation::Vertex is not streamble\n";
|
||||||
|
std::cerr << " "
|
||||||
|
<< typeid(typename C3t3::Triangulation::Vertex).name()
|
||||||
|
<< "\n";
|
||||||
|
}
|
||||||
|
|
||||||
if(!is_streamable<typename C3t3::Triangulation::Cell>::value)
|
if(!is_streamable<typename C3t3::Triangulation::Cell>::value) {
|
||||||
std::cerr << " - C3t3::Triangulation::Cell is not streamble\n";
|
std::cerr << " - C3t3::Triangulation::Cell is not streamble\n";
|
||||||
|
std::cerr << " "
|
||||||
|
<< typeid(typename C3t3::Triangulation::Cell).name()
|
||||||
|
<< "\n";
|
||||||
|
}
|
||||||
|
|
||||||
if(!is_streamable<typename C3t3::Surface_patch_index>::value)
|
if(!is_streamable<typename C3t3::Surface_patch_index>::value) {
|
||||||
std::cerr << " - C3t3::Surface_patch_index is not streamable\n";
|
std::cerr << " - C3t3::Surface_patch_index is not streamable\n";
|
||||||
|
std::cerr << " "
|
||||||
if(!is_streamable<typename C3t3::Subdomain_index>::value)
|
<< typeid(typename C3t3::Surface_patch_index).name()
|
||||||
|
<< "\n";
|
||||||
|
}
|
||||||
|
if(!is_streamable<typename C3t3::Subdomain_index>::value) {
|
||||||
std::cerr << " - C3t3::Subdomain_index is not streamable\n";
|
std::cerr << " - C3t3::Subdomain_index is not streamable\n";
|
||||||
|
std::cerr << " "
|
||||||
|
<< typeid(typename C3t3::Subdomain_index).name()
|
||||||
|
<< "\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}; // end struct template specialization Dump_c3t3<C3t3, false>
|
}; // end struct template specialization Dump_c3t3<C3t3, false>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
// Copyright (c) 2009 INRIA Sophia-Antipolis (France).
|
// Copyright (c) 2003-2009 INRIA Sophia-Antipolis (France).
|
||||||
|
// Copyright (c) 2013 GeometryFactory Sarl (France).
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// This file is part of CGAL (www.cgal.org).
|
// This file is part of CGAL (www.cgal.org).
|
||||||
|
|
@ -16,7 +17,7 @@
|
||||||
// $Id$
|
// $Id$
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Author(s) : Stéphane Tayeb
|
// Author(s) : Laurent Rineau, Stéphane Tayeb
|
||||||
//
|
//
|
||||||
//******************************************************************************
|
//******************************************************************************
|
||||||
// File Description : Implements class Mesh_complex_3_in_triangulation_3.
|
// File Description : Implements class Mesh_complex_3_in_triangulation_3.
|
||||||
|
|
@ -35,6 +36,7 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <CGAL/Mesh_3/io_signature.h>
|
#include <CGAL/Mesh_3/io_signature.h>
|
||||||
|
#include <CGAL/Union_find.h>
|
||||||
|
|
||||||
#ifdef CGAL_LINKED_WITH_TBB
|
#ifdef CGAL_LINKED_WITH_TBB
|
||||||
#include <tbb/atomic.h>
|
#include <tbb/atomic.h>
|
||||||
|
|
@ -43,6 +45,46 @@
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
namespace Mesh_3 {
|
namespace Mesh_3 {
|
||||||
|
|
||||||
|
namespace details {
|
||||||
|
|
||||||
|
template <typename Tr>
|
||||||
|
class C3t3_helper_class
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
typedef typename Tr::Vertex_handle Vertex_handle;
|
||||||
|
typedef typename Tr::Cell_handle Cell_handle;
|
||||||
|
typedef typename Tr::Facet Facet;
|
||||||
|
typedef typename Tr::Edge Edge;
|
||||||
|
|
||||||
|
typedef std::pair<Vertex_handle, Vertex_handle> Pair_of_vertices;
|
||||||
|
|
||||||
|
// computes and return an ordered pair of Vertex
|
||||||
|
Pair_of_vertices
|
||||||
|
make_ordered_pair(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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// same from an Edge
|
||||||
|
Pair_of_vertices
|
||||||
|
make_ordered_pair(const Edge e) const {
|
||||||
|
return make_ordered_pair(e.first->vertex(e.second),
|
||||||
|
e.first->vertex(e.third));
|
||||||
|
}
|
||||||
|
|
||||||
|
Facet canonical_facet(Cell_handle c, int i) const {
|
||||||
|
Cell_handle c2 = c->neighbor(i);
|
||||||
|
return (c2 < c) ? std::make_pair(c2,c2->index(c)) : std::make_pair(c,i);
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // end class template C3t3_helper_class
|
||||||
|
|
||||||
|
} // end namespace Mesh_3::details
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class Mesh_complex_3_in_triangulation_3_base
|
* @class Mesh_complex_3_in_triangulation_3_base
|
||||||
* @brief A data-structure to represent and maintain a 3D complex embedded
|
* @brief A data-structure to represent and maintain a 3D complex embedded
|
||||||
|
|
@ -50,8 +92,10 @@ namespace Mesh_3 {
|
||||||
*/
|
*/
|
||||||
template<typename Tr, typename Concurrency_tag>
|
template<typename Tr, typename Concurrency_tag>
|
||||||
class Mesh_complex_3_in_triangulation_3_base
|
class Mesh_complex_3_in_triangulation_3_base
|
||||||
|
: public details::C3t3_helper_class<Tr>
|
||||||
{
|
{
|
||||||
typedef Mesh_complex_3_in_triangulation_3_base<Tr, Concurrency_tag> Self;
|
typedef Mesh_complex_3_in_triangulation_3_base<Tr, Concurrency_tag> Self;
|
||||||
|
typedef details::C3t3_helper_class<Tr> Base;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Triangulation types
|
// Triangulation types
|
||||||
|
|
@ -67,6 +111,26 @@ public:
|
||||||
typedef typename Tr::Cell::Surface_patch_index Surface_patch_index;
|
typedef typename Tr::Cell::Surface_patch_index Surface_patch_index;
|
||||||
typedef typename Tr::Vertex::Index Index;
|
typedef typename Tr::Vertex::Index Index;
|
||||||
|
|
||||||
|
enum Face_status{ NOT_IN_COMPLEX = 0,
|
||||||
|
ISOLATED = 1, // - An ISOLATED edge is a marked edge,
|
||||||
|
// without any incident facets.
|
||||||
|
BOUNDARY, // - An edge is on BOUNDARY if it has only
|
||||||
|
// one incident facet.
|
||||||
|
// - A vertex is on BOUNDARY if all its
|
||||||
|
// incident edges are REGULAR or on
|
||||||
|
// BOUNDARY, at least one is on
|
||||||
|
// BOUNDARY, and the incident facets
|
||||||
|
// form only one connected component.
|
||||||
|
REGULAR, // - A facet that is in the complex is
|
||||||
|
// REGULAR.
|
||||||
|
// - An edge is REGULAR if it has
|
||||||
|
// exactly two incident facets.
|
||||||
|
// - A vertex is REGULAR if all it
|
||||||
|
// incident edges are REGULAR, and the
|
||||||
|
// incident facets form only one
|
||||||
|
// connected component.
|
||||||
|
SINGULAR}; // - SINGULAR is for all other cases.
|
||||||
|
|
||||||
//-------------------------------------------------------
|
//-------------------------------------------------------
|
||||||
// Constructors / Destructors
|
// Constructors / Destructors
|
||||||
//-------------------------------------------------------
|
//-------------------------------------------------------
|
||||||
|
|
@ -75,7 +139,10 @@ public:
|
||||||
* Builds an empty 3D complex.
|
* Builds an empty 3D complex.
|
||||||
*/
|
*/
|
||||||
Mesh_complex_3_in_triangulation_3_base()
|
Mesh_complex_3_in_triangulation_3_base()
|
||||||
: tr_()
|
: Base()
|
||||||
|
, tr_()
|
||||||
|
, edge_facet_counter_() //TODO: parallel!
|
||||||
|
, manifold_info_initialized_(false) //TODO: parallel!
|
||||||
{
|
{
|
||||||
// We don't put it in the initialization list because
|
// We don't put it in the initialization list because
|
||||||
// tbb::atomic has no contructors
|
// tbb::atomic has no contructors
|
||||||
|
|
@ -85,7 +152,10 @@ public:
|
||||||
|
|
||||||
/// Copy constructor
|
/// Copy constructor
|
||||||
Mesh_complex_3_in_triangulation_3_base(const Self& rhs)
|
Mesh_complex_3_in_triangulation_3_base(const Self& rhs)
|
||||||
: tr_(rhs.tr_)
|
: Base()
|
||||||
|
, tr_(rhs.tr_)
|
||||||
|
, edge_facet_counter_(rhs.edge_facet_counter_)
|
||||||
|
, manifold_info_initialized_(rhs.manifold_info_initialized_)
|
||||||
{
|
{
|
||||||
number_of_facets_ = rhs.number_of_facets_;
|
number_of_facets_ = rhs.number_of_facets_;
|
||||||
number_of_cells_ = rhs.number_of_cells_;
|
number_of_cells_ = rhs.number_of_cells_;
|
||||||
|
|
@ -98,6 +168,8 @@ public:
|
||||||
number_of_cells_ = 0;
|
number_of_cells_ = 0;
|
||||||
number_of_facets_ = 0;
|
number_of_facets_ = 0;
|
||||||
tr_.clear();
|
tr_.clear();
|
||||||
|
manifold_info_initialized_ = false;
|
||||||
|
edge_facet_counter_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Assignment operator
|
/// Assignment operator
|
||||||
|
|
@ -146,6 +218,87 @@ public:
|
||||||
cell->set_surface_patch_index(i, index);
|
cell->set_surface_patch_index(i, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `NOT_IN_COMPLEX`, `BOUNDARY`, `REGULAR`, or `SINGULAR`,
|
||||||
|
/// depending on the number of incident facets in the complex, and the
|
||||||
|
/// number of connected components of its link
|
||||||
|
Face_status face_status(const Vertex_handle v) const
|
||||||
|
{
|
||||||
|
if(!manifold_info_initialized_) init_manifold_info();
|
||||||
|
const int n = v->cached_number_of_incident_facets();
|
||||||
|
|
||||||
|
if(n == 0) return NOT_IN_COMPLEX;
|
||||||
|
|
||||||
|
//test incident edges for REGULARITY and count BOUNDARY edges
|
||||||
|
typename std::vector<Edge> edges;
|
||||||
|
edges.reserve(64);
|
||||||
|
tr_.incident_edges(v, std::back_inserter(edges));
|
||||||
|
int number_of_boundary_incident_edges = 0; // could be a bool
|
||||||
|
for (typename std::vector<Edge>::iterator
|
||||||
|
eit=edges.begin(), end = edges.end();
|
||||||
|
eit != end; eit++)
|
||||||
|
{
|
||||||
|
switch( face_status(*eit) )
|
||||||
|
{
|
||||||
|
case NOT_IN_COMPLEX: case REGULAR: break;
|
||||||
|
case BOUNDARY: ++number_of_boundary_incident_edges; break;
|
||||||
|
default :
|
||||||
|
#ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
std::cerr << "singular edge...\n";
|
||||||
|
std::cerr << v->point() << std::endl;
|
||||||
|
#endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
return SINGULAR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// From here all incident edges (in complex) are REGULAR or BOUNDARY.
|
||||||
|
const int nb_components = union_find_of_incident_facets(v);
|
||||||
|
if(nb_components > 1) {
|
||||||
|
#ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
std::cerr << "singular vertex: nb_components=" << nb_components << std::endl;
|
||||||
|
std::cerr << v->point() << std::endl;
|
||||||
|
#endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
return SINGULAR;
|
||||||
|
}
|
||||||
|
else { // REGULAR OR BOUNDARY
|
||||||
|
#ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
std::cerr << "regular or boundary: " << v->point() << std::endl;
|
||||||
|
#endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
if (number_of_boundary_incident_edges != 0)
|
||||||
|
return BOUNDARY;
|
||||||
|
else
|
||||||
|
return REGULAR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This function should be called only when incident edges
|
||||||
|
/// are known to be REGULAR OR BOUNDARY
|
||||||
|
bool is_regular_or_boundary_for_vertices(Vertex_handle v) const {
|
||||||
|
return union_find_of_incident_facets(v) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns `NOT_IN_COMPLEX`, `BOUNDARY`, `REGULAR`, or `SINGULAR`,
|
||||||
|
/// depending on the number of incident facets in the complex
|
||||||
|
Face_status face_status(const Edge& edge) const
|
||||||
|
{
|
||||||
|
if(!manifold_info_initialized_) init_manifold_info();
|
||||||
|
|
||||||
|
switch(edge_facet_counter_[this->make_ordered_pair(edge)])
|
||||||
|
{
|
||||||
|
case 0: return NOT_IN_COMPLEX;
|
||||||
|
case 1: return BOUNDARY;
|
||||||
|
case 2: return REGULAR;
|
||||||
|
default: return SINGULAR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the vertex \c v has is incident to at least a facet
|
||||||
|
/// of the complex
|
||||||
|
bool has_incident_facets_in_complex(const Vertex_handle& v) const
|
||||||
|
{
|
||||||
|
if(!manifold_info_initialized_) init_manifold_info();
|
||||||
|
return v->cached_number_of_incident_facets() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns true if facet \c facet is in complex
|
/// Returns true if facet \c facet is in complex
|
||||||
bool is_in_complex(const Facet& facet) const
|
bool is_in_complex(const Facet& facet) const
|
||||||
{
|
{
|
||||||
|
|
@ -314,6 +467,94 @@ public:
|
||||||
/// Returns bbox
|
/// Returns bbox
|
||||||
Bbox_3 bbox() const;
|
Bbox_3 bbox() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void init_manifold_info() const {
|
||||||
|
for(typename Tr::All_vertices_iterator
|
||||||
|
vit = triangulation().finite_vertices_begin(),
|
||||||
|
end = triangulation().finite_vertices_end();
|
||||||
|
vit != end; ++vit)
|
||||||
|
{
|
||||||
|
vit->set_c2t3_cache(0, -1);
|
||||||
|
}
|
||||||
|
for(typename Tr::Finite_facets_iterator
|
||||||
|
fit = triangulation().finite_facets_begin(),
|
||||||
|
end = triangulation().finite_facets_end();
|
||||||
|
fit != end; ++fit)
|
||||||
|
{
|
||||||
|
if ( is_in_complex(*fit) ) {
|
||||||
|
const Cell_handle cell = fit->first;
|
||||||
|
const int i = fit->second;
|
||||||
|
for(int j = 0; j < 3; ++j)
|
||||||
|
{
|
||||||
|
const int edge_index_va = tr_.vertex_triple_index(i, j);
|
||||||
|
const int edge_index_vb = tr_.vertex_triple_index(i, (j == 2) ? 0 : (j+1));
|
||||||
|
const Vertex_handle edge_va = cell->vertex(edge_index_va);
|
||||||
|
const Vertex_handle edge_vb = cell->vertex(edge_index_vb);
|
||||||
|
++edge_facet_counter_[this->make_ordered_pair(edge_va, edge_vb)];
|
||||||
|
|
||||||
|
const int n = edge_va->cached_number_of_incident_facets();
|
||||||
|
edge_va->set_c2t3_cache(n+1, -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
manifold_info_initialized_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extract the subset `F` of facets of the complex incident to `v` and
|
||||||
|
/// return the number of connected component of the adjacency graph of `F`.
|
||||||
|
int union_find_of_incident_facets(const Vertex_handle v) const
|
||||||
|
{
|
||||||
|
if( v->is_c2t3_cache_valid() )
|
||||||
|
{
|
||||||
|
const int n = v->cached_number_of_components();
|
||||||
|
if(n >= 0) return v->cached_number_of_components();
|
||||||
|
}
|
||||||
|
|
||||||
|
Union_find<Facet> facets;
|
||||||
|
{ // fill the union find
|
||||||
|
std::vector<Facet> non_filtered_facets;
|
||||||
|
tr_.incident_facets(v, std::back_inserter(non_filtered_facets));
|
||||||
|
|
||||||
|
for(typename std::vector<Facet>::iterator
|
||||||
|
fit = non_filtered_facets.begin(),
|
||||||
|
end = non_filtered_facets.end();
|
||||||
|
fit != end; ++fit)
|
||||||
|
{
|
||||||
|
if(is_in_complex(*fit)) facets.push_back(*fit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef std::map<Vertex_handle,
|
||||||
|
typename Union_find<Facet>::handle> Vertex_set_map;
|
||||||
|
typedef typename Vertex_set_map::iterator Vertex_set_map_iterator;
|
||||||
|
|
||||||
|
Vertex_set_map vsmap;
|
||||||
|
|
||||||
|
for(typename Union_find<Facet>::iterator
|
||||||
|
it = facets.begin(), end = facets.end();
|
||||||
|
it != end; ++it)
|
||||||
|
{
|
||||||
|
const Cell_handle& ch = (*it).first;
|
||||||
|
const int& i = (*it).second;
|
||||||
|
for(int j=0; j < 3; ++j) {
|
||||||
|
const Vertex_handle w = ch->vertex(tr_.vertex_triple_index(i,j));
|
||||||
|
if(w != v){
|
||||||
|
Vertex_set_map_iterator vsm_it = vsmap.find(w);
|
||||||
|
if(vsm_it != vsmap.end()){
|
||||||
|
facets.unify_sets(vsm_it->second, it);
|
||||||
|
} else {
|
||||||
|
vsmap.insert(std::make_pair(w, it));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const int nb_components = static_cast<int>(facets.number_of_sets());
|
||||||
|
|
||||||
|
const int n = v->cached_number_of_incident_facets();
|
||||||
|
v->set_c2t3_cache(n, nb_components);
|
||||||
|
return nb_components;
|
||||||
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------
|
//-------------------------------------------------------
|
||||||
// Traversal
|
// Traversal
|
||||||
//-------------------------------------------------------
|
//-------------------------------------------------------
|
||||||
|
|
@ -525,8 +766,16 @@ private:
|
||||||
|
|
||||||
// Private date members
|
// Private date members
|
||||||
Triangulation tr_;
|
Triangulation tr_;
|
||||||
|
|
||||||
|
typedef typename Base::Pair_of_vertices Pair_of_vertices;
|
||||||
|
typedef std::map<Pair_of_vertices, int> Edge_facet_counter;
|
||||||
|
|
||||||
|
mutable Edge_facet_counter edge_facet_counter_;
|
||||||
|
|
||||||
typename Number_of_elements<Concurrency_tag>::type number_of_facets_;
|
typename Number_of_elements<Concurrency_tag>::type number_of_facets_;
|
||||||
typename Number_of_elements<Concurrency_tag>::type number_of_cells_;
|
typename Number_of_elements<Concurrency_tag>::type number_of_cells_;
|
||||||
|
|
||||||
|
mutable bool manifold_info_initialized_;
|
||||||
}; // end class Mesh_complex_3_in_triangulation_3_base
|
}; // end class Mesh_complex_3_in_triangulation_3_base
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -545,6 +794,31 @@ Mesh_complex_3_in_triangulation_3_base<Tr,Ct>::add_to_complex(
|
||||||
set_surface_patch_index(cell, i, index);
|
set_surface_patch_index(cell, i, index);
|
||||||
set_surface_patch_index(mirror.first, mirror.second, index);
|
set_surface_patch_index(mirror.first, mirror.second, index);
|
||||||
++number_of_facets_;
|
++number_of_facets_;
|
||||||
|
if(manifold_info_initialized_) {
|
||||||
|
for(int j = 0; j < 3; ++j)
|
||||||
|
{
|
||||||
|
int edge_index_va = tr_.vertex_triple_index(i, j);
|
||||||
|
int edge_index_vb = tr_.vertex_triple_index(i, (j == 2) ? 0 : (j+1));
|
||||||
|
Vertex_handle edge_va = cell->vertex(edge_index_va);
|
||||||
|
Vertex_handle edge_vb = cell->vertex(edge_index_vb);
|
||||||
|
++edge_facet_counter_[this->make_ordered_pair(edge_va, edge_vb)];
|
||||||
|
|
||||||
|
const int n = edge_va->cached_number_of_incident_facets();
|
||||||
|
const int m = edge_va->cached_number_of_components();
|
||||||
|
edge_va->set_c2t3_cache(n+1, m);
|
||||||
|
}
|
||||||
|
const int dimension_plus_1 = tr_.dimension() + 1;
|
||||||
|
// update c2t3 for vertices of f
|
||||||
|
for (int j = 0; j < dimension_plus_1; j++) {
|
||||||
|
if (j != i) {
|
||||||
|
#ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
if(cell->vertex(j)->is_c2t3_cache_valid())
|
||||||
|
std::cerr << "(" << cell->vertex(j)->point() << ")->invalidate_c2t3_cache()\n";
|
||||||
|
#endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
cell->vertex(j)->invalidate_c2t3_cache();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -559,6 +833,34 @@ Mesh_complex_3_in_triangulation_3_base<Tr,Ct>::remove_from_complex(const Facet&
|
||||||
set_surface_patch_index(facet.first, facet.second, Surface_patch_index());
|
set_surface_patch_index(facet.first, facet.second, Surface_patch_index());
|
||||||
set_surface_patch_index(mirror.first, mirror.second, Surface_patch_index());
|
set_surface_patch_index(mirror.first, mirror.second, Surface_patch_index());
|
||||||
--number_of_facets_;
|
--number_of_facets_;
|
||||||
|
if(manifold_info_initialized_) {
|
||||||
|
const Cell_handle cell = facet.first;
|
||||||
|
const int i = facet.second;
|
||||||
|
for(int j = 0; j < 3; ++j)
|
||||||
|
{
|
||||||
|
const int edge_index_va = tr_.vertex_triple_index(i, j);
|
||||||
|
const int edge_index_vb = tr_.vertex_triple_index(i, (j == 2) ? 0 : (j+1));
|
||||||
|
const Vertex_handle edge_va = cell->vertex(edge_index_va);
|
||||||
|
const Vertex_handle edge_vb = cell->vertex(edge_index_vb);
|
||||||
|
--edge_facet_counter_[this->make_ordered_pair(edge_va, edge_vb)];
|
||||||
|
|
||||||
|
const int n = edge_va->cached_number_of_incident_facets();
|
||||||
|
CGAL_assertion(n>0);
|
||||||
|
const int m = edge_va->cached_number_of_components();
|
||||||
|
edge_va->set_c2t3_cache(n-1, m);
|
||||||
|
}
|
||||||
|
const int dimension_plus_1 = tr_.dimension() + 1;
|
||||||
|
// update c2t3 for vertices of f
|
||||||
|
for (int j = 0; j < dimension_plus_1; j++) {
|
||||||
|
if (j != facet.second) {
|
||||||
|
#ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
if(cell->vertex(j)->is_c2t3_cache_valid())
|
||||||
|
std::cerr << "(" << cell->vertex(j)->point() << ")->invalidate_c2t3_cache()\n";
|
||||||
|
#endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
cell->vertex(j)->invalidate_c2t3_cache();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
#include <CGAL/Mesh_3/Dump_c3t3.h>
|
#include <CGAL/Mesh_3/Dump_c3t3.h>
|
||||||
|
|
||||||
#include<CGAL/Mesh_3/Refine_facets_3.h>
|
#include<CGAL/Mesh_3/Refine_facets_3.h>
|
||||||
|
#include<CGAL/Mesh_3/Refine_facets_manifold_base.h>
|
||||||
#include<CGAL/Mesh_3/Refine_cells_3.h>
|
#include<CGAL/Mesh_3/Refine_cells_3.h>
|
||||||
#include <CGAL/Mesh_3/Refine_tets_visitor.h>
|
#include <CGAL/Mesh_3/Refine_tets_visitor.h>
|
||||||
#include <CGAL/Mesher_level_visitors.h>
|
#include <CGAL/Mesher_level_visitors.h>
|
||||||
|
|
|
||||||
|
|
@ -337,10 +337,12 @@ template<class Tr,
|
||||||
typename Criteria::Facet_quality>
|
typename Criteria::Facet_quality>
|
||||||
# endif
|
# endif
|
||||||
#endif // CGAL_LINKED_WITH_TBB
|
#endif // CGAL_LINKED_WITH_TBB
|
||||||
|
, class Base_ = Refine_facets_3_base<typename MeshDomain::Index,
|
||||||
|
typename Tr::Facet,
|
||||||
|
Concurrency_tag>
|
||||||
>
|
>
|
||||||
class Refine_facets_3
|
class Refine_facets_3
|
||||||
: public Refine_facets_3_base<typename MeshDomain::Index, typename Tr::Facet,
|
: public Base_
|
||||||
Concurrency_tag>
|
|
||||||
, public Mesh_3::Mesher_level<Tr,
|
, public Mesh_3::Mesher_level<Tr,
|
||||||
Refine_facets_3<Tr,
|
Refine_facets_3<Tr,
|
||||||
Criteria,
|
Criteria,
|
||||||
|
|
@ -348,7 +350,8 @@ class Refine_facets_3
|
||||||
Complex3InTriangulation3,
|
Complex3InTriangulation3,
|
||||||
Previous_level_,
|
Previous_level_,
|
||||||
Concurrency_tag,
|
Concurrency_tag,
|
||||||
Container_>,
|
Container_,
|
||||||
|
Base_>,
|
||||||
typename Tr::Facet,
|
typename Tr::Facet,
|
||||||
Previous_level_,
|
Previous_level_,
|
||||||
Triangulation_mesher_level_traits_3<Tr>,
|
Triangulation_mesher_level_traits_3<Tr>,
|
||||||
|
|
@ -364,11 +367,10 @@ class Refine_facets_3
|
||||||
Complex3InTriangulation3,
|
Complex3InTriangulation3,
|
||||||
Previous_level_,
|
Previous_level_,
|
||||||
Concurrency_tag,
|
Concurrency_tag,
|
||||||
Container_> Self;
|
Container_,
|
||||||
|
Base_> Self;
|
||||||
|
|
||||||
typedef Refine_facets_3_base<typename MeshDomain::Index,
|
typedef Base_ Base;
|
||||||
typename Tr::Facet,
|
|
||||||
Concurrency_tag> Base;
|
|
||||||
|
|
||||||
typedef Mesher_level<Tr,
|
typedef Mesher_level<Tr,
|
||||||
Refine_facets_3<Tr,
|
Refine_facets_3<Tr,
|
||||||
|
|
@ -836,8 +838,8 @@ private:
|
||||||
|
|
||||||
|
|
||||||
// For sequential
|
// For sequential
|
||||||
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_>
|
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_, class B_>
|
||||||
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_>::
|
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_,B_>::
|
||||||
Refine_facets_3(Tr& triangulation,
|
Refine_facets_3(Tr& triangulation,
|
||||||
const Cr& criteria,
|
const Cr& criteria,
|
||||||
const MD& oracle,
|
const MD& oracle,
|
||||||
|
|
@ -857,8 +859,8 @@ Refine_facets_3(Tr& triangulation,
|
||||||
}
|
}
|
||||||
|
|
||||||
// For parallel
|
// For parallel
|
||||||
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_>
|
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_, class B_>
|
||||||
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_>::
|
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_,B_>::
|
||||||
Refine_facets_3(Tr& triangulation,
|
Refine_facets_3(Tr& triangulation,
|
||||||
const Cr& criteria,
|
const Cr& criteria,
|
||||||
const MD& oracle,
|
const MD& oracle,
|
||||||
|
|
@ -881,9 +883,9 @@ Refine_facets_3(Tr& triangulation,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_>
|
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_, class B_>
|
||||||
void
|
void
|
||||||
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_>::
|
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_,B_>::
|
||||||
scan_triangulation_impl()
|
scan_triangulation_impl()
|
||||||
{
|
{
|
||||||
typedef typename Tr::Finite_facets_iterator Finite_facet_iterator;
|
typedef typename Tr::Finite_facets_iterator Finite_facet_iterator;
|
||||||
|
|
@ -960,9 +962,9 @@ scan_triangulation_impl()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_>
|
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_, class B_>
|
||||||
int
|
int
|
||||||
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_>::
|
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_,B_>::
|
||||||
number_of_bad_elements_impl()
|
number_of_bad_elements_impl()
|
||||||
{
|
{
|
||||||
typedef typename Tr::Finite_facets_iterator Finite_facet_iterator;
|
typedef typename Tr::Finite_facets_iterator Finite_facet_iterator;
|
||||||
|
|
@ -1120,9 +1122,9 @@ number_of_bad_elements_impl()
|
||||||
}
|
}
|
||||||
|
|
||||||
// For sequential
|
// For sequential
|
||||||
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_>
|
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_, class B_>
|
||||||
Mesher_level_conflict_status
|
Mesher_level_conflict_status
|
||||||
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_>::
|
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_,B_>::
|
||||||
test_point_conflict_from_superior_impl(const Point& point, Zone& zone)
|
test_point_conflict_from_superior_impl(const Point& point, Zone& zone)
|
||||||
{
|
{
|
||||||
typedef typename Zone::Facets_iterator Facet_iterator;
|
typedef typename Zone::Facets_iterator Facet_iterator;
|
||||||
|
|
@ -1166,10 +1168,10 @@ test_point_conflict_from_superior_impl(const Point& point, Zone& zone)
|
||||||
}
|
}
|
||||||
|
|
||||||
// For parallel
|
// For parallel
|
||||||
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_>
|
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_, class B_>
|
||||||
template <typename Mesh_visitor>
|
template <typename Mesh_visitor>
|
||||||
Mesher_level_conflict_status
|
Mesher_level_conflict_status
|
||||||
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_>::
|
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_,B_>::
|
||||||
test_point_conflict_from_superior_impl(const Point& point, Zone& zone,
|
test_point_conflict_from_superior_impl(const Point& point, Zone& zone,
|
||||||
Mesh_visitor &visitor)
|
Mesh_visitor &visitor)
|
||||||
{
|
{
|
||||||
|
|
@ -1216,9 +1218,9 @@ test_point_conflict_from_superior_impl(const Point& point, Zone& zone,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_>
|
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_, class B_>
|
||||||
typename Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_>::Zone
|
typename Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_,B_>::Zone
|
||||||
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_>::
|
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_,B_>::
|
||||||
conflicts_zone_impl(const Point& point
|
conflicts_zone_impl(const Point& point
|
||||||
, const Facet& facet
|
, const Facet& facet
|
||||||
, bool &facet_is_in_its_cz)
|
, bool &facet_is_in_its_cz)
|
||||||
|
|
@ -1275,9 +1277,9 @@ conflicts_zone_impl(const Point& point
|
||||||
return zone;
|
return zone;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_>
|
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_, class B_>
|
||||||
typename Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_>::Zone
|
typename Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_,B_>::Zone
|
||||||
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_>::
|
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_,B_>::
|
||||||
conflicts_zone_impl(const Point& point
|
conflicts_zone_impl(const Point& point
|
||||||
, const Facet& facet
|
, const Facet& facet
|
||||||
, bool &facet_is_in_its_cz
|
, bool &facet_is_in_its_cz
|
||||||
|
|
@ -1338,9 +1340,9 @@ conflicts_zone_impl(const Point& point
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_>
|
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_, class B_>
|
||||||
void
|
void
|
||||||
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_>::
|
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_,B_>::
|
||||||
before_insertion_impl(const Facet& facet,
|
before_insertion_impl(const Facet& facet,
|
||||||
const Point& point,
|
const Point& point,
|
||||||
Zone& zone)
|
Zone& zone)
|
||||||
|
|
@ -1418,9 +1420,9 @@ before_insertion_impl(const Facet& facet,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_>
|
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_, class B_>
|
||||||
typename Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_>::Vertex_handle
|
typename Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_,B_>::Vertex_handle
|
||||||
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_>::
|
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_,B_>::
|
||||||
insert_impl(const Point& point,
|
insert_impl(const Point& point,
|
||||||
const Zone& zone)
|
const Zone& zone)
|
||||||
{
|
{
|
||||||
|
|
@ -1447,9 +1449,9 @@ insert_impl(const Point& point,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_>
|
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_, class B_>
|
||||||
void
|
void
|
||||||
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_>::
|
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_,B_>::
|
||||||
restore_restricted_Delaunay(const Vertex_handle& vertex)
|
restore_restricted_Delaunay(const Vertex_handle& vertex)
|
||||||
{
|
{
|
||||||
typedef std::vector<Cell_handle> Cell_handle_vector;
|
typedef std::vector<Cell_handle> Cell_handle_vector;
|
||||||
|
|
@ -1481,9 +1483,9 @@ restore_restricted_Delaunay(const Vertex_handle& vertex)
|
||||||
//-------------------------------------------------------
|
//-------------------------------------------------------
|
||||||
// Private methods
|
// Private methods
|
||||||
//-------------------------------------------------------
|
//-------------------------------------------------------
|
||||||
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_>
|
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_, class B_>
|
||||||
void
|
void
|
||||||
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_>::
|
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_,B_>::
|
||||||
treat_new_facet(Facet& facet)
|
treat_new_facet(Facet& facet)
|
||||||
{
|
{
|
||||||
// Treat facet
|
// Treat facet
|
||||||
|
|
@ -1525,9 +1527,9 @@ treat_new_facet(Facet& facet)
|
||||||
set_facet_visited(mirror);
|
set_facet_visited(mirror);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_>
|
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_, class B_>
|
||||||
void
|
void
|
||||||
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_>::
|
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_,B_>::
|
||||||
dual_segment(const Facet & facet, Bare_point& p, Bare_point& q) const
|
dual_segment(const Facet & facet, Bare_point& p, Bare_point& q) const
|
||||||
{
|
{
|
||||||
Cell_handle c = facet.first;
|
Cell_handle c = facet.first;
|
||||||
|
|
@ -1546,9 +1548,9 @@ dual_segment(const Facet & facet, Bare_point& p, Bare_point& q) const
|
||||||
n->vertex(3)->point());
|
n->vertex(3)->point());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_>
|
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_, class B_>
|
||||||
void
|
void
|
||||||
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_>::
|
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_,B_>::
|
||||||
dual_segment_exact(const Facet & facet, Bare_point& p, Bare_point& q) const
|
dual_segment_exact(const Facet & facet, Bare_point& p, Bare_point& q) const
|
||||||
{
|
{
|
||||||
Cell_handle c = facet.first;
|
Cell_handle c = facet.first;
|
||||||
|
|
@ -1569,9 +1571,9 @@ dual_segment_exact(const Facet & facet, Bare_point& p, Bare_point& q) const
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_>
|
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_, class B_>
|
||||||
void
|
void
|
||||||
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_>::
|
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_,B_>::
|
||||||
dual_ray(const Facet & facet, Ray_3& ray) const
|
dual_ray(const Facet & facet, Ray_3& ray) const
|
||||||
{
|
{
|
||||||
Cell_handle c = facet.first;
|
Cell_handle c = facet.first;
|
||||||
|
|
@ -1604,9 +1606,9 @@ dual_ray(const Facet & facet, Ray_3& ray) const
|
||||||
n->vertex(3)->point()), l);
|
n->vertex(3)->point()), l);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_>
|
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_, class B_>
|
||||||
void
|
void
|
||||||
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_>::
|
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_,B_>::
|
||||||
dual_ray_exact(const Facet & facet, Ray_3& ray) const
|
dual_ray_exact(const Facet & facet, Ray_3& ray) const
|
||||||
{
|
{
|
||||||
Cell_handle c = facet.first;
|
Cell_handle c = facet.first;
|
||||||
|
|
@ -1644,9 +1646,9 @@ dual_ray_exact(const Facet & facet, Ray_3& ray) const
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_>
|
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_, class B_>
|
||||||
void
|
void
|
||||||
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_>::
|
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_,B_>::
|
||||||
compute_facet_properties(const Facet& facet,
|
compute_facet_properties(const Facet& facet,
|
||||||
Facet_properties& fp,
|
Facet_properties& fp,
|
||||||
bool force_exact) const
|
bool force_exact) const
|
||||||
|
|
@ -1759,9 +1761,9 @@ compute_facet_properties(const Facet& facet,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_>
|
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_, class B_>
|
||||||
bool
|
bool
|
||||||
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_>::
|
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_,B_>::
|
||||||
is_facet_encroached(const Facet& facet,
|
is_facet_encroached(const Facet& facet,
|
||||||
const Point& point) const
|
const Point& point) const
|
||||||
{
|
{
|
||||||
|
|
@ -1783,9 +1785,9 @@ is_facet_encroached(const Facet& facet,
|
||||||
return ( compare_distance(center, reference_point, point) != CGAL::SMALLER );
|
return ( compare_distance(center, reference_point, point) != CGAL::SMALLER );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_>
|
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_, class B_>
|
||||||
bool
|
bool
|
||||||
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_>::
|
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_,B_>::
|
||||||
is_encroached_facet_refinable(Facet& facet) const
|
is_encroached_facet_refinable(Facet& facet) const
|
||||||
{
|
{
|
||||||
typedef typename Gt::Point_3 Point_3;
|
typedef typename Gt::Point_3 Point_3;
|
||||||
|
|
@ -1872,9 +1874,9 @@ is_encroached_facet_refinable(Facet& facet) const
|
||||||
* \c facet is an internal facet we are going to remove
|
* \c facet is an internal facet we are going to remove
|
||||||
* \c source_facet is the facet we want to refine by inserting a new point
|
* \c source_facet is the facet we want to refine by inserting a new point
|
||||||
*/
|
*/
|
||||||
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_>
|
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_, class B_>
|
||||||
bool
|
bool
|
||||||
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_>::
|
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_,B_>::
|
||||||
before_insertion_handle_facet_in_conflict_zone(Facet& facet,
|
before_insertion_handle_facet_in_conflict_zone(Facet& facet,
|
||||||
const Facet& source_facet)
|
const Facet& source_facet)
|
||||||
{
|
{
|
||||||
|
|
@ -1899,9 +1901,9 @@ before_insertion_handle_facet_in_conflict_zone(Facet& facet,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_>
|
template<class Tr, class Cr, class MD, class C3T3_, class P_, class Ct, class C_, class B_>
|
||||||
void
|
void
|
||||||
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_>::
|
Refine_facets_3<Tr,Cr,MD,C3T3_,P_,Ct,C_,B_>::
|
||||||
after_insertion_handle_incident_facet(Facet& facet)
|
after_insertion_handle_incident_facet(Facet& facet)
|
||||||
{
|
{
|
||||||
// If the facet is infinite or has been already visited,
|
// If the facet is infinite or has been already visited,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,627 @@
|
||||||
|
// Copyright (c) 2003-2007 INRIA Sophia-Antipolis (France).
|
||||||
|
// Copyright (c) 2008,2013 GeometryFactory, Sophia Antipolis (France)
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org).
|
||||||
|
// You can redistribute it and/or modify it under the terms of the GNU
|
||||||
|
// General Public License as published by the Free Software Foundation,
|
||||||
|
// either version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// 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$
|
||||||
|
// $Id$
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Steve Oudot, David Rey, Mariette Yvinec, Laurent Rineau, Andreas Fabri
|
||||||
|
|
||||||
|
#ifndef CGAL_MESH_3_REFINE_FACETS_MANIFOLD_BASE_H
|
||||||
|
#define CGAL_MESH_3_REFINE_FACETS_MANIFOLD_BASE_H
|
||||||
|
|
||||||
|
#include <CGAL/utility.h>
|
||||||
|
#include <set>
|
||||||
|
#include <vector>
|
||||||
|
#include <boost/bimap.hpp>
|
||||||
|
#include <boost/bimap/unordered_set_of.hpp>
|
||||||
|
#include <boost/bimap/multiset_of.hpp>
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
#include <boost/mpl/has_xxx.hpp>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
|
||||||
|
namespace Mesh_3 {
|
||||||
|
|
||||||
|
BOOST_MPL_HAS_XXX_TRAIT_DEF(Has_manifold_criterion)
|
||||||
|
|
||||||
|
template <typename Criteria,
|
||||||
|
bool has_Has_manifold_criterion =
|
||||||
|
has_Has_manifold_criterion<Criteria>::value>
|
||||||
|
struct Has_manifold_criterion :
|
||||||
|
public CGAL::Boolean_tag<Criteria::Has_manifold_criterion::value>
|
||||||
|
// when Criteria has the nested type Has_manifold_criterion
|
||||||
|
{};
|
||||||
|
|
||||||
|
template <typename Criteria>
|
||||||
|
struct Has_manifold_criterion<Criteria, false> : public CGAL::Tag_false
|
||||||
|
// when Criteria does not have the nested type Has_manifold_criterion
|
||||||
|
{};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <typename Criteria>
|
||||||
|
bool get_with_manifold(const Criteria& c, CGAL::Tag_false)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Criteria>
|
||||||
|
bool get_with_manifold(const Criteria& c, CGAL::Tag_true)
|
||||||
|
{
|
||||||
|
return (c.topology() & MANIFOLD_WITH_BOUNDARY) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Criteria>
|
||||||
|
bool get_with_manifold(const Criteria& c)
|
||||||
|
{
|
||||||
|
return get_with_manifold(c, Has_manifold_criterion<Criteria>());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Criteria>
|
||||||
|
bool get_with_boundary(const Criteria& c, CGAL::Tag_false)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Criteria>
|
||||||
|
bool get_with_boundary(const Criteria& c, CGAL::Tag_true)
|
||||||
|
{
|
||||||
|
return (c.topology() & NO_BOUNDARY) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Criteria>
|
||||||
|
bool get_with_boundary(const Criteria& c)
|
||||||
|
{
|
||||||
|
return get_with_boundary(c, Has_manifold_criterion<Criteria>());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <
|
||||||
|
typename Base_,
|
||||||
|
bool withBoundary = false
|
||||||
|
>
|
||||||
|
class Refine_facets_manifold_base
|
||||||
|
: public Base_
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef Base_ Base ;
|
||||||
|
|
||||||
|
typedef typename Base::C3T3 C3t3;
|
||||||
|
typedef typename Base::Criteria Criteria;
|
||||||
|
typedef typename Base::Mesh_domain Mesh_domain;
|
||||||
|
typedef typename C3t3::Triangulation Tr;
|
||||||
|
typedef typename Tr::Point Point;
|
||||||
|
typedef typename Tr::Facet Facet;
|
||||||
|
typedef typename Tr::Vertex_handle Vertex_handle;
|
||||||
|
|
||||||
|
typedef typename Triangulation_mesher_level_traits_3<Tr>::Zone Zone;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
typedef typename Tr::Geom_traits GT;
|
||||||
|
typedef typename GT::FT FT;
|
||||||
|
typedef typename Tr::Edge Edge;
|
||||||
|
typedef typename Tr::Cell_handle Cell_handle;
|
||||||
|
|
||||||
|
typedef typename Tr::Facet_circulator Tr_facet_circulator;
|
||||||
|
typedef std::pair<Vertex_handle, Vertex_handle> EdgeVV;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Tr& r_tr_;
|
||||||
|
C3t3& r_c3t3_;
|
||||||
|
|
||||||
|
typedef ::boost::bimap< EdgeVV,
|
||||||
|
::boost::bimaps::multiset_of<int> > Bad_edges;
|
||||||
|
typedef typename Bad_edges::value_type Bad_edge;
|
||||||
|
|
||||||
|
mutable Bad_edges m_bad_edges;
|
||||||
|
mutable std::set<Vertex_handle> m_bad_vertices;
|
||||||
|
|
||||||
|
mutable bool m_manifold_info_initialized;
|
||||||
|
mutable bool m_bad_vertices_initialized;
|
||||||
|
bool m_with_manifold_criterion;
|
||||||
|
bool m_with_boundary;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// 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 v1 = arete.first;
|
||||||
|
Vertex_handle v2 = arete.second;
|
||||||
|
Cell_handle c;
|
||||||
|
int index1, index2;
|
||||||
|
|
||||||
|
CGAL_assertion_code(bool is_edge =)
|
||||||
|
r_tr_.is_edge(v1, v2, c, index1, index2);
|
||||||
|
CGAL_assertion(is_edge);
|
||||||
|
|
||||||
|
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) );
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
r_tr_.geom_traits().compute_squared_distance_3_object()(fcenter.point(),
|
||||||
|
vpoint.point())
|
||||||
|
- vpoint.weight();
|
||||||
|
}
|
||||||
|
|
||||||
|
Facet
|
||||||
|
biggest_incident_facet_in_complex(const Vertex_handle v) const
|
||||||
|
{
|
||||||
|
#ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
std::cerr << "Bad vertex: " << v->point() << std::endl;
|
||||||
|
#endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
std::vector<Facet> facets;
|
||||||
|
facets.reserve(64);
|
||||||
|
r_tr_.incident_facets(v, std::back_inserter(facets));
|
||||||
|
|
||||||
|
typename std::vector<Facet>::iterator fit = facets.begin();
|
||||||
|
while(fit != facets.end() && !r_c3t3_.is_in_complex(*fit)) ++fit;
|
||||||
|
CGAL_assertion(fit!=facets.end());
|
||||||
|
CGAL_assertion_code(int facet_counter = 1);
|
||||||
|
|
||||||
|
#ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
std::cerr << " " << v->cached_number_of_incident_facets()
|
||||||
|
<< " incident faces, with sizes:\n";
|
||||||
|
std::cerr << " " << compute_distance_to_facet_center(*fit, v) << "\n";
|
||||||
|
#endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
Facet biggest_facet = *fit++;
|
||||||
|
while(fit != facets.end() && !r_c3t3_.is_in_complex(*fit)) ++fit;
|
||||||
|
|
||||||
|
for (; fit != facets.end(); )
|
||||||
|
{
|
||||||
|
CGAL_assertion_code(++facet_counter);
|
||||||
|
Facet current_facet = *fit;
|
||||||
|
#ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
std::cerr << " " << compute_distance_to_facet_center(*fit, v) << "\n";
|
||||||
|
#endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
// is the current facet bigger than the current biggest one
|
||||||
|
if ( compute_distance_to_facet_center(current_facet, v) >
|
||||||
|
compute_distance_to_facet_center(biggest_facet, v) )
|
||||||
|
{
|
||||||
|
biggest_facet = current_facet;
|
||||||
|
}
|
||||||
|
++fit;
|
||||||
|
while(fit != facets.end() && !r_c3t3_.is_in_complex(*fit)) ++fit;
|
||||||
|
}
|
||||||
|
CGAL_assertion(v->cached_number_of_incident_facets() ==
|
||||||
|
facet_counter);
|
||||||
|
CGAL_assertion(r_c3t3_.is_in_complex(biggest_facet));
|
||||||
|
#ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
std::cerr << "Biggest facet radius: "
|
||||||
|
<< compute_distance_to_facet_center(biggest_facet, v)
|
||||||
|
<< std::endl;
|
||||||
|
#endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
|
||||||
|
return biggest_facet;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
Vertex_handle fev = edge_to_edgevv(arete).first;
|
||||||
|
#ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
std::cerr << "Bad edge: (" << fev->point()
|
||||||
|
<< ", " << arete.first->vertex(arete.third)->point()
|
||||||
|
<< ")\n incident facets sizes:\n";
|
||||||
|
#endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
Tr_facet_circulator fcirc = r_tr_.incident_facets(arete);
|
||||||
|
while(!r_c3t3_.is_in_complex(*fcirc)) ++fcirc;
|
||||||
|
Facet first_facet = *fcirc;
|
||||||
|
Facet biggest_facet = *fcirc;
|
||||||
|
#ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
std::cerr << " "
|
||||||
|
<< compute_distance_to_facet_center(*fcirc, fev) << std::endl;
|
||||||
|
#endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
|
||||||
|
for (++fcirc; *fcirc != first_facet; ++fcirc)
|
||||||
|
{
|
||||||
|
while(!r_c3t3_.is_in_complex(*fcirc)) ++fcirc;
|
||||||
|
if(*fcirc == first_facet) break;
|
||||||
|
#ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
std::cerr << " "
|
||||||
|
<< compute_distance_to_facet_center(*fcirc, fev) << std::endl;
|
||||||
|
#endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
std::cerr << "Biggest facet radius: "
|
||||||
|
<< compute_distance_to_facet_center(biggest_facet, fev)
|
||||||
|
<< std::endl;
|
||||||
|
#endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
|
||||||
|
return biggest_facet;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////
|
||||||
|
// For before_insertion
|
||||||
|
|
||||||
|
// Actions to perform on a facet inside the conflict zone
|
||||||
|
void
|
||||||
|
before_insertion_handle_facet_inside_conflict_zone (const Facet& f)
|
||||||
|
{
|
||||||
|
if ( r_c3t3_.is_in_complex(f) ) {
|
||||||
|
// foreach edge of f
|
||||||
|
const Cell_handle cell = f.first;
|
||||||
|
const int i = f.second;
|
||||||
|
for(int j = 0; j < 3; ++j)
|
||||||
|
{
|
||||||
|
const int edge_index_va = r_tr_.vertex_triple_index(i, j);
|
||||||
|
const int edge_index_vb = r_tr_.vertex_triple_index(i, (j == 2) ? 0 : (j+1));
|
||||||
|
const Vertex_handle edge_va = cell->vertex(edge_index_va);
|
||||||
|
const Vertex_handle edge_vb = cell->vertex(edge_index_vb);
|
||||||
|
m_bad_edges.left.erase( make_edgevv(edge_va, edge_vb));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Action to perform on a facet on the boundary of the conflict zone
|
||||||
|
void
|
||||||
|
before_insertion_handle_facet_on_boundary_of_conflict_zone(const Facet& f)
|
||||||
|
{
|
||||||
|
// perform the same operations as for an internal facet
|
||||||
|
before_insertion_handle_facet_inside_conflict_zone (f);
|
||||||
|
|
||||||
|
if(m_bad_vertices_initialized) {
|
||||||
|
const Cell_handle& c = f.first;
|
||||||
|
const int i = f.second;
|
||||||
|
|
||||||
|
// for each v of f
|
||||||
|
for (int j = 0; j < 4; j++)
|
||||||
|
if (i != j)
|
||||||
|
if(m_bad_vertices.erase(c->vertex(j)) > 0) {
|
||||||
|
#ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
std::cerr << "m_bad_vertices.erase("
|
||||||
|
<< c->vertex(j)->point() << ")\n";
|
||||||
|
#endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
Refine_facets_manifold_base(Tr& triangulation,
|
||||||
|
const Criteria& criteria,
|
||||||
|
const Mesh_domain& oracle,
|
||||||
|
C3t3& c3t3,
|
||||||
|
bool /*with_boundary*/ = withBoundary)
|
||||||
|
: Base(triangulation,
|
||||||
|
criteria,
|
||||||
|
oracle,
|
||||||
|
c3t3)
|
||||||
|
, r_tr_(triangulation)
|
||||||
|
, r_c3t3_(c3t3)
|
||||||
|
, m_manifold_info_initialized(false)
|
||||||
|
, m_bad_vertices_initialized(false)
|
||||||
|
, m_with_manifold_criterion(get_with_manifold(criteria))
|
||||||
|
, m_with_boundary(get_with_boundary(criteria))
|
||||||
|
{
|
||||||
|
#ifdef CGAL_MESH_3_DEBUG_CONSTRUCTORS
|
||||||
|
std::cerr << "CONS: Refine_facets_manifold_base";
|
||||||
|
if(m_with_manifold_criterion) {
|
||||||
|
if(m_with_boundary)
|
||||||
|
std::cerr << " (with boundaries)\n";
|
||||||
|
else
|
||||||
|
std::cerr << " (without boundary)\n";
|
||||||
|
} else {
|
||||||
|
std::cerr << " (DEACTIVATED)\n";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Initialization function
|
||||||
|
void initialize_manifold_info() const {
|
||||||
|
#ifdef CGAL_MESH_3_VERBOSE
|
||||||
|
std::cerr << "\nscanning edges ";
|
||||||
|
if(m_with_boundary)
|
||||||
|
std::cerr << "(boundaries allowed)";
|
||||||
|
std::cerr << "...\n";
|
||||||
|
int n = 0;
|
||||||
|
#endif
|
||||||
|
for (typename Tr::Finite_edges_iterator
|
||||||
|
eit = r_tr_.finite_edges_begin(), end = r_tr_.finite_edges_end();
|
||||||
|
eit != end; ++eit)
|
||||||
|
{
|
||||||
|
if ( (r_c3t3_.face_status(*eit) == C3t3::SINGULAR) ||
|
||||||
|
( (!m_with_boundary) &&
|
||||||
|
(r_c3t3_.face_status(*eit) == C3t3::BOUNDARY) ) )
|
||||||
|
{
|
||||||
|
m_bad_edges.insert(Bad_edge(edge_to_edgevv(*eit),
|
||||||
|
(r_c3t3_.face_status(*eit) ==
|
||||||
|
C3t3::SINGULAR ? 0 : 1)));
|
||||||
|
#ifdef CGAL_MESH_3_VERBOSE
|
||||||
|
++n;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_manifold_info_initialized = true;
|
||||||
|
#ifdef CGAL_MESH_3_VERBOSE
|
||||||
|
std::cerr << " -> found " << n << " bad edges\n";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void initialize_bad_vertices() const
|
||||||
|
{
|
||||||
|
CGAL_assertion(m_bad_vertices_initialized == false);
|
||||||
|
CGAL_assertion(m_bad_vertices.empty());
|
||||||
|
#ifdef CGAL_MESH_3_VERBOSE
|
||||||
|
std::cerr << "\nscanning vertices..." << std::endl;
|
||||||
|
int n = 0;
|
||||||
|
#endif
|
||||||
|
for (typename Tr::Finite_vertices_iterator
|
||||||
|
vit = r_tr_.finite_vertices_begin(),
|
||||||
|
end = r_tr_.finite_vertices_end();
|
||||||
|
vit != end; ++vit)
|
||||||
|
{
|
||||||
|
if( r_c3t3_.face_status(vit) == C3t3::SINGULAR ) {
|
||||||
|
#ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
std::cerr << "m_bad_edges.insert("
|
||||||
|
<< vit->point() << ")\n";
|
||||||
|
#endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
m_bad_vertices.insert( vit );
|
||||||
|
#ifdef CGAL_MESH_3_VERBOSE
|
||||||
|
++n;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_bad_vertices_initialized = true;
|
||||||
|
#ifdef CGAL_MESH_3_VERBOSE
|
||||||
|
std::cerr << " -> found " << n << " bad vertices\n";
|
||||||
|
# ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
std::cerr << "Bad vertices queue:\n";
|
||||||
|
BOOST_FOREACH(Vertex_handle v2, m_bad_vertices)
|
||||||
|
{
|
||||||
|
std::cerr << v2->point() << std::endl;
|
||||||
|
}
|
||||||
|
CGAL::dump_c3t3(r_c3t3_, "dump-at-scan-vertices");
|
||||||
|
# endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
void scan_triangulation_impl() {
|
||||||
|
Base::scan_triangulation_impl();
|
||||||
|
#ifdef CGAL_MESH_3_VERBOSE
|
||||||
|
std::cerr << "scanning edges (lazy)" << std::endl;
|
||||||
|
std::cerr << "scanning vertices (lazy)" << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tells whether there remain elements to refine
|
||||||
|
bool no_longer_element_to_refine_impl() const {
|
||||||
|
if(Base::no_longer_element_to_refine_impl())
|
||||||
|
{
|
||||||
|
if(!m_with_manifold_criterion) return true;
|
||||||
|
// Disable the manifold criterion
|
||||||
|
|
||||||
|
if( ! m_manifold_info_initialized ) initialize_manifold_info();
|
||||||
|
|
||||||
|
if(m_bad_edges.left.empty())
|
||||||
|
{
|
||||||
|
if( ! m_bad_vertices_initialized ) initialize_bad_vertices();
|
||||||
|
|
||||||
|
return m_bad_vertices.empty();
|
||||||
|
}
|
||||||
|
else // m_bad_vertices is not empty
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else // Base::no_longer_element_to_refine_impl() returned false
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the next element to refine
|
||||||
|
Facet get_next_element_impl() {
|
||||||
|
|
||||||
|
if (!Base::no_longer_element_to_refine_impl()) {
|
||||||
|
return Base::get_next_element_impl();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(!m_bad_edges.left.empty()) {
|
||||||
|
Edge first_bad_edge = edgevv_to_edge(m_bad_edges.right.begin()->second);
|
||||||
|
#ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
const EdgeVV& edgevv = m_bad_edges.right.begin()->second;
|
||||||
|
std::cerr << "Bad edge "
|
||||||
|
<< edgevv.first->point()
|
||||||
|
<< " - "
|
||||||
|
<< edgevv.second->point()
|
||||||
|
<< "\n";
|
||||||
|
#endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
return biggest_incident_facet_in_complex(first_bad_edge);
|
||||||
|
} else {
|
||||||
|
CGAL_assertion(!m_bad_vertices.empty());
|
||||||
|
const Vertex_handle& v = *m_bad_vertices.begin();
|
||||||
|
#ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
std::cerr << "Bad vertices queue:\n";
|
||||||
|
BOOST_FOREACH(Vertex_handle v2, m_bad_vertices)
|
||||||
|
{
|
||||||
|
std::cerr << v2->point() << std::endl;
|
||||||
|
}
|
||||||
|
std::cerr << "Bad vertex " << v->point() << "\n";
|
||||||
|
#endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
CGAL_assertion(r_c3t3_.has_incident_facets_in_complex(v));
|
||||||
|
if(r_c3t3_.face_status(v) != C3t3::SINGULAR) {
|
||||||
|
dump_c3t3(r_c3t3_, "dump-crash");
|
||||||
|
CGAL_error_msg("r_c3t3_.face_status(v) != C3t3::SINGULAR");
|
||||||
|
}
|
||||||
|
return biggest_incident_facet_in_complex(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void before_insertion_impl(const Facet& f, const Point& s,
|
||||||
|
Zone& zone) {
|
||||||
|
if( m_manifold_info_initialized )
|
||||||
|
{
|
||||||
|
for (typename Zone::Facets_iterator fit =
|
||||||
|
zone.internal_facets.begin();
|
||||||
|
fit != zone.internal_facets.end();
|
||||||
|
++fit)
|
||||||
|
before_insertion_handle_facet_inside_conflict_zone (*fit);
|
||||||
|
|
||||||
|
for (typename Zone::Facets_iterator fit =
|
||||||
|
zone.boundary_facets.begin(); fit !=
|
||||||
|
zone.boundary_facets.end(); ++fit)
|
||||||
|
before_insertion_handle_facet_on_boundary_of_conflict_zone (*fit);
|
||||||
|
}
|
||||||
|
Base::before_insertion_impl(f, s, zone);
|
||||||
|
}
|
||||||
|
|
||||||
|
void after_insertion_impl(const Vertex_handle v) {
|
||||||
|
Base::after_insertion_impl(v);
|
||||||
|
|
||||||
|
if( ! m_manifold_info_initialized )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// search for incident facets around v
|
||||||
|
typedef std::vector<Facet> Facets;
|
||||||
|
Facets facets;
|
||||||
|
facets.reserve(64);
|
||||||
|
r_tr_.incident_facets (v, std::back_inserter(facets));
|
||||||
|
|
||||||
|
// foreach f in star(v)
|
||||||
|
for (typename Facets::iterator fit = facets.begin();
|
||||||
|
fit != facets.end();
|
||||||
|
++fit)
|
||||||
|
{
|
||||||
|
// foreach edge of *fit
|
||||||
|
const Cell_handle cell = fit->first;
|
||||||
|
const int i = fit->second;
|
||||||
|
for(int j = 0; j < 3; ++j)
|
||||||
|
{
|
||||||
|
const int edge_index_va = r_tr_.vertex_triple_index(i, j);
|
||||||
|
const int edge_index_vb = r_tr_.vertex_triple_index(i, (j == 2) ? 0 : (j+1));
|
||||||
|
Edge edge(cell, edge_index_va, edge_index_vb);
|
||||||
|
// test if edge is in Complex
|
||||||
|
if ( r_c3t3_.face_status(edge) != C3t3::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 ( (r_c3t3_.face_status(edge) == C3t3::SINGULAR) ||
|
||||||
|
( (!m_with_boundary) &&
|
||||||
|
(r_c3t3_.face_status(edge) == C3t3::BOUNDARY) )
|
||||||
|
)
|
||||||
|
{
|
||||||
|
m_bad_edges.insert(Bad_edge(edge_to_edgevv(edge),
|
||||||
|
(r_c3t3_.face_status(edge) ==
|
||||||
|
C3t3::SINGULAR ? 0 : 1)));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_bad_edges.left.erase( edge_to_edgevv(edge) ); // @TODO: pourquoi?!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!m_bad_vertices_initialized) return;
|
||||||
|
|
||||||
|
// foreach v' in star of v
|
||||||
|
std::vector<Vertex_handle> vertices;
|
||||||
|
vertices.reserve(64);
|
||||||
|
r_tr_.incident_vertices(v, std::back_inserter(vertices));
|
||||||
|
|
||||||
|
// is_regular_or_boundary_for_vertices
|
||||||
|
// is used here also incident edges are not known to be
|
||||||
|
// REGULAR which may cause some singular vertices to be forgotten
|
||||||
|
// This causes no problem because
|
||||||
|
// those SINGULAR incident SINGULAR edges are going to be handled
|
||||||
|
for (typename std::vector<Vertex_handle>::iterator
|
||||||
|
vit = vertices.begin(), end = vertices.end();
|
||||||
|
vit != end; ++vit)
|
||||||
|
{
|
||||||
|
if ( r_c3t3_.has_incident_facets_in_complex(*vit) &&
|
||||||
|
(r_c3t3_.face_status(*vit) == C3t3::SINGULAR)
|
||||||
|
// !r_c3t3_.is_regular_or_boundary_for_vertices(*vit)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
#ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
std::cerr << "m_bad_vertices.insert("
|
||||||
|
<< (*vit)->point() << ")\n";
|
||||||
|
#endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
m_bad_vertices.insert(*vit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( r_c3t3_.has_incident_facets_in_complex(v) &&
|
||||||
|
(r_c3t3_.face_status(v) == C3t3::SINGULAR)
|
||||||
|
// !r_c3t3_.is_regular_or_boundary_for_vertices(v)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
#ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
std::cerr << "m_bad_vertices.insert("
|
||||||
|
<< v->point() << ")\n";
|
||||||
|
#endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||||
|
m_bad_vertices.insert(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string debug_info() const
|
||||||
|
{
|
||||||
|
std::stringstream s;
|
||||||
|
s << Base::debug_info();
|
||||||
|
if(m_with_manifold_criterion) {
|
||||||
|
s << "," << m_bad_edges.left.size()
|
||||||
|
<< "," << m_bad_vertices.size();
|
||||||
|
}
|
||||||
|
return s.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string debug_info_header() const
|
||||||
|
{
|
||||||
|
std::stringstream s;
|
||||||
|
s << Base::debug_info_header();
|
||||||
|
if(m_with_manifold_criterion) {
|
||||||
|
s << ",#bad edges,#bad vertices";
|
||||||
|
}
|
||||||
|
return s.str();
|
||||||
|
}
|
||||||
|
}; // end Refine_facets_manifold_base
|
||||||
|
|
||||||
|
} // end namespace Mesh_3
|
||||||
|
|
||||||
|
} // end namespace CGAL
|
||||||
|
|
||||||
|
|
||||||
|
#endif // CGAL_MESH_3_REFINE_FACETS_MANIFOLD_BASE_H
|
||||||
|
|
@ -50,6 +50,8 @@ private:
|
||||||
typedef Mesh_facet_criteria_3<Tr> Self;
|
typedef Mesh_facet_criteria_3<Tr> Self;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
typedef CGAL::Tag_true Has_manifold_criterion;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constructor
|
* @brief Constructor
|
||||||
*/
|
*/
|
||||||
|
|
@ -110,6 +112,10 @@ public:
|
||||||
criteria_.add(criterion);
|
criteria_.add(criterion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Mesh_facet_topology topology() const {
|
||||||
|
return topology_;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init_aspect(const FT& angle_bound)
|
void init_aspect(const FT& angle_bound)
|
||||||
{
|
{
|
||||||
|
|
@ -138,7 +144,8 @@ private:
|
||||||
|
|
||||||
void init_topo(const Mesh_facet_topology topology)
|
void init_topo(const Mesh_facet_topology topology)
|
||||||
{
|
{
|
||||||
switch ( topology )
|
topology_ = topology;
|
||||||
|
switch ( topology % MANIFOLD )
|
||||||
{
|
{
|
||||||
case FACET_VERTICES_ON_SURFACE:
|
case FACET_VERTICES_ON_SURFACE:
|
||||||
{
|
{
|
||||||
|
|
@ -166,6 +173,7 @@ private:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Criteria criteria_;
|
Criteria criteria_;
|
||||||
|
Mesh_facet_topology topology_;
|
||||||
}; // end class Mesh_facet_criteria_3
|
}; // end class Mesh_facet_criteria_3
|
||||||
|
|
||||||
} // end namespace CGAL
|
} // end namespace CGAL
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,11 @@ namespace CGAL {
|
||||||
|
|
||||||
enum Mesh_facet_topology {
|
enum Mesh_facet_topology {
|
||||||
FACET_VERTICES_ON_SURFACE = 1,
|
FACET_VERTICES_ON_SURFACE = 1,
|
||||||
FACET_VERTICES_ON_SAME_SURFACE_PATCH,
|
FACET_VERTICES_ON_SAME_SURFACE_PATCH = 2,
|
||||||
FACET_VERTICES_ON_SAME_SURFACE_PATCH_WITH_ADJACENCY_CHECK
|
FACET_VERTICES_ON_SAME_SURFACE_PATCH_WITH_ADJACENCY_CHECK = 3,
|
||||||
|
MANIFOLD_WITH_BOUNDARY = 8,
|
||||||
|
NO_BOUNDARY = 16,
|
||||||
|
MANIFOLD = 24
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace CGAL
|
} // end namespace CGAL
|
||||||
|
|
|
||||||
|
|
@ -212,12 +212,12 @@ public:
|
||||||
cache_validity = true;
|
cache_validity = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cached_number_of_incident_facets() const
|
std::size_t cached_number_of_incident_facets() const
|
||||||
{
|
{
|
||||||
return number_of_incident_facets_;
|
return number_of_incident_facets_;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cached_number_of_components() const
|
std::size_t cached_number_of_components() const
|
||||||
{
|
{
|
||||||
return number_of_components_;
|
return number_of_components_;
|
||||||
}
|
}
|
||||||
|
|
@ -232,8 +232,8 @@ public:
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
|
||||||
int number_of_incident_facets_;
|
std::size_t number_of_incident_facets_;
|
||||||
int number_of_components_; // number of components in the adjacency
|
std::size_t number_of_components_; // number of components in the adjacency
|
||||||
// graph of incident facets (in complex)
|
// graph of incident facets (in complex)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,19 +42,12 @@ namespace CGAL {
|
||||||
typedef C2T3 C2t3;
|
typedef C2T3 C2t3;
|
||||||
typedef typename C2T3::Triangulation Tr;
|
typedef typename C2T3::Triangulation Tr;
|
||||||
typedef typename Tr::Geom_traits GT;
|
typedef typename Tr::Geom_traits GT;
|
||||||
typedef typename GT::FT FT;
|
|
||||||
typedef typename Tr::Point Point;
|
typedef typename Tr::Point Point;
|
||||||
typedef typename Tr::Facet Facet;
|
typedef typename Tr::Facet Facet;
|
||||||
typedef typename Tr::Cell_handle Cell_handle;
|
|
||||||
typedef typename Tr::Vertex_handle Vertex_handle;
|
typedef typename Tr::Vertex_handle Vertex_handle;
|
||||||
typedef typename Triangulation_mesher_level_traits_3<Tr>::Zone Zone;
|
typedef typename Triangulation_mesher_level_traits_3<Tr>::Zone Zone;
|
||||||
typedef std::list<Facet> Facets;
|
|
||||||
typedef std::list<Vertex_handle> Vertices;
|
|
||||||
typedef typename Facets::iterator Facets_iterator;
|
|
||||||
typedef typename Vertices::iterator Vertices_iterator;
|
|
||||||
typedef typename Tr::Finite_vertices_iterator Finite_vertices_iterator;
|
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
// because of the caching, these two members have to be mutable,
|
// because of the caching, these two members have to be mutable,
|
||||||
// because they are actually updated in the const method
|
// because they are actually updated in the const method
|
||||||
// 'no_longer_element_to_refine_impl()'
|
// 'no_longer_element_to_refine_impl()'
|
||||||
|
|
@ -63,6 +56,13 @@ namespace CGAL {
|
||||||
mutable bool bad_vertices_initialized;
|
mutable bool bad_vertices_initialized;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
typedef typename Tr::Cell_handle Cell_handle;
|
||||||
|
typedef std::list<Facet> Facets;
|
||||||
|
typedef std::list<Vertex_handle> Vertices;
|
||||||
|
typedef typename Facets::iterator Facets_iterator;
|
||||||
|
typedef typename Vertices::iterator Vertices_iterator;
|
||||||
|
typedef typename Tr::Finite_vertices_iterator Finite_vertices_iterator;
|
||||||
|
|
||||||
Facet canonical_facet(const Facet& f) const {
|
Facet canonical_facet(const Facet& f) const {
|
||||||
const Cell_handle& c = f.first;
|
const Cell_handle& c = f.first;
|
||||||
const Cell_handle& c2 = c->neighbor(f.second);
|
const Cell_handle& c2 = c->neighbor(f.second);
|
||||||
|
|
@ -107,6 +107,27 @@ namespace CGAL {
|
||||||
return biggest_facet;
|
return biggest_facet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void initialize_bad_vertices() const
|
||||||
|
{
|
||||||
|
#ifdef CGAL_SURFACE_MESHER_VERBOSE
|
||||||
|
std::cerr << "scanning vertices" << std::endl;
|
||||||
|
#endif
|
||||||
|
int n = 0;
|
||||||
|
for (Finite_vertices_iterator vit = SMMBB::tr.finite_vertices_begin();
|
||||||
|
vit != SMMBB::tr.finite_vertices_end();
|
||||||
|
++vit) {
|
||||||
|
if ( (SMMBB::c2t3.face_status(vit) // @TODO: appeler is_regular
|
||||||
|
== C2t3::SINGULAR) ) {
|
||||||
|
bad_vertices.insert( vit );
|
||||||
|
++n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bad_vertices_initialized = true;
|
||||||
|
#ifdef CGAL_SURFACE_MESHER_VERBOSE
|
||||||
|
std::cerr << " -> found " << n << " bad vertices\n";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Surface_mesher_manifold_base (C2T3& c2t3,
|
Surface_mesher_manifold_base (C2T3& c2t3,
|
||||||
const Surface& surface,
|
const Surface& surface,
|
||||||
|
|
@ -133,27 +154,6 @@ namespace CGAL {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initialize_bad_vertices() const
|
|
||||||
{
|
|
||||||
#ifdef CGAL_SURFACE_MESHER_VERBOSE
|
|
||||||
std::cerr << "scanning vertices" << std::endl;
|
|
||||||
#endif
|
|
||||||
int n = 0;
|
|
||||||
for (Finite_vertices_iterator vit = SMMBB::tr.finite_vertices_begin();
|
|
||||||
vit != SMMBB::tr.finite_vertices_end();
|
|
||||||
++vit) {
|
|
||||||
if ( (SMMBB::c2t3.face_status(vit) // @TODO: appeler is_regular
|
|
||||||
== C2t3::SINGULAR) ) {
|
|
||||||
bad_vertices.insert( vit );
|
|
||||||
++n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bad_vertices_initialized = true;
|
|
||||||
#ifdef CGAL_SURFACE_MESHER_VERBOSE
|
|
||||||
std::cerr << " -> found " << n << " bad vertices\n";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lazy initialization function
|
// Lazy initialization function
|
||||||
void scan_triangulation_impl() {
|
void scan_triangulation_impl() {
|
||||||
SMMBB::scan_triangulation_impl();
|
SMMBB::scan_triangulation_impl();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue