Changeset 131


Ignore:
Timestamp:
06/24/13 21:31:15 (12 years ago)
Author:
shark
Message:
  • array2d::resize() copies over data if preserve parameter is true. Also confirms that the size changed and won't do anything if it hasn't.
  • array2d::get_sub_array [2 overloads] and array2d::set_sub_array [6 overloads] added.
  • array2d::clone() added.
  • Added a third constructor (takes dimensions of array separate instead of in a vector) for convenience.
  • Added documentation.
  • Needs some testing to make sure the math is all correct.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/nv/array2d.hh

    r130 r131  
    1111 */
    1212
    13 // TODO: implement copy on resize! See image::set_region
    14 // TODO: implement set sub_array or something like that
    1513// TODO: make it work with the stl allocator
    1614
     
    3735                typedef const_pointer     const_iterator;
    3836
     37                /**
     38                 *Creates a new 2D array.
     39                 */
    3940                array2d() : m_size(), m_data( nullptr ) {}
     41
     42                /**
     43                 *Creates a new 2D array.
     44                 *
     45                 *@param asize The dimensions of the new array.
     46                 */
    4047                array2d( const ivec2& asize ) : m_size(), m_data( nullptr ) { resize( asize ); }
     48
     49                /**
     50                 *Creates a new 2D array.
     51                 *
     52                 *@param asize_x The width of the new array.
     53                 *@param asize_y The height of the new array.
     54                 */
     55                array2d( const sint32 asize_x, const sint32 asize_y ) : m_size(), m_data( nullptr ) { resize( new ivec2( asize_x, asize_y ) ); }
    4156               
     57                /**
     58                 *Gets the dimensions of the array.
     59                 *
     60                 *@returns The size of the array.
     61                 */
    4262                const ivec2& size() const { return m_size; }
     63
     64                /**
     65                 *Gets a pointer to the data in the array.
     66                 *
     67                 *@returns A pointer to the data in the array.
     68                 */
    4369                pointer data() { return m_data; }
     70
     71                /**
     72                 *Gets a constant pointer to the data in the array.
     73                 *
     74                 *@returns A constant pointer to the data in the array.
     75                 */
    4476                const_pointer data() const { return m_data; }
    4577
    46                 void resize( const ivec2& new_size )
    47                 {
     78                /**
     79                 *Changes the dimensions of the array.
     80                 *
     81                 *@param new_size The new dimensions of the array.
     82                 *@param preserve True to keep as much of the existing data as will fit in the new array, False to discard the existing data.
     83                 */
     84                void resize( const ivec2& new_size, bool preserve = false )
     85                {
     86                        if (new_size == m_size) return; // Don't do anything if the sizes are the same.
     87
    4888                        pointer new_data = new value_type[ new_size.x * new_size.y ];
    4989                        if ( m_data != nullptr )
    5090                        {
    51                                 // TODO: implement copy! See image::set_region
    52                                 delete[] m_data;
     91                                if (!preserve)
     92                                {
     93                                        // Just delete the data.
     94                                        delete[] m_data;
     95                                }
     96                                else
     97                                {
     98                                        // Copy the data.  Truncates the bottom or right side of the data if destination is smaller.
     99                                        for ( sint32 i = 0; i < min(new_size.y, m_size.y); i++ )
     100                                        {
     101                                                std::copy( m_data + m_size.x * i, m_data + m_size.x * i + min( new_size.x, m_size.x ), new_data + m_size.x * i );
     102                                        }
     103                                        // ...then delete the original data.
     104                                        delete[] m_data;
     105                                }
    53106                        }
    54107                        m_data = new_data;
     
    56109                }
    57110
     111                /**
     112                 *Gets a pointer to the start of the array.
     113                 *
     114                 *@returns A pointer to the first position in the array.
     115                 */
    58116                iterator       begin()       { return m_data; }
     117
     118                /**
     119                 *Gets a constant pointer to the start of the array.
     120                 *
     121                 *@returns A constant pointer to the first position in the array.
     122                 */
    59123                const_iterator begin() const { return m_data; }
     124
     125                /**
     126                 *Gets a pointer to the end of the array.
     127                 *
     128                 *@returns A pointer to the end of the array.
     129                 */
    60130                iterator       end()         { return m_data + ( m_size.x * m_size.y ); }
     131
     132                /**
     133                 *Gets a constant pointer to the end of the array.
     134                 *
     135                 *@returns A constant pointer to the end of the array.
     136                 */
    61137                const_iterator end() const   { return m_data + ( m_size.x * m_size.y ); }
    62138
     139
     140                /**
     141                 *Looks up a position by X and Y value.
     142                 *
     143                 *@param x The X position of the array to look up.
     144                 *@param y The Y position of the array to look up.
     145                 *@returns A reference to the data at the indicated position.
     146                 */
    63147                inline const_reference operator() ( sint32 x, sint32 y ) const
    64148                {
     
    66150                        return m_data[ y * m_size.x + x ];
    67151                }
     152
     153                /**
     154                 *Looks up a position by X and Y value.
     155                 *
     156                 *@param x The X position of the array to look up.
     157                 *@param y The Y position of the array to look up.
     158                 *@returns A reference to the data at the indicated position.
     159                 */
    68160                inline reference operator() ( sint32 x, sint32 y )
    69161                {
     
    71163                        return m_data[ y * m_size.x + x ];
    72164                }
     165
     166                /**
     167                 *Looks up the given position in the array.
     168                 *
     169                 *@param c The position to look up.
     170                 *@returns A reference to the data at the indicated position.
     171                 */
    73172                inline const_reference operator[] ( const ivec2& c ) const
    74173                {
     
    76175                        return m_data[ c.y * m_size.x + c.x ];
    77176                }
     177
     178                /**
     179                 *Looks up the given position in the array.
     180                 *
     181                 *@param c The position to look up.
     182                 *@returns A reference to the data at the indicated position.
     183                 */
    78184                inline reference operator[] ( const ivec2& c )
    79185                {
     
    82188                }
    83189
     190                /**
     191                 *Returns a copy of this array in a new instance.
     192                 *
     193                 *@returns An independent copy of this array.
     194                 */
     195                array2d<T> clone()
     196                {
     197                        array2d<T> temp = new array2d<T>(m_size);
     198                        for ( sint32 i = 0; i < m_size.y; i++ )
     199                        {
     200                                std::copy( m_data + m_size.x * i, m_data + m_size.x * i + m_size.x, m_size.x * i );
     201                        }
     202                        return temp;
     203                }
     204
     205                /**
     206                 *Returns an array that represents a subset of the data in this array.
     207                 *
     208                 *@param start The upper and left bounds of data to retrieve.
     209                 *@param size The width and height of the data to retrieve.
     210                 *@returns A new 2D array containing the subset of data within the bounds specified.
     211                 */
     212                array2d<T> get_sub_array( const ivec2& start, const ivec2& size ) {     return get_sub_array( start.x, start.y, size.x, size.y ); }
     213                /**
     214                 *Returns an array that represents a subset of the data in this array.
     215                 *
     216                 *@param start_x The left bound of the data to retrieve.
     217                 *@param start_y The upper bound of the data to retrieve.
     218                 *@param size_x The width of the data to retrieve.
     219                 *@param size_y The height of the data to retrieve.
     220                 *@returns A new 2D array containing the subset of data within the bounds specified.
     221                 */
     222                array2d<T> get_sub_array( const sint32 start_x, const sint32 start_y, const sint32 size_x, const sint32 size_y)
     223                {
     224                        // Make sure the parameters are correct and in bounds.
     225                        NV_ASSERT( start_x >= 0 && start_x < m_size.x && start_y >= 0 && start_y < m_size.y, "get_sub_array: start is out of bounds." );
     226                        NV_ASSERT( size_x >= 1 && size_x + start_x <= m_size.x && size_y >= 1 && size_y + start_y <= m_size.y, "get_sub_array: size is invalid." );
     227                        // Empty holder for the sub array of the correct size.
     228                        array2d<T> temp = new array2d<T>( size_x, size_y );
     229                        for ( sint32 i = start_y; i < start_y + size_y; i++ )
     230                        {
     231                                // Copy starts at start_x.
     232                                // Copy end is the end position.
     233                                // Destination is the start of the destination row.
     234                                //         Start                              End                                         Destination
     235                                std::copy( m_data + m_size().x * i + start_x, m_data + m_size().x * i + start_x + size_x, temp.m_data + temp.m_size().x * ( i - start_y ) );
     236                        }
     237                        return temp;
     238                }
     239
     240                /**
     241                 *Fills this array with another array.
     242                 *
     243                 *@param source The array to fill with.  If it does not fit in the destination it will be truncated.
     244                 *@param dest_start The upper and left bounds of the data to fill.
     245                 */
     246                void set_sub_array( const array2d<T> source, const ivec2& dest_start )
     247                {
     248                        return set_sub_array( source, dest_start.x, dest_start.y, 0, 0, source.m_size.x, source.m_size.y );
     249                }
     250
     251                /**
     252                 *Fills this array with a subset of another array.
     253                 *
     254                 *@param source The arrya to fill with.  If it does not fit in the destination it will be truncated.
     255                 *@param dest_start The upper and left bounds of the data to fill.
     256                 *@param size The size of the area to copy over.
     257                 */
     258                void set_sub_array( const array2d<T> source, const ivec2& dest_start, const ivec2& size )
     259                {
     260                        return set_sub_array( source, dest_start.x, dest_start.y, 0, 0, size.x, size.y );
     261                }
     262
     263
     264                /**
     265                 *Fills this array with a subset of another array.
     266                 *
     267                 *@param source The array to fill with.  If it does not fit in the destination it will be truncated.
     268                 *@param dest_start The upper and left bounds of the data to fill.
     269                 *@param source_start The upper and left bounds of the source to fill with.
     270                 *@param size The size of the area to copy over.
     271                 */
     272                void set_sub_array( const array2d<T> source, const ivec2& dest_start, const ivec2& source_start, const ivec2& size )
     273                {
     274                        return set_sub_array( source, dest_start.x, dest_start.y, source_start.x, source_start.y, size.x, size.y );
     275                }
     276
     277                /**
     278                 *Fills this array with another array.
     279                 *
     280                 *@param source The array to fill with.  If it does not fit in the area to fill, it will be truncated.
     281                 *@param dest_start_x The left bound of the data to fill.
     282                 *@param dest_start_y The upper bound of the data to fill.
     283                 */
     284                void set_sub_array( const array2d<T> source, const sint32 dest_start_x, const sint32 dest_start_y )
     285                {
     286                        return set_sub_array( source, dest_start_x, dest_start_y, 0, 0, source.m_size.x, source.m_size.y );
     287                }
     288
     289                /**
     290                 *Fills this array with another array.
     291                 *
     292                 *@param source The array to fill with.  If it does not fit in the area to fill, it will be truncated.
     293                 *@param dest_start_x The left bound of the data to fill.
     294                 *@param dest_start_y The upper bound of the data to fill.
     295                 *@param size_x The width of the area to copy over.
     296                 *@param size_y The height of the area to copy over.
     297                 */
     298                void set_sub_array( const array2d<T> source, const sint32 dest_start_x, const sint32 dest_start_y, const sint32 size_x, const sint32 size_y )
     299                {
     300                        return set_sub_array( source, dest_start_x, dest_start_y, 0, 0, size_x, size_y );
     301                }
     302
     303                /**
     304                 *Fills this array with a subset of another array.
     305                 *
     306                 *@param source The array to fill with.  If it does not fit in the area to fill, it will be truncated.
     307                 *@param dest_start_x The left bound of the data to fill.
     308                 *@param dest_start_y The upper bound of the data to fill.
     309                 *@param source_start_x The left bound of the source to fill with.
     310                 *@param source_start_y The upper bound of the source to fill with.
     311                 *@param size_x The width of the area to copy over.
     312                 *@param size_y The height of the area to copy over.
     313                 */
     314                void set_sub_array( const array2d<T> source, const sint32 dest_start_x, const sint32 dest_start_y, const sint32 source_start_x, const sint32 source_start_y, const sint32 size_x, const sint32 size_y )
     315                {
     316                        // Start by checking the parameters.  Make sure nothing is out of bounds.
     317                        NV_ASSERT( source != nullptr, "set_sub_array: no source defined." );
     318                        NV_ASSERT( dest_start_x >= 0 && dest_start_x < m_size.x && dest_start_y >= 0 && dest_start_y < m_size.y, "set_sub_array: destination start is out of bounds." );
     319                        NV_ASSERT( source_start_x >= 0 && source_start_x < source.m_size.x && source_start_y >= 0 && source_start_y < source.m_size.y, "set_sub_array: source start is out of bounds." );
     320                        NV_ASSERT( size_x >= 1 && size_y >= 1, "set_sub_array: invalid size specified." ); // If size is 0, nothing would be copied in the first place.
     321               
     322                        // Warn when copied data is truncated.
     323                        // If the end of the copied area is beyond the bounds of the destination array, data will be truncated.
     324                        if ( dest_start_x + min(size_x, source.m_size.x - source_start_x) > m_size.x || dest_start_y + min(size_y, source.m_size.y - source_start_y) > m_size.y )
     325                        {
     326                                NV_LOG( LOG_WARNING, "set_sub_array: Source area does not fit in the destination area.  Data will be truncated." );
     327                        }
     328               
     329                        // Copy into THIS array from source the following.
     330                        // Highest row is either the size limit or the end of either array, whichever is smaller.
     331                        for ( i = 0; i < min( size_y , min ( m_size.y - dest_start_y, source.m_size.y - source_start_y ) ); i++ )
     332                        {
     333                                // Copy the indicated row.
     334                                // The start position is the beginning of the current row (which is source_start_y + i), offset by source_start_x.
     335                                // The end position is either the size limit or the end of either array, whichever is smaller.
     336                                // Destination start is the beginning of the current destination row (which is dest_start_y + i), offset by dest_start_x.
     337                                std:copy( source.m_data + ( source_start_y + i ) * source.m_size.x + source_start_x,  // Source Start
     338                                                  source.m_data + ( source_start_y + i ) * source.m_size.x + min( source.m_size.x, min( source_start_x + size_x, source_start_x + m_size.x - dest_start_x ) ), // Source End
     339                                                  m_data + (dest_start_y + i) * m_size.x + dest_start_x ) // Destination Start
     340                        }
     341                }
     342
     343                /**
     344                 *Destructor.
     345                 */
    84346                ~array2d()
    85347                {
     
    90352                }
    91353        protected:
    92                 pointer m_data;
    93                 ivec2   m_size;
     354                pointer m_data; ///< Pointer to the data.
     355                ivec2   m_size; ///< Allocated size of the data.
    94356        };
    95357
Note: See TracChangeset for help on using the changeset viewer.