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