Skip to content

Commit 574d8c3

Browse files
committed
Merge branch 'faster_split_box_creation'
2 parents 23162a3 + a377ec2 commit 574d8c3

File tree

16 files changed

+1323
-956
lines changed

16 files changed

+1323
-956
lines changed

README.md

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ What is Morton-Z space-filling curve? https://en.wikipedia.org/wiki/Z-order_curv
1212
* Adaptable to any existing geometric system
1313
* Adaptable to the original container of geometrical entities
1414
* Arbitrary number of dimensions for other scientific usages
15-
* Support of `std::execution` policies (so it is parallelizable)
15+
* Parallelization is available (via `std::execution` policies)
1616
* Edit functions to Insert/Update/Erase entities
1717
* Wide range of search functions
1818
* Range search
@@ -35,7 +35,8 @@ What is Morton-Z space-filling curve? https://en.wikipedia.org/wiki/Z-order_curv
3535

3636
## Usage
3737
* 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.
38-
* 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)
38+
* Decide to let the geometry management for octree or not. `Container` types could manage the geometries life-cycle, meanwhile the `non-container` types are just update the relevant metadata about the changes.
39+
* Use `PAR_EXEC` tag as first parameter of constructor for parallel execution
3940
* Use `PickSearch()` / `RangeSearch()` member functions to collect the wanted id-s
4041
* Use `PlaneSearch()` / `PlaneIntersection()` / `PlanePositiveSegmentation()` member functions for hyperplane related searches
4142
* Use `FrustumCulling()` to get entities in the multi-plane-bounded space/frustum
@@ -55,9 +56,9 @@ What is Morton-Z space-filling curve? https://en.wikipedia.org/wiki/Z-order_curv
5556
* Naming
5657
* Container types have "C" postfix (e.g.: core `OctreeBox`'s container is `OctreeBoxC`).
5758
* `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.
58-
* `s` means adjustable `SPLIT_DEPTH_INCREASEMENT` for box-types.
59+
* `s` means adjustable `DO_SPLIT_PARENT_ENTITIES` for box-types.
5960
* If `int` is preferred for indexing instead of `std::size_t`, declare `#define ORTHOTREE_INDEX_T__INT`.
60-
* 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.
61+
* Bounding box-based solution stores item id in the parent node if it is not fit into any child node. Using `DO_SPLIT_PARENT_ENTITIES` template parameter, these boxes can be splitted and placed on the first child level of the node. The `DO_SPLIT_PARENT_ENTITIES` default is `true`, it is applied by default.
6162
* Edit functions are available but not recommended to fully build the tree with them.
6263
* If less element is collected in a node than the max element then the child node won't be created.
6364
* The underlying container is a hash-table (`std::unordered_map`) under 16D, which only stores the id-s and the bounding box of the child nodes.
@@ -67,8 +68,8 @@ What is Morton-Z space-filling curve? https://en.wikipedia.org/wiki/Z-order_curv
6768
## Recommendations
6869
* If the geometrical entities are already available, build the tree using the Constructor or Create, rather than entity-wise Insertions. This can result in a significant performance gain.
6970
* For tree building, `InsertWithRebalancing()` offers much better performance than Insert() with leaf-node settings.
70-
* If the box tree is used only for collision detection, set `SPLIT_DEPTH_INCREASEMENT = 0` (`OctreeBox` uses 2 by default). Both creation and collision detection will be significantly faster.
71-
* For `Pick`/`Range`/`Ray`/`Plane` related search, the default `SPLIT_DEPTH_INCREASEMENT = 2` is recommended.
71+
* If the box tree is used only for collision detection, set `DO_SPLIT_PARENT_ENTITIES = false` (`OctreeBox` uses `true` by default). Both creation and collision detection will be significantly faster.
72+
* For `Pick`/`Range`/`Ray`/`Plane` related search, the default `DO_SPLIT_PARENT_ENTITIES = true` is recommended.
7273
* If the overall modeling space size changes dynamically, this tool cannot be applied directly. However, you can combine it with sparse grid-based spatial partitioning, where each cell contains an `Orthotree`.
7374
* After calling `Init()`, the max depth cannot be changed, and the tree cannot be deepened further.
7475
* See the **BENCHMARKS** page for performance-related graphs.
@@ -139,17 +140,17 @@ The following defines can be used before the header file include:
139140
using QuadtreePointC = TreePointContainerND<2, BaseGeometryType>;
140141

141142
// Quadtree for bounding boxes
142-
template<uint32_t SPLIT_DEPTH_INCREASEMENT = 2>
143-
using QuadtreeBoxCs = TreeBoxContainerND<2, SPLIT_DEPTH_INCREASEMENT, BaseGeometryType>;
144-
using QuadtreeBoxC = TreeBoxContainerND<2, 2, BaseGeometryType>;
143+
template<bool DO_SPLIT_PARENT_ENTITIES = true>
144+
using QuadtreeBoxCs = TreeBoxContainerND<2, DO_SPLIT_PARENT_ENTITIES, BaseGeometryType>;
145+
using QuadtreeBoxC = TreeBoxContainerND<2, true, BaseGeometryType>;
145146

146147
// Octree for points
147148
using OctreePointC = TreePointContainerND<3, BaseGeometryType>;
148149

149150
// Octree for bounding boxes
150-
template<uint32_t SPLIT_DEPTH_INCREASEMENT = 2>
151-
using OctreeBoxCs = TreeBoxContainerND<3, 2, BaseGeometryType>;
152-
using OctreeBoxC = TreeBoxContainerND<3, 2, BaseGeometryType>;
151+
template<bool DO_SPLIT_PARENT_ENTITIES = true>
152+
using OctreeBoxCs = TreeBoxContainerND<3, DO_SPLIT_PARENT_ENTITIES, BaseGeometryType>;
153+
using OctreeBoxC = TreeBoxContainerND<3, true, BaseGeometryType>;
153154
```
154155

155156
## Basic examples
@@ -216,11 +217,11 @@ Usage of Container types
216217
/* and more... */
217218
};
218219

219-
auto octreeUsingCtor = OctreeBoxC(boxes
220+
auto octreeUsingCtor = OctreeBoxC(PAR_EXEC
221+
, boxes
220222
, 3
221223
, std::nullopt
222224
, OctreeBox::DEFAULT_MAX_ELEMENT
223-
, true // Set std::execution::parallel_unsequenced_policy
224225
);
225226

226227
auto octreeUsingCreate = OctreeBoxC::Create<true>(boxes, 3);
@@ -378,7 +379,7 @@ using QuadtreeBoxCustom = OrthoTree::OrthoTreeBoundingBox<
378379
MyRay2D,
379380
MyPlane2D,
380381
float,
381-
2,
382+
true,
382383
AdaptorCustom>;
383384
```
384385

adaptor.boost.h

Lines changed: 48 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -202,15 +202,15 @@ namespace OrthoTree
202202
BoostAdaptorGeneral<DIMENSION_NO, TGeometry>,
203203
TContainer>;
204204

205-
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>>
205+
template<dim_t DIMENSION_NO, bool DO_SPLIT_PARENT_ENTITIES, typename TGeometry, typename TContainer = std::span<boost::geometry::model::boxNd_t<DIMENSION_NO, TGeometry> const>>
206206
using BoostOrthoTreeBoundingBox = OrthoTreeBoundingBox<
207207
DIMENSION_NO,
208208
boost::geometry::model::pointNd_t<DIMENSION_NO, TGeometry>,
209209
boost::geometry::model::boxNd_t<DIMENSION_NO, TGeometry>,
210210
boost::geometry::model::rayNd_t<DIMENSION_NO, TGeometry>,
211211
boost::geometry::model::planeNd_t<DIMENSION_NO, TGeometry>,
212212
TGeometry,
213-
SPLIT_DEPTH_INCREASEMENT,
213+
DO_SPLIT_PARENT_ENTITIES,
214214
BoostAdaptorGeneral<DIMENSION_NO, TGeometry>,
215215
TContainer>;
216216
} // namespace BoostAdaptor
@@ -225,8 +225,8 @@ namespace boost::geometry
225225
template<int DIMENSION_NO, typename TGeometry = double, typename TContainer = std::span<model::pointNd_t<DIMENSION_NO, TGeometry> const>>
226226
using orthotree_point_t = BoostOrthoTreePoint<DIMENSION_NO, TGeometry, TContainer>;
227227

