Directory: | ./ |
---|---|
File: | src/Tree/PNTreeLightNode_impl.h |
Date: | 2025-03-14 11:38:38 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 135 | 140 | 96.4% |
Branches: | 59 | 83 | 71.1% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /*************************************** | ||
2 | Auteur : Pierre Aubert | ||
3 | Mail : pierre.aubert@lapp.in2p3.fr | ||
4 | Licence : CeCILL-C | ||
5 | ****************************************/ | ||
6 | |||
7 | #ifndef __PNTREE_LIGHT_NODE_H_IMPL__ | ||
8 | #define __PNTREE_LIGHT_NODE_H_IMPL__ | ||
9 | |||
10 | #include <string.h> | ||
11 | #include <math.h> | ||
12 | |||
13 | #include "pstatic_computation.h" | ||
14 | |||
15 | #include "PNTreeLightNode.h" | ||
16 | |||
17 | ///Default constructor of PNTreeLightNode | ||
18 | template<typename T, typename U, unsigned char N> | ||
19 | 1340 | PNTreeLightNode<T, U, N>::PNTreeLightNode(){ | |
20 | 1340 | initialisationPNTreeLightNode(); | |
21 | 1340 | } | |
22 | |||
23 | ///Copy constructor of PNTreeLightNode | ||
24 | /** @param other : class to copy | ||
25 | */ | ||
26 | template<typename T, typename U, unsigned char N> | ||
27 | PNTreeLightNode<T, U, N>::PNTreeLightNode(const PNTreeLightNode<T, U, N> & other){ | ||
28 | copyPNTreeLightNode(other); | ||
29 | } | ||
30 | |||
31 | ///Destructeur of PNTreeLightNode | ||
32 | template<typename T, typename U, unsigned char N> | ||
33 | 1340 | PNTreeLightNode<T, U, N>::~PNTreeLightNode(){ | |
34 | 1340 | clear(); | |
35 | } | ||
36 | |||
37 | ///Get the size of the child | ||
38 | /** @param[out] childSize : child size | ||
39 | * @param parentSize : parent size | ||
40 | */ | ||
41 | template<typename T, unsigned char N> | ||
42 | 3656 | void makeHalfSize(T childSize[N], const T parentSize[N]){ | |
43 |
2/2✓ Branch 0 taken 5268 times.
✓ Branch 1 taken 1828 times.
|
14192 | for(unsigned char i(0lu); i < N; ++i){ |
44 | 10536 | childSize[i] = parentSize[i]/2.f; | |
45 | } | ||
46 | 3656 | } | |
47 | |||
48 | ///Check the size of the childs of a N Tree | ||
49 | /** @param halfSizeChild : table of half size of the current N Tree | ||
50 | * @param sizeLimit : limit of the cell size | ||
51 | * @return true if everything is OK, false if the childs are too small | ||
52 | */ | ||
53 | template<typename T, unsigned char N> | ||
54 | 4984 | bool checkSizeLimitLight(const T halfSizeChild[N], T sizeLimit){ | |
55 |
2/2✓ Branch 0 taken 7178 times.
✓ Branch 1 taken 2492 times.
|
19340 | for(unsigned char i(0); i < N; ++i){ |
56 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7178 times.
|
14356 | if(halfSizeChild[i] < sizeLimit) return false; |
57 | } | ||
58 | 4984 | return true; | |
59 | } | ||
60 | |||
61 | ///Add an element in the PNTreeLightNode | ||
62 | /** @param posData : position of the data | ||
63 | * @param data : pointer to the data we want to sort | ||
64 | * @param pos : position of the current node | ||
65 | * @param size : size of the current node | ||
66 | * @param sizeLimit : limit of the cell size | ||
67 | * @return true on success, false otherwise | ||
68 | */ | ||
69 | template<typename T, typename U, unsigned char N> | ||
70 | 4796 | bool PNTreeLightNode<T, U, N>::addElement(T * posData, U * data, const T pos[N], const T size[N], T sizeLimit){ | |
71 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2398 times.
|
4796 | if(!checkSizeLimitLight<T, N>(size, sizeLimit)){ |
72 | ✗ | return false; | |
73 | } | ||
74 |
2/2✓ Branch 0 taken 764 times.
✓ Branch 1 taken 1634 times.
|
4796 | if(p_tableChildren == NULL){ |
75 |
2/2✓ Branch 0 taken 670 times.
✓ Branch 1 taken 94 times.
|
1528 | if(p_data == NULL){ //The cell is empty |
76 | 1340 | p_data = data; | |
77 | 1340 | p_posData = posData; | |
78 | 1340 | return true; | |
79 | }else{ //There is a data in the cell | ||
80 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 94 times.
|
188 | if(!split(pos, size, sizeLimit)) return false; |
81 | 188 | return addElement(posData, data, pos, size, sizeLimit); | |
82 | } | ||
83 | }else{ //There are children | ||
84 | T childPos[N]; | ||
85 | 3268 | PNTreeLightNode<T, U, N> * child = getChildFromPos(childPos, posData, pos, size); | |
86 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1634 times.
|
3268 | if(child == NULL){ |
87 | ✗ | return false; | |
88 | }else{ | ||
89 | T childSize[N]; | ||
90 | 3268 | makeHalfSize<T,N>(childSize, size); | |
91 |
1/1✓ Branch 1 taken 1634 times.
|
3268 | return child->addElement(posData, data, childPos, childSize, sizeLimit); |
92 | } | ||
93 | } | ||
94 | } | ||
95 | |||
96 | ///Saves the PNTreeLightNode into a txt file for gnuplot | ||
97 | /** @param fileName : name of the text file we want to write | ||
98 | * @param pos : position of the current node | ||
99 | * @param size : size of the current node | ||
100 | * @return true on success, false otherwise | ||
101 | */ | ||
102 | template<typename T, typename U, unsigned char N> | ||
103 | 4 | bool PNTreeLightNode<T, U, N>::saveGnuplotData(const std::string & fileName, T pos[N], T size[N]){ | |
104 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
4 | if(fileName == "") return false; |
105 |
1/1✓ Branch 1 taken 2 times.
|
4 | std::ofstream fs; |
106 |
1/1✓ Branch 1 taken 2 times.
|
4 | fs.open(fileName); |
107 |
2/3✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
|
4 | if(!fs.is_open()){return false;} |
108 |
1/1✓ Branch 1 taken 2 times.
|
4 | bool b = saveGnuplotData(fs, 0, pos, size); |
109 |
1/1✓ Branch 1 taken 2 times.
|
4 | fs.close(); |
110 | 4 | return b; | |
111 | 4 | } | |
112 | |||
113 | ///Saves the PNTreeLightNode into a txt file for gnuplot | ||
114 | /** @param fs : text file we want to write | ||
115 | * @param height : height of the quad to draw | ||
116 | * @param pos : position of the current node | ||
117 | * @param size : size of the current node | ||
118 | * @return true on success, false otherwise | ||
119 | */ | ||
120 | template<typename T, typename U, unsigned char N> | ||
121 | 1340 | bool PNTreeLightNode<T, U, N>::saveGnuplotData(std::ofstream & fs, T height, T pos[N], T size[N]){ | |
122 | if(N == 2){ | ||
123 | 170 | fs << pos[0] << "\t" << pos[1] << "\t" << height << std::endl; | |
124 | 170 | fs << (pos[0] + size[0]) << "\t" << pos[1] << "\t" << height << std::endl; | |
125 | 170 | fs << (pos[0] + size[0]) << "\t" << (pos[1] + size[1]) << "\t" << height << std::endl; | |
126 | 170 | fs << pos[0] << "\t" << (pos[1] + size[1]) << "\t" << height << std::endl; | |
127 | 170 | fs << pos[0] << "\t" << pos[1] << "\t" << height << std::endl; | |
128 | }else if(N == 3){ | ||
129 | 1170 | T px0(pos[0]), px1(pos[0] + size[0]); | |
130 | 1170 | T py0(pos[1]), py1(pos[1] + size[1]); | |
131 | 1170 | T pz0(pos[2]), pz1(pos[2] + size[2]); | |
132 | |||
133 | //lower quad | ||
134 | 1170 | fs << px0 << "\t" << py0 << "\t" << pz0 << std::endl; | |
135 | 1170 | fs << px1 << "\t" << py0 << "\t" << pz0 << std::endl; | |
136 | 1170 | fs << px1 << "\t" << py1 << "\t" << pz0 << std::endl; | |
137 | 1170 | fs << px0 << "\t" << py1 << "\t" << pz0 << std::endl; | |
138 | 1170 | fs << px0 << "\t" << py0 << "\t" << pz0 << std::endl; | |
139 | 1170 | fs << std::endl; | |
140 | //upper quad | ||
141 | 1170 | fs << px0 << "\t" << py0 << "\t" << pz1 << std::endl; | |
142 | 1170 | fs << px1 << "\t" << py0 << "\t" << pz1 << std::endl; | |
143 | 1170 | fs << px1 << "\t" << py1 << "\t" << pz1 << std::endl; | |
144 | 1170 | fs << px0 << "\t" << py1 << "\t" << pz1 << std::endl; | |
145 | 1170 | fs << px0 << "\t" << py0 << "\t" << pz1 << std::endl; | |
146 | 1170 | fs << std::endl; | |
147 | //Lines on Oz axis | ||
148 | 1170 | fs << px0 << "\t" << py0 << "\t" << pz0 << std::endl; | |
149 | 1170 | fs << px0 << "\t" << py0 << "\t" << pz1 << std::endl; | |
150 | 1170 | fs << std::endl; | |
151 | 1170 | fs << px0 << "\t" << py1 << "\t" << pz0 << std::endl; | |
152 | 1170 | fs << px0 << "\t" << py1 << "\t" << pz1 << std::endl; | |
153 | 1170 | fs << std::endl; | |
154 | 1170 | fs << px1 << "\t" << py1 << "\t" << pz0 << std::endl; | |
155 | 1170 | fs << px1 << "\t" << py1 << "\t" << pz1 << std::endl; | |
156 | 1170 | fs << std::endl; | |
157 | 1170 | fs << px1 << "\t" << py0 << "\t" << pz0 << std::endl; | |
158 | 1170 | fs << px1 << "\t" << py0 << "\t" << pz1 << std::endl; | |
159 | } | ||
160 | 1340 | fs << std::endl; | |
161 |
2/2✓ Branch 0 taken 94 times.
✓ Branch 1 taken 576 times.
|
1340 | if(p_tableChildren != NULL){ |
162 | T childSize[N], posChild[N]; | ||
163 | 188 | makeHalfSize<T,N>(childSize, size); | |
164 |
2/2✓ Branch 0 taken 668 times.
✓ Branch 1 taken 94 times.
|
1524 | for(unsigned char i(0); i < PPower<2, N>::Value; ++i){ |
165 |
2/2✓ Branch 0 taken 1920 times.
✓ Branch 1 taken 668 times.
|
5176 | for(unsigned char k(0); k < N; ++k){ |
166 | 3840 | posChild[k] = pos[k] + ((i >> k) & 1)*childSize[k]; | |
167 | } | ||
168 |
1/1✓ Branch 1 taken 668 times.
|
1336 | p_tableChildren[i].saveGnuplotData(fs, height + 1, posChild, childSize); |
169 | } | ||
170 | } | ||
171 | 1340 | return true; | |
172 | } | ||
173 | |||
174 | ///Clear the PNTreeLightNode content | ||
175 | template<typename T, typename U, unsigned char N> | ||
176 | 2680 | void PNTreeLightNode<T, U, N>::clear(){ | |
177 |
2/2✓ Branch 0 taken 94 times.
✓ Branch 1 taken 1246 times.
|
2680 | if(p_tableChildren != NULL){ |
178 |
2/2✓ Branch 0 taken 668 times.
✓ Branch 1 taken 94 times.
|
1524 | for(unsigned char i(0); i < PPower<2, N>::Value; ++i){ |
179 | 1336 | PNTreeLightNode<T, U, N> * child = &(p_tableChildren[i]); | |
180 | 1336 | child->clear(); | |
181 | } | ||
182 |
3/4✓ Branch 0 taken 94 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 668 times.
✓ Branch 3 taken 94 times.
|
1524 | delete [] p_tableChildren; |
183 | 188 | p_tableChildren = NULL; | |
184 | } | ||
185 | 2680 | p_data = NULL; | |
186 | 2680 | } | |
187 | |||
188 | ///Get the data of the last node in the N tree | ||
189 | /** @param posData : position of the data | ||
190 | * @param pos : position of the current node | ||
191 | * @param size : size of the current node | ||
192 | * @return data of the last node in the N tree | ||
193 | */ | ||
194 | template<typename T, typename U, unsigned char N> | ||
195 | 16 | const U * PNTreeLightNode<T, U, N>::getLastData(const T * posData, const T pos[N], const T size[N]) const{ | |
196 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
|
16 | if(p_tableChildren == NULL){ |
197 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
4 | if(p_data == NULL) return NULL; |
198 | 4 | else return p_data; | |
199 | }else{ | ||
200 | T childPos[N]; | ||
201 | 12 | const PNTreeLightNode<T, U, N> * child = getChildFromPos(childPos, posData, pos, size); | |
202 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
|
12 | if(child == NULL) return NULL; |
203 | else{ | ||
204 | T childSize[N]; | ||
205 | 12 | makeHalfSize<T,N>(childSize, size); | |
206 |
1/1✓ Branch 1 taken 6 times.
|
12 | return child->getLastData(posData, pos, childSize); |
207 | } | ||
208 | } | ||
209 | } | ||
210 | |||
211 | ///Get the distance between two points | ||
212 | /** @param posA : first position | ||
213 | * @param posB : second position | ||
214 | * @return distance between posA and posB | ||
215 | */ | ||
216 | template<typename T, unsigned char N> | ||
217 | T getDistanceFromData(const T posA[N], const T posB[N]){ | ||
218 | T res = 0.0, x; | ||
219 | for(unsigned char i(0); i < N; ++i){ | ||
220 | x = posA[i] - posB[i]; | ||
221 | res += x*x; | ||
222 | } | ||
223 | return sqrt(res); | ||
224 | } | ||
225 | |||
226 | ///Get the index of the check neighbours tab | ||
227 | /** @param indexChild : index of the reference cell | ||
228 | * @param currentChildIndex : index of the current node to be checked | ||
229 | * @return index of the neighbours to be checked in the neighbours table | ||
230 | */ | ||
231 | template<unsigned char N> | ||
232 | unsigned int getNeighbourCellIndex(unsigned char indexChild[N], unsigned char currentChildIndex[N]){ | ||
233 | unsigned int index(0u), base(1u), tmp; | ||
234 | for(unsigned char i(N); i < N; ++i){ | ||
235 | tmp = 0u; | ||
236 | if(indexChild[i] > currentChildIndex[i]){ | ||
237 | tmp = 2u; | ||
238 | }else if(indexChild[i] == currentChildIndex[i]){ | ||
239 | tmp = 1u; | ||
240 | } | ||
241 | index += base*tmp; | ||
242 | base *= 3u; | ||
243 | } | ||
244 | return index; | ||
245 | } | ||
246 | |||
247 | ///Get the closer data from the given position posData | ||
248 | /** @param[out] closerData : pointer to the closer data found | ||
249 | * @param[out] distFromCloserData : distance from the closer data to the search position posData | ||
250 | * @param[out] tabIsNeighbourChecked : table of the checked neighbours (true), or unchecked neighbours (false) | ||
251 | * @param nbNeighbour : size of the table of neighbours | ||
252 | * @param posData : position used to search the closer data | ||
253 | * @param pos : position of the current node | ||
254 | * @param size : size of the current node | ||
255 | * @return true if the closer data has been found, false if the parent needs to keep searching | ||
256 | */ | ||
257 | template<typename T, typename U, unsigned char N> | ||
258 | bool PNTreeLightNode<T, U, N>::getCloserData(U*& closerData, T & distFromCloserData, bool * tabIsNeighbourChecked, unsigned int nbNeighbour, | ||
259 | const T * posData, const T pos[N], const T size[N]) const | ||
260 | { | ||
261 | if(p_tableChildren == NULL){ //If the node has no child | ||
262 | if(p_data == NULL) return false; //If the node has no data | ||
263 | else{ //If the node has data | ||
264 | if(closerData == NULL){ | ||
265 | closerData = p_data; | ||
266 | distFromCloserData = getDistanceFromData<T,N>(p_posData, posData); | ||
267 | return true; | ||
268 | }else{ | ||
269 | T dist = getDistanceFromData<T,N>(p_posData, posData); | ||
270 | if(dist < distFromCloserData){ | ||
271 | distFromCloserData = dist; | ||
272 | closerData = p_data; | ||
273 | } | ||
274 | return false; | ||
275 | } | ||
276 | } | ||
277 | }else{ //If the node has children | ||
278 | T childPos[N]; | ||
279 | const PNTreeLightNode<T, U, N> * child = getChildFromPos(childPos, posData, pos, size); | ||
280 | if(child == NULL) return false; | ||
281 | else{ | ||
282 | T childSize[N]; | ||
283 | makeHalfSize<T,N>(childSize, size); | ||
284 | bool b = child->getCloserData(closerData, distFromCloserData, tabIsNeighbourChecked, nbNeighbour, posData, childPos, childSize); | ||
285 | if(b) return true; | ||
286 | else{ | ||
287 | unsigned char indexChild[N], currentChildIndex[N]; | ||
288 | T currentChildPos[N]; | ||
289 | getIndexOfChildFromPos(indexChild, posData, pos, size); | ||
290 | unsigned char fullIndexChild(getFullIndexChild(indexChild)); | ||
291 | |||
292 | for(unsigned char i(0); i < PPower<2, N>::Value; ++i){ | ||
293 | if(i == fullIndexChild) continue; | ||
294 | for(unsigned char j(0); j < N; ++j){ | ||
295 | currentChildIndex[j] = (i >> j) & 1; | ||
296 | currentChildPos[j] = pos[j] + ((T)currentChildIndex[j])*childSize[j]; | ||
297 | } | ||
298 | unsigned int indexCurrentNeighbour(getNeighbourCellIndex<N>(indexChild, currentChildIndex)); | ||
299 | //If the neighbours is already checked, skip it | ||
300 | if(tabIsNeighbourChecked[indexCurrentNeighbour]) continue; | ||
301 | //If the neighbours is not check yet, check it and write it in the tabIsNeighbourChecked | ||
302 | tabIsNeighbourChecked[indexCurrentNeighbour] = true; | ||
303 | if(child->getCloserData(closerData, distFromCloserData, tabIsNeighbourChecked, nbNeighbour, | ||
304 | posData, currentChildPos, childSize)) | ||
305 | { | ||
306 | return true; | ||
307 | } | ||
308 | } | ||
309 | if(isNeighbourSearchFinised(tabIsNeighbourChecked, nbNeighbour)) return true; | ||
310 | return false; | ||
311 | } | ||
312 | } | ||
313 | } | ||
314 | } | ||
315 | |||
316 | ///Get the child of the PNTreeLightNode with a position | ||
317 | /** @param[out] childPos : position of the child | ||
318 | * @param posData : position of the data | ||
319 | * @param pos : position of the current node | ||
320 | * @param size : size of the current node | ||
321 | * @return child of the current PNTreeLightNode which contains the position (pos) | ||
322 | */ | ||
323 | template<typename T, typename U, unsigned char N> | ||
324 | 12 | const PNTreeLightNode<T, U, N> * PNTreeLightNode<T, U, N>::getChildFromPos(T childPos[N], const T * posData, const T pos[N], const T size[N]) const{ | |
325 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
|
12 | if(p_tableChildren == NULL) return NULL; |
326 | 12 | unsigned char posChild(0), base(1); | |
327 | bool cond; | ||
328 |
2/2✓ Branch 0 taken 15 times.
✓ Branch 1 taken 6 times.
|
42 | for(unsigned char j(0); j < N; ++j){ |
329 | 30 | cond = ((posData[j] - pos[j]) > size[j]*0.5); | |
330 | 30 | childPos[j] = pos[j] + cond*size[j]*0.5; | |
331 | 30 | posChild += cond*base; | |
332 | 30 | base *= 2; //on poura faire du décalage de bit plus tard | |
333 | } | ||
334 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
|
12 | if(posChild >= PPower<2, N>::Value) return NULL; |
335 | 12 | else return &(p_tableChildren[posChild]); | |
336 | } | ||
337 | |||
338 | ///Get the child of the PNTreeLightNode with a position | ||
339 | /** @param[out] childPos : position of the child | ||
340 | * @param posData : position of the data | ||
341 | * @param pos : position of the current node | ||
342 | * @param size : size of the current node | ||
343 | * @return child of the current PNTreeLightNode which contains the position (pos) | ||
344 | */ | ||
345 | template<typename T, typename U, unsigned char N> | ||
346 | 3456 | PNTreeLightNode<T, U, N> * PNTreeLightNode<T, U, N>::getChildFromPos(T childPos[N], const T * posData, const T pos[N], const T size[N]){ | |
347 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1728 times.
|
3456 | if(p_tableChildren == NULL) return NULL; |
348 | 3456 | unsigned char posChild(0), base(1); | |
349 | bool cond; | ||
350 |
2/2✓ Branch 0 taken 4992 times.
✓ Branch 1 taken 1728 times.
|
13440 | for(unsigned char j(0); j < N; ++j){ |
351 | 9984 | cond = ((posData[j] - pos[j]) > size[j]*0.5); | |
352 | 9984 | childPos[j] = pos[j] + cond*size[j]*0.5; | |
353 | 9984 | posChild += cond*base; | |
354 | 9984 | base *= 2; //on poura faire du décalage de bit plus tard | |
355 | } | ||
356 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1728 times.
|
3456 | if(posChild >= PPower<2, N>::Value) return NULL; |
357 | else{ | ||
358 | // std::cerr << "PNTreeLightNode<T, U, N>::getChildFromPos : posChild = " << ((int)posChild) << std::endl; | ||
359 | 3456 | return &(p_tableChildren[posChild]); | |
360 | } | ||
361 | } | ||
362 | |||
363 | ///Get the index of the child position by respect to the position pos | ||
364 | /** @param[out] index : vector of the position of the child | ||
365 | * @param posData : position used to get the child | ||
366 | * @param pos : position of the current node | ||
367 | * @param size : size of the current node | ||
368 | */ | ||
369 | template<typename T, typename U, unsigned char N> | ||
370 | void PNTreeLightNode<T, U, N>::getIndexOfChildFromPos(unsigned char index[N], const T * posData, const T pos[N], const T size[N]) const{ | ||
371 | if(p_tableChildren == NULL) return; | ||
372 | for(unsigned char j(0lu); j < N; ++j){ | ||
373 | index[j] = ((posData[j] - pos[j]) > size[j]*0.5); | ||
374 | } | ||
375 | } | ||
376 | |||
377 | ///Get the index of the child position by respect to the position pos | ||
378 | /** @param[out] index : vector of the position of the child | ||
379 | * @param posData : position used to get the child | ||
380 | * @param pos : position of the current node | ||
381 | * @param size : size of the current node | ||
382 | */ | ||
383 | template<typename T, typename U, unsigned char N> | ||
384 | void PNTreeLightNode<T, U, N>::getIndexOfChildFromPos(unsigned char index[N], T * posData, T pos[N], T size[N]){ | ||
385 | if(p_tableChildren == NULL) return; | ||
386 | for(unsigned char j(0); j < N; ++j){ | ||
387 | index[j] = ((posData[j] - pos[j]) > size[j]*0.5); | ||
388 | } | ||
389 | } | ||
390 | |||
391 | ///Get the full index position of a child | ||
392 | /** @param index : vector of index position of a child | ||
393 | * @return full index position of a child | ||
394 | */ | ||
395 | template<typename T, typename U, unsigned char N> | ||
396 | unsigned char PNTreeLightNode<T, U, N>::getFullIndexChild(unsigned char index[N]) const{ | ||
397 | unsigned char posChild(0), base(1); | ||
398 | for(unsigned char j(0); j < N; ++j){ | ||
399 | posChild += (index[j])*base; | ||
400 | base *= 2; //on poura faire du décalage de bit plus tard | ||
401 | } | ||
402 | return posChild; | ||
403 | } | ||
404 | |||
405 | ///Returns the data position | ||
406 | /** @return data position | ||
407 | */ | ||
408 | template<typename T, typename U, unsigned char N> | ||
409 | const T * PNTreeLightNode<T, U, N>::getDataPos() const{return p_posData;} | ||
410 | |||
411 | ///Returns the data position | ||
412 | /** @return data position | ||
413 | */ | ||
414 | template<typename T, typename U, unsigned char N> | ||
415 | T * PNTreeLightNode<T, U, N>::getDataPos(){return p_posData;} | ||
416 | |||
417 | ///Returns the table of children of the PNTreeLightNode | ||
418 | /** @return table of children of the PNTreeLightNode | ||
419 | */ | ||
420 | template<typename T, typename U, unsigned char N> | ||
421 | const PNTreeLightNode<T, U, N> * PNTreeLightNode<T, U, N>::getTabChildren() const{return p_tableChildren;} | ||
422 | |||
423 | ///Returns the table of children of the PNTreeLightNode | ||
424 | /** @return table of children of the PNTreeLightNode | ||
425 | */ | ||
426 | template<typename T, typename U, unsigned char N> | ||
427 | PNTreeLightNode<T, U, N> * PNTreeLightNode<T, U, N>::getTabChildren(){return p_tableChildren;} | ||
428 | |||
429 | ///Returns the child of the PNTreeLightNode | ||
430 | /** @param childId : id of the child we want to have | ||
431 | * @return pointer to the child or NULL if there is not | ||
432 | */ | ||
433 | template<typename T, typename U, unsigned char N> | ||
434 | const PNTreeLightNode<T, U, N> * PNTreeLightNode<T, U, N>::getChild(unsigned char childId) const{ | ||
435 | if(p_tableChildren == NULL || childId >= PPower<2, N>::Value) return NULL; | ||
436 | return &(p_tableChildren[childId]); | ||
437 | } | ||
438 | |||
439 | ///Returns the child of the PNTreeLightNode | ||
440 | /** @param childId : id of the child we want to have | ||
441 | * @return pointer to the child or NULL if there is not | ||
442 | */ | ||
443 | template<typename T, typename U, unsigned char N> | ||
444 | PNTreeLightNode<T, U, N> * PNTreeLightNode<T, U, N>::getChild(unsigned char childId){ | ||
445 | if(p_tableChildren == NULL || childId >= PPower<2, N>::Value) return NULL; | ||
446 | return &(p_tableChildren[childId]); | ||
447 | } | ||
448 | |||
449 | ///Copy function of PNTreeLightNode | ||
450 | /** @param other : class to copy | ||
451 | */ | ||
452 | template<typename T, typename U, unsigned char N> | ||
453 | void PNTreeLightNode<T, U, N>::copyPNTreeLightNode(const PNTreeLightNode<T, U, N> & other){ | ||
454 | |||
455 | } | ||
456 | |||
457 | ///Split the PNTreeLightNode | ||
458 | /** @param pos : position of the current node | ||
459 | * @param size : size of the current node | ||
460 | * @param sizeLimit : limit of the cell size | ||
461 | * @return true on success, false otherwise | ||
462 | */ | ||
463 | template<typename T, typename U, unsigned char N> | ||
464 | 188 | bool PNTreeLightNode<T, U, N>::split(const T pos[N], const T size[N], T sizeLimit){ | |
465 |
2/4✓ Branch 0 taken 94 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 94 times.
|
188 | if(p_tableChildren != NULL || p_data == NULL){ |
466 | ✗ | std::cerr << "PNTreeLightNode<T, U, N>::split() : current node already split" << std::endl; | |
467 | ✗ | return false; | |
468 | } | ||
469 | // std::cerr << "PNTreeLightNode<T, U, N>::split() : begin" << std::endl; | ||
470 | T halfSizeChild[N]; | ||
471 | 188 | makeHalfSize<T, N>(halfSizeChild, size); | |
472 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 94 times.
|
188 | if(!checkSizeLimitLight<T, N>(halfSizeChild, sizeLimit)){ |
473 | // std::cerr << "PNTreeLightNode<T, U, N>::split : can't split more, child sizes less than " << sizeLimit << std::endl; | ||
474 | ✗ | return false; | |
475 | } | ||
476 | 188 | unsigned char nbChildren(PPower<2, N>::Value); | |
477 |
5/8✓ Branch 0 taken 94 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 94 times.
✓ Branch 6 taken 668 times.
✓ Branch 8 taken 668 times.
✓ Branch 9 taken 94 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
|
1524 | p_tableChildren = new PNTreeLightNode<T, U, N>[nbChildren]; |
478 |
2/2✓ Branch 0 taken 668 times.
✓ Branch 1 taken 94 times.
|
1524 | for(unsigned char i(0); i < nbChildren; ++i){ |
479 | 1336 | PNTreeLightNode<T, U, N> * child = &(p_tableChildren[i]); | |
480 | 1336 | child->p_tableChildren = NULL; | |
481 | 1336 | child->p_data = NULL; | |
482 | 1336 | child->p_posData = NULL; | |
483 | } | ||
484 | // std::cerr << "PNTreeLightNode<T, U, N>::split : replace child" << std::endl; | ||
485 | T childPos[N]; | ||
486 | 188 | PNTreeLightNode<T, U, N> * child = getChildFromPos(childPos, p_posData, pos, size); | |
487 | 188 | bool b = true;; | |
488 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 94 times.
|
188 | if(child == NULL) return false; |
489 | else{ | ||
490 |
1/1✓ Branch 1 taken 94 times.
|
188 | b = child->addElement(p_posData, p_data, childPos, halfSizeChild, sizeLimit); |
491 | } | ||
492 | 188 | p_data = NULL; | |
493 | 188 | p_posData = NULL; | |
494 | 188 | return b; | |
495 | } | ||
496 | |||
497 | ///Initialisation function of the class PNTreeLightNode | ||
498 | template<typename T, typename U, unsigned char N> | ||
499 | 1340 | void PNTreeLightNode<T, U, N>::initialisationPNTreeLightNode(){ | |
500 | 1340 | p_posData = NULL; | |
501 | 1340 | p_data = NULL; | |
502 | 1340 | p_tableChildren = NULL; | |
503 | 1340 | } | |
504 | |||
505 | |||
506 | |||
507 | |||
508 | |||
509 | #endif | ||
510 | |||
511 | |||
512 | |||
513 |