OpenWalnut  1.4.0
WGridRegular3D.h
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #ifndef WGRIDREGULAR3D_H
26 #define WGRIDREGULAR3D_H
27 
28 #include <cmath>
29 #include <string>
30 #include <utility>
31 #include <vector>
32 
33 #include <boost/array.hpp>
34 #include <boost/shared_ptr.hpp>
35 
36 #include <osg/Matrix>
37 #include <osg/Vec3>
38 
39 #include "../common/exceptions/WOutOfBounds.h"
40 #include "../common/exceptions/WPreconditionNotMet.h"
41 #include "../common/math/WLinearAlgebraFunctions.h"
42 #include "../common/math/WMatrix.h"
43 #include "../common/WBoundingBox.h"
44 #include "../common/WCondition.h"
45 #include "../common/WDefines.h"
46 #include "../common/WProperties.h"
47 
48 #include "WGrid.h"
49 #include "WGridTransformOrtho.h"
50 
51 /**
52  * A grid that has parallelepiped cells which all have the same proportion. I.e.
53  * the samples along a single axis are equidistant. The distance of samples may
54  * vary between axes.
55  *
56  * \warning Positions on the upper bounddaries in x, y and z are considered outside the grid.
57  * \ingroup dataHandler
58  */
59 template< typename T >
60 class WGridRegular3DTemplate : public WGrid // NOLINT
61 {
62  // this (friend) is necessary to allow casting
63  template <class U>
64  friend class WGridRegular3DTemplate;
65  /**
66  * Only test are allowed as friends.
67  */
68  friend class WGridRegular3DTest;
69 public:
70  /**
71  * Convenience typedef for 3d vectors of the appropriate numerical type.
72  */
74 
75  /**
76  * Convenience typedef for a boost::shared_ptr< WGridRegular3DTemplate >.
77  */
78  typedef boost::shared_ptr< WGridRegular3DTemplate > SPtr;
79 
80  /**
81  * Convenience typedef for a boost::shared_ptr< const WGridRegular3DTemplate >.
82  */
83  typedef boost::shared_ptr< const WGridRegular3DTemplate > ConstSPtr;
84 
85  /**
86  * Convenience typedef for a boost::array< size_t, 8 >. Return type of getCellVertexIds.
87  */
88  typedef boost::array< size_t, 8 > CellVertexArray;
89 
90  /**
91  * Copy constructor.
92  * Copies the data from an WGridRegular3DTemplate object with arbitary numerical type.
93  *
94  * \param rhs A WGridRegular3DTemplate object, which mustn't have the same numerical type.
95  */
96  template< typename InputType >
97  WGridRegular3DTemplate( WGridRegular3DTemplate< InputType > const& rhs ); // NOLINT -- no explicit, this allows casts
98 
99  /**
100  * Defines the number of samples in each coordinate direction as ints,
101  * and the transformation of the grid via a grid transform.
102  *
103  * \param nbPosX number of positions along first axis
104  * \param nbPosY number of positions along second axis
105  * \param nbPosZ number of positions along third axis
106  * \param transform a grid transformation
107  */
108  WGridRegular3DTemplate( unsigned int nbPosX, unsigned int nbPosY, unsigned int nbPosZ,
110 
111  /**
112  * Defines the number of samples in each coordinate direction as ints,
113  * and the transformation of the grid via a grid transform.
114  *
115  * \param nbPosX number of positions along first axis
116  * \param nbPosY number of positions along second axis
117  * \param nbPosZ number of positions along third axis
118  * \param scaleX scaling of a voxel in x direction
119  * \param scaleY scaling of a voxel in y direction
120  * \param scaleZ scaling of a voxel in z direction
121  */
122  WGridRegular3DTemplate( unsigned int nbPosX, unsigned int nbPosY, unsigned int nbPosZ,
123  double scaleX, double scaleY, double scaleZ );
124 
125  /**
126  * Returns the number of samples in x direction.
127  * \return The number of samples in x direction.
128  */
129  unsigned int getNbCoordsX() const;
130 
131  /**
132  * Returns the number of samples in y direction.
133  * \return The number of samples in y direction.
134  */
135  unsigned int getNbCoordsY() const;
136 
137  /**
138  * Returns the number of samples in z direction.
139  * \return The number of samples in z direction.
140  */
141  unsigned int getNbCoordsZ() const;
142 
143  /**
144  * Returns the distance between samples in x direction.
145  * \return The distance between samples in x direction.
146  */
147  T getOffsetX() const;
148 
149  /**
150  * Returns the distance between samples in y direction.
151  * \return The distance between samples in y direction.
152  */
153  T getOffsetY() const;
154 
155  /**
156  * Returns the distance between samples in z direction.
157  * \return The distance between samples in z direction.
158  */
159  T getOffsetZ() const;
160 
161  /**
162  * Returns the vector determining the direction of samples in x direction.
163  * Adding this vector to a grid position in world coordinates yields the position of the next sample
164  * along the grids (world coordinate) x-axis.
165  * \return The vector determining the direction of samples in x direction.
166  */
167  Vector3Type getDirectionX() const;
168 
169  /**
170  * Returns the vector determining the direction of samples in y direction.
171  * Adding this vector to a grid position in world coordinates yields the position of the next sample
172  * along the grids (world coordinate) y-axis.
173  * \return The vector determining the direction of samples in y direction.
174  */
175  Vector3Type getDirectionY() const;
176 
177  /**
178  * Returns the vector determining the direction of samples in z direction.
179  * Adding this vector to a grid position in world coordinates yields the position of the next sample
180  * along the grids (world coordinate) z-axis.
181  * \return The vector determining the direction of samples in z direction.
182  */
183  Vector3Type getDirectionZ() const;
184 
185  /**
186  * Returns the vector determining the unit (normalized) direction of samples in x direction.
187  * \return The vector determining the unit (normalized) direction of samples in x direction.
188  */
190 
191  /**
192  * Returns the vector determining the unit (normalized) direction of samples in y direction.
193  * \return The vector determining the unit (normalized) direction of samples in y direction.
194  */
196 
197  /**
198  * Returns the vector determining the unit (normalized) direction of samples in z direction.
199  * \return The vector determining the unit (normalized) direction of samples in z direction.
200  */
202 
203  /**
204  * Returns the position of the origin of the grid.
205  * \return The position of the origin of the grid.
206  */
207  Vector3Type getOrigin() const;
208 
209  /**
210  * Returns a 4x4 matrix that represents the grid's transformation.
211  * \return The grid's transformation.
212  */
214 
215  /**
216  * \copybrief WGrid::getBoundingBox()
217  * \return \copybrief WGrid::getBoundingBox()
218  */
220 
221  /**
222  * Calculates the bounding box but includes the border voxel associated cell too.
223  *
224  * \return the bounding box
225  */
227 
228  /**
229  * Calculate the bounding box in voxel space. In contrast to the cell bounding box, this includes the space of the last voxel in each
230  * direction.
231  *
232  * \return the voxel space bounding box.
233  */
235 
236  /**
237  * Returns the i-th position on the grid.
238  * \param i id of position to be obtained
239  * \return i-th position of the grid.
240  */
241  Vector3Type getPosition( unsigned int i ) const;
242 
243  /**
244  * Returns the position that is the iX-th in x direction, the iY-th in
245  * y direction and the iZ-th in z direction.
246  * \param iX id along first axis of position to be obtained
247  * \param iY id along second axis of position to be obtained
248  * \param iZ id along third axis of position to be obtained
249  * \return Position (iX,iY,iZ)
250  */
251  Vector3Type getPosition( unsigned int iX, unsigned int iY, unsigned int iZ ) const;
252 
253  /**
254  * Transforms world coordinates to texture coordinates.
255  * \param point The point with these coordinates will be transformed.
256  * \return point transformed into texture coordinate system
257  */
259 
260  /**
261  * Returns the i'th voxel where the given position belongs too.
262  *
263  * A voxel is a cuboid which surrounds a point on the grid.
264  *
265  * \verbatim
266  Voxel:
267  ______________ ____ (0.5, 0.5, 0.5)
268  /: /|
269  / : / |
270  / : / |
271  / : / |
272  _/____:_ ___ __/ |
273  | : | |
274  | : *<--|--------- grid point (0, 0, 0)
275  | :........|....|__
276  dz == 1| / | /
277  | / | / dy == 1
278  | / | /
279  _|/____________|/__
280  |<- dx == 1 ->|
281  -0.5,-0.5,-0.5
282  \endverbatim
283  *
284  * Please note the first voxel has only 1/8 of the size a normal voxel
285  * would have since all positions outside the grid do not belong
286  * to any voxel. Note: a cell is different to a voxel in terms of position.
287  * A voxel has a grid point as center whereas a cell has grid points as
288  * corners.
289  * \param pos Position for which we want to have the voxel number.
290  *
291  * \return Voxel number or -1 if the position refers to a point outside of
292  * the grid.
293  */
294  int getVoxelNum( const Vector3Type& pos ) const;
295 
296  /**
297  * returns the voxel index for a given discrete position in the grid
298  *
299  * \param x Position for which we want to have the voxel number.
300  * \param y Position for which we want to have the voxel number.
301  * \param z Position for which we want to have the voxel number.
302  *
303  * \return Voxel number or -1 if the position refers to a point outside of
304  * the grid.
305  */
306  int getVoxelNum( const size_t x, const size_t y, const size_t z ) const;
307 
308  /**
309  * Computes the X coordinate of that voxel that contains the
310  * position pos.
311  *
312  * \param pos The position which selects the voxel for which the X
313  * coordinate is computed.
314  *
315  * \return The X coordinate or -1 if pos refers to point outside of the
316  * grid.
317  */
318  int getXVoxelCoord( const Vector3Type& pos ) const;
319 
320  /**
321  * Computes the Y coordinate of that voxel that contains the
322  * position pos.
323  *
324  * \param pos The position which selects the voxel for which the Y
325  * coordinate is computed.
326  *
327  * \return The Y coordinate or -1 if pos refers to point outside of the
328  * grid.
329  */
330  int getYVoxelCoord( const Vector3Type& pos ) const;
331 
332  /**
333  * Computes the Z coordinate of that voxel that contains the
334  * position pos.
335  *
336  * \param pos The position which selects the voxel for which the Z
337  * coordinate is computed.
338  *
339  * \return The Z coordinate or -1 if pos refers to point outside of the
340  * grid.
341  */
342  int getZVoxelCoord( const Vector3Type& pos ) const;
343 
344  /**
345  * Computes the voxel coordinates of that voxel which contains
346  * the position pos.
347  *
348  * \param pos The position selecting the voxel.
349  *
350  * \return A vector of ints where the first component is the X voxel
351  * coordinate, the second the Y component voxel coordinate and the last the
352  * Z component of the voxel coordinate. If the selecting position is
353  * outside of the grid then -1 -1 -1 is returned.
354  */
355  WVector3i getVoxelCoord( const Vector3Type& pos ) const;
356 
357  /**
358  * Computes the id of the cell containing the position pos. Note that the upper
359  * bound of the grid does not belong to any cell
360  *
361  * \param pos The position selecting the cell.
362  * \param success True if the position pos is inside the grid.
363  *
364  * \return id of the containing the position.
365  */
366  size_t getCellId( const Vector3Type& pos, bool* success ) const;
367 
368  /**
369  * Computes the ids of the vertices of a cell given by its id.
370  *
371  * \param cellId The id of the cell we want to know ther vertices of.
372  *
373  * \return Ids of vertices belonging to cell with given cellId.
374 
375  * \verbatim
376  z-axis y-axis
377  | /
378  | 6___/_7
379  |/: /|
380  4_:___5 |
381  | :...|.|
382  |.2 | 3
383  |_____|/ ____x-axis
384  0 1
385  \endverbatim
386  *
387  */
388  CellVertexArray getCellVertexIds( size_t cellId ) const;
389 
390  /**
391  * Computes the vertices for a voxel cuboid around the given point:
392  *
393  * \verbatim
394  z-axis y-axis
395  | /
396  | h___/_g
397  |/: /|
398  d_:___c |
399  | :...|.|
400  |.e | f
401  |_____|/ ____x-axis
402  a b
403  \endverbatim
404  *
405  * As you can see the order of the points is: a, b, c, d, e, f, g, h.
406  *
407  * \param point Center of the cuboid which must not necesarrily be a point
408  * of the grid.
409  * \param margin If you need to shrink the Voxel put here the delta > 0.
410  *
411  * \return Reference to a list of vertices which are the corner points of
412  * the cube. Note this must not be a voxel, but has the same size of the an
413  * voxel. If you need voxels at grid positions fill this function with
414  * voxel center positions aka grid points.
415  */
416  boost::shared_ptr< std::vector< Vector3Type > > getVoxelVertices( const Vector3Type& point,
417  const T margin = 0.0 ) const;
418 
419  /**
420  * Return the list of neighbour voxels.
421  *
422  * \throw WOutOfBounds If the voxel id is outside of the grid.
423  *
424  * \param id Number of the voxel for which the neighbours should be computed
425  *
426  * \return Vector of voxel ids which are all neighboured
427  */
428  std::vector< size_t > getNeighbours( size_t id ) const;
429 
430  /**
431  * Return the list of all neighbour voxels.
432  *
433  * \throw WOutOfBounds If the voxel id is outside of the grid.
434  *
435  * \param id Number of the voxel for which the neighbours should be computed
436  *
437  * \return Vector of voxel ids which are all neighboured
438  */
439  std::vector< size_t > getNeighbours27( size_t id ) const;
440 
441  /**
442  * Return the list of all neighbour voxels.
443  *
444  * \throw WOutOfBounds If the voxel id is outside of the grid.
445  *
446  * \param id Number of the voxel for which the neighbours should be computed
447  *
448  * \param range neighborhood range selected. It specifies the distance to count as neighbour in each direction.
449  *
450  * \return Vector of voxel ids which are all neighboured
451  */
452  std::vector< size_t > getNeighboursRange( size_t id, size_t range ) const;
453 
454  /**
455  * Return the list of all neighbour voxels.
456  *
457  * \throw WOutOfBounds If the voxel id is outside of the grid.
458  *
459  * \param id Number of the voxel for which the neighbours should be computed
460  *
461  * \return Vector of voxel ids which are all neighboured along the XY plane
462  */
463  std::vector< size_t > getNeighbours9XY( size_t id ) const;
464 
465  /**
466  * Return the list of all neighbour voxels.
467  *
468  * \throw WOutOfBounds If the voxel id is outside of the grid.
469  *
470  * \param id Number of the voxel for which the neighbours should be computed
471  *
472  * \return Vector of voxel ids which are all neighboured along the YZ plane
473  */
474  std::vector< size_t > getNeighbours9YZ( size_t id ) const;
475 
476  /**
477  * Return the list of all neighbour voxels.
478  *
479  * \throw WOutOfBounds If the voxel id is outside of the grid.
480  *
481  * \param id Number of the voxel for which the neighbours should be computed
482  *
483  * \return Vector of voxel ids which are all neighboured along the XZ plane
484  */
485  std::vector< size_t > getNeighbours9XZ( size_t id ) const;
486 
487  /**
488  * Decides whether a certain position is inside this grid or not.
489  *
490  * \param pos Position to test
491  *
492  * \return True if and only if the given point is inside or on boundary of this grid, otherwise false.
493  */
494  bool encloses( const Vector3Type& pos ) const;
495 
496  /**
497  * Return whether the transformations of the grid are only translation and/or scaling
498  * \return Transformation does not contain rotation?
499  */
500  bool isNotRotated() const;
501 
502  /**
503  * Returns the transformation used by this grid.
504  * \return The transformation.
505  */
507 
508  /**
509  * Compares two grids. Matches the transform and x,y,z resolution.
510  *
511  * \param other the one to compare against
512  *
513  * \return true if transform and resolution matches
514  */
515  bool operator==( const WGridRegular3DTemplate< T >& other ) const;
516 
517 protected:
518 private:
519  /**
520  * Computes for the n'th component of the voxel coordinate where the voxel
521  * contains the position pos.
522  *
523  * \param pos The position for which the n'th component of the voxel
524  * coordinates should be computed.
525  * \param axis The number of the component. (0 == x-axis, 1 == y-axis, ...)
526  *
527  * \return The n'th component of the voxel coordinate
528  */
529  int getNVoxelCoord( const Vector3Type& pos, size_t axis ) const;
530 
531  /**
532  * Adds the specific information of this grid type to the
533  * informational properties.
534  */
536 
537  unsigned int m_nbPosX; //!< Number of positions in x direction
538  unsigned int m_nbPosY; //!< Number of positions in y direction
539  unsigned int m_nbPosZ; //!< Number of positions in z direction
540 
541  //! The grid's transformation.
543 };
544 
545 // Convenience typedefs
549 
550 template< typename T >
551 template< typename InputType >
553  WGrid( rhs.m_nbPosX * rhs.m_nbPosY * rhs.m_nbPosZ ),
554  m_nbPosX( rhs.m_nbPosX ),
555  m_nbPosY( rhs.m_nbPosY ),
556  m_nbPosZ( rhs.m_nbPosZ ),
557  m_transform( rhs.m_transform )
558 {
560 }
561 
562 template< typename T >
563 WGridRegular3DTemplate< T >::WGridRegular3DTemplate( unsigned int nbPosX, unsigned int nbPosY, unsigned int nbPosZ,
564  WGridTransformOrthoTemplate< T > const transform )
565  : WGrid( nbPosX * nbPosY * nbPosZ ),
566  m_nbPosX( nbPosX ),
567  m_nbPosY( nbPosY ),
568  m_nbPosZ( nbPosZ ),
569  m_transform( transform )
570 {
572 }
573 
574 template< typename T >
575 WGridRegular3DTemplate< T >::WGridRegular3DTemplate( unsigned int nbPosX, unsigned int nbPosY, unsigned int nbPosZ,
576  double scaleX, double scaleY, double scaleZ ):
577  WGrid( nbPosX * nbPosY * nbPosZ ),
578  m_nbPosX( nbPosX ),
579  m_nbPosY( nbPosY ),
580  m_nbPosZ( nbPosZ ),
581  m_transform( WGridTransformOrthoTemplate< T >( scaleX, scaleY, scaleZ ) )
582 {
584 }
585 
586 template< typename T >
587 inline unsigned int WGridRegular3DTemplate< T >::getNbCoordsX() const
588 {
589  return m_nbPosX;
590 }
591 
592 template< typename T >
593 inline unsigned int WGridRegular3DTemplate< T >::getNbCoordsY() const
594 {
595  return m_nbPosY;
596 }
597 
598 template< typename T >
599 inline unsigned int WGridRegular3DTemplate< T >::getNbCoordsZ() const
600 {
601  return m_nbPosZ;
602 }
603 
604 template< typename T >
606 {
607  return m_transform.getOffsetX();
608 }
609 
610 template< typename T >
612 {
613  return m_transform.getOffsetY();
614 }
615 
616 template< typename T >
618 {
619  return m_transform.getOffsetZ();
620 }
621 
622 template< typename T >
624 {
625  return m_transform.getDirectionX();
626 }
627 
628 template< typename T >
630 {
631  return m_transform.getDirectionY();
632 }
633 
634 template< typename T >
636 {
637  return m_transform.getDirectionZ();
638 }
639 
640 template< typename T >
642 {
643  return m_transform.getUnitDirectionX();
644 }
645 
646 template< typename T >
648 {
649  return m_transform.getUnitDirectionY();
650 }
651 
652 template< typename T >
654 {
655  return m_transform.getUnitDirectionZ();
656 }
657 
658 template< typename T >
660 {
661  return m_transform.getOrigin();
662 }
663 
664 template< typename T >
666 {
667  return m_transform.getTransformationMatrix();
668 }
669 
670 template< typename T >
672 {
673  WBoundingBox result;
674  result.expandBy( m_transform.positionToWorldSpace( Vector3Type( 0.0, 0.0, 0.0 ) ) );
675  result.expandBy( m_transform.positionToWorldSpace( Vector3Type( getNbCoordsX() - 1, 0.0, 0.0 ) ) );
676  result.expandBy( m_transform.positionToWorldSpace( Vector3Type( 0.0, getNbCoordsY() - 1, 0.0 ) ) );
677  result.expandBy( m_transform.positionToWorldSpace( Vector3Type( getNbCoordsX() - 1, getNbCoordsY() - 1, 0.0 ) ) );
678  result.expandBy( m_transform.positionToWorldSpace( Vector3Type( 0.0, 0.0, getNbCoordsZ() - 1 ) ) );
679  result.expandBy( m_transform.positionToWorldSpace( Vector3Type( getNbCoordsX() - 1, 0.0, getNbCoordsZ() - 1 ) ) );
680  result.expandBy( m_transform.positionToWorldSpace( Vector3Type( 0.0, getNbCoordsY() - 1, getNbCoordsZ() - 1 ) ) );
681  result.expandBy( m_transform.positionToWorldSpace( Vector3Type( getNbCoordsX() - 1, getNbCoordsY() - 1, getNbCoordsZ() - 1 ) ) );
682  return result;
683 }
684 
685 template< typename T >
687 {
688  WBoundingBox result;
689  result.expandBy( m_transform.positionToWorldSpace( Vector3Type( 0.0, 0.0, 0.0 ) ) );
690  result.expandBy( m_transform.positionToWorldSpace( Vector3Type( getNbCoordsX(), 0.0, 0.0 ) ) );
691  result.expandBy( m_transform.positionToWorldSpace( Vector3Type( 0.0, getNbCoordsY(), 0.0 ) ) );
692  result.expandBy( m_transform.positionToWorldSpace( Vector3Type( getNbCoordsX(), getNbCoordsY(), 0.0 ) ) );
693  result.expandBy( m_transform.positionToWorldSpace( Vector3Type( 0.0, 0.0, getNbCoordsZ() ) ) );
694  result.expandBy( m_transform.positionToWorldSpace( Vector3Type( getNbCoordsX(), 0.0, getNbCoordsZ() ) ) );
695  result.expandBy( m_transform.positionToWorldSpace( Vector3Type( 0.0, getNbCoordsY(), getNbCoordsZ() ) ) );
696  result.expandBy( m_transform.positionToWorldSpace( Vector3Type( getNbCoordsX(), getNbCoordsY(), getNbCoordsZ() ) ) );
697  return result;
698 }
699 
700 template< typename T >
702 {
703  WBoundingBox result;
704  result.expandBy( m_transform.positionToWorldSpace( Vector3Type( -0.5, -0.5, -0.5 ) ) );
705  result.expandBy( m_transform.positionToWorldSpace( Vector3Type( getNbCoordsX() - 0.5, -0.5, -0.5 ) ) );
706  result.expandBy( m_transform.positionToWorldSpace( Vector3Type( -0.5, getNbCoordsY() - 0.5, -0.5 ) ) );
707  result.expandBy( m_transform.positionToWorldSpace( Vector3Type( getNbCoordsX() - 0.5, getNbCoordsY() - 0.5, -0.5 ) ) );
708  result.expandBy( m_transform.positionToWorldSpace( Vector3Type( -0.5, -0.5, getNbCoordsZ() - 0.5 ) ) );
709  result.expandBy( m_transform.positionToWorldSpace( Vector3Type( getNbCoordsX() - 0.5, -0.5, getNbCoordsZ() - 0.5 ) ) );
710  result.expandBy( m_transform.positionToWorldSpace( Vector3Type( -0.5, getNbCoordsY() - 0.5, getNbCoordsZ() - 0.5 ) ) );
711  result.expandBy( m_transform.positionToWorldSpace( Vector3Type( getNbCoordsX() - 0.5, getNbCoordsY() - 0.5, getNbCoordsZ() - 0.5 ) ) );
712  return result;
713 }
714 
715 template< typename T >
717 {
718  return getPosition( i % m_nbPosX, ( i / m_nbPosX ) % m_nbPosY, i / ( m_nbPosX * m_nbPosY ) );
719 }
720 
721 template< typename T >
723  unsigned int iY,
724  unsigned int iZ ) const
725 {
726  Vector3Type i( iX, iY, iZ );
727  return m_transform.positionToWorldSpace( i );
728 }
729 
730 template< typename T >
732 {
733  Vector3Type r( m_transform.positionToGridSpace( point ) );
734 
735  // Scale to [0,1]
736  r[0] = r[0] / m_nbPosX;
737  r[1] = r[1] / m_nbPosY;
738  r[2] = r[2] / m_nbPosZ;
739 
740  // Correct the coordinates to have the position at the center of the texture voxel.
741  r[0] += 0.5 / m_nbPosX;
742  r[1] += 0.5 / m_nbPosY;
743  r[2] += 0.5 / m_nbPosZ;
744 
745  return r;
746 }
747 
748 template< typename T >
750 {
751  // Note: the reason for the +1 is that the first and last Voxel in a x-axis
752  // row are cut.
753  //
754  // y-axis
755  // _|_______ ___ this is the 3rd Voxel
756  // 1 | | | v
757  // |...............
758  // _|_:_|_:_|_:_|_:____ x-axis
759  // | : | : | : | :
760  // |.:...:...:...:.
761  // 0 1 2
762  int xVoxelCoord = getXVoxelCoord( pos );
763  int yVoxelCoord = getYVoxelCoord( pos );
764  int zVoxelCoord = getZVoxelCoord( pos );
765  if( xVoxelCoord == -1 || yVoxelCoord == -1 || zVoxelCoord == -1 )
766  {
767  return -1;
768  }
769  return xVoxelCoord
770  + yVoxelCoord * ( m_nbPosX )
771  + zVoxelCoord * ( m_nbPosX ) * ( m_nbPosY );
772 }
773 
774 template< typename T >
775 inline int WGridRegular3DTemplate< T >::getVoxelNum( const size_t x, const size_t y, const size_t z ) const
776 {
777  // since we use size_t here only a check for the upper bounds is needed
778  if( x > m_nbPosX || y > m_nbPosY || z > m_nbPosZ )
779  {
780  return -1;
781  }
782  return x + y * ( m_nbPosX ) + z * ( m_nbPosX ) * ( m_nbPosY );
783 }
784 
785 template< typename T >
787 {
788  // the current get*Voxel stuff is too complicated anyway
789  Vector3Type v = m_transform.positionToGridSpace( pos );
790 
791  // this part could be refactored into an inline function
792  T d;
793  v[ 2 ] = std::modf( v[ 0 ] + T( 0.5 ), &d );
794  int i = static_cast< int >( v[ 0 ] >= T( 0.0 ) && v[ 0 ] < m_nbPosX - T( 1.0 ) );
795  return -1 + i * static_cast< int >( T( 1.0 ) + d );
796 }
797 
798 template< typename T >
800 {
801  Vector3Type v = m_transform.positionToGridSpace( pos );
802 
803  T d;
804  v[ 0 ] = std::modf( v[ 1 ] + T( 0.5 ), &d );
805  int i = static_cast< int >( v[ 1 ] >= T( 0.0 ) && v[ 1 ] < m_nbPosY - T( 1.0 ) );
806  return -1 + i * static_cast< int >( T( 1.0 ) + d );
807 }
808 
809 template< typename T >
811 {
812  Vector3Type v = m_transform.positionToGridSpace( pos );
813 
814  T d;
815  v[ 0 ] = std::modf( v[ 2 ] + T( 0.5 ), &d );
816  int i = static_cast< int >( v[ 2 ] >= T( 0.0 ) && v[ 2 ] < m_nbPosZ - T( 1.0 ) );
817  return -1 + i * static_cast< int >( T( 1.0 ) + d );
818 }
819 
820 template< typename T >
822 {
823  WVector3i result;
824  result[0] = getXVoxelCoord( pos );
825  result[1] = getYVoxelCoord( pos );
826  result[2] = getZVoxelCoord( pos );
827  return result;
828 }
829 
830 template< typename T >
832 {
833  Vector3Type v = m_transform.positionToGridSpace( pos );
834 
835  T xCellId = floor( v[0] );
836  T yCellId = floor( v[1] );
837  T zCellId = floor( v[2] );
838 
839  *success = xCellId >= 0 && yCellId >=0 && zCellId >= 0 && xCellId < m_nbPosX - 1 && yCellId < m_nbPosY -1 && zCellId < m_nbPosZ -1;
840 
841  return xCellId + yCellId * ( m_nbPosX - 1 ) + zCellId * ( m_nbPosX - 1 ) * ( m_nbPosY - 1 );
842 }
843 
844 template< typename T >
846 {
848  size_t minVertexIdZ = cellId / ( ( m_nbPosX - 1 ) * ( m_nbPosY - 1 ) );
849  size_t remainderXY = cellId - minVertexIdZ * ( ( m_nbPosX - 1 ) * ( m_nbPosY - 1 ) );
850  size_t minVertexIdY = remainderXY / ( m_nbPosX - 1 );
851  size_t minVertexIdX = remainderXY % ( m_nbPosX - 1 );
852 
853  size_t minVertexId = minVertexIdX + minVertexIdY * m_nbPosX + minVertexIdZ * m_nbPosX * m_nbPosY;
854 
855  vertices[0] = minVertexId;
856  vertices[1] = vertices[0] + 1;
857  vertices[2] = minVertexId + m_nbPosX;
858  vertices[3] = vertices[2] + 1;
859  vertices[4] = minVertexId + m_nbPosX * m_nbPosY;
860  vertices[5] = vertices[4] + 1;
861  vertices[6] = vertices[4] + m_nbPosX;
862  vertices[7] = vertices[6] + 1;
863  return vertices;
864 }
865 
866 template< typename T >
867 boost::shared_ptr< std::vector< typename WGridRegular3DTemplate< T >::Vector3Type > > WGridRegular3DTemplate< T >::getVoxelVertices( const WGridRegular3DTemplate< T >::Vector3Type& point, const T margin ) const // NOLINT -- too long line
868 {
869  typedef boost::shared_ptr< std::vector< Vector3Type > > ReturnType;
870  ReturnType result = ReturnType( new std::vector< Vector3Type > );
871  result->reserve( 8 );
872  T halfMarginX = getOffsetX() / 2.0 - std::abs( margin );
873  T halfMarginY = getOffsetY() / 2.0 - std::abs( margin );
874  T halfMarginZ = getOffsetZ() / 2.0 - std::abs( margin );
875  result->push_back( Vector3Type( point[0] - halfMarginX, point[1] - halfMarginY, point[2] - halfMarginZ ) ); // a
876  result->push_back( Vector3Type( point[0] + halfMarginX, point[1] - halfMarginY, point[2] - halfMarginZ ) ); // b
877  result->push_back( Vector3Type( point[0] + halfMarginX, point[1] - halfMarginY, point[2] + halfMarginZ ) ); // c
878  result->push_back( Vector3Type( point[0] - halfMarginX, point[1] - halfMarginY, point[2] + halfMarginZ ) ); // d
879  result->push_back( Vector3Type( point[0] - halfMarginX, point[1] + halfMarginY, point[2] - halfMarginZ ) ); // e
880  result->push_back( Vector3Type( point[0] + halfMarginX, point[1] + halfMarginY, point[2] - halfMarginZ ) ); // f
881  result->push_back( Vector3Type( point[0] + halfMarginX, point[1] + halfMarginY, point[2] + halfMarginZ ) ); // g
882  result->push_back( Vector3Type( point[0] - halfMarginX, point[1] + halfMarginY, point[2] + halfMarginZ ) ); // h
883  return result;
884 }
885 
886 template< typename T >
887 std::vector< size_t > WGridRegular3DTemplate< T >::getNeighbours( size_t id ) const
888 {
889  std::vector< size_t > neighbours;
890  size_t x = id % m_nbPosX;
891  size_t y = ( id / m_nbPosX ) % m_nbPosY;
892  size_t z = id / ( m_nbPosX * m_nbPosY );
893 
894  if( x >= m_nbPosX || y >= m_nbPosY || z >= m_nbPosZ )
895  {
896  std::stringstream ss;
897  ss << "This point: " << id << " is not part of this grid: ";
898  ss << " nbPosX: " << m_nbPosX;
899  ss << " nbPosY: " << m_nbPosY;
900  ss << " nbPosZ: " << m_nbPosZ;
901  throw WOutOfBounds( ss.str() );
902  }
903  // for every neighbour we must check if its not on the boundary, it will be skipped otherwise
904  if( x > 0 )
905  {
906  neighbours.push_back( id - 1 );
907  }
908  if( x < m_nbPosX - 1 )
909  {
910  neighbours.push_back( id + 1 );
911  }
912  if( y > 0 )
913  {
914  neighbours.push_back( id - m_nbPosX );
915  }
916  if( y < m_nbPosY - 1 )
917  {
918  neighbours.push_back( id + m_nbPosX );
919  }
920  if( z > 0 )
921  {
922  neighbours.push_back( id - ( m_nbPosX * m_nbPosY ) );
923  }
924  if( z < m_nbPosZ - 1 )
925  {
926  neighbours.push_back( id + ( m_nbPosX * m_nbPosY ) );
927  }
928  return neighbours;
929 }
930 
931 template< typename T >
932 std::vector< size_t > WGridRegular3DTemplate< T >::getNeighbours27( size_t id ) const
933 {
934  std::vector< size_t > neighbours;
935  size_t x = id % m_nbPosX;
936  size_t y = ( id / m_nbPosX ) % m_nbPosY;
937  size_t z = id / ( m_nbPosX * m_nbPosY );
938 
939  if( x >= m_nbPosX || y >= m_nbPosY || z >= m_nbPosZ )
940  {
941  std::stringstream ss;
942  ss << "This point: " << id << " is not part of this grid: ";
943  ss << " nbPosX: " << m_nbPosX;
944  ss << " nbPosY: " << m_nbPosY;
945  ss << " nbPosZ: " << m_nbPosZ;
946  throw WOutOfBounds( ss.str() );
947  }
948  // for every neighbour we must check if its not on the boundary, it will be skipped otherwise
949  std::vector< int >tempResult;
950 
951  tempResult.push_back( getVoxelNum( x , y , z ) );
952  tempResult.push_back( getVoxelNum( x , y - 1, z ) );
953  tempResult.push_back( getVoxelNum( x , y + 1, z ) );
954  tempResult.push_back( getVoxelNum( x - 1, y , z ) );
955  tempResult.push_back( getVoxelNum( x - 1, y - 1, z ) );
956  tempResult.push_back( getVoxelNum( x - 1, y + 1, z ) );
957  tempResult.push_back( getVoxelNum( x + 1, y , z ) );
958  tempResult.push_back( getVoxelNum( x + 1, y - 1, z ) );
959  tempResult.push_back( getVoxelNum( x + 1, y + 1, z ) );
960 
961  tempResult.push_back( getVoxelNum( x , y , z - 1 ) );
962  tempResult.push_back( getVoxelNum( x , y - 1, z - 1 ) );
963  tempResult.push_back( getVoxelNum( x , y + 1, z - 1 ) );
964  tempResult.push_back( getVoxelNum( x - 1, y , z - 1 ) );
965  tempResult.push_back( getVoxelNum( x - 1, y - 1, z - 1 ) );
966  tempResult.push_back( getVoxelNum( x - 1, y + 1, z - 1 ) );
967  tempResult.push_back( getVoxelNum( x + 1, y , z - 1 ) );
968  tempResult.push_back( getVoxelNum( x + 1, y - 1, z - 1 ) );
969  tempResult.push_back( getVoxelNum( x + 1, y + 1, z - 1 ) );
970 
971  tempResult.push_back( getVoxelNum( x , y , z + 1 ) );
972  tempResult.push_back( getVoxelNum( x , y - 1, z + 1 ) );
973  tempResult.push_back( getVoxelNum( x , y + 1, z + 1 ) );
974  tempResult.push_back( getVoxelNum( x - 1, y , z + 1 ) );
975  tempResult.push_back( getVoxelNum( x - 1, y - 1, z + 1 ) );
976  tempResult.push_back( getVoxelNum( x - 1, y + 1, z + 1 ) );
977  tempResult.push_back( getVoxelNum( x + 1, y , z + 1 ) );
978  tempResult.push_back( getVoxelNum( x + 1, y - 1, z + 1 ) );
979  tempResult.push_back( getVoxelNum( x + 1, y + 1, z + 1 ) );
980 
981  for( size_t k = 0; k < tempResult.size(); ++k )
982  {
983  if( tempResult[k] != -1 )
984  {
985  neighbours.push_back( tempResult[k] );
986  }
987  }
988  return neighbours;
989 }
990 
991 template< typename T >
992 std::vector< size_t > WGridRegular3DTemplate< T >::getNeighboursRange( size_t id, size_t range ) const
993 {
994  std::vector< size_t > neighbours;
995  size_t x = id % m_nbPosX;
996  size_t y = ( id / m_nbPosX ) % m_nbPosY;
997  size_t z = id / ( m_nbPosX * m_nbPosY );
998 
999  if( x >= m_nbPosX || y >= m_nbPosY || z >= m_nbPosZ )
1000  {
1001  std::stringstream ss;
1002  ss << "This point: " << id << " is not part of this grid: ";
1003  ss << " nbPosX: " << m_nbPosX;
1004  ss << " nbPosY: " << m_nbPosY;
1005  ss << " nbPosZ: " << m_nbPosZ;
1006  throw WOutOfBounds( ss.str() );
1007  }
1008  // for every neighbour we must check if its not on the boundary, it will be skipped otherwise
1009  std::vector< int >tempResult;
1010 
1011  for( size_t xx = x - range; xx < x + range + 1; ++xx )
1012  {
1013  for( size_t yy = y - range; yy < y + range + 1; ++yy )
1014  {
1015  for( size_t zz = z - range; zz < z + range + 1; ++zz )
1016  {
1017  tempResult.push_back( getVoxelNum( xx, yy, zz ) );
1018  }
1019  }
1020  }
1021 
1022  for( size_t k = 0; k < tempResult.size(); ++k )
1023  {
1024  if( tempResult[k] != -1 )
1025  {
1026  neighbours.push_back( tempResult[k] );
1027  }
1028  }
1029  return neighbours;
1030 }
1031 
1032 template< typename T >
1033 std::vector< size_t > WGridRegular3DTemplate< T >::getNeighbours9XY( size_t id ) const
1034 {
1035  std::vector< size_t > neighbours;
1036  size_t x = id % m_nbPosX;
1037  size_t y = ( id / m_nbPosX ) % m_nbPosY;
1038  size_t z = id / ( m_nbPosX * m_nbPosY );
1039 
1040  if( x >= m_nbPosX || y >= m_nbPosY || z >= m_nbPosZ )
1041  {
1042  std::stringstream ss;
1043  ss << "This point: " << id << " is not part of this grid: ";
1044  ss << " nbPosX: " << m_nbPosX;
1045  ss << " nbPosY: " << m_nbPosY;
1046  ss << " nbPosZ: " << m_nbPosZ;
1047  throw WOutOfBounds( ss.str() );
1048  }
1049  // boundary check now happens in the getVoxelNum function
1050  int vNum;
1051 
1052  vNum = getVoxelNum( x - 1, y, z );
1053  if( vNum != -1 )
1054  {
1055  neighbours.push_back( vNum );
1056  }
1057  vNum = getVoxelNum( x - 1, y - 1, z );
1058  if( vNum != -1 )
1059  {
1060  neighbours.push_back( vNum );
1061  }
1062  vNum = getVoxelNum( x, y - 1, z );
1063  if( vNum != -1 )
1064  {
1065  neighbours.push_back( vNum );
1066  }
1067  vNum = getVoxelNum( x + 1, y - 1, z );
1068  if( vNum != -1 )
1069  {
1070  neighbours.push_back( vNum );
1071  }
1072  vNum = getVoxelNum( x + 1, y, z );
1073  if( vNum != -1 )
1074  {
1075  neighbours.push_back( vNum );
1076  }
1077  vNum = getVoxelNum( x + 1, y + 1, z );
1078  if( vNum != -1 )
1079  {
1080  neighbours.push_back( vNum );
1081  }
1082  vNum = getVoxelNum( x, y + 1, z );
1083  if( vNum != -1 )
1084  {
1085  neighbours.push_back( vNum );
1086  }
1087  vNum = getVoxelNum( x - 1, y + 1, z );
1088  if( vNum != -1 )
1089  {
1090  neighbours.push_back( vNum );
1091  }
1092  return neighbours;
1093 }
1094 
1095 template< typename T >
1096 std::vector< size_t > WGridRegular3DTemplate< T >::getNeighbours9YZ( size_t id ) const
1097 {
1098  std::vector< size_t > neighbours;
1099  size_t x = id % m_nbPosX;
1100  size_t y = ( id / m_nbPosX ) % m_nbPosY;
1101  size_t z = id / ( m_nbPosX * m_nbPosY );
1102 
1103  if( x >= m_nbPosX || y >= m_nbPosY || z >= m_nbPosZ )
1104  {
1105  std::stringstream ss;
1106  ss << "This point: " << id << " is not part of this grid: ";
1107  ss << " nbPosX: " << m_nbPosX;
1108  ss << " nbPosY: " << m_nbPosY;
1109  ss << " nbPosZ: " << m_nbPosZ;
1110  throw WOutOfBounds( ss.str() );
1111  }
1112  // boundary check now happens in the getVoxelNum function
1113  int vNum;
1114 
1115  vNum = getVoxelNum( x, y, z - 1 );
1116  if( vNum != -1 )
1117  {
1118  neighbours.push_back( vNum );
1119  }
1120  vNum = getVoxelNum( x, y - 1, z - 1 );
1121  if( vNum != -1 )
1122  {
1123  neighbours.push_back( vNum );
1124  }
1125  vNum = getVoxelNum( x, y - 1, z );
1126  if( vNum != -1 )
1127  {
1128  neighbours.push_back( vNum );
1129  }
1130  vNum = getVoxelNum( x, y - 1, z + 1 );
1131  if( vNum != -1 )
1132  {
1133  neighbours.push_back( vNum );
1134  }
1135  vNum = getVoxelNum( x, y, z + 1 );
1136  if( vNum != -1 )
1137  {
1138  neighbours.push_back( vNum );
1139  }
1140  vNum = getVoxelNum( x, y + 1, z + 1 );
1141  if( vNum != -1 )
1142  {
1143  neighbours.push_back( vNum );
1144  }
1145  vNum = getVoxelNum( x, y + 1, z );
1146  if( vNum != -1 )
1147  {
1148  neighbours.push_back( vNum );
1149  }
1150  vNum = getVoxelNum( x, y + 1, z - 1 );
1151  if( vNum != -1 )
1152  {
1153  neighbours.push_back( vNum );
1154  }
1155 
1156  return neighbours;
1157 }
1158 
1159 template< typename T >
1160 std::vector< size_t > WGridRegular3DTemplate< T >::getNeighbours9XZ( size_t id ) const
1161 {
1162  std::vector< size_t > neighbours;
1163  size_t x = id % m_nbPosX;
1164  size_t y = ( id / m_nbPosX ) % m_nbPosY;
1165  size_t z = id / ( m_nbPosX * m_nbPosY );
1166 
1167  if( x >= m_nbPosX || y >= m_nbPosY || z >= m_nbPosZ )
1168  {
1169  std::stringstream ss;
1170  ss << "This point: " << id << " is not part of this grid: ";
1171  ss << " nbPosX: " << m_nbPosX;
1172  ss << " nbPosY: " << m_nbPosY;
1173  ss << " nbPosZ: " << m_nbPosZ;
1174  throw WOutOfBounds( ss.str() );
1175  }
1176  // boundary check now happens in the getVoxelNum function
1177  int vNum;
1178 
1179  vNum = getVoxelNum( x, y, z - 1 );
1180  if( vNum != -1 )
1181  {
1182  neighbours.push_back( vNum );
1183  }
1184  vNum = getVoxelNum( x - 1, y, z - 1 );
1185  if( vNum != -1 )
1186  {
1187  neighbours.push_back( vNum );
1188  }
1189  vNum = getVoxelNum( x - 1, y, z );
1190  if( vNum != -1 )
1191  {
1192  neighbours.push_back( vNum );
1193  }
1194  vNum = getVoxelNum( x - 1, y, z + 1 );
1195  if( vNum != -1 )
1196  {
1197  neighbours.push_back( vNum );
1198  }
1199  vNum = getVoxelNum( x, y, z + 1 );
1200  if( vNum != -1 )
1201  {
1202  neighbours.push_back( vNum );
1203  }
1204  vNum = getVoxelNum( x + 1, y, z + 1 );
1205  if( vNum != -1 )
1206  {
1207  neighbours.push_back( vNum );
1208  }
1209  vNum = getVoxelNum( x + 1, y, z );
1210  if( vNum != -1 )
1211  {
1212  neighbours.push_back( vNum );
1213  }
1214  vNum = getVoxelNum( x + 1, y, z - 1 );
1215  if( vNum != -1 )
1216  {
1217  neighbours.push_back( vNum );
1218  }
1219 
1220  return neighbours;
1221 }
1222 
1223 template< typename T >
1225 {
1226  Vector3Type v = m_transform.positionToGridSpace( pos );
1227 
1228  if( v[ 0 ] < T( 0.0 ) || v[ 0 ] >= static_cast< T >( m_nbPosX - 1 ) )
1229  {
1230  return false;
1231  }
1232  if( v[ 1 ] < T( 0.0 ) || v[ 1 ] >= static_cast< T >( m_nbPosY - 1 ) )
1233  {
1234  return false;
1235  }
1236  if( v[ 2 ] < T( 0.0 ) || v[ 2 ] >= static_cast< T >( m_nbPosZ - 1 ) )
1237  {
1238  return false;
1239  }
1240  return true;
1241 }
1242 
1243 template< typename T >
1245 {
1246  return m_transform.isNotRotated();
1247 }
1248 
1249 template< typename T >
1251 {
1252  return m_transform;
1253 }
1254 
1255 template< typename T >
1257 {
1258  WPropInt xDim = m_infoProperties->addProperty( "X dimension: ",
1259  "The x dimension of the grid.",
1260  static_cast<int>( getNbCoordsX() ) );
1261  WPropInt yDim = m_infoProperties->addProperty( "Y dimension: ",
1262  "The y dimension of the grid.",
1263  static_cast<int>( getNbCoordsY() ) );
1264  WPropInt zDim = m_infoProperties->addProperty( "Z dimension: ",
1265  "The z dimension of the grid.",
1266  static_cast<int>( getNbCoordsZ() ) );
1267 
1268  WPropDouble xOffset = m_infoProperties->addProperty( "X offset: ",
1269  "The distance between samples in x direction",
1270  static_cast< double >( getOffsetX() ) );
1271  WPropDouble yOffset = m_infoProperties->addProperty( "Y offset: ",
1272  "The distance between samples in y direction",
1273  static_cast< double >( getOffsetY() ) );
1274  WPropDouble zOffset = m_infoProperties->addProperty( "Z offset: ",
1275  "The distance between samples in z direction",
1276  static_cast< double >( getOffsetZ() ) );
1277 }
1278 
1279 template< typename T >
1281 {
1282  return ( getNbCoordsX() == other.getNbCoordsX() ) &&
1283  ( getNbCoordsY() == other.getNbCoordsY() ) &&
1284  ( getNbCoordsZ() == other.getNbCoordsZ() ) &&
1285  ( m_transform == other.m_transform );
1286 }
1287 
1288 // +----------------------+
1289 // | non-member functions |
1290 // +----------------------+
1291 
1292 /**
1293  * Convinience function returning all offsets per axis.
1294  * 0 : xAxis, 1 : yAxis, 2 : zAxis
1295  * \param grid The grid having the information.
1296  * \note Implementing this as NonMemberNonFriend was intentional.
1297  * \return Array of number of samples per axis.
1298  */
1299 template< typename T >
1300 inline boost::array< T, 3 > getOffsets( boost::shared_ptr< const WGridRegular3DTemplate< T > > grid )
1301 {
1302  boost::array< T, 3 > result = { { grid->getOffsetX(), grid->getOffsetY(), grid->getOffsetZ() } }; // NOLINT curly braces
1303  return result;
1304 }
1305 
1306 /**
1307  * Convinience function returning all number coords per axis.
1308  * 0 : xAxis, 1 : yAxis, 2 : zAxis
1309  * \param grid The grid having the information.
1310  * \note Implementing this as NonMemberNonFriend was intentional.
1311  * \return Array of number of samples per axis.
1312  */
1313 template< typename T >
1314 inline boost::array< unsigned int, 3 > getNbCoords( boost::shared_ptr< const WGridRegular3DTemplate< T > > grid )
1315 {
1316  boost::array< unsigned int, 3 > result = { { grid->getNbCoordsX(), grid->getNbCoordsY(), grid->getNbCoordsZ() } }; // NOLINT curly braces
1317  return result;
1318 }
1319 
1320 /**
1321  * Convinience function returning all axis directions.
1322  * 0 : xAxis, 1 : yAxis, 2 : zAxis
1323  * \param grid The grid having the information.
1324  * \note Implementing this as NonMemberNonFriend was intentional.
1325  * \return The direction of each axis as array
1326  */
1327 template< typename T >
1328 inline boost::array< typename WGridRegular3DTemplate< T >::Vector3Type, 3 > getDirections( boost::shared_ptr< const WGridRegular3DTemplate< T > > grid ) // NOLINT -- too long line
1329 {
1330  boost::array< typename WGridRegular3DTemplate< T >::Vector3Type, 3 > result = { { grid->getDirectionX(), grid->getDirectionY(), grid->getDirectionZ() } }; // NOLINT curly braces
1331  return result;
1332 }
1333 
1334 /**
1335  * Convinience function returning all axis unit directions.
1336  * 0 : xAxis, 1 : yAxis, 2 : zAxis
1337  * \param grid The grid having the information.
1338  * \note Implementing this as NonMemberNonFriend was intentional.
1339  * \return The direction of each axis as array
1340  */
1341 template< typename T >
1342 inline boost::array< typename WGridRegular3DTemplate< T >::Vector3Type, 3 > getUnitDirections( boost::shared_ptr< const WGridRegular3DTemplate< T > > grid ) // NOLINT -- too long line
1343 {
1344  boost::array< typename WGridRegular3DTemplate< T >::Vector3Type, 3 > result = { { grid->getUnitDirectionX(), grid->getUnitDirectionY(), grid->getUnitDirectionZ() } }; // NOLINT curly braces
1345  return result;
1346 }
1347 
1348 #endif // WGRIDREGULAR3D_H
Vector3Type getDirectionX() const
Returns the vector determining the direction of samples in x direction.
unsigned int getNbCoordsY() const
Returns the number of samples in y direction.
std::vector< size_t > getNeighboursRange(size_t id, size_t range) const
Return the list of all neighbour voxels.
WVector3i getVoxelCoord(const Vector3Type &pos) const
Computes the voxel coordinates of that voxel which contains the position pos.
A grid that has parallelepiped cells which all have the same proportion.
boost::shared_ptr< std::vector< Vector3Type > > getVoxelVertices(const Vector3Type &point, const T margin=0.0) const
Computes the vertices for a voxel cuboid around the given point:
Vector3Type worldCoordToTexCoord(Vector3Type point)
Transforms world coordinates to texture coordinates.
boost::array< size_t, 8 > CellVertexArray
Convenience typedef for a boost::array< size_t, 8 >.
int getVoxelNum(const Vector3Type &pos) const
Returns the i'th voxel where the given position belongs too.
WMatrix< T > getTransformationMatrix() const
Returns a 4x4 matrix that represents the grid's transformation.
unsigned int m_nbPosY
Number of positions in y direction.
std::vector< size_t > getNeighbours9XY(size_t id) const
Return the list of all neighbour voxels.
WGridTransformOrthoTemplate< T > const m_transform
The grid's transformation.
void expandBy(const WBoundingBoxImpl< VT > &bb)
Expands this bounding box to include the given bounding box.
Definition: WBoundingBox.h:253
int getNVoxelCoord(const Vector3Type &pos, size_t axis) const
Computes for the n'th component of the voxel coordinate where the voxel contains the position pos...
WGridTransformOrthoTemplate< T > const getTransform() const
Returns the transformation used by this grid.
WBoundingBox getBoundingBoxIncludingBorder() const
Calculates the bounding box but includes the border voxel associated cell too.
boost::shared_ptr< WGridRegular3DTemplate > SPtr
Convenience typedef for a boost::shared_ptr< WGridRegular3DTemplate >.
Indicates invalid element access of a container.
Definition: WOutOfBounds.h:36
std::vector< size_t > getNeighbours27(size_t id) const
Return the list of all neighbour voxels.
Base class to all grid types, e.g.
Definition: WGrid.h:42
WBoundingBox getVoxelBoundingBox() const
Calculate the bounding box in voxel space.
unsigned int getNbCoordsZ() const
Returns the number of samples in z direction.
Matrix template class with variable number of rows and columns.
Vector3Type getPosition(unsigned int i) const
Returns the i-th position on the grid.
T getOffsetZ() const
Returns the distance between samples in z direction.
std::vector< size_t > getNeighbours9YZ(size_t id) const
Return the list of all neighbour voxels.
CellVertexArray getCellVertexIds(size_t cellId) const
Computes the ids of the vertices of a cell given by its id.
Vector3Type getUnitDirectionX() const
Returns the vector determining the unit (normalized) direction of samples in x direction.
T getOffsetY() const
Returns the distance between samples in y direction.
unsigned int m_nbPosX
Number of positions in x direction.
std::vector< size_t > getNeighbours9XZ(size_t id) const
Return the list of all neighbour voxels.
unsigned int m_nbPosZ
Number of positions in z direction.
size_t getCellId(const Vector3Type &pos, bool *success) const
Computes the id of the cell containing the position pos.
bool operator==(const WGridRegular3DTemplate< T > &other) const
Compares two grids.
bool isNotRotated() const
Return whether the transformations of the grid are only translation and/or scaling.
bool encloses(const Vector3Type &pos) const
Decides whether a certain position is inside this grid or not.
int getYVoxelCoord(const Vector3Type &pos) const
Computes the Y coordinate of that voxel that contains the position pos.
T getOffsetX() const
Returns the distance between samples in x direction.
int getZVoxelCoord(const Vector3Type &pos) const
Computes the Z coordinate of that voxel that contains the position pos.
Vector3Type getDirectionZ() const
Returns the vector determining the direction of samples in z direction.
Vector3Type getOrigin() const
Returns the position of the origin of the grid.
boost::shared_ptr< const WGridRegular3DTemplate > ConstSPtr
Convenience typedef for a boost::shared_ptr< const WGridRegular3DTemplate >.
Vector3Type getDirectionY() const
Returns the vector determining the direction of samples in y direction.
unsigned int getNbCoordsX() const
Returns the number of samples in x direction.
int getXVoxelCoord(const Vector3Type &pos) const
Computes the X coordinate of that voxel that contains the position pos.
Vector3Type getUnitDirectionZ() const
Returns the vector determining the unit (normalized) direction of samples in z direction.
WMatrixFixed< T, 3, 1 > Vector3Type
Convenience typedef for 3d vectors of the appropriate numerical type.
void initInformationProperties()
Adds the specific information of this grid type to the informational properties.
WBoundingBox getBoundingBox() const
Axis aligned Bounding Box that encloses this grid.
Implements an orthogonal grid transformation.
std::vector< size_t > getNeighbours(size_t id) const
Return the list of neighbour voxels.
Tests the WGridRegular3D class.
Vector3Type getUnitDirectionY() const
Returns the vector determining the unit (normalized) direction of samples in y direction.