~ubuntu-branches/ubuntu/wily/openwalnut/wily-proposed

« back to all changes in this revision

Viewing changes to .pc/gcc5.patch/src/core/dataHandler/WGridRegular3D.h

  • Committer: Package Import Robot
  • Author(s): Michael Terry
  • Date: 2015-08-12 13:14:55 UTC
  • Revision ID: package-import@ubuntu.com-20150812131455-cwndvoy9wwx34ya2
Tags: 1.4.0~rc1+hg3a3147463ee2-1ubuntu4
* debian/patches/gcc5.patch:
  - Work around incompatibility between boost+gcc5 and Qt4, fixing FTBFS

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 <cmath>
 
29
#include <string>
 
30
#include <utility>
 
31
#include <vector>
 
32
 
 
33
#include <boost/array.hpp>
 
34
#include <boost/shared_ptr.hpp>
 
35
 
 
36
#include <osg/Matrix>
 
37
#include <osg/Vec3>
 
38
 
 
39
#include "../common/exceptions/WOutOfBounds.h"
 
40
#include "../common/exceptions/WPreconditionNotMet.h"
 
41
#include "../common/math/WLinearAlgebraFunctions.h"
 
42
#include "../common/math/WMatrix.h"
 
43
#include "../common/WBoundingBox.h"
 
44
#include "../common/WCondition.h"
 
45
#include "../common/WDefines.h"
 
46
#include "../common/WProperties.h"
 
47
 
 
48
#include "WGrid.h"
 
49
#include "WGridTransformOrtho.h"
 
50
 
 
51
/**
 
52
 * A grid that has parallelepiped cells which all have the same proportion. I.e.
 
53
 * the samples along a single axis are equidistant. The distance of samples may
 
54
 * vary between axes.
 
55
 *
 
56
 * \warning Positions on the upper bounddaries in x, y and z are considered outside the grid.
 
57
 * \ingroup dataHandler
 
58
 */
 
59
template< typename T >
 
60
class WGridRegular3DTemplate : public WGrid // NOLINT
 
61
{
 
62
    // this (friend) is necessary to allow casting
 
63
    template <class U>
 
64
    friend class WGridRegular3DTemplate;
 
65
    /**
 
66
     * Only test are allowed as friends.
 
67
     */
 
68
    friend class WGridRegular3DTest;
 
69
public:
 
70
    /**
 
71
     * Convenience typedef for 3d vectors of the appropriate numerical type.
 
72
     */
 
73
    typedef WMatrixFixed< T, 3, 1 > Vector3Type;
 
74
 
 
75
    /**
 
76
     * Convenience typedef for a boost::shared_ptr< WGridRegular3DTemplate >.
 
77
     */
 
78
    typedef boost::shared_ptr< WGridRegular3DTemplate > SPtr;
 
79
 
 
80
    /**
 
81
     * Convenience typedef for a boost::shared_ptr< const WGridRegular3DTemplate >.
 
82
     */
 
83
    typedef boost::shared_ptr< const WGridRegular3DTemplate > ConstSPtr;
 
84
 
 
85
    /**
 
86
     * Convenience typedef for a boost::array< size_t, 8 >. Return type of getCellVertexIds.
 
87
     */
 
88
    typedef boost::array< size_t, 8 > CellVertexArray;
 
89
 
 
90
    /**
 
91
     * Copy constructor.
 
92
     * Copies the data from an WGridRegular3DTemplate object with arbitary numerical type.
 
93
     *
 
94
     * \param rhs A WGridRegular3DTemplate object, which mustn't have the same numerical type.
 
95
     */
 
96
    template< typename InputType >
 
97
    WGridRegular3DTemplate( WGridRegular3DTemplate< InputType > const& rhs ); // NOLINT -- no explicit, this allows casts
 
98
 
 
99
    /**
 
100
     * Defines the number of samples in each coordinate direction as ints,
 
101
     * and the transformation of the grid via a grid transform.
 
102
     *
 
103
     * \param nbPosX number of positions along first axis
 
104
     * \param nbPosY number of positions along second axis
 
105
     * \param nbPosZ number of positions along third axis
 
106
     * \param transform a grid transformation
 
107
     */
 
108
    WGridRegular3DTemplate( unsigned int nbPosX, unsigned int nbPosY, unsigned int nbPosZ,
 
109
                            WGridTransformOrthoTemplate< T > const transform = WGridTransformOrthoTemplate< T >() );
 
110
 
 
111
    /**
 
112
     * Defines the number of samples in each coordinate direction as ints,
 
113
     * and the transformation of the grid via a grid transform.
 
114
     *
 
115
     * \param nbPosX number of positions along first axis
 
116
     * \param nbPosY number of positions along second axis
 
117
     * \param nbPosZ number of positions along third axis
 
118
     * \param scaleX scaling of a voxel in x direction
 
119
     * \param scaleY scaling of a voxel in y direction
 
120
     * \param scaleZ scaling of a voxel in z direction
 
121
     */
 
122
    WGridRegular3DTemplate( unsigned int nbPosX, unsigned int nbPosY, unsigned int nbPosZ,
 
123
                            double scaleX, double scaleY, double scaleZ );
 
124
 
 
125
    /**
 
126
     * Returns the number of samples in x direction.
 
127
     * \return The number of samples in x direction.
 
128
     */
 
129
    unsigned int getNbCoordsX() const;
 
130
 
 
131
    /**
 
132
     * Returns the number of samples in y direction.
 
133
     * \return The number of samples in y direction.
 
134
     */
 
135
    unsigned int getNbCoordsY() const;
 
136
 
 
137
    /**
 
138
     * Returns the number of samples in z direction.
 
139
     * \return The number of samples in z direction.
 
140
     */
 
141
    unsigned int getNbCoordsZ() const;
 
142
 
 
143
    /**
 
144
     * Returns the distance between samples in x direction.
 
145
     * \return The distance between samples in x direction.
 
146
     */
 
147
    T getOffsetX() const;
 
148
 
 
149
    /**
 
150
     * Returns the distance between samples in y direction.
 
151
     * \return The distance between samples in y direction.
 
152
     */
 
153
    T getOffsetY() const;
 
154
 
 
155
    /**
 
156
     * Returns the distance between samples in z direction.
 
157
     * \return The distance between samples in z direction.
 
158
     */
 
159
    T getOffsetZ() const;
 
160
 
 
161
    /**
 
162
     * Returns the vector determining the direction of samples in x direction.
 
163
     * Adding this vector to a grid position in world coordinates yields the position of the next sample
 
164
     * along the grids (world coordinate) x-axis.
 
165
     * \return The vector determining the direction of samples in x direction.
 
166
     */
 
167
    Vector3Type getDirectionX() const;
 
168
 
 
169
    /**
 
170
     * Returns the vector determining the direction of samples in y direction.
 
171
     * Adding this vector to a grid position in world coordinates yields the position of the next sample
 
172
     * along the grids (world coordinate) y-axis.
 
173
     * \return The vector determining the direction of samples in y direction.
 
174
     */
 
175
    Vector3Type getDirectionY() const;
 
176
 
 
177
    /**
 
178
     * Returns the vector determining the direction of samples in z direction.
 
179
     * Adding this vector to a grid position in world coordinates yields the position of the next sample
 
180
     * along the grids (world coordinate) z-axis.
 
181
     * \return The vector determining the direction of samples in z direction.
 
182
     */
 
183
    Vector3Type getDirectionZ() const;
 
184
 
 
185
    /**
 
186
     * Returns the vector determining the unit (normalized) direction of samples in x direction.
 
187
     * \return The vector determining the unit (normalized) direction of samples in x direction.
 
188
     */
 
189
    Vector3Type getUnitDirectionX() const;
 
190
 
 
191
    /**
 
192
     * Returns the vector determining the unit (normalized) direction of samples in y direction.
 
193
     * \return The vector determining the unit (normalized) direction of samples in y direction.
 
194
     */
 
195
    Vector3Type getUnitDirectionY() const;
 
196
 
 
197
    /**
 
198
     * Returns the vector determining the unit (normalized) direction of samples in z direction.
 
199
     * \return The vector determining the unit (normalized) direction of samples in z direction.
 
200
     */
 
201
    Vector3Type getUnitDirectionZ() const;
 
202
 
 
203
    /**
 
204
     * Returns the position of the origin of the grid.
 
205
     * \return The position of the origin of the grid.
 
206
     */
 
207
    Vector3Type getOrigin() const;
 
208
 
 
209
    /**
 
210
     * Returns a 4x4 matrix that represents the grid's transformation.
 
211
     * \return The grid's transformation.
 
212
     */
 
213
    WMatrix< T > getTransformationMatrix() const;
 
214
 
 
215
    /**
 
216
     * \copybrief WGrid::getBoundingBox()
 
217
     * \return \copybrief WGrid::getBoundingBox()
 
218
     */
 
219
    WBoundingBox getBoundingBox() const;
 
220
 
 
221
    /**
 
222
     * Calculates the bounding box but includes the border voxel associated cell too.
 
223
     *
 
224
     * \return the bounding box
 
225
     */
 
226
    WBoundingBox getBoundingBoxIncludingBorder() const;
 
227
 
 
228
    /**
 
229
     * Calculate the bounding box in voxel space. In contrast to the cell bounding box, this includes the space of the last voxel in each
 
230
     * direction.
 
231
     *
 
232
     * \return the voxel space bounding box.
 
233
     */
 
234
    WBoundingBox getVoxelBoundingBox() const;
 
235
 
 
236
    /**
 
237
     * Returns the i-th position on the grid.
 
238
     * \param i id of position to be obtained
 
239
     * \return i-th position of the grid.
 
240
     */
 
241
    Vector3Type getPosition( unsigned int i ) const;
 
242
 
 
243
    /**
 
244
     * Returns the position that is the iX-th in x direction, the iY-th in
 
245
     * y direction and the iZ-th in z direction.
 
246
     * \param iX id along first axis of position to be obtained
 
247
     * \param iY id along second axis of position to be obtained
 
248
     * \param iZ id along third axis of position to be obtained
 
249
     * \return Position (iX,iY,iZ)
 
250
     */
 
251
    Vector3Type getPosition( unsigned int iX, unsigned int iY, unsigned int iZ ) const;
 
252
 
 
253
    /**
 
254
     * Transforms world coordinates to texture coordinates.
 
255
     * \param point The point with these coordinates will be transformed.
 
256
     * \return point transformed into texture coordinate system
 
257
     */
 
258
    Vector3Type worldCoordToTexCoord( Vector3Type point );
 
259
 
 
260
    /**
 
261
     * Returns the i'th voxel where the given position belongs too.
 
262
     *
 
263
     * A voxel is a cuboid which surrounds a point on the grid.
 
264
     *
 
265
     * \verbatim
 
266
      Voxel:
 
267
                     ______________ ____ (0.5, 0.5, 0.5)
 
268
                    /:            /|
 
269
                   / :           / |
 
270
                  /  :          /  |
 
271
                 /   :         /   |
 
272
               _/____:_ ___ __/    |
 
273
                |    :        |    |
 
274
                |    :    *<--|--------- grid point (0, 0, 0)
 
275
                |    :........|....|__
 
276
         dz == 1|   /         |   /
 
277
                |  /          |  / dy == 1
 
278
                | /           | /
 
279
               _|/____________|/__
 
280
                |<- dx == 1 ->|
 
281
         -0.5,-0.5,-0.5
 
282
       \endverbatim
 
283
     *
 
284
     * Please note the first voxel has only 1/8 of the size a normal voxel
 
285
     * would have since all positions outside the grid do not belong
 
286
     * to any voxel. Note: a cell is different to a voxel in terms of position.
 
287
     * A voxel has a grid point as center whereas a cell has grid points as
 
288
     * corners.
 
289
     * \param pos Position for which we want to have the voxel number.
 
290
     *
 
291
     * \return Voxel number or -1 if the position refers to a point outside of
 
292
     * the grid.
 
293
     */
 
294
    int getVoxelNum( const Vector3Type& pos ) const;
 
295
 
 
296
    /**
 
297
     * returns the voxel index for a given discrete position in the grid
 
298
     *
 
299
     * \param x Position for which we want to have the voxel number.
 
300
     * \param y Position for which we want to have the voxel number.
 
301
     * \param z Position for which we want to have the voxel number.
 
302
     *
 
303
     * \return Voxel number or -1 if the position refers to a point outside of
 
304
     * the grid.
 
305
     */
 
306
    int getVoxelNum( const size_t x, const size_t y, const size_t z ) const;
 
307
 
 
308
    /**
 
309
     * Computes the X coordinate of that voxel that contains the
 
310
     * position pos.
 
311
     *
 
312
     * \param pos The position which selects the voxel for which the X
 
313
     * coordinate is computed.
 
314
     *
 
315
     * \return The X coordinate or -1 if pos refers to point outside of the
 
316
     * grid.
 
317
     */
 
318
    int getXVoxelCoord( const Vector3Type& pos ) const;
 
319
 
 
320
    /**
 
321
     * Computes the Y coordinate of that voxel that contains the
 
322
     * position pos.
 
323
     *
 
324
     * \param pos The position which selects the voxel for which the Y
 
325
     * coordinate is computed.
 
326
     *
 
327
     * \return The Y coordinate or -1 if pos refers to point outside of the
 
328
     * grid.
 
329
     */
 
330
    int getYVoxelCoord( const Vector3Type& pos ) const;
 
331
 
 
332
    /**
 
333
     * Computes the Z coordinate of that voxel that contains the
 
334
     * position pos.
 
335
     *
 
336
     * \param pos The position which selects the voxel for which the Z
 
337
     * coordinate is computed.
 
338
     *
 
339
     * \return The Z coordinate or -1 if pos refers to point outside of the
 
340
     * grid.
 
341
     */
 
342
    int getZVoxelCoord( const Vector3Type& pos ) const;
 
343
 
 
344
    /**
 
345
     * Computes the voxel coordinates of that voxel which contains
 
346
     * the position pos.
 
347
     *
 
348
     * \param pos The position selecting the voxel.
 
349
     *
 
350
     * \return A vector of ints where the first component is the X voxel
 
351
     * coordinate, the second the Y component voxel coordinate and the last the
 
352
     * Z component of the voxel coordinate. If the selecting position is
 
353
     * outside of the grid then -1 -1 -1 is returned.
 
354
     */
 
355
    WVector3i getVoxelCoord( const Vector3Type& pos ) const;
 
356
 
 
357
    /**
 
358
     * Computes the id of the cell containing the position pos. Note that the upper
 
359
     * bound of the grid does not belong to any cell
 
360
     *
 
361
     * \param pos The position selecting the cell.
 
362
     * \param success True if the position pos is inside the grid.
 
363
     *
 
364
     * \return id of the containing the position.
 
365
     */
 
366
    size_t getCellId( const Vector3Type& pos, bool* success ) const;
 
367
 
 
368
    /**
 
369
     * Computes the ids of the vertices of a cell given by its id.
 
370
     *
 
371
     * \param cellId The id of the cell we want to know ther vertices of.
 
372
     *
 
373
     * \return Ids of vertices belonging to cell with given cellId.
 
374
 
 
375
     * \verbatim
 
376
        z-axis  y-axis
 
377
        |      /
 
378
        | 6___/_7
 
379
        |/:    /|
 
380
        4_:___5 |
 
381
        | :...|.|
 
382
        |.2   | 3
 
383
        |_____|/ ____x-axis
 
384
       0      1
 
385
       \endverbatim
 
386
     *
 
387
     */
 
388
    CellVertexArray getCellVertexIds( size_t cellId ) const;
 
389
 
 
390
    /**
 
391
     * Computes the vertices for a voxel cuboid around the given point:
 
392
     *
 
393
     * \verbatim
 
394
        z-axis  y-axis
 
395
        |      /
 
396
        | h___/_g
 
397
        |/:    /|
 
398
        d_:___c |
 
399
        | :...|.|
 
400
        |.e   | f
 
401
        |_____|/ ____x-axis
 
402
       a      b
 
403
       \endverbatim
 
404
     *
 
405
     * As you can see the order of the points is: a, b, c, d, e, f, g, h.
 
406
     *
 
407
     * \param point Center of the cuboid which must not necesarrily be a point
 
408
     * of the grid.
 
409
     * \param margin If you need to shrink the Voxel put here the delta > 0.
 
410
     *
 
411
     * \return Reference to a list of vertices which are the corner points of
 
412
     * the cube. Note this must not be a voxel, but has the same size of the an
 
413
     * voxel. If you need voxels at grid positions fill this function with
 
414
     * voxel center positions aka grid points.
 
415
     */
 
416
    boost::shared_ptr< std::vector< Vector3Type > > getVoxelVertices( const Vector3Type& point,
 
417
                                                                      const T margin = 0.0 ) const;
 
418
 
 
419
    /**
 
420
     * Return the list of neighbour voxels.
 
421
     *
 
422
     * \throw WOutOfBounds If the voxel id is outside of the grid.
 
423
     *
 
424
     * \param id Number of the voxel for which the neighbours should be computed
 
425
     *
 
426
     * \return Vector of voxel ids which are all neighboured
 
427
     */
 
428
    std::vector< size_t > getNeighbours( size_t id ) const;
 
429
 
 
430
    /**
 
431
     * Return the list of all neighbour voxels.
 
432
     *
 
433
     * \throw WOutOfBounds If the voxel id is outside of the grid.
 
434
     *
 
435
     * \param id Number of the voxel for which the neighbours should be computed
 
436
     *
 
437
     * \return Vector of voxel ids which are all neighboured
 
438
     */
 
439
    std::vector< size_t > getNeighbours27( size_t id ) const;
 
440
 
 
441
    /**
 
442
     * Return the list of all neighbour voxels.
 
443
     *
 
444
     * \throw WOutOfBounds If the voxel id is outside of the grid.
 
445
     *
 
446
     * \param id Number of the voxel for which the neighbours should be computed
 
447
     *
 
448
     * \param range neighborhood range selected. It specifies the distance to count as neighbour in each direction.
 
449
     *
 
450
     * \return Vector of voxel ids which are all neighboured
 
451
     */
 
452
    std::vector< size_t > getNeighboursRange( size_t id, size_t range ) const;
 
453
 
 
454
    /**
 
455
     * Return the list of all neighbour voxels.
 
456
     *
 
457
     * \throw WOutOfBounds If the voxel id is outside of the grid.
 
458
     *
 
459
     * \param id Number of the voxel for which the neighbours should be computed
 
460
     *
 
461
     * \return Vector of voxel ids which are all neighboured along the XY plane
 
462
     */
 
463
    std::vector< size_t > getNeighbours9XY( size_t id ) const;
 
464
 
 
465
    /**
 
466
     * Return the list of all neighbour voxels.
 
467
     *
 
468
     * \throw WOutOfBounds If the voxel id is outside of the grid.
 
469
     *
 
470
     * \param id Number of the voxel for which the neighbours should be computed
 
471
     *
 
472
     * \return Vector of voxel ids which are all neighboured along the YZ plane
 
473
     */
 
474
    std::vector< size_t > getNeighbours9YZ( size_t id ) const;
 
475
 
 
476
    /**
 
477
     * Return the list of all neighbour voxels.
 
478
     *
 
479
     * \throw WOutOfBounds If the voxel id is outside of the grid.
 
480
     *
 
481
     * \param id Number of the voxel for which the neighbours should be computed
 
482
     *
 
483
     * \return Vector of voxel ids which are all neighboured along the XZ plane
 
484
     */
 
485
    std::vector< size_t > getNeighbours9XZ( size_t id ) const;
 
486
 
 
487
    /**
 
488
     * Decides whether a certain position is inside this grid or not.
 
489
     *
 
490
     * \param pos Position to test
 
491
     *
 
492
     * \return True if and only if the given point is inside or on boundary of this grid, otherwise false.
 
493
     */
 
494
    bool encloses( const Vector3Type& pos ) const;
 
495
 
 
496
    /**
 
497
     * Return whether the transformations of the grid are only translation and/or scaling
 
498
     * \return Transformation does not contain rotation?
 
499
     */
 
500
    bool isNotRotated() const;
 
501
 
 
502
    /**
 
503
     * Returns the transformation used by this grid.
 
504
     * \return The transformation.
 
505
     */
 
506
    WGridTransformOrthoTemplate< T > const getTransform() const;
 
507
 
 
508
    /**
 
509
     * Compares two grids. Matches the transform and x,y,z resolution.
 
510
     *
 
511
     * \param other the one to compare against
 
512
     *
 
513
     * \return true if transform and resolution matches
 
514
     */
 
515
    bool operator==( const WGridRegular3DTemplate< T >& other ) const;
 
516
 
 
517
protected:
 
518
private:
 
519
    /**
 
520
     * Computes for the n'th component of the voxel coordinate where the voxel
 
521
     * contains the position pos.
 
522
     *
 
523
     * \param pos The position for which the n'th component of the voxel
 
524
     * coordinates should be computed.
 
525
     * \param axis The number of the component. (0 == x-axis, 1 == y-axis, ...)
 
526
     *
 
527
     * \return The n'th component of the voxel coordinate
 
528
     */
 
529
    int getNVoxelCoord( const Vector3Type& pos, size_t axis ) const;
 
530
 
 
531
    /**
 
532
     * Adds the specific information of this grid type to the
 
533
     * informational properties.
 
534
     */
 
535
    void initInformationProperties();
 
536
 
 
537
    unsigned int m_nbPosX; //!< Number of positions in x direction
 
538
    unsigned int m_nbPosY; //!< Number of positions in y direction
 
539
    unsigned int m_nbPosZ; //!< Number of positions in z direction
 
540
 
 
541
    //! The grid's transformation.
 
542
    WGridTransformOrthoTemplate< T > const m_transform;
 
543
};
 
544
 
 
545
// Convenience typedefs
 
546
typedef WGridRegular3DTemplate< double > WGridRegular3D;
 
547
typedef WGridRegular3DTemplate< double > WGridRegular3DDouble;
 
548
typedef WGridRegular3DTemplate< float > WGridRegular3DFloat;
 
549
 
 
550
template< typename T >
 
551
template< typename InputType >
 
552
WGridRegular3DTemplate< T >::WGridRegular3DTemplate( WGridRegular3DTemplate< InputType > const& rhs ) :
 
553
    WGrid( rhs.m_nbPosX * rhs.m_nbPosY * rhs.m_nbPosZ ),
 
554
    m_nbPosX( rhs.m_nbPosX ),
 
555
    m_nbPosY( rhs.m_nbPosY ),
 
556
    m_nbPosZ( rhs.m_nbPosZ ),
 
557
    m_transform( rhs.m_transform )
 
558
{
 
559
    initInformationProperties();
 
560
}
 
561
 
 
562
template< typename T >
 
563
WGridRegular3DTemplate< T >::WGridRegular3DTemplate( unsigned int nbPosX, unsigned int nbPosY, unsigned int nbPosZ,
 
564
                                     WGridTransformOrthoTemplate< T > const transform )
 
565
    : WGrid( nbPosX * nbPosY * nbPosZ ),
 
566
      m_nbPosX( nbPosX ),
 
567
      m_nbPosY( nbPosY ),
 
568
      m_nbPosZ( nbPosZ ),
 
569
      m_transform( transform )
 
570
{
 
571
    initInformationProperties();
 
572
}
 
573
 
 
574
template< typename T >
 
575
WGridRegular3DTemplate< T >::WGridRegular3DTemplate( unsigned int nbPosX, unsigned int nbPosY, unsigned int nbPosZ,
 
576
                                                     double scaleX, double scaleY, double scaleZ ):
 
577
    WGrid( nbPosX * nbPosY * nbPosZ ),
 
578
    m_nbPosX( nbPosX ),
 
579
    m_nbPosY( nbPosY ),
 
580
    m_nbPosZ( nbPosZ ),
 
581
    m_transform( WGridTransformOrthoTemplate< T >( scaleX, scaleY, scaleZ ) )
 
582
{
 
583
    initInformationProperties();
 
584
}
 
585
 
 
586
template< typename T >
 
587
inline unsigned int WGridRegular3DTemplate< T >::getNbCoordsX() const
 
588
{
 
589
    return m_nbPosX;
 
590
}
 
591
 
 
592
template< typename T >
 
593
inline unsigned int WGridRegular3DTemplate< T >::getNbCoordsY() const
 
594
{
 
595
    return m_nbPosY;
 
596
}
 
597
 
 
598
template< typename T >
 
599
inline unsigned int WGridRegular3DTemplate< T >::getNbCoordsZ() const
 
600
{
 
601
    return m_nbPosZ;
 
602
}
 
603
 
 
604
template< typename T >
 
605
inline T WGridRegular3DTemplate< T >::getOffsetX() const
 
606
{
 
607
    return m_transform.getOffsetX();
 
608
}
 
609
 
 
610
template< typename T >
 
611
inline T WGridRegular3DTemplate< T >::getOffsetY() const
 
612
{
 
613
    return m_transform.getOffsetY();
 
614
}
 
615
 
 
616
template< typename T >
 
617
inline T WGridRegular3DTemplate< T >::getOffsetZ() const
 
618
{
 
619
    return m_transform.getOffsetZ();
 
620
}
 
621
 
 
622
template< typename T >
 
623
inline typename WGridRegular3DTemplate< T >::Vector3Type WGridRegular3DTemplate< T >::getDirectionX() const
 
624
{
 
625
    return m_transform.getDirectionX();
 
626
}
 
627
 
 
628
template< typename T >
 
629
inline typename WGridRegular3DTemplate< T >::Vector3Type WGridRegular3DTemplate< T >::getDirectionY() const
 
630
{
 
631
    return m_transform.getDirectionY();
 
632
}
 
633
 
 
634
template< typename T >
 
635
inline typename WGridRegular3DTemplate< T >::Vector3Type WGridRegular3DTemplate< T >::getDirectionZ() const
 
636
{
 
637
    return m_transform.getDirectionZ();
 
638
}
 
639
 
 
640
template< typename T >
 
641
inline typename WGridRegular3DTemplate< T >::Vector3Type WGridRegular3DTemplate< T >::getUnitDirectionX() const
 
642
{
 
643
    return m_transform.getUnitDirectionX();
 
644
}
 
645
 
 
646
template< typename T >
 
647
inline typename WGridRegular3DTemplate< T >::Vector3Type WGridRegular3DTemplate< T >::getUnitDirectionY() const
 
648
{
 
649
    return m_transform.getUnitDirectionY();
 
650
}
 
651
 
 
652
template< typename T >
 
653
inline typename WGridRegular3DTemplate< T >::Vector3Type WGridRegular3DTemplate< T >::getUnitDirectionZ() const
 
654
{
 
655
    return m_transform.getUnitDirectionZ();
 
656
}
 
657
 
 
658
template< typename T >
 
659
inline typename WGridRegular3DTemplate< T >::Vector3Type WGridRegular3DTemplate< T >::getOrigin() const
 
660
{
 
661
    return m_transform.getOrigin();
 
662
}
 
663
 
 
664
template< typename T >
 
665
inline WMatrix< T > WGridRegular3DTemplate< T >::getTransformationMatrix() const
 
666
{
 
667
    return m_transform.getTransformationMatrix();
 
668
}
 
669
 
 
670
template< typename T >
 
671
inline WBoundingBox WGridRegular3DTemplate< T >::getBoundingBox() const
 
672
{
 
673
    WBoundingBox result;
 
674
    result.expandBy( m_transform.positionToWorldSpace( Vector3Type( 0.0,                0.0,                0.0            ) ) );
 
675
    result.expandBy( m_transform.positionToWorldSpace( Vector3Type( getNbCoordsX() - 1, 0.0,                0.0            ) ) );
 
676
    result.expandBy( m_transform.positionToWorldSpace( Vector3Type( 0.0,                getNbCoordsY() - 1, 0.0            ) ) );
 
677
    result.expandBy( m_transform.positionToWorldSpace( Vector3Type( getNbCoordsX() - 1, getNbCoordsY() - 1, 0.0            ) ) );
 
678
    result.expandBy( m_transform.positionToWorldSpace( Vector3Type( 0.0,                0.0,                getNbCoordsZ() - 1 ) ) );
 
679
    result.expandBy( m_transform.positionToWorldSpace( Vector3Type( getNbCoordsX() - 1, 0.0,                getNbCoordsZ() - 1 ) ) );
 
680
    result.expandBy( m_transform.positionToWorldSpace( Vector3Type( 0.0,                getNbCoordsY() - 1, getNbCoordsZ() - 1 ) ) );
 
681
    result.expandBy( m_transform.positionToWorldSpace( Vector3Type( getNbCoordsX() - 1, getNbCoordsY() - 1, getNbCoordsZ() - 1 ) ) );
 
682
    return result;
 
683
}
 
684
 
 
685
template< typename T >
 
686
inline WBoundingBox WGridRegular3DTemplate< T >::getBoundingBoxIncludingBorder() const
 
687
{
 
688
    WBoundingBox result;
 
689
    result.expandBy( m_transform.positionToWorldSpace( Vector3Type( 0.0,            0.0,            0.0            ) ) );
 
690
    result.expandBy( m_transform.positionToWorldSpace( Vector3Type( getNbCoordsX(), 0.0,            0.0            ) ) );
 
691
    result.expandBy( m_transform.positionToWorldSpace( Vector3Type( 0.0,            getNbCoordsY(), 0.0            ) ) );
 
692
    result.expandBy( m_transform.positionToWorldSpace( Vector3Type( getNbCoordsX(), getNbCoordsY(), 0.0            ) ) );
 
693
    result.expandBy( m_transform.positionToWorldSpace( Vector3Type( 0.0,            0.0,            getNbCoordsZ() ) ) );
 
694
    result.expandBy( m_transform.positionToWorldSpace( Vector3Type( getNbCoordsX(), 0.0,            getNbCoordsZ() ) ) );
 
695
    result.expandBy( m_transform.positionToWorldSpace( Vector3Type( 0.0,            getNbCoordsY(), getNbCoordsZ() ) ) );
 
696
    result.expandBy( m_transform.positionToWorldSpace( Vector3Type( getNbCoordsX(), getNbCoordsY(), getNbCoordsZ() ) ) );
 
697
    return result;
 
698
}
 
699
 
 
700
template< typename T >
 
701
inline WBoundingBox WGridRegular3DTemplate< T >::getVoxelBoundingBox() const
 
702
{
 
703
    WBoundingBox result;
 
704
    result.expandBy( m_transform.positionToWorldSpace( Vector3Type( -0.5,                 -0.5,                 -0.5            ) ) );
 
705
    result.expandBy( m_transform.positionToWorldSpace( Vector3Type( getNbCoordsX() - 0.5, -0.5,                 -0.5            ) ) );
 
706
    result.expandBy( m_transform.positionToWorldSpace( Vector3Type( -0.5,                 getNbCoordsY() - 0.5, -0.5            ) ) );
 
707
    result.expandBy( m_transform.positionToWorldSpace( Vector3Type( getNbCoordsX() - 0.5, getNbCoordsY() - 0.5, -0.5            ) ) );
 
708
    result.expandBy( m_transform.positionToWorldSpace( Vector3Type( -0.5,                 -0.5,                 getNbCoordsZ() - 0.5 ) ) );
 
709
    result.expandBy( m_transform.positionToWorldSpace( Vector3Type( getNbCoordsX() - 0.5, -0.5,                 getNbCoordsZ() - 0.5 ) ) );
 
710
    result.expandBy( m_transform.positionToWorldSpace( Vector3Type( -0.5,                 getNbCoordsY() - 0.5, getNbCoordsZ() - 0.5 ) ) );
 
711
    result.expandBy( m_transform.positionToWorldSpace( Vector3Type( getNbCoordsX() - 0.5, getNbCoordsY() - 0.5, getNbCoordsZ() - 0.5 ) ) );
 
712
    return result;
 
713
}
 
714
 
 
715
template< typename T >
 
716
inline typename WGridRegular3DTemplate< T >::Vector3Type WGridRegular3DTemplate< T >::getPosition( unsigned int i ) const
 
717
{
 
718
    return getPosition( i % m_nbPosX, ( i / m_nbPosX ) % m_nbPosY, i / ( m_nbPosX * m_nbPosY ) );
 
719
}
 
720
 
 
721
template< typename T >
 
722
inline typename WGridRegular3DTemplate< T >::Vector3Type WGridRegular3DTemplate< T >::getPosition( unsigned int iX,
 
723
                                                                                                   unsigned int iY,
 
724
                                                                                                   unsigned int iZ ) const
 
725
{
 
726
    Vector3Type i( iX, iY, iZ );
 
727
    return m_transform.positionToWorldSpace( i );
 
728
}
 
729
 
 
730
template< typename T >
 
731
inline typename WGridRegular3DTemplate< T >::Vector3Type WGridRegular3DTemplate< T >::worldCoordToTexCoord( WGridRegular3DTemplate< T >::Vector3Type point ) // NOLINT -- too long line
 
732
{
 
733
    Vector3Type r( m_transform.positionToGridSpace( point ) );
 
734
 
 
735
    // Scale to [0,1]
 
736
    r[0] = r[0] / m_nbPosX;
 
737
    r[1] = r[1] / m_nbPosY;
 
738
    r[2] = r[2] / m_nbPosZ;
 
739
 
 
740
    // Correct the coordinates to have the position at the center of the texture voxel.
 
741
    r[0] += 0.5 / m_nbPosX;
 
742
    r[1] += 0.5 / m_nbPosY;
 
743
    r[2] += 0.5 / m_nbPosZ;
 
744
 
 
745
    return r;
 
746
}
 
747
 
 
748
template< typename T >
 
749
inline int WGridRegular3DTemplate< T >::getVoxelNum( const Vector3Type& pos ) const
 
750
{
 
751
    // Note: the reason for the +1 is that the first and last Voxel in a x-axis
 
752
    // row are cut.
 
753
    //
 
754
    //  y-axis
 
755
    //  _|_______     ___ this is the 3rd Voxel
 
756
    // 1 |   |   |   v
 
757
    //   |...............
 
758
    //  _|_:_|_:_|_:_|_:____ x-axis
 
759
    //   | : | : | : | :
 
760
    //   |.:...:...:...:.
 
761
    //   0   1   2
 
762
    int xVoxelCoord = getXVoxelCoord( pos );
 
763
    int yVoxelCoord = getYVoxelCoord( pos );
 
764
    int zVoxelCoord = getZVoxelCoord( pos );
 
765
    if( xVoxelCoord == -1 || yVoxelCoord == -1 || zVoxelCoord == -1 )
 
766
    {
 
767
        return -1;
 
768
    }
 
769
    return xVoxelCoord
 
770
         + yVoxelCoord * ( m_nbPosX )
 
771
         + zVoxelCoord * ( m_nbPosX ) * ( m_nbPosY );
 
772
}
 
773
 
 
774
template< typename T >
 
775
inline int WGridRegular3DTemplate< T >::getVoxelNum( const size_t x, const size_t y, const size_t z ) const
 
776
{
 
777
    // since we use size_t here only a check for the upper bounds is needed
 
778
    if( x > m_nbPosX || y > m_nbPosY || z > m_nbPosZ )
 
779
    {
 
780
        return -1;
 
781
    }
 
782
    return x + y * ( m_nbPosX ) + z * ( m_nbPosX ) * ( m_nbPosY );
 
783
}
 
784
 
 
785
template< typename T >
 
786
inline int WGridRegular3DTemplate< T >::getXVoxelCoord( const WGridRegular3DTemplate< T >::Vector3Type& pos ) const
 
787
{
 
788
    // the current get*Voxel stuff is too complicated anyway
 
789
    Vector3Type v = m_transform.positionToGridSpace( pos );
 
790
 
 
791
    // this part could be refactored into an inline function
 
792
    T d;
 
793
    v[ 2 ] = std::modf( v[ 0 ] + T( 0.5 ), &d );
 
794
    int i = static_cast< int >( v[ 0 ] >= T( 0.0 ) && v[ 0 ] < m_nbPosX - T( 1.0 ) );
 
795
    return -1 + i * static_cast< int >( T( 1.0 ) + d );
 
796
}
 
797
 
 
798
template< typename T >
 
799
inline int WGridRegular3DTemplate< T >::getYVoxelCoord( const WGridRegular3DTemplate< T >::Vector3Type& pos ) const
 
800
{
 
801
    Vector3Type v = m_transform.positionToGridSpace( pos );
 
802
 
 
803
    T d;
 
804
    v[ 0 ] = std::modf( v[ 1 ] + T( 0.5 ), &d );
 
805
    int i = static_cast< int >( v[ 1 ] >= T( 0.0 ) && v[ 1 ] < m_nbPosY - T( 1.0 ) );
 
806
    return -1 + i * static_cast< int >( T( 1.0 ) + d );
 
807
}
 
808
 
 
809
template< typename T >
 
810
inline int WGridRegular3DTemplate< T >::getZVoxelCoord( const WGridRegular3DTemplate< T >::Vector3Type& pos ) const
 
811
{
 
812
    Vector3Type v = m_transform.positionToGridSpace( pos );
 
813
 
 
814
    T d;
 
815
    v[ 0 ] = std::modf( v[ 2 ] + T( 0.5 ), &d );
 
816
    int i = static_cast< int >( v[ 2 ] >= T( 0.0 ) && v[ 2 ] < m_nbPosZ - T( 1.0 ) );
 
817
    return -1 + i * static_cast< int >( T( 1.0 ) + d );
 
818
}
 
819
 
 
820
template< typename T >
 
821
inline WVector3i WGridRegular3DTemplate< T >::getVoxelCoord( const WGridRegular3DTemplate< T >::Vector3Type& pos ) const
 
822
{
 
823
    WVector3i result;
 
824
    result[0] = getXVoxelCoord( pos );
 
825
    result[1] = getYVoxelCoord( pos );
 
826
    result[2] = getZVoxelCoord( pos );
 
827
    return result;
 
828
}
 
829
 
 
830
template< typename T >
 
831
inline size_t WGridRegular3DTemplate< T >::getCellId( const WGridRegular3DTemplate< T >::Vector3Type& pos, bool* success ) const
 
832
{
 
833
    Vector3Type v = m_transform.positionToGridSpace( pos );
 
834
 
 
835
    T xCellId = floor( v[0] );
 
836
    T yCellId = floor( v[1] );
 
837
    T zCellId = floor( v[2] );
 
838
 
 
839
    *success = xCellId >= 0 && yCellId >=0 && zCellId >= 0 && xCellId < m_nbPosX - 1 && yCellId < m_nbPosY -1 && zCellId < m_nbPosZ -1;
 
840
 
 
841
    return xCellId + yCellId * ( m_nbPosX - 1 ) + zCellId * ( m_nbPosX - 1 ) * ( m_nbPosY - 1 );
 
842
}
 
843
 
 
844
template< typename T >
 
845
inline typename WGridRegular3DTemplate< T >::CellVertexArray WGridRegular3DTemplate< T >::getCellVertexIds( size_t cellId ) const
 
846
{
 
847
    typename WGridRegular3DTemplate< T >::CellVertexArray vertices;
 
848
    size_t minVertexIdZ =  cellId / ( ( m_nbPosX - 1 ) * ( m_nbPosY - 1 ) );
 
849
    size_t remainderXY = cellId - minVertexIdZ * ( ( m_nbPosX - 1 ) * ( m_nbPosY - 1 ) );
 
850
    size_t minVertexIdY = remainderXY  / ( m_nbPosX - 1 );
 
851
    size_t minVertexIdX = remainderXY % ( m_nbPosX - 1 );
 
852
 
 
853
    size_t minVertexId = minVertexIdX + minVertexIdY * m_nbPosX + minVertexIdZ * m_nbPosX * m_nbPosY;
 
854
 
 
855
    vertices[0] = minVertexId;
 
856
    vertices[1] = vertices[0] + 1;
 
857
    vertices[2] = minVertexId + m_nbPosX;
 
858
    vertices[3] = vertices[2] + 1;
 
859
    vertices[4] = minVertexId + m_nbPosX * m_nbPosY;
 
860
    vertices[5] = vertices[4] + 1;
 
861
    vertices[6] = vertices[4] + m_nbPosX;
 
862
    vertices[7] = vertices[6] + 1;
 
863
    return vertices;
 
864
}
 
865
 
 
866
template< typename T >
 
867
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
 
868
{
 
869
    typedef boost::shared_ptr< std::vector< Vector3Type > > ReturnType;
 
870
    ReturnType result = ReturnType( new std::vector< Vector3Type > );
 
871
    result->reserve( 8 );
 
872
    T halfMarginX = getOffsetX() / 2.0 - std::abs( margin );
 
873
    T halfMarginY = getOffsetY() / 2.0 - std::abs( margin );
 
874
    T halfMarginZ = getOffsetZ() / 2.0 - std::abs( margin );
 
875
    result->push_back( Vector3Type( point[0] - halfMarginX, point[1] - halfMarginY, point[2] - halfMarginZ ) ); // a
 
876
    result->push_back( Vector3Type( point[0] + halfMarginX, point[1] - halfMarginY, point[2] - halfMarginZ ) ); // b
 
877
    result->push_back( Vector3Type( point[0] + halfMarginX, point[1] - halfMarginY, point[2] + halfMarginZ ) ); // c
 
878
    result->push_back( Vector3Type( point[0] - halfMarginX, point[1] - halfMarginY, point[2] + halfMarginZ ) ); // d
 
879
    result->push_back( Vector3Type( point[0] - halfMarginX, point[1] + halfMarginY, point[2] - halfMarginZ ) ); // e
 
880
    result->push_back( Vector3Type( point[0] + halfMarginX, point[1] + halfMarginY, point[2] - halfMarginZ ) ); // f
 
881
    result->push_back( Vector3Type( point[0] + halfMarginX, point[1] + halfMarginY, point[2] + halfMarginZ ) ); // g
 
882
    result->push_back( Vector3Type( point[0] - halfMarginX, point[1] + halfMarginY, point[2] + halfMarginZ ) ); // h
 
883
    return result;
 
884
}
 
885
 
 
886
template< typename T >
 
887
std::vector< size_t > WGridRegular3DTemplate< T >::getNeighbours( size_t id ) const
 
888
{
 
889
    std::vector< size_t > neighbours;
 
890
    size_t x = id % m_nbPosX;
 
891
    size_t y = ( id / m_nbPosX ) % m_nbPosY;
 
892
    size_t z = id / ( m_nbPosX * m_nbPosY );
 
893
 
 
894
    if( x >= m_nbPosX || y >= m_nbPosY || z >= m_nbPosZ )
 
895
    {
 
896
        std::stringstream ss;
 
897
        ss << "This point: " << id << " is not part of this grid: ";
 
898
        ss << " nbPosX: " << m_nbPosX;
 
899
        ss << " nbPosY: " << m_nbPosY;
 
900
        ss << " nbPosZ: " << m_nbPosZ;
 
901
        throw WOutOfBounds( ss.str() );
 
902
    }
 
903
    // for every neighbour we must check if its not on the boundary, it will be skipped otherwise
 
904
    if( x > 0 )
 
905
    {
 
906
        neighbours.push_back( id - 1 );
 
907
    }
 
908
    if( x < m_nbPosX - 1 )
 
909
    {
 
910
        neighbours.push_back( id + 1 );
 
911
    }
 
912
    if( y > 0 )
 
913
    {
 
914
        neighbours.push_back( id - m_nbPosX );
 
915
    }
 
916
    if( y < m_nbPosY - 1 )
 
917
    {
 
918
        neighbours.push_back( id + m_nbPosX );
 
919
    }
 
920
    if( z > 0 )
 
921
    {
 
922
        neighbours.push_back( id - ( m_nbPosX * m_nbPosY ) );
 
923
    }
 
924
    if( z < m_nbPosZ - 1 )
 
925
    {
 
926
         neighbours.push_back( id + ( m_nbPosX * m_nbPosY ) );
 
927
    }
 
928
    return neighbours;
 
929
}
 
930
 
 
931
template< typename T >
 
932
std::vector< size_t > WGridRegular3DTemplate< T >::getNeighbours27( size_t id ) const
 
933
{
 
934
    std::vector< size_t > neighbours;
 
935
    size_t x = id % m_nbPosX;
 
936
    size_t y = ( id / m_nbPosX ) % m_nbPosY;
 
937
    size_t z = id / ( m_nbPosX * m_nbPosY );
 
938
 
 
939
    if( x >= m_nbPosX || y >= m_nbPosY || z >= m_nbPosZ )
 
940
    {
 
941
        std::stringstream ss;
 
942
        ss << "This point: " << id << " is not part of this grid: ";
 
943
        ss << " nbPosX: " << m_nbPosX;
 
944
        ss << " nbPosY: " << m_nbPosY;
 
945
        ss << " nbPosZ: " << m_nbPosZ;
 
946
        throw WOutOfBounds( ss.str() );
 
947
    }
 
948
    // for every neighbour we must check if its not on the boundary, it will be skipped otherwise
 
949
    std::vector< int >tempResult;
 
950
 
 
951
    tempResult.push_back( getVoxelNum( x    , y    , z ) );
 
952
    tempResult.push_back( getVoxelNum( x    , y - 1, z ) );
 
953
    tempResult.push_back( getVoxelNum( x    , y + 1, z ) );
 
954
    tempResult.push_back( getVoxelNum( x - 1, y    , z ) );
 
955
    tempResult.push_back( getVoxelNum( x - 1, y - 1, z ) );
 
956
    tempResult.push_back( getVoxelNum( x - 1, y + 1, z ) );
 
957
    tempResult.push_back( getVoxelNum( x + 1, y    , z ) );
 
958
    tempResult.push_back( getVoxelNum( x + 1, y - 1, z ) );
 
959
    tempResult.push_back( getVoxelNum( x + 1, y + 1, z ) );
 
960
 
 
961
    tempResult.push_back( getVoxelNum( x    , y    , z - 1 ) );
 
962
    tempResult.push_back( getVoxelNum( x    , y - 1, z - 1 ) );
 
963
    tempResult.push_back( getVoxelNum( x    , y + 1, z - 1 ) );
 
964
    tempResult.push_back( getVoxelNum( x - 1, y    , z - 1 ) );
 
965
    tempResult.push_back( getVoxelNum( x - 1, y - 1, z - 1 ) );
 
966
    tempResult.push_back( getVoxelNum( x - 1, y + 1, z - 1 ) );
 
967
    tempResult.push_back( getVoxelNum( x + 1, y    , z - 1 ) );
 
968
    tempResult.push_back( getVoxelNum( x + 1, y - 1, z - 1 ) );
 
969
    tempResult.push_back( getVoxelNum( x + 1, y + 1, z - 1 ) );
 
970
 
 
971
    tempResult.push_back( getVoxelNum( x    , y    , z + 1 ) );
 
972
    tempResult.push_back( getVoxelNum( x    , y - 1, z + 1 ) );
 
973
    tempResult.push_back( getVoxelNum( x    , y + 1, z + 1 ) );
 
974
    tempResult.push_back( getVoxelNum( x - 1, y    , z + 1 ) );
 
975
    tempResult.push_back( getVoxelNum( x - 1, y - 1, z + 1 ) );
 
976
    tempResult.push_back( getVoxelNum( x - 1, y + 1, z + 1 ) );
 
977
    tempResult.push_back( getVoxelNum( x + 1, y    , z + 1 ) );
 
978
    tempResult.push_back( getVoxelNum( x + 1, y - 1, z + 1 ) );
 
979
    tempResult.push_back( getVoxelNum( x + 1, y + 1, z + 1 ) );
 
980
 
 
981
    for( size_t k = 0; k < tempResult.size(); ++k )
 
982
    {
 
983
        if( tempResult[k] != -1 )
 
984
        {
 
985
            neighbours.push_back( tempResult[k] );
 
986
        }
 
987
    }
 
988
    return neighbours;
 
989
}
 
990
 
 
991
template< typename T >
 
992
std::vector< size_t > WGridRegular3DTemplate< T >::getNeighboursRange( size_t id, size_t range ) const
 
993
{
 
994
    std::vector< size_t > neighbours;
 
995
    size_t x = id % m_nbPosX;
 
996
    size_t y = ( id / m_nbPosX ) % m_nbPosY;
 
997
    size_t z = id / ( m_nbPosX * m_nbPosY );
 
998
 
 
999
    if( x >= m_nbPosX || y >= m_nbPosY || z >= m_nbPosZ )
 
1000
    {
 
1001
        std::stringstream ss;
 
1002
        ss << "This point: " << id << " is not part of this grid: ";
 
1003
        ss << " nbPosX: " << m_nbPosX;
 
1004
        ss << " nbPosY: " << m_nbPosY;
 
1005
        ss << " nbPosZ: " << m_nbPosZ;
 
1006
        throw WOutOfBounds( ss.str() );
 
1007
    }
 
1008
    // for every neighbour we must check if its not on the boundary, it will be skipped otherwise
 
1009
    std::vector< int >tempResult;
 
1010
 
 
1011
    for( size_t xx = x - range; xx < x + range + 1; ++xx )
 
1012
    {
 
1013
        for( size_t yy = y - range; yy < y + range + 1; ++yy )
 
1014
        {
 
1015
            for( size_t zz = z - range; zz < z + range + 1; ++zz )
 
1016
            {
 
1017
                tempResult.push_back( getVoxelNum( xx, yy, zz ) );
 
1018
            }
 
1019
        }
 
1020
    }
 
1021
 
 
1022
    for( size_t k = 0; k < tempResult.size(); ++k )
 
1023
    {
 
1024
        if( tempResult[k] != -1 )
 
1025
        {
 
1026
            neighbours.push_back( tempResult[k] );
 
1027
        }
 
1028
    }
 
1029
    return neighbours;
 
1030
}
 
1031
 
 
1032
template< typename T >
 
1033
std::vector< size_t > WGridRegular3DTemplate< T >::getNeighbours9XY( size_t id ) const
 
1034
{
 
1035
    std::vector< size_t > neighbours;
 
1036
    size_t x = id % m_nbPosX;
 
1037
    size_t y = ( id / m_nbPosX ) % m_nbPosY;
 
1038
    size_t z = id / ( m_nbPosX * m_nbPosY );
 
1039
 
 
1040
    if( x >= m_nbPosX || y >= m_nbPosY || z >= m_nbPosZ )
 
1041
    {
 
1042
        std::stringstream ss;
 
1043
        ss << "This point: " << id << " is not part of this grid: ";
 
1044
        ss << " nbPosX: " << m_nbPosX;
 
1045
        ss << " nbPosY: " << m_nbPosY;
 
1046
        ss << " nbPosZ: " << m_nbPosZ;
 
1047
        throw WOutOfBounds( ss.str() );
 
1048
    }
 
1049
    // boundary check now happens in the getVoxelNum function
 
1050
    int vNum;
 
1051
 
 
1052
    vNum = getVoxelNum( x - 1, y, z );
 
1053
    if( vNum != -1 )
 
1054
    {
 
1055
        neighbours.push_back( vNum );
 
1056
    }
 
1057
    vNum = getVoxelNum( x - 1, y - 1, z );
 
1058
    if( vNum != -1 )
 
1059
    {
 
1060
        neighbours.push_back( vNum );
 
1061
    }
 
1062
    vNum = getVoxelNum( x, y - 1, z );
 
1063
    if( vNum != -1 )
 
1064
    {
 
1065
        neighbours.push_back( vNum );
 
1066
    }
 
1067
    vNum = getVoxelNum( x + 1, y - 1, z );
 
1068
    if( vNum != -1 )
 
1069
    {
 
1070
        neighbours.push_back( vNum );
 
1071
    }
 
1072
    vNum = getVoxelNum( x + 1, y, z );
 
1073
    if( vNum != -1 )
 
1074
    {
 
1075
        neighbours.push_back( vNum );
 
1076
    }
 
1077
    vNum = getVoxelNum( x + 1, y + 1, z );
 
1078
    if( vNum != -1 )
 
1079
    {
 
1080
        neighbours.push_back( vNum );
 
1081
    }
 
1082
    vNum = getVoxelNum( x, y + 1, z );
 
1083
    if( vNum != -1 )
 
1084
    {
 
1085
        neighbours.push_back( vNum );
 
1086
    }
 
1087
    vNum = getVoxelNum( x - 1, y + 1, z );
 
1088
    if( vNum != -1 )
 
1089
    {
 
1090
        neighbours.push_back( vNum );
 
1091
    }
 
1092
    return neighbours;
 
1093
}
 
1094
 
 
1095
template< typename T >
 
1096
std::vector< size_t > WGridRegular3DTemplate< T >::getNeighbours9YZ( size_t id ) const
 
1097
{
 
1098
    std::vector< size_t > neighbours;
 
1099
    size_t x = id % m_nbPosX;
 
1100
    size_t y = ( id / m_nbPosX ) % m_nbPosY;
 
1101
    size_t z = id / ( m_nbPosX * m_nbPosY );
 
1102
 
 
1103
    if( x >= m_nbPosX || y >= m_nbPosY || z >= m_nbPosZ )
 
1104
    {
 
1105
        std::stringstream ss;
 
1106
        ss << "This point: " << id << " is not part of this grid: ";
 
1107
        ss << " nbPosX: " << m_nbPosX;
 
1108
        ss << " nbPosY: " << m_nbPosY;
 
1109
        ss << " nbPosZ: " << m_nbPosZ;
 
1110
        throw WOutOfBounds( ss.str() );
 
1111
    }
 
1112
    // boundary check now happens in the getVoxelNum function
 
1113
    int vNum;
 
1114
 
 
1115
    vNum = getVoxelNum( x, y, z - 1 );
 
1116
    if( vNum != -1 )
 
1117
    {
 
1118
        neighbours.push_back( vNum );
 
1119
    }
 
1120
    vNum = getVoxelNum( x, y - 1, z - 1 );
 
1121
    if( vNum != -1 )
 
1122
    {
 
1123
        neighbours.push_back( vNum );
 
1124
    }
 
1125
    vNum = getVoxelNum( x, y - 1, z );
 
1126
    if( vNum != -1 )
 
1127
    {
 
1128
        neighbours.push_back( vNum );
 
1129
    }
 
1130
    vNum = getVoxelNum( x, y - 1, z + 1 );
 
1131
    if( vNum != -1 )
 
1132
    {
 
1133
        neighbours.push_back( vNum );
 
1134
    }
 
1135
    vNum = getVoxelNum( x, y, z + 1 );
 
1136
    if( vNum != -1 )
 
1137
    {
 
1138
        neighbours.push_back( vNum );
 
1139
    }
 
1140
    vNum = getVoxelNum( x, y + 1, z + 1 );
 
1141
    if( vNum != -1 )
 
1142
    {
 
1143
        neighbours.push_back( vNum );
 
1144
    }
 
1145
    vNum = getVoxelNum( x, y + 1, z );
 
1146
    if( vNum != -1 )
 
1147
    {
 
1148
        neighbours.push_back( vNum );
 
1149
    }
 
1150
    vNum = getVoxelNum( x, y + 1, z - 1 );
 
1151
    if( vNum != -1 )
 
1152
    {
 
1153
        neighbours.push_back( vNum );
 
1154
    }
 
1155
 
 
1156
    return neighbours;
 
1157
}
 
1158
 
 
1159
template< typename T >
 
1160
std::vector< size_t > WGridRegular3DTemplate< T >::getNeighbours9XZ( size_t id ) const
 
1161
{
 
1162
    std::vector< size_t > neighbours;
 
1163
    size_t x = id % m_nbPosX;
 
1164
    size_t y = ( id / m_nbPosX ) % m_nbPosY;
 
1165
    size_t z = id / ( m_nbPosX * m_nbPosY );
 
1166
 
 
1167
    if( x >= m_nbPosX || y >= m_nbPosY || z >= m_nbPosZ )
 
1168
    {
 
1169
        std::stringstream ss;
 
1170
        ss << "This point: " << id << " is not part of this grid: ";
 
1171
        ss << " nbPosX: " << m_nbPosX;
 
1172
        ss << " nbPosY: " << m_nbPosY;
 
1173
        ss << " nbPosZ: " << m_nbPosZ;
 
1174
        throw WOutOfBounds( ss.str() );
 
1175
    }
 
1176
    // boundary check now happens in the getVoxelNum function
 
1177
    int vNum;
 
1178
 
 
1179
    vNum = getVoxelNum( x, y, z - 1 );
 
1180
    if( vNum != -1 )
 
1181
    {
 
1182
        neighbours.push_back( vNum );
 
1183
    }
 
1184
    vNum = getVoxelNum( x - 1, y, z - 1 );
 
1185
    if( vNum != -1 )
 
1186
    {
 
1187
        neighbours.push_back( vNum );
 
1188
    }
 
1189
    vNum = getVoxelNum( x - 1, y, z );
 
1190
    if( vNum != -1 )
 
1191
    {
 
1192
        neighbours.push_back( vNum );
 
1193
    }
 
1194
    vNum = getVoxelNum( x - 1, y, z + 1 );
 
1195
    if( vNum != -1 )
 
1196
    {
 
1197
        neighbours.push_back( vNum );
 
1198
    }
 
1199
    vNum = getVoxelNum( x, y, z + 1 );
 
1200
    if( vNum != -1 )
 
1201
    {
 
1202
        neighbours.push_back( vNum );
 
1203
    }
 
1204
    vNum = getVoxelNum( x + 1, y, z + 1 );
 
1205
    if( vNum != -1 )
 
1206
    {
 
1207
        neighbours.push_back( vNum );
 
1208
    }
 
1209
    vNum = getVoxelNum( x + 1, y, z );
 
1210
    if( vNum != -1 )
 
1211
    {
 
1212
        neighbours.push_back( vNum );
 
1213
    }
 
1214
    vNum = getVoxelNum( x + 1, y, z - 1 );
 
1215
    if( vNum != -1 )
 
1216
    {
 
1217
        neighbours.push_back( vNum );
 
1218
    }
 
1219
 
 
1220
    return neighbours;
 
1221
}
 
1222
 
 
1223
template< typename T >
 
1224
inline bool WGridRegular3DTemplate< T >::encloses( WGridRegular3DTemplate< T >::Vector3Type const& pos ) const
 
1225
{
 
1226
    Vector3Type v = m_transform.positionToGridSpace( pos );
 
1227
 
 
1228
    if( v[ 0 ] < T( 0.0 ) || v[ 0 ] >= static_cast< T >( m_nbPosX - 1 ) )
 
1229
    {
 
1230
        return false;
 
1231
    }
 
1232
    if( v[ 1 ] < T( 0.0 ) || v[ 1 ] >= static_cast< T >( m_nbPosY - 1 ) )
 
1233
    {
 
1234
        return false;
 
1235
    }
 
1236
    if( v[ 2 ] < T( 0.0 ) || v[ 2 ] >= static_cast< T >( m_nbPosZ - 1 ) )
 
1237
    {
 
1238
        return false;
 
1239
    }
 
1240
    return true;
 
1241
}
 
1242
 
 
1243
template< typename T >
 
1244
inline bool WGridRegular3DTemplate< T >::isNotRotated() const
 
1245
{
 
1246
    return m_transform.isNotRotated();
 
1247
}
 
1248
 
 
1249
template< typename T >
 
1250
inline WGridTransformOrthoTemplate< T > const WGridRegular3DTemplate< T >::getTransform() const
 
1251
{
 
1252
    return m_transform;
 
1253
}
 
1254
 
 
1255
template< typename T >
 
1256
void WGridRegular3DTemplate< T >::initInformationProperties()
 
1257
{
 
1258
    WPropInt xDim = m_infoProperties->addProperty( "X dimension: ",
 
1259
                                                   "The x dimension of the grid.",
 
1260
                                                   static_cast<int>( getNbCoordsX() ) );
 
1261
    WPropInt yDim = m_infoProperties->addProperty( "Y dimension: ",
 
1262
                                                   "The y dimension of the grid.",
 
1263
                                                   static_cast<int>( getNbCoordsY() ) );
 
1264
    WPropInt zDim = m_infoProperties->addProperty( "Z dimension: ",
 
1265
                                                   "The z dimension of the grid.",
 
1266
                                                   static_cast<int>( getNbCoordsZ() ) );
 
1267
 
 
1268
    WPropDouble xOffset = m_infoProperties->addProperty( "X offset: ",
 
1269
                                                         "The distance between samples in x direction",
 
1270
                                                         static_cast< double >( getOffsetX() ) );
 
1271
    WPropDouble yOffset = m_infoProperties->addProperty( "Y offset: ",
 
1272
                                                         "The distance between samples in y direction",
 
1273
                                                         static_cast< double >( getOffsetY() ) );
 
1274
    WPropDouble zOffset = m_infoProperties->addProperty( "Z offset: ",
 
1275
                                                         "The distance between samples in z direction",
 
1276
                                                         static_cast< double >( getOffsetZ() ) );
 
1277
}
 
1278
 
 
1279
template< typename T >
 
1280
bool WGridRegular3DTemplate< T >::operator==( const WGridRegular3DTemplate< T >& other ) const
 
1281
{
 
1282
    return ( getNbCoordsX() == other.getNbCoordsX() ) &&
 
1283
           ( getNbCoordsY() == other.getNbCoordsY() ) &&
 
1284
           ( getNbCoordsZ() == other.getNbCoordsZ() ) &&
 
1285
           ( m_transform == other.m_transform );
 
1286
}
 
1287
 
 
1288
// +----------------------+
 
1289
// | non-member functions |
 
1290
// +----------------------+
 
1291
 
 
1292
/**
 
1293
 * Convinience function returning all offsets per axis.
 
1294
 * 0 : xAxis, 1 : yAxis, 2 : zAxis
 
1295
 * \param grid The grid having the information.
 
1296
 * \note Implementing this as NonMemberNonFriend was intentional.
 
1297
 * \return Array of number of samples per axis.
 
1298
 */
 
1299
template< typename T >
 
1300
inline boost::array< T, 3 > getOffsets( boost::shared_ptr< const WGridRegular3DTemplate< T > > grid )
 
1301
{
 
1302
    boost::array< T, 3 > result = { { grid->getOffsetX(), grid->getOffsetY(), grid->getOffsetZ() } }; // NOLINT curly braces
 
1303
    return result;
 
1304
}
 
1305
 
 
1306
/**
 
1307
 * Convinience function returning all number coords per axis.
 
1308
 * 0 : xAxis, 1 : yAxis, 2 : zAxis
 
1309
 * \param grid The grid having the information.
 
1310
 * \note Implementing this as NonMemberNonFriend was intentional.
 
1311
 * \return Array of number of samples per axis.
 
1312
 */
 
1313
template< typename T >
 
1314
inline boost::array< unsigned int, 3 > getNbCoords( boost::shared_ptr< const WGridRegular3DTemplate< T > > grid )
 
1315
{
 
1316
    boost::array< unsigned int, 3 > result = { { grid->getNbCoordsX(), grid->getNbCoordsY(), grid->getNbCoordsZ() } }; // NOLINT curly braces
 
1317
    return result;
 
1318
}
 
1319
 
 
1320
/**
 
1321
 * Convinience function returning all axis directions.
 
1322
 * 0 : xAxis, 1 : yAxis, 2 : zAxis
 
1323
 * \param grid The grid having the information.
 
1324
 * \note Implementing this as NonMemberNonFriend was intentional.
 
1325
 * \return The direction of each axis as array
 
1326
 */
 
1327
template< typename T >
 
1328
inline boost::array< typename WGridRegular3DTemplate< T >::Vector3Type, 3 > getDirections( boost::shared_ptr< const WGridRegular3DTemplate< T > > grid ) // NOLINT -- too long line
 
1329
{
 
1330
    boost::array< typename WGridRegular3DTemplate< T >::Vector3Type, 3 > result = { { grid->getDirectionX(), grid->getDirectionY(), grid->getDirectionZ() } }; // NOLINT curly braces
 
1331
    return result;
 
1332
}
 
1333
 
 
1334
/**
 
1335
 * Convinience function returning all axis unit directions.
 
1336
 * 0 : xAxis, 1 : yAxis, 2 : zAxis
 
1337
 * \param grid The grid having the information.
 
1338
 * \note Implementing this as NonMemberNonFriend was intentional.
 
1339
 * \return The direction of each axis as array
 
1340
 */
 
1341
template< typename T >
 
1342
inline boost::array< typename WGridRegular3DTemplate< T >::Vector3Type, 3 > getUnitDirections( boost::shared_ptr< const WGridRegular3DTemplate< T > > grid ) // NOLINT -- too long line
 
1343
{
 
1344
    boost::array< typename WGridRegular3DTemplate< T >::Vector3Type, 3 > result = { { grid->getUnitDirectionX(), grid->getUnitDirectionY(), grid->getUnitDirectionZ() } }; // NOLINT curly braces
 
1345
    return result;
 
1346
}
 
1347
 
 
1348
#endif  // WGRIDREGULAR3D_H