11#include " storage.h"
22#include " traversal.h"
33
4+ #include < map>
5+ #include < array>
6+
47set_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
113197regular_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