OpenWalnut 1.3.1
WGridRegular3D.h
00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
00006 // For more information see http://www.openwalnut.org/copying
00007 //
00008 // This file is part of OpenWalnut.
00009 //
00010 // OpenWalnut is free software: you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as published by
00012 // the Free Software Foundation, either version 3 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // OpenWalnut is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public License
00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
00022 //
00023 //---------------------------------------------------------------------------
00024 
00025 #ifndef WGRIDREGULAR3D_H
00026 #define WGRIDREGULAR3D_H
00027 
00028 #include <cmath>
00029 #include <string>
00030 #include <utility>
00031 #include <vector>
00032 
00033 #include <boost/array.hpp>
00034 #include <boost/shared_ptr.hpp>
00035 
00036 #include <osg/Matrix>
00037 #include <osg/Vec3>
00038 
00039 #include "../common/exceptions/WOutOfBounds.h"
00040 #include "../common/exceptions/WPreconditionNotMet.h"
00041 #include "../common/math/WLinearAlgebraFunctions.h"
00042 #include "../common/math/WMatrix.h"
00043 #include "../common/math/linearAlgebra/WLinearAlgebra.h"
00044 #include "../common/WBoundingBox.h"
00045 #include "../common/WCondition.h"
00046 #include "../common/WDefines.h"
00047 #include "../common/WProperties.h"
00048 
00049 #include "WGrid.h"
00050 #include "WGridTransformOrtho.h"
00051 
00052 /**
00053  * A grid that has parallelepiped cells which all have the same proportion. I.e.
00054  * the samples along a single axis are equidistant. The distance of samples may
00055  * vary between axes.
00056  *
00057  * \warning Positions on the upper bounddaries in x, y and z are considered outside the grid.
00058  * \ingroup dataHandler
00059  */
00060 template< typename T >
00061 class WGridRegular3DTemplate : public WGrid // NOLINT
00062 {
00063     // this (friend) is necessary to allow casting
00064     template <class U>
00065     friend class WGridRegular3DTemplate;
00066     /**
00067      * Only test are allowed as friends.
00068      */
00069     friend class WGridRegular3DTest;
00070 public:
00071     /**
00072      * Convenience typedef for 3d vectors of the appropriate numerical type.
00073      */
00074     typedef WMatrixFixed< T, 3, 1 > Vector3Type;
00075 
00076     /**
00077      * Convenience typedef for a boost::shared_ptr< WGridRegular3DTemplate >.
00078      */
00079     typedef boost::shared_ptr< WGridRegular3DTemplate > SPtr;
00080 
00081     /**
00082      * Convenience typedef for a boost::shared_ptr< const WGridRegular3DTemplate >.
00083      */
00084     typedef boost::shared_ptr< const WGridRegular3DTemplate > ConstSPtr;
00085 
00086     /**
00087      * Convenience typedef for a boost::array< size_t, 8 >. Return type of getCellVertexIds.
00088      */
00089     typedef boost::array< size_t, 8 > CellVertexArray;
00090 
00091     /**
00092      * Copy constructor.
00093      * Copies the data from an WGridRegular3DTemplate object with arbitary numerical type.
00094      *
00095      * \param rhs A WGridRegular3DTemplate object, which mustn't have the same numerical type.
00096      */
00097     template< typename InputType >
00098     WGridRegular3DTemplate( WGridRegular3DTemplate< InputType > const& rhs ); // NOLINT -- no explicit, this allows casts
00099 
00100     /**
00101      * Defines the number of samples in each coordinate direction as ints,
00102      * and the transformation of the grid via a grid transform.
00103      *
00104      * \param nbPosX number of positions along first axis
00105      * \param nbPosY number of positions along second axis
00106      * \param nbPosZ number of positions along third axis
00107      * \param transform a grid transformation
00108      */
00109     WGridRegular3DTemplate( unsigned int nbPosX, unsigned int nbPosY, unsigned int nbPosZ,
00110                             WGridTransformOrthoTemplate< T > const transform = WGridTransformOrthoTemplate< T >() );
00111 
00112     /**
00113      * Returns the number of samples in x direction.
00114      * \return The number of samples in x direction.
00115      */
00116     unsigned int getNbCoordsX() const;
00117 
00118     /**
00119      * Returns the number of samples in y direction.
00120      * \return The number of samples in y direction.
00121      */
00122     unsigned int getNbCoordsY() const;
00123 
00124     /**
00125      * Returns the number of samples in z direction.
00126      * \return The number of samples in z direction.
00127      */
00128     unsigned int getNbCoordsZ() const;
00129 
00130     /**
00131      * Returns the distance between samples in x direction.
00132      * \return The distance between samples in x direction.
00133      */
00134     T getOffsetX() const;
00135 
00136     /**
00137      * Returns the distance between samples in y direction.
00138      * \return The distance between samples in y direction.
00139      */
00140     T getOffsetY() const;
00141 
00142     /**
00143      * Returns the distance between samples in z direction.
00144      * \return The distance between samples in z direction.
00145      */
00146     T getOffsetZ() const;
00147 
00148     /**
00149      * Returns the vector determining the direction of samples in x direction.
00150      * Adding this vector to a grid position in world coordinates yields the position of the next sample
00151      * along the grids (world coordinate) x-axis.
00152      * \return The vector determining the direction of samples in x direction.
00153      */
00154     Vector3Type getDirectionX() const;
00155 
00156     /**
00157      * Returns the vector determining the direction of samples in y direction.
00158      * Adding this vector to a grid position in world coordinates yields the position of the next sample
00159      * along the grids (world coordinate) y-axis.
00160      * \return The vector determining the direction of samples in y direction.
00161      */
00162     Vector3Type getDirectionY() const;
00163 
00164     /**
00165      * Returns the vector determining the direction of samples in z direction.
00166      * Adding this vector to a grid position in world coordinates yields the position of the next sample
00167      * along the grids (world coordinate) z-axis.
00168      * \return The vector determining the direction of samples in z direction.
00169      */
00170     Vector3Type getDirectionZ() const;
00171 
00172     /**
00173      * Returns the vector determining the unit (normalized) direction of samples in x direction.
00174      * \return The vector determining the unit (normalized) direction of samples in x direction.
00175      */
00176     Vector3Type getUnitDirectionX() const;
00177 
00178     /**
00179      * Returns the vector determining the unit (normalized) direction of samples in y direction.
00180      * \return The vector determining the unit (normalized) direction of samples in y direction.
00181      */
00182     Vector3Type getUnitDirectionY() const;
00183 
00184     /**
00185      * Returns the vector determining the unit (normalized) direction of samples in z direction.
00186      * \return The vector determining the unit (normalized) direction of samples in z direction.
00187      */
00188     Vector3Type getUnitDirectionZ() const;
00189 
00190     /**
00191      * Returns the position of the origin of the grid.
00192      * \return The position of the origin of the grid.
00193      */
00194     Vector3Type getOrigin() const;
00195 
00196     /**
00197      * Returns a 4x4 matrix that represents the grid's transformation.
00198      * \return The grid's transformation.
00199      */
00200     WMatrix< T > getTransformationMatrix() const;
00201 
00202     /**
00203      * \copybrief WGrid::getBoundingBox()
00204      * \return \copybrief WGrid::getBoundingBox()
00205      */
00206     WBoundingBox getBoundingBox() const;
00207 
00208     /**
00209      * Returns the i-th position on the grid.
00210      * \param i id of position to be obtained
00211      * \return i-th position of the grid.
00212      */
00213     Vector3Type getPosition( unsigned int i ) const;
00214 
00215     /**
00216      * Returns the position that is the iX-th in x direction, the iY-th in
00217      * y direction and the iZ-th in z direction.
00218      * \param iX id along first axis of position to be obtained
00219      * \param iY id along second axis of position to be obtained
00220      * \param iZ id along third axis of position to be obtained
00221      * \return Position (iX,iY,iZ)
00222      */
00223     Vector3Type getPosition( unsigned int iX, unsigned int iY, unsigned int iZ ) const;
00224 
00225     /**
00226      * Transforms world coordinates to texture coordinates.
00227      * \param point The point with these coordinates will be transformed.
00228      * \return point transformed into texture coordinate system
00229      */
00230     Vector3Type worldCoordToTexCoord( Vector3Type point );
00231 
00232     /**
00233      * Returns the i'th voxel where the given position belongs too.
00234      *
00235      * A voxel is a cuboid which surrounds a point on the grid.
00236      *
00237      * \verbatim
00238       Voxel:
00239                      ______________ ____ (0.5, 0.5, 0.5)
00240                     /:            /|
00241                    / :           / |
00242                   /  :          /  |
00243                  /   :         /   |
00244                _/____:_ ___ __/    |
00245                 |    :        |    |
00246                 |    :    *<--|--------- grid point (0, 0, 0)
00247                 |    :........|....|__
00248          dz == 1|   /         |   /
00249                 |  /          |  / dy == 1
00250                 | /           | /
00251                _|/____________|/__
00252                 |<- dx == 1 ->|
00253          -0.5,-0.5,-0.5
00254        \endverbatim
00255      *
00256      * Please note the first voxel has only 1/8 of the size a normal voxel
00257      * would have since all positions outside the grid do not belong
00258      * to any voxel. Note: a cell is different to a voxel in terms of position.
00259      * A voxel has a grid point as center whereas a cell has grid points as
00260      * corners.
00261      * \param pos Position for which we want to have the voxel number.
00262      *
00263      * \return Voxel number or -1 if the position refers to a point outside of
00264      * the grid.
00265      */
00266     int getVoxelNum( const Vector3Type& pos ) const;
00267 
00268     /**
00269      * returns the voxel index for a given discrete position in the grid
00270      *
00271      * \param x Position for which we want to have the voxel number.
00272      * \param y Position for which we want to have the voxel number.
00273      * \param z Position for which we want to have the voxel number.
00274      *
00275      * \return Voxel number or -1 if the position refers to a point outside of
00276      * the grid.
00277      */
00278     int getVoxelNum( const size_t x, const size_t y, const size_t z ) const;
00279     /**
00280      * Computes the X coordinate of that voxel that contains the
00281      * position pos.
00282      *
00283      * \param pos The position which selects the voxel for which the X
00284      * coordinate is computed.
00285      *
00286      * \return The X coordinate or -1 if pos refers to point outside of the
00287      * grid.
00288      */
00289     int getXVoxelCoord( const Vector3Type& pos ) const;
00290 
00291     /**
00292      * Computes the Y coordinate of that voxel that contains the
00293      * position pos.
00294      *
00295      * \param pos The position which selects the voxel for which the Y
00296      * coordinate is computed.
00297      *
00298      * \return The Y coordinate or -1 if pos refers to point outside of the
00299      * grid.
00300      */
00301     int getYVoxelCoord( const Vector3Type& pos ) const;
00302 
00303     /**
00304      * Computes the Z coordinate of that voxel that contains the
00305      * position pos.
00306      *
00307      * \param pos The position which selects the voxel for which the Z
00308      * coordinate is computed.
00309      *
00310      * \return The Z coordinate or -1 if pos refers to point outside of the
00311      * grid.
00312      */
00313     int getZVoxelCoord( const Vector3Type& pos ) const;
00314 
00315     /**
00316      * Computes the voxel coordinates of that voxel which contains
00317      * the position pos.
00318      *
00319      * \param pos The position selecting the voxel.
00320      *
00321      * \return A vector of ints where the first component is the X voxel
00322      * coordinate, the second the Y component voxel coordinate and the last the
00323      * Z component of the voxel coordinate. If the selecting position is
00324      * outside of the grid then -1 -1 -1 is returned.
00325      */
00326     WVector3i getVoxelCoord( const Vector3Type& pos ) const;
00327 
00328     /**
00329      * Computes the id of the cell containing the position pos. Note that the upper
00330      * bound of the grid does not belong to any cell
00331      *
00332      * \param pos The position selecting the cell.
00333      * \param success True if the position pos is inside the grid.
00334      *
00335      * \return id of the containing the position.
00336      */
00337     size_t getCellId( const Vector3Type& pos, bool* success ) const;
00338 
00339     /**
00340      * Computes the ids of the vertices of a cell given by its id.
00341      *
00342      * \param cellId The id of the cell we want to know ther vertices of.
00343      *
00344      * \return Ids of vertices belonging to cell with given cellId.
00345 
00346      * \verbatim
00347         z-axis  y-axis
00348         |      /
00349         | 6___/_7
00350         |/:    /|
00351         4_:___5 |
00352         | :...|.|
00353         |.2   | 3
00354         |_____|/ ____x-axis
00355        0      1
00356        \endverbatim
00357      *
00358      */
00359     CellVertexArray getCellVertexIds( size_t cellId ) const;
00360 
00361     /**
00362      * Computes the vertices for a voxel cuboid around the given point:
00363      *
00364      * \verbatim
00365         z-axis  y-axis
00366         |      /
00367         | h___/_g
00368         |/:    /|
00369         d_:___c |
00370         | :...|.|
00371         |.e   | f
00372         |_____|/ ____x-axis
00373        a      b
00374        \endverbatim
00375      *
00376      * As you can see the order of the points is: a, b, c, d, e, f, g, h.
00377      *
00378      * \param point Center of the cuboid which must not necesarrily be a point
00379      * of the grid.
00380      * \param margin If you need to shrink the Voxel put here the delta > 0.
00381      *
00382      * \return Reference to a list of vertices which are the corner points of
00383      * the cube. Note this must not be a voxel, but has the same size of the an
00384      * voxel. If you need voxels at grid positions fill this function with
00385      * voxel center positions aka grid points.
00386      */
00387     boost::shared_ptr< std::vector< Vector3Type > > getVoxelVertices( const Vector3Type& point,
00388                                                                       const T margin = 0.0 ) const;
00389 
00390     /**
00391      * Return the list of neighbour voxels.
00392      *
00393      * \throw WOutOfBounds If the voxel id is outside of the grid.
00394      *
00395      * \param id Number of the voxel for which the neighbours should be computed
00396      *
00397      * \return Vector of voxel ids which are all neighboured
00398      */
00399     std::vector< size_t > getNeighbours( size_t id ) const;
00400 
00401     /**
00402      * Return the list of all neighbour voxels.
00403      *
00404      * \throw WOutOfBounds If the voxel id is outside of the grid.
00405      *
00406      * \param id Number of the voxel for which the neighbours should be computed
00407      *
00408      * \return Vector of voxel ids which are all neighboured
00409      */
00410     std::vector< size_t > getNeighbours27( size_t id ) const;
00411 
00412     /**
00413      * Return the list of all neighbour voxels.
00414      *
00415      * \throw WOutOfBounds If the voxel id is outside of the grid.
00416      *
00417      * \param id Number of the voxel for which the neighbours should be computed
00418      *
00419      * \param range neighborhood range selected. It specifies the distance to count as neighbour in each direction.
00420      *
00421      * \return Vector of voxel ids which are all neighboured
00422      */
00423     std::vector< size_t > getNeighboursRange( size_t id, size_t range ) const;
00424 
00425     /**
00426      * Return the list of all neighbour voxels.
00427      *
00428      * \throw WOutOfBounds If the voxel id is outside of the grid.
00429      *
00430      * \param id Number of the voxel for which the neighbours should be computed
00431      *
00432      * \return Vector of voxel ids which are all neighboured along the XY plane
00433      */
00434     std::vector< size_t > getNeighbours9XY( size_t id ) const;
00435 
00436     /**
00437      * Return the list of all neighbour voxels.
00438      *
00439      * \throw WOutOfBounds If the voxel id is outside of the grid.
00440      *
00441      * \param id Number of the voxel for which the neighbours should be computed
00442      *
00443      * \return Vector of voxel ids which are all neighboured along the YZ plane
00444      */
00445     std::vector< size_t > getNeighbours9YZ( size_t id ) const;
00446 
00447     /**
00448      * Return the list of all neighbour voxels.
00449      *
00450      * \throw WOutOfBounds If the voxel id is outside of the grid.
00451      *
00452      * \param id Number of the voxel for which the neighbours should be computed
00453      *
00454      * \return Vector of voxel ids which are all neighboured along the XZ plane
00455      */
00456     std::vector< size_t > getNeighbours9XZ( size_t id ) const;
00457 
00458     /**
00459      * Decides whether a certain position is inside this grid or not.
00460      *
00461      * \param pos Position to test
00462      *
00463      * \return True if and only if the given point is inside or on boundary of this grid, otherwise false.
00464      */
00465     bool encloses( const Vector3Type& pos ) const;
00466 
00467     /**
00468      * Return whether the transformations of the grid are only translation and/or scaling
00469      * \return Transformation does not contain rotation?
00470      */
00471     bool isNotRotated() const;
00472 
00473     /**
00474      * Returns the transformation used by this grid.
00475      * \return The transformation.
00476      */
00477     WGridTransformOrthoTemplate< T > const getTransform() const;
00478 
00479 protected:
00480 private:
00481     /**
00482      * Computes for the n'th component of the voxel coordinate where the voxel
00483      * contains the position pos.
00484      *
00485      * \param pos The position for which the n'th component of the voxel
00486      * coordinates should be computed.
00487      * \param axis The number of the component. (0 == x-axis, 1 == y-axis, ...)
00488      *
00489      * \return The n'th component of the voxel coordinate
00490      */
00491     int getNVoxelCoord( const Vector3Type& pos, size_t axis ) const;
00492 
00493     /**
00494      * Adds the specific information of this grid type to the
00495      * informational properties.
00496      */
00497     void initInformationProperties();
00498 
00499     unsigned int m_nbPosX; //!< Number of positions in x direction
00500     unsigned int m_nbPosY; //!< Number of positions in y direction
00501     unsigned int m_nbPosZ; //!< Number of positions in z direction
00502 
00503     //! The grid's transformation.
00504     WGridTransformOrthoTemplate< T > const m_transform;
00505 };
00506 
00507 // Convenience typedefs
00508 typedef WGridRegular3DTemplate< double > WGridRegular3D;
00509 typedef WGridRegular3DTemplate< double > WGridRegular3DDouble;
00510 typedef WGridRegular3DTemplate< float > WGridRegular3DFloat;
00511 
00512 template< typename T >
00513 template< typename InputType >
00514 WGridRegular3DTemplate< T >::WGridRegular3DTemplate( WGridRegular3DTemplate< InputType > const& rhs ) :
00515     WGrid( rhs.m_nbPosX * rhs.m_nbPosY * rhs.m_nbPosZ ),
00516     m_nbPosX( rhs.m_nbPosX ),
00517     m_nbPosY( rhs.m_nbPosY ),
00518     m_nbPosZ( rhs.m_nbPosZ ),
00519     m_transform( rhs.m_transform )
00520 {
00521     initInformationProperties();
00522 }
00523 
00524 template< typename T >
00525 WGridRegular3DTemplate< T >::WGridRegular3DTemplate( unsigned int nbPosX, unsigned int nbPosY, unsigned int nbPosZ,
00526                                      WGridTransformOrthoTemplate< T > const transform )
00527     : WGrid( nbPosX * nbPosY * nbPosZ ),
00528       m_nbPosX( nbPosX ),
00529       m_nbPosY( nbPosY ),
00530       m_nbPosZ( nbPosZ ),
00531       m_transform( transform )
00532 {
00533     initInformationProperties();
00534 }
00535 
00536 template< typename T >
00537 inline unsigned int WGridRegular3DTemplate< T >::getNbCoordsX() const
00538 {
00539     return m_nbPosX;
00540 }
00541 
00542 template< typename T >
00543 inline unsigned int WGridRegular3DTemplate< T >::getNbCoordsY() const
00544 {
00545     return m_nbPosY;
00546 }
00547 
00548 template< typename T >
00549 inline unsigned int WGridRegular3DTemplate< T >::getNbCoordsZ() const
00550 {
00551     return m_nbPosZ;
00552 }
00553 
00554 template< typename T >
00555 inline T WGridRegular3DTemplate< T >::getOffsetX() const
00556 {
00557     return m_transform.getOffsetX();
00558 }
00559 
00560 template< typename T >
00561 inline T WGridRegular3DTemplate< T >::getOffsetY() const
00562 {
00563     return m_transform.getOffsetY();
00564 }
00565 
00566 template< typename T >
00567 inline T WGridRegular3DTemplate< T >::getOffsetZ() const
00568 {
00569     return m_transform.getOffsetZ();
00570 }
00571 
00572 template< typename T >
00573 inline typename WGridRegular3DTemplate< T >::Vector3Type WGridRegular3DTemplate< T >::getDirectionX() const
00574 {
00575     return m_transform.getDirectionX();
00576 }
00577 
00578 template< typename T >
00579 inline typename WGridRegular3DTemplate< T >::Vector3Type WGridRegular3DTemplate< T >::getDirectionY() const
00580 {
00581     return m_transform.getDirectionY();
00582 }
00583 
00584 template< typename T >
00585 inline typename WGridRegular3DTemplate< T >::Vector3Type WGridRegular3DTemplate< T >::getDirectionZ() const
00586 {
00587     return m_transform.getDirectionZ();
00588 }
00589 
00590 template< typename T >
00591 inline typename WGridRegular3DTemplate< T >::Vector3Type WGridRegular3DTemplate< T >::getUnitDirectionX() const
00592 {
00593     return m_transform.getUnitDirectionX();
00594 }
00595 
00596 template< typename T >
00597 inline typename WGridRegular3DTemplate< T >::Vector3Type WGridRegular3DTemplate< T >::getUnitDirectionY() const
00598 {
00599     return m_transform.getUnitDirectionY();
00600 }
00601 
00602 template< typename T >
00603 inline typename WGridRegular3DTemplate< T >::Vector3Type WGridRegular3DTemplate< T >::getUnitDirectionZ() const
00604 {
00605     return m_transform.getUnitDirectionZ();
00606 }
00607 
00608 template< typename T >
00609 inline typename WGridRegular3DTemplate< T >::Vector3Type WGridRegular3DTemplate< T >::getOrigin() const
00610 {
00611     return m_transform.getOrigin();
00612 }
00613 
00614 template< typename T >
00615 inline WMatrix< T > WGridRegular3DTemplate< T >::getTransformationMatrix() const
00616 {
00617     return m_transform.getTransformationMatrix();
00618 }
00619 
00620 template< typename T >
00621 inline WBoundingBox WGridRegular3DTemplate< T >::getBoundingBox() const
00622 {
00623     WBoundingBox result;
00624     result.expandBy( m_transform.positionToWorldSpace( Vector3Type( 0.0,                0.0,                0.0            ) ) );
00625     result.expandBy( m_transform.positionToWorldSpace( Vector3Type( getNbCoordsX() - 1, 0.0,                0.0            ) ) );
00626     result.expandBy( m_transform.positionToWorldSpace( Vector3Type( 0.0,                getNbCoordsY() - 1, 0.0            ) ) );
00627     result.expandBy( m_transform.positionToWorldSpace( Vector3Type( getNbCoordsX() - 1, getNbCoordsY() - 1, 0.0            ) ) );
00628     result.expandBy( m_transform.positionToWorldSpace( Vector3Type( 0.0,                0.0,                getNbCoordsZ() - 1 ) ) );
00629     result.expandBy( m_transform.positionToWorldSpace( Vector3Type( getNbCoordsX() - 1, 0.0,                getNbCoordsZ() - 1 ) ) );
00630     result.expandBy( m_transform.positionToWorldSpace( Vector3Type( 0.0,                getNbCoordsY() - 1, getNbCoordsZ() - 1 ) ) );
00631     result.expandBy( m_transform.positionToWorldSpace( Vector3Type( getNbCoordsX() - 1, getNbCoordsY() - 1, getNbCoordsZ() - 1 ) ) );
00632     return result;
00633 }
00634 
00635 template< typename T >
00636 inline typename WGridRegular3DTemplate< T >::Vector3Type WGridRegular3DTemplate< T >::getPosition( unsigned int i ) const
00637 {
00638     return getPosition( i % m_nbPosX, ( i / m_nbPosX ) % m_nbPosY, i / ( m_nbPosX * m_nbPosY ) );
00639 }
00640 
00641 template< typename T >
00642 inline typename WGridRegular3DTemplate< T >::Vector3Type WGridRegular3DTemplate< T >::getPosition( unsigned int iX,
00643                                                                                                    unsigned int iY,
00644                                                                                                    unsigned int iZ ) const
00645 {
00646     Vector3Type i( iX, iY, iZ );
00647     return m_transform.positionToWorldSpace( i );
00648 }
00649 
00650 template< typename T >
00651 inline typename WGridRegular3DTemplate< T >::Vector3Type WGridRegular3DTemplate< T >::worldCoordToTexCoord( WGridRegular3DTemplate< T >::Vector3Type point ) // NOLINT -- too long line
00652 {
00653     Vector3Type r( m_transform.positionToGridSpace( point ) );
00654 
00655     // Scale to [0,1]
00656     r[0] = r[0] / m_nbPosX;
00657     r[1] = r[1] / m_nbPosY;
00658     r[2] = r[2] / m_nbPosZ;
00659 
00660     // Correct the coordinates to have the position at the center of the texture voxel.
00661     r[0] += 0.5 / m_nbPosX;
00662     r[1] += 0.5 / m_nbPosY;
00663     r[2] += 0.5 / m_nbPosZ;
00664 
00665     return r;
00666 }
00667 
00668 template< typename T >
00669 inline int WGridRegular3DTemplate< T >::getVoxelNum( const Vector3Type& pos ) const
00670 {
00671     // Note: the reason for the +1 is that the first and last Voxel in a x-axis
00672     // row are cut.
00673     //
00674     //  y-axis
00675     //  _|_______     ___ this is the 3rd Voxel
00676     // 1 |   |   |   v
00677     //   |...............
00678     //  _|_:_|_:_|_:_|_:____ x-axis
00679     //   | : | : | : | :
00680     //   |.:...:...:...:.
00681     //   0   1   2
00682     int xVoxelCoord = getXVoxelCoord( pos );
00683     int yVoxelCoord = getYVoxelCoord( pos );
00684     int zVoxelCoord = getZVoxelCoord( pos );
00685     if( xVoxelCoord == -1 || yVoxelCoord == -1 || zVoxelCoord == -1 )
00686     {
00687         return -1;
00688     }
00689     return xVoxelCoord
00690          + yVoxelCoord * ( m_nbPosX )
00691          + zVoxelCoord * ( m_nbPosX ) * ( m_nbPosY );
00692 }
00693 
00694 template< typename T >
00695 inline int WGridRegular3DTemplate< T >::getVoxelNum( const size_t x, const size_t y, const size_t z ) const
00696 {
00697     // since we use size_t here only a check for the upper bounds is needed
00698     if( x > m_nbPosX || y > m_nbPosY || z > m_nbPosZ )
00699     {
00700         return -1;
00701     }
00702     return x + y * ( m_nbPosX ) + z * ( m_nbPosX ) * ( m_nbPosY );
00703 }
00704 
00705 template< typename T >
00706 inline int WGridRegular3DTemplate< T >::getXVoxelCoord( const WGridRegular3DTemplate< T >::Vector3Type& pos ) const
00707 {
00708     // the current get*Voxel stuff is too complicated anyway
00709     Vector3Type v = m_transform.positionToGridSpace( pos );
00710 
00711     // this part could be refactored into an inline function
00712     T d;
00713     v[ 2 ] = std::modf( v[ 0 ] + T( 0.5 ), &d );
00714     int i = static_cast< int >( v[ 0 ] >= T( 0.0 ) && v[ 0 ] < m_nbPosX - T( 1.0 ) );
00715     return -1 + i * static_cast< int >( T( 1.0 ) + d );
00716 }
00717 
00718 template< typename T >
00719 inline int WGridRegular3DTemplate< T >::getYVoxelCoord( const WGridRegular3DTemplate< T >::Vector3Type& pos ) const
00720 {
00721     Vector3Type v = m_transform.positionToGridSpace( pos );
00722 
00723     T d;
00724     v[ 0 ] = std::modf( v[ 1 ] + T( 0.5 ), &d );
00725     int i = static_cast< int >( v[ 1 ] >= T( 0.0 ) && v[ 1 ] < m_nbPosY - T( 1.0 ) );
00726     return -1 + i * static_cast< int >( T( 1.0 ) + d );
00727 }
00728 
00729 template< typename T >
00730 inline int WGridRegular3DTemplate< T >::getZVoxelCoord( const WGridRegular3DTemplate< T >::Vector3Type& pos ) const
00731 {
00732     Vector3Type v = m_transform.positionToGridSpace( pos );
00733 
00734     T d;
00735     v[ 0 ] = std::modf( v[ 2 ] + T( 0.5 ), &d );
00736     int i = static_cast< int >( v[ 2 ] >= T( 0.0 ) && v[ 2 ] < m_nbPosZ - T( 1.0 ) );
00737     return -1 + i * static_cast< int >( T( 1.0 ) + d );
00738 }
00739 
00740 template< typename T >
00741 inline WVector3i WGridRegular3DTemplate< T >::getVoxelCoord( const WGridRegular3DTemplate< T >::Vector3Type& pos ) const
00742 {
00743     WVector3i result;
00744     result[0] = getXVoxelCoord( pos );
00745     result[1] = getYVoxelCoord( pos );
00746     result[2] = getZVoxelCoord( pos );
00747     return result;
00748 }
00749 
00750 template< typename T >
00751 inline size_t WGridRegular3DTemplate< T >::getCellId( const WGridRegular3DTemplate< T >::Vector3Type& pos, bool* success ) const
00752 {
00753     Vector3Type v = m_transform.positionToGridSpace( pos );
00754 
00755     T xCellId = floor( v[0] );
00756     T yCellId = floor( v[1] );
00757     T zCellId = floor( v[2] );
00758 
00759     *success = xCellId >= 0 && yCellId >=0 && zCellId >= 0 && xCellId < m_nbPosX - 1 && yCellId < m_nbPosY -1 && zCellId < m_nbPosZ -1;
00760 
00761     return xCellId + yCellId * ( m_nbPosX - 1 ) + zCellId * ( m_nbPosX - 1 ) * ( m_nbPosY - 1 );
00762 }
00763 
00764 template< typename T >
00765 inline typename WGridRegular3DTemplate< T >::CellVertexArray WGridRegular3DTemplate< T >::getCellVertexIds( size_t cellId ) const
00766 {
00767     typename WGridRegular3DTemplate< T >::CellVertexArray vertices;
00768     size_t minVertexIdZ =  cellId / ( ( m_nbPosX - 1 ) * ( m_nbPosY - 1 ) );
00769     size_t remainderXY = cellId - minVertexIdZ * ( ( m_nbPosX - 1 ) * ( m_nbPosY - 1 ) );
00770     size_t minVertexIdY = remainderXY  / ( m_nbPosX - 1 );
00771     size_t minVertexIdX = remainderXY % ( m_nbPosX - 1 );
00772 
00773     size_t minVertexId = minVertexIdX + minVertexIdY * m_nbPosX + minVertexIdZ * m_nbPosX * m_nbPosY;
00774 
00775     vertices[0] = minVertexId;
00776     vertices[1] = vertices[0] + 1;
00777     vertices[2] = minVertexId + m_nbPosX;
00778     vertices[3] = vertices[2] + 1;
00779     vertices[4] = minVertexId + m_nbPosX * m_nbPosY;
00780     vertices[5] = vertices[4] + 1;
00781     vertices[6] = vertices[4] + m_nbPosX;
00782     vertices[7] = vertices[6] + 1;
00783     return vertices;
00784 }
00785 
00786 template< typename T >
00787 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
00788 {
00789     typedef boost::shared_ptr< std::vector< Vector3Type > > ReturnType;
00790     ReturnType result = ReturnType( new std::vector< Vector3Type > );
00791     result->reserve( 8 );
00792     T halfMarginX = getOffsetX() / 2.0 - std::abs( margin );
00793     T halfMarginY = getOffsetY() / 2.0 - std::abs( margin );
00794     T halfMarginZ = getOffsetZ() / 2.0 - std::abs( margin );
00795     result->push_back( Vector3Type( point[0] - halfMarginX, point[1] - halfMarginY, point[2] - halfMarginZ ) ); // a
00796     result->push_back( Vector3Type( point[0] + halfMarginX, point[1] - halfMarginY, point[2] - halfMarginZ ) ); // b
00797     result->push_back( Vector3Type( point[0] + halfMarginX, point[1] - halfMarginY, point[2] + halfMarginZ ) ); // c
00798     result->push_back( Vector3Type( point[0] - halfMarginX, point[1] - halfMarginY, point[2] + halfMarginZ ) ); // d
00799     result->push_back( Vector3Type( point[0] - halfMarginX, point[1] + halfMarginY, point[2] - halfMarginZ ) ); // e
00800     result->push_back( Vector3Type( point[0] + halfMarginX, point[1] + halfMarginY, point[2] - halfMarginZ ) ); // f
00801     result->push_back( Vector3Type( point[0] + halfMarginX, point[1] + halfMarginY, point[2] + halfMarginZ ) ); // g
00802     result->push_back( Vector3Type( point[0] - halfMarginX, point[1] + halfMarginY, point[2] + halfMarginZ ) ); // h
00803     return result;
00804 }
00805 
00806 template< typename T >
00807 std::vector< size_t > WGridRegular3DTemplate< T >::getNeighbours( size_t id ) const
00808 {
00809     std::vector< size_t > neighbours;
00810     size_t x = id % m_nbPosX;
00811     size_t y = ( id / m_nbPosX ) % m_nbPosY;
00812     size_t z = id / ( m_nbPosX * m_nbPosY );
00813 
00814     if( x >= m_nbPosX || y >= m_nbPosY || z >= m_nbPosZ )
00815     {
00816         std::stringstream ss;
00817         ss << "This point: " << id << " is not part of this grid: ";
00818         ss << " nbPosX: " << m_nbPosX;
00819         ss << " nbPosY: " << m_nbPosY;
00820         ss << " nbPosZ: " << m_nbPosZ;
00821         throw WOutOfBounds( ss.str() );
00822     }
00823     // for every neighbour we must check if its not on the boundary, it will be skipped otherwise
00824     if( x > 0 )
00825     {
00826         neighbours.push_back( id - 1 );
00827     }
00828     if( x < m_nbPosX - 1 )
00829     {
00830         neighbours.push_back( id + 1 );
00831     }
00832     if( y > 0 )
00833     {
00834         neighbours.push_back( id - m_nbPosX );
00835     }
00836     if( y < m_nbPosY - 1 )
00837     {
00838         neighbours.push_back( id + m_nbPosX );
00839     }
00840     if( z > 0 )
00841     {
00842         neighbours.push_back( id - ( m_nbPosX * m_nbPosY ) );
00843     }
00844     if( z < m_nbPosZ - 1 )
00845     {
00846          neighbours.push_back( id + ( m_nbPosX * m_nbPosY ) );
00847     }
00848     return neighbours;
00849 }
00850 
00851 template< typename T >
00852 std::vector< size_t > WGridRegular3DTemplate< T >::getNeighbours27( size_t id ) const
00853 {
00854     std::vector< size_t > neighbours;
00855     size_t x = id % m_nbPosX;
00856     size_t y = ( id / m_nbPosX ) % m_nbPosY;
00857     size_t z = id / ( m_nbPosX * m_nbPosY );
00858 
00859     if( x >= m_nbPosX || y >= m_nbPosY || z >= m_nbPosZ )
00860     {
00861         std::stringstream ss;
00862         ss << "This point: " << id << " is not part of this grid: ";
00863         ss << " nbPosX: " << m_nbPosX;
00864         ss << " nbPosY: " << m_nbPosY;
00865         ss << " nbPosZ: " << m_nbPosZ;
00866         throw WOutOfBounds( ss.str() );
00867     }
00868     // for every neighbour we must check if its not on the boundary, it will be skipped otherwise
00869     std::vector< int >tempResult;
00870 
00871     tempResult.push_back( getVoxelNum( x    , y    , z ) );
00872     tempResult.push_back( getVoxelNum( x    , y - 1, z ) );
00873     tempResult.push_back( getVoxelNum( x    , y + 1, z ) );
00874     tempResult.push_back( getVoxelNum( x - 1, y    , z ) );
00875     tempResult.push_back( getVoxelNum( x - 1, y - 1, z ) );
00876     tempResult.push_back( getVoxelNum( x - 1, y + 1, z ) );
00877     tempResult.push_back( getVoxelNum( x + 1, y    , z ) );
00878     tempResult.push_back( getVoxelNum( x + 1, y - 1, z ) );
00879     tempResult.push_back( getVoxelNum( x + 1, y + 1, z ) );
00880 
00881     tempResult.push_back( getVoxelNum( x    , y    , z - 1 ) );
00882     tempResult.push_back( getVoxelNum( x    , y - 1, z - 1 ) );
00883     tempResult.push_back( getVoxelNum( x    , y + 1, z - 1 ) );
00884     tempResult.push_back( getVoxelNum( x - 1, y    , z - 1 ) );
00885     tempResult.push_back( getVoxelNum( x - 1, y - 1, z - 1 ) );
00886     tempResult.push_back( getVoxelNum( x - 1, y + 1, z - 1 ) );
00887     tempResult.push_back( getVoxelNum( x + 1, y    , z - 1 ) );
00888     tempResult.push_back( getVoxelNum( x + 1, y - 1, z - 1 ) );
00889     tempResult.push_back( getVoxelNum( x + 1, y + 1, z - 1 ) );
00890 
00891     tempResult.push_back( getVoxelNum( x    , y    , z + 1 ) );
00892     tempResult.push_back( getVoxelNum( x    , y - 1, z + 1 ) );
00893     tempResult.push_back( getVoxelNum( x    , y + 1, z + 1 ) );
00894     tempResult.push_back( getVoxelNum( x - 1, y    , z + 1 ) );
00895     tempResult.push_back( getVoxelNum( x - 1, y - 1, z + 1 ) );
00896     tempResult.push_back( getVoxelNum( x - 1, y + 1, z + 1 ) );
00897     tempResult.push_back( getVoxelNum( x + 1, y    , z + 1 ) );
00898     tempResult.push_back( getVoxelNum( x + 1, y - 1, z + 1 ) );
00899     tempResult.push_back( getVoxelNum( x + 1, y + 1, z + 1 ) );
00900 
00901     for( size_t k = 0; k < tempResult.size(); ++k )
00902     {
00903         if( tempResult[k] != -1 )
00904         {
00905             neighbours.push_back( tempResult[k] );
00906         }
00907     }
00908     return neighbours;
00909 }
00910 
00911 template< typename T >
00912 std::vector< size_t > WGridRegular3DTemplate< T >::getNeighboursRange( size_t id, size_t range ) const
00913 {
00914     std::vector< size_t > neighbours;
00915     size_t x = id % m_nbPosX;
00916     size_t y = ( id / m_nbPosX ) % m_nbPosY;
00917     size_t z = id / ( m_nbPosX * m_nbPosY );
00918 
00919     if( x >= m_nbPosX || y >= m_nbPosY || z >= m_nbPosZ )
00920     {
00921         std::stringstream ss;
00922         ss << "This point: " << id << " is not part of this grid: ";
00923         ss << " nbPosX: " << m_nbPosX;
00924         ss << " nbPosY: " << m_nbPosY;
00925         ss << " nbPosZ: " << m_nbPosZ;
00926         throw WOutOfBounds( ss.str() );
00927     }
00928     // for every neighbour we must check if its not on the boundary, it will be skipped otherwise
00929     std::vector< int >tempResult;
00930 
00931     for( size_t xx = x - range; xx < x + range + 1; ++xx )
00932     {
00933         for( size_t yy = y - range; yy < y + range + 1; ++yy )
00934         {
00935             for( size_t zz = z - range; zz < z + range + 1; ++zz )
00936             {
00937                 tempResult.push_back( getVoxelNum( xx, yy, zz ) );
00938             }
00939         }
00940     }
00941 
00942     for( size_t k = 0; k < tempResult.size(); ++k )
00943     {
00944         if( tempResult[k] != -1 )
00945         {
00946             neighbours.push_back( tempResult[k] );
00947         }
00948     }
00949     return neighbours;
00950 }
00951 
00952 template< typename T >
00953 std::vector< size_t > WGridRegular3DTemplate< T >::getNeighbours9XY( size_t id ) const
00954 {
00955     std::vector< size_t > neighbours;
00956     size_t x = id % m_nbPosX;
00957     size_t y = ( id / m_nbPosX ) % m_nbPosY;
00958     size_t z = id / ( m_nbPosX * m_nbPosY );
00959 
00960     if( x >= m_nbPosX || y >= m_nbPosY || z >= m_nbPosZ )
00961     {
00962         std::stringstream ss;
00963         ss << "This point: " << id << " is not part of this grid: ";
00964         ss << " nbPosX: " << m_nbPosX;
00965         ss << " nbPosY: " << m_nbPosY;
00966         ss << " nbPosZ: " << m_nbPosZ;
00967         throw WOutOfBounds( ss.str() );
00968     }
00969     // boundary check now happens in the getVoxelNum function
00970     int vNum;
00971 
00972     vNum = getVoxelNum( x - 1, y, z );
00973     if( vNum != -1 )
00974     {
00975         neighbours.push_back( vNum );
00976     }
00977     vNum = getVoxelNum( x - 1, y - 1, z );
00978     if( vNum != -1 )
00979     {
00980         neighbours.push_back( vNum );
00981     }
00982     vNum = getVoxelNum( x, y - 1, z );
00983     if( vNum != -1 )
00984     {
00985         neighbours.push_back( vNum );
00986     }
00987     vNum = getVoxelNum( x + 1, y - 1, z );
00988     if( vNum != -1 )
00989     {
00990         neighbours.push_back( vNum );
00991     }
00992     vNum = getVoxelNum( x + 1, y, z );
00993     if( vNum != -1 )
00994     {
00995         neighbours.push_back( vNum );
00996     }
00997     vNum = getVoxelNum( x + 1, y + 1, z );
00998     if( vNum != -1 )
00999     {
01000         neighbours.push_back( vNum );
01001     }
01002     vNum = getVoxelNum( x, y + 1, z );
01003     if( vNum != -1 )
01004     {
01005         neighbours.push_back( vNum );
01006     }
01007     vNum = getVoxelNum( x - 1, y + 1, z );
01008     if( vNum != -1 )
01009     {
01010         neighbours.push_back( vNum );
01011     }
01012     return neighbours;
01013 }
01014 
01015 template< typename T >
01016 std::vector< size_t > WGridRegular3DTemplate< T >::getNeighbours9YZ( size_t id ) const
01017 {
01018     std::vector< size_t > neighbours;
01019     size_t x = id % m_nbPosX;
01020     size_t y = ( id / m_nbPosX ) % m_nbPosY;
01021     size_t z = id / ( m_nbPosX * m_nbPosY );
01022 
01023     if( x >= m_nbPosX || y >= m_nbPosY || z >= m_nbPosZ )
01024     {
01025         std::stringstream ss;
01026         ss << "This point: " << id << " is not part of this grid: ";
01027         ss << " nbPosX: " << m_nbPosX;
01028         ss << " nbPosY: " << m_nbPosY;
01029         ss << " nbPosZ: " << m_nbPosZ;
01030         throw WOutOfBounds( ss.str() );
01031     }
01032     // boundary check now happens in the getVoxelNum function
01033     int vNum;
01034 
01035     vNum = getVoxelNum( x, y, z - 1 );
01036     if( vNum != -1 )
01037     {
01038         neighbours.push_back( vNum );
01039     }
01040     vNum = getVoxelNum( x, y - 1, z - 1 );
01041     if( vNum != -1 )
01042     {
01043         neighbours.push_back( vNum );
01044     }
01045     vNum = getVoxelNum( x, y - 1, z );
01046     if( vNum != -1 )
01047     {
01048         neighbours.push_back( vNum );
01049     }
01050     vNum = getVoxelNum( x, y - 1, z + 1 );
01051     if( vNum != -1 )
01052     {
01053         neighbours.push_back( vNum );
01054     }
01055     vNum = getVoxelNum( x, y, z + 1 );
01056     if( vNum != -1 )
01057     {
01058         neighbours.push_back( vNum );
01059     }
01060     vNum = getVoxelNum( x, y + 1, z + 1 );
01061     if( vNum != -1 )
01062     {
01063         neighbours.push_back( vNum );
01064     }
01065     vNum = getVoxelNum( x, y + 1, z );
01066     if( vNum != -1 )
01067     {
01068         neighbours.push_back( vNum );
01069     }
01070     vNum = getVoxelNum( x, y + 1, z - 1 );
01071     if( vNum != -1 )
01072     {
01073         neighbours.push_back( vNum );
01074     }
01075 
01076     return neighbours;
01077 }
01078 
01079 template< typename T >
01080 std::vector< size_t > WGridRegular3DTemplate< T >::getNeighbours9XZ( size_t id ) const
01081 {
01082     std::vector< size_t > neighbours;
01083     size_t x = id % m_nbPosX;
01084     size_t y = ( id / m_nbPosX ) % m_nbPosY;
01085     size_t z = id / ( m_nbPosX * m_nbPosY );
01086 
01087     if( x >= m_nbPosX || y >= m_nbPosY || z >= m_nbPosZ )
01088     {
01089         std::stringstream ss;
01090         ss << "This point: " << id << " is not part of this grid: ";
01091         ss << " nbPosX: " << m_nbPosX;
01092         ss << " nbPosY: " << m_nbPosY;
01093         ss << " nbPosZ: " << m_nbPosZ;
01094         throw WOutOfBounds( ss.str() );
01095     }
01096     // boundary check now happens in the getVoxelNum function
01097     int vNum;
01098 
01099     vNum = getVoxelNum( x, y, z - 1 );
01100     if( vNum != -1 )
01101     {
01102         neighbours.push_back( vNum );
01103     }
01104     vNum = getVoxelNum( x - 1, y, z - 1 );
01105     if( vNum != -1 )
01106     {
01107         neighbours.push_back( vNum );
01108     }
01109     vNum = getVoxelNum( x - 1, y, z );
01110     if( vNum != -1 )
01111     {
01112         neighbours.push_back( vNum );
01113     }
01114     vNum = getVoxelNum( x - 1, y, z + 1 );
01115     if( vNum != -1 )
01116     {
01117         neighbours.push_back( vNum );
01118     }
01119     vNum = getVoxelNum( x, y, z + 1 );
01120     if( vNum != -1 )
01121     {
01122         neighbours.push_back( vNum );
01123     }
01124     vNum = getVoxelNum( x + 1, y, z + 1 );
01125     if( vNum != -1 )
01126     {
01127         neighbours.push_back( vNum );
01128     }
01129     vNum = getVoxelNum( x + 1, y, z );
01130     if( vNum != -1 )
01131     {
01132         neighbours.push_back( vNum );
01133     }
01134     vNum = getVoxelNum( x + 1, y, z - 1 );
01135     if( vNum != -1 )
01136     {
01137         neighbours.push_back( vNum );
01138     }
01139 
01140     return neighbours;
01141 }
01142 
01143 template< typename T >
01144 inline bool WGridRegular3DTemplate< T >::encloses( WGridRegular3DTemplate< T >::Vector3Type const& pos ) const
01145 {
01146     Vector3Type v = m_transform.positionToGridSpace( pos );
01147 
01148     if( v[ 0 ] < T( 0.0 ) || v[ 0 ] >= static_cast< T >( m_nbPosX - 1 ) )
01149     {
01150         return false;
01151     }
01152     if( v[ 1 ] < T( 0.0 ) || v[ 1 ] >= static_cast< T >( m_nbPosY - 1 ) )
01153     {
01154         return false;
01155     }
01156     if( v[ 2 ] < T( 0.0 ) || v[ 2 ] >= static_cast< T >( m_nbPosZ - 1 ) )
01157     {
01158         return false;
01159     }
01160     return true;
01161 }
01162 
01163 template< typename T >
01164 inline bool WGridRegular3DTemplate< T >::isNotRotated() const
01165 {
01166     return m_transform.isNotRotated();
01167 }
01168 
01169 template< typename T >
01170 inline WGridTransformOrthoTemplate< T > const WGridRegular3DTemplate< T >::getTransform() const
01171 {
01172     return m_transform;
01173 }
01174 
01175 template< typename T >
01176 void WGridRegular3DTemplate< T >::initInformationProperties()
01177 {
01178     WPropInt xDim = m_infoProperties->addProperty( "X dimension: ",
01179                                                    "The x dimension of the grid.",
01180                                                    static_cast<int>( getNbCoordsX() ) );
01181     WPropInt yDim = m_infoProperties->addProperty( "Y dimension: ",
01182                                                    "The y dimension of the grid.",
01183                                                    static_cast<int>( getNbCoordsY() ) );
01184     WPropInt zDim = m_infoProperties->addProperty( "Z dimension: ",
01185                                                    "The z dimension of the grid.",
01186                                                    static_cast<int>( getNbCoordsZ() ) );
01187 
01188     WPropDouble xOffset = m_infoProperties->addProperty( "X offset: ",
01189                                                          "The distance between samples in x direction",
01190                                                          static_cast< double >( getOffsetX() ) );
01191     WPropDouble yOffset = m_infoProperties->addProperty( "Y offset: ",
01192                                                          "The distance between samples in y direction",
01193                                                          static_cast< double >( getOffsetY() ) );
01194     WPropDouble zOffset = m_infoProperties->addProperty( "Z offset: ",
01195                                                          "The distance between samples in z direction",
01196                                                          static_cast< double >( getOffsetZ() ) );
01197 
01198     WPropMatrix4X4 transformation = m_infoProperties->addProperty( "Transformation",
01199                                                                    "The transformation of this grid.",
01200                                                                    static_cast< WMatrix4d >( getTransform() ) );
01201 }
01202 
01203 // +----------------------+
01204 // | non-member functions |
01205 // +----------------------+
01206 
01207 /**
01208  * Convinience function returning all offsets per axis.
01209  * 0 : xAxis, 1 : yAxis, 2 : zAxis
01210  * \param grid The grid having the information.
01211  * \note Implementing this as NonMemberNonFriend was intentional.
01212  * \return Array of number of samples per axis.
01213  */
01214 template< typename T >
01215 inline boost::array< T, 3 > getOffsets( boost::shared_ptr< const WGridRegular3DTemplate< T > > grid )
01216 {
01217     boost::array< T, 3 > result = { { grid->getOffsetX(), grid->getOffsetY(), grid->getOffsetZ() } }; // NOLINT curly braces
01218     return result;
01219 }
01220 
01221 /**
01222  * Convinience function returning all number coords per axis.
01223  * 0 : xAxis, 1 : yAxis, 2 : zAxis
01224  * \param grid The grid having the information.
01225  * \note Implementing this as NonMemberNonFriend was intentional.
01226  * \return Array of number of samples per axis.
01227  */
01228 template< typename T >
01229 inline boost::array< unsigned int, 3 > getNbCoords( boost::shared_ptr< const WGridRegular3DTemplate< T > > grid )
01230 {
01231     boost::array< unsigned int, 3 > result = { { grid->getNbCoordsX(), grid->getNbCoordsY(), grid->getNbCoordsZ() } }; // NOLINT curly braces
01232     return result;
01233 }
01234 
01235 /**
01236  * Convinience function returning all axis directions.
01237  * 0 : xAxis, 1 : yAxis, 2 : zAxis
01238  * \param grid The grid having the information.
01239  * \note Implementing this as NonMemberNonFriend was intentional.
01240  * \return The direction of each axis as array
01241  */
01242 template< typename T >
01243 inline boost::array< typename WGridRegular3DTemplate< T >::Vector3Type, 3 > getDirections( boost::shared_ptr< const WGridRegular3DTemplate< T > > grid ) // NOLINT -- too long line
01244 {
01245     boost::array< typename WGridRegular3DTemplate< T >::Vector3Type, 3 > result = { { grid->getDirectionX(), grid->getDirectionY(), grid->getDirectionZ() } }; // NOLINT curly braces
01246     return result;
01247 }
01248 
01249 /**
01250  * Convinience function returning all axis unit directions.
01251  * 0 : xAxis, 1 : yAxis, 2 : zAxis
01252  * \param grid The grid having the information.
01253  * \note Implementing this as NonMemberNonFriend was intentional.
01254  * \return The direction of each axis as array
01255  */
01256 template< typename T >
01257 inline boost::array< typename WGridRegular3DTemplate< T >::Vector3Type, 3 > getUnitDirections( boost::shared_ptr< const WGridRegular3DTemplate< T > > grid ) // NOLINT -- too long line
01258 {
01259     boost::array< typename WGridRegular3DTemplate< T >::Vector3Type, 3 > result = { { grid->getUnitDirectionX(), grid->getUnitDirectionY(), grid->getUnitDirectionZ() } }; // NOLINT curly braces
01260     return result;
01261 }
01262 
01263 #endif  // WGRIDREGULAR3D_H