changing dimension and degree in orthtree(_traits) to int

This commit is contained in:
Sven Oesau 2024-01-30 16:47:53 +01:00
parent 546c0c842a
commit 11f0a842de
11 changed files with 71 additions and 76 deletions

View File

@ -6,9 +6,9 @@
template parameter of the `CGAL::Orthtree` class. template parameter of the `CGAL::Orthtree` class.
\cgalHasModelsBegin \cgalHasModelsBegin
\cgalHasModels{CGAL::Orthtree_traits_point<GeomTraits, PointRange, PointMap, DimensionTag>} \cgalHasModels{CGAL::Orthtree_traits_point<GeomTraits, PointRange, PointMap, dimension >}
\cgalHasModels{CGAL::Orthtree_traits_face_graph<PolygonMesh, VPM>} \cgalHasModels{CGAL::Orthtree_traits_face_graph<PolygonMesh, VPM>}
\cgalHasModels{CGAL::Orthtree_traits_base_for_dimension< K, DimensionTag >} \cgalHasModels{CGAL::Orthtree_traits_base_for_dimension< K, dimension >}
\cgalHasModelsEnd \cgalHasModelsEnd
*/ */
class OrthtreeTraits class OrthtreeTraits
@ -18,7 +18,7 @@ public:
/// \name Types /// \name Types
/// @{ /// @{
using Node_index = unspecified_type; ///< An integer type for nodes using Node_index = unspecified_type; ///< An integer type for nodes
using Dimension = unspecified_type; ///< Dimension type (see `CGAL::Dimension_tag`). constexpr int dimension; ///< Dimension.
using FT = unspecified_type; ///< The number type of the %Cartesian coordinates of types `Point_d` using FT = unspecified_type; ///< The number type of the %Cartesian coordinates of types `Point_d`
using Point_d = unspecified_type; ///< Point type. using Point_d = unspecified_type; ///< Point type.
using Bbox_d = unspecified_type; ///< Bounding box type. Must be constructible from a pair of `Point_d` types. using Bbox_d = unspecified_type; ///< Bounding box type. Must be constructible from a pair of `Point_d` types.

View File

@ -7,12 +7,12 @@
#include <CGAL/Random.h> #include <CGAL/Random.h>
// Type Declarations // Type Declarations
using Dimension = CGAL::Dimension_tag<4>; const int dimension = 4;
using Kernel = CGAL::Epick_d<Dimension>; using Kernel = CGAL::Epick_d<CGAL::Dimension_tag<dimension> >;
using Point_d = Kernel::Point_d; using Point_d = Kernel::Point_d;
using Point_vector = std::vector<Point_d>; using Point_vector = std::vector<Point_d>;
using Traits = CGAL::Orthtree_traits_point<Kernel, Point_vector>; using Traits = CGAL::Orthtree_traits_point<Kernel, Point_vector>;
using Traits2 = CGAL::Orthtree_traits_point<Kernel, Point_vector, CGAL::Identity_property_map<typename std::iterator_traits<typename Point_vector::iterator>::value_type>, CGAL::Dimension_tag<4>>; using Traits2 = CGAL::Orthtree_traits_point<Kernel, Point_vector, CGAL::Identity_property_map<typename std::iterator_traits<typename Point_vector::iterator>::value_type>, dimension>;
using Orthtree = CGAL::Orthtree<Traits2>; using Orthtree = CGAL::Orthtree<Traits2>;
int main() int main()
@ -22,7 +22,7 @@ int main()
Point_vector points_dd; Point_vector points_dd;
for (std::size_t i = 0; i < 500; ++ i) for (std::size_t i = 0; i < 500; ++ i)
{ {
std::array<double, Dimension::value> init{}; std::array<double, dimension> init{};
for (double& v : init) for (double& v : init)
v = r.get_double(-1., 1.); v = r.get_double(-1., 1.);
points_dd.emplace_back (init.begin(), init.end()); points_dd.emplace_back (init.begin(), init.end());

View File

@ -13,10 +13,10 @@ namespace CGAL {
struct empty_type { struct empty_type {
}; };
template <typename K, typename DimensionTag> template <typename K, int dimension>
struct Orthtree_traits_empty : public Orthtree_traits_base_for_dimension<K, DimensionTag> { struct Orthtree_traits_empty : public Orthtree_traits_base_for_dimension<K, dimension> {
using Self = Orthtree_traits_empty<K, DimensionTag>; using Self = Orthtree_traits_empty<K, dimension>;
using Tree = Orthtree<Self>; using Tree = Orthtree<Self>;
using Node_data = std::array<empty_type, 0>; using Node_data = std::array<empty_type, 0>;
@ -40,7 +40,7 @@ private:
}; };
} }
using EmptyQuadtree = CGAL::Orthtree<CGAL::Orthtree_traits_empty<Kernel, CGAL::Dimension_tag<2>>>; using EmptyQuadtree = CGAL::Orthtree<CGAL::Orthtree_traits_empty<Kernel, 2 >>;
int main() { int main() {

View File

@ -33,7 +33,7 @@ template <
typename PointRange, typename PointRange,
typename PointMap = Identity_property_map<typename std::iterator_traits<typename PointRange::iterator>::value_type> typename PointMap = Identity_property_map<typename std::iterator_traits<typename PointRange::iterator>::value_type>
> >
using Octree = Orthtree<Orthtree_traits_point<GeomTraits, PointRange, PointMap, Dimension_tag<3>>>; using Octree = Orthtree<Orthtree_traits_point<GeomTraits, PointRange, PointMap, 3>>;
} // namespace CGAL } // namespace CGAL

View File

@ -26,7 +26,6 @@
#include <CGAL/property_map.h> #include <CGAL/property_map.h>
#include <CGAL/intersections.h> #include <CGAL/intersections.h>
#include <CGAL/squared_distance_3.h> #include <CGAL/squared_distance_3.h>
#include <CGAL/Dimension.h>
#include <CGAL/span.h> #include <CGAL/span.h>
#include <boost/function.hpp> #include <boost/function.hpp>
@ -76,7 +75,7 @@ public:
/// \name Traits Types /// \name Traits Types
/// @{ /// @{
using Dimension = typename Traits::Dimension; ///< Dimension of the tree static constexpr int dimension = Traits::dimension; ///< Dimension of the tree
using Kernel = typename Traits::Kernel; ///< Kernel type. using Kernel = typename Traits::Kernel; ///< Kernel type.
using FT = typename Traits::FT; ///< Number type. using FT = typename Traits::FT; ///< Number type.
using Point = typename Traits::Point_d; ///< Point type. using Point = typename Traits::Point_d; ///< Point type.
@ -99,7 +98,7 @@ public:
/*! /*!
* \brief Degree of the tree (number of children of non-leaf nodes). * \brief Degree of the tree (number of children of non-leaf nodes).
*/ */
using Degree = Dimension_tag<(2 << (Dimension::value - 1))>; static constexpr int degree = (2 << (dimension - 1));
/*! /*!
* \brief Index of a given node in the tree; the root always has index 0. * \brief Index of a given node in the tree; the root always has index 0.
@ -119,7 +118,7 @@ public:
`z` is greater, and so on for higher dimensions if needed. `z` is greater, and so on for higher dimensions if needed.
Used to represent a node's relationship to the center of its parent. Used to represent a node's relationship to the center of its parent.
*/ */
using Local_coordinates = std::bitset<Dimension::value>; using Local_coordinates = std::bitset<dimension>;
/*! /*!
\brief Coordinates representing this node's relationship \brief Coordinates representing this node's relationship
@ -128,7 +127,7 @@ public:
Each value `(x, y, z, ...)` of global coordinates is calculated by doubling Each value `(x, y, z, ...)` of global coordinates is calculated by doubling
the parent's global coordinates and adding the local coordinates. the parent's global coordinates and adding the local coordinates.
*/ */
using Global_coordinates = std::array<std::uint32_t, Dimension::value>; using Global_coordinates = std::array<std::uint32_t, dimension>;
/*! /*!
* \brief A predicate that determines whether a node must be split when refining a tree. * \brief A predicate that determines whether a node must be split when refining a tree.
@ -173,7 +172,7 @@ private: // data members :
Property_array<Maybe_node_index>& m_node_parents; Property_array<Maybe_node_index>& m_node_parents;
Property_array<Maybe_node_index>& m_node_children; Property_array<Maybe_node_index>& m_node_children;
using Bbox_dimensions = std::array<FT, Dimension::value>; using Bbox_dimensions = std::array<FT, dimension>;
Bbox m_bbox; Bbox m_bbox;
std::vector<Bbox_dimensions> m_side_per_depth; /* precomputed (potentially approximated) side length per node's depth */ std::vector<Bbox_dimensions> m_side_per_depth; /* precomputed (potentially approximated) side length per node's depth */
@ -214,7 +213,7 @@ public:
// Determine dimensions of the root bbox // Determine dimensions of the root bbox
Bbox_dimensions size; Bbox_dimensions size;
for (int i = 0; i < Dimension::value; ++i) for (int i = 0; i < dimension; ++i)
{ {
size[i] = (m_bbox.max)()[i] - (m_bbox.min)()[i]; size[i] = (m_bbox.max)()[i] - (m_bbox.min)()[i];
} }
@ -298,7 +297,7 @@ public:
if (!is_leaf(current)) { if (!is_leaf(current)) {
// Process each of its children // Process each of its children
for (int i = 0; i < Degree::value; ++i) for (int i = 0; i < degree; ++i)
todo.push(child(current, i)); todo.push(child(current, i));
} }
} }
@ -381,7 +380,7 @@ public:
split(*neighbor); split(*neighbor);
// Add newly created children to the queue // Add newly created children to the queue
for (int i = 0; i < Degree::value; ++i) { for (int i = 0; i < degree; ++i) {
leaf_nodes.push(child(*neighbor, i)); leaf_nodes.push(child(*neighbor, i));
} }
} }
@ -465,12 +464,12 @@ public:
\return the bounding box of the node n \return the bounding box of the node n
*/ */
Bbox bbox(Node_index n) const { Bbox bbox(Node_index n) const {
using Cartesian_coordinate = std::array<FT, Dimension::value>; using Cartesian_coordinate = std::array<FT, dimension>;
Cartesian_coordinate min_corner, max_corner; Cartesian_coordinate min_corner, max_corner;
std::size_t node_depth = depth(n); std::size_t node_depth = depth(n);
Bbox_dimensions size = m_side_per_depth[node_depth]; Bbox_dimensions size = m_side_per_depth[node_depth];
const std::size_t last_coord = std::pow(2,node_depth)-1; const std::size_t last_coord = std::pow(2,node_depth)-1;
for (int i = 0; i < Dimension::value; i++) { for (int i = 0; i < dimension; i++) {
min_corner[i] = (m_bbox.min)()[i] + int(global_coordinates(n)[i]) * size[i]; min_corner[i] = (m_bbox.min)()[i] + int(global_coordinates(n)[i]) * size[i];
max_corner[i] = std::size_t(global_coordinates(n)[i]) == last_coord max_corner[i] = std::size_t(global_coordinates(n)[i]) == last_coord
? (m_bbox.max)()[i] ? (m_bbox.max)()[i]
@ -585,9 +584,9 @@ public:
// Find the index of the correct sub-node // Find the index of the correct sub-node
Local_coordinates local_coords; Local_coordinates local_coords;
std::size_t dimension = 0; std::size_t dim = 0;
for (const auto& r: cartesian_range(center, point)) for (const auto& r: cartesian_range(center, point))
local_coords[dimension++] = m_traits.locate_halfspace_object()(get<0>(r), get<1>(r)); local_coords[dim++] = m_traits.locate_halfspace_object()(get<0>(r), get<1>(r));
// Find the correct sub-node of the current node // Find the correct sub-node of the current node
node_for_point = child(node_for_point, local_coords.to_ulong()); node_for_point = child(node_for_point, local_coords.to_ulong());
@ -740,7 +739,7 @@ public:
*/ */
Local_coordinates local_coordinates(Node_index n) const { Local_coordinates local_coordinates(Node_index n) const {
Local_coordinates result; Local_coordinates result;
for (std::size_t i = 0; i < Dimension::value; ++i) for (std::size_t i = 0; i < dimension; ++i)
result[i] = global_coordinates(n)[i] & 1; result[i] = global_coordinates(n)[i] & 1;
return result; return result;
} }
@ -826,7 +825,7 @@ public:
std::size_t local_coords = local_coordinates(n).to_ulong(); std::size_t local_coords = local_coordinates(n).to_ulong();
// The last child has no more siblings // The last child has no more siblings
if (int(local_coords) == Degree::value - 1) if (int(local_coords) == degree - 1)
return {}; return {};
// The next sibling is the child of the parent with the following local coordinates // The next sibling is the child of the parent with the following local coordinates
@ -898,7 +897,7 @@ public:
return node; return node;
if (!is_leaf(node)) if (!is_leaf(node))
for (int i = 0; i < Degree::value; ++i) for (int i = 0; i < degree; ++i)
todo.push(child(node, i)); todo.push(child(node, i));
} }
@ -910,7 +909,7 @@ public:
Only leaf nodes should be split. Only leaf nodes should be split.
When a node is split it is no longer a leaf node. When a node is split it is no longer a leaf node.
A number of `Degree::value` children are constructed automatically, and their values are set. The full set of `degree` children are constructed automatically, and their values are set.
Contents of this node are _not_ propagated automatically, this is responsibility of the Contents of this node are _not_ propagated automatically, this is responsibility of the
`distribute_node_contents_object` in the traits class. `distribute_node_contents_object` in the traits class.
@ -923,8 +922,8 @@ public:
// Split the node to create children // Split the node to create children
using Local_coordinates = Local_coordinates; using Local_coordinates = Local_coordinates;
m_node_children[n] = m_node_properties.emplace_group(Degree::value); m_node_children[n] = m_node_properties.emplace_group(degree);
for (std::size_t i = 0; i < Degree::value; i++) { for (std::size_t i = 0; i < degree; i++) {
Node_index c = *m_node_children[n] + i; Node_index c = *m_node_children[n] + i;
@ -932,7 +931,7 @@ public:
CGAL_assertion(n != *m_node_children[n] + i); CGAL_assertion(n != *m_node_children[n] + i);
Local_coordinates local_coordinates{i}; Local_coordinates local_coordinates{i};
for (int i = 0; i < Dimension::value; i++) for (int i = 0; i < dimension; i++)
m_node_coordinates[c][i] = (2 * m_node_coordinates[n][i]) + local_coordinates[i]; m_node_coordinates[c][i] = (2 * m_node_coordinates[n][i]) + local_coordinates[i];
m_node_depths[c] = m_node_depths[n] + 1; m_node_depths[c] = m_node_depths[n] + 1;
m_node_parents[c] = n; m_node_parents[c] = n;
@ -943,7 +942,7 @@ public:
// Update the side length map with the dimensions of the children // Update the side length map with the dimensions of the children
Bbox_dimensions size = m_side_per_depth.back(); Bbox_dimensions size = m_side_per_depth.back();
Bbox_dimensions child_size; Bbox_dimensions child_size;
for (int i = 0; i < Dimension::value; ++i) for (int i = 0; i < dimension; ++i)
child_size[i] = size[i] / FT(2); child_size[i] = size[i] / FT(2);
m_side_per_depth.push_back(child_size); m_side_per_depth.push_back(child_size);
} }
@ -968,8 +967,8 @@ public:
Bbox_dimensions size = m_side_per_depth[depth(n)]; Bbox_dimensions size = m_side_per_depth[depth(n)];
// Determine the location this node should be split // Determine the location this node should be split
std::array<FT, Dimension::value> bary; std::array<FT, dimension> bary;
for (std::size_t i = 0; i < Dimension::value; i++) for (std::size_t i = 0; i < dimension; i++)
// use the same expression as for the bbox computation // use the same expression as for the bbox computation
bary[i] = (m_bbox.min)()[i] + int(2 * global_coordinates(n)[i]+1) * ( size[i] / FT(2) ); bary[i] = (m_bbox.min)()[i] + int(2 * global_coordinates(n)[i]+1) * ( size[i] / FT(2) );
@ -996,7 +995,7 @@ public:
if (!lhsTree.is_leaf(lhsNode)) { if (!lhsTree.is_leaf(lhsNode)) {
// Check all the children // Check all the children
for (int i = 0; i < Degree::value; ++i) { for (int i = 0; i < degree; ++i) {
// If any child cell is different, they're not the same // If any child cell is different, they're not the same
if (!is_topology_equal(lhsTree.child(lhsNode, i), lhsTree, if (!is_topology_equal(lhsTree.child(lhsNode, i), lhsTree,
rhsTree.child(rhsNode, i), rhsTree)) rhsTree.child(rhsNode, i), rhsTree))
@ -1022,11 +1021,11 @@ public:
/*! /*!
\brief finds the directly adjacent node in a specific direction \brief finds the directly adjacent node in a specific direction
\pre `direction.to_ulong < 2 * Dimension::value` \pre `direction.to_ulong < 2 * dimension`
Adjacent nodes are found according to several properties: Adjacent nodes are found according to several properties:
- adjacent nodes may be larger than the seek node, but never smaller - adjacent nodes may be larger than the seek node, but never smaller
- a node has at most `2 * Dimension::value` different adjacent nodes (in 3D: left, right, up, down, front, back) - a node has at most `2 * dimension` different adjacent nodes (in 3D: left, right, up, down, front, back)
- adjacent nodes are not required to be leaf nodes - adjacent nodes are not required to be leaf nodes
Here's a diagram demonstrating the concept for a quadtree: Here's a diagram demonstrating the concept for a quadtree:
@ -1076,7 +1075,7 @@ public:
// direction: 000 001 010 011 100 101 // direction: 000 001 010 011 100 101
// Nodes only have up to 2*dim different adjacent nodes (since boxes have 6 sides) // Nodes only have up to 2*dim different adjacent nodes (since boxes have 6 sides)
CGAL_precondition(direction.to_ulong() < Dimension::value * 2); CGAL_precondition(direction.to_ulong() < dimension * 2);
// The root node has no adjacent nodes! // The root node has no adjacent nodes!
if (is_root(n)) return {}; if (is_root(n)) return {};
@ -1085,16 +1084,16 @@ public:
bool sign = direction[0]; bool sign = direction[0];
// The first two bits indicate the dimension/axis (x, y, z) // The first two bits indicate the dimension/axis (x, y, z)
uint8_t dimension = uint8_t((direction >> 1).to_ulong()); uint8_t dim = uint8_t((direction >> 1).to_ulong());
// Create an offset so that the bit-significance lines up with the dimension (e.g., 1, 2, 4 --> 001, 010, 100) // Create an offset so that the bit-significance lines up with the dimension (e.g., 1, 2, 4 --> 001, 010, 100)
int8_t offset = (uint8_t) 1 << dimension; int8_t offset = (uint8_t) 1 << dim;
// Finally, apply the sign to the offset // Finally, apply the sign to the offset
offset = (sign ? offset : -offset); offset = (sign ? offset : -offset);
// Check if this child has the opposite sign along the direction's axis // Check if this child has the opposite sign along the direction's axis
if (local_coordinates(n)[dimension] != sign) { if (local_coordinates(n)[dim] != sign) {
// This means the adjacent node is a direct sibling, the offset can be applied easily! // This means the adjacent node is a direct sibling, the offset can be applied easily!
return {child(parent(n), local_coordinates(n).to_ulong() + offset)}; return {child(parent(n), local_coordinates(n).to_ulong() + offset)};
} }
@ -1120,7 +1119,7 @@ public:
\param adjacency which way to find the adjacent node relative to this one \param adjacency which way to find the adjacent node relative to this one
*/ */
Maybe_node_index adjacent_node(Node_index n, Adjacency adjacency) const { Maybe_node_index adjacent_node(Node_index n, Adjacency adjacency) const {
return adjacent_node(n, std::bitset<Dimension::value>(static_cast<int>(adjacency))); return adjacent_node(n, std::bitset<dimension>(static_cast<int>(adjacency)));
} }
/// @} /// @}
@ -1157,7 +1156,7 @@ private: // functions :
} }
// Otherwise, each of the children need to be checked // Otherwise, each of the children need to be checked
for (int i = 0; i < Degree::value; ++i) { for (int i = 0; i < degree; ++i) {
intersected_nodes_recursive(query, child(node, i), output); intersected_nodes_recursive(query, child(node, i), output);
} }
} }

View File

@ -80,10 +80,10 @@ void nearest_k_neighbors_recursive(const Tree& orthtree,
// Create a list to map children to their distances // Create a list to map children to their distances
std::vector<Node_index_with_distance> children_with_distances; std::vector<Node_index_with_distance> children_with_distances;
children_with_distances.reserve(Tree::Degree::value); children_with_distances.reserve(Tree::degree);
// Fill the list with child nodes // Fill the list with child nodes
for (int i = 0; i < Tree::Degree::value; ++i) { for (int i = 0; i < Tree::degree; ++i) {
auto child_node = orthtree.child(node, i); auto child_node = orthtree.child(node, i);
// Add a child to the list, with its distance // Add a child to the list, with its distance

View File

@ -14,7 +14,6 @@
#include <CGAL/license/Orthtree.h> #include <CGAL/license/Orthtree.h>
#include <CGAL/Dimension.h>
#include <CGAL/Bbox_2.h> #include <CGAL/Bbox_2.h>
#include <CGAL/Point_set_2.h> #include <CGAL/Point_set_2.h>
#include <CGAL/Orthtree/Cartesian_ranges.h> #include <CGAL/Orthtree/Cartesian_ranges.h>
@ -26,22 +25,22 @@ namespace CGAL {
\ingroup PkgOrthtreeTraits \ingroup PkgOrthtreeTraits
The class `Orthtree_traits_base_for_dimension` is a base class providing common choices for types and functors. The class `Orthtree_traits_base_for_dimension` is a base class providing common choices for types and functors.
The base class is extended by `CGAL::Orthtree_traits_point<GeomTraits, PointRange, PointMap, DimensionTag>` and by `CGAL::Orthtree_traits_face_graph<PolygonMesh, VertexPointMap>`. The base class is extended by `CGAL::Orthtree_traits_point<GeomTraits, PointRange, PointMap, dimension>` and by `CGAL::Orthtree_traits_face_graph<PolygonMesh, VertexPointMap>`.
\tparam K a model of `Kernel`. \tparam K a model of `Kernel`.
\tparam DimensionTag a tag representing the dimension of the ambient Euclidean space. Must be `Dimension_tag<d>` where `d` is an integer. \tparam dim dimension of the ambient Euclidean space.
\sa `CGAL::Orthtree_traits_point<GeomTraits, PointRange, PointMap, DimensionTag>` \sa `CGAL::Orthtree_traits_point<GeomTraits, PointRange, PointMap, dim>`
\sa `CGAL::Orthtree_traits_face_graph<PolygonMesh, VertexPointMap>` \sa `CGAL::Orthtree_traits_face_graph<PolygonMesh, VertexPointMap>`
*/ */
template <typename K, typename DimensionTag> template <typename K, int dim>
struct Orthtree_traits_base_for_dimension { struct Orthtree_traits_base_for_dimension {
/// \name Types /// \name Types
/// @{ /// @{
using Node_index = std::size_t; using Node_index = std::size_t;
using Kernel = K; using Kernel = K;
using Dimension = DimensionTag; static constexpr int dimension = dim;
using FT = typename K::FT; using FT = typename K::FT;
using Point_d = typename K::Point_d; using Point_d = typename K::Point_d;
using Bbox_d = typename K::Iso_box_d; using Bbox_d = typename K::Iso_box_d;
@ -52,7 +51,7 @@ struct Orthtree_traits_base_for_dimension {
* *
* \note This type is used to identify adjacency directions with * \note This type is used to identify adjacency directions with
* easily understandable keywords (left, right, up, down, ...) and is thus * easily understandable keywords (left, right, up, down, ...) and is thus
* mainly useful for `Dimension_tag<2>` and `Dimension_tag<3>`. In * mainly useful in 2d and 3d. In
* higher dimensions, such keywords do not exist and this type is * higher dimensions, such keywords do not exist and this type is
* simply an integer. Conversions from this integer to bitsets still * simply an integer. Conversions from this integer to bitsets still
* work but do not provide any user-friendly API for adjacency selection. * work but do not provide any user-friendly API for adjacency selection.
@ -107,10 +106,10 @@ struct Orthtree_traits_base_for_dimension {
}; };
template <typename K> template <typename K>
struct Orthtree_traits_base_for_dimension<K, Dimension_tag<2>> { struct Orthtree_traits_base_for_dimension<K, 2> {
using Node_index = std::size_t; using Node_index = std::size_t;
using Kernel = K; using Kernel = K;
using Dimension = Dimension_tag<2>; static constexpr int dimension = 2;
using FT = typename K::FT; using FT = typename K::FT;
using Point_d = typename K::Point_2; using Point_d = typename K::Point_2;
using Bbox_d = typename K::Iso_rectangle_2; using Bbox_d = typename K::Iso_rectangle_2;
@ -138,10 +137,10 @@ struct Orthtree_traits_base_for_dimension<K, Dimension_tag<2>> {
}; };
template <typename K> template <typename K>
struct Orthtree_traits_base_for_dimension<K, Dimension_tag<3>> { struct Orthtree_traits_base_for_dimension<K, 3> {
using Node_index = std::size_t; using Node_index = std::size_t;
using Kernel = K; using Kernel = K;
using Dimension = Dimension_tag<3>; static constexpr int dimension = 3;
using FT = typename K::FT; using FT = typename K::FT;
using Point_d = typename K::Point_3; using Point_d = typename K::Point_3;
using Bbox_d = typename K::Iso_cuboid_3; using Bbox_d = typename K::Iso_cuboid_3;

View File

@ -39,8 +39,7 @@ to which the minimal extend of a node should be provided.
*/ */
template <class TriangleMesh, class VertexPointMap> template <class TriangleMesh, class VertexPointMap>
struct Orthtree_traits_face_graph : public Orthtree_traits_base_for_dimension< struct Orthtree_traits_face_graph : public Orthtree_traits_base_for_dimension<
typename Kernel_traits<typename boost::property_traits<VertexPointMap>::value_type>::type, typename Kernel_traits<typename boost::property_traits<VertexPointMap>::value_type>::type, 3 > {
Dimension_tag<3> > {
Orthtree_traits_face_graph(const TriangleMesh& pm, VertexPointMap vpm) Orthtree_traits_face_graph(const TriangleMesh& pm, VertexPointMap vpm)
: m_pm(pm), m_vpm(vpm) {} : m_pm(pm), m_vpm(vpm) {}
@ -49,14 +48,12 @@ struct Orthtree_traits_face_graph : public Orthtree_traits_base_for_dimension<
/// @{ /// @{
using Base = Orthtree_traits_base_for_dimension< using Base = Orthtree_traits_base_for_dimension<
typename Kernel_traits<typename boost::property_traits<VertexPointMap>::value_type>::type, typename Kernel_traits<typename boost::property_traits<VertexPointMap>::value_type>::type, 3 >;
Dimension_tag<3> >;
using Node_index = typename Base::Node_index; using Node_index = typename Base::Node_index;
using Self = Orthtree_traits_face_graph<TriangleMesh, VertexPointMap>; using Self = Orthtree_traits_face_graph<TriangleMesh, VertexPointMap>;
using Tree = Orthtree<Self>; using Tree = Orthtree<Self>;
using Point_d = typename Self::Point_d; using Point_d = typename Self::Point_d;
using Dimension = typename Self::Dimension;
using Bbox_d = typename Self::Bbox_d; using Bbox_d = typename Self::Bbox_d;
using FT = typename Self::FT; using FT = typename Self::FT;
using Cartesian_const_iterator_d = typename Self::Cartesian_const_iterator_d; using Cartesian_const_iterator_d = typename Self::Cartesian_const_iterator_d;
@ -77,7 +74,7 @@ struct Orthtree_traits_face_graph : public Orthtree_traits_base_for_dimension<
auto construct_root_node_bbox_object() const { auto construct_root_node_bbox_object() const {
return [&]() -> Bbox_d { return [&]() -> Bbox_d {
std::array<FT, Dimension::value> min = {0.0, 0}, max = {0.0, 0}; std::array<FT, dimension> min = {0.0, 0}, max = {0.0, 0};
if (faces(m_pm).begin() != faces(m_pm).end()) { if (faces(m_pm).begin() != faces(m_pm).end()) {
const Point_d& p = get(m_vpm, *vertices(m_pm).begin()); const Point_d& p = get(m_vpm, *vertices(m_pm).begin());
min = {p.x(), p.y(), p.z()}; min = {p.x(), p.y(), p.z()};

View File

@ -27,11 +27,11 @@ template <typename Tree, typename PointMap>
void reassign_points( void reassign_points(
Tree& tree, PointMap& point_map, Tree& tree, PointMap& point_map,
typename Tree::Node_index n, const typename Tree::Point& center, typename Tree::Node_data points, typename Tree::Node_index n, const typename Tree::Point& center, typename Tree::Node_data points,
std::bitset<Tree::Dimension::value> coord = {}, std::size_t dimension = 0 std::bitset<Tree::dimension> coord = {}, std::size_t dimension = 0
) { ) {
// Root case: reached the last dimension // Root case: reached the last dimension
if (dimension == Tree::Dimension::value) { if (dimension == Tree::dimension) {
tree.data(tree.child(n, coord.to_ulong())) = points; tree.data(tree.child(n, coord.to_ulong())) = points;
return; return;
} }
@ -49,12 +49,12 @@ void reassign_points(
); );
// Further subdivide the first side of the split // Further subdivide the first side of the split
std::bitset<Tree::Dimension::value> coord_left = coord; std::bitset<Tree::dimension> coord_left = coord;
coord_left[dimension] = false; coord_left[dimension] = false;
reassign_points(tree, point_map, n, center, {points.begin(), split_point}, coord_left, dimension + 1); reassign_points(tree, point_map, n, center, {points.begin(), split_point}, coord_left, dimension + 1);
// Further subdivide the second side of the split // Further subdivide the second side of the split
std::bitset<Tree::Dimension::value> coord_right = coord; std::bitset<Tree::dimension> coord_right = coord;
coord_right[dimension] = true; coord_right[dimension] = true;
reassign_points(tree, point_map, n, center, {split_point, points.end()}, coord_right, dimension + 1); reassign_points(tree, point_map, n, center, {split_point, points.end()}, coord_right, dimension + 1);
} }
@ -67,7 +67,7 @@ void reassign_points(
\tparam GeomTraits model of `Kernel`. \tparam GeomTraits model of `Kernel`.
\tparam PointRange must be a model of `Range` whose value type is the key type of `PointMap` and whose iterator type is model of `RandomAccessIterator` \tparam PointRange must be a model of `Range` whose value type is the key type of `PointMap` and whose iterator type is model of `RandomAccessIterator`
\tparam PointMap must be a model of `ReadablePropertyMap` whose value type is a point type from `GeomTraits` matching the current dimension \tparam PointMap must be a model of `ReadablePropertyMap` whose value type is a point type from `GeomTraits` matching the current dimension
\tparam DimensionTag a tag representing the dimension of the ambient Euclidean space. Must be `Dimension_tag<d>` where `d` is an integer. \tparam dimension the dimension of the ambient Euclidean space.
\warning The input point set is not copied. It is used directly \warning The input point set is not copied. It is used directly
and is rearranged by the `Orthtree`. Altering the point range and is rearranged by the `Orthtree`. Altering the point range
@ -82,20 +82,20 @@ template <
typename GeomTraits, typename GeomTraits,
typename PointRange, typename PointRange,
typename PointMap = Identity_property_map<typename std::iterator_traits<typename PointRange::iterator>::value_type>, typename PointMap = Identity_property_map<typename std::iterator_traits<typename PointRange::iterator>::value_type>,
typename DimensionTag = Ambient_dimension< int dimension = Ambient_dimension<
typename std::iterator_traits<typename PointRange::iterator>::value_type, typename std::iterator_traits<typename PointRange::iterator>::value_type,
GeomTraits GeomTraits
>::value
> >
> struct Orthtree_traits_point : public Orthtree_traits_base_for_dimension<GeomTraits, dimension> {
struct Orthtree_traits_point : public Orthtree_traits_base_for_dimension<GeomTraits, DimensionTag> {
public: public:
/// \name Types /// \name Types
/// @{ /// @{
using Node_data = boost::iterator_range<typename PointRange::iterator>; using Node_data = boost::iterator_range<typename PointRange::iterator>;
/// @} /// @}
using Base = Orthtree_traits_base_for_dimension<GeomTraits, DimensionTag>; using Base = Orthtree_traits_base_for_dimension<GeomTraits, dimension>;
using Self = Orthtree_traits_point<GeomTraits, PointRange, PointMap, DimensionTag>; using Self = Orthtree_traits_point<GeomTraits, PointRange, PointMap, dimension>;
using Tree = Orthtree<Self>; using Tree = Orthtree<Self>;
using Node_data_element = typename std::iterator_traits<typename PointRange::iterator>::value_type; using Node_data_element = typename std::iterator_traits<typename PointRange::iterator>::value_type;
@ -110,7 +110,7 @@ public:
auto construct_root_node_bbox_object() const { auto construct_root_node_bbox_object() const {
return [&]() -> typename Self::Bbox_d { return [&]() -> typename Self::Bbox_d {
std::array<typename Self::FT, Self::Dimension::value> bbox_min, bbox_max; std::array<typename Self::FT, Self::dimension> bbox_min, bbox_max;
Orthtrees::internal::Cartesian_ranges<Self> cartesian_range; Orthtrees::internal::Cartesian_ranges<Self> cartesian_range;
// init bbox with first values found // init bbox with first values found

View File

@ -32,7 +32,7 @@ template <typename GeomTraits, typename PointRange,
typename PointMap = Identity_property_map typename PointMap = Identity_property_map
<typename std::iterator_traits<typename PointRange::iterator>::value_type> > <typename std::iterator_traits<typename PointRange::iterator>::value_type> >
using Quadtree = Orthtree<Orthtree_traits_point<GeomTraits, PointRange, PointMap, Dimension_tag<2>>>; using Quadtree = Orthtree<Orthtree_traits_point<GeomTraits, PointRange, PointMap, 2>>;
} // namespace CGAL } // namespace CGAL

View File

@ -56,7 +56,7 @@ class RANSAC_octree {
typedef std::vector<std::size_t> Input_range; typedef std::vector<std::size_t> Input_range;
typedef Random_index_access_property_map<Input_iterator, Point_map> Indexed_point_map; typedef Random_index_access_property_map<Input_iterator, Point_map> Indexed_point_map;
typedef Orthtree_traits_point<typename Traits_base<Traits>::type, Input_range, Indexed_point_map, Dimension_tag<3>> OTraits; typedef Orthtree_traits_point<typename Traits_base<Traits>::type, Input_range, Indexed_point_map, 3> OTraits;
typedef CGAL::Orthtree<OTraits> Octree; typedef CGAL::Orthtree<OTraits> Octree;