mirror of https://github.com/CGAL/cgal
Merge remote-tracking branch 'origin/Mesh_3-fix_exuder_holes_on_surface-GF' into releases/CGAL-4.5-branch
Bug-fix for Mesh_3: Fix a bug in the sliver exudation preservation of boundaries. Approved by the Release Manager.
This commit is contained in:
commit
d85eaa327c
|
|
@ -1,4 +1,14 @@
|
|||
|
||||
-------------------------------- Release 4.5.1 --------------------------------
|
||||
|
||||
Release date: XX 2014
|
||||
|
||||
|
||||
* 3D Mesh Generation
|
||||
|
||||
- Fix a bug in the sliver exudation preservation of boundaries.
|
||||
|
||||
|
||||
-------------------------------- Release 4.5 --------------------------------
|
||||
|
||||
Release date: October 2014
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@
|
|||
<td width="28%">
|
||||
|
||||
<table CELLSPACING=0>
|
||||
<tr><td><a href="#release4.5.1">4.5.1</a> <td> (XX 2014)
|
||||
<tr><td><a href="#release4.5">4.5</a> <td> (October 2014)
|
||||
<tr><td><a href="#release4.4">4.4</a> <td> (April 2014)
|
||||
<tr><td><a href="#release4.3">4.3.1</a> <td> (November 2013)
|
||||
|
|
@ -109,6 +110,17 @@ and <code>src/</code> directories).
|
|||
|
||||
<HR>
|
||||
|
||||
|
||||
<h2 id="release4.5.1">Release 4.5.1 </h2>
|
||||
<div>
|
||||
<p>Release date: XX 2014 </p>
|
||||
|
||||
<h3>3D Mesh Generation</h3>
|
||||
<ul>
|
||||
<li>Fix a bug in the sliver exudation preservation of boundaries. </li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h2 id="release4.5">Release 4.5 </h2>
|
||||
<div>
|
||||
<p>Release date: October 2014 </p>
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
#include <boost/bind.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include <CGAL/Timer.h>
|
||||
|
||||
|
|
@ -403,7 +404,8 @@ private: // Types
|
|||
// weighted point conflict zone. Such facets are represented by their edge
|
||||
// which do not contain the pumped vertex
|
||||
typedef std::pair<Vertex_handle,Vertex_handle> Ordered_edge;
|
||||
typedef std::map<Ordered_edge, Surface_patch_index > Umbrella;
|
||||
typedef std::pair<Surface_patch_index, std::size_t> Patch_and_counter;
|
||||
typedef std::map<Ordered_edge, Patch_and_counter> Umbrella;
|
||||
|
||||
// Boundary_facets_from_outside represents the facet of the conflict zone
|
||||
// seen from outside of it. It stores Surface_patch_index of the facet, and
|
||||
|
|
@ -531,14 +533,15 @@ private:
|
|||
/**
|
||||
* Returns the umbrella of internal_facets vector
|
||||
*/
|
||||
Umbrella get_umbrella(const Facet_vector& internal_facets,
|
||||
const Vertex_handle& v) const;
|
||||
boost::optional<Umbrella>
|
||||
get_umbrella(const Facet_vector& internal_facets,
|
||||
const Vertex_handle& v) const;
|
||||
|
||||
/**
|
||||
* Updates the mesh with new_point
|
||||
*/
|
||||
template <bool pump_vertices_on_surfaces>
|
||||
void update_mesh(const Weighted_point& new_point,
|
||||
bool update_mesh(const Weighted_point& new_point,
|
||||
const Vertex_handle& old_vertex,
|
||||
bool *could_lock_zone = NULL);
|
||||
|
||||
|
|
@ -567,6 +570,15 @@ private:
|
|||
std::swap(h1, h2);
|
||||
}
|
||||
|
||||
template <typename Handle>
|
||||
static
|
||||
void order_three_handles(Handle& h1, Handle& h2, Handle& h3)
|
||||
{
|
||||
if(h1 > h2) std::swap(h1, h2);
|
||||
if(h2 > h3) std::swap(h2, h3);
|
||||
if(h1 > h2) std::swap(h1, h2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialization
|
||||
*/
|
||||
|
|
@ -1110,9 +1122,10 @@ pump_vertex(const Vertex_handle& pumped_vertex,
|
|||
Weighted_point wp(pumped_vertex->point(), best_weight);
|
||||
|
||||
// Insert weighted point into mesh
|
||||
update_mesh<pump_vertices_on_surfaces>(wp, pumped_vertex, could_lock_zone);
|
||||
|
||||
return true;
|
||||
// note it can fail if the mesh is non-manifold at pumped_vertex
|
||||
return update_mesh<pump_vertices_on_surfaces>(wp,
|
||||
pumped_vertex,
|
||||
could_lock_zone);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
@ -1355,12 +1368,13 @@ get_best_weight(const Vertex_handle& v, bool *could_lock_zone) const
|
|||
|
||||
|
||||
template <typename C3T3, typename SC, typename V_, typename FT>
|
||||
typename Slivers_exuder<C3T3,SC,V_,FT>::Umbrella
|
||||
boost::optional<typename Slivers_exuder<C3T3,SC,V_,FT>::Umbrella >
|
||||
Slivers_exuder<C3T3,SC,V_,FT>::
|
||||
get_umbrella(const Facet_vector& facets,
|
||||
const Vertex_handle& v) const
|
||||
get_umbrella(const Facet_vector& facets,//internal_facets of conflict zone
|
||||
|
||||
const Vertex_handle& /* v no longer used */) const
|
||||
{
|
||||
Umbrella umbrella;
|
||||
Umbrella umbrella; //std::map<Ordered_edge, Patch_and_counter>
|
||||
|
||||
// Insert into umbrella surface_index of facets which are on the surface
|
||||
typename Facet_vector::const_iterator fit = facets.begin();
|
||||
|
|
@ -1368,11 +1382,55 @@ get_umbrella(const Facet_vector& facets,
|
|||
{
|
||||
if ( c3t3_.is_in_complex(*fit) )
|
||||
{
|
||||
Ordered_edge edge = get_opposite_ordered_edge(*fit, v);
|
||||
umbrella.insert(std::make_pair(edge, c3t3_.surface_patch_index(*fit)));
|
||||
Facet f = *fit;
|
||||
Vertex_handle v1 = f.first->vertex((f.second+1)%4);
|
||||
Vertex_handle v2 = f.first->vertex((f.second+2)%4);
|
||||
Vertex_handle v3 = f.first->vertex((f.second+3)%4);
|
||||
order_three_handles(v1, v2, v3);
|
||||
std::vector<Ordered_edge> edges;
|
||||
edges.push_back(Ordered_edge(v1, v2));
|
||||
edges.push_back(Ordered_edge(v2, v3));
|
||||
edges.push_back(Ordered_edge(v1, v3));
|
||||
|
||||
for(std::size_t i = 0; i < 3; ++i)
|
||||
{
|
||||
Ordered_edge oe = edges[i];
|
||||
typename Umbrella::iterator uit = umbrella.find(oe);
|
||||
if(uit == umbrella.end()) //umbrella does not contain oe yet
|
||||
{
|
||||
umbrella.insert(std::make_pair(oe,
|
||||
std::make_pair(c3t3_.surface_patch_index(f), 1)));
|
||||
}
|
||||
else //umbrella already contains oe. Increment counter or return
|
||||
{
|
||||
std::size_t count = (*uit).second.second;
|
||||
if(count == 2) //there will be more than 3 after insertion
|
||||
return boost::none; //non-manifold configuration
|
||||
|
||||
umbrella.insert(uit,
|
||||
std::make_pair(oe,
|
||||
std::make_pair(c3t3_.surface_patch_index(f), count + 1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// erase edges that have been counted twice
|
||||
//each Oriented_edge should appear only once
|
||||
// twice means it belongs to two internal facets that are restricted
|
||||
// three or more corresponds to a non-manifold geometry
|
||||
typename Umbrella::iterator uit = umbrella.begin();
|
||||
while(uit != umbrella.end())
|
||||
{
|
||||
if((*uit).second.second == 2)
|
||||
{
|
||||
typename Umbrella::iterator to_be_erased = uit++;
|
||||
umbrella.erase(to_be_erased);
|
||||
}
|
||||
else
|
||||
++uit;
|
||||
}
|
||||
|
||||
return umbrella;
|
||||
}
|
||||
|
||||
|
|
@ -1438,6 +1496,8 @@ Slivers_exuder<C3T3,SC,V_,FT>::get_opposite_ordered_edge(
|
|||
const Facet& facet,
|
||||
const Vertex_handle& vertex) const
|
||||
{
|
||||
CGAL_assertion(tr_.has_vertex(facet, vertex));
|
||||
|
||||
Vertex_handle v1;
|
||||
Vertex_handle v2;
|
||||
|
||||
|
|
@ -1484,7 +1544,7 @@ restore_internal_facets(const Umbrella& umbrella,
|
|||
const typename Umbrella::const_iterator um_it = umbrella.find(edge);
|
||||
if( um_it != umbrella.end() )
|
||||
{
|
||||
c3t3_.add_to_complex(*fit, um_it->second);
|
||||
c3t3_.add_to_complex(*fit, um_it->second.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1492,7 +1552,7 @@ restore_internal_facets(const Umbrella& umbrella,
|
|||
|
||||
template <typename C3T3, typename SC, typename V_, typename FT>
|
||||
template <bool pump_vertices_on_surfaces>
|
||||
void
|
||||
bool
|
||||
Slivers_exuder<C3T3,SC,V_,FT>::
|
||||
update_mesh(const Weighted_point& new_point,
|
||||
const Vertex_handle& old_vertex,
|
||||
|
|
@ -1516,13 +1576,16 @@ update_mesh(const Weighted_point& new_point,
|
|||
could_lock_zone);
|
||||
|
||||
if (could_lock_zone && *could_lock_zone == false)
|
||||
return;
|
||||
return false;
|
||||
|
||||
// Get some datas to restore mesh
|
||||
Boundary_facets_from_outside boundary_facets_from_outside =
|
||||
get_boundary_facets_from_outside(boundary_facets);
|
||||
|
||||
Umbrella umbrella = get_umbrella(internal_facets, old_vertex);
|
||||
boost::optional<Umbrella> umbrella
|
||||
= get_umbrella(internal_facets, old_vertex);
|
||||
if(umbrella == boost::none)
|
||||
return false; //abort pumping this vertex
|
||||
|
||||
// Delete old cells from queue (they aren't in the triangulation anymore)
|
||||
this->delete_cells_from_queue(deleted_cells);
|
||||
|
|
@ -1546,10 +1609,12 @@ update_mesh(const Weighted_point& new_point,
|
|||
// Restore mesh
|
||||
restore_cells_and_boundary_facets<pump_vertices_on_surfaces>(
|
||||
boundary_facets_from_outside, new_vertex);
|
||||
restore_internal_facets(umbrella, new_vertex);
|
||||
restore_internal_facets(*umbrella, new_vertex);
|
||||
|
||||
// Only true for sequential version
|
||||
CGAL_assertion(could_lock_zone || nb_vert == tr_.number_of_vertices());
|
||||
|
||||
return true;//pump was done successfully
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue