@@ -164,10 +164,6 @@ bool decimateSpatioTemporal(const std::string &file_stub, double vox_width, int
164164 return true ;
165165}
166166
167- int sign (double x)
168- {
169- return (x > 0.0 ) - (x < 0.0 );
170- }
171167
172168bool decimateRaysSpatial (const std::string &file_stub, double vox_width)
173169{
@@ -177,148 +173,26 @@ bool decimateRaysSpatial(const std::string &file_stub, double vox_width)
177173
178174 // By maintaining these buffers below, we avoid almost all memory fragmentation
179175 ray::Cloud chunk;
180- std::vector<int64_t > subsample;
181- std::set<Eigen::Vector3i, ray::Vector3iLess> voxel_set;
182176
177+ Subsampler subsampler;
183178 auto decimate = [&](std::vector<Eigen::Vector3d> &starts, std::vector<Eigen::Vector3d> &ends,
184179 std::vector<double > ×, std::vector<ray::RGBA> &colours)
185180 {
186181 double width = 0.01 * vox_width;
187- subsample.clear ();
182+ subsampler. subsample .clear ();
188183 for (int i = 0 ; i < (int )ends.size (); i++)
189184 {
190- // #define END_FIRST // by traversing from end to start we match the existence of the ray more to the free space near the end point. In building1 test start first found more ray locations
185+ #define END_FIRST // Testing on building.ply it finds more rays, so deemed to be more successful at filling space
191186 #if defined END_FIRST
192- Eigen::Vector3d dir = starts[i] - ends[i];
193- const Eigen::Vector3d source = ends[i] / width;
194- const Eigen::Vector3d target = starts[i] / width;
187+ walkGrid (ends[i] / width, starts[i] / width, subsampler, i);
195188 #else
196- Eigen::Vector3d dir = ends[i] - starts[i];
197- const Eigen::Vector3d source = starts[i] / width;
198- const Eigen::Vector3d target = ends[i] / width;
199- #endif
200-
201- #define OLD_METHOD
202- #if defined OLD_METHOD
203- const double length = dir.norm ();
204- dir /= length;
205- for (int a = 0 ; a<3 ; a++)
206- {
207- if (dir[a] == 0.0 )
208- {
209- dir[a] = 1e-10 ; // prevent division by 0
210- }
211- }
212- const double eps = 1e-9 ; // to stay away from edge cases
213- const double maxDist = (target - source).norm ();
214-
215- // cached values to speed up the loop below
216- Eigen::Vector3i adds;
217- Eigen::Vector3d offsets;
218- for (int k = 0 ; k < 3 ; ++k)
219- {
220- if (dir[k] > 0.0 )
221- {
222- adds[k] = 1 ;
223- offsets[k] = 0.5 ;
224- }
225- else
226- {
227- adds[k] = -1 ;
228- offsets[k] = -0.5 ;
229- }
230- }
231-
232- Eigen::Vector3d p = source; // our moving variable as we walk over the grid
233- Eigen::Vector3i inds ((int )std::floor (p[0 ]), (int )std::floor (p[1 ]), (int )std::floor (p[2 ]));
234- if (voxel_set.insert (inds).second )
235- {
236- subsample.push_back (i);
237- continue ;
238- }
239- double depth = 0 ;
240- // for every ray, walk over its length and if there is a free space then add it
241- do
242- {
243- double ls[3 ] = { (std::round (p[0 ] + offsets[0 ]) - p[0 ]) / dir[0 ], (std::round (p[1 ] + offsets[1 ]) - p[1 ]) / dir[1 ],
244- (std::round (p[2 ] + offsets[2 ]) - p[2 ]) / dir[2 ] };
245- int axis = (ls[0 ] < ls[1 ] && ls[0 ] < ls[2 ]) ? 0 : (ls[1 ] < ls[2 ] ? 1 : 2 );
246- inds[axis] += adds[axis];
247- depth += ls[axis] + eps;
248- p = source + dir * depth;
249-
250- if (voxel_set.insert (inds).second )
251- {
252- subsample.push_back (i);
253- break ; // only adding to one cell
254- }
255- } while (depth <= maxDist);
256- #else
257- Eigen::Vector3i p = Eigen::Vector3d (std::floor (source[0 ]), std::floor (source[1 ]), std::floor (source[2 ])).cast <int >();
258- Eigen::Vector3i end = Eigen::Vector3d (std::floor (target[0 ]), std::floor (target[1 ]), std::floor (target[2 ])).cast <int >();
259-
260- if (voxel_set.insert (p).second )
261- {
262- std::cout << " missed p: " << p.transpose () << " between " << source.transpose () << " and " << target.transpose () << std::endl;
263- subsample.push_back (i);
264- continue ; // only adding to one cell
265- }
266-
267- Eigen::Vector3i step (sign (target[0 ] - source[0 ]), sign (target[1 ] - source[1 ]), sign (target[2 ] - source[2 ]));
268- Eigen::Vector3d tmax, tdelta;
269- for (int j = 0 ; j<3 ; j++)
270- {
271- step[j] = sign (target[j] - source[j]);
272- double to = std::abs (source[j] - p[j] - (double )std::max (0 , step[j]));
273- double dir = std::max (std::numeric_limits<double >::min (), std::abs (source[j] - target[j]));
274- tmax[j] = to / dir;
275- tdelta[j] = 1.0 / dir;
276- }
277-
278- while (p != end)
279- {
280- int ax = tmax[0 ] < tmax[1 ] && tmax[0 ] < tmax[2 ] ? 0 : (tmax[1 ] < tmax[2 ] ? 1 : 2 );
281- p[ax] += step[ax];
282- tmax[ax] += tdelta[ax];
283- /* if (tmax[0] < tmax[1])
284- {
285- if (tmax[0] < tmax[2])
286- {
287- p[0] += step[0];
288- tmax[0] += tdelta[0];
289- }
290- else
291- {
292- p[2] += step[2];
293- tmax[2] += tdelta[2];
294- }
295- }
296- else
297- {
298- if (tmax[1] < tmax[2])
299- {
300- p[1] += step[1];
301- tmax[1] += tdelta[1];
302- }
303- else
304- {
305- p[2] += step[2];
306- tmax[2] += tdelta[2];
307- }
308- }*/
309- if (voxel_set.insert (p).second )
310- {
311- std::cout << " missed p: " << p.transpose () << " between " << source.transpose () << " and " << target.transpose () << std::endl;
312- subsample.push_back (i);
313- break ; // only adding to one cell
314- }
315- }
316- #endif
189+ walkGrid (starts[i] / width, ends[i] / width, subsampler, i);
190+ #endif
317191 }
318- chunk.resize (subsample.size ());
319- for (int64_t i = 0 ; i < (int64_t )subsample.size (); i++)
192+ chunk.resize (subsampler. subsample .size ());
193+ for (int64_t i = 0 ; i < (int64_t )subsampler. subsample .size (); i++)
320194 {
321- int64_t id = subsample[i];
195+ int64_t id = subsampler. subsample [i];
322196 chunk.starts [i] = starts[id];
323197 chunk.ends [i] = ends[id];
324198 chunk.colours [i] = colours[id];
0 commit comments