0028368: TKMath, BVH -- Fix invalid tree height in QBVH
[occt.git] / src / BVH / BVH_QueueBuilder.hxx
CommitLineData
0ef61b50 1// Created on: 2014-09-15
2// Created by: Denis BOGOLEPOV
3// Copyright (c) 2013-2014 OPEN CASCADE SAS
4//
5// This file is part of Open CASCADE Technology software library.
6//
7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
12//
13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
15
16#ifndef _BVH_QueueBuilder_Header
17#define _BVH_QueueBuilder_Header
18
19#include <BVH_Builder.hxx>
65578e1c 20#include <BVH_BuildThread.hxx>
0ef61b50 21#include <NCollection_Vector.hxx>
22
23//! Abstract BVH builder based on the concept of work queue.
65578e1c 24//! Queue based BVH builders support parallelization with a
25//! fixed number of threads (maximum efficiency is achieved
26//! by setting the number of threads equal to the number of
27//! CPU cores plus one). Note that to support parallel mode,
28//! a corresponding BVH primitive set should provide thread
29//! safe implementations of interface functions (e.g., Swap,
30//! Box, Center). Otherwise, the results will be undefined.
31//! \tparam T Numeric data type
32//! \tparam N Vector dimension
0ef61b50 33template<class T, int N>
34class BVH_QueueBuilder : public BVH_Builder<T, N>
35{
36public:
37
38 //! Creates new BVH queue based builder.
39 BVH_QueueBuilder (const Standard_Integer theLeafNodeSize,
65578e1c 40 const Standard_Integer theMaxTreeDepth,
41 const Standard_Integer theNumOfThreads = 1);
0ef61b50 42
43 //! Releases resources of BVH queue based builder.
44 virtual ~BVH_QueueBuilder() = 0;
45
46public:
47
48 //! Builds BVH using specific algorithm.
49 virtual void Build (BVH_Set<T, N>* theSet,
50 BVH_Tree<T, N>* theBVH,
51 const BVH_Box<T, N>& theBox);
52
53protected:
54
65578e1c 55 //! Stores range of primitives belonging to a BVH node.
56 struct BVH_PrimitiveRange
57 {
58 Standard_Integer Start;
59 Standard_Integer Final;
60
61 //! Creates new primitive range.
62 BVH_PrimitiveRange (Standard_Integer theStart = -1,
63 Standard_Integer theFinal = -1)
64 : Start (theStart),
65 Final (theFinal)
66 {
67 //
68 }
69
70 //! Returns total number of primitives.
71 Standard_Integer Size() const
72 {
73 return Final - Start + 1;
74 }
75
76 //! Checks if the range is initialized.
77 Standard_Boolean IsValid() const
78 {
79 return Start != -1;
80 }
81 };
82
83 //! Stores parameters of constructed child nodes.
84 struct BVH_ChildNodes
85 {
86 //! Bounding boxes of child nodes.
87 BVH_Box<T, N> Boxes[2];
88
89 //! Primitive ranges of child nodes.
90 BVH_PrimitiveRange Ranges[2];
91
92 //! Creates new parameters of BVH child nodes.
93 BVH_ChildNodes()
94 {
95 //
96 }
97
98 //! Creates new parameters of BVH child nodes.
99 BVH_ChildNodes (const BVH_Box<T, N>& theLftBox,
100 const BVH_Box<T, N>& theRghBox,
101 const BVH_PrimitiveRange& theLftRange,
102 const BVH_PrimitiveRange& theRghRange)
103 {
104 Boxes[0] = theLftBox;
105 Boxes[1] = theRghBox;
106 Ranges[0] = theLftRange;
107 Ranges[1] = theRghRange;
108 }
109
110 //! Returns number of primitives in the given child.
111 Standard_Integer NbPrims (const Standard_Integer theChild) const
112 {
113 return Ranges[theChild].Size();
114 }
115
116 //! Checks if the parameters is initialized.
117 Standard_Boolean IsValid() const
118 {
119 return Ranges[0].IsValid() && Ranges[1].IsValid();
120 }
121 };
122
123 //! Wrapper for BVH build data.
124 class BVH_TypedBuildTool : public BVH_BuildTool
125 {
126 public:
127
128 //! Creates new BVH build thread.
129 BVH_TypedBuildTool (BVH_Set<T, N>* theSet,
130 BVH_Tree<T, N>* theBVH,
131 BVH_Builder<T, N>* theAlgo)
132 : mySet (theSet),
133 myBVH (theBVH)
134 {
135 myAlgo = dynamic_cast<BVH_QueueBuilder<T, N>* > (theAlgo);
136
137 Standard_ASSERT_RAISE (myAlgo != NULL,
138 "Error! BVH builder should be queue based");
139 }
140
141 //! Performs splitting of the given BVH node.
142 virtual void Perform (const Standard_Integer theNode)
143 {
144 const typename BVH_QueueBuilder<T, N>::BVH_ChildNodes aChildren = myAlgo->BuildNode (mySet, myBVH, theNode);
145
146 myAlgo->AddChildren (myBVH, theNode, aChildren);
147 }
148
149 protected:
150
151 //! Primitive set to build BVH.
152 BVH_Set<T, N>* mySet;
153
154 //! Output BVH tree for the set.
155 BVH_Tree<T, N>* myBVH;
156
157 //! Queue based BVH builder to use.
158 BVH_QueueBuilder<T, N>* myAlgo;
159 };
160
161protected:
162
163 //! Performs splitting of the given BVH node.
164 virtual typename BVH_QueueBuilder<T, N>::BVH_ChildNodes BuildNode (BVH_Set<T, N>* theSet,
165 BVH_Tree<T, N>* theBVH,
166 const Standard_Integer theNode) = 0;
167
168 //! Processes child nodes of the splitted BVH node.
169 virtual void AddChildren (BVH_Tree<T, N>* theBVH,
170 const Standard_Integer theNode,
171 const BVH_ChildNodes& theSubNodes);
0ef61b50 172
173protected:
174
65578e1c 175 BVH_BuildQueue myBuildQueue; //!< Queue to manage BVH node building tasks
176
177 Standard_Integer myNumOfThreads; //!< Number of threads used to build BVH
0ef61b50 178
179};
180
181#include <BVH_QueueBuilder.lxx>
182
183#endif // _BVH_QueueBuilder_Header