OpenWalnut 1.2.5
|
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