228-
template<int DIMENSION_NO, uint32_t SPLIT_DEPTH_INCREASEMENT = 2, typename TGeometry = double, typename TContainer = std::span<model::boxNd_t<DIMENSION_NO, TGeometry> const>>
229-
using orthotree_box_t = BoostOrthoTreeBoundingBox<DIMENSION_NO, SPLIT_DEPTH_INCREASEMENT, TGeometry, TContainer>;
228+
template<int DIMENSION_NO, bool DO_SPLIT_PARENT_ENTITIES = true, typename TGeometry = double, typename TContainer = std::span<model::boxNd_t<DIMENSION_NO, TGeometry> const>>
229+
using orthotree_box_t = BoostOrthoTreeBoundingBox<DIMENSION_NO, DO_SPLIT_PARENT_ENTITIES, TGeometry, TContainer>;
230230

231231

232232
using quadtree_point_d = BoostOrthoTreePoint<2, double>;
@@ -240,18 +240,18 @@ namespace boost::geometry
240240
using octree_point = octree_point_d;
241241

242242

243-
template<uint32_t SPLIT_DEPTH_INCREASEMENT = 2>
244-
using quadtree_box_ds = BoostOrthoTreeBoundingBox<2, SPLIT_DEPTH_INCREASEMENT, double>;
245-
using quadtree_box_d = BoostOrthoTreeBoundingBox<2, 2, double>;
246-
using quadtree_box_f = BoostOrthoTreeBoundingBox<2, 2, float>;
247-
using quadtree_box_i = BoostOrthoTreeBoundingBox<2, 2, int>;
243+
template<bool DO_SPLIT_PARENT_ENTITIES = true>
244+
using quadtree_box_ds = BoostOrthoTreeBoundingBox<2, DO_SPLIT_PARENT_ENTITIES, double>;
245+
using quadtree_box_d = BoostOrthoTreeBoundingBox<2, true, double>;
246+
using quadtree_box_f = BoostOrthoTreeBoundingBox<2, true, float>;
247+
using quadtree_box_i = BoostOrthoTreeBoundingBox<2, true, int>;
248248
using quadtree_box = quadtree_box_d;
249249

