mirror of https://github.com/CGAL/cgal
Merge pull request #8201 from afabri/ToS-IO-GF
Triangulation on Sphere: Fix I/O # Conflicts: # Triangulation_on_sphere_2/include/CGAL/Delaunay_triangulation_on_sphere_2.h # Triangulation_on_sphere_2/include/CGAL/Triangulation_on_sphere_2.h # Triangulation_on_sphere_2/test/Triangulation_on_sphere_2/CMakeLists.txt
This commit is contained in:
commit
561e7f16d6
|
|
@ -32,4 +32,16 @@ public:
|
||||||
|
|
||||||
/// provides write access to a Boolean used to indicate if the face is a ghost face.
|
/// provides write access to a Boolean used to indicate if the face is a ghost face.
|
||||||
void set_ghost(const bool b);
|
void set_ghost(const bool b);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
inputs the non-combinatorial information given by the face:
|
||||||
|
its ghost status and other possible information.
|
||||||
|
*/
|
||||||
|
std::istream& operator>>(std::istream& is, TriangulationOnSphereFaceBase_2& v);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
outputs the non combinatorial operation given by the face:
|
||||||
|
its ghost status and other possible information.
|
||||||
|
*/
|
||||||
|
std::ostream& operator<<(std::ostream& os, const TriangulationOnSphereFaceBase_2& v);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -327,9 +327,8 @@ public:
|
||||||
Arc_on_sphere_2 dual_on_sphere(const All_edges_iterator ei) const { return dual_on_sphere(*ei); }
|
Arc_on_sphere_2 dual_on_sphere(const All_edges_iterator ei) const { return dual_on_sphere(*ei); }
|
||||||
|
|
||||||
// Validity
|
// Validity
|
||||||
bool is_plane() const;
|
|
||||||
bool is_valid(bool verbose = false, int level = 0) const;
|
|
||||||
bool is_valid_face(Face_handle fh, bool verbose = false, int level = 0) const;
|
bool is_valid_face(Face_handle fh, bool verbose = false, int level = 0) const;
|
||||||
|
bool is_valid(bool verbose = false, int level = 0) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------ PREDICATES / CONSTRUCTIONS --------------------------------//
|
// ------------------------ PREDICATES / CONSTRUCTIONS --------------------------------//
|
||||||
|
|
@ -1090,39 +1089,6 @@ dual_on_sphere(const Edge& e) const
|
||||||
|
|
||||||
//-------------------------------------------CHECK------------------------------------------------//
|
//-------------------------------------------CHECK------------------------------------------------//
|
||||||
|
|
||||||
// checks whether a given triangulation is plane (all points are coplanar)
|
|
||||||
template <typename Gt, typename Tds>
|
|
||||||
bool
|
|
||||||
Delaunay_triangulation_on_sphere_2<Gt, Tds>::
|
|
||||||
is_plane() const
|
|
||||||
{
|
|
||||||
if(number_of_vertices() <= 3)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
bool plane = true;
|
|
||||||
|
|
||||||
Vertices_iterator it1 = vertices_begin(), it2(it1), it3(it1), it4(it1);
|
|
||||||
std::advance(it2, 1);
|
|
||||||
std::advance(it3, 2);
|
|
||||||
std::advance(it4, 3);
|
|
||||||
|
|
||||||
while(it4 != vertices_end())
|
|
||||||
{
|
|
||||||
Orientation s = side_of_oriented_circle(point(it1), point(it2), point(it3), point(it4));
|
|
||||||
plane = plane && s == ON_ORIENTED_BOUNDARY;
|
|
||||||
|
|
||||||
if(!plane)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
++it1;
|
|
||||||
++it2;
|
|
||||||
++it3;
|
|
||||||
++it4;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Gt, typename Tds>
|
template <typename Gt, typename Tds>
|
||||||
bool
|
bool
|
||||||
Delaunay_triangulation_on_sphere_2<Gt, Tds>::
|
Delaunay_triangulation_on_sphere_2<Gt, Tds>::
|
||||||
|
|
@ -1154,47 +1120,19 @@ bool
|
||||||
Delaunay_triangulation_on_sphere_2<Gt, Tds>::
|
Delaunay_triangulation_on_sphere_2<Gt, Tds>::
|
||||||
is_valid(bool verbose, int level) const
|
is_valid(bool verbose, int level) const
|
||||||
{
|
{
|
||||||
bool result = true;
|
// in any dimension
|
||||||
|
|
||||||
if(!tds().is_valid(verbose, level))
|
|
||||||
{
|
|
||||||
if(verbose)
|
if(verbose)
|
||||||
std::cerr << "invalid data structure" << std::endl;
|
{
|
||||||
|
std::cerr << " number of vertices " << number_of_vertices() << "\t" << std::endl;
|
||||||
CGAL_assertion(false);
|
std::cerr << " number of faces " << number_of_faces() << "\t" << std::endl;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool result = Base::is_valid(verbose, level);
|
||||||
|
CGAL_assertion(result);
|
||||||
|
|
||||||
for(All_faces_iterator fit=all_faces_begin(); fit!=all_faces_end(); ++fit)
|
for(All_faces_iterator fit=all_faces_begin(); fit!=all_faces_end(); ++fit)
|
||||||
result = result && is_valid_face(fit, verbose, level);
|
result = result && is_valid_face(fit, verbose, level);
|
||||||
|
|
||||||
for(Vertices_iterator vit=vertices_begin(); vit!=vertices_end(); ++vit)
|
|
||||||
result = result && Base::is_valid_vertex(vit, verbose, level);
|
|
||||||
|
|
||||||
switch(dimension())
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
CGAL_assertion(this->is_plane());
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
for(All_faces_iterator it=all_faces_begin(); it!=all_faces_end(); ++it)
|
|
||||||
{
|
|
||||||
Orientation s = orientation_on_sphere(point(it, 0), point(it, 1), point(it, 2));
|
|
||||||
result = result && (s != NEGATIVE || it->is_ghost());
|
|
||||||
CGAL_assertion(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
result = result && (number_of_faces() == 2 * number_of_vertices() - 4);
|
|
||||||
CGAL_assertion(result);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// in any dimension
|
|
||||||
if(verbose)
|
|
||||||
std::cerr << " number of vertices " << number_of_vertices() << "\t" << std::endl;
|
|
||||||
|
|
||||||
CGAL_assertion(result);
|
CGAL_assertion(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ private:
|
||||||
mutable Base_point proj_pt;
|
mutable Base_point proj_pt;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Point_with_scale() : Base_point() { } // vertex base wants a default constructor
|
Point_with_scale() : Base_point(), cached(false) { } // vertex base wants a default constructor
|
||||||
Point_with_scale(const Base_point& p) : Base_point(p), cached(false) { }
|
Point_with_scale(const Base_point& p) : Base_point(p), cached(false) { }
|
||||||
|
|
||||||
const Base_point& get_projection(const Base_point& center,
|
const Base_point& get_projection(const Base_point& center,
|
||||||
|
|
|
||||||
|
|
@ -482,7 +482,7 @@ public:
|
||||||
|
|
||||||
//-----------------------DEBUG--------------------------------------------------------------------
|
//-----------------------DEBUG--------------------------------------------------------------------
|
||||||
void check_neighboring_faces() const;
|
void check_neighboring_faces() const;
|
||||||
|
bool is_plane() const;
|
||||||
bool is_valid_vertex(Vertex_handle fh, bool verbose = false, int level = 0) const;
|
bool is_valid_vertex(Vertex_handle fh, bool verbose = false, int level = 0) const;
|
||||||
bool is_valid(bool verbose = false, int level = 0) const;
|
bool is_valid(bool verbose = false, int level = 0) const;
|
||||||
|
|
||||||
|
|
@ -1239,6 +1239,39 @@ check_neighboring_faces() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// checks whether a given triangulation is plane (all points are coplanar)
|
||||||
|
template <typename Gt, typename Tds>
|
||||||
|
bool
|
||||||
|
Triangulation_on_sphere_2<Gt, Tds>::
|
||||||
|
is_plane() const
|
||||||
|
{
|
||||||
|
if(number_of_vertices() <= 3)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
bool is_plane = true;
|
||||||
|
|
||||||
|
Vertices_iterator it1 = vertices_begin(), it2(it1), it3(it1), it4(it1);
|
||||||
|
std::advance(it2, 1);
|
||||||
|
std::advance(it3, 2);
|
||||||
|
std::advance(it4, 3);
|
||||||
|
|
||||||
|
while(it4 != vertices_end())
|
||||||
|
{
|
||||||
|
Orientation s = orientation(point(it1), point(it2), point(it3), point(it4));
|
||||||
|
is_plane = is_plane && s == COPLANAR;
|
||||||
|
|
||||||
|
if(!is_plane)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
++it1;
|
||||||
|
++it2;
|
||||||
|
++it3;
|
||||||
|
++it4;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Gt, typename Tds>
|
template <typename Gt, typename Tds>
|
||||||
bool
|
bool
|
||||||
Triangulation_on_sphere_2<Gt, Tds>::
|
Triangulation_on_sphere_2<Gt, Tds>::
|
||||||
|
|
@ -1274,27 +1307,21 @@ is_valid(bool verbose,
|
||||||
if(dimension() <= 0 || (dimension() == 1 && number_of_vertices() == 2))
|
if(dimension() <= 0 || (dimension() == 1 && number_of_vertices() == 2))
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
for(Vertices_iterator vit=vertices_begin(); vit!=vertices_end(); ++vit)
|
||||||
|
result = result && is_valid_vertex(vit, verbose, level);
|
||||||
|
|
||||||
if(dimension() == 1)
|
if(dimension() == 1)
|
||||||
{
|
{
|
||||||
Vertices_iterator it1 = vertices_begin(), it2(it1), it3(it1);
|
result = result && this->is_plane();
|
||||||
std::advance(it2, 1);
|
|
||||||
std::advance(it3, 2);
|
|
||||||
while(it3 != vertices_end())
|
|
||||||
{
|
|
||||||
const Orientation s = orientation(point(it1), point(it2), point(it3));
|
|
||||||
result = result && (s == COLLINEAR);
|
|
||||||
CGAL_assertion(result);
|
CGAL_assertion(result);
|
||||||
++it1; ++it2; ++it3;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else // dimension() == 2
|
else // dimension() == 2
|
||||||
{
|
{
|
||||||
for(All_faces_iterator it=all_faces_begin(); it!=all_faces_end(); ++it)
|
for(All_faces_iterator it=all_faces_begin(); it!=all_faces_end(); ++it)
|
||||||
{
|
{
|
||||||
const Orientation s = orientation_on_sphere(point(it, 0), point(it, 1), point(it, 2));
|
const Orientation s = orientation_on_sphere(point(it, 0), point(it, 1), point(it, 2));
|
||||||
CGAL_assertion(s == LEFT_TURN || is_ghost(it));
|
|
||||||
|
|
||||||
result = result && (s == LEFT_TURN || is_ghost(it));
|
result = result && (s == LEFT_TURN || is_ghost(it));
|
||||||
|
CGAL_assertion(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check number of faces. This cannot be done by the TDS,
|
// check number of faces. This cannot be done by the TDS,
|
||||||
|
|
@ -1314,6 +1341,7 @@ void
|
||||||
Triangulation_on_sphere_2<Gt, Tds>::
|
Triangulation_on_sphere_2<Gt, Tds>::
|
||||||
file_output(std::ostream& os) const
|
file_output(std::ostream& os) const
|
||||||
{
|
{
|
||||||
|
os << _gt.center() << " " << _gt.radius() << "\n";
|
||||||
_tds.file_output(os, Vertex_handle(), true);
|
_tds.file_output(os, Vertex_handle(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1323,7 +1351,15 @@ Triangulation_on_sphere_2<Gt, Tds>::
|
||||||
file_input(std::istream& is)
|
file_input(std::istream& is)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
Vertex_handle v = _tds.file_input(is, true);
|
|
||||||
|
Point_3 center;
|
||||||
|
FT radius;
|
||||||
|
is >> center >> radius;
|
||||||
|
_gt.set_center(center);
|
||||||
|
_gt.set_radius(radius);
|
||||||
|
|
||||||
|
Vertex_handle v = _tds.file_input(is, false);
|
||||||
|
CGAL_assertion(is_valid());
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1340,7 +1376,6 @@ std::istream&
|
||||||
operator>>(std::istream& is, Triangulation_on_sphere_2<Gt, Tds>& tr)
|
operator>>(std::istream& is, Triangulation_on_sphere_2<Gt, Tds>& tr)
|
||||||
{
|
{
|
||||||
tr.file_input(is);
|
tr.file_input(is);
|
||||||
CGAL_assertion(tr.is_valid());
|
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,27 @@ protected:
|
||||||
bool _ghost_flag;
|
bool _ghost_flag;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template < class Gt, class Fb >
|
||||||
|
std::ostream&
|
||||||
|
operator<<(std::ostream &os, const Triangulation_on_sphere_face_base_2<Gt, Fb> &f)
|
||||||
|
{
|
||||||
|
// non combinatorial information. Default = point
|
||||||
|
os << static_cast<const Fb&>(f);
|
||||||
|
os << (f.is_ghost() ? " 1" : " 0");
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
template < class Gt, class Fb >
|
||||||
|
std::istream&
|
||||||
|
operator>>(std::istream &is, Triangulation_on_sphere_face_base_2<Gt, Fb> &f)
|
||||||
|
{
|
||||||
|
int g = -1;
|
||||||
|
is >> static_cast<Fb&>(f);
|
||||||
|
is >> g;
|
||||||
|
f.set_ghost(g == 1);
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace CGAL
|
} // namespace CGAL
|
||||||
|
|
||||||
#endif //CGAL_TRIANGULATION_ON_SPHERE_FACE_BASE_2_H
|
#endif //CGAL_TRIANGULATION_ON_SPHERE_FACE_BASE_2_H
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ create_single_source_cgal_program( "test_dtos_degenerate_cases.cpp" )
|
||||||
create_single_source_cgal_program( "test_dtos_illegal_points.cpp" )
|
create_single_source_cgal_program( "test_dtos_illegal_points.cpp" )
|
||||||
create_single_source_cgal_program( "test_dtos_projection_traits.cpp" )
|
create_single_source_cgal_program( "test_dtos_projection_traits.cpp" )
|
||||||
create_single_source_cgal_program( "test_dtos_traits.cpp" )
|
create_single_source_cgal_program( "test_dtos_traits.cpp" )
|
||||||
|
create_single_source_cgal_program( "issue_8200.cpp" )
|
||||||
|
|
||||||
find_package(Eigen3 3.1.0 QUIET) #(requires 3.1.0 or greater)
|
find_package(Eigen3 3.1.0 QUIET) #(requires 3.1.0 or greater)
|
||||||
include(CGAL_Eigen3_support)
|
include(CGAL_Eigen3_support)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||||
|
|
||||||
|
#include <CGAL/Delaunay_triangulation_on_sphere_2.h>
|
||||||
|
#include <CGAL/Projection_on_sphere_traits_3.h>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||||
|
|
||||||
|
typedef CGAL::Projection_on_sphere_traits_3<K> Traits;
|
||||||
|
typedef CGAL::Delaunay_triangulation_on_sphere_2<Traits> DToS2;
|
||||||
|
|
||||||
|
typedef Traits::Point_3 Point_3;
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
std::vector<Point_3> points;
|
||||||
|
points.emplace_back( 3, 1, 1);
|
||||||
|
points.emplace_back(-8, 1, 1);
|
||||||
|
points.emplace_back( 1, 2, 1);
|
||||||
|
points.emplace_back( 1, -2, 1);
|
||||||
|
points.emplace_back( 1, 1, 10);
|
||||||
|
|
||||||
|
Traits traits(Point_3(4,1,1)); // radius is 1 by default
|
||||||
|
DToS2 dtos(traits);
|
||||||
|
|
||||||
|
Traits::Construct_point_on_sphere_2 cst = traits.construct_point_on_sphere_2_object();
|
||||||
|
|
||||||
|
for(const auto& pt : points)
|
||||||
|
{
|
||||||
|
std::cout << "----- Inserting (" << pt
|
||||||
|
<< ") at squared distance " << CGAL::squared_distance(pt, traits.center())
|
||||||
|
<< " from the center of the sphere" << std::endl;
|
||||||
|
dtos.insert(cst(pt));
|
||||||
|
|
||||||
|
std::cout << "The triangulation now has dimension: " << dtos.dimension() << " and\n";
|
||||||
|
std::cout << dtos.number_of_vertices() << " vertices" << std::endl;
|
||||||
|
std::cout << dtos.number_of_edges() << " edges" << std::endl;
|
||||||
|
std::cout << dtos.number_of_solid_faces() << " solid faces" << std::endl;
|
||||||
|
std::cout << dtos.number_of_ghost_faces() << " ghost faces" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(dtos.is_valid());
|
||||||
|
std::ofstream out("dtos.txt");
|
||||||
|
out.precision(17);
|
||||||
|
out << dtos << std::endl;
|
||||||
|
out.close();
|
||||||
|
|
||||||
|
CGAL::IO::write_OFF("dtos.off", dtos, CGAL::parameters::stream_precision(17));
|
||||||
|
|
||||||
|
DToS2 dtos2;
|
||||||
|
std::ifstream in("dtos.txt");
|
||||||
|
in >> dtos2;
|
||||||
|
in.close();
|
||||||
|
assert(dtos2.is_valid());
|
||||||
|
|
||||||
|
std::cout << "DTOS2 center: " << dtos2.geom_traits().center() << " radius: " << dtos2.geom_traits().radius() << std::endl;
|
||||||
|
std::cout << "DTOS2 has dimension: " << dtos2.dimension() << " and\n";
|
||||||
|
std::cout << dtos2.number_of_vertices() << " vertices" << std::endl;
|
||||||
|
std::cout << dtos2.number_of_edges() << " edges" << std::endl;
|
||||||
|
std::cout << dtos2.number_of_solid_faces() << " solid faces" << std::endl;
|
||||||
|
std::cout << dtos2.number_of_ghost_faces() << " ghost faces" << std::endl;
|
||||||
|
|
||||||
|
CGAL::IO::write_OFF("dtos2.off", dtos2, CGAL::parameters::stream_precision(17));
|
||||||
|
|
||||||
|
assert(dtos.number_of_vertices() == dtos2.number_of_vertices());
|
||||||
|
assert(dtos.number_of_edges() == dtos2.number_of_edges());
|
||||||
|
assert(dtos.number_of_solid_faces() == dtos2.number_of_solid_faces());
|
||||||
|
assert(dtos.number_of_ghost_faces() == dtos2.number_of_ghost_faces());
|
||||||
|
|
||||||
|
std::cout << "Done." << std::endl;
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue