APRIterator.hpp 20.4 KB
Newer Older
1
//
cheesema's avatar
cheesema committed
2
// Created by cheesema on 16.01.18.
3
4
//

cheesema's avatar
cheesema committed
5
6
#ifndef PARTPLAY_APR_ITERATOR_NEW_HPP
#define PARTPLAY_APR_ITERATOR_NEW_HPP
7

8
#include "APR.hpp"
9
#include "APRAccess.hpp"
10

cheesema's avatar
cheesema committed
11
12
template<typename ImageType>
class APRIterator {
13

cheesema's avatar
cheesema committed
14
private:
15

cheesema's avatar
cheesema committed
16
    LocalMapIterators local_iterators;
17

cheesema's avatar
cheesema committed
18
    const uint8_t level_check_max[2] = {_LEVEL_SAME,_LEVEL_DECREASE};
19

cheesema's avatar
cheesema committed
20
    const uint8_t level_check_min[2] = {_LEVEL_SAME,_LEVEL_INCREASE};
21

cheesema's avatar
cheesema committed
22
    const uint8_t level_check_middle[3] = {_LEVEL_SAME,_LEVEL_DECREASE,_LEVEL_INCREASE};
23

24
    ParticleCell neighbour_particle_cell{ 0, 0, 0, 0, 0, UINT64_MAX, UINT64_MAX };
25

26
    ParticleCell current_particle_cell{0, 0, 0, 0, 0, UINT64_MAX, UINT64_MAX };
27

28
    APR<ImageType>* aprOwn;
cheesema's avatar
cheesema committed
29
    APRAccess* apr_access;
30

31
    uint16_t level_delta{};
32

cheesema's avatar
cheesema committed
33
    MapIterator current_gap;
34

cheesema's avatar
cheesema committed
35
    bool check_neigh_flag = false;
36

cheesema's avatar
cheesema committed
37
38
    const uint16_t shift[6] = {YP_LEVEL_SHIFT,YM_LEVEL_SHIFT,XP_LEVEL_SHIFT,XM_LEVEL_SHIFT,ZP_LEVEL_SHIFT,ZM_LEVEL_SHIFT};
    const uint16_t mask[6] = {YP_LEVEL_MASK,YM_LEVEL_MASK,XP_LEVEL_MASK,XM_LEVEL_MASK,ZP_LEVEL_MASK,ZM_LEVEL_MASK};
39

cheesema's avatar
cheesema committed
40

cheesema's avatar
cheesema committed
41

cheesema's avatar
cheesema committed
42
public:
cheesema's avatar
cheesema committed
43
44


45
46
    explicit APRIterator(APR<ImageType>& apr){
        aprOwn = &apr;
cheesema's avatar
cheesema committed
47
        apr_access = &apr.apr_access;
48
        current_particle_cell.global_index = UINT64_MAX;
cheesema's avatar
cheesema committed
49
50
    }

51
    explicit APRIterator(APRAccess& apr_access_){
cheesema's avatar
cheesema committed
52
       apr_access = &apr_access_;
53
        current_particle_cell.global_index = UINT64_MAX;
cheesema's avatar
cheesema committed
54
55
    }

cheesema's avatar
cheesema committed
56
    void initialize_from_apr(APR<ImageType>& apr){
57
        aprOwn = &apr;
cheesema's avatar
cheesema committed
58
        apr_access = &apr.apr_access;
59
        current_particle_cell.global_index = UINT64_MAX;
cheesema's avatar
cheesema committed
60
61
    }

cheesema's avatar
cheesema committed
62
    uint64_t total_number_particles(){
cheesema's avatar
cheesema committed
63
        return (apr_access)->total_number_particles;
cheesema's avatar
cheesema committed
64
65
    }

Ulrik Günther's avatar
Ulrik Günther committed
66
    bool set_iterator_to_particle_by_number(const uint64_t particle_number){
cheesema's avatar
cheesema committed
67
68
69
70
        //
        //  Moves the iterator to point to the particle number (global index of the particle)
        //

71
//        std::cerr << particle_number << std::endl;
cheesema's avatar
cheesema committed
72
73
74
        if(particle_number==0){
            current_particle_cell.level = level_min();
            current_particle_cell.pc_offset=0;
cheesema's avatar
cheesema committed
75

cheesema's avatar
cheesema committed
76
77
78
79
80
81
82
83
            if(move_iterator_to_next_non_empty_row(level_max())){
                //found and set
                set_neighbour_flag();
                return true;
            } else{
                return false; //no particle cells, something is wrong
            }
        } else if (particle_number < apr_access->total_number_particles) {
cheesema's avatar
cheesema committed
84

cheesema's avatar
cheesema committed
85
86
87
88
89
90
            //iterating just move to next
            if(particle_number == (current_particle_cell.global_index+1)){
                bool success = move_to_next_particle_cell();
                set_neighbour_flag();
                return success;
            }
cheesema's avatar
cheesema committed
91

cheesema's avatar
cheesema committed
92
93
            current_particle_cell.level = level_min();
            //otherwise now we have to figure out where to look for the next particle cell;
cheesema's avatar
cheesema committed
94

cheesema's avatar
cheesema committed
95
            //first find the level
cheesema's avatar
cheesema committed
96
            while((current_particle_cell.level <= level_max()) && (particle_number > apr_access->global_index_by_level_end[current_particle_cell.level])  ){
cheesema's avatar
cheesema committed
97
98
                current_particle_cell.level++;
            }
cheesema's avatar
cheesema committed
99

cheesema's avatar
cheesema committed
100
101
102
103
104
105
            //then find the offset (zx row)
            current_particle_cell.pc_offset=0;

            while(particle_number > particles_offset_end(current_particle_cell.level,current_particle_cell.pc_offset)){
                current_particle_cell.pc_offset++;
            }
cheesema's avatar
cheesema committed
106

cheesema's avatar
cheesema committed
107
108
109
            //back out your xz from the offset
            current_particle_cell.z = (current_particle_cell.pc_offset)/spatial_index_x_max(current_particle_cell.level);
            current_particle_cell.x = (current_particle_cell.pc_offset) - current_particle_cell.z*(spatial_index_x_max(current_particle_cell.level));
cheesema's avatar
cheesema committed
110

Krzysztof Gonciarz's avatar
Krzysztof Gonciarz committed
111
            current_gap.iterator = apr_access->gap_map.data[current_particle_cell.level][current_particle_cell.pc_offset][0].map.begin();
cheesema's avatar
cheesema committed
112
113
114
115
116
117
118
119
120
            //then find the gap.
            while((particle_number > apr_access->global_index_end(current_gap))){
                current_gap.iterator++;
            }

            current_particle_cell.y = (current_gap.iterator->first) + (particle_number - current_gap.iterator->second.global_index_begin);
            current_particle_cell.global_index = particle_number;
            set_neighbour_flag();
            return true;
cheesema's avatar
cheesema committed
121

cheesema's avatar
cheesema committed
122
123
124
125
        } else {
            current_particle_cell.global_index = -1;
            return false; // requested particle number exceeds the number of particles
        }
cheesema's avatar
cheesema committed
126

cheesema's avatar
cheesema committed
127
128
129
    }

    inline uint64_t particles_level_begin(const uint16_t& level_){
130
131
132
        //
        //  Used for finding the starting particle on a given level
        //
cheesema's avatar
cheesema committed
133
        return apr_access->global_index_by_level_begin[level_];
134
135
    }

cheesema's avatar
cheesema committed
136
    inline uint64_t particles_level_end(const uint16_t& level_){
137
138
139
        //
        //  Find the last particle on a given level
        //
cheesema's avatar
cheesema committed
140
        return (apr_access->global_index_by_level_end[level_]+1l);
141
142
    }

cheesema's avatar
cheesema committed
143
    inline uint64_t particles_z_begin(const uint16_t& level_,const uint64_t& z_){
144
145
146
        //
        //  Used for finding the starting particle on a given level
        //
cheesema's avatar
cheesema committed
147
        return apr_access->global_index_by_level_and_z_begin[level_][z_];
148
149
    }

cheesema's avatar
cheesema committed
150
    inline uint64_t particles_z_end(const uint16_t& level_,const uint64_t& z_){
151
152
153
        //
        //  Used for finding the starting particle on a given level
        //
cheesema's avatar
cheesema committed
154
        return apr_access->global_index_by_level_and_z_end[level_][z_]+1l;
155
156
    }

cheesema's avatar
cheesema committed
157
    inline uint64_t particles_zx_begin(const uint16_t& level_,const uint64_t& z_,const uint64_t& x_){
158
159
160
        //
        //  Used for finding the starting particle on a given level
        //
cheesema's avatar
cheesema committed
161
162

        return apr_access->get_parts_start(x_,z_,level_);
163
164
    }

cheesema's avatar
cheesema committed
165
    inline uint64_t particles_zx_end(const uint16_t& level_,const uint64_t& z_,const uint64_t& x_){
cheesema's avatar
cheesema committed
166
167
168
169
        //
        //  Used for finding the starting particle on a given level
        //

cheesema's avatar
cheesema committed
170
        return apr_access->get_parts_end(x_,z_,level_)+1l;
cheesema's avatar
cheesema committed
171
    }
172

cheesema's avatar
cheesema committed
173
    inline uint64_t particles_offset_end(const uint16_t& level,const uint64_t& offset){
174
        //
cheesema's avatar
cheesema committed
175
        //  Used for finding the starting particle on a given level
176
177
        //

cheesema's avatar
cheesema committed
178
179
180
181
182
183
        if(apr_access->gap_map.data[level][offset].size() > 0){
            auto it = apr_access->gap_map.data[level][offset][0].map.rbegin();
            return (it->second.global_index_begin + (it->second.y_end-it->first));
        } else {
            return 0;
        }
184

cheesema's avatar
cheesema committed
185
    }
186
187


cheesema's avatar
cheesema committed
188
189
190
191
    inline uint16_t x(){
        //get x
       return current_particle_cell.x;
    }
192

cheesema's avatar
cheesema committed
193
194
195
196
    inline uint16_t y(){
        //get x
        return current_particle_cell.y;
    }
197

cheesema's avatar
cheesema committed
198
199
200
201
    inline uint16_t z(){
        //get x
        return current_particle_cell.z;
    }
202

cheesema's avatar
cheesema committed
203
204
    inline uint8_t type(){
        //get type of the particle cell
205

cheesema's avatar
cheesema committed
206
207
208
209
        if(current_particle_cell.level==level_max()){
            return 1; //all highest resolution pcs are seed, when using the nieghborhood optimization/
        } else {
            return apr_access->particle_cell_type.data[current_particle_cell.global_index];
210
211
212
213
        }

    }

cheesema's avatar
cheesema committed
214
    inline uint16_t level(){
215
        //get x
cheesema's avatar
cheesema committed
216
        return current_particle_cell.level;
217
218
    }

Krzysztof Gonciarz's avatar
Krzysztof Gonciarz committed
219
    inline uint64_t global_index() const {
220
        //get x
cheesema's avatar
cheesema committed
221
        return current_particle_cell.global_index;
222
223
    }

cheesema's avatar
cheesema committed
224
225
    inline ParticleCell get_current_particle_cell(){
        return current_particle_cell;
226
227
    }

cheesema's avatar
cheesema committed
228
229
    inline ParticleCell get_neigh_particle_cell(){
        return neighbour_particle_cell;
230
231
    }

232

233

cheesema's avatar
cheesema committed
234
    bool find_neighbours_in_direction(const uint8_t& direction){
235

cheesema's avatar
cheesema committed
236
237
        //the three cases
        if(current_particle_cell.level == apr_access->level_max){
238
239
240
            //for (int l = 0; l < 2; ++l) {
            //level_delta = level_check_max[l];
            apr_access->get_neighbour_coordinate(current_particle_cell,neighbour_particle_cell,direction,_LEVEL_SAME,0);
241

242
243
244
245
246
247
248
            if(check_neighbours_particle_cell_in_bounds()){
                if(apr_access->find_particle_cell(neighbour_particle_cell,local_iterators.same_level[direction])){
                    //found the neighbour! :D
                    level_delta = _LEVEL_SAME;
                    return true;
                }
            };
249

250
            apr_access->get_neighbour_coordinate(current_particle_cell,neighbour_particle_cell,direction,_LEVEL_DECREASE,0);
251

252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
            if(check_neighbours_particle_cell_in_bounds()){
                if(apr_access->find_particle_cell(neighbour_particle_cell,local_iterators.parent_level[direction])){
                    level_delta = _LEVEL_DECREASE;
                    return true;
                }
            };

            //}

        } else if(current_particle_cell.level == apr_access->level_min){
            //for (int l = 0; l < 2; ++l) {
            //level_delta = level_check_min[l];
            apr_access->get_neighbour_coordinate(current_particle_cell,neighbour_particle_cell,direction,_LEVEL_SAME,0);

            if(check_neighbours_particle_cell_in_bounds()){
                if(apr_access->find_particle_cell(neighbour_particle_cell,local_iterators.same_level[direction])){
                    //found the neighbour! :D
                    level_delta = _LEVEL_SAME;
                    return true;
                }
            };

            apr_access->get_neighbour_coordinate(current_particle_cell,neighbour_particle_cell,direction,_LEVEL_INCREASE,0);

            if(check_neighbours_particle_cell_in_bounds()){
                if(apr_access->find_particle_cell(neighbour_particle_cell,local_iterators.child_level[direction][0])){
                    level_delta = _LEVEL_INCREASE;
                    return true;
                }
            };

            //}
cheesema's avatar
cheesema committed
284
        } else {
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
            //for (int l = 0; l < 3; ++l) {
            apr_access->get_neighbour_coordinate(current_particle_cell,neighbour_particle_cell,direction,_LEVEL_SAME,0);

            if(check_neighbours_particle_cell_in_bounds()){
                if(apr_access->find_particle_cell(neighbour_particle_cell,local_iterators.same_level[direction])){
                    //found the neighbour! :D
                    level_delta = _LEVEL_SAME;
                    return true;
                }
            };

            apr_access->get_neighbour_coordinate(current_particle_cell,neighbour_particle_cell,direction,_LEVEL_DECREASE,0);

            if(check_neighbours_particle_cell_in_bounds()){
                if(apr_access->find_particle_cell(neighbour_particle_cell,local_iterators.parent_level[direction])){
                    level_delta = _LEVEL_DECREASE;
                    return true;
                }
            };
            apr_access->get_neighbour_coordinate(current_particle_cell,neighbour_particle_cell,direction,_LEVEL_INCREASE,0);

            if(check_neighbours_particle_cell_in_bounds()){
                if(apr_access->find_particle_cell(neighbour_particle_cell,local_iterators.child_level[direction][0])){
                    level_delta = _LEVEL_INCREASE;
                    return true;
                }
            };
cheesema's avatar
cheesema committed
312

313
314


cheesema's avatar
cheesema committed
315
        }
316

317
318
319
        level_delta=_NO_NEIGHBOUR;

        return false;
320
321
322

    }

323
324


cheesema's avatar
cheesema committed
325

326

cheesema's avatar
cheesema committed
327
    bool set_neighbour_iterator(APRIterator<ImageType> &original_iterator, const uint8_t& direction, const uint8_t& index){
328
        //
cheesema's avatar
cheesema committed
329
        //  This is sets the this iterator, to the neighbour of the particle cell that original_iterator is pointing to
330
331
        //

cheesema's avatar
cheesema committed
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
        if(original_iterator.level_delta!=_LEVEL_INCREASE){
            //copy the information from the original iterator
            std::swap(current_particle_cell,original_iterator.neighbour_particle_cell);
            //current_gap = apr_access->get_local_iterator(original_iterator.local_iterators,
                                                               //   level_delta, direction,0);
        } else {
            if(index==0){
                std::swap(current_particle_cell,original_iterator.neighbour_particle_cell);
                //current_gap = apr_access->get_local_iterator(original_iterator.local_iterators,
                                                            // level_delta, direction,0);
            } else {
                bool success = original_iterator.find_next_child(direction,index);
                std::swap(current_particle_cell,original_iterator.neighbour_particle_cell);
                //current_gap = apr_access->get_local_iterator(original_iterator.local_iterators,
                                                            // level_delta, direction,index);
                return success;
            }
        }

        //this needs the if clause that finds the neighbour
        return true;
353
354
355

    }

cheesema's avatar
cheesema committed
356
    inline uint8_t number_neighbours_in_direction(const uint8_t& face){
357

cheesema's avatar
cheesema committed
358
359
360
361
362
363
364
        switch (level_delta){
            case _LEVEL_INCREASE:
                return 4;
            case _NO_NEIGHBOUR:
                return 0;
        }
        return 1;
365
366
367
368
369

    }

