From b08eabae93057231f0307a015cb5d85d5d19a253 Mon Sep 17 00:00:00 2001 From: JacksonCampolattaro Date: Mon, 26 Jun 2023 16:59:02 +0200 Subject: [PATCH] Move point-specific functionality to traits class (only Point_3 is currently supported) --- Orthtree/doc/Orthtree/Orthtree.txt | 2 +- Orthtree/doc/Orthtree/PackageDescription.txt | 2 +- Orthtree/include/CGAL/Octree.h | 3 +- Orthtree/include/CGAL/Orthtree.h | 132 ++------- Orthtree/include/CGAL/Orthtree/Traversals.h | 2 +- .../include/CGAL/Orthtree_traits_point_3.h | 258 ++++++++++++++++++ Orthtree/test/Orthtree/test_node_adjacent.cpp | 2 +- Orthtree/test/Orthtree/test_node_index.cpp | 2 +- Orthtree/test/Orthtree/test_octree_bbox.cpp | 6 +- .../test_octree_copy_move_constructors.cpp | 2 +- .../test_octree_custom_properties.cpp | 2 +- .../test/Orthtree/test_octree_equality.cpp | 12 +- Orthtree/test/Orthtree/test_octree_grade.cpp | 2 +- .../Orthtree/test_octree_intersecting.cpp | 2 +- .../test/Orthtree/test_octree_kernels.cpp | 2 +- Orthtree/test/Orthtree/test_octree_locate.cpp | 6 +- .../Orthtree/test_octree_nearest_neighbor.cpp | 12 +- Orthtree/test/Orthtree/test_octree_refine.cpp | 10 +- .../test/Orthtree/test_octree_traverse.cpp | 8 +- 19 files changed, 325 insertions(+), 142 deletions(-) create mode 100644 Orthtree/include/CGAL/Orthtree_traits_point_3.h diff --git a/Orthtree/doc/Orthtree/Orthtree.txt b/Orthtree/doc/Orthtree/Orthtree.txt index 060bda6aaa5..d32afbb0234 100644 --- a/Orthtree/doc/Orthtree/Orthtree.txt +++ b/Orthtree/doc/Orthtree/Orthtree.txt @@ -73,7 +73,7 @@ split. \subsection Section_Orthtree_Point_Vector Building an Octree -The `Orthtree` class may be templated with `Orthtree_traits_point_set_3` and thus +The `Orthtree` class may be templated with `Orthtree_traits_point_3` and thus behave as an %octree. For convenience, the alias `Octree` is provided. The following example shows how to create an %octree from a vector of diff --git a/Orthtree/doc/Orthtree/PackageDescription.txt b/Orthtree/doc/Orthtree/PackageDescription.txt index cb9864363ef..818358a29c8 100644 --- a/Orthtree/doc/Orthtree/PackageDescription.txt +++ b/Orthtree/doc/Orthtree/PackageDescription.txt @@ -48,7 +48,7 @@ \cgalCRPSection{Traits} - `CGAL::Orthtree_traits_2` -- `CGAL::Orthtree_traits_point_set_3` +- `CGAL::Orthtree_traits_point_3` - `CGAL::Orthtree_traits_d` \cgalCRPSection{Split Predicates} diff --git a/Orthtree/include/CGAL/Octree.h b/Orthtree/include/CGAL/Octree.h index 848b2731c73..1d6e8318ff8 100644 --- a/Orthtree/include/CGAL/Octree.h +++ b/Orthtree/include/CGAL/Octree.h @@ -16,6 +16,7 @@ #include #include +#include namespace CGAL { @@ -43,7 +44,7 @@ template < #ifdef DOXYGEN_RUNNING class Octree; #else -using Octree = Orthtree, PointRange, PointMap>; +using Octree = Orthtree>; #endif } // namespace CGAL diff --git a/Orthtree/include/CGAL/Orthtree.h b/Orthtree/include/CGAL/Orthtree.h index 34a15ab0fc1..7abd20858ff 100644 --- a/Orthtree/include/CGAL/Orthtree.h +++ b/Orthtree/include/CGAL/Orthtree.h @@ -62,11 +62,8 @@ namespace CGAL { \sa `CGAL::Octree` \tparam Traits_ must be a model of `OrthtreeTraits` - \tparam PointRange_ must be a model of range whose value type is the key type of `PointMap_` - \tparam PointMap_ must be a model of `ReadablePropertyMap` whose value type is `Traits_::Point_d` */ -template > +template class Orthtree { public: @@ -74,8 +71,6 @@ public: /// \name Template Types /// @{ typedef Traits_ Traits; ///< Geometry traits - typedef PointRange_ PointRange; ///< Point range - typedef PointMap_ PointMap; ///< Point map /// @} /// \name Traits Types @@ -87,6 +82,9 @@ public: typedef typename Traits::Sphere_d Sphere; ///< Sphere type. typedef typename Traits::Adjacency Adjacency; ///< Adjacency type. + typedef typename Traits::Node_data Node_data; + typedef typename Traits::Node_data_element Node_data_element; + /// \cond SKIP_IN_MANUAL typedef typename Traits::Array Array; ///< Array type. typedef typename Traits::Construct_point_d_from_array Construct_point_d_from_array; @@ -94,19 +92,13 @@ public: /// \endcond /// @} - /// \name Types specific to Point_set_3 - /// todo: should be moved to Traits - /// @{ - typedef boost::iterator_range Node_point_range; - /// @} - /// \name Public Types /// @{ /*! * \brief Self typedef for convenience. */ - typedef Orthtree Self; + typedef Orthtree Self; /*! * \brief Degree of the tree (number of children of non-leaf nodes). @@ -168,17 +160,6 @@ public: #endif /// \cond SKIP_IN_MANUAL - - /*! - * \brief A function that determines the next node in a traversal given the current one. - */ - typedef std::function Node_traversal_method_const; - - /// \endcond - - /// \cond SKIP_IN_MANUAL - typedef typename PointRange::iterator Range_iterator; - typedef typename std::iterator_traits::value_type Range_type; typedef Orthtrees::internal::Cartesian_ranges Cartesian_ranges; /// \endcond @@ -187,11 +168,9 @@ public: private: // data members : Traits m_traits; /* the tree traits */ - PointRange& m_range; /* input point range */ - PointMap m_point_map; /* property map: `value_type of InputIterator` -> `Point` (Position) */ Node_property_container m_node_properties; - Node_property_container::Array & m_node_points; + Node_property_container::Array & m_node_points; Node_property_container::Array & m_node_depths; Node_property_container::Array & m_node_coordinates; Node_property_container::Array & m_node_parents; @@ -235,12 +214,10 @@ public: \param enlarge_ratio ratio to which the bounding box should be enlarged. \param traits the traits object. */ - Orthtree(PointRange& point_range, - PointMap point_map = PointMap(), - const FT enlarge_ratio = 1.2, - Traits traits = Traits()) : - m_traits(traits), m_range(point_range), m_point_map(point_map), - m_node_points(m_node_properties.add_property("points")), + Orthtree(Traits traits, + const FT enlarge_ratio = 1.2) : + m_traits(traits), + m_node_points(m_node_properties.add_property("points")), m_node_depths(m_node_properties.add_property("depths", 0)), m_node_coordinates(m_node_properties.add_property("coordinates")), m_node_parents(m_node_properties.add_property("parents")), @@ -248,30 +225,11 @@ public: m_node_properties.emplace(); - Array bbox_min; - Array bbox_max; // init bbox with first values found - { - const Point& p = get(m_point_map, *(point_range.begin())); - std::size_t i = 0; - for (const FT& x: cartesian_range(p)) { - bbox_min[i] = x; - bbox_max[i] = x; - ++i; - } - } - - for (const Range_type& r: point_range) { - const Point& p = get(m_point_map, r); - std::size_t i = 0; - for (const FT& x: cartesian_range(p)) { - bbox_min[i] = (std::min)(x, bbox_min[i]); - bbox_max[i] = (std::max)(x, bbox_max[i]); - ++i; - } - } + auto [bbox_min, bbox_max] = m_traits.root_node_bbox(); + // Dilate the bounding box Array bbox_centroid; FT max_length = FT(0); for (std::size_t i = 0; i < Dimension::value; ++i) { @@ -279,7 +237,6 @@ public: max_length = (std::max)(max_length, bbox_max[i] - bbox_min[i]); } max_length *= enlarge_ratio / FT(2); - for (std::size_t i = 0; i < Dimension::value; ++i) { bbox_min[i] = bbox_centroid[i] - max_length; bbox_max[i] = bbox_centroid[i] + max_length; @@ -291,7 +248,7 @@ public: // save orthtree attributes m_bbox_min = construct_point_d_from_array(bbox_min); m_side_per_depth.push_back(bbox_max[0] - bbox_min[0]); - points(root()) = {point_range.begin(), point_range.end()}; + points(root()) = m_traits.root_node_contents(); } /// @} @@ -300,10 +257,10 @@ public: // copy constructor Orthtree(const Orthtree& other) : - m_traits(other.m_traits), m_range(other.m_range), m_point_map(other.m_point_map), + m_traits(other.m_traits), m_bbox_min(other.m_bbox_min), m_side_per_depth(other.m_side_per_depth), m_node_properties(other.m_node_properties), - m_node_points(m_node_properties.get_property("points")), + m_node_points(m_node_properties.get_property("points")), m_node_depths(m_node_properties.get_property("depths")), m_node_coordinates(m_node_properties.get_property("coordinates")), m_node_parents(m_node_properties.get_property("parents")), @@ -311,10 +268,10 @@ public: // move constructor Orthtree(Orthtree&& other) : - m_traits(other.m_traits), m_range(other.m_range), m_point_map(other.m_point_map), + m_traits(other.m_traits), m_bbox_min(other.m_bbox_min), m_side_per_depth(other.m_side_per_depth), m_node_properties(std::move(other.m_node_properties)), - m_node_points(m_node_properties.get_property("points")), + m_node_points(m_node_properties.get_property("points")), m_node_depths(m_node_properties.get_property("depths")), m_node_coordinates(m_node_properties.get_property("coordinates")), m_node_parents(m_node_properties.get_property("parents")), @@ -742,11 +699,11 @@ public: return m_node_depths[n]; } - Node_point_range& points(Node_index n) { + Node_data& points(Node_index n) { return m_node_points[n]; } - const Node_point_range& points(Node_index n) const { + const Node_data& points(Node_index n) const { return m_node_points[n]; } @@ -883,7 +840,8 @@ public: Point center = barycenter(n); // Add the node's points to its children - reassign_points(n, points(n).begin(), points(n).end(), center); + m_traits.distribute_node_contents(n, *this, center); + //reassign_points(n, points(n).begin(), points(n).end(), center); } /*! @@ -1046,37 +1004,6 @@ public: private: // functions : - void reassign_points(Node_index n, Range_iterator begin, Range_iterator end, const Point& center, - std::bitset coord = {}, - std::size_t dimension = 0) { - - // Root case: reached the last dimension - if (dimension == Dimension::value) { - points(child(n, coord.to_ulong())) = {begin, end}; - return; - } - - // Split the point collection around the center point on this dimension - Range_iterator split_point = std::partition( - begin, end, - [&](const Range_type& a) -> bool { - // This should be done with cartesian iterator, - // but it seems complicated to do efficiently - return (get(m_point_map, a)[int(dimension)] < center[int(dimension)]); - } - ); - - // Further subdivide the first side of the split - std::bitset coord_left = coord; - coord_left[dimension] = false; - reassign_points(n, begin, split_point, center, coord_left, dimension + 1); - - // Further subdivide the second side of the split - std::bitset coord_right = coord; - coord_right[dimension] = true; - reassign_points(n, split_point, end, center, coord_right, dimension + 1); - } - bool do_intersect(Node_index n, const Sphere& sphere) const { // Create a cubic bounding box from the node @@ -1087,8 +1014,8 @@ private: // functions : } // TODO: There has to be a better way than using structs like these! - struct Point_with_distance { - Point point; + struct Node_element_with_distance { + Node_data_element point; FT distance; }; @@ -1102,7 +1029,7 @@ private: // functions : }; void nearest_k_neighbors_recursive(Sphere& search_bounds, Node_index node, - std::vector& results, FT epsilon = 0) const { + std::vector& results, FT epsilon = 0) const { // Check whether the node has children if (is_leaf(node)) { @@ -1111,14 +1038,11 @@ private: // functions : // Loop through each of the points contained by the node // Note: there might be none, and that should be fine! - for (auto point_index: points(node)) { - - // Retrieve each point from the orthtree's point map - auto point = get(m_point_map, point_index); + for (auto p: points(node)) { // Pair that point with its distance from the search point - Point_with_distance current_point_with_distance = - {point, squared_distance(point, search_bounds.center())}; + Node_element_with_distance current_point_with_distance = + {p, squared_distance(m_traits.get_element(p), search_bounds.center())}; // Check if the new point is within the bounds if (current_point_with_distance.distance < search_bounds.squared_radius()) { @@ -1226,7 +1150,7 @@ private: // functions : OutputIterator nearest_k_neighbors_in_radius(Sphere& query_sphere, std::size_t k, OutputIterator output) const { // Create an empty list of points - std::vector points_list; + std::vector points_list; if (k != (std::numeric_limits::max)()) points_list.reserve(k); diff --git a/Orthtree/include/CGAL/Orthtree/Traversals.h b/Orthtree/include/CGAL/Orthtree/Traversals.h index 3c5cf2dc43f..708faa435e0 100644 --- a/Orthtree/include/CGAL/Orthtree/Traversals.h +++ b/Orthtree/include/CGAL/Orthtree/Traversals.h @@ -25,7 +25,7 @@ namespace CGAL { /// \cond SKIP_IN_MANUAL // todo: is this necessary? // Forward declaration -template +template class Orthtree; /// \endcond diff --git a/Orthtree/include/CGAL/Orthtree_traits_point_3.h b/Orthtree/include/CGAL/Orthtree_traits_point_3.h new file mode 100644 index 00000000000..b016dc945a3 --- /dev/null +++ b/Orthtree/include/CGAL/Orthtree_traits_point_3.h @@ -0,0 +1,258 @@ +// Copyright (c) 2023 INRIA (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) : Jackson Campolattaro + +#ifndef ORTHTREE_TESTS_ORTHTREE_TRAITS_POINT_3_H +#define ORTHTREE_TESTS_ORTHTREE_TRAITS_POINT_3_H + + +#include + +#include +#include +#include +#include + +namespace CGAL { + +/*! + \ingroup PkgOrthtreeTraits + + The class `Orthtree_traits_point_3` can be used as a template parameter of + the `Orthtree` class. + + \tparam GeomTraits model of `Kernel`. + \tparam Point_set must be a model of range whose value type is the key type of `Point_map` + \tparam Point_map must be a model of `ReadablePropertyMap` whose value type is `GeomTraits::Traits::Point_d` + + \cgalModels `OrthtreeTraits` + \sa `CGAL::Octree` + \sa `CGAL::Orthtree_traits_2` + \sa `CGAL::Orthtree_traits_d` +*/ +template < + typename GeomTraits, + typename Point_set, + typename Point_map = Identity_property_map +> +struct Orthtree_traits_point_3 { +public: + + /// \name Types + /// @{ + + using Self = Orthtree_traits_point_3; + + using Dimension = Dimension_tag<3>; + using Bbox_d = Bbox_3; + using FT = typename GeomTraits::FT; + using Point_d = typename GeomTraits::Point_3; + using Sphere_d = typename GeomTraits::Sphere_3; + using Cartesian_const_iterator_d = typename GeomTraits::Cartesian_const_iterator_3; + using Array = std::array; // todo: This should have a more descriptive name + + // todo: looking for better names + using Node_data = boost::iterator_range; + using Node_data_element = typename std::iterator_traits::value_type; + + + /*! + * \brief Two directions along each axis in Cartesian space, relative to a node. + * + * Directions are mapped to numbers as 3-bit integers, + * though the numbers 6 and 7 are not used because there are only 6 different directions. + * + * The first two bits indicate the axis (00 = x, 01 = y, 10 = z), + * the third bit indicates the direction along that axis (0 = -, 1 = +). + * + * The following diagram may be a useful reference: + * + * 3 * + * | * 5 + * | / y+ + * |/ * z+ + * 0 *------+------* 1 | * + * /| |/ + * / | +-----* x+ + * 4 * | + * * 2 + * + * This lookup table may also be helpful: + * + * | Direction | bitset | number | Enum | + * | --------- | ------ | ------ | ----- | + * | `-x` | 000 | 0 | LEFT | + * | `+x` | 001 | 1 | RIGHT | + * | `-y` | 010 | 2 | DOWN | + * | `+y` | 011 | 3 | UP | + * | `-z` | 100 | 4 | BACK | + * | `+z` | 101 | 5 | FRONT | + */ + enum Adjacency { + LEFT, + RIGHT, + DOWN, + UP, + BACK, + FRONT + }; + + /// \cond SKIP_IN_MANUAL + enum Child { + LEFT_BOTTOM_BACK, + RIGHT_BOTTOM_BACK, + LEFT_TOP_BACK, + RIGHT_TOP_BACK, + LEFT_BOTTOM_FRONT, + RIGHT_BOTTOM_FRONT, + LEFT_TOP_FRONT, + RIGHT_TOP_FRONT + }; + /// \endcond + +#ifdef DOXYGEN_RUNNING + /*! + Functor with an operator to construct a `Point_d` from an `Array` object. + */ + typedef unspecified_type Construct_point_d_from_array; +#else + + struct Construct_point_d_from_array { + Point_d operator()(const Array& array) const { + return Point_d(array[0], array[1], array[2]); + } + }; + +#endif + +#ifdef DOXYGEN_RUNNING + /*! + Functor with an operator to construct a `Bbox_d` from two `Array` objects (coordinates of minimum and maximum points). + */ + typedef unspecified_type Construct_bbox_d; +#else + + struct Construct_bbox_d { + Bbox_d operator()(const Array& min, + const Array& max) const { + return Bbox_d(min[0], min[1], min[2], max[0], max[1], max[2]); + } + }; + +#endif + + /// @} + + Orthtree_traits_point_3( + Point_set& point_set, + Point_map point_map = Point_map() + ) : m_point_set(point_set), m_point_map(point_map) {} + + /// \name Operations + /// The user shouldn't need to define these themselves + /// @{ + + /*! + Function used to construct an object of type `Construct_point_d_from_array`. + */ + Construct_point_d_from_array construct_point_d_from_array_object() const { return Construct_point_d_from_array(); } + + /*! + Function used to construct an object of type `Construct_bbox_d`. + */ + Construct_bbox_d construct_bbox_d_object() const { return Construct_bbox_d(); } + + std::pair root_node_bbox() const { + + Array bbox_min; + Array bbox_max; + Orthtrees::internal::Cartesian_ranges cartesian_range; + + // init bbox with first values found + { + const Point_d& point = get(m_point_map, *(m_point_set.begin())); + std::size_t i = 0; + for (const FT& x: cartesian_range(point)) { + bbox_min[i] = x; + bbox_max[i] = x; + ++i; + } + } + // Expand bbox to contain all points + for (const auto& p: m_point_set) { + const Point_d& point = get(m_point_map, p); + std::size_t i = 0; + for (const FT& x: cartesian_range(point)) { + bbox_min[i] = (std::min)(x, bbox_min[i]); + bbox_max[i] = (std::max)(x, bbox_max[i]); + ++i; + } + } + + return {bbox_min, bbox_max}; + } + + Node_data root_node_contents() const { return {m_point_set.begin(), m_point_set.end()}; } + + template + void distribute_node_contents(Node_index n, Tree& tree, const Point_d& center) { + CGAL_precondition(!tree.is_leaf(n)); + reassign_points(n, tree, center, tree.points(n)); + } + + Point_d get_element(const Node_data_element& index) const { + return get(m_point_map, index); + } + + /// @} + +private: + + Point_set& m_point_set; + Point_map m_point_map; + + template + void reassign_points(Node_index n, Tree& tree, + const Point_d& center, Node_data points, + std::bitset coord = {}, + std::size_t dimension = 0) { + + // Root case: reached the last dimension + if (dimension == Dimension::value) { + tree.points(tree.child(n, coord.to_ulong())) = points; + return; + } + + // Split the point collection around the center point on this dimension + auto split_point = std::partition( + points.begin(), points.end(), + [&](const auto& p) -> bool { + // This should be done with cartesian iterator, + // but it seems complicated to do efficiently + return (get(m_point_map, p)[int(dimension)] < center[int(dimension)]); + } + ); + + // Further subdivide the first side of the split + std::bitset coord_left = coord; + coord_left[dimension] = false; + reassign_points(n, tree, center, {points.begin(), split_point}, coord_left, dimension + 1); + + // Further subdivide the second side of the split + std::bitset coord_right = coord; + coord_right[dimension] = true; + reassign_points(n, tree, center, {split_point, points.end()}, coord_right, dimension + 1); + } + +}; + +} + +#endif //ORTHTREE_TESTS_ORTHTREE_TRAITS_POINT_3_H diff --git a/Orthtree/test/Orthtree/test_node_adjacent.cpp b/Orthtree/test/Orthtree/test_node_adjacent.cpp index 5eeb1f17cb1..29f5b91dfdc 100644 --- a/Orthtree/test/Orthtree/test_node_adjacent.cpp +++ b/Orthtree/test/Orthtree/test_node_adjacent.cpp @@ -36,7 +36,7 @@ int main(void) { points.insert({-1, -1, -1.8}); points.insert({-1, -1, -1.9}); - Octree octree(points, points.point_map()); + Octree octree({points, points.point_map()}); octree.refine(10, 1); std::cout << octree << std::endl; diff --git a/Orthtree/test/Orthtree/test_node_index.cpp b/Orthtree/test/Orthtree/test_node_index.cpp index 34e6f24f5c6..2390c2c1147 100644 --- a/Orthtree/test/Orthtree/test_node_index.cpp +++ b/Orthtree/test/Orthtree/test_node_index.cpp @@ -34,7 +34,7 @@ int main(void) { points.insert({-1, -1, -1.8}); points.insert({-1, -1, -1.9}); - Octree octree(points, points.point_map()); + Octree octree({points, points.point_map()}); octree.refine(10, 1); std::cout << "root: " << octree.local_coordinates(octree.root()) << std::endl; diff --git a/Orthtree/test/Orthtree/test_octree_bbox.cpp b/Orthtree/test/Orthtree/test_octree_bbox.cpp index 1e3718d59ef..c36e0498474 100644 --- a/Orthtree/test/Orthtree/test_octree_bbox.cpp +++ b/Orthtree/test/Orthtree/test_octree_bbox.cpp @@ -20,7 +20,7 @@ void test_1_node() { points.insert({-1, -1, -1}); // Create the octree - Octree octree(points, points.point_map()); + Octree octree({points, points.point_map()}); octree.refine(10, 1); // Compare the top (only) node @@ -35,7 +35,7 @@ void test_9_nodes() { points.insert({1, 1, 1}); // Create the octree - Octree octree(points, points.point_map(), 1.1); + Octree octree({points, points.point_map()}, 1.1); octree.refine(10, 1); // Compare the top node @@ -62,7 +62,7 @@ void test_25_nodes() { points.insert({1, 0.5, 1}); // Create the octree - Octree octree(points, points.point_map(), 1.5); + Octree octree({points, points.point_map()}, 1.5); octree.refine(10, 1); // Compare the top node diff --git a/Orthtree/test/Orthtree/test_octree_copy_move_constructors.cpp b/Orthtree/test/Orthtree/test_octree_copy_move_constructors.cpp index 2b4dd730e47..ee7c8f3be52 100644 --- a/Orthtree/test/Orthtree/test_octree_copy_move_constructors.cpp +++ b/Orthtree/test/Orthtree/test_octree_copy_move_constructors.cpp @@ -24,7 +24,7 @@ int main(void) for (std::size_t i = 0; i < nb_pts; ++i) points.insert(*(generator++)); - Octree base (points, points.point_map()); + Octree base ({points, points.point_map()}); assert (base.is_leaf(base.root())); // base is not refined yet Octree copy1 (base); diff --git a/Orthtree/test/Orthtree/test_octree_custom_properties.cpp b/Orthtree/test/Orthtree/test_octree_custom_properties.cpp index 0ca1dafab13..cb1139a7c04 100644 --- a/Orthtree/test/Orthtree/test_octree_custom_properties.cpp +++ b/Orthtree/test/Orthtree/test_octree_custom_properties.cpp @@ -23,7 +23,7 @@ int main(void) { for (std::size_t i = 0; i < nb_pts; ++i) points.insert(*(generator++)); - Octree tree(points, points.point_map()); + Octree tree({points, points.point_map()}); // Default value should be respected auto &node_int_property = tree.add_node_property("int", 5); diff --git a/Orthtree/test/Orthtree/test_octree_equality.cpp b/Orthtree/test/Orthtree/test_octree_equality.cpp index 1eb88263774..e73a5cf3cbd 100644 --- a/Orthtree/test/Orthtree/test_octree_equality.cpp +++ b/Orthtree/test/Orthtree/test_octree_equality.cpp @@ -26,8 +26,8 @@ void test_identical_trees() { points.insert({1, 1, 1}); // Create a pair of trees from the same point set - Octree a(points, points.point_map()); - Octree b(points, points.point_map()); + Octree a({points, points.point_map()}); + Octree b({points, points.point_map()}); // Refine both trees using the same criteria a.refine(10, 1); @@ -52,8 +52,8 @@ void test_identical_contents_different_criteria() { points.insert({1, 1, 1}); // Create a pair of trees from the same point set - Octree a(points, points.point_map()); - Octree b(points, points.point_map()); + Octree a({points, points.point_map()}); + Octree b({points, points.point_map()}); // Refine both trees using different criteria a.refine(10, 1); @@ -87,8 +87,8 @@ void test_different_contents_identical_criteria() { points_b.insert({1, 1, 2}); // Create a pair of trees from the different point sets - Octree a(points_a, points_a.point_map()); - Octree b(points_b, points_b.point_map()); + Octree a({points_a, points_a.point_map()}); + Octree b({points_b, points_b.point_map()}); // Refine both trees using the same criteria a.refine(10, 1); diff --git a/Orthtree/test/Orthtree/test_octree_grade.cpp b/Orthtree/test/Orthtree/test_octree_grade.cpp index da3b438e3fd..9c0fed16e79 100644 --- a/Orthtree/test/Orthtree/test_octree_grade.cpp +++ b/Orthtree/test/Orthtree/test_octree_grade.cpp @@ -48,7 +48,7 @@ void test(std::size_t dataset_size) { points.insert(*(generator++)); // Build an octree - Octree octree(points, points.point_map()); + Octree octree({points, points.point_map()}); // Refine the octree octree.refine(); diff --git a/Orthtree/test/Orthtree/test_octree_intersecting.cpp b/Orthtree/test/Orthtree/test_octree_intersecting.cpp index a5e385ea98a..5f1fbc3ee75 100644 --- a/Orthtree/test/Orthtree/test_octree_intersecting.cpp +++ b/Orthtree/test/Orthtree/test_octree_intersecting.cpp @@ -34,7 +34,7 @@ int main(void) { points.emplace_back(-0.9, -1, -1); // Create an octree from the vector - Octree octree(points); + Octree octree(Octree::Traits{points}); // Build the octree octree.refine(10, 2); diff --git a/Orthtree/test/Orthtree/test_octree_kernels.cpp b/Orthtree/test/Orthtree/test_octree_kernels.cpp index 58d49eb4fcc..20a2d616aa7 100644 --- a/Orthtree/test/Orthtree/test_octree_kernels.cpp +++ b/Orthtree/test/Orthtree/test_octree_kernels.cpp @@ -18,7 +18,7 @@ void test() for (std::size_t i = 0; i < 100; ++i) points.insert(*(generator++)); - Octree octree(points, points.point_map()); + Octree octree({points, points.point_map()}); octree.refine(); octree.grade(); } diff --git a/Orthtree/test/Orthtree/test_octree_locate.cpp b/Orthtree/test/Orthtree/test_octree_locate.cpp index cffd6c0a3d4..9407afe8d3b 100644 --- a/Orthtree/test/Orthtree/test_octree_locate.cpp +++ b/Orthtree/test/Orthtree/test_octree_locate.cpp @@ -22,7 +22,7 @@ void test_1_point() { points.insert({-1, -1, -1}); // Create the octree - Octree octree(points, points.point_map()); + Octree octree({points, points.point_map()}); octree.refine(10, 1); // Because there's only the root node, any point should be placed in it @@ -48,7 +48,7 @@ void test_8_points() { points.insert({1, 1, 1}); // Create the octree - Octree octree(points, points.point_map()); + Octree octree({points, points.point_map()}); octree.refine(10, 1); // Existing points should end up in the same place @@ -89,7 +89,7 @@ void test_10_points() { points.insert({-1, -0.75, 1}); // Create the octree - Octree octree(points, points.point_map()); + Octree octree({points, points.point_map()}); octree.refine(10, 1); // Existing points should end up in the same place diff --git a/Orthtree/test/Orthtree/test_octree_nearest_neighbor.cpp b/Orthtree/test/Orthtree/test_octree_nearest_neighbor.cpp index bec700dbc46..df58254cb80 100644 --- a/Orthtree/test/Orthtree/test_octree_nearest_neighbor.cpp +++ b/Orthtree/test/Orthtree/test_octree_nearest_neighbor.cpp @@ -68,13 +68,13 @@ void naive_vs_octree(std::size_t dataset_size) { // Do the same using the octree Point octree_nearest = *generator; - Octree octree(points, points.point_map()); + Octree octree({points, points.point_map()}); octree.refine(10, 20); auto octree_start_time = high_resolution_clock::now(); { - std::vector k_neighbors; + std::vector k_neighbors; octree.nearest_neighbors(random_point, 1, std::back_inserter(k_neighbors)); - octree_nearest = *k_neighbors.begin(); + octree_nearest = get(points.point_map(), *k_neighbors.begin()); } duration octree_elapsed_time = high_resolution_clock::now() - octree_start_time; @@ -119,8 +119,8 @@ void kdtree_vs_octree(std::size_t dataset_size, std::size_t K) { << std::endl; // Do the same using the octree - std::vector octree_nearest_neighbors; - Octree octree(points, points.point_map()); + std::vector octree_nearest_neighbors; + Octree octree({points, points.point_map()}); octree.refine(10, 20); auto octree_start_time = high_resolution_clock::now(); octree.nearest_neighbors(random_point, K, std::back_inserter(octree_nearest_neighbors)); @@ -136,7 +136,7 @@ void kdtree_vs_octree(std::size_t dataset_size, std::size_t K) { // Check that they produce the same answer for (std::size_t j = 0; j < K; ++j) - assert(octree_nearest_neighbors[j] == kd_tree_nearest_neighbors[j]); + assert(get(points.point_map(), octree_nearest_neighbors[j]) == kd_tree_nearest_neighbors[j]); } diff --git a/Orthtree/test/Orthtree/test_octree_refine.cpp b/Orthtree/test/Orthtree/test_octree_refine.cpp index ffdefe14a5c..afea2e7734b 100644 --- a/Orthtree/test/Orthtree/test_octree_refine.cpp +++ b/Orthtree/test/Orthtree/test_octree_refine.cpp @@ -38,7 +38,7 @@ void test_1_point() { points.insert({-1, -1, -1}); // Create the octree - Octree octree(points, points.point_map()); + Octree octree({points, points.point_map()}); octree.refine(10, 1); // Check that the root node was never split @@ -54,11 +54,11 @@ void test_2_points() { points.insert({1, -1, -1}); // Create the octree - Octree octree(points, points.point_map()); + Octree octree({points, points.point_map()}); octree.refine(10, 1); // The octree should have been split once - Octree other(points, points.point_map()); + Octree other({points, points.point_map()}); other.split(other.root()); assert(Octree::is_topology_equal(other, octree)); assert(1 == octree.depth()); @@ -73,11 +73,11 @@ void test_4_points() { points.insert({1, 1, 4}); // Create the octree - Octree octree(points, points.point_map()); + Octree octree({points, points.point_map()}); octree.refine(10, 1); // The octree should have been split once on the first level, and twice on the second - Octree other(points, points.point_map()); + Octree other({points, points.point_map()}); other.split(other.root()); other.split(other.node(3)); other.split(other.node(7)); diff --git a/Orthtree/test/Orthtree/test_octree_traverse.cpp b/Orthtree/test/Orthtree/test_octree_traverse.cpp index 85217f77f92..0d442051faf 100644 --- a/Orthtree/test/Orthtree/test_octree_traverse.cpp +++ b/Orthtree/test/Orthtree/test_octree_traverse.cpp @@ -22,7 +22,7 @@ bool test_preorder_1_node() { points.insert({-1, -1, -1}); // Create the octree - Octree octree(points, points.point_map()); + Octree octree({points, points.point_map()}); octree.refine(10, 1); // Create the range @@ -43,7 +43,7 @@ bool test_preorder_9_nodes() { points.insert({1, -1, -1}); // Create the octree - Octree octree(points, points.point_map()); + Octree octree({points, points.point_map()}); octree.refine(10, 1); // Create the range @@ -68,7 +68,7 @@ bool test_level_9_nodes() { points.insert({1, -1, -1}); // Create the octree - Octree octree(points, points.point_map()); + Octree octree({points, points.point_map()}); octree.refine(10, 1); // Create the range @@ -94,7 +94,7 @@ bool test_preorder_25_nodes() { points.insert({1, 1, 4}); // Create the octree - Octree octree(points, points.point_map()); + Octree octree({points, points.point_map()}); octree.refine(10, 1); // Create the range