mirror of https://github.com/CGAL/cgal
Merge branch 'Mesh_3-using_new_inside_polyhedron-local'
Successfully tested in CGAL-4.3-Ic-85 Approved by the release manager Conflicts: Mesh_3/include/CGAL/Polyhedral_mesh_domain_3.h
This commit is contained in:
commit
20446fa777
|
|
@ -27,6 +27,8 @@
|
|||
#ifndef CGAL_POLYHEDRAL_MESH_DOMAIN_3_H
|
||||
#define CGAL_POLYHEDRAL_MESH_DOMAIN_3_H
|
||||
|
||||
#include <CGAL/internal/Operations_on_polyhedra/Point_inside_vertical_ray_cast.h>
|
||||
|
||||
#include <CGAL/Mesh_3/Robust_intersection_traits_3.h>
|
||||
#include <CGAL/Mesh_3/Triangle_accessor_primitive.h>
|
||||
#include <CGAL/Triangle_accessor_3.h>
|
||||
|
|
@ -718,47 +720,12 @@ Polyhedral_mesh_domain_3<P_,IGT_,TA,Tag,E_tag_>::
|
|||
Is_in_domain::operator()(const Point_3& p) const
|
||||
{
|
||||
if(r_domain_.bounding_tree_ == 0) return Subdomain();
|
||||
const Bounding_box& bbox = r_domain_.bounding_tree_->bbox();
|
||||
|
||||
if( p.x() < bbox.xmin() || p.x() > bbox.xmax()
|
||||
|| p.y() < bbox.ymin() || p.y() > bbox.ymax()
|
||||
|| p.z() < bbox.zmin() || p.z() > bbox.zmax() )
|
||||
{
|
||||
return Subdomain();
|
||||
}
|
||||
|
||||
#ifdef CGAL_POLYHEDRAL_MESH_DOMAIN_USE_GRID
|
||||
Vector_3 v = p - r_domain_.grid_base;
|
||||
int i = boost::math::round(v.x() / r_domain_.grid_dx);
|
||||
int j = boost::math::round(v.y() / r_domain_.grid_dy);
|
||||
int k = boost::math::round(v.z() / r_domain_.grid_dz);
|
||||
if(i>19)i=19;
|
||||
if(j>19)j=19;
|
||||
if(k>19)k=19;
|
||||
int index = i*400 + j*20 + k;
|
||||
|
||||
const std::pair<Point_3,bool>& close_point = r_domain_.grid[index];
|
||||
typename IGT::Construct_segment_3 segment = IGT().construct_segment_3_object();
|
||||
const Segment_3 query = segment(p, close_point.first);
|
||||
typename AABB_tree::size_type M = (close_point.second)? 0 : 1;
|
||||
|
||||
#else
|
||||
|
||||
typename IGT::Construct_ray_3 ray = IGT().construct_ray_3_object();
|
||||
typename IGT::Construct_vector_3 vector = IGT().construct_vector_3_object();
|
||||
|
||||
Random_points_on_sphere_3<Point_3> random_point(1.);
|
||||
|
||||
const Ray_3 query = ray(p, vector(CGAL::ORIGIN,*random_point));
|
||||
typename AABB_tree::size_type M = 1;
|
||||
|
||||
#endif
|
||||
|
||||
if ( (r_domain_.bounding_tree_->number_of_intersected_primitives(query)&1) == M )
|
||||
return Subdomain(Subdomain_index(1));
|
||||
else
|
||||
return Subdomain();
|
||||
internal::Point_inside_vertical_ray_cast<IGT_, AABB_tree_> inside_functor;
|
||||
Bounded_side side = inside_functor(p, *(r_domain_.bounding_tree_));
|
||||
|
||||
if(side == CGAL::ON_UNBOUNDED_SIDE) { return Subdomain(); }
|
||||
else { return Subdomain(Subdomain_index(1)); } // case ON_BOUNDARY && ON_BOUNDED_SIDE
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -22,16 +22,13 @@
|
|||
#ifndef CGAL_POINT_INSIDE_POLYHEDRON_H
|
||||
#define CGAL_POINT_INSIDE_POLYHEDRON_H
|
||||
|
||||
#include <CGAL/internal/Operations_on_polyhedra/Ray_3_Triangle_3_traversal_traits.h>
|
||||
#include <CGAL/internal/Operations_on_polyhedra/Point_inside_vertical_ray_cast.h>
|
||||
#include <CGAL/internal/Operations_on_polyhedra/AABB_triangle_accessor_3_primitive.h>
|
||||
|
||||
#include <CGAL/AABB_tree.h>
|
||||
#include <CGAL/AABB_traits.h>
|
||||
#include <CGAL/point_generators_3.h>
|
||||
#include <CGAL/Triangle_accessor_3.h>
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
/**
|
||||
|
|
@ -57,17 +54,14 @@ class Point_inside_polyhedron_3{
|
|||
// typedefs
|
||||
typedef CGAL::internal::AABB_triangle_accessor_3_primitive<Kernel, TriangleAccessor_3> Primitive;
|
||||
typedef CGAL::AABB_traits<Kernel, Primitive> Traits;
|
||||
typedef typename Traits::Bounding_box Bounding_box;
|
||||
typedef CGAL::AABB_tree<Traits> Tree;
|
||||
typedef typename Kernel::Point_3 Point;
|
||||
typedef typename Kernel::Ray_3 Ray;
|
||||
|
||||
//members
|
||||
typename Kernel::Construct_ray_3 ray_functor;
|
||||
typename Kernel::Construct_vector_3 vector_functor;
|
||||
Tree tree;
|
||||
|
||||
const static unsigned int seed = 1340818006;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Default constructor. The domain is considered to be empty.
|
||||
|
|
@ -137,53 +131,8 @@ public:
|
|||
*/
|
||||
Bounded_side operator()(const Point& point) const
|
||||
{
|
||||
const Bounding_box& bbox = tree.bbox();
|
||||
|
||||
if( point.x() < bbox.xmin() || point.x() > bbox.xmax()
|
||||
|| point.y() < bbox.ymin() || point.y() > bbox.ymax()
|
||||
|| point.z() < bbox.zmin() || point.z() > bbox.zmax() )
|
||||
{
|
||||
return ON_UNBOUNDED_SIDE;
|
||||
}
|
||||
|
||||
//the direction of the vertical ray depends on the position of the point in the bbox
|
||||
//in order to limit the expected number of nodes visited.
|
||||
Ray query = ray_functor(point, vector_functor(0,0,(2*point.z() < tree.bbox().zmax()+tree.bbox().zmin()?-1:1)));
|
||||
boost::optional<Bounded_side> res = is_inside_ray_tree_traversal<Ray,true>(query);
|
||||
|
||||
if(!res) {
|
||||
CGAL::Random rg(seed); // seed some value for make it easy to debug
|
||||
Random_points_on_sphere_3<Point> random_point(1.,rg);
|
||||
|
||||
do { //retry with a random ray
|
||||
query = ray_functor(point, vector_functor(CGAL::ORIGIN,*random_point++));
|
||||
res = is_inside_ray_tree_traversal<Ray,false>(query);
|
||||
} while (!res);
|
||||
}
|
||||
return *res;
|
||||
return internal::Point_inside_vertical_ray_cast<Kernel, Tree>()(point, tree, ray_functor, vector_functor);
|
||||
}
|
||||
|
||||
private:
|
||||
template <class Query,bool ray_is_vertical>
|
||||
boost::optional<Bounded_side>
|
||||
is_inside_ray_tree_traversal(const Query& query) const
|
||||
{
|
||||
std::pair<boost::logic::tribool,std::size_t> status( boost::logic::tribool(boost::logic::indeterminate), 0);
|
||||
|
||||
internal::Ray_3_Triangle_3_traversal_traits<Traits,Kernel,Boolean_tag<ray_is_vertical> > traversal_traits(status);
|
||||
tree.traversal(query, traversal_traits);
|
||||
|
||||
if ( !boost::logic::indeterminate(status.first) )
|
||||
{
|
||||
if (status.first) {
|
||||
return (status.second&1) == 1 ? ON_BOUNDED_SIDE : ON_UNBOUNDED_SIDE;
|
||||
}
|
||||
//otherwise the point is on the facet
|
||||
return ON_BOUNDARY;
|
||||
}
|
||||
return boost::optional<Bounded_side>(); // indeterminate
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namespace CGAL
|
||||
|
|
|
|||
|
|
@ -0,0 +1,80 @@
|
|||
#ifndef CGAL_POINT_INSIDE_POLYHEDRON_POINT_INSIDE_VERTICAL_RAY_CAST_H
|
||||
#define CGAL_POINT_INSIDE_POLYHEDRON_POINT_INSIDE_VERTICAL_RAY_CAST_H
|
||||
|
||||
#include <CGAL/internal/Operations_on_polyhedra/Ray_3_Triangle_3_traversal_traits.h>
|
||||
#include <CGAL/point_generators_3.h>
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
namespace CGAL {
|
||||
namespace internal {
|
||||
|
||||
// internal class for point inside test, using existing AABB tree
|
||||
template<class Kernel, class AABBTree>
|
||||
class Point_inside_vertical_ray_cast
|
||||
{
|
||||
typedef typename Kernel::Point_3 Point;
|
||||
typedef typename Kernel::Ray_3 Ray;
|
||||
typedef typename AABBTree::AABB_traits Traits;
|
||||
|
||||
const static unsigned int seed = 1340818006;
|
||||
|
||||
public:
|
||||
Bounded_side operator()(
|
||||
const Point& point,
|
||||
const AABBTree& tree,
|
||||
typename Kernel::Construct_ray_3 ray_functor = Kernel().construct_ray_3_object(),
|
||||
typename Kernel::Construct_vector_3 vector_functor = Kernel().construct_vector_3_object() ) const
|
||||
{
|
||||
const typename Traits::Bounding_box& bbox = tree.bbox();
|
||||
|
||||
if( point.x() < bbox.xmin() || point.x() > bbox.xmax()
|
||||
|| point.y() < bbox.ymin() || point.y() > bbox.ymax()
|
||||
|| point.z() < bbox.zmin() || point.z() > bbox.zmax() )
|
||||
{
|
||||
return ON_UNBOUNDED_SIDE;
|
||||
}
|
||||
|
||||
//the direction of the vertical ray depends on the position of the point in the bbox
|
||||
//in order to limit the expected number of nodes visited.
|
||||
Ray query = ray_functor(point, vector_functor(0,0,(2*point.z() < tree.bbox().zmax()+tree.bbox().zmin()?-1:1)));
|
||||
boost::optional<Bounded_side> res = is_inside_ray_tree_traversal<true>(query, tree);
|
||||
|
||||
if(!res) {
|
||||
CGAL::Random rg(seed); // seed some value for make it easy to debug
|
||||
Random_points_on_sphere_3<Point> random_point(1.,rg);
|
||||
|
||||
do { //retry with a random ray
|
||||
query = ray_functor(point, vector_functor(CGAL::ORIGIN,*random_point++));
|
||||
res = is_inside_ray_tree_traversal<false>(query, tree);
|
||||
} while (!res);
|
||||
}
|
||||
return *res;
|
||||
}
|
||||
|
||||
private:
|
||||
template<bool ray_is_vertical>
|
||||
boost::optional<Bounded_side>
|
||||
is_inside_ray_tree_traversal(const Ray& ray, const AABBTree& tree) const
|
||||
{
|
||||
std::pair<boost::logic::tribool,std::size_t> status( boost::logic::tribool(boost::logic::indeterminate), 0);
|
||||
|
||||
Ray_3_Triangle_3_traversal_traits<Traits, Kernel, Boolean_tag<ray_is_vertical> > traversal_traits(status);
|
||||
tree.traversal(ray, traversal_traits);
|
||||
|
||||
if ( !boost::logic::indeterminate(status.first) )
|
||||
{
|
||||
if (status.first) {
|
||||
return (status.second&1) == 1 ? ON_BOUNDED_SIDE : ON_UNBOUNDED_SIDE;
|
||||
}
|
||||
//otherwise the point is on the facet
|
||||
return ON_BOUNDARY;
|
||||
}
|
||||
return boost::optional<Bounded_side>(); // indeterminate
|
||||
}
|
||||
};
|
||||
|
||||
}// namespace internal
|
||||
}// namespace CGAL
|
||||
|
||||
#endif
|
||||
Loading…
Reference in New Issue