    inline unsigned int x_nearest_pixel(){
        //get x
cheesema's avatar
cheesema committed
370
        return floor((current_particle_cell.x+0.5)*pow(2, apr_access->level_max - current_particle_cell.level));
371
372
373
374
    }

    inline float x_global(){
        //get x
cheesema's avatar
cheesema committed
375
        return (current_particle_cell.x+0.5)*pow(2, apr_access->level_max - current_particle_cell.level);
376
377
378
379
    }

    inline unsigned int y_nearest_pixel(){
        //get x
cheesema's avatar
cheesema committed
380
        return floor((current_particle_cell.y+0.5)*pow(2, apr_access->level_max - current_particle_cell.level));
381
382
383
384
    }

    inline float y_global(){
        //get x
cheesema's avatar
cheesema committed
385
        return (current_particle_cell.y+0.5)*pow(2, apr_access->level_max - current_particle_cell.level);
386
387
388
    }

    inline unsigned int z_nearest_pixel(){
cheesema's avatar
cheesema committed
389
390
        //get z nearest pixel
        return floor((current_particle_cell.z+0.5)*pow(2, apr_access->level_max - current_particle_cell.level));
391
392
393
    }

    inline float z_global(){
cheesema's avatar
cheesema committed
394
395
        //get z global coordinate
        return (current_particle_cell.z+0.5)*pow(2, apr_access->level_max - current_particle_cell.level);
396
397
    }

cheesema's avatar
cheesema committed
398
    inline uint16_t level_min(){
399
        return apr_access->level_min;
400
401
    }

cheesema's avatar
cheesema committed
402
    inline uint16_t level_max(){
403
        return apr_access->level_max;
404
405
    }

cheesema's avatar
cheesema committed
406
    inline uint64_t spatial_index_x_max(const unsigned int level){
407
        return apr_access->x_num[level];
408
409
    }

cheesema's avatar
cheesema committed
410
    inline uint64_t spatial_index_y_max(const unsigned int level){
411
        return apr_access->y_num[level];
412
413
    }

cheesema's avatar
cheesema committed
414
    inline uint64_t spatial_index_z_max(const unsigned int level){
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
        return apr_access->z_num[level];
    }
    /////////////////////////
    /// Random access
    ///
    /////////////////////////

