Skip to content

Commit

Permalink
Issue: #29 Independent storage
Browse files Browse the repository at this point in the history
  • Loading branch information
attcs committed Jul 28, 2024
1 parent 089f0b6 commit 2b42abf
Show file tree
Hide file tree
Showing 12 changed files with 1,654 additions and 486 deletions.
30 changes: 27 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ What is the Octree and what is good for? https://en.wikipedia.org/wiki/Octree

## Features
* Adaptable to any existing geometric system
* Adaptable to the original container of geometrical entities
* Arbitrary number of dimensions for other scientific usages
* Support of `std::execution` policies (so it is parallelizable)
* Edit functions to Insert/Update/Erase entities
Expand All @@ -32,7 +33,7 @@ What is the Octree and what is good for? https://en.wikipedia.org/wiki/Octree

## Usage
* Use `AdaptorBasicsConcept` or `AdaptorConcept` to adapt the actual geometric system. It is not a necessary step, basic point/vector and bounding box objects are available.
* Use the static member function `Create()` for a contiguous container (any `std::span` compatible) of Points or Bounding boxes to build the tree. It supports `std::execution` policies (e.g.: `std::execution::parallel_unsequenced_policy`) which can be effectively used to parallelize the creation process. (Template argument of the `Create()` functions)
* Use the static member function `Create()` for a container (`std::unordered_map` or any `std::span` compatible) of Points or Bounding boxes to build the tree. It supports `std::execution` policies (e.g.: `std::execution::parallel_unsequenced_policy`) which can be effectively used to parallelize the creation process. (Template argument of the `Create()` functions)
* Use `PickSearch()` / `RangeSearch()` member functions to collect the wanted id-s
* Use `PlaneSearch()` / `PlaneIntersection()` / `PlanePositiveSegmentation()` member functions for hyperplane related searches
* Use `FrustumCulling()` to get entities in the multi-plane-bounded space/frustum
Expand All @@ -46,9 +47,13 @@ What is the Octree and what is good for? https://en.wikipedia.org/wiki/Octree

## Notes
* Header only implementation.
* Point and Bounding box-based solution is distinguished.
* Point and Bounding box-based solutions are distinguished.
* Core types store only the entity ids, use Container types to store. Core types advantages: not copying and managing the entity information; disadvantages: this information may have to be provided again for the member function call.
* Container types have "C" postfix (e.g.: core `OctreeBox`'s container is `OctreeBoxC`).
* Naming
* Container types have "C" postfix (e.g.: core `OctreeBox`'s container is `OctreeBoxC`).
* `Map` named aliases are declared for `std::unordered_map` geometry containers (e.g.: `QuadtreeBoxMap`, `OctreeBoxMap`, `OctreeBoxMapC`). Non-`Map` named aliases uses `std::span`, which is compatible with `std::vector`, `std::array` or any contigous container.
* `s` means adjustable `SPLIT_DEPTH_INCREASEMENT` for box-types.
* If `int` is preferred for indexig instead of `std::size_t`, declare `#define ORTHOTREE_INDEX_T__INT`.
* Bounding box-based solution stores item id in the parent node if it is not fit into any child node. Using `SPLIT_DEPTH_INCREASEMENT` template parameter, these boxes can be splitted then placed on the deeper level of the tree. The `SPLIT_DEPTH_INCREASEMENT` default is 2 and this split method is applied by default.
* Edit functions are available but not recommended to majorly build the tree.
* If less element is collected in a node than the max element then the child node won't be created.
Expand Down Expand Up @@ -206,6 +211,25 @@ Usage of Container types
, 3
);
}


