From 11f0a842de3566e9d180b8ee02f30a2321b3292e Mon Sep 17 00:00:00 2001 From: Sven Oesau Date: Tue, 30 Jan 2024 16:47:53 +0100 Subject: [PATCH] changing dimension and degree in orthtree(_traits) to int --- .../doc/Orthtree/Concepts/OrthtreeTraits.h | 6 +- Orthtree/examples/Orthtree/orthtree_build.cpp | 8 +-- .../Orthtree/quadtree_build_manually.cpp | 8 +-- Orthtree/include/CGAL/Octree.h | 2 +- Orthtree/include/CGAL/Orthtree.h | 63 +++++++++---------- .../include/CGAL/Orthtree/Nearest_neighbors.h | 4 +- .../CGAL/Orthtree_traits_base_for_dimension.h | 21 +++---- .../include/CGAL/Orthtree_traits_face_graph.h | 9 +-- Orthtree/include/CGAL/Orthtree_traits_point.h | 22 +++---- Orthtree/include/CGAL/Quadtree.h | 2 +- .../Shape_detection/Efficient_RANSAC/Octree.h | 2 +- 11 files changed, 71 insertions(+), 76 deletions(-) diff --git a/Orthtree/doc/Orthtree/Concepts/OrthtreeTraits.h b/Orthtree/doc/Orthtree/Concepts/OrthtreeTraits.h index a3e149263d7..546c1211637 100644 --- a/Orthtree/doc/Orthtree/Concepts/OrthtreeTraits.h +++ b/Orthtree/doc/Orthtree/Concepts/OrthtreeTraits.h @@ -6,9 +6,9 @@ template parameter of the `CGAL::Orthtree` class. \cgalHasModelsBegin - \cgalHasModels{CGAL::Orthtree_traits_point} + \cgalHasModels{CGAL::Orthtree_traits_point} \cgalHasModels{CGAL::Orthtree_traits_face_graph} - \cgalHasModels{CGAL::Orthtree_traits_base_for_dimension< K, DimensionTag >} + \cgalHasModels{CGAL::Orthtree_traits_base_for_dimension< K, dimension >} \cgalHasModelsEnd */ class OrthtreeTraits @@ -18,7 +18,7 @@ public: /// \name Types /// @{ 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 Point_d = unspecified_type; ///< Point type. using Bbox_d = unspecified_type; ///< Bounding box type. Must be constructible from a pair of `Point_d` types. diff --git a/Orthtree/examples/Orthtree/orthtree_build.cpp b/Orthtree/examples/Orthtree/orthtree_build.cpp index 25abed86def..f4d6d2300f9 100644 --- a/Orthtree/examples/Orthtree/orthtree_build.cpp +++ b/Orthtree/examples/Orthtree/orthtree_build.cpp @@ -7,12 +7,12 @@ #include // Type Declarations -using Dimension = CGAL::Dimension_tag<4>; -using Kernel = CGAL::Epick_d; +const int dimension = 4; +using Kernel = CGAL::Epick_d >; using Point_d = Kernel::Point_d; using Point_vector = std::vector; using Traits = CGAL::Orthtree_traits_point; -using Traits2 = CGAL::Orthtree_traits_point::value_type>, CGAL::Dimension_tag<4>>; +using Traits2 = CGAL::Orthtree_traits_point::value_type>, dimension>; using Orthtree = CGAL::Orthtree; int main() @@ -22,7 +22,7 @@ int main() Point_vector points_dd; for (std::size_t i = 0; i < 500; ++ i) { - std::array init{}; + std::array init{}; for (double& v : init) v = r.get_double(-1., 1.); points_dd.emplace_back (init.begin(), init.end()); diff --git a/Orthtree/examples/Orthtree/quadtree_build_manually.cpp b/Orthtree/examples/Orthtree/quadtree_build_manually.cpp index 708b680213b..601917bf3c9 100644 --- a/Orthtree/examples/Orthtree/quadtree_build_manually.cpp +++ b/Orthtree/examples/Orthtree/quadtree_build_manually.cpp @@ -13,10 +13,10 @@ namespace CGAL { struct empty_type { }; -template -struct Orthtree_traits_empty : public Orthtree_traits_base_for_dimension { +template +struct Orthtree_traits_empty : public Orthtree_traits_base_for_dimension { - using Self = Orthtree_traits_empty; + using Self = Orthtree_traits_empty; using Tree = Orthtree; using Node_data = std::array; @@ -40,7 +40,7 @@ private: }; } -using EmptyQuadtree = CGAL::Orthtree>>; +using EmptyQuadtree = CGAL::Orthtree>; int main() { diff --git a/Orthtree/include/CGAL/Octree.h b/Orthtree/include/CGAL/Octree.h index 167d8d21101..625494bb2be 100644 --- a/Orthtree/include/CGAL/Octree.h +++ b/Orthtree/include/CGAL/Octree.h @@ -33,7 +33,7 @@ template < typename PointRange, typename PointMap = Identity_property_map::value_type> > -using Octree = Orthtree>>; +using Octree = Orthtree>; } // namespace CGAL diff --git a/Orthtree/include/CGAL/Orthtree.h b/Orthtree/include/CGAL/Orthtree.h index b7aa9772b21..19d9ea20b4e 100644 --- a/Orthtree/include/CGAL/Orthtree.h +++ b/Orthtree/include/CGAL/Orthtree.h @@ -26,7 +26,6 @@ #include #include #include -#include #include #include @@ -76,7 +75,7 @@ public: /// \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 FT = typename Traits::FT; ///< Number 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). */ - 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. @@ -119,7 +118,7 @@ public: `z` is greater, and so on for higher dimensions if needed. Used to represent a node's relationship to the center of its parent. */ - using Local_coordinates = std::bitset; + using Local_coordinates = std::bitset; /*! \brief Coordinates representing this node's relationship @@ -128,7 +127,7 @@ public: Each value `(x, y, z, ...)` of global coordinates is calculated by doubling the parent's global coordinates and adding the local coordinates. */ - using Global_coordinates = std::array; + using Global_coordinates = std::array; /*! * \brief A predicate that determines whether a node must be split when refining a tree. @@ -173,7 +172,7 @@ private: // data members : Property_array& m_node_parents; Property_array& m_node_children; - using Bbox_dimensions = std::array; + using Bbox_dimensions = std::array; Bbox m_bbox; std::vector m_side_per_depth; /* precomputed (potentially approximated) side length per node's depth */ @@ -214,7 +213,7 @@ public: // Determine dimensions of the root bbox 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]; } @@ -298,7 +297,7 @@ public: if (!is_leaf(current)) { // 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)); } } @@ -381,7 +380,7 @@ public: split(*neighbor); // 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)); } } @@ -465,12 +464,12 @@ public: \return the bounding box of the node n */ Bbox bbox(Node_index n) const { - using Cartesian_coordinate = std::array; + using Cartesian_coordinate = std::array; Cartesian_coordinate min_corner, max_corner; std::size_t node_depth = depth(n); Bbox_dimensions size = m_side_per_depth[node_depth]; 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]; max_corner[i] = std::size_t(global_coordinates(n)[i]) == last_coord ? (m_bbox.max)()[i] @@ -585,9 +584,9 @@ public: // Find the index of the correct sub-node Local_coordinates local_coords; - std::size_t dimension = 0; + std::size_t dim = 0; 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 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 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; return result; } @@ -826,7 +825,7 @@ public: std::size_t local_coords = local_coordinates(n).to_ulong(); // The last child has no more siblings - if (int(local_coords) == Degree::value - 1) + if (int(local_coords) == degree - 1) return {}; // The next sibling is the child of the parent with the following local coordinates @@ -898,7 +897,7 @@ public: return 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)); } @@ -910,7 +909,7 @@ public: Only leaf nodes should be split. 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 `distribute_node_contents_object` in the traits class. @@ -923,8 +922,8 @@ public: // Split the node to create children using Local_coordinates = Local_coordinates; - m_node_children[n] = m_node_properties.emplace_group(Degree::value); - for (std::size_t i = 0; i < Degree::value; i++) { + m_node_children[n] = m_node_properties.emplace_group(degree); + for (std::size_t i = 0; i < degree; i++) { Node_index c = *m_node_children[n] + i; @@ -932,7 +931,7 @@ public: CGAL_assertion(n != *m_node_children[n] + 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_depths[c] = m_node_depths[n] + 1; m_node_parents[c] = n; @@ -943,7 +942,7 @@ public: // Update the side length map with the dimensions of the children Bbox_dimensions size = m_side_per_depth.back(); 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); m_side_per_depth.push_back(child_size); } @@ -968,8 +967,8 @@ public: Bbox_dimensions size = m_side_per_depth[depth(n)]; // Determine the location this node should be split - std::array bary; - for (std::size_t i = 0; i < Dimension::value; i++) + std::array bary; + for (std::size_t i = 0; i < dimension; i++) // 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) ); @@ -996,7 +995,7 @@ public: if (!lhsTree.is_leaf(lhsNode)) { // 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 (!is_topology_equal(lhsTree.child(lhsNode, i), lhsTree, rhsTree.child(rhsNode, i), rhsTree)) @@ -1022,11 +1021,11 @@ public: /*! \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 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 Here's a diagram demonstrating the concept for a quadtree: @@ -1076,7 +1075,7 @@ public: // direction: 000 001 010 011 100 101 // 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! if (is_root(n)) return {}; @@ -1085,16 +1084,16 @@ public: bool sign = direction[0]; // 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) - int8_t offset = (uint8_t) 1 << dimension; + int8_t offset = (uint8_t) 1 << dim; // Finally, apply the sign to the offset offset = (sign ? offset : -offset); // 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! 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 */ Maybe_node_index adjacent_node(Node_index n, Adjacency adjacency) const { - return adjacent_node(n, std::bitset(static_cast(adjacency))); + return adjacent_node(n, std::bitset(static_cast(adjacency))); } /// @} @@ -1157,7 +1156,7 @@ private: // functions : } // 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); } } diff --git a/Orthtree/include/CGAL/Orthtree/Nearest_neighbors.h b/Orthtree/include/CGAL/Orthtree/Nearest_neighbors.h index 8f2b47fe1ed..63266158f4d 100644 --- a/Orthtree/include/CGAL/Orthtree/Nearest_neighbors.h +++ b/Orthtree/include/CGAL/Orthtree/Nearest_neighbors.h @@ -80,10 +80,10 @@ void nearest_k_neighbors_recursive(const Tree& orthtree, // Create a list to map children to their distances std::vector children_with_distances; - children_with_distances.reserve(Tree::Degree::value); + children_with_distances.reserve(Tree::degree); // 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); // Add a child to the list, with its distance diff --git a/Orthtree/include/CGAL/Orthtree_traits_base_for_dimension.h b/Orthtree/include/CGAL/Orthtree_traits_base_for_dimension.h index b64cfdd7506..88043d53cdf 100644 --- a/Orthtree/include/CGAL/Orthtree_traits_base_for_dimension.h +++ b/Orthtree/include/CGAL/Orthtree_traits_base_for_dimension.h @@ -14,7 +14,6 @@ #include -#include #include #include #include @@ -26,22 +25,22 @@ namespace CGAL { \ingroup PkgOrthtreeTraits 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` and by `CGAL::Orthtree_traits_face_graph`. + The base class is extended by `CGAL::Orthtree_traits_point` and by `CGAL::Orthtree_traits_face_graph`. \tparam K a model of `Kernel`. - \tparam DimensionTag a tag representing the dimension of the ambient Euclidean space. Must be `Dimension_tag` where `d` is an integer. + \tparam dim dimension of the ambient Euclidean space. - \sa `CGAL::Orthtree_traits_point` + \sa `CGAL::Orthtree_traits_point` \sa `CGAL::Orthtree_traits_face_graph` */ -template +template struct Orthtree_traits_base_for_dimension { /// \name Types /// @{ using Node_index = std::size_t; using Kernel = K; - using Dimension = DimensionTag; + static constexpr int dimension = dim; using FT = typename K::FT; using Point_d = typename K::Point_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 * 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 * simply an integer. Conversions from this integer to bitsets still * work but do not provide any user-friendly API for adjacency selection. @@ -107,10 +106,10 @@ struct Orthtree_traits_base_for_dimension { }; template -struct Orthtree_traits_base_for_dimension> { +struct Orthtree_traits_base_for_dimension { using Node_index = std::size_t; using Kernel = K; - using Dimension = Dimension_tag<2>; + static constexpr int dimension = 2; using FT = typename K::FT; using Point_d = typename K::Point_2; using Bbox_d = typename K::Iso_rectangle_2; @@ -138,10 +137,10 @@ struct Orthtree_traits_base_for_dimension> { }; template -struct Orthtree_traits_base_for_dimension> { +struct Orthtree_traits_base_for_dimension { using Node_index = std::size_t; using Kernel = K; - using Dimension = Dimension_tag<3>; + static constexpr int dimension = 3; using FT = typename K::FT; using Point_d = typename K::Point_3; using Bbox_d = typename K::Iso_cuboid_3; diff --git a/Orthtree/include/CGAL/Orthtree_traits_face_graph.h b/Orthtree/include/CGAL/Orthtree_traits_face_graph.h index 17218fa9bbe..baaebe51d70 100644 --- a/Orthtree/include/CGAL/Orthtree_traits_face_graph.h +++ b/Orthtree/include/CGAL/Orthtree_traits_face_graph.h @@ -39,8 +39,7 @@ to which the minimal extend of a node should be provided. */ template struct Orthtree_traits_face_graph : public Orthtree_traits_base_for_dimension< - typename Kernel_traits::value_type>::type, - Dimension_tag<3> > { + typename Kernel_traits::value_type>::type, 3 > { Orthtree_traits_face_graph(const TriangleMesh& pm, VertexPointMap 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< - typename Kernel_traits::value_type>::type, - Dimension_tag<3> >; + typename Kernel_traits::value_type>::type, 3 >; using Node_index = typename Base::Node_index; using Self = Orthtree_traits_face_graph; using Tree = Orthtree; using Point_d = typename Self::Point_d; - using Dimension = typename Self::Dimension; using Bbox_d = typename Self::Bbox_d; using FT = typename Self::FT; 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 { return [&]() -> Bbox_d { - std::array min = {0.0, 0}, max = {0.0, 0}; + std::array min = {0.0, 0}, max = {0.0, 0}; if (faces(m_pm).begin() != faces(m_pm).end()) { const Point_d& p = get(m_vpm, *vertices(m_pm).begin()); min = {p.x(), p.y(), p.z()}; diff --git a/Orthtree/include/CGAL/Orthtree_traits_point.h b/Orthtree/include/CGAL/Orthtree_traits_point.h index 1bb4e4a9d36..ca801cd5871 100644 --- a/Orthtree/include/CGAL/Orthtree_traits_point.h +++ b/Orthtree/include/CGAL/Orthtree_traits_point.h @@ -27,11 +27,11 @@ template void reassign_points( Tree& tree, PointMap& point_map, typename Tree::Node_index n, const typename Tree::Point& center, typename Tree::Node_data points, - std::bitset coord = {}, std::size_t dimension = 0 + std::bitset coord = {}, std::size_t dimension = 0 ) { // Root case: reached the last dimension - if (dimension == Tree::Dimension::value) { + if (dimension == Tree::dimension) { tree.data(tree.child(n, coord.to_ulong())) = points; return; } @@ -49,12 +49,12 @@ void reassign_points( ); // Further subdivide the first side of the split - std::bitset coord_left = coord; + std::bitset coord_left = coord; coord_left[dimension] = false; reassign_points(tree, point_map, n, center, {points.begin(), split_point}, coord_left, dimension + 1); // Further subdivide the second side of the split - std::bitset coord_right = coord; + std::bitset coord_right = coord; coord_right[dimension] = true; 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 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 DimensionTag a tag representing the dimension of the ambient Euclidean space. Must be `Dimension_tag` 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 and is rearranged by the `Orthtree`. Altering the point range @@ -82,20 +82,20 @@ template < typename GeomTraits, typename PointRange, typename PointMap = Identity_property_map::value_type>, - typename DimensionTag = Ambient_dimension< + int dimension = Ambient_dimension< typename std::iterator_traits::value_type, GeomTraits - > + >::value > -struct Orthtree_traits_point : public Orthtree_traits_base_for_dimension { +struct Orthtree_traits_point : public Orthtree_traits_base_for_dimension { public: /// \name Types /// @{ using Node_data = boost::iterator_range; /// @} - using Base = Orthtree_traits_base_for_dimension; - using Self = Orthtree_traits_point; + using Base = Orthtree_traits_base_for_dimension; + using Self = Orthtree_traits_point; using Tree = Orthtree; using Node_data_element = typename std::iterator_traits::value_type; @@ -110,7 +110,7 @@ public: auto construct_root_node_bbox_object() const { return [&]() -> typename Self::Bbox_d { - std::array bbox_min, bbox_max; + std::array bbox_min, bbox_max; Orthtrees::internal::Cartesian_ranges cartesian_range; // init bbox with first values found diff --git a/Orthtree/include/CGAL/Quadtree.h b/Orthtree/include/CGAL/Quadtree.h index 3e02147073e..5bbf2ecea8e 100644 --- a/Orthtree/include/CGAL/Quadtree.h +++ b/Orthtree/include/CGAL/Quadtree.h @@ -32,7 +32,7 @@ template ::value_type> > -using Quadtree = Orthtree>>; +using Quadtree = Orthtree>; } // namespace CGAL diff --git a/Shape_detection/include/CGAL/Shape_detection/Efficient_RANSAC/Octree.h b/Shape_detection/include/CGAL/Shape_detection/Efficient_RANSAC/Octree.h index 7971b638ad1..ceaa7fe0bda 100644 --- a/Shape_detection/include/CGAL/Shape_detection/Efficient_RANSAC/Octree.h +++ b/Shape_detection/include/CGAL/Shape_detection/Efficient_RANSAC/Octree.h @@ -56,7 +56,7 @@ class RANSAC_octree { typedef std::vector Input_range; typedef Random_index_access_property_map Indexed_point_map; - typedef Orthtree_traits_point::type, Input_range, Indexed_point_map, Dimension_tag<3>> OTraits; + typedef Orthtree_traits_point::type, Input_range, Indexed_point_map, 3> OTraits; typedef CGAL::Orthtree Octree;