250-
template<uint32_t SPLIT_DEPTH_INCREASEMENT = 2>
251-
using octree_box_ds = BoostOrthoTreeBoundingBox<3, SPLIT_DEPTH_INCREASEMENT, double>;
252-
using octree_box_d = BoostOrthoTreeBoundingBox<3, 2, double>;
253-
using octree_box_f = BoostOrthoTreeBoundingBox<3, 2, float>;
254-
using octree_box_i = BoostOrthoTreeBoundingBox<3, 2, int>;
250+
template<bool DO_SPLIT_PARENT_ENTITIES = true>
251+
using octree_box_ds = BoostOrthoTreeBoundingBox<3, DO_SPLIT_PARENT_ENTITIES, double>;
252+
using octree_box_d = BoostOrthoTreeBoundingBox<3, true, double>;
253+
using octree_box_f = BoostOrthoTreeBoundingBox<3, true, float>;
254+
using octree_box_i = BoostOrthoTreeBoundingBox<3, true, int>;
255255
using octree_box = octree_box_d;
256256

257257
// Container types
@@ -270,21 +270,21 @@ namespace boost::geometry
270270
using octree_point_c = octree_point_c_d;
271271

272272

273-
template<int DIMENSION_NO, uint32_t SPLIT_DEPTH_INCREASEMENT = 2, typename TGeometry = double>
274-
using orthotree_box_c_t = OrthoTree::OrthoTreeContainerBox<orthotree_box_t<DIMENSION_NO, SPLIT_DEPTH_INCREASEMENT, TGeometry>>;
273+
template<int DIMENSION_NO, bool DO_SPLIT_PARENT_ENTITIES = true, typename TGeometry = double>
274+
using orthotree_box_c_t = OrthoTree::OrthoTreeContainerBox<orthotree_box_t<DIMENSION_NO, DO_SPLIT_PARENT_ENTITIES, TGeometry>>;
275275

