1
1
#include " storage.h"
2
2
#include " traversal.h"
3
3
4
+ #include < map>
5
+ #include < array>
6
+
4
7
set_voxel_iterator::set_voxel_iterator (regular_voxel_storage* storage, vec_n<3 , size_t > current)
5
8
: storage_(storage)
6
9
, current_(current)
@@ -35,23 +38,49 @@ set_voxel_iterator& set_voxel_iterator::operator++() {
35
38
return *this ;
36
39
}
37
40
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 >() ;
40
43
if ((v < bounds_[0 ]).any () || (v > bounds_[1 ]).any ()) {
41
44
return false ;
42
45
}
43
46
return storage_->Get (v);
44
47
}
45
48
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) {
47
69
obj_export_helper helper (fs);
48
- obj_export (helper, with_components);
70
+ obj_export (helper, with_components, use_value );
49
71
}
50
72
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 ) {
52
74
std::ostream& fs = *obj.stream ;
53
75
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) {
55
84
size_t counter = 0 ;
56
85
connected_components (this , [&obj, &fs, &counter](regular_voxel_storage* component) {
57
86
fs << " g component" << (counter++) << " \n " ;
@@ -66,10 +95,18 @@ void regular_voxel_storage::obj_export(obj_export_helper& obj, bool with_compone
66
95
67
96
size_t & nv = obj.vert_counter ;
68
97
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
+
69
105
const double d = voxel_size ();
70
106
for (auto it = begin (); it != end (); ++it) {
107
+ it.value (V1);
71
108
for (size_t f = 0 ; f < 6 ; ++f) {
72
- vec_n<3 , size_t > n;
109
+ vec_n<3 , long > n;
73
110
size_t normal = f / 2 ;
74
111
size_t o0 = (normal + 1 ) % 3 ;
75
112
size_t o1 = (normal + 2 ) % 3 ;
@@ -80,25 +117,61 @@ void regular_voxel_storage::obj_export(obj_export_helper& obj, bool with_compone
80
117
break ;
81
118
}
82
119
}
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 ;
90
133
if (!side) {
91
134
std::reverse (vs.begin (), vs.end ());
92
135
}
93
136
for (auto & v : vs) {
94
137
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);
96
166
}
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
+ }
98
174
}
99
- fs << " f " << (nv + 0 ) << " " << (nv + 1 ) << " " << (nv + 2 ) << " \n " ;
100
- fs << " f " << (nv + 0 ) << " " << (nv + 2 ) << " " << (nv + 3 ) << " \n " ;
101
- nv += 4 ;
102
175
}
103
176
}
104
177
/*
@@ -108,6 +181,17 @@ void regular_voxel_storage::obj_export(obj_export_helper& obj, bool with_compone
108
181
n++;
109
182
*/
110
183
}
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
+ }
111
195
}
112
196
113
197
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