aimsdata  5.1.2
Neuroimaging data handling
borderiterator.h
Go to the documentation of this file.
1 #ifndef AIMSDATA_BORDER_BORDERITERATOR_H
2 #define AIMSDATA_BORDER_BORDERITERATOR_H
3 
4 
5 #include <aims/vector/vector.h> // Point*
6 #include <cartodata/volume/volume.h> // VolumeRef
7 #include <iostream>
8 
9 namespace aims
10 {
11  //==========================================================================
12  // BORDER ITERATOR
13  //==========================================================================
24  template <typename T>
26  {
27  public:
49  BorderIterator( carto::VolumeRef<T> in, bool inside = false,
50  const Point4dl & size = Point4dl( -1, -1, -1, -1 ) ):
51  _volume(in),
52  _inside(inside),
53  _sizeinf(size),
54  _sizesup(size)
55  {
56  if( !inside )
57  {
58  std::vector<int> borders = _volume.getBorders();
59  if( size[0] < 0 )
60  {
61  _sizeinf[0] = borders[0];
62  _sizesup[0] = borders[1];
63  }
64  if( size[1] < 0 )
65  {
66  _sizeinf[1] = borders[2];
67  _sizesup[1] = borders[3];
68  }
69  if( size[2] < 0 )
70  {
71  _sizeinf[2] = borders[4];
72  _sizesup[2] = borders[5];
73  }
74  if( size[3] < 0 )
75  {
76  _sizeinf[3] = borders[6];
77  _sizesup[3] = borders[7];
78  }
79  }
80  }
82  const Point4dl & sizeinf,
83  const Point4dl & sizesup ):
84  _volume(in),
85  _inside(inside),
86  _sizeinf(sizeinf),
87  _sizesup(sizesup)
88  {
89  if( !inside )
90  {
91  std::vector<int> borders = _volume.getBorders();
92  if( _sizeinf[0] < 0 )
93  _sizeinf[0] = borders[0];
94  if( _sizesup[0] < 0 )
95  _sizesup[0] = borders[1];
96 
97  if( _sizeinf[1] < 0 )
98  _sizeinf[1] = borders[2];
99  if( _sizesup[1] < 0 )
100  _sizesup[1] = borders[3];
101 
102  if( _sizeinf[2] < 0 )
103  _sizeinf[2] = borders[4];
104  if( _sizesup[1] < 0 )
105  _sizesup[2] = borders[5];
106 
107  if( _sizeinf[3] < 0 )
108  _sizeinf[3] = borders[6];
109  if( _sizesup[1] < 0 )
110  _sizesup[3] = borders[7];
111  }
112  }
113 
115  _volume( (carto::Volume<T>*)0 ),
116  _inside(false),
117  _sizeinf(),
118  _sizesup()
119  {}
120 
121  public:
122  class iterator;
123 
126  {
127  //--- constructors -----------------------------------------------------
128  public:
132  const_iterator();
134  const_iterator( const const_iterator & other );
136  const_iterator( const iterator & other );
137  protected:
140  const_iterator( BorderIterator<T> & b, bool end = false );
142  const_iterator( BorderIterator<T> & b, const Point4dl & current );
143 
144  //--- operators --------------------------------------------------------
145  public:
149  const_iterator & operator=( const iterator & other );
154  const T & operator*() const;
155  const T * operator->() const;
156  bool operator==( const const_iterator & other ) const;
157  bool operator==( const iterator & other ) const;
158  bool operator!=( const const_iterator & other ) const;
159  bool operator!=( const iterator & other ) const;
160 
161  //--- member method ----------------------------------------------------
163  Point4dl coordinate() const { return _current; }
165  carto::VolumeRef<T> volume() { return _border._volume; }
166 
167  //--- members ----------------------------------------------------------
168  protected:
171 
172  //--- helpers ----------------------------------------------------------
173  protected:
175  bool isBorder( const Point4dl & p ) const;
177  bool isNonBorderImage( const Point4dl & p ) const;
180  Point4dl reset( const Point4dl & p,
181  const Point4dl & move ) const;
185  Point4dl nextMove( const Point4dl & move ) const;
191  Point4dl computeNext( const Point4dl & p ) const;
195  Point4dl end() const;
198  long jumpX() const;
199 
200  //--- friends ----------------------------------------------------------
201  friend class BorderIterator<T>;
202  friend class iterator;
203  };
204 
206  class iterator: public const_iterator
207  {
208  //--- constructors -----------------------------------------------------
209  public:
213  iterator();
215  iterator( const iterator & other );
216  protected:
219  iterator( BorderIterator<T> & b, bool end = false );
221  iterator( BorderIterator<T> & b, const Point4dl & current );
222 
223  //--- operators --------------------------------------------------------
224  public:
226  iterator & operator=( const iterator & other );
228  iterator & operator++();
229  iterator operator++(int);
230  T & operator*();
231  T * operator->();
232 
233  //--- friends ----------------------------------------------------------
234  friend class BorderIterator<T>;
235  };
236 
237  public:
238  iterator begin() { return iterator(*this); }
239  iterator end() { return iterator(*this,true); }
240  const_iterator begin() const { return const_iterator(*this); }
241  const_iterator end() const { return const_iterator(*this,true); }
242 
243  bool operator==( const BorderIterator<T> & other ) const
244  {
245  return ( _inside == other._inside ) &&
246  ( _sizeinf == other._sizeinf ) &&
247  ( _sizesup == other._sizesup ) &&
248  ( _volume.get()== other._volume.get() );
249  }
250 
251  protected:
253  bool _inside;
256 
257  friend class const_iterator;
258  friend class iterator;
259  };
260 
261  //--- const_iterator -------------------------------------------------------
262  template <typename T>
264  _border(),
265  _current()
266  {}
267 
268  template <typename T>
270  _border(b),
271  _current( (end ? this->end() : Point4dl(0,0,0,0) ) )
272  {
273  if( !_border._inside && !end )
274  {
275  const Point4dl & start = _border._sizeinf;
276  _current = Point4dl( -start[0], -start[1], -start[2], -start[3] );
277  if( !isBorder(_current) )
279  }
280  }
281 
282  template <typename T>
284  const Point4dl & current ):
285  _border(b),
286  _current(current)
287  {}
288 
289  template <typename T>
291  const typename BorderIterator<T>::const_iterator & other ):
292  _border(other._border),
293  _current(other._current)
294  {}
295 
296  template <typename T>
298  const typename BorderIterator<T>::iterator & other ):
299  _border(other._border),
300  _current(other._current)
301  {}
302 
303  template <typename T>
305  const typename BorderIterator<T>::const_iterator & other )
306  {
307  _border = other._border;
308  _current = other._current;
309  return *this;
310  }
311 
312  template <typename T>
314  const typename BorderIterator<T>::iterator & other )
315  {
316  _border = other._border;
317  _current = other._current;
318  return *this;
319  }
320 
321  template <typename T>
323  {
324  return _border._volume( _current[0], _current[1], _current[2], _current[3] );
325  }
326 
327  template <typename T>
329  {
330  return &( _border._volume( _current[0], _current[1], _current[2], _current[3] ) );
331  }
332 
333  template <typename T>
335  {
336  return (_border == other._border) && (_current == other._current);
337  }
338 
339  template <typename T>
341  {
342  return (_border == other._border) && (_current == other._current);
343  }
344 
345  template <typename T>
347  {
348  return !(*this == other);
349  }
350 
351  template <typename T>
353  {
354  return !(*this == other);
355  }
356 
357  template <typename T>
359  {
364  }
365 
366  template <typename T>
368  {
369  if( _border._inside )
370  return _border._volume.getSizeX() - _border._sizesup[0];
371  else
372  return _border._volume.getSizeX();
373  }
374 
375  template <typename T>
377  {
378  if( _border._inside )
379  {
380  // outside allocated volume
381  if( ( p[0] < 0 ) || ( p[0] >= _border._volume.getSizeX() ) ||
382  ( p[1] < 0 ) || ( p[1] >= _border._volume.getSizeY() ) ||
383  ( p[2] < 0 ) || ( p[2] >= _border._volume.getSizeZ() ) ||
384  ( p[3] < 0 ) || ( p[3] >= _border._volume.getSizeT() ) )
385  return false;
386  // inside borders
387  else if( ( p[0] < _border._sizeinf[0] ) ||
388  ( p[0] >= _border._volume.getSizeX() - _border._sizesup[0] + 1 ) ||
389  ( p[1] < _border._sizeinf[1] ) ||
390  ( p[1] >= _border._volume.getSizeY() - _border._sizesup[1] + 1 ) ||
391  ( p[2] < _border._sizeinf[2] ) ||
392  ( p[2] >= _border._volume.getSizeZ() - _border._sizesup[2] + 1 ) ||
393  ( p[3] < _border._sizeinf[3] ) ||
394  ( p[3] >= _border._volume.getSizeT() - _border._sizesup[3] + 1 ) )
395  return true;
396  // inside non-border volume
397  else
398  return false;
399  }
400  else
401  {
402  // outside allocated volume
403  if( ( p[0] < -_border._sizeinf[0] ) ||
404  ( p[0] >= _border._volume.getSizeX() + _border._sizesup[0] ) ||
405  ( p[1] < -_border._sizeinf[1] ) ||
406  ( p[1] >= _border._volume.getSizeY() + _border._sizesup[1] ) ||
407  ( p[2] < -_border._sizeinf[2] ) ||
408  ( p[2] >= _border._volume.getSizeZ() + _border._sizesup[2] ) ||
409  ( p[3] < -_border._sizeinf[3] ) ||
410  ( p[3] >= _border._volume.getSizeT() + _border._sizesup[3] ) )
411  return false;
412  // inside border
413  else if( ( p[0] < 0 ) || ( p[0] >= _border._volume.getSizeX() ) ||
414  ( p[1] < 0 ) || ( p[1] >= _border._volume.getSizeY() ) ||
415  ( p[2] < 0 ) || ( p[2] >= _border._volume.getSizeZ() ) ||
416  ( p[3] < 0 ) || ( p[3] >= _border._volume.getSizeT() ) )
417  return true;
418  // inside non-border volume
419  else
420  return false;
421  }
422  }
423 
424  template <typename T>
426  {
427  if( _border._inside )
428  {
429  return( _border._sizeinf[0] <= p[0] && p[0] < _border._volume.getSizeX() - _border._sizesup[0] &&
430  _border._sizeinf[1] <= p[1] && p[1] < _border._volume.getSizeY() - _border._sizesup[1] &&
431  _border._sizeinf[2] <= p[2] && p[2] < _border._volume.getSizeZ() - _border._sizesup[2] &&
432  _border._sizeinf[3] <= p[3] && p[3] < _border._volume.getSizeT() - _border._sizesup[3] );
433  }
434  else
435  {
436  return( 0 <= p[0] && p[0] < _border._volume.getSizeX() &&
437  0 <= p[1] && p[1] < _border._volume.getSizeY() &&
438  0 <= p[2] && p[2] < _border._volume.getSizeZ() &&
439  0 <= p[3] && p[3] < _border._volume.getSizeT() );
440  }
441  }
442 
443  template <typename T>
445  const Point4dl & p, const Point4dl & move ) const
446  {
447  Point4dl newp = p;
448 
449  if( _border._inside )
450  {
451  if( move[0] > 0 )
452  newp[0] = 0;
453  else if( move[1] > 0 )
454  newp[1] = 0;
455  else if( move[2] > 0 )
456  newp[2] = 0;
457  else if( move[3] > 0 )
458  newp[3] = 0;
459  }
460  else
461  {
462  if( move[0] > 0 )
463  newp[0] = -_border._sizeinf[0];
464  else if( move[1] > 0 )
465  newp[1] = -_border._sizeinf[1];
466  else if( move[2] > 0 )
467  newp[2] = -_border._sizeinf[2];
468  else if( move[3] > 0 )
469  newp[3] = -_border._sizeinf[3];
470  }
471 
472  return newp;
473  }
474 
475  template <typename T>
477  const Point4dl & move ) const
478  {
479  if( move[0] > 0 )
480  return Point4dl(0,1,0,0);
481  else if( move[1] > 0 )
482  return Point4dl(0,0,1,0);
483  else if( move[2] > 0 )
484  return Point4dl(0,0,0,1);
485  else if( move[3] > 0 )
486  return Point4dl(0,0,0,0);
487 
488  // error
489  return move;
490  }
491 
492  template <typename T>
494  const Point4dl & current ) const
495  {
496  Point4dl move( 1, 0, 0, 0 );
497  Point4dl next = current + move;
498  while( !isBorder(next) && next != end() )
499  {
500  // if next is inside: jump inside image
501  if( isNonBorderImage( next ) ) {
502  next[0] = jumpX();
503  move = Point4dl( 1, 0, 0, 0 );
504  }
505  // else: reset studied dim at line begin, and change dim
506  else
507  {
508  next = reset( next, move );
509  move = nextMove( move );
510  if( move == Point4dl(0, 0, 0, 0) )
511  next = end();
512  else
513  next = next + move;
514  }
515  }
516 
517  return next;
518  }
519 
520  template <typename T>
522  {
523  _current = computeNext( _current );
524  return *this;
525  }
526 
527  template <typename T>
529  {
530  typename BorderIterator<T>::const_iterator prev = *this;
531  _current = computeNext( _current );
532  return prev;
533  }
534 
535  //--- iterator -------------------------------------------------------------
536  template <typename T>
539  {}
540 
541  template <typename T>
544  {}
545 
546  template <typename T>
548  const_iterator(b, current)
549  {}
550 
551  template <typename T>
553  const typename BorderIterator<T>::iterator & other ):
554  const_iterator(other)
555  {}
556 
557  template <typename T>
559  const typename BorderIterator<T>::iterator & other )
560  {
561  const_iterator::operator=( other );
562  return *this;
563  }
564 
565  template <typename T>
567  {
568  return const_iterator::_border._volume(
573  }
574 
575  template <typename T>
577  {
578  return &( const_iterator::_border._volume(
583  }
584 
585  template <typename T>
587  {
590  return *this;
591  }
592 
593  template <typename T>
595  {
596  typename BorderIterator<T>::iterator prev = *this;
599  return prev;
600  }
601 
602 } // namespace aims
603 
604 #endif // AIMSDATA_BORDER_BORDERITERATOR_H
bool isBorder(const Point4dl &p) const
returns true if the p is in the border described by _border
const_iterator(const const_iterator &other)
Copy constructor from a const_iterator.
Point4dl coordinate() const
Returns the coordinates of the current point in the linked volume.
bool isNonBorderImage(const Point4dl &p) const
returns true if p is in the image but not in the border.
bool operator!=(const const_iterator &other) const
Point4dl reset(const Point4dl &p, const Point4dl &move) const
Sets the coordinate (in the dimension described by move) at its most inferior (i.e.
bool operator==(const const_iterator &other) const
const_iterator()
Default constructor Create a non initialized iterator than cannot be incremented or accessed.
const_iterator(const iterator &other)
Copy constructor from an iterator.
carto::VolumeRef< T > volume()
Returns a reference to the linked volume.
long jumpX() const
Gives the size of the non-border volume in the X dimension.
Point4dl nextMove(const Point4dl &move) const
Computes the next move.
const_iterator & operator++()
increment (prefix)
Point4dl computeNext(const Point4dl &p) const
computeNext(p) returns the next point in the border.
const_iterator & operator=(const iterator &other)
assignment from iterator
const_iterator & operator=(const const_iterator &other)
assignment from const_iterator
Point4dl end() const
Point value for the "end" iterator (which points to no voxel).
iterator(const iterator &other)
Copy constructor from an iterator.
iterator()
Default constructor Create a non initialized iterator than cannot be incremented or accessed.
iterator & operator++()
increment (prefix)
iterator & operator=(const iterator &other)
assignment from iterator
Represents the border of a volume.
bool operator==(const BorderIterator< T > &other) const
const_iterator end() const
carto::VolumeRef< T > _volume
BorderIterator(carto::VolumeRef< T > in, bool inside, const Point4dl &sizeinf, const Point4dl &sizesup)
friend class const_iterator
const_iterator begin() const
BorderIterator(carto::VolumeRef< T > in, bool inside=false, const Point4dl &size=Point4dl(-1, -1, -1, -1))
Border constructor.
std::vector< int > getBorders() const
T * get() const
The class for EcatSino data write operation.
Definition: borderfiller.h:13