276-
template<uint32_t SPLIT_DEPTH_INCREASEMENT = 2>
277-
using quadtree_box_c_ds = orthotree_box_c_t<2, SPLIT_DEPTH_INCREASEMENT, double>;
278-
using quadtree_box_c_d = orthotree_box_c_t<2, 2, double>;
279-
using quadtree_box_c_f = orthotree_box_c_t<2, 2, float>;
280-
using quadtree_box_c_i = orthotree_box_c_t<2, 2, int>;
276+
template<bool DO_SPLIT_PARENT_ENTITIES = true>
277+
using quadtree_box_c_ds = orthotree_box_c_t<2, DO_SPLIT_PARENT_ENTITIES, double>;
278+
using quadtree_box_c_d = orthotree_box_c_t<2, true, double>;
279+
using quadtree_box_c_f = orthotree_box_c_t<2, true, float>;
280+
using quadtree_box_c_i = orthotree_box_c_t<2, true, int>;
281281
using quadtree_box_c = quadtree_box_c_d;
282282

283-
template<uint32_t SPLIT_DEPTH_INCREASEMENT = 2>
284-
using octree_box_c_ds = orthotree_box_c_t<3, SPLIT_DEPTH_INCREASEMENT, double>;
285-
using octree_box_c_d = orthotree_box_c_t<3, 2, double>;
286-
using octree_box_c_f = orthotree_box_c_t<3, 2, float>;
287-
using octree_box_c_i = orthotree_box_c_t<3, 2, int>;
283+
template<bool DO_SPLIT_PARENT_ENTITIES = true>
284+
using octree_box_c_ds = orthotree_box_c_t<3, DO_SPLIT_PARENT_ENTITIES, double>;
285+
using octree_box_c_d = orthotree_box_c_t<3, true, double>;
286+
using octree_box_c_f = orthotree_box_c_t<3, true, float>;
287+
using octree_box_c_i = orthotree_box_c_t<3, true, int>;
288288
using octree_box_c = octree_box_c_d;
289289

290290

@@ -304,18 +304,18 @@ namespace boost::geometry
304304
using octree_point_map = octree_point_map_d;
305305

306306

307-
template<uint32_t SPLIT_DEPTH_INCREASEMENT = 2>
308-
using quadtree_box_map_ds = BoostOrthoTreeBoundingBox<2, SPLIT_DEPTH_INCREASEMENT, double, map_container<model::boxNd_t<2, double>>>;
309-
using quadtree_box_map_d = BoostOrthoTreeBoundingBox<2, 2, double, map_container<model::boxNd_t<2, double>>>;
310-
using quadtree_box_map_f = BoostOrthoTreeBoundingBox<2, 2, float, map_container<model::boxNd_t<2, float>>>;
311-
using quadtree_box_map_i = BoostOrthoTreeBoundingBox<2, 2, int, map_container<model::boxNd_t<2, int>>>;
307+
template<bool DO_SPLIT_PARENT_ENTITIES = true>
308+
using quadtree_box_map_ds = BoostOrthoTreeBoundingBox<2, DO_SPLIT_PARENT_ENTITIES, double, map_container<model::boxNd_t<2, double>>>;
309+
using quadtree_box_map_d = BoostOrthoTreeBoundingBox<2, true, double, map_container<model::boxNd_t<2, double>>>;
310+
using quadtree_box_map_f = BoostOrthoTreeBoundingBox<2, true, float, map_container<model::boxNd_t<2, float>>>;
311+
using quadtree_box_map_i = BoostOrthoTreeBoundingBox<2, true, int, map_container<model::boxNd_t<2, int>>>;
312312
using quadtree_box_map = quadtree_box_map_d;
313313

