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 <utility>
00029 #include <vector>
00030 
00031 #include <boost/array.hpp>
00032 #include <boost/shared_ptr.hpp>
00033 
00034 #include <osg/Matrix>
00035 #include <osg/Vec3>
00036 
00037 #include "../common/math/WMatrix.h"
00038 #include "../common/math/linearAlgebra/WLinearAlgebra.h"
00039 #include "../common/WBoundingBox.h"
00040 #include "../common/WCondition.h"
00041 #include "../common/WDefines.h"
00042 #include "WExportDataHandler.h"
00043 #include "WGrid.h"
00044 #include "WGridTransformOrtho.h"
00045 
00046 /**
00047  * A grid that has parallelepiped cells which all have the same proportion. I.e.
00048  * the samples along a single axis are equidistant. The distance of samples may
00049  * vary between axes.
00050  *
00051  * \warning Positions on the upper bounddaries in x, y and z are considered outside the grid.
00052  * \ingroup dataHandler
00053  */
00054 class OWDATAHANDLER_EXPORT WGridRegular3D : public WGrid // NOLINT
00055 {
00056     /**
00057      * Only test are allowed as friends.
00058      */
00059     friend class WGridRegular3DTest;
00060 public:
00061     /**
00062      * Convenience typedef for a boost::shared_ptr< WGridRegular3D >.
00063      */
00064     typedef boost::shared_ptr< WGridRegular3D > SPtr;
00065 
00066     /**
00067      * Convenience typedef for a boost::shared_ptr< const WGridRegular3D >.
00068      */
00069     typedef boost::shared_ptr< const WGridRegular3D > ConstSPtr;
00070 
00071     /**
00072      * Defines the number of samples in each coordinate direction as ints,
00073      * and the transformation of the grid via a grid transform.
00074      *
00075      * \param nbPosX number of positions along first axis
00076      * \param nbPosY number of positions along second axis
00077      * \param nbPosZ number of positions along third axis
00078      * \param transform a grid transformation
00079      */
00080     WGridRegular3D( unsigned int nbPosX, unsigned int nbPosY, unsigned int nbPosZ,
00081                     WGridTransformOrtho const transform = WGridTransformOrtho() );
00082 
00083     /**
00084      * Returns the number of samples in x direction.
00085      * \return The number of samples in x direction.
00086      */
00087     unsigned int getNbCoordsX() const;
00088 
00089     /**
00090      * Returns the number of samples in y direction.
00091      * \return The number of samples in y direction.
00092      */
00093     unsigned int getNbCoordsY() const;
00094 
00095     /**
00096      * Returns the number of samples in z direction.
00097      * \return The number of samples in z direction.
00098      */
00099     unsigned int getNbCoordsZ() const;
00100 
00101     /**
00102      * Returns the distance between samples in x direction.
00103      * \return The distance between samples in x direction.
00104      */
00105     double getOffsetX() const;
00106 
00107     /**
00108      * Returns the distance between samples in y direction.
00109      * \return The distance between samples in y direction.
00110      */
00111     double getOffsetY() const;
00112 
00113     /**
00114      * Returns the distance between samples in z direction.
00115      * \return The distance between samples in z direction.
00116      */
00117     double getOffsetZ() const;
00118 
00119     /**
00120      * Returns the vector determining the direction of samples in x direction.
00121      * Adding this vector to a grid position in world coordinates yields the position of the next sample
00122      * along the grids (world coordinate) x-axis.
00123      * \return The vector determining the direction of samples in x direction.
00124      */
00125     WVector3d getDirectionX() const;
00126 
00127     /**
00128      * Returns the vector determining the direction of samples in y direction.
00129      * Adding this vector to a grid position in world coordinates yields the position of the next sample
00130      * along the grids (world coordinate) y-axis.
00131      * \return The vector determining the direction of samples in y direction.
00132      */
00133     WVector3d getDirectionY() const;
00134 
00135     /**
00136      * Returns the vector determining the direction of samples in z direction.
00137      * Adding this vector to a grid position in world coordinates yields the position of the next sample
00138      * along the grids (world coordinate) z-axis.
00139      * \return The vector determining the direction of samples in z direction.
00140      */
00141     WVector3d getDirectionZ() const;
00142 
00143     /**
00144      * Returns the vector determining the unit (normalized) direction of samples in x direction.
00145      * \return The vector determining the unit (normalized) direction of samples in x direction.
00146      */
00147     WVector3d getUnitDirectionX() const;
00148 
00149     /**
00150      * Returns the vector determining the unit (normalized) direction of samples in y direction.
00151      * \return The vector determining the unit (normalized) direction of samples in y direction.
00152      */
00153     WVector3d getUnitDirectionY() const;
00154 
00155     /**
00156      * Returns the vector determining the unit (normalized) direction of samples in z direction.
00157      * \return The vector determining the unit (normalized) direction of samples in z direction.
00158      */
00159     WVector3d getUnitDirectionZ() const;
00160 
00161     /**
00162      * Returns the position of the origin of the grid.
00163      * \return The position of the origin of the grid.
00164      */
00165     WPosition getOrigin() const;
00166 
00167     /**
00168      * Returns a 4x4 matrix that represents the grid's transformation.
00169      * \return The grid's transformation.
00170      */
00171     WMatrix< double > getTransformationMatrix() const;
00172 
00173     /**
00174      * \copybrief WGrid::getBoundingBox()
00175      * \return \copybrief WGrid::getBoundingBox()
00176      */
00177     WBoundingBox getBoundingBox() const;
00178 
00179     /**
00180      * Returns the i-th position on the grid.
00181      * \param i id of position to be obtained
00182      * \return i-th position of the grid.
00183      */
00184     WPosition getPosition( unsigned int i ) const;
00185 
00186     /**
00187      * Returns the position that is the iX-th in x direction, the iY-th in
00188      * y direction and the iZ-th in z direction.
00189      * \param iX id along first axis of position to be obtained
00190      * \param iY id along second axis of position to be obtained
00191      * \param iZ id along third axis of position to be obtained
00192      * \return Position (iX,iY,iZ)
00193      */
00194     WPosition getPosition( unsigned int iX, unsigned int iY, unsigned int iZ ) const;
00195 
00196     /**
00197      * Transforms world coordinates to texture coordinates.
00198      * \param point The point with these coordinates will be transformed.
00199      * \return point transformed into texture coordinate system
00200      */
00201     WVector3d worldCoordToTexCoord( WPosition point );
00202 
00203     /**
00204      * Transforms texture coordinates to world coordinates.
00205      * \param coords The point with these coordinates will be transformed.
00206      * \return coords transformed into world coordinate system.
00207      */
00208     WPosition texCoordToWorldCoord( WVector3d coords );
00209 
00210     /**
00211      * Returns the i'th voxel where the given position belongs too.
00212      *
00213      * A voxel is a cuboid which surrounds a point on the grid.
00214      *
00215      * \verbatim
00216       Voxel:
00217                      ______________ ____ (0.5, 0.5, 0.5)
00218                     /:            /|
00219                    / :           / |
00220                   /  :          /  |
00221                  /   :         /   |
00222                _/____:_ ___ __/    |
00223                 |    :        |    |
00224                 |    :    *<--|--------- grid point (0, 0, 0)
00225                 |    :........|....|__
00226          dz == 1|   /         |   /
00227                 |  /          |  / dy == 1
00228                 | /           | /
00229                _|/____________|/__
00230                 |<- dx == 1 ->|
00231          -0.5,-0.5,-0.5
00232        \endverbatim
00233      *
00234      * Please note the first voxel has only 1/8 of the size a normal voxel
00235      * would have since all positions outside the grid do not belong
00236      * to any voxel. Note: a cell is different to a voxel in terms of position.
00237      * A voxel has a grid point as center whereas a cell has grid points as
00238      * corners.
00239      * \param pos Position for which we want to have the voxel number.
00240      *
00241      * \return Voxel number or -1 if the position refers to a point outside of
00242      * the grid.
00243      */
00244     int getVoxelNum( const WPosition& pos ) const;
00245 
00246     /**
00247      * returns the voxel index for a given discrete position in the grid
00248      *
00249      * \param x Position for which we want to have the voxel number.
00250      * \param y Position for which we want to have the voxel number.
00251      * \param z Position for which we want to have the voxel number.
00252      *
00253      * \return Voxel number or -1 if the position refers to a point outside of
00254      * the grid.
00255      */
00256     int getVoxelNum( const size_t x, const size_t y, const size_t z ) const;
00257 
00258     /**
00259      * Computes the X coordinate of that voxel that contains the
00260      * position pos.
00261      *
00262      * \param pos The position which selects the voxel for which the X
00263      * coordinate is computed.
00264      *
00265      * \return The X coordinate or -1 if pos refers to point outside of the
00266      * grid.
00267      */
00268     int getXVoxelCoord( const WPosition& pos ) const;
00269 
00270     /**
00271      * Computes the Y coordinate of that voxel that contains the
00272      * position pos.
00273      *
00274      * \param pos The position which selects the voxel for which the Y
00275      * coordinate is computed.
00276      *
00277      * \return The Y coordinate or -1 if pos refers to point outside of the
00278      * grid.
00279      */
00280     int getYVoxelCoord( const WPosition& pos ) const;
00281 
00282     /**
00283      * Computes the Z coordinate of that voxel that contains the
00284      * position pos.
00285      *
00286      * \param pos The position which selects the voxel for which the Z
00287      * coordinate is computed.
00288      *
00289      * \return The Z coordinate or -1 if pos refers to point outside of the
00290      * grid.
00291      */
00292     int getZVoxelCoord( const WPosition& pos ) const;
00293 
00294     /**
00295      * Computes the X coordinate of that voxel that contains the
00296      * position pos. Works on rotated grids.
00297      *
00298      * \param pos The position which selects the voxel for which the X
00299      * coordinate is computed.
00300      *
00301      * \return The X coordinate or -1 if pos refers to point outside of the
00302      * grid.
00303      */
00304     int getXVoxelCoordRotated( const WPosition& pos ) const;
00305 
00306     /**
00307      * Computes the Y coordinate of that voxel that contains the
00308      * position pos. Works on rotated grids.
00309      *
00310      * \param pos The position which selects the voxel for which the Y
00311      * coordinate is computed.
00312      *
00313      * \return The Y coordinate or -1 if pos refers to point outside of the
00314      * grid.
00315      */
00316     int getYVoxelCoordRotated( const WPosition& pos ) const;
00317 
00318     /**
00319      * Computes the Z coordinate of that voxel that contains the
00320      * position pos. Works on rotated grids.
00321      *
00322      * \param pos The position which selects the voxel for which the Z
00323      * coordinate is computed.
00324      *
00325      * \return The Z coordinate or -1 if pos refers to point outside of the
00326      * grid.
00327      */
00328     int getZVoxelCoordRotated( const WPosition& pos ) const;
00329 
00330     /**
00331      * Computes the voxel coordinates of that voxel which contains
00332      * the position pos.
00333      *
00334      * \param pos The position selecting the voxel.
00335      *
00336      * \return A vector of ints where the first component is the X voxel
00337      * coordinate, the second the Y component voxel coordinate and the last the
00338      * Z component of the voxel coordinate. If the selecting position is
00339      * outside of the grid then -1 -1 -1 is returned.
00340      */
00341     WValue< int > getVoxelCoord( const WPosition& pos ) const;
00342 
00343     /**
00344      * Computes the id of the cell containing the position pos. Note that the upper
00345      * bound of the grid does not belong to any cell
00346      *
00347      * \param pos The position selecting the cell.
00348      * \param success True if the position pos is inside the grid.
00349      *
00350      * \return id of the containing the position.
00351      */
00352     size_t getCellId( const WPosition& pos, bool* success ) const;
00353 
00354     /**
00355      * Computes the ids of the vertices of a cell given by its id.
00356      *
00357      * \param cellId The id of the cell we want to know ther vertices of.
00358      *
00359      * \return Ids of vertices belonging to cell with given cellId.
00360 
00361      * \verbatim
00362         z-axis  y-axis
00363         |      /
00364         | 6___/_7
00365         |/:    /|
00366         4_:___5 |
00367         | :...|.|
00368         |.2   | 3
00369         |_____|/ ____x-axis
00370        0      1
00371        \endverbatim
00372      *
00373      */
00374     std::vector< size_t > getCellVertexIds( const size_t cellId ) const;
00375 
00376     /**
00377      * Computes the vertices for a voxel cuboid around the given point:
00378      *
00379      * \verbatim
00380         z-axis  y-axis
00381         |      /
00382         | h___/_g
00383         |/:    /|
00384         d_:___c |
00385         | :...|.|
00386         |.e   | f
00387         |_____|/ ____x-axis
00388        a      b
00389        \endverbatim
00390      *
00391      * As you can see the order of the points is: a, b, c, d, e, f, g, h.
00392      *
00393      * \param point Center of the cuboid which must not necesarrily be a point
00394      * of the grid.
00395      * \param margin If you need to shrink the Voxel put here the delta > 0.
00396      *
00397      * \return Reference to a list of vertices which are the corner points of
00398      * the cube. Note this must not be a voxel, but has the same size of the an
00399      * voxel. If you need voxels at grid positions fill this function with
00400      * voxel center positions aka grid points.
00401      */
00402     boost::shared_ptr< std::vector< WPosition > > getVoxelVertices( const WPosition& point,
00403                                                                            const double margin = 0.0 ) const;
00404 
00405     /**
00406      * Return the list of neighbour voxels.
00407      *
00408      * \throw WOutOfBounds If the voxel id is outside of the grid.
00409      *
00410      * \param id Number of the voxel for which the neighbours should be computed
00411      *
00412      * \return Vector of voxel ids which are all neighboured
00413      */
00414     std::vector< size_t > getNeighbours( size_t id ) const;
00415 
00416     /**
00417      * Return the list of all neighbour voxels.
00418      *
00419      * \throw WOutOfBounds If the voxel id is outside of the grid.
00420      *
00421      * \param id Number of the voxel for which the neighbours should be computed
00422      *
00423      * \return Vector of voxel ids which are all neighboured
00424      */
00425     std::vector< size_t > getNeighbours27( size_t id ) const;
00426 
00427     /**
00428      * Return the list of all neighbour voxels.
00429      *
00430      * \throw WOutOfBounds If the voxel id is outside of the grid.
00431      *
00432      * \param id Number of the voxel for which the neighbours should be computed
00433      *
00434      * \return Vector of voxel ids which are all neighboured along the XY plane
00435      */
00436     std::vector< size_t > getNeighbours9XY( size_t id ) const;
00437 
00438     /**
00439      * Return the list of all neighbour voxels.
00440      *
00441      * \throw WOutOfBounds If the voxel id is outside of the grid.
00442      *
00443      * \param id Number of the voxel for which the neighbours should be computed
00444      *
00445      * \return Vector of voxel ids which are all neighboured along the YZ plane
00446      */
00447     std::vector< size_t > getNeighbours9YZ( size_t id ) const;
00448 
00449     /**
00450      * Return the list of all neighbour voxels.
00451      *
00452      * \throw WOutOfBounds If the voxel id is outside of the grid.
00453      *
00454      * \param id Number of the voxel for which the neighbours should be computed
00455      *
00456      * \return Vector of voxel ids which are all neighboured along the XZ plane
00457      */
00458     std::vector< size_t > getNeighbours9XZ( size_t id ) const;
00459 
00460     /**
00461      * Decides whether a certain position is inside this grid or not.
00462      *
00463      * \param pos Position to test
00464      *
00465      * \return True if and only if the given point is inside or on boundary of this grid, otherwise false.
00466      */
00467     bool encloses( const WPosition& pos ) const;
00468 
00469     /**
00470      * Return whether the transformations of the grid are only translation and/or scaling
00471      * \return Transformation does not contain rotation?
00472      */
00473     bool isNotRotated() const;
00474 
00475     /**
00476      * Returns the transformation used by this grid.
00477      * \return The transformation.
00478      */
00479     WGridTransformOrtho const getTransform() const;
00480 
00481 protected:
00482 
00483 private:
00484     /**
00485      * Computes for the n'th component of the voxel coordinate where the voxel
00486      * contains the position pos.
00487      *
00488      * \param pos The position for which the n'th component of the voxel
00489      * coordinates should be computed.
00490      * \param axis The number of the component. (0 == x-axis, 1 == y-axis, ...)
00491      *
00492      * \return The n'th component of the voxel coordinate
00493      */
00494     int getNVoxelCoord( const WPosition& pos, size_t axis ) const;
00495 
00496     /**
00497      * Adds the specific information of this grid type to the
00498      * informational properties.
00499      */
00500     void initInformationProperties();
00501 
00502     unsigned int m_nbPosX; //!< Number of positions in x direction
00503     unsigned int m_nbPosY; //!< Number of positions in y direction
00504     unsigned int m_nbPosZ; //!< Number of positions in z direction
00505 
00506     //! The grid's transformation.
00507     WGridTransformOrtho const m_transform;
00508 };
00509 
00510 /**
00511  * Convinience function returning all offsets per axis.
00512  * 0 : xAxis, 1 : yAxis, 2 : zAxis
00513  * \param grid The grid having the information.
00514  * \note Implementing this as NonMemberNonFriend was intentional.
00515  * \return Array of number of samples per axis.
00516  */
00517 inline boost::array< double, 3 > getOffsets( boost::shared_ptr< const WGridRegular3D > grid )
00518 {
00519     boost::array< double, 3 > result = { { grid->getOffsetX(), grid->getOffsetY(), grid->getOffsetZ() } }; // NOLINT curly braces
00520     return result;
00521 }
00522 
00523 /**
00524  * Convinience function returning all number coords per axis.
00525  * 0 : xAxis, 1 : yAxis, 2 : zAxis
00526  * \param grid The grid having the information.
00527  * \note Implementing this as NonMemberNonFriend was intentional.
00528  * \return Array of number of samples per axis.
00529  */
00530 inline boost::array< unsigned int, 3 > getNbCoords( boost::shared_ptr< const WGridRegular3D > grid )
00531 {
00532     boost::array< unsigned int, 3 > result = { { grid->getNbCoordsX(), grid->getNbCoordsY(), grid->getNbCoordsZ() } }; // NOLINT curly braces
00533     return result;
00534 }
00535 
00536 /**
00537  * Convinience function returning all axis directions.
00538  * 0 : xAxis, 1 : yAxis, 2 : zAxis
00539  * \param grid The grid having the information.
00540  * \note Implementing this as NonMemberNonFriend was intentional.
00541  * \return The direction of each axis as array
00542  */
00543 inline boost::array< WVector3d, 3 > getDirections( boost::shared_ptr< const WGridRegular3D > grid )
00544 {
00545     boost::array< WVector3d, 3 > result = { { grid->getDirectionX(), grid->getDirectionY(), grid->getDirectionZ() } }; // NOLINT curly braces
00546     return result;
00547 }
00548 
00549 /**
00550  * Convinience function returning all axis unit directions.
00551  * 0 : xAxis, 1 : yAxis, 2 : zAxis
00552  * \param grid The grid having the information.
00553  * \note Implementing this as NonMemberNonFriend was intentional.
00554  * \return The direction of each axis as array
00555  */
00556 inline boost::array< WVector3d, 3 > getUnitDirections( boost::shared_ptr< const WGridRegular3D > grid )
00557 {
00558     boost::array< WVector3d, 3 > result = { { grid->getUnitDirectionX(), grid->getUnitDirectionY(), grid->getUnitDirectionZ() } }; // NOLINT curly braces
00559     return result;
00560 }
00561 
00562 inline unsigned int WGridRegular3D::getNbCoordsX() const
00563 {
00564     return m_nbPosX;
00565 }
00566 
00567 inline unsigned int WGridRegular3D::getNbCoordsY() const
00568 {
00569     return m_nbPosY;
00570 }
00571 
00572 inline unsigned int WGridRegular3D::getNbCoordsZ() const
00573 {
00574     return m_nbPosZ;
00575 }
00576 
00577 inline double WGridRegular3D::getOffsetX() const
00578 {
00579     return m_transform.getOffsetX();
00580 }
00581 
00582 inline double WGridRegular3D::getOffsetY() const
00583 {
00584     return m_transform.getOffsetY();
00585 }
00586 
00587 inline double WGridRegular3D::getOffsetZ() const
00588 {
00589     return m_transform.getOffsetZ();
00590 }
00591 
00592 inline WVector3d WGridRegular3D::getUnitDirectionX() const
00593 {
00594     return m_transform.getUnitDirectionX();
00595 }
00596 
00597 inline WVector3d WGridRegular3D::getUnitDirectionY() const
00598 {
00599     return m_transform.getUnitDirectionY();
00600 }
00601 
00602 inline WVector3d WGridRegular3D::getUnitDirectionZ() const
00603 {
00604     return m_transform.getUnitDirectionZ();
00605 }
00606 
00607 inline WVector3d WGridRegular3D::getDirectionX() const
00608 {
00609     return m_transform.getDirectionX();
00610 }
00611 
00612 inline WVector3d WGridRegular3D::getDirectionY() const
00613 {
00614     return m_transform.getDirectionY();
00615 }
00616 
00617 inline WVector3d WGridRegular3D::getDirectionZ() const
00618 {
00619     return m_transform.getDirectionZ();
00620 }
00621 
00622 inline WPosition WGridRegular3D::getOrigin() const
00623 {
00624     return m_transform.getOrigin();
00625 }
00626 
00627 inline WGridTransformOrtho const WGridRegular3D::getTransform() const
00628 {
00629     return m_transform;
00630 }
00631 
00632 inline WMatrix< double > WGridRegular3D::getTransformationMatrix() const
00633 {
00634     return m_transform.getTransformationMatrix();
00635 }
00636 #endif  // WGRIDREGULAR3D_H
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends