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
|
#ifndef CGAL_POLYHEDRAL_MESH_DOMAIN_3_H
|
||||||
#define 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/Robust_intersection_traits_3.h>
|
||||||
#include <CGAL/Mesh_3/Triangle_accessor_primitive.h>
|
#include <CGAL/Mesh_3/Triangle_accessor_primitive.h>
|
||||||
#include <CGAL/Triangle_accessor_3.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
|
Is_in_domain::operator()(const Point_3& p) const
|
||||||
{
|
{
|
||||||
if(r_domain_.bounding_tree_ == 0) return Subdomain();
|
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()
|
internal::Point_inside_vertical_ray_cast<IGT_, AABB_tree_> inside_functor;
|
||||||
|| p.y() < bbox.ymin() || p.y() > bbox.ymax()
|
Bounded_side side = inside_functor(p, *(r_domain_.bounding_tree_));
|
||||||
|| 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();
|
|
||||||
|
|
||||||
|
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
|
#ifndef CGAL_POINT_INSIDE_POLYHEDRON_H
|
||||||
#define 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/internal/Operations_on_polyhedra/AABB_triangle_accessor_3_primitive.h>
|
||||||
|
|
||||||
#include <CGAL/AABB_tree.h>
|
#include <CGAL/AABB_tree.h>
|
||||||
#include <CGAL/AABB_traits.h>
|
#include <CGAL/AABB_traits.h>
|
||||||
#include <CGAL/point_generators_3.h>
|
|
||||||
#include <CGAL/Triangle_accessor_3.h>
|
#include <CGAL/Triangle_accessor_3.h>
|
||||||
|
|
||||||
#include <boost/optional.hpp>
|
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -57,17 +54,14 @@ class Point_inside_polyhedron_3{
|
||||||
// typedefs
|
// typedefs
|
||||||
typedef CGAL::internal::AABB_triangle_accessor_3_primitive<Kernel, TriangleAccessor_3> Primitive;
|
typedef CGAL::internal::AABB_triangle_accessor_3_primitive<Kernel, TriangleAccessor_3> Primitive;
|
||||||
typedef CGAL::AABB_traits<Kernel, Primitive> Traits;
|
typedef CGAL::AABB_traits<Kernel, Primitive> Traits;
|
||||||
typedef typename Traits::Bounding_box Bounding_box;
|
|
||||||
typedef CGAL::AABB_tree<Traits> Tree;
|
typedef CGAL::AABB_tree<Traits> Tree;
|
||||||
typedef typename Kernel::Point_3 Point;
|
typedef typename Kernel::Point_3 Point;
|
||||||
typedef typename Kernel::Ray_3 Ray;
|
|
||||||
//members
|
//members
|
||||||
typename Kernel::Construct_ray_3 ray_functor;
|
typename Kernel::Construct_ray_3 ray_functor;
|
||||||
typename Kernel::Construct_vector_3 vector_functor;
|
typename Kernel::Construct_vector_3 vector_functor;
|
||||||
Tree tree;
|
Tree tree;
|
||||||
|
|
||||||
const static unsigned int seed = 1340818006;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Default constructor. The domain is considered to be empty.
|
* Default constructor. The domain is considered to be empty.
|
||||||
|
|
@ -137,53 +131,8 @@ public:
|
||||||
*/
|
*/
|
||||||
Bounded_side operator()(const Point& point) const
|
Bounded_side operator()(const Point& point) const
|
||||||
{
|
{
|
||||||
const Bounding_box& bbox = tree.bbox();
|
return internal::Point_inside_vertical_ray_cast<Kernel, Tree>()(point, tree, ray_functor, vector_functor);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
} // 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