diff --git a/Orthtree/examples/Orthtree/orthtree_build.cpp b/Orthtree/examples/Orthtree/orthtree_build.cpp index a721b2c6723..3af483eb8fc 100644 --- a/Orthtree/examples/Orthtree/orthtree_build.cpp +++ b/Orthtree/examples/Orthtree/orthtree_build.cpp @@ -12,7 +12,7 @@ typedef CGAL::Epick_d Kernel; typedef Kernel::Point_d Point_d; typedef std::vector Point_vector; -typedef CGAL::Orthtree_traits_point_d Traits; +typedef CGAL::Orthtree_traits_point Traits; typedef CGAL::Orthtree Orthtree; int main() diff --git a/Orthtree/examples/Orthtree/quadtree_build_manually.cpp b/Orthtree/examples/Orthtree/quadtree_build_manually.cpp index 55be9e46ed6..f0fe27d1f20 100644 --- a/Orthtree/examples/Orthtree/quadtree_build_manually.cpp +++ b/Orthtree/examples/Orthtree/quadtree_build_manually.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include using Kernel = CGAL::Simple_cartesian; @@ -13,15 +13,15 @@ namespace CGAL { struct empty_type { }; -template -struct Orthtree_traits_empty_2 : public Orthtree_traits_2_base { +template +struct Orthtree_traits_empty : public Orthtree_traits_base_for_dimension { - using Self = Orthtree_traits_empty_2; + using Self = Orthtree_traits_empty; using Tree = Orthtree; using Node_data = std::array; - Orthtree_traits_empty_2(typename Self::Bbox_d bbox) : m_bbox(bbox) {}; + Orthtree_traits_empty(typename Self::Bbox_d bbox) : m_bbox(bbox) {}; auto root_node_bbox_object() const { return [&]() -> typename Self::Bbox_d { return m_bbox; }; @@ -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 9911668d67b..324d655e1d9 100644 --- a/Orthtree/include/CGAL/Octree.h +++ b/Orthtree/include/CGAL/Octree.h @@ -43,7 +43,7 @@ template < #ifdef DOXYGEN_RUNNING class Octree; #else -using Octree = Orthtree>; +using Octree = Orthtree>>; #endif } // namespace CGAL diff --git a/Orthtree/include/CGAL/Orthtree_traits_base_for_dimension.h b/Orthtree/include/CGAL/Orthtree_traits_base_for_dimension.h new file mode 100644 index 00000000000..fb7d4f6b2f9 --- /dev/null +++ b/Orthtree/include/CGAL/Orthtree_traits_base_for_dimension.h @@ -0,0 +1,196 @@ +// 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_EXAMPLES_ORTHTREE_TRAITS_BASE_FOR_DIMENSION_H +#define ORTHTREE_EXAMPLES_ORTHTREE_TRAITS_BASE_FOR_DIMENSION_H + +#include + +#include +#include +#include +#include + +namespace CGAL { + +template +struct Orthtree_traits_base_for_dimension; + +template +struct Orthtree_traits_base_for_dimension { + /// \name Types + /// @{ + using Dimension = DimensionTag; + using FT = typename K::FT; + using Point_d = typename K::Point_d; + using Bbox_d = typename K::Iso_box_d; + using Sphere_d = typename K::Sphere_d; + using Cartesian_const_iterator_d = typename K::Cartesian_const_iterator_d; + /*! + Adjacency type. + + \note This type is used to identify adjacency directions with + easily understandable keywords (left, right, up, etc.) and is thus + mainly useful for `Orthtree_traits_2` and `Orthtree_traits_3`. 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 easier API for adjacency selection. + */ + using Adjacency = int; + /// @} + + /// \name Operations + /// @{ + auto construct_point_d_object() const { + return [](auto... Args) -> Point_d { + std::initializer_list args_list{Args...}; + return Point_d{args_list.size(), args_list.begin(), args_list.end()}; + }; + } + /// @} +}; + +template +struct Orthtree_traits_base_for_dimension> { + /// \name Types + /// @{ + using Dimension = Dimension_tag<2>; + using FT = typename K::FT; + using Point_d = typename K::Point_2; + using Bbox_d = typename K::Iso_rectangle_2; + using Sphere_d = typename K::Circle_2; + using Cartesian_const_iterator_d = typename K::Cartesian_const_iterator_2; + /*! + * \brief Two directions along each axis in Cartesian space, relative to a node. + * + * Directions are mapped to numbers as 2-bit integers. + * + * The first bit indicates the axis (0 = x, 1 = y), + * the second bit indicates the direction along that axis (0 = -, 1 = +). + * + * The following diagram may be a useful reference: + * + * 3 * + * | + * | y+ + * | * + * 0 *------+------* 1 | + * | | + * | +-----* x+ + * | + * * 2 + * + * This lookup table may also be helpful: + * + * | Direction | bitset | number | Enum | + * | --------- | ------ | ------ | ----- | + * | `-x` | 00 | 0 | LEFT | + * | `+x` | 01 | 1 | RIGHT | + * | `-y` | 10 | 2 | DOWN | + * | `+y` | 11 | 3 | UP | + */ + enum Adjacency { + LEFT, + RIGHT, + DOWN, + UP + }; + /// @} + + /// \name Operations + /// @{ + auto construct_point_d_object() const { + return [](const FT& x, const FT& y) -> Point_d { + return {x, y}; + }; + } + /// @} +}; + +template +struct Orthtree_traits_base_for_dimension> { + /// \name Types + /// @{ + using GeomTraits = K; + using Dimension = Dimension_tag<3>; + using FT = typename K::FT; + using Point_d = typename K::Point_3; + using Bbox_d = typename K::Iso_cuboid_3; + using Sphere_d = typename K::Sphere_3; + using Cartesian_const_iterator_d = typename K::Cartesian_const_iterator_3; + /*! + * \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 + /// @} + + /// \name Operations + /// @{ + auto construct_point_d_object() const { + return [](const FT& x, const FT& y, const FT& z) -> Point_d { + return {x, y, z}; + }; + } + /// @} +}; + + +} + +#endif //ORTHTREE_EXAMPLES_ORTHTREE_TRAITS_BASE_FOR_DIMENSION_H diff --git a/Orthtree/include/CGAL/Orthtree_traits_face_graph.h b/Orthtree/include/CGAL/Orthtree_traits_face_graph.h index 084baed7b4d..144564ebf79 100644 --- a/Orthtree/include/CGAL/Orthtree_traits_face_graph.h +++ b/Orthtree/include/CGAL/Orthtree_traits_face_graph.h @@ -15,7 +15,7 @@ #include -#include +#include #include #include @@ -23,8 +23,15 @@ namespace CGAL { template -struct Orthtree_traits_face_graph - : public Orthtree_traits_3_base::value_type>::type> { +struct Orthtree_traits_face_graph : public Orthtree_traits_base_for_dimension< + typename Kernel_traits::value_type>::type, + Dimension_tag<3> + // todo: it should be possible to determine the ambient dimension automatically, but this isn't working +// Ambient_dimension< +// typename boost::property_traits::value_type, +// typename Kernel_traits::value_type>::type +// > +> { Orthtree_traits_face_graph(const PolygonMesh& pm, VPM vpm) : m_pm(pm), m_vpm(vpm) {} @@ -110,8 +117,9 @@ struct Orthtree_traits_face_graph if (tree.data(ni).empty()) return false; Bbox_d bb = tree.bbox(ni); - //TODO: we should get better version to get guarantees + // TODO: we should get better version to get guarantees // TODO: as long as the bbox is cubic you can use depth and initial size to conclude. + // todo (jackson): bbox is _not_ guaranteed to be cubic now, this may break in some very niche cases for (int i = 0; i < 3; ++i) if ((bb.max()[i] - bb.min()[i]) < 2 * m_min_extent) return false; diff --git a/Orthtree/include/CGAL/Orthtree_traits_point.h b/Orthtree/include/CGAL/Orthtree_traits_point.h index b94acca60b9..dd4803e07bf 100644 --- a/Orthtree/include/CGAL/Orthtree_traits_point.h +++ b/Orthtree/include/CGAL/Orthtree_traits_point.h @@ -19,9 +19,7 @@ #include #include -#include -#include -#include +#include namespace CGAL { @@ -78,16 +76,19 @@ void reassign_points( template < typename GeomTraits, typename PointSet, - typename PointMap, - typename OrthtreeTraitsDimensionBase + typename PointMap = Identity_property_map::value_type>, + typename DimensionTag = Ambient_dimension< + typename std::iterator_traits::value_type, + GeomTraits + > > -struct Orthtree_traits_point : public OrthtreeTraitsDimensionBase { +struct Orthtree_traits_point : public Orthtree_traits_base_for_dimension { public: /// \name Types /// @{ - using Self = Orthtree_traits_point; + using Self = Orthtree_traits_point; using Tree = Orthtree; using Node_data = boost::iterator_range; @@ -163,31 +164,6 @@ private: }; -template < - typename GeomTraits, - typename PointSet, - typename PointMap = Identity_property_map -> -using Orthtree_traits_point_2 = - Orthtree_traits_point>; - -template < - typename GeomTraits, - typename PointSet, - typename PointMap = Identity_property_map -> -using Orthtree_traits_point_3 = - Orthtree_traits_point>; - -template < - typename GeomTraits, - typename DimensionTag, - typename PointSet, - typename PointMap = Identity_property_map -> -using Orthtree_traits_point_d = - Orthtree_traits_point>; - } diff --git a/Orthtree/include/CGAL/Quadtree.h b/Orthtree/include/CGAL/Quadtree.h index 52184807e3b..5ed4dc1baab 100644 --- a/Orthtree/include/CGAL/Quadtree.h +++ b/Orthtree/include/CGAL/Quadtree.h @@ -41,7 +41,7 @@ template >; +using Quadtree = Orthtree>>; #endif } // namespace CGAL