    bool set_iterator_by_particle_cell(ParticleCell& random_particle_cell){
        //
        //  Have to have set the particle cells x,y,z,level, and it will move the iterator to this location if it exists
        //

        random_particle_cell.pc_offset =  apr_access->x_num[random_particle_cell.level] * random_particle_cell.z + random_particle_cell.x;

        if(apr_access->find_particle_cell(random_particle_cell,current_gap)){
            current_particle_cell = random_particle_cell;
431
            set_neighbour_flag();
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
            //exists
            return true;
        } else {
            //particle cell doesn't exist
            return false;
        }
    }

    bool set_iterator_by_global_coordinate(float x,float y,float z){
        //
        //  Finds the Particle Cell for which the point (x,y,z) belongs to its spatial domain and set the iterator to it
        //

        //check in bounds
        if(((uint16_t)(x)>(apr_access->org_dims[1]-1)) | ((uint16_t)(z)>(apr_access->org_dims[2]-1)) | ((uint16_t)(y)>(apr_access->org_dims[0]-1))){
            //out of bounds
            return false;
        }

        //Then check from the highest level to lowest.
        ParticleCell particle_cell;
        particle_cell.y = round(y);
        particle_cell.x = round(x);
        particle_cell.z = round(z);
        particle_cell.level = level_max();

        particle_cell.pc_offset =  apr_access->x_num[particle_cell.level] * particle_cell.z + particle_cell.x;

cheesema's avatar
cheesema committed
460
        while( (particle_cell.level >= level_min()) && !(apr_access->find_particle_cell(particle_cell,current_gap)) ){
461
462
463
464
465
466
467
468
469
            particle_cell.y = particle_cell.y/2;
            particle_cell.x = particle_cell.x/2;
            particle_cell.z = particle_cell.z/2;
            particle_cell.level--;

            particle_cell.pc_offset =  apr_access->x_num[particle_cell.level] * particle_cell.z + particle_cell.x;
        }

        current_particle_cell = particle_cell; //if its in bounds it will always have a particle cell responsible
470
        set_neighbour_flag();
471
        return true;
cheesema's avatar
cheesema committed
472
473
474
    }


cheesema's avatar
cheesema committed
475
private:
476
    //private methods
cheesema's avatar
cheesema committed
477

478
    bool find_next_child(const uint8_t& direction,const uint8_t& index){
cheesema's avatar
cheesema committed
479

480
481
        level_delta = _LEVEL_INCREASE;
        apr_access->get_neighbour_coordinate(current_particle_cell,neighbour_particle_cell,direction,level_delta,index);
cheesema's avatar
cheesema committed
482

483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
        if(check_neighbours_particle_cell_in_bounds()){
            if(apr_access->find_particle_cell(neighbour_particle_cell,apr_access->get_local_iterator(local_iterators, level_delta, direction,index))){
                //found the neighbour! :D
                return true;
            }
        };
        return false;
    }

