From 5e2e2d256d88a32fb571bb1c8666d0ff2f69ad0a Mon Sep 17 00:00:00 2001 From: iyaz Date: Wed, 10 Jul 2013 16:04:27 +0300 Subject: [PATCH] First version of polyhedron orientation test --- .../orient_polyhedron_3_test.cpp | 39 +++++++++ .../include/CGAL/orient_polyhedron_3.h | 87 +++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 Operations_on_polyhedra/examples/Operations_on_polyhedra/orient_polyhedron_3_test.cpp create mode 100644 Operations_on_polyhedra/include/CGAL/orient_polyhedron_3.h diff --git a/Operations_on_polyhedra/examples/Operations_on_polyhedra/orient_polyhedron_3_test.cpp b/Operations_on_polyhedra/examples/Operations_on_polyhedra/orient_polyhedron_3_test.cpp new file mode 100644 index 00000000000..08b8603dc20 --- /dev/null +++ b/Operations_on_polyhedra/examples/Operations_on_polyhedra/orient_polyhedron_3_test.cpp @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include + +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Polyhedron_3 Polyhedron; + + +void test(const char* file_name) { + + std::ifstream input(file_name); + Polyhedron oriented_poly; // file should contain oriented poly + if ( !input || !(input >> oriented_poly) || oriented_poly.empty() ){ + std::cerr << "Error: can not read file: " << file_name; + assert(false); + } + + assert(CGAL::is_oriented(oriented_poly)); + oriented_poly.inside_out(); + assert(!CGAL::is_oriented(oriented_poly)); + + std::cerr << file_name << " passed the test." << std::endl; +} + +int main() { + std::vector files; + files.push_back("data/elephant.off"); + files.push_back("data/camel.off"); + + for(std::vector::iterator it = files.begin(); it != files.end(); ++it) { + test(it->c_str()); + } + std::cerr << "All done." << std::endl; +} \ No newline at end of file diff --git a/Operations_on_polyhedra/include/CGAL/orient_polyhedron_3.h b/Operations_on_polyhedra/include/CGAL/orient_polyhedron_3.h new file mode 100644 index 00000000000..31d96ed34b3 --- /dev/null +++ b/Operations_on_polyhedra/include/CGAL/orient_polyhedron_3.h @@ -0,0 +1,87 @@ +#include +#include + +namespace CGAL { +namespace internal { + +template +struct Axis_compare { + template + bool operator()(const Vertex& v0, const Vertex& v1) const + { return v0.point()[axis] < v1.point()[axis]; } +}; + +// Taken from compute_normal.h inside Polyhedron demo // +template +typename Kernel::Vector_3 compute_facet_normal(const Facet& f) +{ + typedef typename Kernel::Point_3 Point; + typedef typename Kernel::Vector_3 Vector; + typedef typename Facet::Halfedge_around_facet_const_circulator HF_circulator; + Vector normal = CGAL::NULL_VECTOR; + HF_circulator he = f.facet_begin(); + HF_circulator end = he; + CGAL_For_all(he,end) + { + const Point& prev = he->prev()->vertex()->point(); + const Point& curr = he->vertex()->point(); + const Point& next = he->next()->vertex()->point(); + Vector n = CGAL::cross_product(next-curr,prev-curr); + normal = normal + n; + } + return normal / std::sqrt(normal * normal); +} + +template +typename Kernel::Vector_3 compute_vertex_normal(const Vertex& v) +{ + typedef typename Kernel::Vector_3 Vector; + typedef typename Vertex::Halfedge_around_vertex_const_circulator HV_circulator; + typedef typename Vertex::Facet Facet; + Vector normal = CGAL::NULL_VECTOR; + HV_circulator he = v.vertex_begin(); + HV_circulator end = he; + CGAL_For_all(he,end) + { + if(!he->is_border()) + { + Vector n = compute_facet_normal(*he->facet()); + normal = normal + (n / std::sqrt(n*n)); + } + } + return normal; // No need to normalize here +} + +} // namespace internal + +/** + * Test whether a polyhedron has correct orientation + * @pre @a polyhedron.is_closed() + * + * @tparam Polyhedron a %CGAL polyhedron + * + * @param polyhedron a closed polyhedron to be tested + * + * @return true if orientation is OK + * @code + * // use inside out to fix orientation + * if(!is_oriented(polyhedron)) { + * polyhedron.inside_out(); + * } + * @endcode + */ +template +bool is_oriented(const Polyhedron& polyhedron) { + CGAL_assertion(polyhedron.is_closed()); + const unsigned int axis = 0; + + typename Polyhedron::Vertex_const_iterator v_min + = std::min_element(polyhedron.vertices_begin(), polyhedron.vertices_end(), internal::Axis_compare()); + + typedef typename Polyhedron::Traits K; + const typename K::Vector_3& normal_v_min = internal::compute_vertex_normal(*v_min); + + CGAL_warning(normal_v_min[axis] != 0); + return normal_v_min[axis] < 0; +} +} // namespace CGAL \ No newline at end of file