Skip to content

Commit dcf0495

Browse files
committed
32bit voxel ids option
2 parents 7840dad + 7fd54f2 commit dcf0495

File tree

9 files changed

+481
-68
lines changed

9 files changed

+481
-68
lines changed

processor.h

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
#ifndef PROCESSOR_H
22
#define PROCESSOR_H
33

4-
#include "voxelizer.h"
4+
#include "traversal.h"
55
#include "factory.h"
66
#include "storage.h"
77
#include "writer.h"
88
#include "progress_writer.h"
99
#include "volume.h"
10+
#include "voxelizer.h"
1011

1112
#include <TopoDS_Shape.hxx>
1213
#include <TopoDS_Compound.hxx>
@@ -41,10 +42,15 @@ class SEPARATE_MINUS : public voxelization_mode {
4142
public:
4243
SEPARATE_MINUS() : voxelization_mode(3) {}
4344
};
45+
enum VOXEL_VALUATION {
46+
CONSTANT_ONE,
47+
PRODUCT_ID
48+
};
4449
class fill_volume_t {
4550
public:
4651
bool y;
47-
fill_volume_t(bool b) : y(b) {}
52+
VOXEL_VALUATION value;
53+
fill_volume_t(bool b, VOXEL_VALUATION v = CONSTANT_ONE) : y(b), value(v) {}
4854
};
4955
class VOLUME : public fill_volume_t {
5056
public:
@@ -54,6 +60,10 @@ class SURFACE : public fill_volume_t {
5460
public:
5561
SURFACE() : fill_volume_t(false) {}
5662
};
63+
class VOLUME_PRODUCT_ID : public fill_volume_t {
64+
public:
65+
VOLUME_PRODUCT_ID() : fill_volume_t(true, PRODUCT_ID) {}
66+
};
5767

5868
class output {
5969
private:
@@ -186,22 +196,53 @@ class processor : public abstract_processor {
186196
abstract_voxel_storage* to_write = volume.y ? voxels_temp_ : voxels_;
187197

188198
if (volume.y) {
189-
voxelizer voxeliser(it->second, (regular_voxel_storage*) to_write);
199+
voxelizer voxeliser(it->second, (regular_voxel_storage*) to_write, !use_scanline_, !use_scanline_);
200+
voxeliser.epsilon() = 1e-9;
190201
voxeliser.Convert();
191202

192-
volume_filler volume((regular_voxel_storage*) to_write);
193-
volume.fill();
203+
auto filled = traversal_voxel_filler_inverse()((regular_voxel_storage*)to_write);
204+
// @todo this is not very efficient as the above does exactly the inverse subtraction
205+
to_write->boolean_union_inplace(filled);
206+
delete filled;
194207

195208
output.intermediate_result(it->first, voxels_, voxels_temp_);
209+
210+
int n = voxels_->value_bits();
211+
if (volume.value == PRODUCT_ID) {
212+
if (n != 32) {
213+
throw std::runtime_error("Unable to assign product ids to this voxel value type");
214+
}
215+
if (auto cvs32 = dynamic_cast<chunked_voxel_storage<voxel_uint32_t>*>(voxels_)) {
216+
size_t nchunksx, nchunksy, nchunksz;
217+
cvs32->num_chunks().tie(nchunksx, nchunksy, nchunksz);
218+
BEGIN_LOOP(size_t(0), nchunksx, 0U, nchunksy, 0U, nchunksz)
219+
auto c = cvs32->get_chunk(ijk);
220+
if (c != nullptr) {
221+
if (!c->is_explicit()) {
222+
throw std::runtime_error("Not implemented");
223+
}
224+
auto c32 = (continuous_voxel_storage<voxel_uint32_t>*) c;
225+
auto d = c32->data();
226+
for (size_t i = 0; i < c32->size(); ++i) {
227+
if (d[i] == 1) {
228+
d[i] = it->first;
229+
}
230+
}
231+
}
232+
END_LOOP;
233+
}
234+
}
196235

197-
delete voxels_temp_;
198236
if (use_copy_) {
199-
voxels_temp_ = voxels_temp_->empty_copy();
237+
auto tmp = voxels_temp_->empty_copy();
238+
delete voxels_temp_;
239+
voxels_temp_ = tmp;
200240
} else {
241+
delete voxels_temp_;
201242
voxels_temp_ = factory_.create(x1_, y1_, z1_, d_, nx_, ny_, nz_);
202243
}
203244
} else {
204-
voxelizer voxeliser(it->second, (regular_voxel_storage*) to_write);
245+
voxelizer voxeliser(it->second, (regular_voxel_storage*) to_write, !use_scanline_, !use_scanline_);
205246
voxeliser.epsilon() = 1e-9;
206247
voxeliser.Convert();
207248
}

storage.cpp

Lines changed: 103 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#include "storage.h"
22
#include "traversal.h"
33

4+
#include <map>
5+
#include <array>
6+
47
set_voxel_iterator::set_voxel_iterator(regular_voxel_storage* storage, vec_n<3, size_t> current)
58
: storage_(storage)
69
, current_(current)
@@ -35,23 +38,49 @@ set_voxel_iterator& set_voxel_iterator::operator++() {
3538
return *this;
3639
}
3740

38-
bool set_voxel_iterator::neighbour(const vec_n<3, size_t>& d) const {
39-
vec_n<3, size_t> v = current_ + d;
41+
bool set_voxel_iterator::neighbour(const vec_n<3, long>& d) const {
42+
vec_n<3, size_t> v = (current_.as<long>() + d).as<size_t>();
4043
if ((v < bounds_[0]).any() || (v > bounds_[1]).any()) {
4144
return false;
4245
}
4346
return storage_->Get(v);
4447
}
4548

46-
void regular_voxel_storage::obj_export(std::ostream& fs, bool with_components) {
49+
void* set_voxel_iterator::value(void* val) const {
50+
storage_->Get(current_, val);
51+
return val;
52+
}
53+
54+
void* set_voxel_iterator::neighbour_value(const vec_n<3, long>& d, void* val) const {
55+
vec_n<3, size_t> v = (current_.as<long>() + d).as<size_t>();
56+
if ((v < bounds_[0]).any() || (v > bounds_[1]).any()) {
57+
uint8_t* loc = (uint8_t*)val;
58+
// @todo is this correct?
59+
for (int i = 0; i < storage_->value_bits() / 8; ++i) {
60+
(*loc++) = 0;
61+
}
62+
} else {
63+
storage_->Get(v, val);
64+
}
65+
return val;
66+
}
67+
68+
void regular_voxel_storage::obj_export(std::ostream& fs, bool with_components, bool use_value) {
4769
obj_export_helper helper(fs);
48-
obj_export(helper, with_components);
70+
obj_export(helper, with_components, use_value);
4971
}
5072

51-
void regular_voxel_storage::obj_export(obj_export_helper& obj, bool with_components) {
73+
void regular_voxel_storage::obj_export(obj_export_helper& obj, bool with_components, bool use_value) {
5274
std::ostream& fs = *obj.stream;
5375

54-
if (with_components) {
76+
fs << "vn 1 0 0\n";
77+
fs << "vn -1 0 0\n";
78+
fs << "vn 0 1 0\n";
79+
fs << "vn 0 -1 0\n";
80+
fs << "vn 0 0 1\n";
81+
fs << "vn 0 0 -1\n";
82+
83+
if (with_components && !use_value) {
5584
size_t counter = 0;
5685
connected_components(this, [&obj, &fs, &counter](regular_voxel_storage* component) {
5786
fs << "g component" << (counter++) << "\n";
@@ -66,10 +95,18 @@ void regular_voxel_storage::obj_export(obj_export_helper& obj, bool with_compone
6695

6796
size_t& nv = obj.vert_counter;
6897

98+
// big enough?
99+
char V0[8];
100+
char V1[8];
101+
102+
std::map< std::array<size_t, 3>, size_t > vertex_map;
103+
std::map< std::array<long long, 2>, std::vector< std::pair<std::array<size_t, 3>, size_t> > > triangles;
104+
69105
const double d = voxel_size();
70106
for (auto it = begin(); it != end(); ++it) {
107+
it.value(V1);
71108
for (size_t f = 0; f < 6; ++f) {
72-
vec_n<3, size_t> n;
109+
vec_n<3, long> n;
73110
size_t normal = f / 2;
74111
size_t o0 = (normal + 1) % 3;
75112
size_t o1 = (normal + 2) % 3;
@@ -80,25 +117,61 @@ void regular_voxel_storage::obj_export(obj_export_helper& obj, bool with_compone
80117
break;
81118
}
82119
}
83-
if (!it.neighbour(n)) {
84-
std::array<vec_n<3, double >, 4> vs;
85-
vs.fill((*it).as<double>() * d + origin());
86-
vs[1].get(o0) += d;
87-
vs[2].get(o0) += d;
88-
vs[2].get(o1) += d;
89-
vs[3].get(o1) += d;
120+
if (use_value
121+
? (
122+
!equal_pointed_to(value_bits() / 8, it.neighbour_value(n, V0), V1) &&
123+
(!(!is_zero(value_bits() / 8, V0) && !is_zero(value_bits() / 8, V1)) || side)
124+
)
125+
: !it.neighbour(n))
126+
{
127+
std::array< std::array<size_t, 3>, 4 > vs;
128+
vs.fill((*it).as_array());
129+
vs[1][o0] += 1;
130+
vs[2][o0] += 1;
131+
vs[2][o1] += 1;
132+
vs[3][o1] += 1;
90133
if (!side) {
91134
std::reverse(vs.begin(), vs.end());
92135
}
93136
for (auto& v : vs) {
94137
if (side) {
95-
v.get(normal) += d;
138+
v[normal] += 1;
139+
}
140+
auto inserted = vertex_map.insert({ v, vertex_map.size() + 1 });
141+
if (inserted.second) {
142+
fs << "v";
143+
for (int i = 0; i < 3; ++i) {
144+
fs << " " << (v[i] * d + origin().get(i));
145+
}
146+
fs << "\n";
147+
}
148+
}
149+
static std::array< std::array<int, 3>, 2 > indices = {{
150+
{{0,1,2}},
151+
{{0,2,3}}
152+
}};
153+
if (!use_value) {
154+
for (auto& i : indices) {
155+
fs << "f";
156+
for (auto& j : i) {
157+
fs << " " << vertex_map.find(vs[j])->second << "//" << (f+1);
158+
}
159+
fs << "\n";
160+
}
161+
} else {
162+
auto va = to_number(value_bits() / 8, V0);
163+
auto vb = to_number(value_bits() / 8, V1);
164+
if (va > vb) {
165+
std::swap(va, vb);
96166
}
97-
fs << "v" << " " << v.format(false) << "\n";
167+
for (auto& i : indices) {
168+
std::array<size_t, 3> arr;
169+
for (int j = 0; j < 3; ++j) {
170+
arr[j] = vertex_map.find(vs[i[j]])->second;
171+
}
172+
triangles[{ { va, vb }}].push_back({ arr, f + 1 });
173+
}
98174
}
99-
fs << "f " << (nv + 0) << " " << (nv + 1) << " " << (nv + 2) << "\n";
100-
fs << "f " << (nv + 0) << " " << (nv + 2) << " " << (nv + 3) << "\n";
101-
nv += 4;
102175
}
103176
}
104177
/*
@@ -108,6 +181,17 @@ void regular_voxel_storage::obj_export(obj_export_helper& obj, bool with_compone
108181
n++;
109182
*/
110183
}
184+
185+
for (const auto& p : triangles) {
186+
fs << "g " << p.first[0] << "-" << p.first[1] << "\n";
187+
for (const auto& t : p.second) {
188+
fs << "f";
189+
for (auto& i : t.first) {
190+
fs << " " << i << "//" << t.second;
191+
}
192+
fs << "\n";
193+
}
194+
}
111195
}
112196

113197
regular_voxel_storage* storage_for(std::array< vec_n<3, double>, 2 >& bounds, size_t max_extents, size_t padding, size_t chunk_size) {

0 commit comments

Comments
 (0)