dust3d/thirdparty/cgal/CGAL-5.1/include/CGAL/AABB_polyhedral_oracle.h

196 lines
5.7 KiB
C++

// Copyright (c) 2008 INRIA Sophia-Antipolis (France).
// Copyright (c) 2009 GeometryFactory (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL: https://github.com/CGAL/cgal/blob/v5.1/Surface_mesher/include/CGAL/AABB_polyhedral_oracle.h $
// $Id: AABB_polyhedral_oracle.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Pierre Alliez, Laurent Rineau, Stephane Tayeb
#ifndef CGAL_AABB_POLYHEDRAL_ORACLE_H
#define CGAL_AABB_POLYHEDRAL_ORACLE_H
#include <CGAL/license/Surface_mesher.h>
#include <utility>
#include <CGAL/iterator.h>
#include <CGAL/point_generators_3.h>
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_traits.h>
#include <CGAL/AABB_face_graph_triangle_primitive.h>
#include <boost/shared_ptr.hpp>
namespace CGAL {
template <class Polyhedron, class Kernel, class Dummy_kernel>
class AABB_polyhedral_oracle : public Polyhedron
{
public:
typedef typename Kernel::FT FT;
typedef typename Kernel::Ray_3 Ray_3;
typedef typename Kernel::Line_3 Line_3;
typedef typename Kernel::Point_3 Point_3;
typedef typename Kernel::Segment_3 Segment_3;
typedef AABB_polyhedral_oracle<Polyhedron,Kernel,Dummy_kernel> Self;
typedef Self Surface_mesher_traits_3;
typedef Point_3 Intersection_point;
typedef Self Surface_3;
// AABB tree
typedef AABB_face_graph_triangle_primitive<Polyhedron> AABB_primitive;
typedef class AABB_traits<Kernel,AABB_primitive> AABB_traits;
typedef AABB_tree<AABB_traits> Tree;
typedef typename AABB_traits::Bounding_box Bounding_box;
typedef boost::shared_ptr<Tree> Tree_shared_ptr;
Tree_shared_ptr m_pTree;
public:
Tree* tree() const { return m_pTree.get(); }
public:
// Surface constructor
AABB_polyhedral_oracle(const Polyhedron& poly)
{
m_pTree = Tree_shared_ptr(new Tree(faces(poly).first,
faces(poly).second,
poly ));
}
AABB_polyhedral_oracle(const AABB_polyhedral_oracle& oracle)
{
m_pTree = oracle.m_pTree;
}
class Intersect_3;
friend class Intersect_3;
class Intersect_3 {
const Self& self;
public:
Intersect_3(const Self& self) : self(self)
{
}
Object operator()(const Surface_3& surface, const Segment_3& segment) const
{
boost::optional< typename AABB_traits::template Intersection_and_primitive_id<Segment_3>::Type >
intersection = surface.tree()->any_intersection(segment);
if ( intersection )
return intersection->first;
else
return Object();
}
Object operator()(const Surface_3& surface, const Line_3& line) const
{
boost::optional< typename AABB_traits::template Intersection_and_primitive_id<Line_3>::Type >
intersection = surface.tree()->any_intersection(line);
if ( intersection )
return intersection->first;
else
return Object();
}
Object operator()(const Surface_3& surface, const Ray_3& ray) const
{
boost::optional< typename AABB_traits::template Intersection_and_primitive_id<Ray_3>::Type >
intersection = surface.tree()->any_intersection(ray);
if ( intersection )
return intersection->first;
else
return Object();
}
};
Intersect_3 intersect_3_object() const
{
return Intersect_3(*this);
}
class Construct_initial_points;
friend class Construct_initial_points;
class Construct_initial_points
{
const Self& self;
public:
Construct_initial_points(const Self& self) : self(self)
{
}
template <typename OutputIteratorPoints>
OutputIteratorPoints operator() (const Surface_3& /* surface */,
OutputIteratorPoints out,
int /* n */) const
{
// std::cout << "AABB_polyhedral_oracle: empty initial point set" << std::endl;
return out;
}
};
Construct_initial_points construct_initial_points_object() const
{
return Construct_initial_points(*this);
}
template <class P>
bool is_in_volume(const Surface_3& surface, const P& p)
{
const Bounding_box bbox = surface.tree()->root_bbox();
if(p.x() < bbox.xmin() || p.x() > bbox.xmax())
return false;
if(p.y() < bbox.ymin() || p.y() > bbox.ymax())
return false;
if(p.z() < bbox.zmin() || p.z() > bbox.zmax())
return false;
const double diameter = max_bbox_length(bbox) * 2;
typename CGAL::Random_points_on_sphere_3<Point_3> random_point(FT(1));
typename Kernel::Construct_vector_3 vector =
Kernel().construct_vector_3_object();
typename Kernel::Construct_segment_3 segment =
Kernel().construct_segment_3_object();
typename Kernel::Construct_translated_point_3 translate =
Kernel().construct_translated_point_3_object();
typename Kernel::Construct_scaled_vector_3 scale =
Kernel().construct_scaled_vector_3_object();
const Segment_3 seg =
segment(p, translate(p,
scale(vector(ORIGIN,
*random_point),
diameter)));
return (surface.tree()->number_of_intersections(seg) % 2) == 1;
}
private:
double max_bbox_length(const Bounding_box& bbox) const
{
return (std::max)(bbox.xmax()-bbox.xmin(),
(std::max)(bbox.ymax()-bbox.ymin(),
bbox.zmax()-bbox.zmin()));
}
}; // end class AABB_polyhedral_oracle
} // end namespace CGAL
#endif // CGAL_AABB_POLYHEDRAL_ORACLE_H