OpenWalnut  1.2.5
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
WGridRegular3D.h
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #ifndef WGRIDREGULAR3D_H
26 #define WGRIDREGULAR3D_H
27 
28 #include <utility>
29 #include <vector>
30 
31 #include <boost/array.hpp>
32 #include <boost/shared_ptr.hpp>
33 
34 #include <osg/Matrix>
35 #include <osg/Vec3>
36 
37 #include "../common/math/WMatrix.h"
38 #include "../common/math/linearAlgebra/WLinearAlgebra.h"
39 #include "../common/WBoundingBox.h"
40 #include "../common/WCondition.h"
41 #include "../common/WDefines.h"
42 #include "WExportDataHandler.h"
43 #include "WGrid.h"
44 #include "WGridTransformOrtho.h"
45 
46 /**
47  * A grid that has parallelepiped cells which all have the same proportion. I.e.
48  * the samples along a single axis are equidistant. The distance of samples may
49  * vary between axes.
50  *
51  * \warning Positions on the upper bounddaries in x, y and z are considered outside the grid.
52  * \ingroup dataHandler
53  */
54 class OWDATAHANDLER_EXPORT WGridRegular3D : public WGrid // NOLINT
55 {
56  /**
57  * Only test are allowed as friends.
58  */
59  friend class WGridRegular3DTest;
60 public:
61  /**
62  * Convenience typedef for a boost::shared_ptr< WGridRegular3D >.
63  */
64  typedef boost::shared_ptr< WGridRegular3D > SPtr;
65 
66  /**
67  * Convenience typedef for a boost::shared_ptr< const WGridRegular3D >.
68  */
69  typedef boost::shared_ptr< const WGridRegular3D > ConstSPtr;
70 
71  /**
72  * Defines the number of samples in each coordinate direction as ints,
73  * and the transformation of the grid via a grid transform.
74  *
75  * \param nbPosX number of positions along first axis
76  * \param nbPosY number of positions along second axis
77  * \param nbPosZ number of positions along third axis
78  * \param transform a grid transformation
79  */
80  WGridRegular3D( unsigned int nbPosX, unsigned int nbPosY, unsigned int nbPosZ,
81  WGridTransformOrtho const transform = WGridTransformOrtho() );
82 
83  /**
84  * Returns the number of samples in x direction.
85  * \return The number of samples in x direction.
86  */
87  unsigned int getNbCoordsX() const;
88 
89  /**
90  * Returns the number of samples in y direction.
91  * \return The number of samples in y direction.
92  */
93  unsigned int getNbCoordsY() const;
94 
95  /**
96  * Returns the number of samples in z direction.
97  * \return The number of samples in z direction.
98  */
99  unsigned int getNbCoordsZ() const;
100 
101  /**
102  * Returns the distance between samples in x direction.
103  * \return The distance between samples in x direction.
104  */
105  double getOffsetX() const;
106 
107  /**
108  * Returns the distance between samples in y direction.
109  * \return The distance between samples in y direction.
110  */
111  double getOffsetY() const;
112 
113  /**
114  * Returns the distance between samples in z direction.
115  * \return The distance between samples in z direction.
116  */
117  double getOffsetZ() const;
118 
119  /**
120  * Returns the vector determining the direction of samples in x direction.
121  * Adding this vector to a grid position in world coordinates yields the position of the next sample
122  * along the grids (world coordinate) x-axis.
123  * \return The vector determining the direction of samples in x direction.
124  */
125  WVector3d getDirectionX() const;
126 
127  /**
128  * Returns the vector determining the direction of samples in y direction.
129  * Adding this vector to a grid position in world coordinates yields the position of the next sample
130  * along the grids (world coordinate) y-axis.
131  * \return The vector determining the direction of samples in y direction.
132  */
133  WVector3d getDirectionY() const;
134 
135  /**
136  * Returns the vector determining the direction of samples in z direction.
137  * Adding this vector to a grid position in world coordinates yields the position of the next sample
138  * along the grids (world coordinate) z-axis.
139  * \return The vector determining the direction of samples in z direction.
140  */
141  WVector3d getDirectionZ() const;
142 
143  /**
144  * Returns the vector determining the unit (normalized) direction of samples in x direction.
145  * \return The vector determining the unit (normalized) direction of samples in x direction.
146  */
147  WVector3d getUnitDirectionX() const;
148 
149  /**
150  * Returns the vector determining the unit (normalized) direction of samples in y direction.
151  * \return The vector determining the unit (normalized) direction of samples in y direction.
152  */
153  WVector3d getUnitDirectionY() const;
154 
155  /**
156  * Returns the vector determining the unit (normalized) direction of samples in z direction.
157  * \return The vector determining the unit (normalized) direction of samples in z direction.
158  */
159  WVector3d getUnitDirectionZ() const;
160 
161  /**
162  * Returns the position of the origin of the grid.
163  * \return The position of the origin of the grid.
164  */
165  WPosition getOrigin() const;
166 
167  /**
168  * Returns a 4x4 matrix that represents the grid's transformation.
169  * \return The grid's transformation.
170  */
171  WMatrix< double > getTransformationMatrix() const;
172 
173  /**
174  * \copybrief WGrid::getBoundingBox()
175  * \return \copybrief WGrid::getBoundingBox()
176  */
178 
179  /**
180  * Returns the i-th position on the grid.
181  * \param i id of position to be obtained
182  * \return i-th position of the grid.
183  */
184  WPosition getPosition( unsigned int i ) const;
185 
186  /**
187  * Returns the position that is the iX-th in x direction, the iY-th in
188  * y direction and the iZ-th in z direction.
189  * \param iX id along first axis of position to be obtained
190  * \param iY id along second axis of position to be obtained
191  * \param iZ id along third axis of position to be obtained
192  * \return Position (iX,iY,iZ)
193  */
194  WPosition getPosition( unsigned int iX, unsigned int iY, unsigned int iZ ) const;
195 
196  /**
197  * Transforms world coordinates to texture coordinates.
198  * \param point The point with these coordinates will be transformed.
199  * \return point transformed into texture coordinate system
200  */
201  WVector3d worldCoordToTexCoord( WPosition point );
202 
203  /**
204  * Transforms texture coordinates to world coordinates.
205  * \param coords The point with these coordinates will be transformed.
206  * \return coords transformed into world coordinate system.
207  */
208  WPosition texCoordToWorldCoord( WVector3d coords );
209 
210  /**
211  * Returns the i'th voxel where the given position belongs too.
212  *
213  * A voxel is a cuboid which surrounds a point on the grid.
214  *
215  * \verbatim
216  Voxel:
217  ______________ ____ (0.5, 0.5, 0.5)
218  /: /|
219  / : / |
220  / : / |
221  / : / |
222  _/____:_ ___ __/ |
223  | : | |
224  | : *<--|--------- grid point (0, 0, 0)
225  | :........|....|__
226  dz == 1| / | /
227  | / | / dy == 1
228  | / | /
229  _|/____________|/__
230  |<- dx == 1 ->|
231  -0.5,-0.5,-0.5
232  \endverbatim
233  *
234  * Please note the first voxel has only 1/8 of the size a normal voxel
235  * would have since all positions outside the grid do not belong
236  * to any voxel. Note: a cell is different to a voxel in terms of position.
237  * A voxel has a grid point as center whereas a cell has grid points as
238  * corners.
239  * \param pos Position for which we want to have the voxel number.
240  *
241  * \return Voxel number or -1 if the position refers to a point outside of
242  * the grid.
243  */
244  int getVoxelNum( const WPosition& pos ) const;
245 
246  /**
247  * returns the voxel index for a given discrete position in the grid
248  *
249  * \param x Position for which we want to have the voxel number.
250  * \param y Position for which we want to have the voxel number.
251  * \param z Position for which we want to have the voxel number.
252  *
253  * \return Voxel number or -1 if the position refers to a point outside of
254  * the grid.
255  */
256  int getVoxelNum( const size_t x, const size_t y, const size_t z ) const;
257 
258  /**
259  * Computes the X coordinate of that voxel that contains the
260  * position pos.
261  *
262  * \param pos The position which selects the voxel for which the X
263  * coordinate is computed.
264  *
265  * \return The X coordinate or -1 if pos refers to point outside of the
266  * grid.
267  */
268  int getXVoxelCoord( const WPosition& pos ) const;
269 
270  /**
271  * Computes the Y coordinate of that voxel that contains the
272  * position pos.
273  *
274  * \param pos The position which selects the voxel for which the Y
275  * coordinate is computed.
276  *
277  * \return The Y coordinate or -1 if pos refers to point outside of the
278  * grid.
279  */
280  int getYVoxelCoord( const WPosition& pos ) const;
281 
282  /**
283  * Computes the Z coordinate of that voxel that contains the
284  * position pos.
285  *
286  * \param pos The position which selects the voxel for which the Z
287  * coordinate is computed.
288  *
289  * \return The Z coordinate or -1 if pos refers to point outside of the
290  * grid.
291  */
292  int getZVoxelCoord( const WPosition& pos ) const;
293 
294  /**
295  * Computes the X coordinate of that voxel that contains the
296  * position pos. Works on rotated grids.
297  *
298  * \param pos The position which selects the voxel for which the X
299  * coordinate is computed.
300  *
301  * \return The X coordinate or -1 if pos refers to point outside of the
302  * grid.
303  */
304  int getXVoxelCoordRotated( const WPosition& pos ) const;
305 
306  /**
307  * Computes the Y coordinate of that voxel that contains the
308  * position pos. Works on rotated grids.
309  *
310  * \param pos The position which selects the voxel for which the Y
311  * coordinate is computed.
312  *
313  * \return The Y coordinate or -1 if pos refers to point outside of the
314  * grid.
315  */
316  int getYVoxelCoordRotated( const WPosition& pos ) const;
317 
318  /**
319  * Computes the Z coordinate of that voxel that contains the
320  * position pos. Works on rotated grids.
321  *
322  * \param pos The position which selects the voxel for which the Z
323  * coordinate is computed.
324  *
325  * \return The Z coordinate or -1 if pos refers to point outside of the
326  * grid.
327  */
328  int getZVoxelCoordRotated( const WPosition& pos ) const;
329 
330  /**
331  * Computes the voxel coordinates of that voxel which contains
332  * the position pos.
333  *
334  * \param pos The position selecting the voxel.
335  *
336  * \return A vector of ints where the first component is the X voxel
337  * coordinate, the second the Y component voxel coordinate and the last the
338  * Z component of the voxel coordinate. If the selecting position is
339  * outside of the grid then -1 -1 -1 is returned.
340  */
341  WValue< int > getVoxelCoord( const WPosition& pos ) const;
342 
343  /**
344  * Computes the id of the cell containing the position pos. Note that the upper
345  * bound of the grid does not belong to any cell
346  *
347  * \param pos The position selecting the cell.
348  * \param success True if the position pos is inside the grid.
349  *
350  * \return id of the containing the position.
351  */
352  size_t getCellId( const WPosition& pos, bool* success ) const;
353 
354  /**
355  * Computes the ids of the vertices of a cell given by its id.
356  *
357  * \param cellId The id of the cell we want to know ther vertices of.
358  *
359  * \return Ids of vertices belonging to cell with given cellId.
360 
361  * \verbatim
362  z-axis y-axis
363  | /
364  | 6___/_7
365  |/: /|
366  4_:___5 |
367  | :...|.|
368  |.2 | 3
369  |_____|/ ____x-axis
370  0 1
371  \endverbatim
372  *
373  */
374  std::vector< size_t > getCellVertexIds( const size_t cellId ) const;
375 
376  /**
377  * Computes the vertices for a voxel cuboid around the given point:
378  *
379  * \verbatim
380  z-axis y-axis
381  | /
382  | h___/_g
383  |/: /|
384  d_:___c |
385  | :...|.|
386  |.e | f
387  |_____|/ ____x-axis
388  a b
389  \endverbatim
390  *
391  * As you can see the order of the points is: a, b, c, d, e, f, g, h.
392  *
393  * \param point Center of the cuboid which must not necesarrily be a point
394  * of the grid.
395  * \param margin If you need to shrink the Voxel put here the delta > 0.
396  *
397  * \return Reference to a list of vertices which are the corner points of
398  * the cube. Note this must not be a voxel, but has the same size of the an
399  * voxel. If you need voxels at grid positions fill this function with
400  * voxel center positions aka grid points.
401  */
402  boost::shared_ptr< std::vector< WPosition > > getVoxelVertices( const WPosition& point,
403  const double margin = 0.0 ) const;
404 
405  /**
406  * Return the list of neighbour voxels.
407  *
408  * \throw WOutOfBounds If the voxel id is outside of the grid.
409  *
410  * \param id Number of the voxel for which the neighbours should be computed
411  *
412  * \return Vector of voxel ids which are all neighboured
413  */
414  std::vector< size_t > getNeighbours( size_t id ) const;
415 
416  /**
417  * Return the list of all neighbour voxels.
418  *
419  * \throw WOutOfBounds If the voxel id is outside of the grid.
420  *
421  * \param id Number of the voxel for which the neighbours should be computed
422  *
423  * \return Vector of voxel ids which are all neighboured
424  */
425  std::vector< size_t > getNeighbours27( size_t id ) const;
426 
427  /**
428  * Return the list of all neighbour voxels.
429  *
430  * \throw WOutOfBounds If the voxel id is outside of the grid.
431  *
432  * \param id Number of the voxel for which the neighbours should be computed
433  *
434  * \return Vector of voxel ids which are all neighboured along the XY plane
435  */
436  std::vector< size_t > getNeighbours9XY( size_t id ) const;
437 
438  /**
439  * Return the list of all neighbour voxels.
440  *
441  * \throw WOutOfBounds If the voxel id is outside of the grid.
442  *
443  * \param id Number of the voxel for which the neighbours should be computed
444  *
445  * \return Vector of voxel ids which are all neighboured along the YZ plane
446  */
447  std::vector< size_t > getNeighbours9YZ( size_t id ) const;
448 
449  /**
450  * Return the list of all neighbour voxels.
451  *
452  * \throw WOutOfBounds If the voxel id is outside of the grid.
453  *
454  * \param id Number of the voxel for which the neighbours should be computed
455  *
456  * \return Vector of voxel ids which are all neighboured along the XZ plane
457  */
458  std::vector< size_t > getNeighbours9XZ( size_t id ) const;
459 
460  /**
461  * Decides whether a certain position is inside this grid or not.
462  *
463  * \param pos Position to test
464  *
465  * \return True if and only if the given point is inside or on boundary of this grid, otherwise false.
466  */
467  bool encloses( const WPosition& pos ) const;
468 
469  /**
470  * Return whether the transformations of the grid are only translation and/or scaling
471  * \return Transformation does not contain rotation?
472  */
473  bool isNotRotated() const;
474 
475  /**
476  * Returns the transformation used by this grid.
477  * \return The transformation.
478  */
479  WGridTransformOrtho const getTransform() const;
480 
481 protected:
482 
483 private:
484  /**
485  * Computes for the n'th component of the voxel coordinate where the voxel
486  * contains the position pos.
487  *
488  * \param pos The position for which the n'th component of the voxel
489  * coordinates should be computed.
490  * \param axis The number of the component. (0 == x-axis, 1 == y-axis, ...)
491  *
492  * \return The n'th component of the voxel coordinate
493  */
494  int getNVoxelCoord( const WPosition& pos, size_t axis ) const;
495 
496  /**
497  * Adds the specific information of this grid type to the
498  * informational properties.
499  */
500  void initInformationProperties();
501 
502  unsigned int m_nbPosX; //!< Number of positions in x direction
503  unsigned int m_nbPosY; //!< Number of positions in y direction
504  unsigned int m_nbPosZ; //!< Number of positions in z direction
505 
506  //! The grid's transformation.
508 };
509 
510 /**
511  * Convinience function returning all offsets per axis.
512  * 0 : xAxis, 1 : yAxis, 2 : zAxis
513  * \param grid The grid having the information.
514  * \note Implementing this as NonMemberNonFriend was intentional.
515  * \return Array of number of samples per axis.
516  */
517 inline boost::array< double, 3 > getOffsets( boost::shared_ptr< const WGridRegular3D > grid )
518 {
519  boost::array< double, 3 > result = { { grid->getOffsetX(), grid->getOffsetY(), grid->getOffsetZ() } }; // NOLINT curly braces
520  return result;
521 }
522 
523 /**
524  * Convinience function returning all number coords per axis.
525  * 0 : xAxis, 1 : yAxis, 2 : zAxis
526  * \param grid The grid having the information.
527  * \note Implementing this as NonMemberNonFriend was intentional.
528  * \return Array of number of samples per axis.
529  */
530 inline boost::array< unsigned int, 3 > getNbCoords( boost::shared_ptr< const WGridRegular3D > grid )
531 {
532  boost::array< unsigned int, 3 > result = { { grid->getNbCoordsX(), grid->getNbCoordsY(), grid->getNbCoordsZ() } }; // NOLINT curly braces
533  return result;
534 }
535 
536 /**
537  * Convinience function returning all axis directions.
538  * 0 : xAxis, 1 : yAxis, 2 : zAxis
539  * \param grid The grid having the information.
540  * \note Implementing this as NonMemberNonFriend was intentional.
541  * \return The direction of each axis as array
542  */
543 inline boost::array< WVector3d, 3 > getDirections( boost::shared_ptr< const WGridRegular3D > grid )
544 {
545  boost::array< WVector3d, 3 > result = { { grid->getDirectionX(), grid->getDirectionY(), grid->getDirectionZ() } }; // NOLINT curly braces
546  return result;
547 }
548 
549 /**
550  * Convinience function returning all axis unit directions.
551  * 0 : xAxis, 1 : yAxis, 2 : zAxis
552  * \param grid The grid having the information.
553  * \note Implementing this as NonMemberNonFriend was intentional.
554  * \return The direction of each axis as array
555  */
556 inline boost::array< WVector3d, 3 > getUnitDirections( boost::shared_ptr< const WGridRegular3D > grid )
557 {
558  boost::array< WVector3d, 3 > result = { { grid->getUnitDirectionX(), grid->getUnitDirectionY(), grid->getUnitDirectionZ() } }; // NOLINT curly braces
559  return result;
560 }
561 
562 inline unsigned int WGridRegular3D::getNbCoordsX() const
563 {
564  return m_nbPosX;
565 }
566 
567 inline unsigned int WGridRegular3D::getNbCoordsY() const
568 {
569  return m_nbPosY;
570 }
571 
572 inline unsigned int WGridRegular3D::getNbCoordsZ() const
573 {
574  return m_nbPosZ;
575 }
576 
577 inline double WGridRegular3D::getOffsetX() const
578 {
579  return m_transform.getOffsetX();
580 }
581 
582 inline double WGridRegular3D::getOffsetY() const
583 {
584  return m_transform.getOffsetY();
585 }
586 
587 inline double WGridRegular3D::getOffsetZ() const
588 {
589  return m_transform.getOffsetZ();
590 }
591 
593 {
595 }
596 
598 {
600 }
601 
603 {
605 }
606 
608 {
609  return m_transform.getDirectionX();
610 }
611 
613 {
614  return m_transform.getDirectionY();
615 }
616 
618 {
619  return m_transform.getDirectionZ();
620 }
621 
623 {
624  return m_transform.getOrigin();
625 }
626 
628 {
629  return m_transform;
630 }
631 
633 {
635 }
636 #endif // WGRIDREGULAR3D_H