mirror of https://github.com/CGAL/cgal
add code to protect_constraints
edges tagged as constraints are not refined when protect_constraints is true
This commit is contained in:
parent
ebeb1fdcaa
commit
00cc96f968
|
|
@ -35,6 +35,7 @@ namespace CGAL{
|
|||
enum less_halfedge_t { less_halfedge };
|
||||
enum geom_traits_t { geom_traits };
|
||||
enum number_of_iterations_t { number_of_iterations };
|
||||
enum protect_constraints_t { protect_constraints };
|
||||
|
||||
//internal
|
||||
enum weight_calculator_t { weight_calculator };
|
||||
|
|
@ -130,6 +131,13 @@ namespace CGAL{
|
|||
return Params(n, *this);
|
||||
}
|
||||
|
||||
pmp_bgl_named_params<bool, protect_constraints_t, self>
|
||||
protect_constraints(const bool& b) const
|
||||
{
|
||||
typedef pmp_bgl_named_params<bool, protect_constraints_t, self> Params;
|
||||
return Params(b, *this);
|
||||
}
|
||||
|
||||
//overload
|
||||
template <typename EdgeIsConstrained>
|
||||
pmp_bgl_named_params<EdgeIsConstrained, edge_is_constrained_t, self>
|
||||
|
|
@ -252,6 +260,13 @@ namespace parameters{
|
|||
return Params(n);
|
||||
}
|
||||
|
||||
pmp_bgl_named_params<bool, protect_constraints_t>
|
||||
protect_constraints(const bool& b)
|
||||
{
|
||||
typedef pmp_bgl_named_params<bool, protect_constraints_t> Params;
|
||||
return Params(b);
|
||||
}
|
||||
|
||||
//overload
|
||||
template <typename EdgeIsConstrained>
|
||||
pmp_bgl_named_params<EdgeIsConstrained, edge_is_constrained_t>
|
||||
|
|
|
|||
|
|
@ -96,12 +96,14 @@ namespace internal {
|
|||
Incremental_remesher(PolygonMesh& pmesh
|
||||
, const FaceRange& face_range
|
||||
, VertexPointMap& vpmap
|
||||
, const EdgeIsConstrainedMap& ecmap)
|
||||
, const EdgeIsConstrainedMap& ecmap
|
||||
, const bool protect_constraints)
|
||||
: mesh_(pmesh)
|
||||
, vpmap_(vpmap)
|
||||
, own_tree_(true)
|
||||
, input_triangles_()
|
||||
, halfedge_status_map_()
|
||||
, protect_constraints_(protect_constraints)
|
||||
{
|
||||
CGAL_assertion(CGAL::is_triangle_mesh(mesh_));
|
||||
|
||||
|
|
@ -162,9 +164,12 @@ namespace internal {
|
|||
halfedge_descriptor he = eit->second;
|
||||
double sqlen = eit->first;
|
||||
long_edges.right.erase(eit);
|
||||
Point refinement_point = this->midpoint(he);
|
||||
|
||||
if (protect_constraints_ && !is_split_allowed(edge(he, mesh_)))
|
||||
continue;
|
||||
|
||||
//split edge
|
||||
Point refinement_point = this->midpoint(he);
|
||||
halfedge_descriptor hnew = CGAL::Euler::split_edge(he, mesh_);
|
||||
CGAL_assertion(he == next(hnew, mesh_));
|
||||
++nb_splits;
|
||||
|
|
@ -173,6 +178,11 @@ namespace internal {
|
|||
vertex_descriptor vnew = target(hnew, mesh_);
|
||||
put(vpmap_, vnew, refinement_point);
|
||||
|
||||
//after splitting
|
||||
halfedge_descriptor hnew_opp = opposite(hnew, mesh_);
|
||||
halfedge_added(hnew, status(he));
|
||||
halfedge_added(hnew_opp, status(opposite(he, mesh_)));
|
||||
|
||||
//check sub-edges
|
||||
double sqlen_new = 0.25 * sqlen;
|
||||
if (sqlen_new > sq_high)
|
||||
|
|
@ -182,20 +192,13 @@ namespace internal {
|
|||
long_edges.insert(long_edge(next(hnew, mesh_), sqlen_new));
|
||||
}
|
||||
|
||||
//after splitting
|
||||
halfedge_descriptor hnew_opp = opposite(hnew, mesh_);
|
||||
halfedge_added(hnew, status(he));
|
||||
halfedge_added(hnew_opp, status(opposite(he, mesh_)));
|
||||
|
||||
//insert new edges to keep triangular faces, and update long_edges
|
||||
|
||||
if (!is_on_border(hnew))
|
||||
{
|
||||
halfedge_descriptor hnew2 = CGAL::Euler::split_face(hnew,
|
||||
next(next(hnew, mesh_), mesh_),
|
||||
mesh_);
|
||||
Halfedge_status snew = (is_on_patch(hnew)
|
||||
|| (is_on_patch_border(hnew) && !is_on_patch(hnew_opp)))
|
||||
Halfedge_status snew = (is_on_patch(hnew) || is_on_patch_border(hnew))
|
||||
? PATCH
|
||||
: MESH;
|
||||
halfedge_added(hnew2, snew);
|
||||
|
|
@ -215,8 +218,7 @@ namespace internal {
|
|||
halfedge_descriptor hnew2 = CGAL::Euler::split_face(prev(hnew_opp, mesh_),
|
||||
next(hnew_opp, mesh_),
|
||||
mesh_);
|
||||
Halfedge_status snew = (is_on_patch(hnew_opp)
|
||||
|| (is_on_patch_border(hnew_opp) && !is_on_patch(hnew)))
|
||||
Halfedge_status snew = (is_on_patch(hnew_opp) || is_on_patch_border(hnew_opp))
|
||||
? PATCH
|
||||
: MESH;
|
||||
halfedge_added(hnew2, snew);
|
||||
|
|
@ -641,23 +643,59 @@ namespace internal {
|
|||
&& (plane1.oriented_side(p4) != plane2.oriented_side(p4));
|
||||
}
|
||||
|
||||
//todo : simplify the list of cases
|
||||
bool is_split_allowed(const edge_descriptor& e) const
|
||||
{
|
||||
halfedge_descriptor he = halfedge(e, mesh_);
|
||||
return is_on_patch(he) //opp is also on patch
|
||||
|| (is_on_border(he) && is_on_patch_border(opposite(he, mesh_)))
|
||||
|| (is_on_border(opposite(he, mesh_)) && is_on_patch_border(he))
|
||||
|| is_on_patch_border(he)
|
||||
|| is_on_patch_border(opposite(he, mesh_));
|
||||
halfedge_descriptor hopp = opposite(he, mesh_);
|
||||
|
||||
bool splittable = false;
|
||||
if (is_on_patch(face(he, mesh_)))
|
||||
splittable = is_split_allowed(he);
|
||||
|
||||
if (splittable && is_on_patch(face(hopp, mesh_)))
|
||||
splittable = is_split_allowed(hopp);
|
||||
|
||||
return splittable;
|
||||
}
|
||||
|
||||
bool is_split_allowed(const halfedge_descriptor& h) const
|
||||
{
|
||||
if (!protect_constraints_)//allow splitting constraints
|
||||
{
|
||||
return is_on_patch_border(h)
|
||||
|| is_on_patch(h)
|
||||
|| is_on_border(h);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!is_on_patch(h)) //PATCH are the only splittable edges
|
||||
return false;
|
||||
else
|
||||
return is_longest_edge_of_face(h);
|
||||
}
|
||||
}
|
||||
|
||||
bool is_longest_edge_of_face(const halfedge_descriptor& h) const
|
||||
{
|
||||
double sqh = sqlength(h);
|
||||
return sqh >= sqlength(next(h, mesh_))
|
||||
&& sqh >= sqlength(next(next(h, mesh_), mesh_));
|
||||
}
|
||||
|
||||
bool is_collapse_allowed(const edge_descriptor& e) const
|
||||
{
|
||||
halfedge_descriptor he = halfedge(e, mesh_);
|
||||
halfedge_descriptor hopp = opposite(he, mesh_);
|
||||
|
||||
if (protect_constraints_)
|
||||
{
|
||||
if (is_on_patch_border(he) || is_on_patch_border(hopp))
|
||||
return false;
|
||||
}
|
||||
|
||||
return is_on_patch(he) //opp is also on patch
|
||||
|| (is_on_border(he) && is_on_patch_border(opposite(he, mesh_)))
|
||||
|| (is_on_border(opposite(he, mesh_)) && is_on_patch_border(he));
|
||||
|| (is_on_border(he) && is_on_patch_border(hopp))
|
||||
|| (is_on_border(hopp) && is_on_patch_border(he));
|
||||
}
|
||||
|
||||
void tag_halfedges_status(const FaceRange& face_range
|
||||
|
|
@ -743,6 +781,17 @@ namespace internal {
|
|||
return res;
|
||||
}
|
||||
|
||||
bool is_on_patch(const face_descriptor& f) const
|
||||
{
|
||||
BOOST_FOREACH(halfedge_descriptor h,
|
||||
halfedges_around_face(halfedge(f, mesh_), mesh_))
|
||||
{
|
||||
if (is_on_patch(h) || is_on_patch_border(h))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_on_patch(const vertex_descriptor& v) const
|
||||
{
|
||||
BOOST_FOREACH(halfedge_descriptor h,
|
||||
|
|
@ -894,6 +943,7 @@ namespace internal {
|
|||
bool own_tree_;
|
||||
Triangle_list input_triangles_;
|
||||
std::map<halfedge_descriptor, Halfedge_status> halfedge_status_map_;
|
||||
bool protect_constraints_;
|
||||
|
||||
};//end class Incremental_remesher
|
||||
}//end namespace internal
|
||||
|
|
|
|||
|
|
@ -71,6 +71,8 @@ void incremental_triangle_based_remeshing(PolygonMesh& pmesh
|
|||
, const double& target_edge_length
|
||||
, const NamedParameters& np)
|
||||
{
|
||||
std::cout.precision(18);
|
||||
|
||||
typedef PolygonMesh PM;
|
||||
using boost::choose_pmap;
|
||||
using boost::get_param;
|
||||
|
|
@ -92,8 +94,10 @@ void incremental_triangle_based_remeshing(PolygonMesh& pmesh
|
|||
= choose_param(get_param(np, edge_is_constrained),
|
||||
internal::Border_constraint_pmap<PM, FaceRange>(pmesh, faces));
|
||||
|
||||
bool protect = choose_param(get_param(np, protect_constraints), false);
|
||||
|
||||
typename internal::Incremental_remesher<PM, FaceRange, VPMap, GT, ECMap>
|
||||
remesher(pmesh, faces, vpmap, ecmap);
|
||||
remesher(pmesh, faces, vpmap, ecmap, protect);
|
||||
|
||||
unsigned int nb_iterations = choose_param(get_param(np, number_of_iterations), 1);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue