Salome HOME
Merge branch 'V9_9_BR'
[modules/smesh.git] / src / SMESHUtils / SMESH_Indexer.hxx
1 // Copyright (C) 2007-2022  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 // File      : SMESH_Indexer.hxx
23 // Created   : Tue May 21 18:24:01 2019
24 // Author    : Edward AGAPOV (eap)
25
26
27 #ifndef __SMESH_Indexer_HXX__
28 #define __SMESH_Indexer_HXX__
29
30 //================================================================================
31 /*!
32  * \brief Converter of a pair of indices to a sole index, useful to make
33  *        1D array behave as 2D one
34  */
35 struct SMESH_Indexer
36 {
37   size_t _xSize, _ySize;
38
39   //! Initialize with size in two directions
40   SMESH_Indexer( size_t xSize=0, size_t ySize=0 ): _xSize(xSize), _ySize(ySize) {}
41
42   //! set size
43   void set(size_t xSize, size_t ySize ) { _xSize = xSize, _ySize = ySize; }
44
45   //! \return size of 1D array
46   size_t size() const { return _xSize * _ySize; }
47
48   // \return 1D index by two indices
49   size_t operator()(size_t x, size_t y) const { return y * _xSize + x; }
50 };
51
52 //================================================================================
53 /*!
54  * \brief Converter of a triple of indices to a sole index, useful to make
55  *        1D array behave as 3D one
56  */
57 struct SMESH_Indexer3D
58 {
59   size_t _xSize, _ySize, _zSize;
60
61   //! Initialize with size in two directions
62   SMESH_Indexer3D( size_t xSize=0, size_t ySize=0, size_t zSize=0 ):
63     _xSize(xSize), _ySize(ySize), _zSize(zSize) {}
64
65   //! set size
66   void set(size_t xSize, size_t ySize, size_t zSize )
67   { _xSize = xSize, _ySize = ySize, _zSize = zSize; }
68
69   //! \return size of 1D array
70   size_t size() const { return _xSize * _ySize * _zSize; }
71
72   // \return 1D index by three indices
73   size_t operator()(size_t x, size_t y, size_t z) const { return z*_xSize*_ySize +  y*_xSize + x; }
74 };
75
76 //================================================================================
77 /*!
78  * \brief Oriented converter of a pair of integers to a sole index
79  *
80  * Allows virtual transformation of an 1D array viewed as 2D one.
81  * Possible transformations are inverse in one or two directions and exchange of
82  * the directions. Any combination of these transformations is allowed.
83  *
84  * The following code picks up a transformation such that two known array items
85  * appear in desired positions:
86  * \code
87  * for ( int ori = 0; ori < SMESH_OrientedIndexer::MAX_ORI+1; ++ori )
88  * {
89  *   SMESH_OrientedIndexer oriIndex( index, ori );
90  *   if ( item1 == array[ oriIndex( i1, j1 ) ] &&
91  *        item2 == array[ oriIndex( i2, j2 ) ])
92  *   {
93  *     // needed transformation found
94  *   }
95  * }
96  * \endcode
97  */
98 class SMESH_OrientedIndexer : public SMESH_Indexer
99 {
100   typedef SMESH_Indexer TFather;
101 public:
102   enum OriFlags //!< transformation types
103     {
104       NO_TRSF = 0, REV_X = 1, REV_Y = 2, SWAP_XY = 4, MAX_ORI = REV_X|REV_Y|SWAP_XY
105     };
106
107   SMESH_OrientedIndexer( const SMESH_Indexer& indexer, const int oriFlags = NO_TRSF):
108     TFather( indexer._xSize, indexer._ySize ),
109     _xRevFun( (oriFlags & REV_X) ? & reverse : & lazy ),
110     _yRevFun( (oriFlags & REV_Y) ? & reverse : & lazy ),
111     _swapFun( (oriFlags & SWAP_XY ) ? & swap : & lazy ),
112     _xSizeOriented( indexer._xSize ),
113     _ySizeOriented( indexer._ySize )
114   {
115     (*_swapFun)( _xSizeOriented, _ySizeOriented );
116   }
117
118   //!< Return index by XY
119   size_t operator()(size_t x, size_t y) const
120   {
121     (*_swapFun)( x, y );
122     (*_xRevFun)( x, const_cast< size_t& >( _xSize ));
123     (*_yRevFun)( y, const_cast< size_t& >( _ySize ));
124     return TFather::operator()( x, y );
125   }
126
127   //!< Return index for a corner
128   size_t corner(bool xMax, bool yMax) const
129   {
130     size_t x = xMax, y = yMax, size = 2;
131     (*_swapFun)( x, y );
132     (*_xRevFun)( x, size );
133     (*_yRevFun)( y, size );
134     return TFather::operator()( x ? _xSize-1 : 0,
135                                 y ? _ySize-1 : 0 );
136   }
137   size_t xSize() const { return _xSizeOriented; }
138   size_t ySize() const { return _ySizeOriented; }
139
140 private:
141
142   typedef void (*TFun)(size_t& x, size_t& y);
143   TFun _xRevFun, _yRevFun, _swapFun;
144
145   size_t _xSizeOriented, _ySizeOriented;
146
147   static void lazy   (size_t&  , size_t& ) {}
148   static void reverse(size_t& x, size_t& size) { x = size - x - 1; }
149   static void swap   (size_t& x, size_t& y) { std::swap( x, y ); }
150 };
151
152
153 #endif