// Example #4: Using std::unordered_map-based container
{
auto boxes = std::unordered_map<OrthoTree::index_t, BoundingBox2D>{
{ 10, BoundingBox2D{{ 0.0, 0.0 }, { 1.0, 1.0 }}},
{ 13, BoundingBox2D{{ 3.0, 3.0 }, { 4.0, 4.0 }}},
{ 11, BoundingBox2D{{ 1.0, 1.0 }, { 2.0, 2.0 }}},
{ 14, BoundingBox2D{{ 1.2, 1.2 }, { 2.8, 2.8 }}},
{ 12, BoundingBox2D{{ 2.0, 2.0 }, { 3.0, 3.0 }}}
};

auto qt = QuadtreeBoxMap(
boxes,
3, // max depth
std::nullopt, // user-provided bounding Box for all
2 // max element in a node
);
}
```
Usage of Core types
Expand Down
95 changes: 83 additions & 12 deletions adaptor.boost.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,17 +191,18 @@ namespace OrthoTree
TGeometry,
AdaptorGeneralBasics<DIMENSION_NO, TGeometry>>;

template<dim_t DIMENSION_NO, typename TGeometry>
template<dim_t DIMENSION_NO, typename TGeometry, typename TContainer = std::span<boost::geometry::model::pointNd_t<DIMENSION_NO, TGeometry> const>>
using BoostOrthoTreePoint = OrthoTreePoint<
DIMENSION_NO,
boost::geometry::model::pointNd_t<DIMENSION_NO, TGeometry>,
boost::geometry::model::boxNd_t<DIMENSION_NO, TGeometry>,
boost::geometry::model::rayNd_t<DIMENSION_NO, TGeometry>,
boost::geometry::model::planeNd_t<DIMENSION_NO, TGeometry>,
TGeometry,
BoostAdaptorGeneral<DIMENSION_NO, TGeometry>>;
BoostAdaptorGeneral<DIMENSION_NO, TGeometry>,
TContainer>;

template<dim_t DIMENSION_NO, uint32_t SPLIT_DEPTH_INCREASEMENT, typename TGeometry>
template<dim_t DIMENSION_NO, uint32_t SPLIT_DEPTH_INCREASEMENT, typename TGeometry, typename TContainer = std::span<boost::geometry::model::boxNd_t<DIMENSION_NO, TGeometry> const>>
using BoostOrthoTreeBoundingBox = OrthoTreeBoundingBox<
DIMENSION_NO,
boost::geometry::model::pointNd_t<DIMENSION_NO, TGeometry>,
Expand All @@ -210,7 +211,8 @@ namespace OrthoTree
boost::geometry::model::planeNd_t<DIMENSION_NO, TGeometry>,
TGeometry,
SPLIT_DEPTH_INCREASEMENT,
BoostAdaptorGeneral<DIMENSION_NO, TGeometry>>;
BoostAdaptorGeneral<DIMENSION_NO, TGeometry>,
TContainer>;
} // namespace BoostAdaptor
} // namespace OrthoTree

Expand All @@ -220,8 +222,16 @@ namespace boost::geometry

// Core types

template<int DIMENSION_NO, typename TGeometry = double>
using orthotree_point_t = BoostOrthoTreePoint<DIMENSION_NO, TGeometry>;
template<int DIMENSION_NO, typename TGeometry = double, typename TContainer = std::span<model::pointNd_t<DIMENSION_NO, TGeometry> const>>
using orthotree_point_t = BoostOrthoTreePoint<DIMENSION_NO, TGeometry, TContainer>;

template<
int DIMENSION_NO,
uint32_t SPLIT_DEPTH_INCREASEMENT = 2,
typename TGeometry = double,
typename TContainer = std::span<model::boxNd_t<DIMENSION_NO, TGeometry> const>>
using orthotree_box_t = BoostOrthoTreeBoundingBox<DIMENSION_NO, SPLIT_DEPTH_INCREASEMENT, TGeometry, TContainer>;


using quadtree_point_d = BoostOrthoTreePoint<2, double>;
using quadtree_point_f = BoostOrthoTreePoint<2, float>;
Expand All @@ -234,9 +244,6 @@ namespace boost::geometry
using octree_point = octree_point_d;


template<int DIMENSION_NO, uint32_t SPLIT_DEPTH_INCREASEMENT = 2, typename TGeometry = double>
using orthotree_box_t = BoostOrthoTreeBoundingBox<DIMENSION_NO, SPLIT_DEPTH_INCREASEMENT, TGeometry>;

template<uint32_t SPLIT_DEPTH_INCREASEMENT = 2>
using quadtree_box_ds = BoostOrthoTreeBoundingBox<2, SPLIT_DEPTH_INCREASEMENT, double>;
using quadtree_box_d = BoostOrthoTreeBoundingBox<2, 2, double>;
Expand All @@ -254,7 +261,7 @@ namespace boost::geometry
// Container types

template<int DIMENSION_NO, typename TGeometry = double>
using orthotree_point_c_t = OrthoTree::OrthoTreeContainerPoint<orthotree_point_t<DIMENSION_NO, TGeometry>, model::pointNd_t<DIMENSION_NO, TGeometry>>;
using orthotree_point_c_t = OrthoTree::OrthoTreeContainerPoint<orthotree_point_t<DIMENSION_NO, TGeometry>>;

using quadtree_point_c_d = orthotree_point_c_t<2, double>;
using quadtree_point_c_f = orthotree_point_c_t<2, float>;
Expand All @@ -268,8 +275,7 @@ namespace boost::geometry


template<int DIMENSION_NO, uint32_t SPLIT_DEPTH_INCREASEMENT = 2, typename TGeometry = double>
using orthotree_box_c_t =
OrthoTree::OrthoTreeContainerBox<orthotree_box_t<DIMENSION_NO, SPLIT_DEPTH_INCREASEMENT, TGeometry>, model::boxNd_t<DIMENSION_NO, TGeometry>>;
using orthotree_box_c_t = OrthoTree::OrthoTreeContainerBox<orthotree_box_t<DIMENSION_NO, SPLIT_DEPTH_INCREASEMENT, TGeometry>>;

template<uint32_t SPLIT_DEPTH_INCREASEMENT = 2>
using quadtree_box_c_ds = orthotree_box_c_t<2, SPLIT_DEPTH_INCREASEMENT, double>;
Expand All @@ -284,4 +290,69 @@ namespace boost::geometry
using octree_box_c_f = orthotree_box_c_t<3, 2, float>;
using octree_box_c_i = orthotree_box_c_t<3, 2, int>;
using octree_box_c = octree_box_c_d;


// Map types

template<typename TEntity>
using map_container = std::unordered_map<size_t, TEntity>;

using quadtree_point_map_d = BoostOrthoTreePoint<2, double, map_container<model::pointNd_t<2, double>>>;
using quadtree_point_map_f = BoostOrthoTreePoint<2, float, map_container<model::pointNd_t<2, float>>>;
using quadtree_point_map_i = BoostOrthoTreePoint<2, int, map_container<model::pointNd_t<2, int>>>;
using quadtree_point_map = quadtree_point_map_d;

using octree_point_map_d = BoostOrthoTreePoint<3, double, map_container<model::pointNd_t<3, double>>>;
using octree_point_map_f = BoostOrthoTreePoint<3, float, map_container<model::pointNd_t<3, float>>>;
using octree_point_map_i = BoostOrthoTreePoint<3, int, map_container<model::pointNd_t<3, int>>>;
using octree_point_map = octree_point_map_d;


template<uint32_t SPLIT_DEPTH_INCREASEMENT = 2>
using quadtree_box_map_ds = BoostOrthoTreeBoundingBox<2, SPLIT_DEPTH_INCREASEMENT, double, map_container<model::boxNd_t<2, double>>>;
using quadtree_box_map_d = BoostOrthoTreeBoundingBox<2, 2, double, map_container<model::boxNd_t<2, double>>>;
using quadtree_box_map_f = BoostOrthoTreeBoundingBox<2, 2, float, map_container<model::boxNd_t<2, float>>>;
using quadtree_box_map_i = BoostOrthoTreeBoundingBox<2, 2, int, map_container<model::boxNd_t<2, int>>>;
using quadtree_box_map = quadtree_box_map_d;

template<uint32_t SPLIT_DEPTH_INCREASEMENT = 2>
using octree_box_map_ds = BoostOrthoTreeBoundingBox<3, SPLIT_DEPTH_INCREASEMENT, double, map_container<model::boxNd_t<3, double>>>;
using octree_box_map_d = BoostOrthoTreeBoundingBox<3, 2, double, map_container<model::boxNd_t<3, double>>>;
using octree_box_map_f = BoostOrthoTreeBoundingBox<3, 2, float, map_container<model::boxNd_t<3, float>>>;
using octree_box_map_i = BoostOrthoTreeBoundingBox<3, 2, int, map_container<model::boxNd_t<3, int>>>;
using octree_box_map = octree_box_map_d;

// Container types

template<int DIMENSION_NO, typename TGeometry = double>
using orthotree_point_map_c_t = OrthoTree::OrthoTreeContainerPoint<orthotree_point_t<DIMENSION_NO, TGeometry, map_container<model::pointNd_t<DIMENSION_NO, TGeometry>>>>;

using quadtree_point_map_c_d = orthotree_point_map_c_t<2, double>;
using quadtree_point_map_c_f = orthotree_point_map_c_t<2, float>;
using quadtree_point_map_c_i = orthotree_point_map_c_t<2, int>;
using quadtree_point_map_c = quadtree_point_map_c_d;

using octree_point_map_c_d = orthotree_point_c_t<3, double>;
using octree_point_map_c_f = orthotree_point_c_t<3, float>;
using octree_point_map_c_i = orthotree_point_c_t<3, int>;
using octree_point_map_c = octree_point_map_c_d;


template<int DIMENSION_NO, uint32_t SPLIT_DEPTH_INCREASEMENT = 2, typename TGeometry = double>
using orthotree_box_map_c_t = OrthoTree::OrthoTreeContainerBox<orthotree_box_t<DIMENSION_NO, SPLIT_DEPTH_INCREASEMENT, TGeometry, map_container<model::boxNd_t<DIMENSION_NO, TGeometry>>>>;

template<uint32_t SPLIT_DEPTH_INCREASEMENT = 2>
using quadtree_box_map_c_ds = orthotree_box_map_c_t<2, SPLIT_DEPTH_INCREASEMENT, double>;
using quadtree_box_map_c_d = orthotree_box_map_c_t<2, 2, double>;
using quadtree_box_map_c_f = orthotree_box_map_c_t<2, 2, float>;
using quadtree_box_map_c_i = orthotree_box_map_c_t<2, 2, int>;
using quadtree_box_map_c = quadtree_box_map_c_d;

template<uint32_t SPLIT_DEPTH_INCREASEMENT = 2>
using octree_box_map_c_ds = orthotree_box_map_c_t<3, SPLIT_DEPTH_INCREASEMENT, double>;
using octree_box_map_c_d = orthotree_box_map_c_t<3, 2, double>;
using octree_box_map_c_f = orthotree_box_map_c_t<3, 2, float>;
using octree_box_map_c_i = orthotree_box_map_c_t<3, 2, int>;
using octree_box_map_c = octree_box_map_c_d;

} // namespace boost::geometry
76 changes: 72 additions & 4 deletions adaptor.cgal.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,13 +198,81 @@ namespace CGAL

// Container types

using QuadtreePointC = OrthoTree::OrthoTreeContainerPoint<QuadtreePoint, Point_2<Cartesian<double>>>;
using OctreePointC = OrthoTree::OrthoTreeContainerPoint<OctreePoint, Point_3<Cartesian<double>>>;
using QuadtreePointC = OrthoTree::OrthoTreeContainerPoint<QuadtreePoint>;
using OctreePointC = OrthoTree::OrthoTreeContainerPoint<OctreePoint>;

template<int SPLIT_DEPTH_INCREASEMENT>
using QuadtreeBoxCs = OrthoTree::OrthoTreeContainerBox<QuadtreeBoxs<SPLIT_DEPTH_INCREASEMENT>, Bbox_2>;
using QuadtreeBoxCs = OrthoTree::OrthoTreeContainerBox<QuadtreeBoxs<SPLIT_DEPTH_INCREASEMENT>>;
using QuadtreeBoxC = QuadtreeBoxCs<2>;
template<int SPLIT_DEPTH_INCREASEMENT>
using OctreeBoxCs = OrthoTree::OrthoTreeContainerBox<OctreeBoxs<SPLIT_DEPTH_INCREASEMENT>, Bbox_3>;
using OctreeBoxCs = OrthoTree::OrthoTreeContainerBox<OctreeBoxs<SPLIT_DEPTH_INCREASEMENT>>;
using OctreeBoxC = OctreeBoxCs<2>;


// Map types

template<typename T>
using CGALContainer = std::unordered_map<std::size_t, T>;

// Core types
using QuadtreePointMap = OrthoTree::OrthoTreePoint<
2,
CGAL::Point_2<CGAL::Cartesian<double>>,
CGAL::Bbox_2,
CGAL::Ray_2<CGAL::Cartesian<double>>,
CGAL::Plane_2,
double,
CGALAdaptorGeneral2D,
CGALContainer<CGAL::Point_2<CGAL::Cartesian<double>>>>;

using OctreePointMap = OrthoTree::OrthoTreePoint<
3,
CGAL::Point_3<CGAL::Cartesian<double>>,
CGAL::Bbox_3,
CGAL::Ray_3<CGAL::Cartesian<double>>,
CGAL::Plane_3<CGAL::Cartesian<double>>,
double,
CGALAdaptorGeneral3D,
CGALContainer<CGAL::Point_3<CGAL::Cartesian<double>>>>;

template<int SPLIT_DEPTH_INCREASEMENT>
using QuadtreeBoxsMap = OrthoTree::OrthoTreeBoundingBox<
2,
CGAL::Point_2<CGAL::Cartesian<double>>,
CGAL::Bbox_2,
CGAL::Ray_2<CGAL::Cartesian<double>>,
CGAL::Plane_2,
double,
SPLIT_DEPTH_INCREASEMENT,
CGALAdaptorGeneral2D,
CGALContainer<CGAL::Bbox_2>>;

using QuadtreeBoxMap = QuadtreeBoxs<2>;

template<int SPLIT_DEPTH_INCREASEMENT>
using OctreeBoxsMap = OrthoTree::OrthoTreeBoundingBox<
3,
CGAL::Point_3<CGAL::Cartesian<double>>,
CGAL::Bbox_3,
CGAL::Ray_3<CGAL::Cartesian<double>>,
CGAL::Plane_3<CGAL::Cartesian<double>>,
double,
SPLIT_DEPTH_INCREASEMENT,
CGALAdaptorGeneral3D,
CGALContainer<CGAL::Bbox_3>>;

using OctreeBoxMap = OctreeBoxsMap<2>;


// Container types

using QuadtreePointMapC = OrthoTree::OrthoTreeContainerPoint<QuadtreePointMap>;
using OctreePointMapC = OrthoTree::OrthoTreeContainerPoint<OctreePointMap>;

template<int SPLIT_DEPTH_INCREASEMENT>
using QuadtreeBoxMapCs = OrthoTree::OrthoTreeContainerBox<QuadtreeBoxsMap<SPLIT_DEPTH_INCREASEMENT>>;
using QuadtreeBoxMapC = QuadtreeBoxMapCs<2>;
template<int SPLIT_DEPTH_INCREASEMENT>
using OctreeBoxMapCs = OrthoTree::OrthoTreeContainerBox<OctreeBoxsMap<SPLIT_DEPTH_INCREASEMENT>>;
using OctreeBoxMapC = OctreeBoxMapCs<2>;
} // namespace CGAL
Loading

0 comments on commit 2b42abf

Please sign in to comment.