Radium Engine  1.5.20
Loading...
Searching...
No Matches
Grid.hpp
1#pragma once
2
3#include <vector>
4
5#include <Core/RaCore.hpp>
6#include <Eigen/Core>
7
8namespace Ra {
9namespace Core {
16template <typename T, uint D>
17class Grid
18{
19
20 public:
21 // public types and constants.
22 static const uint Dimension = D;
23 using IdxVector =
24 Eigen::Matrix<uint, D, 1>;
25 using OffsetVector = Eigen::Matrix<int, D, 1>;
26
30 {
31 public:
32 //
33 // Construction
34 //
35
37 explicit Iterator( const IdxVector& size, uint startIdx = 0 );
38
40 Iterator( const IdxVector& size, const IdxVector& startIdx );
41
43 explicit Iterator( const Grid<T, D>& grid, uint startIdx = 0 );
44
46 Iterator( const Grid<T, D>& grid, const IdxVector& startIdx );
47
49 Iterator( const Iterator& other ) = default;
50 Iterator& operator=( const Iterator& other ) = default;
51
53 template <typename T2>
54 typename Grid<T2, D>::Iterator cast() const;
55
56 //
57 // Basic getters and setters
58 //
59
61 inline void setFromLinear( uint idx );
62
64 inline void setFromVector( const IdxVector& idx );
65
67 inline uint getLinear() const;
68
70 inline IdxVector getVector() const;
71
73 inline const IdxVector& getGridSize() const;
74
76 inline bool isOut() const;
77
79 inline bool isIn() const;
80
81 //
82 // Increment and decrement operators
83 //
84
86 inline Iterator& operator++();
87 inline Iterator operator++( int );
88
90 inline Iterator& operator--();
91 inline Iterator operator--( int );
92
93 //
94 // Add and substract operators with linear offset
95 //
96
98 inline Iterator& operator+=( uint i );
99
101 inline Iterator& operator-=( uint i );
102
103 //
104 // Add and substract operators with vector offset
105 //
106
107 // Note : these convenience functions do not do any kind
108 // of check. If you get out of bounds on one dimension, the iterator
109 // might still be valid but not pointing to the element you think
110 // it should.
111
112 inline Iterator& operator+=( const IdxVector& idx );
113 inline Iterator& operator-=( const IdxVector& idx );
114 inline Iterator& operator+=( const OffsetVector& idx );
115
118 bool isValidOffset( const OffsetVector& idx );
119
120 //
121 // Comparison operators
122 //
123
124 // Note : comparing iterators of different grid sizes will assert.
125
126 inline bool operator==( const Iterator& other ) const;
127 inline bool operator<( const Iterator& other ) const;
128
129 //
130 // Extra operators
131 //
132
133 // Declare binary operators directly (see C++ faq 35.16)
134 friend Iterator operator+( const Iterator& it, uint i ) {
135 Iterator copy( it );
136 return copy += i;
137 }
138 friend Iterator operator-( const Iterator& it, uint i ) {
139 Iterator copy( it );
140 return copy -= i;
141 }
142 friend Iterator operator+( const Iterator& it, const IdxVector& idx ) {
143 Iterator copy( it );
144 return copy += idx;
145 }
146 friend Iterator operator-( const Iterator& it, const IdxVector& idx ) {
147 Iterator copy( it );
148 return copy -= idx;
149 }
150 friend Iterator operator+( const Iterator& it, const OffsetVector& idx ) {
151 Iterator copy( it );
152 return copy += idx;
153 }
154
155 // Extraneous comparison operators default implementation.
156 inline bool operator!=( const Iterator& rhs ) const { return !( *this == rhs ); }
157 inline bool operator>( const Iterator& rhs ) const { return rhs < *this; }
158 inline bool operator<=( const Iterator& rhs ) const { return !( *this > rhs ); }
159 inline bool operator>=( const Iterator& rhs ) const { return !( *this < rhs ); }
160
161 private:
162 const IdxVector& m_sizes;
163 uint m_index;
164 };
165
166 public:
167 //
168 // Constructors
169 //
170
172 Grid( const IdxVector& size = IdxVector::Zero(), const T& val = T() ) :
173 m_size( size ), m_data( size.prod(), val ) {}
174
176 Grid( const IdxVector& size, const T* values ) :
177 m_size( size ), m_data( size.prod(), values ) {}
178
180 Grid( const Grid<T, D>& other ) = default;
181 Grid& operator=( const Grid<T, D>& other ) = default;
182
183 //
184 // Basic getters
185 //
186
188 inline uint size() const;
190 inline const IdxVector& sizeVector() const;
192 inline bool empty() const;
194 inline void clear();
195
196 //
197 // Element access
198 //
199
201 // Note that since initializer lists are implicitly convertible to
202 // Eigen vectors, you can call grid.at({x,y,z})
203 inline const T& at( const IdxVector& idx ) const;
204 inline T& at( const IdxVector& idx );
205
207 inline const T& at( uint idx ) const;
208 inline T& at( uint idx );
209
211 inline const T& at( const Iterator& it ) const;
212 inline T& at( const Iterator& it );
213
215 inline const T* data() const;
216
218 inline T* data();
219
220 //
221 // std::iterators-like interface
222 //
223
225 inline Iterator begin();
226 inline Iterator begin() const;
227
229 inline Iterator end();
230 inline Iterator end() const;
231
232 protected:
237};
238
239// Anonymous helper functions to convert to/from multi-dimensional indices
240// If we want to make the grid row-major we just need to overload these functions
241// by reversing the loops.
242namespace {
243
244template <typename T, uint D>
245inline typename Grid<T, D>::IdxVector
246linearToIdxVector( uint linIdx, const typename Grid<T, D>::IdxVector& size ) {
248
249 for ( uint i = 0; i < D; ++i ) {
250 result[i] = linIdx % size[i];
251 linIdx = linIdx / size[i];
252 }
253 return result;
254}
255
256template <typename T, uint D>
257inline uint idxVectorToLinear( const typename Grid<T, D>::IdxVector& vecIdx,
258 const typename Grid<T, D>::IdxVector& size ) {
259 uint result = 0;
260 uint dimProd = 1;
261 for ( uint i = 0; i < D; ++i ) {
262 result += vecIdx[i] * dimProd;
263 dimProd *= size[i];
264 }
265 return result;
266}
267} // namespace
268
269// Vector size and data management.
270//
271
272template <typename T, uint D>
273inline uint Grid<T, D>::size() const {
274 CORE_ASSERT( m_data.size() == m_size.prod(), "Inconsistent grid size" );
275 return m_data.size();
276}
277
278template <typename T, uint D>
279inline const typename Grid<T, D>::IdxVector& Grid<T, D>::sizeVector() const {
280 CORE_ASSERT( m_data.size() == m_size.prod(), "Inconsistent grid size" );
281 return m_size;
282}
283
284template <typename T, uint D>
285inline bool Grid<T, D>::empty() const {
286 CORE_ASSERT( m_data.size() == m_size.prod(), "Inconsistent grid size" );
287 return m_data.empty();
288}
289
290template <typename T, uint D>
291inline void Grid<T, D>::clear() {
292 m_data.clear();
293 m_size = IdxVector::Zero();
294 CORE_ASSERT( empty(), "Inconsistent grid" );
295}
296
297template <typename T, uint D>
298inline const T* Grid<T, D>::data() const {
299 return m_data.data();
300}
301
302template <typename T, uint D>
303inline T* Grid<T, D>::data() {
304 return m_data.data();
305}
306
307//
308// Individual element access.
309//
310
311template <typename T, uint D>
312inline const T& Grid<T, D>::at( const typename Grid<T, D>::IdxVector& idx ) const {
313 const uint linIdx = idxVectorToLinear<T, D>( idx, sizeVector() );
314 CORE_ASSERT( linIdx < m_data.size(), "Invalid vector index" );
315 return m_data[linIdx];
316}
317
318template <typename T, uint D>
319inline T& Grid<T, D>::at( const typename Grid<T, D>::IdxVector& idx ) {
320 const uint linIdx = idxVectorToLinear<T, D>( idx, sizeVector() );
321 CORE_ASSERT( linIdx < m_data.size(), "Invalid vector index" );
322 return m_data[linIdx];
323}
324
325template <typename T, uint D>
326inline const T& Grid<T, D>::at( uint idx ) const {
327 CORE_ASSERT( idx < m_data.size(), "Invalid vector index" );
328 return m_data[idx];
329}
330
331template <typename T, uint D>
332inline T& Grid<T, D>::at( uint idx ) {
333 CORE_ASSERT( idx < m_data.size(), "Invalid vector index" );
334 return m_data[idx];
335}
336
337template <typename T, uint D>
338const T& Grid<T, D>::at( const typename Grid<T, D>::Iterator& it ) const {
339 CORE_ASSERT( it.getGridSize() == m_size, "Incompatible iterator" );
340 return at( it.getLinear() );
341}
342
343template <typename T, uint D>
344T& Grid<T, D>::at( const typename Grid<T, D>::Iterator& it ) {
345 CORE_ASSERT( it.getGridSize() == m_size, "Incompatible iterator" );
346 return at( it.getLinear() );
347}
348
349//
350// Iterators begin / end functions.
351//
352
353template <typename T, uint D>
355 return Iterator( *this );
356}
357
358template <typename T, uint D>
359inline typename Grid<T, D>::Iterator Grid<T, D>::begin() const {
360 return Iterator( *this );
361}
362
363template <typename T, uint D>
365 return Iterator( *this, size() );
366}
367
368template <typename T, uint D>
369inline typename Grid<T, D>::Iterator Grid<T, D>::end() const {
370 return Iterator( *this, size() );
371}
372
373//
374// Iterators construction
375//
376
377template <typename T, uint D>
378inline Grid<T, D>::Iterator::Iterator( const typename Grid<T, D>::IdxVector& size, uint startIdx ) :
379 m_sizes( size ) {
380 setFromLinear( startIdx );
381}
382
383template <typename T, uint D>
384inline Grid<T, D>::Iterator::Iterator( const typename Grid<T, D>::IdxVector& size,
385 const typename Grid<T, D>::IdxVector& startIdx ) :
386 m_sizes( size ) {
387 setFromVector( startIdx );
388}
389
390template <typename T, uint D>
391inline Grid<T, D>::Iterator::Iterator( const Grid<T, D>& grid, uint startIdx ) :
392 m_sizes( grid.sizeVector() ) {
393 setFromLinear( startIdx );
394}
395
396template <typename T, uint D>
398 const typename Grid<T, D>::IdxVector& startIdx ) :
399 m_sizes( grid.sizeVector() ) {
400 setFromVector( startIdx );
401}
402
403//
404// Basic Iterator get/set
405//
406
407template <typename T, uint D>
409 m_index = i;
410}
411
412template <typename T, uint D>
414 m_index = idxVectorToLinear<T, D>( idx, m_sizes );
415}
416
417template <typename T, uint D>
419 return m_index;
420}
421
422template <typename T, uint D>
424 return linearToIdxVector<T, D>( m_index, m_sizes );
425}
426
427template <typename T, uint D>
428inline bool Grid<T, D>::Iterator::isOut() const {
429 return !isIn();
430}
431
432template <typename T, uint D>
433inline bool Grid<T, D>::Iterator::isIn() const {
434 return m_index < m_sizes.prod();
435}
436
437//
438// Iterator increment and decrement
439//
440
441template <typename T, uint D>
443 m_index++;
444 return *this;
445}
446
447template <typename T, uint D>
449 m_index--;
450 return *this;
451}
452
453template <typename T, uint D>
455 Iterator copy( *this );
456 ++( *this );
457 return copy;
458}
459
460template <typename T, uint D>
462 Iterator copy( *this );
463 --( *this );
464 return copy;
465}
466
467template <typename T, uint D>
469 m_index += i;
470 return *this;
471}
472
473template <typename T, uint D>
475 m_index -= i;
476 return *this;
477}
478
479template <typename T, uint D>
480typename Grid<T, D>::Iterator&
482 CORE_ASSERT( isValidOffset( idx.template cast<int>() ), "Invalid offset vector." );
483 setFromVector( getVector() + idx );
484 return *this;
485}
486
487template <typename T, uint D>
488typename Grid<T, D>::Iterator&
490 CORE_ASSERT( isValidOffset( -( idx.template cast<int>() ) ), "Invalid offset vector." );
491 setFromVector( getVector() - idx );
492 return *this;
493}
494
495template <typename T, uint D>
496typename Grid<T, D>::Iterator&
498 CORE_ASSERT( isValidOffset( idx ), "Invalid offset vector" );
499 setFromVector( ( getVector().template cast<int>() + idx ).template cast<uint>() );
500 return *this;
501}
502
503template <typename T, uint D>
504bool Grid<T, D>::Iterator::operator==( const typename Grid<T, D>::Iterator& other ) const {
505 CORE_ASSERT( m_sizes == other.m_sizes, "Comparing unrelated grid iterators" );
506 return m_index == other.m_index;
507}
508
509template <typename T, uint D>
510bool Grid<T, D>::Iterator::operator<( const typename Grid<T, D>::Iterator& other ) const {
511 CORE_ASSERT( m_sizes == other.m_sizes, "Comparing unrelated grid iterators" );
512 return m_index < other.m_index;
513}
514
515template <typename T, uint D>
517 return m_sizes;
518}
519
520template <typename T, uint D>
521template <typename T2>
523 return typename Grid<T2, D>::Iterator( m_sizes, m_index );
524}
525
526template <typename T, uint D>
528 OffsetVector pos = getVector().template cast<int>() + idx;
529 return !( ( pos.array() < 0 ).any() ||
530 ( pos.array() >= m_sizes.template cast<int>().array() ).any() );
531}
532
533} // namespace Core
534} // namespace Ra
A vector of signed offsets.
Definition Grid.hpp:30
IdxVector getVector() const
Get the current vector index.
Definition Grid.hpp:423
Iterator & operator++()
Advance the iterator to the next-element.
Definition Grid.hpp:442
void setFromLinear(uint idx)
Set an existing iterator to a linear index value.
Definition Grid.hpp:408
bool isOut() const
Returns true if the current index is out of the grid.
Definition Grid.hpp:428
void setFromVector(const IdxVector &idx)
Set an existing iterator to a vector index value.
Definition Grid.hpp:413
const IdxVector & getGridSize() const
Get the associated grid size.
Definition Grid.hpp:516
bool isValidOffset(const OffsetVector &idx)
Definition Grid.hpp:527
Iterator(const Iterator &other)=default
Default copy constructor and assignment operator.
Grid< T2, D >::Iterator cast() const
Cast to the an iterator in a different type grid.
Definition Grid.hpp:522
Iterator & operator-=(uint i)
Rewind the iterator with an offset of i elements.
Definition Grid.hpp:474
Iterator & operator+=(uint i)
Advance the iterator with an offset of i elements.
Definition Grid.hpp:468
Iterator(const IdxVector &size, const IdxVector &startIdx)
Constructor from size and vector index.
Iterator(const IdxVector &size, uint startIdx=0)
Constructor from size and linear index.
bool isIn() const
Returns true if the current index is inside the grid.
Definition Grid.hpp:433
Iterator & operator--()
Move the iterator back to the previous element.
Definition Grid.hpp:448
Iterator(const Grid< T, D > &grid, const IdxVector &startIdx)
Constructor from grid and vector index.
uint getLinear() const
Get the current linear index.
Definition Grid.hpp:418
Iterator begin()
Get an iterator on this grid at the first element.
Definition Grid.hpp:354
IdxVector m_size
Indicate the extends of the grid along each dimension.
Definition Grid.hpp:234
const T & at(uint idx) const
Access an element with a linear index.
Definition Grid.hpp:326
Grid(const Grid< T, D > &other)=default
Copy constructor and assignment operator.
Grid(const IdxVector &size, const T *values)
Construct a grid of a given size with values in ()-major format.
Definition Grid.hpp:176
T * data()
Read-write access to the underlying data.
Definition Grid.hpp:303
Grid(const IdxVector &size=IdxVector::Zero(), const T &val=T())
Construct a grid of a given size and fill it with the given value.
Definition Grid.hpp:172
void clear()
Erases all data and makes the grid empty.
Definition Grid.hpp:291
Eigen::Matrix< uint, D, 1 > IdxVector
Dimension of our grid.
Definition Grid.hpp:23
const IdxVector & sizeVector() const
Returns the size vector (a D-dimensional vector with the size along each dimension).
Definition Grid.hpp:279
const T & at(const IdxVector &idx) const
Access an element with a D-dimensional index.
const T & at(const Iterator &it) const
Access an element with an iterator.
const T * data() const
Read only access to the underlying data.
Definition Grid.hpp:298
Eigen::Matrix< int, D, 1 > OffsetVector
A vector of the size of the grid along each dimension.
Definition Grid.hpp:25
bool empty() const
Returns true if the grid is empty (i.e. if size() ==0).
Definition Grid.hpp:285
std::vector< T > m_data
Storage for the grid data.
Definition Grid.hpp:236
uint size() const
Returns the number of elements stored.
Definition Grid.hpp:273
Iterator end()
Get an iterator on this grid past the last element.
Definition Grid.hpp:364
hepler function to manage enum as underlying types in VariableSet
Definition Cage.cpp:3