mirror of https://github.com/CGAL/cgal
start updating the AABB-tree to work in both 2D and 3D
This commit is contained in:
parent
d68ef56d8d
commit
006d46b1d4
|
|
@ -3,8 +3,8 @@
|
|||
\ingroup PkgAABBTreeConcepts
|
||||
\cgalConcept
|
||||
|
||||
The concept `AABBGeomTraits` defines the requirements for the first template parameter of the class
|
||||
`CGAL::AABB_traits<AABBGeomTraits, AABBPrimitive>`. It provides predicates and constructors to detect
|
||||
The concept `AABBGeomTraits_3` defines the requirements for the first template parameter of the class
|
||||
`CGAL::AABB_traits<AABBGeomTraits_3, AABBPrimitive>`. It provides predicates and constructors to detect
|
||||
and compute intersections between query objects and the primitives stored in the AABB tree.
|
||||
In addition, it contains predicates and constructors to compute distances between a point query
|
||||
and the primitives stored in the AABB tree.
|
||||
|
|
@ -15,13 +15,13 @@ and the primitives stored in the AABB tree.
|
|||
\cgalHasModelsBare{All models of the concept `Kernel`}
|
||||
\cgalHasModelsEnd
|
||||
|
||||
\sa `CGAL::AABB_traits<AABBGeomTraits,AABBPrimitive>`
|
||||
\sa `CGAL::AABB_traits<AABBGeomTraits_3,AABBPrimitive>`
|
||||
\sa `CGAL::AABB_tree<AABBTraits>`
|
||||
\sa `AABBPrimitive`
|
||||
|
||||
*/
|
||||
|
||||
class AABBGeomTraits {
|
||||
class AABBGeomTraits_3 {
|
||||
public:
|
||||
|
||||
/// \name Types
|
||||
|
|
@ -199,5 +199,5 @@ Equal_3 equal_3_object();
|
|||
|
||||
/// @}
|
||||
|
||||
}; /* end AABBGeomTraits */
|
||||
}; /* end AABBGeomTraits_3 */
|
||||
|
||||
|
|
@ -21,46 +21,48 @@ define the Intersection_distance functor.
|
|||
class AABBRayIntersectionGeomTraits {
|
||||
public:
|
||||
/*!
|
||||
Type of a 3D ray.
|
||||
Type of a ray.
|
||||
*/
|
||||
typedef unspecified_type Ray_3;
|
||||
typedef unspecified_type Ray;
|
||||
|
||||
/*!
|
||||
Type of a 3D vector.
|
||||
Type of a vector.
|
||||
*/
|
||||
typedef unspecified_type Vector_3;
|
||||
typedef unspecified_type Vector;
|
||||
|
||||
/*!
|
||||
A functor object to construct the source point of a ray. Provides the operator:
|
||||
`Point_3 operator()(const Ray_3&);`
|
||||
`Point operator()(const Ray&);`
|
||||
*/
|
||||
typedef unspecified_type Construct_source_3;
|
||||
typedef unspecified_type Construct_source;
|
||||
|
||||
/*!
|
||||
*/
|
||||
Construct_source_3 construct_source_3_object();
|
||||
Construct_source construct_source_object();
|
||||
|
||||
/*!
|
||||
@todo update me
|
||||
A model of `CartesianConstIterator3`.
|
||||
*/
|
||||
typedef unspecified_type Cartesian_const_iterator_3;
|
||||
typedef unspecified_type Cartesian_const_iterator;
|
||||
|
||||
/*!
|
||||
@todo update me
|
||||
A model of `ConstructCartesianConstIterator3`.
|
||||
*/
|
||||
typedef unspecified_type Construct_cartesian_const_iterator_3;
|
||||
typedef unspecified_type Construct_cartesian_const_iterator;
|
||||
|
||||
/*!
|
||||
*/
|
||||
Construct_source_3 construct_cartesian_const_iterator_3_object();
|
||||
Construct_source construct_cartesian_const_iterator_object();
|
||||
|
||||
/*!
|
||||
A functor object to construct a vector giving the direction of a ray. Provides the operator:
|
||||
`Vector_3 operator()(const Ray_3&);`
|
||||
`Vector operator()(const Ray&);`
|
||||
*/
|
||||
typedef unspecified_type Construct_vector_3;
|
||||
typedef unspecified_type Construct_vector;
|
||||
|
||||
/*!
|
||||
*/
|
||||
Construct_source_3 construct_vector_3_object();
|
||||
Construct_source construct_vector_object();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ The concept `AABBTraits` provides the geometric primitive types and methods for
|
|||
\cgalHasModels{CGAL::AABB_traits<AABBGeomTraits,AABBPrimitive>}
|
||||
\cgalHasModelsEnd
|
||||
|
||||
\cgalRefines{SearchGeomTraits_3}
|
||||
\cgalRefines{SearchTraits}
|
||||
|
||||
\sa `CGAL::AABB_traits<AABBGeomTraits,AABBPrimitive>`
|
||||
\sa `CGAL::AABB_tree<AABBTraits>`
|
||||
|
|
@ -30,7 +30,7 @@ typedef unspecified_type FT;
|
|||
/*!
|
||||
Type of a 3D point.
|
||||
*/
|
||||
typedef unspecified_type Point_3;
|
||||
typedef unspecified_type Point;
|
||||
|
||||
/*!
|
||||
Type of primitive.
|
||||
|
|
@ -43,19 +43,10 @@ Bounding box type.
|
|||
*/
|
||||
typedef unspecified_type Bounding_box;
|
||||
|
||||
/*!
|
||||
enum required for axis selection
|
||||
*/
|
||||
enum Axis {
|
||||
CGAL_X_AXIS,
|
||||
CGAL_Y_AXIS,
|
||||
CGAL_Z_AXIS
|
||||
};
|
||||
|
||||
/*!
|
||||
3D Point and Primitive Id type
|
||||
*/
|
||||
typedef std::pair<Point_3, Primitive::Id> Point_and_primitive_id;
|
||||
typedef std::pair<Point, Primitive::Id> Point_and_primitive_id;
|
||||
|
||||
/*!
|
||||
\deprecated
|
||||
|
|
@ -145,21 +136,21 @@ typedef unspecified_type Compare_distance;
|
|||
|
||||
/*!
|
||||
A functor object to compute closest point from the query on a primitive. Provides the operator:
|
||||
`Point_3 operator()(const Query& query, const Primitive& primitive, const Point_3 & closest);` which returns the closest point to `query`, among `closest` and all points of the primitive.
|
||||
`Point operator()(const Query& query, const Primitive& primitive, const Point & closest);` which returns the closest point to `query`, among `closest` and all points of the primitive.
|
||||
*/
|
||||
typedef unspecified_type Closest_point;
|
||||
|
||||
/*!
|
||||
A functor object to compute the squared distance between two points. Provides the operator:
|
||||
`FT operator()(const Point& query, const Point_3 & p);` which returns the squared distance between `p` and `q`.
|
||||
`FT operator()(const Point& query, const Point & p);` which returns the squared distance between `p` and `q`.
|
||||
*/
|
||||
typedef unspecified_type Squared_distance;
|
||||
|
||||
/*!
|
||||
A functor object to compare two points. Provides the operator:
|
||||
`bool operator()(const Point_3& p, const Point_3& q);}` which returns `true` if `p` is equal to `q`.
|
||||
`bool operator()(const Point& p, const Point& q);}` which returns `true` if `p` is equal to `q`.
|
||||
*/
|
||||
typedef unspecified_type Equal_3;
|
||||
typedef unspecified_type Equal;
|
||||
/// @}
|
||||
|
||||
/// \name Operations
|
||||
|
|
@ -203,7 +194,7 @@ Squared_distance squared_distance_object();
|
|||
/*!
|
||||
returns the equal functor.
|
||||
*/
|
||||
Equal_3 equal_3_object();
|
||||
Equal equal_object();
|
||||
|
||||
/// @}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,12 +5,12 @@
|
|||
|
||||
/*!
|
||||
\addtogroup PkgAABBTreeRef
|
||||
\cgalPkgDescriptionBegin{3D Fast Intersection and Distance Computation,PkgAABBTree}
|
||||
\cgalPkgDescriptionBegin{Fast Intersection and Distance Computation,PkgAABBTree}
|
||||
\cgalPkgPicture{aabb-teaser-thumb.png}
|
||||
\cgalPkgSummaryBegin
|
||||
\cgalPkgAuthors{Pierre Alliez, Stéphane Tayeb, and Camille Wormser}
|
||||
\cgalPkgDesc{The AABB (axis-aligned bounding box) tree component offers a static data structure and algorithms to perform efficient intersection and distance queries on sets of finite 3D geometric objects.}
|
||||
\cgalPkgManuals{Chapter_3D_Fast_Intersection_and_Distance_Computation,PkgAABBTreeRef}
|
||||
\cgalPkgManuals{Chapter_Fast_Intersection_and_Distance_Computation,PkgAABBTreeRef}
|
||||
\cgalPkgSummaryEnd
|
||||
\cgalPkgShortInfoBegin
|
||||
\cgalPkgSince{3.5}
|
||||
|
|
@ -25,18 +25,23 @@
|
|||
\cgalCRPSection{Concepts}
|
||||
- `AABBPrimitive`
|
||||
- `AABBPrimitiveWithSharedData`
|
||||
- `AABBGeomTraits`
|
||||
- `AABBGeomTraits_2`
|
||||
- `AABBGeomTraits_3`
|
||||
- `AABBTraits`
|
||||
- `AABBRayIntersectionGeomTraits`
|
||||
- `AABBRayIntersectionGeomTraits_2`
|
||||
- `AABBRayIntersectionGeomTraits_3`
|
||||
- `AABBRayIntersectionTraits`
|
||||
|
||||
\cgalCRPSection{Classes}
|
||||
- `CGAL::AABB_traits<GeomTraits,Primitive>`
|
||||
- `CGAL::AABB_traits_2<GeomTraits,Primitive>`
|
||||
- `CGAL::AABB_traits_3<GeomTraits,Primitive>`
|
||||
- `CGAL::AABB_tree<AT>`
|
||||
|
||||
\cgalCRPSection{Primitives}
|
||||
- `CGAL::AABB_triangle_primitive<GeomTraits, Iterator, CacheDatum>`
|
||||
- `CGAL::AABB_segment_primitive<GeomTraits, Iterator, CacheDatum>`
|
||||
- `CGAL::AABB_triangle_primitive_2<GeomTraits, Iterator, CacheDatum>`
|
||||
- `CGAL::AABB_segment_primitive_2<GeomTraits, Iterator, CacheDatum>`
|
||||
- `CGAL::AABB_triangle_primitive_3<GeomTraits, Iterator, CacheDatum>`
|
||||
- `CGAL::AABB_segment_primitive_3<GeomTraits, Iterator, CacheDatum>`
|
||||
- `CGAL::AABB_primitive<Id,ObjectPropertyMap,PointPropertyMap,ExternalPropertyMaps,CacheDatum>`
|
||||
- `CGAL::AABB_halfedge_graph_segment_primitive<HalfedgeGraph,Vpm,OneHalfedgeGraphPerTree,CacheDatum>`
|
||||
- `CGAL::AABB_face_graph_triangle_primitive<FaceGraph,Vpm,OneFaceGraphPerTree,CacheDatum>`
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ namespace CGAL {
|
|||
/*!
|
||||
|
||||
\mainpage User Manual
|
||||
\anchor Chapter_3D_Fast_Intersection_and_Distance_Computation
|
||||
\anchor Chapter_Fast_Intersection_and_Distance_Computation
|
||||
\cgalAutoToc
|
||||
|
||||
\authors Pierre Alliez, Stephane Tayeb, and Camille Wormser
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2009 INRIA Sophia-Antipolis (France).
|
||||
// Copyright (c) 2024 INRIA Sophia-Antipolis (France).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org).
|
||||
|
|
@ -14,524 +14,24 @@
|
|||
#ifndef CGAL_AABB_TRAITS_H_
|
||||
#define CGAL_AABB_TRAITS_H_
|
||||
|
||||
#define CGAL_DEPRECATED_HEADER "<CGAL/AABB_traits.h>"
|
||||
#define CGAL_REPLACEMENT_HEADER "<CGAL/AABB_traits_3.h>"
|
||||
#include <CGAL/Installation/internal/deprecation_warning.h>
|
||||
|
||||
#ifndef CGAL_NO_DEPRECATED_CODE
|
||||
|
||||
#include <CGAL/license/AABB_tree.h>
|
||||
|
||||
#include <CGAL/disable_warnings.h>
|
||||
#include <CGAL/AABB_traits_3.h>
|
||||
|
||||
#include <CGAL/Bbox_3.h>
|
||||
#include <CGAL/Default.h>
|
||||
#include <CGAL/intersections.h>
|
||||
#include <CGAL/AABB_tree/internal/Has_nested_type_Shared_data.h>
|
||||
#include <CGAL/AABB_tree/internal/Is_ray_intersection_geomtraits.h>
|
||||
#include <CGAL/AABB_tree/internal/Primitive_helper.h>
|
||||
#include <CGAL/Kernel_23/internal/Has_boolean_tags.h>
|
||||
|
||||
|
||||
#include <optional>
|
||||
|
||||
/// \file AABB_traits.h
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
namespace internal{ namespace AABB_tree {
|
||||
|
||||
template <class T>
|
||||
struct Remove_optional { typedef T type; };
|
||||
|
||||
template <class T>
|
||||
struct Remove_optional< ::std::optional<T> > { typedef T type; };
|
||||
|
||||
//helper controlling whether extra data should be stored in the AABB_tree traits class
|
||||
template <class Primitive, bool has_shared_data=Has_nested_type_Shared_data<Primitive>::value>
|
||||
struct AABB_traits_base;
|
||||
|
||||
template <class Primitive>
|
||||
struct AABB_traits_base<Primitive,false>{};
|
||||
|
||||
template <class Primitive>
|
||||
struct AABB_traits_base<Primitive,true>{
|
||||
typename Primitive::Shared_data m_primitive_data;
|
||||
|
||||
template <typename ... T>
|
||||
void set_shared_data(T&& ... t){
|
||||
m_primitive_data=Primitive::construct_shared_data(std::forward<T>(t)...);
|
||||
}
|
||||
const typename Primitive::Shared_data& shared_data() const {return m_primitive_data;}
|
||||
};
|
||||
|
||||
// AABB_traits_base_2 brings in the Intersection_distance predicate,
|
||||
// if GeomTraits is a model RayIntersectionGeomTraits.
|
||||
template <typename GeomTraits, bool ray_intersection_geom_traits=Is_ray_intersection_geomtraits<GeomTraits>::value>
|
||||
struct AABB_traits_base_2;
|
||||
|
||||
template <typename GeomTraits>
|
||||
struct AABB_traits_base_2<GeomTraits,false>{};
|
||||
|
||||
template <typename GeomTraits>
|
||||
struct AABB_traits_base_2<GeomTraits,true>{
|
||||
typedef typename GeomTraits::Ray_3 Ray_3;
|
||||
typedef typename GeomTraits::Point_3 Point_3;
|
||||
typedef typename GeomTraits::Vector_3 Vector_3;
|
||||
typedef typename GeomTraits::FT FT;
|
||||
typedef typename GeomTraits::Cartesian_const_iterator_3 Cartesian_const_iterator_3;
|
||||
typedef typename GeomTraits::Construct_cartesian_const_iterator_3 Construct_cartesian_const_iterator_3;
|
||||
typedef typename GeomTraits::Construct_source_3 Construct_source_3;
|
||||
typedef typename GeomTraits::Construct_vector_3 Construct_vector_3;
|
||||
|
||||
// Defining Bounding_box and other types from the full AABB_traits
|
||||
// here is might seem strange, but otherwise we would need to use
|
||||
// CRTP to get access to the derived class, which would bloat the
|
||||
// code more.
|
||||
typedef typename CGAL::Bbox_3 Bounding_box;
|
||||
|
||||
struct Intersection_distance {
|
||||
std::optional<FT> operator()(const Ray_3& ray, const Bounding_box& bbox) const {
|
||||
FT t_near = -DBL_MAX; // std::numeric_limits<FT>::lowest(); C++1903
|
||||
FT t_far = DBL_MAX;
|
||||
|
||||
const Construct_cartesian_const_iterator_3 construct_cartesian_const_iterator_3
|
||||
= GeomTraits().construct_cartesian_const_iterator_3_object();
|
||||
const Construct_source_3 construct_source_3 = GeomTraits().construct_source_3_object();
|
||||
const Construct_vector_3 construct_vector_3 = GeomTraits().construct_vector_3_object();
|
||||
const Point_3 source = construct_source_3(ray);
|
||||
const Vector_3 direction = construct_vector_3(ray);
|
||||
Cartesian_const_iterator_3 source_iter = construct_cartesian_const_iterator_3(source);
|
||||
Cartesian_const_iterator_3 direction_iter = construct_cartesian_const_iterator_3(direction);
|
||||
|
||||
for(int i = 0; i < 3; ++i, ++source_iter, ++direction_iter) {
|
||||
if(*direction_iter == 0) {
|
||||
if((*source_iter < (bbox.min)(i)) || (*source_iter > (bbox.max)(i))) {
|
||||
return std::nullopt;
|
||||
}
|
||||
} else {
|
||||
FT t1 = ((bbox.min)(i) - *source_iter) / *direction_iter;
|
||||
FT t2 = ((bbox.max)(i) - *source_iter) / *direction_iter;
|
||||
|
||||
t_near = (std::max)(t_near, (std::min)(t1, t2));
|
||||
t_far = (std::min)(t_far, (std::max)(t1, t2));
|
||||
|
||||
// if(t1 > t2)
|
||||
// std::swap(t1, t2);
|
||||
// if(t1 > t_near)
|
||||
// t_near = t1;
|
||||
// if(t2 < t_far)
|
||||
// t_far = t2;
|
||||
|
||||
if(t_near > t_far || t_far < FT(0.))
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
if(t_near < FT(0.))
|
||||
return FT(0.);
|
||||
else
|
||||
return t_near;
|
||||
}
|
||||
};
|
||||
|
||||
Intersection_distance intersection_distance_object() const { return Intersection_distance(); }
|
||||
};
|
||||
|
||||
} } //end of namespace internal::AABB_tree
|
||||
|
||||
/// \addtogroup PkgAABBTreeRef
|
||||
/// @{
|
||||
|
||||
// forward declaration
|
||||
template< typename AABBTraits>
|
||||
class AABB_tree;
|
||||
|
||||
|
||||
/// This traits class handles any type of 3D geometric
|
||||
/// primitives provided that the proper intersection tests and
|
||||
/// constructions are implemented. It handles points, rays, lines and
|
||||
/// segments as query types for intersection detection and
|
||||
/// computations, and it handles points as query type for distance
|
||||
/// queries.
|
||||
///
|
||||
/// \cgalModels{AABBTraits,AABBRayIntersectionTraits}
|
||||
///
|
||||
/// \tparam GeomTraits must be a model of the concept \ref AABBGeomTraits,
|
||||
/// and provide the geometric types as well as the intersection tests and computations.
|
||||
/// \tparam Primitive provide the type of primitives stored in the AABB_tree.
|
||||
/// It is a model of the concept `AABBPrimitive` or `AABBPrimitiveWithSharedData`.
|
||||
///
|
||||
/// \tparam BboxMap must be a model of `ReadablePropertyMap` that has as key type a primitive id,
|
||||
/// and as value type a `Bounding_box`.
|
||||
/// If the type is `Default` the `Datum` must have the
|
||||
/// member function `bbox()` that returns the bounding box of the primitive.
|
||||
///
|
||||
/// If the argument `GeomTraits` is a model of the concept \ref
|
||||
/// AABBRayIntersectionGeomTraits, this class is also a model of \ref
|
||||
/// AABBRayIntersectionTraits.
|
||||
///
|
||||
/// \sa `AABBTraits`
|
||||
/// \sa `AABB_tree`
|
||||
/// \sa `AABBPrimitive`
|
||||
/// \sa `AABBPrimitiveWithSharedData`
|
||||
namespace CGAL
|
||||
{
|
||||
|
||||
template<typename GeomTraits, typename AABBPrimitive, typename BboxMap = Default>
|
||||
class AABB_traits
|
||||
#ifndef DOXYGEN_RUNNING
|
||||
: public internal::AABB_tree::AABB_traits_base<AABBPrimitive>,
|
||||
public internal::AABB_tree::AABB_traits_base_2<GeomTraits>
|
||||
#endif
|
||||
{
|
||||
typedef typename CGAL::Object Object;
|
||||
public:
|
||||
typedef GeomTraits Geom_traits;
|
||||
using AABB_traits = AABB_traits_3<GeomTraits, AABBPrimitive, BboxMap>;
|
||||
|
||||
typedef AABB_traits<GeomTraits, AABBPrimitive, BboxMap> AT;
|
||||
// AABBTraits concept types
|
||||
typedef typename GeomTraits::FT FT;
|
||||
typedef AABBPrimitive Primitive;
|
||||
} // namespace CGAL
|
||||
|
||||
typedef typename std::pair<Object,typename Primitive::Id> Object_and_primitive_id;
|
||||
|
||||
typedef typename std::pair<typename GeomTraits::Point_3, typename Primitive::Id> Point_and_primitive_id;
|
||||
|
||||
/// `Intersection_and_primitive_id<Query>::%Type::first_type` is found according to
|
||||
/// the result type of `GeomTraits::Intersect_3::operator()`. If it is
|
||||
/// `std::optional<T>` then it is `T`, and the result type otherwise.
|
||||
template<typename Query>
|
||||
struct Intersection_and_primitive_id {
|
||||
typedef decltype(
|
||||
std::declval<typename GeomTraits::Intersect_3>()(
|
||||
std::declval<Query>(),
|
||||
std::declval<typename Primitive::Datum>())) Intersection_type;
|
||||
|
||||
typedef std::pair<
|
||||
typename internal::AABB_tree::Remove_optional<Intersection_type>::type,
|
||||
typename Primitive::Id > Type;
|
||||
};
|
||||
|
||||
// types for search tree
|
||||
/// \name Types
|
||||
/// @{
|
||||
|
||||
/// Point query type.
|
||||
typedef typename GeomTraits::Point_3 Point_3;
|
||||
|
||||
/// additional types for the search tree, required by the RangeSearchTraits concept
|
||||
/// \bug This is not documented for now in the AABBTraits concept.
|
||||
typedef typename GeomTraits::Iso_cuboid_3 Iso_cuboid_3;
|
||||
|
||||
/// Bounding box type.
|
||||
typedef typename CGAL::Bbox_3 Bounding_box;
|
||||
|
||||
/// @}
|
||||
|
||||
typedef typename GeomTraits::Sphere_3 Sphere_3;
|
||||
typedef typename GeomTraits::Cartesian_const_iterator_3 Cartesian_const_iterator_3;
|
||||
typedef typename GeomTraits::Construct_cartesian_const_iterator_3 Construct_cartesian_const_iterator_3;
|
||||
typedef typename GeomTraits::Construct_center_3 Construct_center_3;
|
||||
typedef typename GeomTraits::Compute_squared_radius_3 Compute_squared_radius_3;
|
||||
typedef typename GeomTraits::Construct_min_vertex_3 Construct_min_vertex_3;
|
||||
typedef typename GeomTraits::Construct_max_vertex_3 Construct_max_vertex_3;
|
||||
typedef typename GeomTraits::Construct_iso_cuboid_3 Construct_iso_cuboid_3;
|
||||
|
||||
BboxMap bbm;
|
||||
|
||||
/// Default constructor.
|
||||
AABB_traits() { }
|
||||
|
||||
AABB_traits(BboxMap bbm)
|
||||
: bbm(bbm)
|
||||
{}
|
||||
|
||||
|
||||
typedef typename GeomTraits::Compute_squared_distance_3 Squared_distance;
|
||||
Squared_distance squared_distance_object() const { return GeomTraits().compute_squared_distance_3_object(); }
|
||||
|
||||
typedef typename GeomTraits::Equal_3 Equal_3;
|
||||
Equal_3 equal_3_object() const { return GeomTraits().equal_3_object(); }
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief Sorts [first,beyond[
|
||||
* @param first iterator on first element
|
||||
* @param beyond iterator on beyond element
|
||||
* @param bbox the bounding box of [first,beyond[
|
||||
*
|
||||
* Sorts the range defined by [first,beyond[. Sort is achieved on bbox longest
|
||||
* axis, using the comparison function `<dim>_less_than` (dim in {x,y,z})
|
||||
*/
|
||||
class Split_primitives
|
||||
{
|
||||
typedef AABB_traits<GeomTraits,AABBPrimitive,BboxMap> Traits;
|
||||
const Traits& m_traits;
|
||||
public:
|
||||
Split_primitives(const AABB_traits<GeomTraits,AABBPrimitive,BboxMap>& traits)
|
||||
: m_traits(traits) {}
|
||||
|
||||
typedef void result_type;
|
||||
template<typename PrimitiveIterator>
|
||||
void operator()(PrimitiveIterator first,
|
||||
PrimitiveIterator beyond,
|
||||
const typename AT::Bounding_box& bbox) const
|
||||
{
|
||||
PrimitiveIterator middle = first + (beyond - first)/2;
|
||||
switch(Traits::longest_axis(bbox))
|
||||
{
|
||||
case AT::CGAL_AXIS_X: // sort along x
|
||||
std::nth_element(first, middle, beyond, [this](const Primitive& p1, const Primitive& p2){ return Traits::less_x(p1, p2, this->m_traits); });
|
||||
break;
|
||||
case AT::CGAL_AXIS_Y: // sort along y
|
||||
std::nth_element(first, middle, beyond, [this](const Primitive& p1, const Primitive& p2){ return Traits::less_y(p1, p2, this->m_traits); });
|
||||
break;
|
||||
case AT::CGAL_AXIS_Z: // sort along z
|
||||
std::nth_element(first, middle, beyond, [this](const Primitive& p1, const Primitive& p2){ return Traits::less_z(p1, p2, this->m_traits); });
|
||||
break;
|
||||
default:
|
||||
CGAL_error();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Split_primitives split_primitives_object() const {return Split_primitives(*this);}
|
||||
|
||||
|
||||
/*
|
||||
* Computes the bounding box of a set of primitives
|
||||
* @param first an iterator on the first primitive
|
||||
* @param beyond an iterator on the past-the-end primitive
|
||||
* @return the bounding box of the primitives of the iterator range
|
||||
*/
|
||||
class Compute_bbox {
|
||||
const AABB_traits<GeomTraits,AABBPrimitive, BboxMap>& m_traits;
|
||||
public:
|
||||
Compute_bbox(const AABB_traits<GeomTraits,AABBPrimitive, BboxMap>& traits)
|
||||
:m_traits (traits) {}
|
||||
|
||||
template<typename ConstPrimitiveIterator>
|
||||
typename AT::Bounding_box operator()(ConstPrimitiveIterator first,
|
||||
ConstPrimitiveIterator beyond) const
|
||||
{
|
||||
typename AT::Bounding_box bbox = m_traits.compute_bbox(*first,m_traits.bbm);
|
||||
for(++first; first != beyond; ++first)
|
||||
{
|
||||
bbox = bbox + m_traits.compute_bbox(*first,m_traits.bbm);
|
||||
}
|
||||
return bbox;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Compute_bbox compute_bbox_object() const {return Compute_bbox(*this);}
|
||||
|
||||
/// \brief Function object using `GeomTraits::Do_intersect`.
|
||||
/// In the case the query is a `CGAL::AABB_tree`, the `do_intersect()`
|
||||
/// function of this tree is used.
|
||||
class Do_intersect {
|
||||
const AABB_traits<GeomTraits,AABBPrimitive, BboxMap>& m_traits;
|
||||
public:
|
||||
Do_intersect(const AABB_traits<GeomTraits,AABBPrimitive, BboxMap>& traits)
|
||||
:m_traits(traits) {}
|
||||
|
||||
template<typename Query>
|
||||
bool operator()(const Query& q, const Bounding_box& bbox) const
|
||||
{
|
||||
return GeomTraits().do_intersect_3_object()(q, bbox);
|
||||
}
|
||||
|
||||
template<typename Query>
|
||||
bool operator()(const Query& q, const Primitive& pr) const
|
||||
{
|
||||
return GeomTraits().do_intersect_3_object()(q, internal::Primitive_helper<AT>::get_datum(pr,m_traits));
|
||||
}
|
||||
|
||||
// intersection with AABB-tree
|
||||
template<typename AABBTraits>
|
||||
bool operator()(const CGAL::AABB_tree<AABBTraits>& other_tree, const Primitive& pr) const
|
||||
{
|
||||
return other_tree.do_intersect( internal::Primitive_helper<AT>::get_datum(pr,m_traits) );
|
||||
}
|
||||
|
||||
template<typename AABBTraits>
|
||||
bool operator()(const CGAL::AABB_tree<AABBTraits>& other_tree, const Bounding_box& bbox) const
|
||||
{
|
||||
return other_tree.do_intersect(bbox);
|
||||
}
|
||||
};
|
||||
|
||||
Do_intersect do_intersect_object() const {return Do_intersect(*this);}
|
||||
|
||||
|
||||
class Intersection {
|
||||
const AABB_traits<GeomTraits,AABBPrimitive,BboxMap>& m_traits;
|
||||
public:
|
||||
Intersection(const AABB_traits<GeomTraits,AABBPrimitive,BboxMap>& traits)
|
||||
:m_traits(traits) {}
|
||||
template<typename Query>
|
||||
std::optional< typename Intersection_and_primitive_id<Query>::Type >
|
||||
operator()(const Query& query, const typename AT::Primitive& primitive) const {
|
||||
auto inter_res = GeomTraits().intersect_3_object()(query, internal::Primitive_helper<AT>::get_datum(primitive,m_traits));
|
||||
if (!inter_res)
|
||||
return std::nullopt;
|
||||
return std::make_optional( std::make_pair(*inter_res, primitive.id()) );
|
||||
}
|
||||
};
|
||||
|
||||
Intersection intersection_object() const {return Intersection(*this);}
|
||||
|
||||
|
||||
// This should go down to the GeomTraits, i.e. the kernel
|
||||
class Closest_point {
|
||||
typedef typename AT::Point_3 Point;
|
||||
typedef typename AT::Primitive Primitive;
|
||||
const AABB_traits<GeomTraits,AABBPrimitive, BboxMap>& m_traits;
|
||||
public:
|
||||
Closest_point(const AABB_traits<GeomTraits,AABBPrimitive, BboxMap>& traits)
|
||||
: m_traits(traits) {}
|
||||
|
||||
|
||||
Point operator()(const Point& p, const Primitive& pr, const Point& bound) const
|
||||
{
|
||||
GeomTraits geom_traits;
|
||||
Point closest_point = geom_traits.construct_projected_point_3_object()(
|
||||
internal::Primitive_helper<AT>::get_datum(pr,m_traits), p);
|
||||
|
||||
return (geom_traits.compare_distance_3_object()(p, closest_point, bound) == LARGER) ?
|
||||
bound : closest_point;
|
||||
}
|
||||
};
|
||||
|
||||
// This should go down to the GeomTraits, i.e. the kernel
|
||||
// and the internal implementation should change its name from
|
||||
// do_intersect to something like does_contain (this is what we compute,
|
||||
// this is not the same do_intersect as the spherical kernel)
|
||||
class Compare_distance {
|
||||
typedef typename AT::Point_3 Point;
|
||||
typedef typename AT::FT FT;
|
||||
typedef typename AT::Primitive Primitive;
|
||||
public:
|
||||
CGAL::Comparison_result operator()(const Point& p, const Bounding_box& bb, const Point& bound, Tag_true) const
|
||||
{
|
||||
return GeomTraits().do_intersect_3_object()
|
||||
(GeomTraits().construct_sphere_3_object()
|
||||
(p, GeomTraits().compute_squared_distance_3_object()(p, bound)), bb,true)?
|
||||
CGAL::SMALLER : CGAL::LARGER;
|
||||
}
|
||||
|
||||
CGAL::Comparison_result operator()(const Point& p, const Bounding_box& bb, const Point& bound, Tag_false) const
|
||||
{
|
||||
return GeomTraits().do_intersect_3_object()
|
||||
(GeomTraits().construct_sphere_3_object()
|
||||
(p, GeomTraits().compute_squared_distance_3_object()(p, bound)), bb)?
|
||||
CGAL::SMALLER : CGAL::LARGER;
|
||||
}
|
||||
|
||||
CGAL::Comparison_result operator()(const Point& p, const Bounding_box& bb, const Point& bound) const
|
||||
{
|
||||
return (*this)(p, bb, bound, Boolean_tag<internal::Has_static_filters<GeomTraits>::value>());
|
||||
}
|
||||
|
||||
// The following functions seem unused...?
|
||||
template <class Solid>
|
||||
CGAL::Comparison_result operator()(const Point& p, const Solid& pr, const Point& bound) const
|
||||
{
|
||||
return GeomTraits().do_intersect_3_object()
|
||||
(GeomTraits().construct_sphere_3_object()
|
||||
(p, GeomTraits().compute_squared_distance_3_object()(p, bound)), pr)?
|
||||
CGAL::SMALLER : CGAL::LARGER;
|
||||
}
|
||||
|
||||
template <class Solid>
|
||||
CGAL::Comparison_result operator()(const Point& p, const Solid& pr, const FT& sq_distance) const
|
||||
{
|
||||
return GeomTraits().do_intersect_3_object()
|
||||
(GeomTraits().construct_sphere_3_object()(p, sq_distance),
|
||||
pr) ?
|
||||
CGAL::SMALLER :
|
||||
CGAL::LARGER;
|
||||
}
|
||||
};
|
||||
|
||||
Closest_point closest_point_object() const {return Closest_point(*this);}
|
||||
Compare_distance compare_distance_object() const {return Compare_distance();}
|
||||
|
||||
typedef enum { CGAL_AXIS_X = 0,
|
||||
CGAL_AXIS_Y = 1,
|
||||
CGAL_AXIS_Z = 2} Axis;
|
||||
|
||||
static Axis longest_axis(const Bounding_box& bbox);
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Computes bounding box of one primitive
|
||||
* @param pr the primitive
|
||||
* @return the bounding box of the primitive \c pr
|
||||
*/
|
||||
template <typename PM>
|
||||
Bounding_box compute_bbox(const Primitive& pr, const PM&)const
|
||||
{
|
||||
return get(bbm, pr.id());
|
||||
}
|
||||
|
||||
Bounding_box compute_bbox(const Primitive& pr, const Default&)const
|
||||
{
|
||||
return internal::Primitive_helper<AT>::get_datum(pr,*this).bbox();
|
||||
}
|
||||
|
||||
/// Comparison functions
|
||||
static bool less_x(const Primitive& pr1, const Primitive& pr2,const AABB_traits<GeomTraits,AABBPrimitive, BboxMap>& traits)
|
||||
{
|
||||
return GeomTraits().less_x_3_object()( internal::Primitive_helper<AT>::get_reference_point(pr1,traits),
|
||||
internal::Primitive_helper<AT>::get_reference_point(pr2,traits) );
|
||||
}
|
||||
static bool less_y(const Primitive& pr1, const Primitive& pr2,const AABB_traits<GeomTraits,AABBPrimitive, BboxMap>& traits)
|
||||
{
|
||||
return GeomTraits().less_y_3_object()( internal::Primitive_helper<AT>::get_reference_point(pr1,traits),
|
||||
internal::Primitive_helper<AT>::get_reference_point(pr2,traits) );
|
||||
}
|
||||
static bool less_z(const Primitive& pr1, const Primitive& pr2,const AABB_traits<GeomTraits,AABBPrimitive, BboxMap>& traits)
|
||||
{
|
||||
return GeomTraits().less_z_3_object()( internal::Primitive_helper<AT>::get_reference_point(pr1,traits),
|
||||
internal::Primitive_helper<AT>::get_reference_point(pr2,traits) );
|
||||
}
|
||||
|
||||
}; // end class AABB_traits
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Private methods
|
||||
//-------------------------------------------------------
|
||||
template<typename GT, typename P, typename B>
|
||||
typename AABB_traits<GT,P,B>::Axis
|
||||
AABB_traits<GT,P,B>::longest_axis(const Bounding_box& bbox)
|
||||
{
|
||||
const double dx = bbox.xmax() - bbox.xmin();
|
||||
const double dy = bbox.ymax() - bbox.ymin();
|
||||
const double dz = bbox.zmax() - bbox.zmin();
|
||||
|
||||
if(dx>=dy)
|
||||
{
|
||||
if(dx>=dz)
|
||||
{
|
||||
return CGAL_AXIS_X;
|
||||
}
|
||||
else // dz>dx and dx>=dy
|
||||
{
|
||||
return CGAL_AXIS_Z;
|
||||
}
|
||||
}
|
||||
else // dy>dx
|
||||
{
|
||||
if(dy>=dz)
|
||||
{
|
||||
return CGAL_AXIS_Y;
|
||||
}
|
||||
else // dz>dy and dy>dx
|
||||
{
|
||||
return CGAL_AXIS_Z;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
} // end namespace CGAL
|
||||
|
||||
#include <CGAL/enable_warnings.h>
|
||||
#endif // CGAL_NO_DEPRECATED_CODE
|
||||
|
||||
#endif // CGAL_AABB_TRAITS_H_
|
||||
|
|
|
|||
|
|
@ -0,0 +1,539 @@
|
|||
// Copyright (c) 2009 INRIA Sophia-Antipolis (France).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org).
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
//
|
||||
// Author(s) : Stéphane Tayeb, Pierre Alliez, Camille Wormser
|
||||
//
|
||||
|
||||
#ifndef CGAL_AABB_TRAITS_3_H_
|
||||
#define CGAL_AABB_TRAITS_3_H_
|
||||
|
||||
#include <CGAL/license/AABB_tree.h>
|
||||
|
||||
#include <CGAL/disable_warnings.h>
|
||||
|
||||
#include <CGAL/Bbox_3.h>
|
||||
#include <CGAL/Default.h>
|
||||
#include <CGAL/intersections.h>
|
||||
#include <CGAL/AABB_tree/internal/Has_nested_type_Shared_data.h>
|
||||
#include <CGAL/AABB_tree/internal/Is_ray_intersection_geomtraits.h>
|
||||
#include <CGAL/AABB_tree/internal/Primitive_helper.h>
|
||||
#include <CGAL/Kernel_23/internal/Has_boolean_tags.h>
|
||||
|
||||
|
||||
#include <optional>
|
||||
|
||||
/// \file AABB_traits_3.h
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
namespace internal{ namespace AABB_tree {
|
||||
|
||||
template <class T>
|
||||
struct Remove_optional { typedef T type; };
|
||||
|
||||
template <class T>
|
||||
struct Remove_optional< ::std::optional<T> > { typedef T type; };
|
||||
|
||||
//helper controlling whether extra data should be stored in the AABB_tree traits class
|
||||
template <class Primitive, bool has_shared_data=Has_nested_type_Shared_data<Primitive>::value>
|
||||
struct AABB_traits_base;
|
||||
|
||||
template <class Primitive>
|
||||
struct AABB_traits_base<Primitive,false>{};
|
||||
|
||||
template <class Primitive>
|
||||
struct AABB_traits_base<Primitive,true>{
|
||||
typename Primitive::Shared_data m_primitive_data;
|
||||
|
||||
template <typename ... T>
|
||||
void set_shared_data(T&& ... t){
|
||||
m_primitive_data=Primitive::construct_shared_data(std::forward<T>(t)...);
|
||||
}
|
||||
const typename Primitive::Shared_data& shared_data() const {return m_primitive_data;}
|
||||
};
|
||||
|
||||
// AABB_traits_intersection_base brings in the Intersection_distance predicate,
|
||||
// if GeomTraits is a model RayIntersectionGeomTraits.
|
||||
template <typename GeomTraits, bool ray_intersection_geom_traits=Is_ray_intersection_geomtraits<GeomTraits>::value>
|
||||
struct AABB_traits_intersection_base;
|
||||
|
||||
template <typename GeomTraits>
|
||||
struct AABB_traits_intersection_base<GeomTraits,false>{};
|
||||
|
||||
template <typename GeomTraits>
|
||||
struct AABB_traits_intersection_base<GeomTraits,true>{
|
||||
typedef typename GeomTraits::Ray_3 Ray_3;
|
||||
typedef typename GeomTraits::Point_3 Point_3;
|
||||
typedef typename GeomTraits::Point_3 Point;
|
||||
typedef typename GeomTraits::Point_3 Ray;
|
||||
typedef typename GeomTraits::Vector_3 Vector_3;
|
||||
typedef typename GeomTraits::FT FT;
|
||||
typedef typename GeomTraits::Cartesian_const_iterator_3 Cartesian_const_iterator_3;
|
||||
typedef typename GeomTraits::Construct_cartesian_const_iterator_3 Construct_cartesian_const_iterator_3;
|
||||
typedef typename GeomTraits::Construct_source_3 Construct_source_3;
|
||||
typedef typename GeomTraits::Construct_vector_3 Construct_vector_3;
|
||||
|
||||
// Defining Bounding_box and other types from the full AABB_traits_3
|
||||
// here is might seem strange, but otherwise we would need to use
|
||||
// CRTP to get access to the derived class, which would bloat the
|
||||
// code more.
|
||||
typedef typename CGAL::Bbox_3 Bounding_box;
|
||||
|
||||
struct Intersection_distance {
|
||||
std::optional<FT> operator()(const Ray_3& ray, const Bounding_box& bbox) const {
|
||||
FT t_near = -DBL_MAX; // std::numeric_limits<FT>::lowest(); C++1903
|
||||
FT t_far = DBL_MAX;
|
||||
|
||||
const Construct_cartesian_const_iterator_3 construct_cartesian_const_iterator_3
|
||||
= GeomTraits().construct_cartesian_const_iterator_3_object();
|
||||
const Construct_source_3 construct_source_3 = GeomTraits().construct_source_3_object();
|
||||
const Construct_vector_3 construct_vector_3 = GeomTraits().construct_vector_3_object();
|
||||
const Point_3 source = construct_source_3(ray);
|
||||
const Vector_3 direction = construct_vector_3(ray);
|
||||
Cartesian_const_iterator_3 source_iter = construct_cartesian_const_iterator_3(source);
|
||||
Cartesian_const_iterator_3 direction_iter = construct_cartesian_const_iterator_3(direction);
|
||||
|
||||
for(int i = 0; i < 3; ++i, ++source_iter, ++direction_iter) {
|
||||
if(*direction_iter == 0) {
|
||||
if((*source_iter < (bbox.min)(i)) || (*source_iter > (bbox.max)(i))) {
|
||||
return std::nullopt;
|
||||
}
|
||||
} else {
|
||||
FT t1 = ((bbox.min)(i) - *source_iter) / *direction_iter;
|
||||
FT t2 = ((bbox.max)(i) - *source_iter) / *direction_iter;
|
||||
|
||||
t_near = (std::max)(t_near, (std::min)(t1, t2));
|
||||
t_far = (std::min)(t_far, (std::max)(t1, t2));
|
||||
|
||||
// if(t1 > t2)
|
||||
// std::swap(t1, t2);
|
||||
// if(t1 > t_near)
|
||||
// t_near = t1;
|
||||
// if(t2 < t_far)
|
||||
// t_far = t2;
|
||||
|
||||
if(t_near > t_far || t_far < FT(0.))
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
if(t_near < FT(0.))
|
||||
return FT(0.);
|
||||
else
|
||||
return t_near;
|
||||
}
|
||||
};
|
||||
|
||||
Intersection_distance intersection_distance_object() const { return Intersection_distance(); }
|
||||
};
|
||||
|
||||
} } //end of namespace internal::AABB_tree
|
||||
|
||||
/// \addtogroup PkgAABBTreeRef
|
||||
/// @{
|
||||
|
||||
// forward declaration
|
||||
template< typename AABBTraits>
|
||||
class AABB_tree;
|
||||
|
||||
|
||||
/// This traits class handles any type of 3D geometric
|
||||
/// primitives provided that the proper intersection tests and
|
||||
/// constructions are implemented. It handles points, rays, lines and
|
||||
/// segments as query types for intersection detection and
|
||||
/// computations, and it handles points as query type for distance
|
||||
/// queries.
|
||||
///
|
||||
/// \cgalModels{AABBTraits,AABBRayIntersectionTraits}
|
||||
///
|
||||
/// \tparam GeomTraits must be a model of the concept \ref AABBGeomTraits_3,
|
||||
/// and provide the geometric types as well as the intersection tests and computations.
|
||||
/// \tparam Primitive provide the type of primitives stored in the AABB_tree.
|
||||
/// It is a model of the concept `AABBPrimitive` or `AABBPrimitiveWithSharedData`.
|
||||
///
|
||||
/// \tparam BboxMap must be a model of `ReadablePropertyMap` that has as key type a primitive id,
|
||||
/// and as value type a `Bounding_box`.
|
||||
/// If the type is `Default` the `Datum` must have the
|
||||
/// member function `bbox()` that returns the bounding box of the primitive.
|
||||
///
|
||||
/// If the argument `GeomTraits` is a model of the concept \ref
|
||||
/// AABBRayIntersectionGeomTraits, this class is also a model of \ref
|
||||
/// AABBRayIntersectionTraits.
|
||||
///
|
||||
/// \sa `AABBTraits`
|
||||
/// \sa `AABB_tree`
|
||||
/// \sa `AABBPrimitive`
|
||||
/// \sa `AABBPrimitiveWithSharedData`
|
||||
|
||||
template<typename GeomTraits, typename AABBPrimitive, typename BboxMap = Default>
|
||||
class AABB_traits_3
|
||||
#ifndef DOXYGEN_RUNNING
|
||||
: public internal::AABB_tree::AABB_traits_base<AABBPrimitive>,
|
||||
public internal::AABB_tree::AABB_traits_intersection_base<GeomTraits>
|
||||
#endif
|
||||
{
|
||||
typedef typename CGAL::Object Object;
|
||||
public:
|
||||
typedef GeomTraits Geom_traits;
|
||||
|
||||
typedef AABB_traits_3<GeomTraits, AABBPrimitive, BboxMap> AT;
|
||||
// AABBTraits concept types
|
||||
typedef typename GeomTraits::FT FT;
|
||||
typedef AABBPrimitive Primitive;
|
||||
|
||||
typedef typename std::pair<Object,typename Primitive::Id> Object_and_primitive_id;
|
||||
|
||||
typedef typename std::pair<typename GeomTraits::Point_3, typename Primitive::Id> Point_and_primitive_id;
|
||||
|
||||
/// `Intersection_and_primitive_id<Query>::%Type::first_type` is found according to
|
||||
/// the result type of `GeomTraits::Intersect_3::operator()`. If it is
|
||||
/// `std::optional<T>` then it is `T`, and the result type otherwise.
|
||||
template<typename Query>
|
||||
struct Intersection_and_primitive_id {
|
||||
typedef decltype(
|
||||
std::declval<typename GeomTraits::Intersect_3>()(
|
||||
std::declval<Query>(),
|
||||
std::declval<typename Primitive::Datum>())) Intersection_type;
|
||||
|
||||
typedef std::pair<
|
||||
typename internal::AABB_tree::Remove_optional<Intersection_type>::type,
|
||||
typename Primitive::Id > Type;
|
||||
};
|
||||
|
||||
// types for search tree
|
||||
/// \name Types
|
||||
/// @{
|
||||
|
||||
/// Point query type.
|
||||
typedef typename GeomTraits::Point_3 Point_3;
|
||||
|
||||
/// additional types for the search tree, required by the RangeSearchTraits concept
|
||||
/// \bug This is not documented for now in the AABBTraits concept.
|
||||
typedef typename GeomTraits::Iso_cuboid_3 Iso_cuboid_3;
|
||||
|
||||
/// Bounding box type.
|
||||
typedef typename CGAL::Bbox_3 Bounding_box;
|
||||
|
||||
/// @}
|
||||
|
||||
typedef typename GeomTraits::Sphere_3 Sphere_3;
|
||||
typedef typename GeomTraits::Cartesian_const_iterator_3 Cartesian_const_iterator_3;
|
||||
typedef typename GeomTraits::Construct_cartesian_const_iterator_3 Construct_cartesian_const_iterator_3;
|
||||
typedef typename GeomTraits::Construct_center_3 Construct_center_3;
|
||||
typedef typename GeomTraits::Compute_squared_radius_3 Compute_squared_radius_3;
|
||||
typedef typename GeomTraits::Construct_min_vertex_3 Construct_min_vertex_3;
|
||||
typedef typename GeomTraits::Construct_max_vertex_3 Construct_max_vertex_3;
|
||||
typedef typename GeomTraits::Construct_iso_cuboid_3 Construct_iso_cuboid_3;
|
||||
|
||||
BboxMap bbm;
|
||||
|
||||
/// Default constructor.
|
||||
AABB_traits_3() { }
|
||||
|
||||
AABB_traits_3(BboxMap bbm)
|
||||
: bbm(bbm)
|
||||
{}
|
||||
|
||||
|
||||
typedef typename GeomTraits::Compute_squared_distance_3 Squared_distance;
|
||||
Squared_distance squared_distance_object() const { return GeomTraits().compute_squared_distance_3_object(); }
|
||||
|
||||
typedef typename GeomTraits::Equal_3 Equal_3;
|
||||
Equal_3 equal_3_object() const { return GeomTraits().equal_3_object(); }
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief Sorts [first,beyond[
|
||||
* @param first iterator on first element
|
||||
* @param beyond iterator on beyond element
|
||||
* @param bbox the bounding box of [first,beyond[
|
||||
*
|
||||
* Sorts the range defined by [first,beyond[. Sort is achieved on bbox longest
|
||||
* axis, using the comparison function `<dim>_less_than` (dim in {x,y,z})
|
||||
*/
|
||||
class Split_primitives
|
||||
{
|
||||
typedef AABB_traits_3<GeomTraits,AABBPrimitive,BboxMap> Traits;
|
||||
const Traits& m_traits;
|
||||
public:
|
||||
Split_primitives(const AABB_traits_3<GeomTraits,AABBPrimitive,BboxMap>& traits)
|
||||
: m_traits(traits) {}
|
||||
|
||||
typedef void result_type;
|
||||
template<typename PrimitiveIterator>
|
||||
void operator()(PrimitiveIterator first,
|
||||
PrimitiveIterator beyond,
|
||||
const typename AT::Bounding_box& bbox) const
|
||||
{
|
||||
PrimitiveIterator middle = first + (beyond - first)/2;
|
||||
switch(Traits::longest_axis(bbox))
|
||||
{
|
||||
case AT::CGAL_AXIS_X: // sort along x
|
||||
std::nth_element(first, middle, beyond, [this](const Primitive& p1, const Primitive& p2){ return Traits::less_x(p1, p2, this->m_traits); });
|
||||
break;
|
||||
case AT::CGAL_AXIS_Y: // sort along y
|
||||
std::nth_element(first, middle, beyond, [this](const Primitive& p1, const Primitive& p2){ return Traits::less_y(p1, p2, this->m_traits); });
|
||||
break;
|
||||
case AT::CGAL_AXIS_Z: // sort along z
|
||||
std::nth_element(first, middle, beyond, [this](const Primitive& p1, const Primitive& p2){ return Traits::less_z(p1, p2, this->m_traits); });
|
||||
break;
|
||||
default:
|
||||
CGAL_error();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Split_primitives split_primitives_object() const {return Split_primitives(*this);}
|
||||
|
||||
|
||||
/*
|
||||
* Computes the bounding box of a set of primitives
|
||||
* @param first an iterator on the first primitive
|
||||
* @param beyond an iterator on the past-the-end primitive
|
||||
* @return the bounding box of the primitives of the iterator range
|
||||
*/
|
||||
class Compute_bbox {
|
||||
const AABB_traits_3<GeomTraits,AABBPrimitive, BboxMap>& m_traits;
|
||||
public:
|
||||
Compute_bbox(const AABB_traits_3<GeomTraits,AABBPrimitive, BboxMap>& traits)
|
||||
:m_traits (traits) {}
|
||||
|
||||
template<typename ConstPrimitiveIterator>
|
||||
typename AT::Bounding_box operator()(ConstPrimitiveIterator first,
|
||||
ConstPrimitiveIterator beyond) const
|
||||
{
|
||||
typename AT::Bounding_box bbox = m_traits.compute_bbox(*first,m_traits.bbm);
|
||||
for(++first; first != beyond; ++first)
|
||||
{
|
||||
bbox = bbox + m_traits.compute_bbox(*first,m_traits.bbm);
|
||||
}
|
||||
return bbox;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Compute_bbox compute_bbox_object() const {return Compute_bbox(*this);}
|
||||
|
||||
/// \brief Function object using `GeomTraits::Do_intersect`.
|
||||
/// In the case the query is a `CGAL::AABB_tree`, the `do_intersect()`
|
||||
/// function of this tree is used.
|
||||
class Do_intersect {
|
||||
const AABB_traits_3<GeomTraits,AABBPrimitive, BboxMap>& m_traits;
|
||||
public:
|
||||
Do_intersect(const AABB_traits_3<GeomTraits,AABBPrimitive, BboxMap>& traits)
|
||||
:m_traits(traits) {}
|
||||
|
||||
template<typename Query>
|
||||
bool operator()(const Query& q, const Bounding_box& bbox) const
|
||||
{
|
||||
return GeomTraits().do_intersect_3_object()(q, bbox);
|
||||
}
|
||||
|
||||
template<typename Query>
|
||||
bool operator()(const Query& q, const Primitive& pr) const
|
||||
{
|
||||
return GeomTraits().do_intersect_3_object()(q, internal::Primitive_helper<AT>::get_datum(pr,m_traits));
|
||||
}
|
||||
|
||||
// intersection with AABB-tree
|
||||
template<typename AABBTraits>
|
||||
bool operator()(const CGAL::AABB_tree<AABBTraits>& other_tree, const Primitive& pr) const
|
||||
{
|
||||
return other_tree.do_intersect( internal::Primitive_helper<AT>::get_datum(pr,m_traits) );
|
||||
}
|
||||
|
||||
template<typename AABBTraits>
|
||||
bool operator()(const CGAL::AABB_tree<AABBTraits>& other_tree, const Bounding_box& bbox) const
|
||||
{
|
||||
return other_tree.do_intersect(bbox);
|
||||
}
|
||||
};
|
||||
|
||||
Do_intersect do_intersect_object() const {return Do_intersect(*this);}
|
||||
|
||||
|
||||
class Intersection {
|
||||
const AABB_traits_3<GeomTraits,AABBPrimitive,BboxMap>& m_traits;
|
||||
public:
|
||||
Intersection(const AABB_traits_3<GeomTraits,AABBPrimitive,BboxMap>& traits)
|
||||
:m_traits(traits) {}
|
||||
template<typename Query>
|
||||
std::optional< typename Intersection_and_primitive_id<Query>::Type >
|
||||
operator()(const Query& query, const typename AT::Primitive& primitive) const {
|
||||
auto inter_res = GeomTraits().intersect_3_object()(query, internal::Primitive_helper<AT>::get_datum(primitive,m_traits));
|
||||
if (!inter_res)
|
||||
return std::nullopt;
|
||||
return std::make_optional( std::make_pair(*inter_res, primitive.id()) );
|
||||
}
|
||||
};
|
||||
|
||||
Intersection intersection_object() const {return Intersection(*this);}
|
||||
|
||||
|
||||
// This should go down to the GeomTraits, i.e. the kernel
|
||||
class Closest_point {
|
||||
typedef typename AT::Point_3 Point;
|
||||
typedef typename AT::Primitive Primitive;
|
||||
const AABB_traits_3<GeomTraits,AABBPrimitive, BboxMap>& m_traits;
|
||||
public:
|
||||
Closest_point(const AABB_traits_3<GeomTraits,AABBPrimitive, BboxMap>& traits)
|
||||
: m_traits(traits) {}
|
||||
|
||||
|
||||
Point operator()(const Point& p, const Primitive& pr, const Point& bound) const
|
||||
{
|
||||
GeomTraits geom_traits;
|
||||
Point closest_point = geom_traits.construct_projected_point_3_object()(
|
||||
internal::Primitive_helper<AT>::get_datum(pr,m_traits), p);
|
||||
|
||||
return (geom_traits.compare_distance_3_object()(p, closest_point, bound) == LARGER) ?
|
||||
bound : closest_point;
|
||||
}
|
||||
};
|
||||
|
||||
// This should go down to the GeomTraits, i.e. the kernel
|
||||
// and the internal implementation should change its name from
|
||||
// do_intersect to something like does_contain (this is what we compute,
|
||||
// this is not the same do_intersect as the spherical kernel)
|
||||
class Compare_distance {
|
||||
typedef typename AT::Point_3 Point;
|
||||
typedef typename AT::FT FT;
|
||||
typedef typename AT::Primitive Primitive;
|
||||
public:
|
||||
CGAL::Comparison_result operator()(const Point& p, const Bounding_box& bb, const Point& bound, Tag_true) const
|
||||
{
|
||||
return GeomTraits().do_intersect_3_object()
|
||||
(GeomTraits().construct_sphere_3_object()
|
||||
(p, GeomTraits().compute_squared_distance_3_object()(p, bound)), bb,true)?
|
||||
CGAL::SMALLER : CGAL::LARGER;
|
||||
}
|
||||
|
||||
CGAL::Comparison_result operator()(const Point& p, const Bounding_box& bb, const Point& bound, Tag_false) const
|
||||
{
|
||||
return GeomTraits().do_intersect_3_object()
|
||||
(GeomTraits().construct_sphere_3_object()
|
||||
(p, GeomTraits().compute_squared_distance_3_object()(p, bound)), bb)?
|
||||
CGAL::SMALLER : CGAL::LARGER;
|
||||
}
|
||||
|
||||
CGAL::Comparison_result operator()(const Point& p, const Bounding_box& bb, const Point& bound) const
|
||||
{
|
||||
return (*this)(p, bb, bound, Boolean_tag<internal::Has_static_filters<GeomTraits>::value>());
|
||||
}
|
||||
|
||||
// The following functions seem unused...?
|
||||
template <class Solid>
|
||||
CGAL::Comparison_result operator()(const Point& p, const Solid& pr, const Point& bound) const
|
||||
{
|
||||
return GeomTraits().do_intersect_3_object()
|
||||
(GeomTraits().construct_sphere_3_object()
|
||||
(p, GeomTraits().compute_squared_distance_3_object()(p, bound)), pr)?
|
||||
CGAL::SMALLER : CGAL::LARGER;
|
||||
}
|
||||
|
||||
template <class Solid>
|
||||
CGAL::Comparison_result operator()(const Point& p, const Solid& pr, const FT& sq_distance) const
|
||||
{
|
||||
return GeomTraits().do_intersect_3_object()
|
||||
(GeomTraits().construct_sphere_3_object()(p, sq_distance),
|
||||
pr) ?
|
||||
CGAL::SMALLER :
|
||||
CGAL::LARGER;
|
||||
}
|
||||
};
|
||||
|
||||
Closest_point closest_point_object() const {return Closest_point(*this);}
|
||||
Compare_distance compare_distance_object() const {return Compare_distance();}
|
||||
|
||||
typedef enum { CGAL_AXIS_X = 0,
|
||||
CGAL_AXIS_Y = 1,
|
||||
CGAL_AXIS_Z = 2} Axis;
|
||||
|
||||
static Axis longest_axis(const Bounding_box& bbox);
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Computes bounding box of one primitive
|
||||
* @param pr the primitive
|
||||
* @return the bounding box of the primitive \c pr
|
||||
*/
|
||||
template <typename PM>
|
||||
Bounding_box compute_bbox(const Primitive& pr, const PM&)const
|
||||
{
|
||||
return get(bbm, pr.id());
|
||||
}
|
||||
|
||||
Bounding_box compute_bbox(const Primitive& pr, const Default&)const
|
||||
{
|
||||
return internal::Primitive_helper<AT>::get_datum(pr,*this).bbox();
|
||||
}
|
||||
|
||||
/// Comparison functions
|
||||
static bool less_x(const Primitive& pr1, const Primitive& pr2,const AABB_traits_3<GeomTraits,AABBPrimitive, BboxMap>& traits)
|
||||
{
|
||||
return GeomTraits().less_x_3_object()( internal::Primitive_helper<AT>::get_reference_point(pr1,traits),
|
||||
internal::Primitive_helper<AT>::get_reference_point(pr2,traits) );
|
||||
}
|
||||
static bool less_y(const Primitive& pr1, const Primitive& pr2,const AABB_traits_3<GeomTraits,AABBPrimitive, BboxMap>& traits)
|
||||
{
|
||||
return GeomTraits().less_y_3_object()( internal::Primitive_helper<AT>::get_reference_point(pr1,traits),
|
||||
internal::Primitive_helper<AT>::get_reference_point(pr2,traits) );
|
||||
}
|
||||
static bool less_z(const Primitive& pr1, const Primitive& pr2,const AABB_traits_3<GeomTraits,AABBPrimitive, BboxMap>& traits)
|
||||
{
|
||||
return GeomTraits().less_z_3_object()( internal::Primitive_helper<AT>::get_reference_point(pr1,traits),
|
||||
internal::Primitive_helper<AT>::get_reference_point(pr2,traits) );
|
||||
}
|
||||
|
||||
}; // end class AABB_traits_3
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Private methods
|
||||
//-------------------------------------------------------
|
||||
template<typename GT, typename P, typename B>
|
||||
typename AABB_traits_3<GT,P,B>::Axis
|
||||
AABB_traits_3<GT,P,B>::longest_axis(const Bounding_box& bbox)
|
||||
{
|
||||
const double dx = bbox.xmax() - bbox.xmin();
|
||||
const double dy = bbox.ymax() - bbox.ymin();
|
||||
const double dz = bbox.zmax() - bbox.zmin();
|
||||
|
||||
if(dx>=dy)
|
||||
{
|
||||
if(dx>=dz)
|
||||
{
|
||||
return CGAL_AXIS_X;
|
||||
}
|
||||
else // dz>dx and dx>=dy
|
||||
{
|
||||
return CGAL_AXIS_Z;
|
||||
}
|
||||
}
|
||||
else // dy>dx
|
||||
{
|
||||
if(dy>=dz)
|
||||
{
|
||||
return CGAL_AXIS_Y;
|
||||
}
|
||||
else // dz>dy and dy>dx
|
||||
{
|
||||
return CGAL_AXIS_Z;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
} // end namespace CGAL
|
||||
|
||||
#include <CGAL/enable_warnings.h>
|
||||
|
||||
#endif // CGAL_AABB_TRAITS_3_H_
|
||||
|
|
@ -76,7 +76,7 @@ namespace CGAL {
|
|||
|
||||
|
||||
/// Type of 3D point.
|
||||
typedef typename AABBTraits::Point_3 Point;
|
||||
typedef typename AABBTraits::Point Point;
|
||||
|
||||
/// Type of input primitive.
|
||||
typedef typename AABBTraits::Primitive Primitive;
|
||||
|
|
@ -300,7 +300,7 @@ public:
|
|||
|
||||
/// returns the intersection and primitive id closest to the source point of the ray
|
||||
/// query.
|
||||
/// \tparam Ray must be the same as `AABBTraits::Ray_3` and
|
||||
/// \tparam Ray must be the same as `AABBTraits::Ray` and
|
||||
/// `do_intersect` predicates and intersections for it must be
|
||||
/// defined.
|
||||
/// \tparam Skip a functor with an operator
|
||||
|
|
@ -331,7 +331,7 @@ public:
|
|||
|
||||
/// returns the primitive id closest to the source point of the ray
|
||||
/// query.
|
||||
/// \tparam Ray must be the same as `AABBTraits::Ray_3` and
|
||||
/// \tparam Ray must be the same as `AABBTraits::Ray` and
|
||||
/// `do_intersect` predicates and intersections for it must be
|
||||
/// defined.
|
||||
/// \tparam Skip a functor with an operator
|
||||
|
|
|
|||
Loading…
Reference in New Issue