    inline bool check_neighbours_particle_cell_in_bounds(){
        //uses the fact that the coordinates have unsigned type, and therefore if they are negative they will be above the bound
        if(check_neigh_flag) {
            return (neighbour_particle_cell.x < apr_access->x_num[neighbour_particle_cell.level]) &
                   (neighbour_particle_cell.z < apr_access->z_num[neighbour_particle_cell.level]);
        } else {
            return true;
        }
    }
cheesema's avatar
cheesema committed
501

cheesema's avatar
cheesema committed
502
    bool move_iterator_to_next_non_empty_row(const uint64_t maximum_level){
cheesema's avatar
cheesema committed
503

504
        uint64_t offset_max = apr_access->x_num[current_particle_cell.level]*apr_access->z_num[current_particle_cell.level];
cheesema's avatar
cheesema committed
505

506
        //iterate until you find the next row or hit the end of the level
507
        while((current_particle_cell.pc_offset < offset_max) && (apr_access->gap_map.data[current_particle_cell.level][current_particle_cell.pc_offset].size()==0)){
508
509
            current_particle_cell.pc_offset++;
        }
cheesema's avatar
cheesema committed
510

511
512
513
514
515
516
517
518
519
520
521
        if(current_particle_cell.pc_offset == offset_max){
            //if within the level range, move to next level
            if(current_particle_cell.level < maximum_level){
                current_particle_cell.level++;
                current_particle_cell.pc_offset=0;
                return move_iterator_to_next_non_empty_row(maximum_level);
            } else {
                //reached last level
                return false;
            }
        } else {
522
            current_gap.iterator = apr_access->gap_map.data[current_particle_cell.level][current_particle_cell.pc_offset][0].map.begin();
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
            current_particle_cell.global_index=current_gap.iterator->second.global_index_begin;
            current_particle_cell.y = current_gap.iterator->first;

            //compute x and z
            current_particle_cell.z = (current_particle_cell.pc_offset)/spatial_index_x_max(current_particle_cell.level);
            current_particle_cell.x = (current_particle_cell.pc_offset) - current_particle_cell.z*(spatial_index_x_max(current_particle_cell.level));

            return true;
        }

    }


    bool move_to_next_particle_cell(){
        //  Assumes all state variabels are valid for the current particle cell
        //
        //  moves particles cell in y direction if possible on same level
        //

        if( (current_particle_cell.y+1) <= current_gap.iterator->second.y_end){
            //  Still in same y gap

            current_particle_cell.global_index++;
            current_particle_cell.y++;
            return true;

        } else {
            //not in the same gap
            current_gap.iterator++;//move the iterator forward.

            if(current_gap.iterator!=(apr_access->gap_map.data[current_particle_cell.level][current_particle_cell.pc_offset][0].map.end())){
                //I am in the next gap
                current_particle_cell.global_index++;
                current_particle_cell.y = current_gap.iterator->first; // the key is the first y value for the gap
                return true;
            } else {
                current_particle_cell.pc_offset++;
                //reached the end of the row
                if(move_iterator_to_next_non_empty_row(level_max())){
                    //found the next row set the iterator to the begining and find the particle cell.

                    return true;
                } else {
                    //reached the end of the particle cells
Ulrik Günther's avatar
Ulrik Günther committed
567
                    current_particle_cell.global_index = UINT64_MAX;
568
569
570
571
572
573
574
575
576
                    return false;
                }
            }
        }
    }

    inline void set_neighbour_flag(){
        check_neigh_flag = apr_access->check_neighbours_flag(current_particle_cell.x,current_particle_cell.z,current_particle_cell.level);
    }
577
578
579
580

};


cheesema's avatar
cheesema committed
581
#endif //PARTPLAY_APR_ITERATOR_NEW_HPP