mirror of https://github.com/CGAL/cgal
Copy modified AABB classes back to M-sum package
Append "_with_join" to each class and include guard to avoid any clashes.
This commit is contained in:
parent
157028d61d
commit
2630936c49
|
|
@ -336,13 +336,6 @@ public:
|
|||
template<typename Query>
|
||||
bool do_intersect(const Query& query) const;
|
||||
|
||||
/// Returns `true`, iff at least one pair of primitives in the
|
||||
/// two trees intersect. The `other` tree is translated by
|
||||
/// `translation` before this is tested. The traits class `AABBTraits`
|
||||
/// needs to define `do_intersect` predicates for the tree's primitive.
|
||||
bool do_intersect(const AABB_tree &other,
|
||||
const Point &translation) const;
|
||||
|
||||
/// Returns the number of primitives intersected by the
|
||||
/// query. \tparam Query must be a type for which
|
||||
/// `do_intersect` predicates are defined
|
||||
|
|
@ -575,24 +568,6 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
/// \internal
|
||||
template <class Traversal_traits>
|
||||
void traversal(const AABB_tree &other_tree, Traversal_traits &traits) const
|
||||
{
|
||||
if (size() > 1 && other_tree.size() > 1)
|
||||
{
|
||||
root_node()->template traversal<Traversal_traits>(*(other_tree.root_node()),
|
||||
traits,
|
||||
m_primitives.size(),
|
||||
other_tree.m_primitives.size(),
|
||||
true);
|
||||
}
|
||||
else // at least tree has less than 2 primitives
|
||||
{
|
||||
// TODO not implemented yet, cannot happen with two polygons
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
typedef AABB_node<AABBTraits> Node;
|
||||
|
||||
|
|
@ -1107,18 +1082,7 @@ public:
|
|||
return traversal_traits.is_intersection_found();
|
||||
}
|
||||
|
||||
template<typename Tr>
|
||||
bool AABB_tree<Tr>::do_intersect(const AABB_tree &other,
|
||||
const Point &translation) const
|
||||
{
|
||||
using namespace CGAL::internal::AABB_tree;
|
||||
typedef typename AABB_tree<Tr>::AABB_traits AABBTraits;
|
||||
Do_intersect_joined_traits<AABBTraits> traversal_traits(translation);
|
||||
this->traversal(other, traversal_traits);
|
||||
return traversal_traits.is_intersection_found();
|
||||
}
|
||||
|
||||
template<typename Tr>
|
||||
template<typename Tr>
|
||||
template<typename Query>
|
||||
typename AABB_tree<Tr>::size_type
|
||||
AABB_tree<Tr>::number_of_intersected_primitives(const Query& query) const
|
||||
|
|
|
|||
|
|
@ -82,22 +82,6 @@ public:
|
|||
Traversal_traits& traits,
|
||||
const std::size_t nb_primitives) const;
|
||||
|
||||
/**
|
||||
* @param other_node root node of a tree which we want to traverse in parallel
|
||||
* @param traits the traversal traits that define the traversal behaviour
|
||||
* @param nb_primitives the number of primitives in this tree
|
||||
* @param nb_primitives_other the number of primitives in the other tree
|
||||
* @param first_stationary if true, the other_node is the translatable tree's root
|
||||
*
|
||||
* General traversal query for two trees.
|
||||
*/
|
||||
template<class Traversal_traits>
|
||||
void traversal(const AABB_node &other_node,
|
||||
Traversal_traits &traits,
|
||||
const std::size_t nb_primitives,
|
||||
const std::size_t nb_primitives_other,
|
||||
bool first_stationary) const;
|
||||
|
||||
private:
|
||||
typedef AABBTraits AABB_traits;
|
||||
typedef AABB_node<AABB_traits> Node;
|
||||
|
|
@ -210,76 +194,6 @@ AABB_node<Tr>::traversal(const Query& query,
|
|||
}
|
||||
}
|
||||
|
||||
template<typename Tr>
|
||||
template<class Traversal_traits>
|
||||
void
|
||||
AABB_node<Tr>::traversal(const AABB_node &other_node,
|
||||
Traversal_traits &traits,
|
||||
const std::size_t nb_primitives,
|
||||
const std::size_t nb_primitives_other,
|
||||
bool first_stationary) const
|
||||
{
|
||||
if (nb_primitives >= nb_primitives_other)
|
||||
{
|
||||
switch(nb_primitives)
|
||||
{
|
||||
case 2: // Both trees contain 2 primitives, test all pairs
|
||||
traits.intersection(left_data(), other_node.left_data(), first_stationary);
|
||||
if (!traits.go_further()) return;
|
||||
traits.intersection(right_data(), other_node.right_data(), first_stationary);
|
||||
if (!traits.go_further()) return;
|
||||
traits.intersection(right_data(), other_node.left_data(), first_stationary);
|
||||
if (!traits.go_further()) return;
|
||||
traits.intersection(left_data(), other_node.right_data(), first_stationary);
|
||||
break;
|
||||
|
||||
case 3: // This tree contains 3 primitives, the other 3 or 2
|
||||
// Both left children are primitives:
|
||||
traits.intersection(left_data(), other_node.left_data(), first_stationary);
|
||||
if (!traits.go_further()) return;
|
||||
|
||||
// Test left child against all right leaves of the other tree
|
||||
if (nb_primitives_other == 2)
|
||||
{
|
||||
traits.intersection(left_data(), other_node.right_data(), first_stationary);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (traits.do_intersect(left_data(), other_node.right_child(), first_stationary))
|
||||
{
|
||||
traits.intersection(left_data(), other_node.right_child().left_data(), first_stationary);
|
||||
if (!traits.go_further()) return;
|
||||
traits.intersection(left_data(), other_node.right_child().right_data(), first_stationary);
|
||||
}
|
||||
}
|
||||
if (!traits.go_further()) return;
|
||||
|
||||
// Test right child against the other node
|
||||
if(traits.do_intersect(right_child(), other_node, first_stationary))
|
||||
{
|
||||
right_child().traversal(other_node, traits, 2, nb_primitives_other, first_stationary);
|
||||
}
|
||||
break;
|
||||
|
||||
default: // This tree has two node-children, test both against the other node
|
||||
if( traits.do_intersect(left_child(), other_node, first_stationary) )
|
||||
{
|
||||
left_child().traversal(other_node, traits, nb_primitives/2, nb_primitives_other, first_stationary);
|
||||
}
|
||||
if (!traits.go_further()) return;
|
||||
if( traits.do_intersect(right_child(), other_node, first_stationary) )
|
||||
{
|
||||
right_child().traversal(other_node, traits, nb_primitives-nb_primitives/2, nb_primitives_other, first_stationary);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// The other node contains more primitives. Call this method the other way around:
|
||||
other_node.traversal(*this, traits, nb_primitives_other, nb_primitives, !first_stationary);
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace CGAL
|
||||
|
||||
#endif // CGAL_AABB_NODE_H
|
||||
|
|
|
|||
|
|
@ -284,90 +284,6 @@ private:
|
|||
};
|
||||
|
||||
|
||||
/**
|
||||
* @class Do_intersect_joined_traits
|
||||
*/
|
||||
template<typename AABBTraits>
|
||||
class Do_intersect_joined_traits
|
||||
{
|
||||
typedef typename AABBTraits::Point_3 Point;
|
||||
typedef typename AABBTraits::Primitive Primitive;
|
||||
typedef AABB_node<AABBTraits> Node;
|
||||
|
||||
public:
|
||||
|
||||
Do_intersect_joined_traits(const Point &point) : m_is_found(false)
|
||||
{
|
||||
m_traits_ptr = new AABBTraits(point);
|
||||
}
|
||||
|
||||
bool go_further() const { return !m_is_found; }
|
||||
|
||||
void intersection(const Primitive &primitive1, const Primitive &primitive2, bool first_stationary)
|
||||
{
|
||||
if (first_stationary)
|
||||
{
|
||||
if (m_traits_ptr->do_intersect_object()(primitive1, primitive2))
|
||||
{
|
||||
m_is_found = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_traits_ptr->do_intersect_object()(primitive2, primitive1))
|
||||
{
|
||||
m_is_found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool do_intersect(const Node &node_1, const Node &node_2, bool first_stationary) const
|
||||
{
|
||||
if (first_stationary)
|
||||
{
|
||||
return m_traits_ptr->do_intersect_object()(node_1.bbox(), node_2.bbox());
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_traits_ptr->do_intersect_object()(node_2.bbox(), node_1.bbox());
|
||||
}
|
||||
}
|
||||
|
||||
bool do_intersect(const Node &node_1, const Primitive &primitive2, bool first_stationary) const
|
||||
{
|
||||
if (first_stationary)
|
||||
{
|
||||
return m_traits_ptr->do_intersect_object()(node_1.bbox(), primitive2);
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_traits_ptr->do_intersect_object()(primitive2, node_1.bbox());
|
||||
}
|
||||
}
|
||||
|
||||
bool do_intersect(const Primitive &primitive1, const Node &node_2, bool first_stationary) const
|
||||
{
|
||||
if (first_stationary)
|
||||
{
|
||||
return m_traits_ptr->do_intersect_object()(primitive1, node_2.bbox());
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_traits_ptr->do_intersect_object()(node_2.bbox(), primitive1);
|
||||
}
|
||||
}
|
||||
|
||||
bool is_intersection_found() const { return m_is_found; }
|
||||
|
||||
~Do_intersect_joined_traits() { delete m_traits_ptr; }
|
||||
|
||||
private:
|
||||
|
||||
bool m_is_found;
|
||||
AABBTraits *m_traits_ptr;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @class Projection_traits
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef CGAL_AABB_COLLISION_DETECTOR_2_H
|
||||
#define CGAL_AABB_COLLISION_DETECTOR_2_H
|
||||
|
||||
#include <CGAL/AABB_tree.h>
|
||||
#include <CGAL/Minkowski_sum_2/AABB_tree_with_join.h>
|
||||
#include <CGAL/Minkowski_sum_2/AABB_traits_2.h>
|
||||
#include <CGAL/Minkowski_sum_2/AABB_segment_2_primitive.h>
|
||||
|
||||
|
|
@ -21,7 +21,7 @@ public:
|
|||
typedef AABB_segment_2_primitive<Kernel_, Edge_iterator, Polygon_2>
|
||||
Tree_segment_2;
|
||||
typedef AABB_traits_2<Kernel_, Tree_segment_2> Tree_traits;
|
||||
typedef AABB_tree<Tree_traits> Tree_2;
|
||||
typedef AABB_tree_with_join<Tree_traits> Tree_2;
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,285 @@
|
|||
// Copyright (c) 2008 INRIA Sophia-Antipolis (France).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org).
|
||||
// You can redistribute it and/or modify it under the terms of the GNU
|
||||
// General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
//
|
||||
//
|
||||
// Author(s) : Camille Wormser, Pierre Alliez, Stephane Tayeb
|
||||
|
||||
#ifndef CGAL_AABB_NODE_WITH_JOIN_H
|
||||
#define CGAL_AABB_NODE_WITH_JOIN_H
|
||||
|
||||
#include <CGAL/Profile_counter.h>
|
||||
#include <CGAL/Cartesian_converter.h>
|
||||
#include <CGAL/intersections.h>
|
||||
#include <CGAL/Bbox_3.h>
|
||||
#include <vector>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
/**
|
||||
* @class AABB_node_with_join
|
||||
*
|
||||
*
|
||||
*/
|
||||
template<typename AABBTraits>
|
||||
class AABB_node_with_join
|
||||
{
|
||||
public:
|
||||
typedef typename AABBTraits::Bounding_box Bounding_box;
|
||||
|
||||
/// Constructor
|
||||
AABB_node_with_join()
|
||||
: m_bbox()
|
||||
, m_p_left_child(NULL)
|
||||
, m_p_right_child(NULL) { };
|
||||
|
||||
/// Non virtual Destructor
|
||||
/// Do not delete children because the tree hosts and delete them
|
||||
~AABB_node_with_join() { };
|
||||
|
||||
/// Returns the bounding box of the node
|
||||
const Bounding_box& bbox() const { return m_bbox; }
|
||||
|
||||
/**
|
||||
* @brief Builds the tree by recursive expansion.
|
||||
* @param first the first primitive to insert
|
||||
* @param last the last primitive to insert
|
||||
* @param range the number of primitive of the range
|
||||
*
|
||||
* [first,last[ is the range of primitives to be added to the tree.
|
||||
*/
|
||||
template<typename ConstPrimitiveIterator>
|
||||
void expand(ConstPrimitiveIterator first,
|
||||
ConstPrimitiveIterator beyond,
|
||||
const std::size_t range,
|
||||
const AABBTraits&);
|
||||
|
||||
/**
|
||||
* @brief General traversal query
|
||||
* @param query the query
|
||||
* @param traits the traversal traits that define the traversal behaviour
|
||||
* @param nb_primitives the number of primitive
|
||||
*
|
||||
* General traversal query. The traits class allows using it for the various
|
||||
* traversal methods we need: listing, counting, detecting intersections,
|
||||
* drawing the boxes.
|
||||
*/
|
||||
template<class Traversal_traits, class Query>
|
||||
void traversal(const Query& query,
|
||||
Traversal_traits& traits,
|
||||
const std::size_t nb_primitives) const;
|
||||
|
||||
/**
|
||||
* @param other_node root node of a tree which we want to traverse in parallel
|
||||
* @param traits the traversal traits that define the traversal behaviour
|
||||
* @param nb_primitives the number of primitives in this tree
|
||||
* @param nb_primitives_other the number of primitives in the other tree
|
||||
* @param first_stationary if true, the other_node is the translatable tree's root
|
||||
*
|
||||
* General traversal query for two trees.
|
||||
*/
|
||||
template<class Traversal_traits>
|
||||
void traversal(const AABB_node_with_join &other_node,
|
||||
Traversal_traits &traits,
|
||||
const std::size_t nb_primitives,
|
||||
const std::size_t nb_primitives_other,
|
||||
bool first_stationary) const;
|
||||
|
||||
private:
|
||||
typedef AABBTraits AABB_traits;
|
||||
typedef AABB_node_with_join<AABB_traits> Node;
|
||||
typedef typename AABB_traits::Primitive Primitive;
|
||||
|
||||
/// Helper functions
|
||||
const Node& left_child() const
|
||||
{ return *static_cast<Node*>(m_p_left_child); }
|
||||
const Node& right_child() const
|
||||
{ return *static_cast<Node*>(m_p_right_child); }
|
||||
const Primitive& left_data() const
|
||||
{ return *static_cast<Primitive*>(m_p_left_child); }
|
||||
const Primitive& right_data() const
|
||||
{ return *static_cast<Primitive*>(m_p_right_child); }
|
||||
|
||||
Node& left_child() { return *static_cast<Node*>(m_p_left_child); }
|
||||
Node& right_child() { return *static_cast<Node*>(m_p_right_child); }
|
||||
Primitive& left_data() { return *static_cast<Primitive*>(m_p_left_child); }
|
||||
Primitive& right_data() { return *static_cast<Primitive*>(m_p_right_child); }
|
||||
|
||||
private:
|
||||
/// node bounding box
|
||||
Bounding_box m_bbox;
|
||||
|
||||
/// children nodes, either pointing towards children (if children are not leaves),
|
||||
/// or pointing toward input primitives (if children are leaves).
|
||||
void *m_p_left_child;
|
||||
void *m_p_right_child;
|
||||
|
||||
private:
|
||||
// Disabled copy constructor & assignment operator
|
||||
typedef AABB_node_with_join<AABBTraits> Self;
|
||||
AABB_node_with_join(const Self& src);
|
||||
Self& operator=(const Self& src);
|
||||
|
||||
}; // end class AABB_node_with_join
|
||||
|
||||
|
||||
template<typename Tr>
|
||||
template<typename ConstPrimitiveIterator>
|
||||
void
|
||||
AABB_node_with_join<Tr>::expand(ConstPrimitiveIterator first,
|
||||
ConstPrimitiveIterator beyond,
|
||||
const std::size_t range,
|
||||
const Tr& traits)
|
||||
{
|
||||
m_bbox = traits.compute_bbox_object()(first, beyond);
|
||||
|
||||
// sort primitives along longest axis aabb
|
||||
traits.sort_primitives_object()(first, beyond, m_bbox);
|
||||
|
||||
switch(range)
|
||||
{
|
||||
case 2:
|
||||
m_p_left_child = &(*first);
|
||||
m_p_right_child = &(*(++first));
|
||||
break;
|
||||
case 3:
|
||||
m_p_left_child = &(*first);
|
||||
m_p_right_child = static_cast<Node*>(this)+1;
|
||||
right_child().expand(first+1, beyond, 2,traits);
|
||||
break;
|
||||
default:
|
||||
const std::size_t new_range = range/2;
|
||||
m_p_left_child = static_cast<Node*>(this) + 1;
|
||||
m_p_right_child = static_cast<Node*>(this) + new_range;
|
||||
left_child().expand(first, first + new_range, new_range,traits);
|
||||
right_child().expand(first + new_range, beyond, range - new_range,traits);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename Tr>
|
||||
template<class Traversal_traits, class Query>
|
||||
void
|
||||
AABB_node_with_join<Tr>::traversal(const Query& query,
|
||||
Traversal_traits& traits,
|
||||
const std::size_t nb_primitives) const
|
||||
{
|
||||
// Recursive traversal
|
||||
switch(nb_primitives)
|
||||
{
|
||||
case 2:
|
||||
traits.intersection(query, left_data());
|
||||
if( traits.go_further() )
|
||||
{
|
||||
traits.intersection(query, right_data());
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
traits.intersection(query, left_data());
|
||||
if( traits.go_further() && traits.do_intersect(query, right_child()) )
|
||||
{
|
||||
right_child().traversal(query, traits, 2);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if( traits.do_intersect(query, left_child()) )
|
||||
{
|
||||
left_child().traversal(query, traits, nb_primitives/2);
|
||||
if( traits.go_further() && traits.do_intersect(query, right_child()) )
|
||||
{
|
||||
right_child().traversal(query, traits, nb_primitives-nb_primitives/2);
|
||||
}
|
||||
}
|
||||
else if( traits.do_intersect(query, right_child()) )
|
||||
{
|
||||
right_child().traversal(query, traits, nb_primitives-nb_primitives/2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Tr>
|
||||
template<class Traversal_traits>
|
||||
void
|
||||
AABB_node_with_join<Tr>::traversal(const AABB_node_with_join &other_node,
|
||||
Traversal_traits &traits,
|
||||
const std::size_t nb_primitives,
|
||||
const std::size_t nb_primitives_other,
|
||||
bool first_stationary) const
|
||||
{
|
||||
if (nb_primitives >= nb_primitives_other)
|
||||
{
|
||||
switch(nb_primitives)
|
||||
{
|
||||
case 2: // Both trees contain 2 primitives, test all pairs
|
||||
traits.intersection(left_data(), other_node.left_data(), first_stationary);
|
||||
if (!traits.go_further()) return;
|
||||
traits.intersection(right_data(), other_node.right_data(), first_stationary);
|
||||
if (!traits.go_further()) return;
|
||||
traits.intersection(right_data(), other_node.left_data(), first_stationary);
|
||||
if (!traits.go_further()) return;
|
||||
traits.intersection(left_data(), other_node.right_data(), first_stationary);
|
||||
break;
|
||||
|
||||
case 3: // This tree contains 3 primitives, the other 3 or 2
|
||||
// Both left children are primitives:
|
||||
traits.intersection(left_data(), other_node.left_data(), first_stationary);
|
||||
if (!traits.go_further()) return;
|
||||
|
||||
// Test left child against all right leaves of the other tree
|
||||
if (nb_primitives_other == 2)
|
||||
{
|
||||
traits.intersection(left_data(), other_node.right_data(), first_stationary);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (traits.do_intersect(left_data(), other_node.right_child(), first_stationary))
|
||||
{
|
||||
traits.intersection(left_data(), other_node.right_child().left_data(), first_stationary);
|
||||
if (!traits.go_further()) return;
|
||||
traits.intersection(left_data(), other_node.right_child().right_data(), first_stationary);
|
||||
}
|
||||
}
|
||||
if (!traits.go_further()) return;
|
||||
|
||||
// Test right child against the other node
|
||||
if(traits.do_intersect(right_child(), other_node, first_stationary))
|
||||
{
|
||||
right_child().traversal(other_node, traits, 2, nb_primitives_other, first_stationary);
|
||||
}
|
||||
break;
|
||||
|
||||
default: // This tree has two node-children, test both against the other node
|
||||
if( traits.do_intersect(left_child(), other_node, first_stationary) )
|
||||
{
|
||||
left_child().traversal(other_node, traits, nb_primitives/2, nb_primitives_other, first_stationary);
|
||||
}
|
||||
if (!traits.go_further()) return;
|
||||
if( traits.do_intersect(right_child(), other_node, first_stationary) )
|
||||
{
|
||||
right_child().traversal(other_node, traits, nb_primitives-nb_primitives/2, nb_primitives_other, first_stationary);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// The other node contains more primitives. Call this method the other way around:
|
||||
other_node.traversal(*this, traits, nb_primitives_other, nb_primitives, !first_stationary);
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace CGAL
|
||||
|
||||
#endif // CGAL_AABB_NODE_WITH_JOIN_H
|
||||
|
|
@ -0,0 +1,428 @@
|
|||
// Copyright (c) 2008-2009 INRIA Sophia-Antipolis (France).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org).
|
||||
// You can redistribute it and/or modify it under the terms of the GNU
|
||||
// General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
//
|
||||
//
|
||||
// Author(s) : Camille Wormser, Pierre Alliez, Stephane Tayeb
|
||||
|
||||
#ifndef CGAL_AABB_TRAVERSAL_TRAITS_WITH_JOIN_H
|
||||
#define CGAL_AABB_TRAVERSAL_TRAITS_WITH_JOIN_H
|
||||
|
||||
#include <CGAL/Minkowski_sum_2/AABB_node_with_join.h>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
namespace internal { namespace AABB_tree_with_join {
|
||||
|
||||
template <class Value_type, typename Integral_type>
|
||||
class Counting_output_iterator {
|
||||
typedef Counting_output_iterator<Value_type,Integral_type> Self;
|
||||
Integral_type* i;
|
||||
public:
|
||||
Counting_output_iterator(Integral_type* i_) : i(i_) {};
|
||||
|
||||
struct Proxy {
|
||||
Proxy& operator=(const Value_type&) { return *this; };
|
||||
};
|
||||
|
||||
Proxy operator*() {
|
||||
return Proxy();
|
||||
}
|
||||
|
||||
Self& operator++() {
|
||||
++*i;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Self& operator++(int) {
|
||||
++*i;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Traits classes for traversal computation
|
||||
//-------------------------------------------------------
|
||||
/**
|
||||
* @class First_intersection_traits
|
||||
*/
|
||||
template<typename AABBTraits, typename Query>
|
||||
class First_intersection_traits
|
||||
{
|
||||
typedef typename AABBTraits::FT FT;
|
||||
typedef typename AABBTraits::Point_3 Point;
|
||||
typedef typename AABBTraits::Primitive Primitive;
|
||||
typedef typename AABBTraits::Bounding_box Bounding_box;
|
||||
typedef typename AABBTraits::Primitive::Id Primitive_id;
|
||||
typedef typename AABBTraits::Point_and_primitive_id Point_and_primitive_id;
|
||||
typedef typename AABBTraits::Object_and_primitive_id Object_and_primitive_id;
|
||||
typedef ::CGAL::AABB_node_with_join<AABBTraits> Node;
|
||||
|
||||
public:
|
||||
typedef
|
||||
#if CGAL_INTERSECTION_VERSION < 2
|
||||
boost::optional<Object_and_primitive_id>
|
||||
#else
|
||||
boost::optional< typename AABBTraits::template Intersection_and_primitive_id<Query>::Type >
|
||||
#endif
|
||||
Result;
|
||||
public:
|
||||
First_intersection_traits(const AABBTraits& traits)
|
||||
: m_result(), m_traits(traits)
|
||||
{}
|
||||
|
||||
bool go_further() const {
|
||||
return !m_result;
|
||||
}
|
||||
|
||||
void intersection(const Query& query, const Primitive& primitive)
|
||||
{
|
||||
m_result = m_traits.intersection_object()(query, primitive);
|
||||
}
|
||||
|
||||
bool do_intersect(const Query& query, const Node& node) const
|
||||
{
|
||||
return m_traits.do_intersect_object()(query, node.bbox());
|
||||
}
|
||||
|
||||
Result result() const { return m_result; }
|
||||
bool is_intersection_found() const {
|
||||
return m_result;
|
||||
}
|
||||
|
||||
private:
|
||||
Result m_result;
|
||||
const AABBTraits& m_traits;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @class Listing_intersection_traits
|
||||
*/
|
||||
template<typename AABBTraits, typename Query, typename Output_iterator>
|
||||
class Listing_intersection_traits
|
||||
{
|
||||
typedef typename AABBTraits::FT FT;
|
||||
typedef typename AABBTraits::Point_3 Point;
|
||||
typedef typename AABBTraits::Primitive Primitive;
|
||||
typedef typename AABBTraits::Bounding_box Bounding_box;
|
||||
typedef typename AABBTraits::Primitive::Id Primitive_id;
|
||||
typedef typename AABBTraits::Point_and_primitive_id Point_and_primitive_id;
|
||||
typedef typename AABBTraits::Object_and_primitive_id Object_and_primitive_id;
|
||||
typedef ::CGAL::AABB_node_with_join<AABBTraits> Node;
|
||||
|
||||
public:
|
||||
Listing_intersection_traits(Output_iterator out_it, const AABBTraits& traits)
|
||||
: m_out_it(out_it), m_traits(traits) {}
|
||||
|
||||
bool go_further() const { return true; }
|
||||
|
||||
void intersection(const Query& query, const Primitive& primitive)
|
||||
{
|
||||
#if CGAL_INTERSECTION_VERSION < 2
|
||||
boost::optional<Object_and_primitive_id>
|
||||
#else
|
||||
boost::optional< typename AABBTraits::template Intersection_and_primitive_id<Query>::Type >
|
||||
#endif
|
||||
intersection = m_traits.intersection_object()(query, primitive);
|
||||
|
||||
if(intersection)
|
||||
{
|
||||
*m_out_it++ = *intersection;
|
||||
}
|
||||
}
|
||||
|
||||
bool do_intersect(const Query& query, const Node& node) const
|
||||
{
|
||||
return m_traits.do_intersect_object()(query, node.bbox());
|
||||
}
|
||||
|
||||
private:
|
||||
Output_iterator m_out_it;
|
||||
const AABBTraits& m_traits;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @class Listing_primitive_traits
|
||||
*/
|
||||
template<typename AABBTraits, typename Query, typename Output_iterator>
|
||||
class Listing_primitive_traits
|
||||
{
|
||||
typedef typename AABBTraits::FT FT;
|
||||
typedef typename AABBTraits::Point_3 Point;
|
||||
typedef typename AABBTraits::Primitive Primitive;
|
||||
typedef typename AABBTraits::Bounding_box Bounding_box;
|
||||
typedef typename AABBTraits::Primitive::Id Primitive_id;
|
||||
typedef typename AABBTraits::Point_and_primitive_id Point_and_primitive_id;
|
||||
typedef typename AABBTraits::Object_and_primitive_id Object_and_primitive_id;
|
||||
typedef ::CGAL::AABB_node_with_join<AABBTraits> Node;
|
||||
|
||||
public:
|
||||
Listing_primitive_traits(Output_iterator out_it, const AABBTraits& traits)
|
||||
: m_out_it(out_it), m_traits(traits) {}
|
||||
|
||||
bool go_further() const { return true; }
|
||||
|
||||
void intersection(const Query& query, const Primitive& primitive)
|
||||
{
|
||||
if( m_traits.do_intersect_object()(query, primitive) )
|
||||
{
|
||||
*m_out_it++ = primitive.id();
|
||||
}
|
||||
}
|
||||
|
||||
bool do_intersect(const Query& query, const Node& node) const
|
||||
{
|
||||
return m_traits.do_intersect_object()(query, node.bbox());
|
||||
}
|
||||
|
||||
private:
|
||||
Output_iterator m_out_it;
|
||||
const AABBTraits& m_traits;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @class First_primitive_traits
|
||||
*/
|
||||
template<typename AABBTraits, typename Query>
|
||||
class First_primitive_traits
|
||||
{
|
||||
typedef typename AABBTraits::FT FT;
|
||||
typedef typename AABBTraits::Point_3 Point;
|
||||
typedef typename AABBTraits::Primitive Primitive;
|
||||
typedef typename AABBTraits::Bounding_box Bounding_box;
|
||||
typedef typename AABBTraits::Primitive::Id Primitive_id;
|
||||
typedef typename AABBTraits::Point_and_primitive_id Point_and_primitive_id;
|
||||
typedef typename AABBTraits::Object_and_primitive_id Object_and_primitive_id;
|
||||
typedef ::CGAL::AABB_node_with_join<AABBTraits> Node;
|
||||
|
||||
public:
|
||||
First_primitive_traits(const AABBTraits& traits)
|
||||
: m_is_found(false)
|
||||
, m_result()
|
||||
, m_traits(traits) {}
|
||||
|
||||
bool go_further() const { return !m_is_found; }
|
||||
|
||||
void intersection(const Query& query, const Primitive& primitive)
|
||||
{
|
||||
if( m_traits.do_intersect_object()(query, primitive) )
|
||||
{
|
||||
m_result = boost::optional<typename Primitive::Id>(primitive.id());
|
||||
m_is_found = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool do_intersect(const Query& query, const Node& node) const
|
||||
{
|
||||
return m_traits.do_intersect_object()(query, node.bbox());
|
||||
}
|
||||
|
||||
boost::optional<typename Primitive::Id> result() const { return m_result; }
|
||||
bool is_intersection_found() const { return m_is_found; }
|
||||
|
||||
private:
|
||||
bool m_is_found;
|
||||
boost::optional<typename Primitive::Id> m_result;
|
||||
const AABBTraits& m_traits;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class Do_intersect_traits
|
||||
*/
|
||||
template<typename AABBTraits, typename Query>
|
||||
class Do_intersect_traits
|
||||
{
|
||||
typedef typename AABBTraits::FT FT;
|
||||
typedef typename AABBTraits::Point_3 Point;
|
||||
typedef typename AABBTraits::Primitive Primitive;
|
||||
typedef typename AABBTraits::Bounding_box Bounding_box;
|
||||
typedef typename AABBTraits::Primitive::Id Primitive_id;
|
||||
typedef typename AABBTraits::Point_and_primitive_id Point_and_primitive_id;
|
||||
typedef typename AABBTraits::Object_and_primitive_id Object_and_primitive_id;
|
||||
typedef ::CGAL::AABB_node_with_join<AABBTraits> Node;
|
||||
|
||||
public:
|
||||
Do_intersect_traits(const AABBTraits& traits)
|
||||
: m_is_found(false), m_traits(traits)
|
||||
{}
|
||||
|
||||
bool go_further() const { return !m_is_found; }
|
||||
|
||||
void intersection(const Query& query, const Primitive& primitive)
|
||||
{
|
||||
if( m_traits.do_intersect_object()(query, primitive) )
|
||||
m_is_found = true;
|
||||
}
|
||||
|
||||
bool do_intersect(const Query& query, const Node& node) const
|
||||
{
|
||||
return m_traits.do_intersect_object()(query, node.bbox());
|
||||
}
|
||||
|
||||
bool is_intersection_found() const { return m_is_found; }
|
||||
|
||||
private:
|
||||
bool m_is_found;
|
||||
const AABBTraits& m_traits;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @class Do_intersect_joined_traits
|
||||
*/
|
||||
template<typename AABBTraits>
|
||||
class Do_intersect_joined_traits
|
||||
{
|
||||
typedef typename AABBTraits::Point_3 Point;
|
||||
typedef typename AABBTraits::Primitive Primitive;
|
||||
typedef AABB_node_with_join<AABBTraits> Node;
|
||||
|
||||
public:
|
||||
|
||||
Do_intersect_joined_traits(const Point &point) : m_is_found(false)
|
||||
{
|
||||
m_traits_ptr = new AABBTraits(point);
|
||||
}
|
||||
|
||||
bool go_further() const { return !m_is_found; }
|
||||
|
||||
void intersection(const Primitive &primitive1, const Primitive &primitive2, bool first_stationary)
|
||||
{
|
||||
if (first_stationary)
|
||||
{
|
||||
if (m_traits_ptr->do_intersect_object()(primitive1, primitive2))
|
||||
{
|
||||
m_is_found = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_traits_ptr->do_intersect_object()(primitive2, primitive1))
|
||||
{
|
||||
m_is_found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool do_intersect(const Node &node_1, const Node &node_2, bool first_stationary) const
|
||||
{
|
||||
if (first_stationary)
|
||||
{
|
||||
return m_traits_ptr->do_intersect_object()(node_1.bbox(), node_2.bbox());
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_traits_ptr->do_intersect_object()(node_2.bbox(), node_1.bbox());
|
||||
}
|
||||
}
|
||||
|
||||
bool do_intersect(const Node &node_1, const Primitive &primitive2, bool first_stationary) const
|
||||
{
|
||||
if (first_stationary)
|
||||
{
|
||||
return m_traits_ptr->do_intersect_object()(node_1.bbox(), primitive2);
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_traits_ptr->do_intersect_object()(primitive2, node_1.bbox());
|
||||
}
|
||||
}
|
||||
|
||||
bool do_intersect(const Primitive &primitive1, const Node &node_2, bool first_stationary) const
|
||||
{
|
||||
if (first_stationary)
|
||||
{
|
||||
return m_traits_ptr->do_intersect_object()(primitive1, node_2.bbox());
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_traits_ptr->do_intersect_object()(node_2.bbox(), primitive1);
|
||||
}
|
||||
}
|
||||
|
||||
bool is_intersection_found() const { return m_is_found; }
|
||||
|
||||
~Do_intersect_joined_traits() { delete m_traits_ptr; }
|
||||
|
||||
private:
|
||||
|
||||
bool m_is_found;
|
||||
AABBTraits *m_traits_ptr;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @class Projection_traits
|
||||
*/
|
||||
template <typename AABBTraits>
|
||||
class Projection_traits
|
||||
{
|
||||
typedef typename AABBTraits::FT FT;
|
||||
typedef typename AABBTraits::Point_3 Point;
|
||||
typedef typename AABBTraits::Primitive Primitive;
|
||||
typedef typename AABBTraits::Bounding_box Bounding_box;
|
||||
typedef typename AABBTraits::Primitive::Id Primitive_id;
|
||||
typedef typename AABBTraits::Point_and_primitive_id Point_and_primitive_id;
|
||||
typedef typename AABBTraits::Object_and_primitive_id Object_and_primitive_id;
|
||||
typedef ::CGAL::AABB_node_with_join<AABBTraits> Node;
|
||||
|
||||
public:
|
||||
Projection_traits(const Point& hint,
|
||||
const typename Primitive::Id& hint_primitive,
|
||||
const AABBTraits& traits)
|
||||
: m_closest_point(hint),
|
||||
m_closest_primitive(hint_primitive),
|
||||
m_traits(traits)
|
||||
{}
|
||||
|
||||
bool go_further() const { return true; }
|
||||
|
||||
void intersection(const Point& query, const Primitive& primitive)
|
||||
{
|
||||
Point new_closest_point = m_traits.closest_point_object()
|
||||
(query, primitive, m_closest_point);
|
||||
if(new_closest_point != m_closest_point)
|
||||
{
|
||||
m_closest_primitive = primitive.id();
|
||||
m_closest_point = new_closest_point; // this effectively shrinks the sphere
|
||||
}
|
||||
}
|
||||
|
||||
bool do_intersect(const Point& query, const Node& node) const
|
||||
{
|
||||
return m_traits.compare_distance_object()
|
||||
(query, node.bbox(), m_closest_point) == CGAL::SMALLER;
|
||||
}
|
||||
|
||||
Point closest_point() const { return m_closest_point; }
|
||||
Point_and_primitive_id closest_point_and_primitive() const
|
||||
{
|
||||
return Point_and_primitive_id(m_closest_point, m_closest_primitive);
|
||||
}
|
||||
|
||||
private:
|
||||
Point m_closest_point;
|
||||
typename Primitive::Id m_closest_primitive;
|
||||
const AABBTraits& m_traits;
|
||||
};
|
||||
|
||||
}}} // end namespace CGAL::internal::AABB_tree_with_join
|
||||
|
||||
#endif // CGAL_AABB_TRAVERSAL_TRAITS_WITH_JOIN_H
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue