mirror of https://github.com/CGAL/cgal
Merge remote-tracking branch 'MaelRL/PMP-Improve_SI_repair-GF' into HEAD
This commit is contained in:
commit
07e917ca09
|
|
@ -437,7 +437,7 @@ struct Face_filtered_graph
|
|||
initialize_halfedge_indices();
|
||||
}
|
||||
|
||||
///change the set of selected faces using a patch id
|
||||
/// changes the set of selected faces using a patch id
|
||||
template<class FacePatchIndexMap>
|
||||
void set_selected_faces(typename boost::property_traits<FacePatchIndexMap>::value_type face_patch_id,
|
||||
FacePatchIndexMap face_patch_index_map)
|
||||
|
|
@ -466,7 +466,7 @@ struct Face_filtered_graph
|
|||
|
||||
reset_indices();
|
||||
}
|
||||
/// change the set of selected faces using a range of patch ids
|
||||
/// changes the set of selected faces using a range of patch ids
|
||||
template<class FacePatchIndexRange, class FacePatchIndexMap>
|
||||
void set_selected_faces(const FacePatchIndexRange& selected_face_patch_indices,
|
||||
FacePatchIndexMap face_patch_index_map
|
||||
|
|
@ -506,7 +506,7 @@ struct Face_filtered_graph
|
|||
reset_indices();
|
||||
}
|
||||
|
||||
/// change the set of selected faces using a range of face descriptors
|
||||
/// changes the set of selected faces using a range of face descriptors
|
||||
template<class FaceRange>
|
||||
void set_selected_faces(const FaceRange& selection)
|
||||
{
|
||||
|
|
@ -569,18 +569,21 @@ struct Face_filtered_graph
|
|||
{
|
||||
return selected_halfedges[get(himap, halfedge(e,_graph))];
|
||||
}
|
||||
///returns the number of selected faces
|
||||
size_type number_of_faces()const
|
||||
|
||||
/// returns the number of selected faces
|
||||
size_type number_of_faces() const
|
||||
{
|
||||
return selected_faces.count();
|
||||
}
|
||||
///returns the number of selected vertices.
|
||||
size_type number_of_vertices()const
|
||||
|
||||
/// returns the number of selected vertices.
|
||||
size_type number_of_vertices() const
|
||||
{
|
||||
return selected_vertices.count();
|
||||
}
|
||||
///returns the number of selected halfedges.
|
||||
size_type number_of_halfedges()const
|
||||
|
||||
/// returns the number of selected halfedges.
|
||||
size_type number_of_halfedges() const
|
||||
{
|
||||
return selected_halfedges.count();
|
||||
}
|
||||
|
|
@ -612,18 +615,15 @@ struct Face_filtered_graph
|
|||
return bind_property_maps(himap, make_property_map(halfedge_indices) );
|
||||
}
|
||||
|
||||
/// returns `true` if around any vertex of a selected face,
|
||||
/// there is at most one connected set of selected faces.
|
||||
/// returns `true` if around any vertex of a selected face there is at most a single umbrella
|
||||
bool is_selection_valid() const
|
||||
{
|
||||
typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor;
|
||||
|
||||
// Non-manifoldness can appear either:
|
||||
// - if 'pm' is pinched at a vertex. While traversing the incoming halfedges at this vertex,
|
||||
// we will meet strictly more than one border halfedge.
|
||||
// - if there are multiple umbrellas around a vertex. In that case, we will find a non-visited
|
||||
// halfedge that has for target a vertex that is already visited.
|
||||
// Non-manifoldness can appear if there are multiple umbrellas around a vertex.
|
||||
// In that case, we will find a non-visited halfedge that has for target a vertex
|
||||
// that is already visited.
|
||||
|
||||
boost::unordered_set<vertex_descriptor> vertices_visited;
|
||||
boost::unordered_set<halfedge_descriptor> halfedges_handled;
|
||||
|
|
@ -643,15 +643,11 @@ struct Face_filtered_graph
|
|||
if(!vertices_visited.insert(vd).second)
|
||||
return false;
|
||||
|
||||
std::size_t border_halfedge_counter = 0;
|
||||
|
||||
// Can't simply call halfedges_around_target(vd, *this) because 'halfedge(vd)' is not necessarily 'hd'
|
||||
// Can't call halfedges_around_target(vd, *this) because 'halfedge(vd)' is not necessarily 'hd'
|
||||
halfedge_descriptor ihd = hd;
|
||||
do
|
||||
{
|
||||
halfedges_handled.insert(ihd);
|
||||
if(is_border(ihd, *this))
|
||||
++border_halfedge_counter;
|
||||
|
||||
do
|
||||
{
|
||||
|
|
@ -660,9 +656,6 @@ struct Face_filtered_graph
|
|||
while(!is_in_cc(ihd) && ihd != hd);
|
||||
}
|
||||
while(ihd != hd);
|
||||
|
||||
if(border_halfedge_counter > 1)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -1050,7 +1043,8 @@ typename boost::graph_traits< Face_filtered_graph<Graph, FIMap, VIMap, HIMap> >:
|
|||
next(typename boost::graph_traits< Face_filtered_graph<Graph, FIMap, VIMap, HIMap> >::halfedge_descriptor h,
|
||||
const Face_filtered_graph<Graph, FIMap, VIMap, HIMap> & w)
|
||||
{
|
||||
CGAL_assertion(w.is_in_cc(h));
|
||||
CGAL_precondition(w.is_in_cc(h));
|
||||
|
||||
if(w.is_in_cc(next(h, w.graph())))
|
||||
return next(h, w.graph());
|
||||
|
||||
|
|
@ -1074,8 +1068,8 @@ typename boost::graph_traits< Face_filtered_graph<Graph, FIMap, VIMap, HIMap> >:
|
|||
prev(typename boost::graph_traits< Face_filtered_graph<Graph, FIMap, VIMap, HIMap> >::halfedge_descriptor h,
|
||||
const Face_filtered_graph<Graph, FIMap, VIMap, HIMap> & w)
|
||||
{
|
||||
CGAL_precondition(w.is_in_cc(h));
|
||||
|
||||
CGAL_assertion(w.is_in_cc(h));
|
||||
if(w.is_in_cc(prev(h, w.graph())))
|
||||
return prev(h, w.graph());
|
||||
|
||||
|
|
|
|||
|
|
@ -484,8 +484,8 @@ void test_invalid_selections()
|
|||
face_range.push_back(SM::Face_index(2));
|
||||
face_range.push_back(SM::Face_index(3));
|
||||
|
||||
CGAL::Face_filtered_graph<SM> bad_fg(mesh, face_range);
|
||||
assert(!bad_fg.is_selection_valid());
|
||||
CGAL::Face_filtered_graph<SM> pinched_fg(mesh, face_range);
|
||||
assert(pinched_fg.is_selection_valid());
|
||||
|
||||
// this creates a non-manifold vertex (multiple umbrellas)
|
||||
clear(mesh);
|
||||
|
|
@ -495,8 +495,8 @@ void test_invalid_selections()
|
|||
face_range.clear();
|
||||
merge_vertices(SM::Vertex_index(1337), SM::Vertex_index(87), face_range, mesh);
|
||||
|
||||
CGAL::Face_filtered_graph<SM> bad_fg_2(mesh, face_range);
|
||||
assert(!bad_fg_2.is_selection_valid());
|
||||
CGAL::Face_filtered_graph<SM> many_umbrellas_fg(mesh, face_range);
|
||||
assert(!many_umbrellas_fg.is_selection_valid());
|
||||
}
|
||||
|
||||
int main()
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ void construct_oriented_bounding_box(const PointRange& points,
|
|||
obb_points[6] = cp(xmax, ymin, zmax);
|
||||
obb_points[7] = cp(xmax, ymax, zmax);
|
||||
|
||||
// Apply the inverse rotation to the rotated axis aligned bounding box
|
||||
// Apply the inverse rotation to the rotated axis-aligned bounding box
|
||||
for(std::size_t i=0; i<8; ++i)
|
||||
{
|
||||
obb_points[i] = inverse_transformation.transform(obb_points[i]);
|
||||
|
|
@ -141,13 +141,13 @@ void compute_best_transformation(const PointRange& points,
|
|||
rot(1, 0), rot(1, 1), rot(1, 2),
|
||||
rot(2, 0), rot(2, 1), rot(2, 2));
|
||||
|
||||
// inverse transformation is simply the transposed since the matrix is unitary
|
||||
// the inverse transformation is simply the transposed matrix since the matrix is unitary
|
||||
inverse_transformation = Aff_transformation_3(rot(0, 0), rot(1, 0), rot(2, 0),
|
||||
rot(0, 1), rot(1, 1), rot(2, 1),
|
||||
rot(0, 2), rot(1, 2), rot(2, 2));
|
||||
}
|
||||
|
||||
// Following two functions are overloads to dispatch depending on return type
|
||||
// The following two functions are overloads to dispatch depending on the return type
|
||||
template <typename PointRange, typename K, typename Traits>
|
||||
void construct_oriented_bounding_box(const PointRange& points,
|
||||
CGAL::Aff_transformation_3<K>& transformation,
|
||||
|
|
@ -325,6 +325,7 @@ void oriented_bounding_box(const PointRange& points,
|
|||
{
|
||||
using CGAL::parameters::choose_parameter;
|
||||
using CGAL::parameters::get_parameter;
|
||||
using CGAL::parameters::is_default_parameter;
|
||||
|
||||
typedef typename CGAL::GetPointMap<PointRange, NamedParameters>::type PointMap;
|
||||
|
||||
|
|
@ -350,7 +351,8 @@ void oriented_bounding_box(const PointRange& points,
|
|||
const unsigned int seed = choose_parameter(get_parameter(np, internal_np::random_seed), -1); // undocumented
|
||||
|
||||
CGAL::Random fixed_seed_rng(seed);
|
||||
CGAL::Random& rng = (seed == unsigned(-1)) ? CGAL::get_default_random() : fixed_seed_rng;
|
||||
CGAL::Random& rng = is_default_parameter(get_parameter(np, internal_np::random_seed)) ?
|
||||
CGAL::get_default_random() : fixed_seed_rng;
|
||||
|
||||
#ifdef CGAL_OPTIMAL_BOUNDING_BOX_DEBUG
|
||||
std::cout << "Random seed: " << rng.get_seed() << std::endl;
|
||||
|
|
|
|||
|
|
@ -46,16 +46,21 @@ struct Tracer_polyhedron
|
|||
int i, int k,
|
||||
bool last = true)
|
||||
{
|
||||
if(i + 1 == k) { return P[i+1]; }
|
||||
if(i + 1 == k)
|
||||
return P[i+1];
|
||||
|
||||
halfedge_descriptor h, g;
|
||||
if(i+2 == k){
|
||||
if(i+2 == k)
|
||||
{
|
||||
if(last)
|
||||
{
|
||||
h = P[i+1];
|
||||
Euler::fill_hole(h,pmesh); }
|
||||
{
|
||||
h = P[i + 1];
|
||||
Euler::fill_hole(h, pmesh);
|
||||
}
|
||||
else
|
||||
{ h = Euler::add_face_to_border(prev(P[i+1],pmesh), P[i+2/*k*/], pmesh); }
|
||||
{
|
||||
h = Euler::add_face_to_border(prev(P[i + 1], pmesh), P[i + 2 /*k*/], pmesh);
|
||||
}
|
||||
|
||||
CGAL_assertion(face(h,pmesh) != boost::graph_traits<PolygonMesh>::null_face());
|
||||
*out++ = face(h,pmesh);
|
||||
|
|
@ -68,12 +73,14 @@ struct Tracer_polyhedron
|
|||
g = operator()(lambda, la, k, false);
|
||||
|
||||
if(last)
|
||||
{
|
||||
h = g;
|
||||
Euler::fill_hole(g,pmesh);
|
||||
}
|
||||
{
|
||||
h = g;
|
||||
Euler::fill_hole(g, pmesh);
|
||||
}
|
||||
else
|
||||
{ h = Euler::add_face_to_border(prev(h,pmesh), g, pmesh); }
|
||||
{
|
||||
h = Euler::add_face_to_border(prev(h, pmesh), g, pmesh);
|
||||
}
|
||||
|
||||
CGAL_assertion(face(h,pmesh) != boost::graph_traits<PolygonMesh>::null_face());
|
||||
*out++ = face(h,pmesh);
|
||||
|
|
@ -106,28 +113,29 @@ triangulate_hole_polygon_mesh(PolygonMesh& pmesh,
|
|||
typedef std::map<vertex_descriptor, int> Vertex_map;
|
||||
typedef typename Vertex_map::iterator Vertex_map_it;
|
||||
|
||||
#ifdef CGAL_PMP_HOLE_FILLING_DEBUG
|
||||
#ifdef CGAL_PMP_HOLE_FILLING_DEBUG
|
||||
CGAL::Timer timer; timer.start();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
std::vector<Point_3> P, Q;
|
||||
std::vector<Point_3> P, Q;
|
||||
std::vector<halfedge_descriptor> P_edges;
|
||||
Vertex_map vertex_map;
|
||||
|
||||
int id = 0;
|
||||
Hedge_around_face_circulator circ(border_halfedge,pmesh), done(circ);
|
||||
do{
|
||||
do
|
||||
{
|
||||
P.push_back(get(vpmap, target(*circ, pmesh)));
|
||||
Q.push_back(get(vpmap, target(next(opposite(next(*circ,pmesh),pmesh),pmesh),pmesh)));
|
||||
P_edges.push_back(*circ);
|
||||
if(!vertex_map.insert(std::make_pair(target(*circ,pmesh), id++)).second) {
|
||||
#ifndef CGAL_TEST_SUITE
|
||||
if(!vertex_map.insert(std::make_pair(target(*circ,pmesh), id++)).second)
|
||||
{
|
||||
#ifndef CGAL_TEST_SUITE
|
||||
CGAL_warning_msg(false, "Returning no output. Non-manifold vertex is found on boundary!");
|
||||
#else
|
||||
#else
|
||||
std::cerr << "W: Returning no output. Non-manifold vertex is found on boundary!\n";
|
||||
#endif
|
||||
return std::make_pair(out,
|
||||
CGAL::internal::Weight_min_max_dihedral_and_area::NOT_VALID());
|
||||
#endif
|
||||
return std::make_pair(out, CGAL::internal::Weight_min_max_dihedral_and_area::NOT_VALID());
|
||||
}
|
||||
} while (++circ != done);
|
||||
|
||||
|
|
@ -151,52 +159,52 @@ triangulate_hole_polygon_mesh(PolygonMesh& pmesh,
|
|||
if(v_it_neigh_it != vertex_map.end()) //other endpoint found in the map
|
||||
{
|
||||
int v_it_neigh_id = v_it_neigh_it->second;
|
||||
if( v_it_neigh_id != v_it_prev && v_it_neigh_id != v_it_next )
|
||||
{ //there is an edge incident to v_it, which is not next or previous
|
||||
if(v_it_neigh_id != v_it_prev && v_it_neigh_id != v_it_next)
|
||||
{
|
||||
//there is an edge incident to v_it, which is not next or previous
|
||||
//from vertex_map (checked by comparing IDs)
|
||||
if(v_it_id < v_it_neigh_id) // to include each edge only once
|
||||
{ existing_edges.push_back(std::make_pair(v_it_id, v_it_neigh_id)); }
|
||||
existing_edges.push_back(std::make_pair(v_it_id, v_it_neigh_id));
|
||||
}
|
||||
}
|
||||
} while(++circ_vertex != done_vertex);
|
||||
}
|
||||
|
||||
//#define CGAL_USE_WEIGHT_INCOMPLETE
|
||||
#ifdef CGAL_USE_WEIGHT_INCOMPLETE
|
||||
//#define CGAL_USE_WEIGHT_INCOMPLETE
|
||||
#ifdef CGAL_USE_WEIGHT_INCOMPLETE
|
||||
typedef CGAL::internal::Weight_calculator<Weight_incomplete<CGAL::internal::Weight_min_max_dihedral_and_area>,
|
||||
CGAL::internal::Is_valid_existing_edges_and_degenerate_triangle> WC;
|
||||
#else
|
||||
#else
|
||||
typedef CGAL::internal::Weight_calculator<CGAL::internal::Weight_min_max_dihedral_and_area,
|
||||
CGAL::internal::Is_valid_existing_edges_and_degenerate_triangle> WC;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
CGAL::internal::Is_valid_existing_edges_and_degenerate_triangle is_valid(existing_edges);
|
||||
|
||||
// fill hole using polyline function, with custom tracer for PolygonMesh
|
||||
Tracer_polyhedron<PolygonMesh, OutputIterator>
|
||||
tracer(out, pmesh, P_edges);
|
||||
Tracer_polyhedron<PolygonMesh, OutputIterator> tracer(out, pmesh, P_edges);
|
||||
|
||||
#ifndef CGAL_HOLE_FILLING_DO_NOT_USE_CDT2
|
||||
if(use_cdt && triangulate_hole_polyline_with_cdt(P, tracer, is_valid, k, max_squared_distance))
|
||||
{
|
||||
return std::make_pair(tracer.out, CGAL::internal::Weight_min_max_dihedral_and_area(0,0));
|
||||
}
|
||||
if(use_cdt && triangulate_hole_polyline_with_cdt(P, tracer, is_valid, k, max_squared_distance))
|
||||
return std::make_pair(tracer.out, CGAL::internal::Weight_min_max_dihedral_and_area(0,0));
|
||||
#endif
|
||||
CGAL::internal::Weight_min_max_dihedral_and_area weight =
|
||||
triangulate_hole_polyline(P, Q, tracer, WC(is_valid),
|
||||
use_delaunay_triangulation, k)
|
||||
#ifdef CGAL_USE_WEIGHT_INCOMPLETE
|
||||
.weight // get actual weight in Weight_incomplete
|
||||
#ifndef CGAL_USE_WEIGHT_INCOMPLETE
|
||||
triangulate_hole_polyline(P, Q, tracer, WC(is_valid), use_delaunay_triangulation, k);
|
||||
#else
|
||||
// get actual weight in Weight_incomplete
|
||||
triangulate_hole_polyline(P, Q, tracer, WC(is_valid), use_delaunay_triangulation, k).weight;
|
||||
#endif
|
||||
;
|
||||
|
||||
#ifdef CGAL_PMP_HOLE_FILLING_DEBUG
|
||||
#ifdef CGAL_PMP_HOLE_FILLING_DEBUG
|
||||
std::cerr << "Hole filling: " << timer.time() << " sc." << std::endl; timer.reset();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return std::make_pair(tracer.out, weight);
|
||||
}
|
||||
|
||||
}// namespace internal
|
||||
}// namespace Polygon_mesh_processing
|
||||
}// namespace CGAL
|
||||
} // namespace internal
|
||||
} // namespace Polygon_mesh_processing
|
||||
} // namespace CGAL
|
||||
|
||||
#endif //CGAL_HOLE_FILLING_TRIANGULATE_HOLE_POLYHEDRON_3_H
|
||||
|
|
|
|||
|
|
@ -1492,11 +1492,11 @@ triangulate_hole_polyline(const PointRange1& points,
|
|||
|
||||
typedef Kernel K;
|
||||
typedef typename K::Point_3 Point_3;
|
||||
#ifndef CGAL_HOLE_FILLING_DO_NOT_USE_DT3
|
||||
#ifndef CGAL_HOLE_FILLING_DO_NOT_USE_DT3
|
||||
typedef CGAL::internal::Triangulate_hole_polyline_DT<K, Tracer, WeightCalculator> Fill_DT;
|
||||
#else
|
||||
#else
|
||||
CGAL_USE(use_delaunay_triangulation);
|
||||
#endif
|
||||
#endif
|
||||
typedef CGAL::internal::Triangulate_hole_polyline<K, Tracer, WeightCalculator> Fill;
|
||||
|
||||
std::vector<Point_3> P(boost::begin(points), boost::end(points));
|
||||
|
|
@ -1510,20 +1510,19 @@ triangulate_hole_polyline(const PointRange1& points,
|
|||
}
|
||||
|
||||
typename WeightCalculator::Weight w =
|
||||
#ifndef CGAL_HOLE_FILLING_DO_NOT_USE_DT3
|
||||
#ifndef CGAL_HOLE_FILLING_DO_NOT_USE_DT3
|
||||
use_delaunay_triangulation ? Fill_DT().operator()(P,Q,tracer,WC) :
|
||||
#endif
|
||||
#endif
|
||||
Fill().operator()(P,Q,tracer,WC);
|
||||
|
||||
#ifndef CGAL_HOLE_FILLING_DO_NOT_USE_DT3
|
||||
if (use_delaunay_triangulation
|
||||
&& w == WeightCalculator::Weight::NOT_VALID())
|
||||
if(use_delaunay_triangulation && w == WeightCalculator::Weight::NOT_VALID())
|
||||
w = Fill().operator()(P, Q, tracer, WC);
|
||||
#endif
|
||||
|
||||
#ifdef CGAL_PMP_HOLE_FILLING_DEBUG
|
||||
#ifdef CGAL_PMP_HOLE_FILLING_DEBUG
|
||||
std::cerr << w << std::endl;
|
||||
#endif
|
||||
#endif
|
||||
return w;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace Polygon_mesh_processing {
|
|||
|
||||
/*!
|
||||
\ingroup PMP_meshing_grp
|
||||
@brief refines a region of a triangle mesh
|
||||
@brief refines a region of a triangle mesh.
|
||||
|
||||
@tparam TriangleMesh model of `MutableFaceGraph`
|
||||
@tparam FaceRange range of face descriptors, model of `Range`.
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ namespace Polygon_mesh_processing {
|
|||
*
|
||||
* \cgalParamNBegin{protect_constraints}
|
||||
* \cgalParamDescription{If `true`, the edges set as constrained in `edge_is_constrained_map`
|
||||
* (or by default the boundary edges) are not split nor collapsed during remeshing.}
|
||||
* (or by default the boundary edges) are neither split nor collapsed during remeshing.}
|
||||
* \cgalParamType{Boolean}
|
||||
* \cgalParamDefault{`false`}
|
||||
* \cgalParamExtra{Note that around constrained edges that have their length higher than
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -136,7 +136,7 @@ namespace Polygon_mesh_processing {
|
|||
|
||||
CGAL_precondition(face(border_halfedge, pmesh) == boost::graph_traits<PolygonMesh>::null_face());
|
||||
bool use_cdt =
|
||||
#ifdef CGAL_HOLE_FILLING_DO_NOT_USE_CDT2
|
||||
#ifdef CGAL_HOLE_FILLING_DO_NOT_USE_CDT2
|
||||
false;
|
||||
#else
|
||||
choose_parameter(get_parameter(np, internal_np::use_2d_constrained_delaunay_triangulation), false);
|
||||
|
|
@ -176,22 +176,6 @@ namespace Polygon_mesh_processing {
|
|||
max_squared_distance).first;
|
||||
}
|
||||
|
||||
template<typename PM, typename VertexRange>
|
||||
void test_in_edges(const PM& pmesh, const VertexRange& patch)
|
||||
{
|
||||
for(typename boost::graph_traits<PM>::vertex_descriptor v0 : patch)
|
||||
{
|
||||
typename boost::graph_traits<PM>::in_edge_iterator e, e_end;
|
||||
for (boost::tie(e, e_end) = in_edges(v0, pmesh); e != e_end; e++)
|
||||
{
|
||||
typename boost::graph_traits<PM>::halfedge_descriptor he = halfedge(*e, pmesh);
|
||||
if (is_border(he, pmesh)) { continue; }
|
||||
|
||||
CGAL_assertion(v0 == target(he, pmesh) || v0 == source(he, pmesh));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\ingroup hole_filling_grp
|
||||
@brief triangulates and refines a hole in a polygon mesh.
|
||||
|
|
@ -285,8 +269,6 @@ namespace Polygon_mesh_processing {
|
|||
triangulate_hole(pmesh, border_halfedge, std::back_inserter(patch), np);
|
||||
face_out = std::copy(patch.begin(), patch.end(), face_out);
|
||||
|
||||
test_in_edges(pmesh, vertices(pmesh));
|
||||
|
||||
return refine(pmesh, patch, face_out, vertex_out, np);
|
||||
}
|
||||
|
||||
|
|
@ -401,16 +383,13 @@ namespace Polygon_mesh_processing {
|
|||
VertexOutputIterator vertex_out,
|
||||
const NamedParameters& np = parameters::default_values())
|
||||
{
|
||||
CGAL_precondition(CGAL::is_triangle_mesh(pmesh));
|
||||
|
||||
std::vector<typename boost::graph_traits<PolygonMesh>::vertex_descriptor> patch;
|
||||
|
||||
CGAL_assertion(CGAL::is_triangle_mesh(pmesh));
|
||||
|
||||
face_out = triangulate_and_refine_hole
|
||||
(pmesh, border_halfedge, face_out, std::back_inserter(patch), np).first;
|
||||
|
||||
CGAL_assertion(CGAL::is_triangle_mesh(pmesh));
|
||||
|
||||
test_in_edges(pmesh, patch);
|
||||
CGAL_postcondition(CGAL::is_triangle_mesh(pmesh));
|
||||
|
||||
bool fair_success = fair(pmesh, patch, np);
|
||||
|
||||
|
|
@ -536,9 +515,9 @@ bool use_dt3 =
|
|||
#ifndef CGAL_HOLE_FILLING_DO_NOT_USE_CDT2
|
||||
if (use_cdt)
|
||||
{
|
||||
struct Always_valid{
|
||||
bool operator()(const std::vector<Point>&, int,int,int)const
|
||||
{return true;}
|
||||
struct Always_valid
|
||||
{
|
||||
bool operator()(const std::vector<Point>&, int,int,int) const { return true; }
|
||||
};
|
||||
Always_valid is_valid;
|
||||
|
||||
|
|
@ -549,8 +528,9 @@ bool use_dt3 =
|
|||
const typename Kernel::FT threshold_distance = choose_parameter(
|
||||
get_parameter(np, internal_np::threshold_distance), typename Kernel::FT(-1));
|
||||
typename Kernel::FT max_squared_distance = default_squared_distance;
|
||||
if (threshold_distance >= typename Kernel::FT(0))
|
||||
if(threshold_distance >= typename Kernel::FT(0))
|
||||
max_squared_distance = threshold_distance * threshold_distance;
|
||||
|
||||
CGAL_assertion(max_squared_distance >= typename Kernel::FT(0));
|
||||
if (triangulate_hole_polyline_with_cdt(
|
||||
points,
|
||||
|
|
|
|||
|
|
@ -1529,6 +1529,9 @@ public:
|
|||
|
||||
/// performs a validity check on a single vertex.
|
||||
bool is_valid(Vertex_index v) const {
|
||||
if(!has_valid_index(v))
|
||||
return false;
|
||||
|
||||
Halfedge_index h = vconn_[v].halfedge_;
|
||||
if(h!= null_halfedge() && (!has_valid_index(h) || is_removed(h))) {
|
||||
std::cerr << "Vertex connectivity halfedge error in " << (size_type)v
|
||||
|
|
@ -1540,6 +1543,9 @@ public:
|
|||
|
||||
/// performs a validity check on a single halfedge.
|
||||
bool is_valid(Halfedge_index h) const {
|
||||
if(!has_valid_index(h))
|
||||
return false;
|
||||
|
||||
Face_index f = hconn_[h].face_;
|
||||
Vertex_index v = hconn_[h].vertex_;
|
||||
Halfedge_index hn = hconn_[h].next_halfedge_;
|
||||
|
|
@ -1581,6 +1587,9 @@ public:
|
|||
|
||||
/// performs a validity check on a single edge.
|
||||
bool is_valid(Edge_index e) const {
|
||||
if(!has_valid_index(e))
|
||||
return false;
|
||||
|
||||
Halfedge_index h = halfedge(e);
|
||||
return is_valid(h) && is_valid(opposite(h));
|
||||
}
|
||||
|
|
@ -1588,6 +1597,9 @@ public:
|
|||
|
||||
/// performs a validity check on a single face.
|
||||
bool is_valid(Face_index f) const {
|
||||
if(!has_valid_index(f))
|
||||
return false;
|
||||
|
||||
Halfedge_index h = fconn_[f].halfedge_;
|
||||
if(!has_valid_index(h) || is_removed(h)) {
|
||||
std::cerr << "Face connectivity halfedge error in " << (size_type)f
|
||||
|
|
|
|||
Loading…
Reference in New Issue