You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
261 lines
9.6 KiB
C
261 lines
9.6 KiB
C
3 weeks ago
|
/*=========================================================================
|
||
|
|
||
|
Program: Visualization Toolkit
|
||
|
Module: vtkSparseArray.h
|
||
|
|
||
|
-------------------------------------------------------------------------
|
||
|
Copyright 2008 Sandia Corporation.
|
||
|
Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||
|
the U.S. Government retains certain rights in this software.
|
||
|
-------------------------------------------------------------------------
|
||
|
|
||
|
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
|
||
|
All rights reserved.
|
||
|
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
|
||
|
|
||
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
||
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||
|
PURPOSE. See the above copyright notice for more information.
|
||
|
|
||
|
=========================================================================*/
|
||
|
|
||
|
/**
|
||
|
* @class vtkSparseArray
|
||
|
* @brief Sparse, independent coordinate storage for N-way arrays.
|
||
|
*
|
||
|
*
|
||
|
* vtkSparseArray is a concrete vtkArray implementation that stores values using
|
||
|
* sparse independent coordinate storage. This means that the array stores the
|
||
|
* complete set of coordinates and the value for each non-null value in the array.
|
||
|
* While this approach requires slightly more storage than other sparse storage
|
||
|
* schemes (such as Compressed-Row or Compressed-Column), it is easier and more
|
||
|
* efficient to work with when implementing algorithms, and it generalizes well
|
||
|
* for arbitrary numbers of dimensions.
|
||
|
*
|
||
|
* In addition to the value retrieval and update methods provided by vtkTypedArray,
|
||
|
* vtkSparseArray provides methods to:
|
||
|
*
|
||
|
* Get and set a special 'null' value that will be returned when retrieving values
|
||
|
* for undefined coordinates.
|
||
|
*
|
||
|
* Clear the contents of the array so that every set of coordinates is undefined.
|
||
|
*
|
||
|
* Sort the array contents so that value coordinates can be visited in a specific order.
|
||
|
*
|
||
|
* Retrieve pointers to the value- and coordinate-storage memory blocks.
|
||
|
*
|
||
|
* Reserve storage for a specific number of non-null values, for efficiency when the
|
||
|
* number of non-null values is known in advance.
|
||
|
*
|
||
|
* Recompute the array extents so that they bound the largest set of non-nullptr values
|
||
|
* along each dimension.
|
||
|
*
|
||
|
* Specify arbitrary array extents.
|
||
|
*
|
||
|
* Add values to the array in amortized-constant time.
|
||
|
*
|
||
|
* Validate that the array does not contain duplicate coordinates.
|
||
|
*
|
||
|
* @sa
|
||
|
* vtkArray, vtkTypedArray, vtkDenseArray
|
||
|
*
|
||
|
* @par Thanks:
|
||
|
* Developed by Timothy M. Shead (tshead@sandia.gov) at Sandia National Laboratories.
|
||
|
*/
|
||
|
|
||
|
#ifndef vtkSparseArray_h
|
||
|
#define vtkSparseArray_h
|
||
|
|
||
|
#include "vtkArrayCoordinates.h"
|
||
|
#include "vtkArraySort.h"
|
||
|
#include "vtkObjectFactory.h"
|
||
|
#include "vtkTypedArray.h"
|
||
|
|
||
|
template <typename T>
|
||
|
class vtkSparseArray : public vtkTypedArray<T>
|
||
|
{
|
||
|
public:
|
||
|
vtkTemplateTypeMacro(vtkSparseArray<T>, vtkTypedArray<T>);
|
||
|
static vtkSparseArray<T>* New();
|
||
|
void PrintSelf(ostream& os, vtkIndent indent) override;
|
||
|
|
||
|
typedef typename vtkArray::CoordinateT CoordinateT;
|
||
|
typedef typename vtkArray::DimensionT DimensionT;
|
||
|
typedef typename vtkArray::SizeT SizeT;
|
||
|
|
||
|
// vtkArray API
|
||
|
bool IsDense() override;
|
||
|
const vtkArrayExtents& GetExtents() override;
|
||
|
SizeT GetNonNullSize() override;
|
||
|
void GetCoordinatesN(const SizeT n, vtkArrayCoordinates& coordinates) override;
|
||
|
vtkArray* DeepCopy() override;
|
||
|
|
||
|
// vtkTypedArray API
|
||
|
const T& GetValue(CoordinateT i) override;
|
||
|
const T& GetValue(CoordinateT i, CoordinateT j) override;
|
||
|
const T& GetValue(CoordinateT i, CoordinateT j, CoordinateT k) override;
|
||
|
const T& GetValue(const vtkArrayCoordinates& coordinates) override;
|
||
|
const T& GetValueN(const SizeT n) override;
|
||
|
void SetValue(CoordinateT i, const T& value) override;
|
||
|
void SetValue(CoordinateT i, CoordinateT j, const T& value) override;
|
||
|
void SetValue(CoordinateT i, CoordinateT j, CoordinateT k, const T& value) override;
|
||
|
void SetValue(const vtkArrayCoordinates& coordinates, const T& value) override;
|
||
|
void SetValueN(const SizeT n, const T& value) override;
|
||
|
|
||
|
// vtkSparseArray API
|
||
|
|
||
|
/**
|
||
|
* Set the value that will be returned by GetValue() for nullptr areas of the array.
|
||
|
*/
|
||
|
void SetNullValue(const T& value);
|
||
|
|
||
|
/**
|
||
|
* Returns the value that will be returned by GetValue() for nullptr areas of the array.
|
||
|
*/
|
||
|
const T& GetNullValue();
|
||
|
|
||
|
/**
|
||
|
* Remove all non-null elements from the array, leaving the number of dimensions, the
|
||
|
* extent of each dimension, and the label for each dimension unchanged.
|
||
|
*/
|
||
|
void Clear();
|
||
|
|
||
|
/**
|
||
|
* Sorts array values so that their coordinates appear in some well-defined order.
|
||
|
* The supplied vtkArraySort object controls which dimensions are sorted, and in what
|
||
|
* order, and should contain one-or-more sort dimensions, up to the number of dimensions
|
||
|
* stored in the array.
|
||
|
*/
|
||
|
void Sort(const vtkArraySort& sort);
|
||
|
|
||
|
/**
|
||
|
* Returns the set of unique coordinates along the given dimension.
|
||
|
*/
|
||
|
std::vector<CoordinateT> GetUniqueCoordinates(DimensionT dimension);
|
||
|
|
||
|
/**
|
||
|
* Return a read-only reference to the underlying coordinate storage. Coordinates
|
||
|
* for each dimension are stored contiguously as a one-dimensional array. The ordering
|
||
|
* of coordinates within the array depends on the order in which values were added to
|
||
|
* the array.
|
||
|
*/
|
||
|
const CoordinateT* GetCoordinateStorage(DimensionT dimension) const;
|
||
|
|
||
|
/**
|
||
|
* Return a mutable reference to the underlying coordinate storage. Coordinates
|
||
|
* for each dimension are stored contiguously as a one-dimensional array. The ordering
|
||
|
* of coordinates within the array depends on the order in which values were added to
|
||
|
* the array, and any subsequent sorting. Use at your own risk!
|
||
|
*/
|
||
|
CoordinateT* GetCoordinateStorage(DimensionT dimension);
|
||
|
|
||
|
/**
|
||
|
* Return a read-only reference to the underlying value storage. Values are stored
|
||
|
* contiguously, but in arbitrary order. Use GetCoordinateStorage() if you need to
|
||
|
* get the corresponding coordinates for a value.
|
||
|
*/
|
||
|
const T* GetValueStorage() const;
|
||
|
|
||
|
/**
|
||
|
* Return a mutable reference to the underlying value storage. Values are stored
|
||
|
* contiguously, but in arbitrary order. Use GetCoordinateStorage() if you need to
|
||
|
* get the corresponding coordinates for a value. Use at your own risk!
|
||
|
*/
|
||
|
T* GetValueStorage();
|
||
|
|
||
|
/**
|
||
|
* Reserve storage for a specific number of values. This is useful for reading external
|
||
|
* data using GetCoordinateStorage() and GetValueStorage(), when the total
|
||
|
* number of non-nullptr values in the array can be determined in advance. Note that after
|
||
|
* calling ReserveStorage(), all coordinates and values will be undefined, so you must
|
||
|
* ensure that every set of coordinates and values is overwritten. It is the caller's
|
||
|
* responsibility to ensure that duplicate coordinates are not inserted into the array.
|
||
|
*/
|
||
|
void ReserveStorage(const SizeT value_count);
|
||
|
|
||
|
/**
|
||
|
* Update the array extents to match its contents, so that the extent along each dimension
|
||
|
* matches the maximum index value along that dimension.
|
||
|
*/
|
||
|
void SetExtentsFromContents();
|
||
|
/**
|
||
|
* Specify arbitrary array extents, without altering the contents of the array. Note
|
||
|
* that the extents must be as-large-or-larger-than the extents of the actual values
|
||
|
* stored in the array. The number of dimensions in the supplied extents must match the
|
||
|
* number of dimensions currently stored in the array.
|
||
|
*/
|
||
|
void SetExtents(const vtkArrayExtents& extents);
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* Adds a new non-null element to the array. Does not test to see if an element with
|
||
|
* matching coordinates already exists. Useful for providing fast initialization of the
|
||
|
* array as long as the caller is prepared to guarantee that no duplicate coordinates are
|
||
|
* ever used.
|
||
|
*/
|
||
|
inline void AddValue(CoordinateT i, const T& value);
|
||
|
inline void AddValue(CoordinateT i, CoordinateT j, const T& value);
|
||
|
inline void AddValue(CoordinateT i, CoordinateT j, CoordinateT k, const T& value);
|
||
|
void AddValue(const vtkArrayCoordinates& coordinates, const T& value);
|
||
|
//@}
|
||
|
|
||
|
/**
|
||
|
* Validate the contents of the array, returning false if there are any problems.
|
||
|
* Potential problems include duplicate coordinates, which can be introduced into the
|
||
|
* array either through AddValue() or direct access to coordinates storage; and coordinates
|
||
|
* out-of-bounds given the current array extents.
|
||
|
|
||
|
* Note that Validate() is a heavyweight O(N log N) operation that is intended for
|
||
|
* temporary use during debugging.
|
||
|
*/
|
||
|
bool Validate();
|
||
|
|
||
|
protected:
|
||
|
vtkSparseArray();
|
||
|
~vtkSparseArray() override;
|
||
|
|
||
|
private:
|
||
|
vtkSparseArray(const vtkSparseArray&) = delete;
|
||
|
void operator=(const vtkSparseArray&) = delete;
|
||
|
|
||
|
void InternalResize(const vtkArrayExtents& extents) override;
|
||
|
void InternalSetDimensionLabel(DimensionT i, const vtkStdString& label) override;
|
||
|
vtkStdString InternalGetDimensionLabel(DimensionT i) override;
|
||
|
|
||
|
typedef vtkSparseArray<T> ThisT;
|
||
|
|
||
|
/**
|
||
|
* Stores the current array extents (size along each dimension)
|
||
|
*/
|
||
|
vtkArrayExtents Extents;
|
||
|
|
||
|
/**
|
||
|
* Stores a label for each array dimension
|
||
|
*/
|
||
|
std::vector<vtkStdString> DimensionLabels;
|
||
|
|
||
|
/**
|
||
|
* Stores the coordinates of each non-null element within the array,
|
||
|
* using one contiguous array to store the coordinates for each dimension.
|
||
|
*/
|
||
|
std::vector<std::vector<CoordinateT> > Coordinates;
|
||
|
|
||
|
/**
|
||
|
* Stores the value of each non-null element within the array
|
||
|
*/
|
||
|
std::vector<T> Values;
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* Stores the value that will be returned when accessing nullptr areas
|
||
|
* of the array.
|
||
|
*/
|
||
|
T NullValue;
|
||
|
//@}
|
||
|
};
|
||
|
|
||
|
#include "vtkSparseArray.txx"
|
||
|
|
||
|
#endif
|
||
|
// VTK-HeaderTest-Exclude: vtkSparseArray.h
|