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