-
Notifications
You must be signed in to change notification settings - Fork 14
/
sweep.h
79 lines (61 loc) · 1.4 KB
/
sweep.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#ifndef SWEEP_H
#define SWEEP_H
#include "storage.h"
class sweep {
public:
abstract_voxel_storage* until = nullptr;
boost::optional<int> max_depth;
regular_voxel_storage* operator()(abstract_voxel_storage* storage, int dx, int dy, int dz) {
int d[3] = { dx, dy, dz };
int nonzero = 0;
int D = -1;
for (int i = 0; i < 3; ++i) {
if (d[i] != 0) {
nonzero++;
D = i;
}
}
if (nonzero != 1) {
throw std::runtime_error("Only orthogonal sweeps supported");
}
uint32_t v = 1;
const bool use_count = storage->value_bits() == 32;
regular_voxel_storage* swepts = (regular_voxel_storage*) storage->copy();
auto bounds = storage->bounds();
auto extents = swepts->extents().as<long>();
auto zero = make_vec<long>(0, 0, 0);
bool pos = d[D] > 0;
BEGIN_LOOP_I2(bounds[0], bounds[1])
if (storage->Get(ijk)) {
if (use_count) {
storage->Get(ijk, &v);
}
auto ijk2 = ijk.as<long>();
int i = 1;
while (until || (i < std::abs(d[D]) * v)) {
if (pos) {
ijk2.get(D)++;
}
else {
ijk2.get(D)--;
}
if (!((ijk2 >= zero).all() && (ijk2 < extents).all())) {
break;
}
if (until) {
if (until->Get(ijk2.as<size_t>())) {
break;
}
}
swepts->Set(ijk2.as<size_t>());
if (max_depth && i >= *max_depth) {
break;
}
++i;
}
}
END_LOOP;
return swepts;
}
};
#endif