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