314-
template<uint32_t SPLIT_DEPTH_INCREASEMENT = 2>
315-
using octree_box_map_ds = BoostOrthoTreeBoundingBox<3, SPLIT_DEPTH_INCREASEMENT, double, map_container<model::boxNd_t<3, double>>>;
316-
using octree_box_map_d = BoostOrthoTreeBoundingBox<3, 2, double, map_container<model::boxNd_t<3, double>>>;
317-
using octree_box_map_f = BoostOrthoTreeBoundingBox<3, 2, float, map_container<model::boxNd_t<3, float>>>;
318-
using octree_box_map_i = BoostOrthoTreeBoundingBox<3, 2, int, map_container<model::boxNd_t<3, int>>>;
314+
template<bool DO_SPLIT_PARENT_ENTITIES = true>
315+
using octree_box_map_ds = BoostOrthoTreeBoundingBox<3, DO_SPLIT_PARENT_ENTITIES, double, map_container<model::boxNd_t<3, double>>>;
316+
using octree_box_map_d = BoostOrthoTreeBoundingBox<3, true, double, map_container<model::boxNd_t<3, double>>>;
317+
using octree_box_map_f = BoostOrthoTreeBoundingBox<3, true, float, map_container<model::boxNd_t<3, float>>>;
318+
using octree_box_map_i = BoostOrthoTreeBoundingBox<3, true, int, map_container<model::boxNd_t<3, int>>>;
319319
using octree_box_map = octree_box_map_d;
320320

321321
// Container types
@@ -335,22 +335,22 @@ namespace boost::geometry
335335
using octree_point_map_c = octree_point_map_c_d;
336336

337337

338-
template<int DIMENSION_NO, uint32_t SPLIT_DEPTH_INCREASEMENT = 2, typename TGeometry = double>
338+
template<int DIMENSION_NO, bool DO_SPLIT_PARENT_ENTITIES = true, typename TGeometry = double>
339339
using orthotree_box_map_c_t =
340-
OrthoTree::OrthoTreeContainerBox<orthotree_box_t<DIMENSION_NO, SPLIT_DEPTH_INCREASEMENT, TGeometry, map_container<model::boxNd_t<DIMENSION_NO, TGeometry>>>>;
340+
OrthoTree::OrthoTreeContainerBox<orthotree_box_t<DIMENSION_NO, DO_SPLIT_PARENT_ENTITIES, TGeometry, map_container<model::boxNd_t<DIMENSION_NO, TGeometry>>>>;
341341

342-
template<uint32_t SPLIT_DEPTH_INCREASEMENT = 2>
343-
using quadtree_box_map_c_ds = orthotree_box_map_c_t<2, SPLIT_DEPTH_INCREASEMENT, double>;
344-
using quadtree_box_map_c_d = orthotree_box_map_c_t<2, 2, double>;
345-
using quadtree_box_map_c_f = orthotree_box_map_c_t<2, 2, float>;
346-
using quadtree_box_map_c_i = orthotree_box_map_c_t<2, 2, int>;
342+
template<bool DO_SPLIT_PARENT_ENTITIES = true>
343+
using quadtree_box_map_c_ds = orthotree_box_map_c_t<2, DO_SPLIT_PARENT_ENTITIES, double>;
344+
using quadtree_box_map_c_d = orthotree_box_map_c_t<2, true, double>;
345+
using quadtree_box_map_c_f = orthotree_box_map_c_t<2, true, float>;
346+
using quadtree_box_map_c_i = orthotree_box_map_c_t<2, true, int>;
347347
using quadtree_box_map_c = quadtree_box_map_c_d;
348348

349-
template<uint32_t SPLIT_DEPTH_INCREASEMENT = 2>
350-
using octree_box_map_c_ds = orthotree_box_map_c_t<3, SPLIT_DEPTH_INCREASEMENT, double>;
351-
using octree_box_map_c_d = orthotree_box_map_c_t<3, 2, double>;
352-
using octree_box_map_c_f = orthotree_box_map_c_t<3, 2, float>;
353-
using octree_box_map_c_i = orthotree_box_map_c_t<3, 2, int>;
349+
template<bool DO_SPLIT_PARENT_ENTITIES = true>
350+
using octree_box_map_c_ds = orthotree_box_map_c_t<3, DO_SPLIT_PARENT_ENTITIES, double>;
351+
using octree_box_map_c_d = orthotree_box_map_c_t<3, true, double>;
352+
using octree_box_map_c_f = orthotree_box_map_c_t<3, true, float>;
353+
using octree_box_map_c_i = orthotree_box_map_c_t<3, true, int>;
354354
using octree_box_map_c = octree_box_map_c_d;
355355

356356
} // namespace boost::geometry

0 commit comments

Comments
 (0)