mirror of https://github.com/CGAL/cgal
First version of polyhedron orientation test
This commit is contained in:
parent
b6cb2bf505
commit
5e2e2d256d
|
|
@ -0,0 +1,39 @@
|
|||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/orient_polyhedron_3.h>
|
||||
#include <CGAL/Polyhedron_3.h>
|
||||
#include <CGAL/IO/Polyhedron_iostream.h>
|
||||
#include <CGAL/Timer.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
typedef CGAL::Polyhedron_3<K> 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<std::string> files;
|
||||
files.push_back("data/elephant.off");
|
||||
files.push_back("data/camel.off");
|
||||
|
||||
for(std::vector<std::string>::iterator it = files.begin(); it != files.end(); ++it) {
|
||||
test(it->c_str());
|
||||
}
|
||||
std::cerr << "All done." << std::endl;
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
#include <algorithm>
|
||||
#include <CGAL/circulator.h>
|
||||
|
||||
namespace CGAL {
|
||||
namespace internal {
|
||||
|
||||
template<unsigned int axis>
|
||||
struct Axis_compare {
|
||||
template<class Vertex>
|
||||
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 <class Facet, class Kernel>
|
||||
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 <class Kernel, class Vertex>
|
||||
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<Facet, Kernel>(*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<class Polyhedron>
|
||||
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<axis>());
|
||||
|
||||
typedef typename Polyhedron::Traits K;
|
||||
const typename K::Vector_3& normal_v_min = internal::compute_vertex_normal<K, typename Polyhedron::Vertex>(*v_min);
|
||||
|
||||
CGAL_warning(normal_v_min[axis] != 0);
|
||||
return normal_v_min[axis] < 0;
|
||||
}
|
||||
} // namespace CGAL
|
||||
Loading…
Reference in New Issue