/*========================================================================= Program: Visualization Toolkit Module: vtkDataArray.h 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 vtkDataArray * @brief abstract superclass for arrays of numeric data * * * vtkDataArray is an abstract superclass for data array objects * containing numeric data. It extends the API defined in * vtkAbstractArray. vtkDataArray is an abstract superclass for data * array objects. This class defines an API that all array objects * must support. Note that the concrete subclasses of this class * represent data in native form (char, int, etc.) and often have * specialized more efficient methods for operating on this data (for * example, getting pointers to data or getting/inserting data in * native form). Subclasses of vtkDataArray are assumed to contain * data whose components are meaningful when cast to and from double. * * @sa * vtkBitArray vtkGenericDataArray */ #ifndef vtkDataArray_h #define vtkDataArray_h #include "vtkCommonCoreModule.h" // For export macro #include "vtkAbstractArray.h" class vtkDoubleArray; class vtkIdList; class vtkInformationStringKey; class vtkInformationDoubleVectorKey; class vtkLookupTable; class vtkPoints; class VTKCOMMONCORE_EXPORT vtkDataArray : public vtkAbstractArray { public: vtkTypeMacro(vtkDataArray,vtkAbstractArray); void PrintSelf(ostream& os, vtkIndent indent) override; /** * Perform a fast, safe cast from a vtkAbstractArray to a vtkDataArray. * This method checks if source->GetArrayType() returns DataArray * or a more derived type, and performs a static_cast to return * source as a vtkDataArray pointer. Otherwise, nullptr is returned. */ static vtkDataArray* FastDownCast(vtkAbstractArray *source); /** * This method is here to make backward compatibility easier. It * must return true if and only if an array contains numeric data. * All vtkDataArray subclasses contain numeric data, hence this method * always returns 1(true). */ int IsNumeric() override { return 1; } /** * Return the size, in bytes, of the lowest-level element of an * array. For vtkDataArray and subclasses this is the size of the * data type. */ int GetElementComponentSize() override { return this->GetDataTypeSize(); } // Reimplemented virtuals (doc strings are inherited from superclass): void InsertTuple(vtkIdType dstTupleIdx, vtkIdType srcTupleIdx, vtkAbstractArray* source) override; vtkIdType InsertNextTuple(vtkIdType srcTupleIdx, vtkAbstractArray* source) override; void InsertTuples(vtkIdList *dstIds, vtkIdList *srcIds, vtkAbstractArray *source) override; void InsertTuples(vtkIdType dstStart, vtkIdType n, vtkIdType srcStart, vtkAbstractArray* source) override; void GetTuples(vtkIdList *tupleIds, vtkAbstractArray *output) override; void GetTuples(vtkIdType p1, vtkIdType p2, vtkAbstractArray *output) override; void InterpolateTuple(vtkIdType dstTupleIdx, vtkIdList *ptIndices, vtkAbstractArray* source, double* weights) override; void InterpolateTuple(vtkIdType dstTupleIdx, vtkIdType srcTupleIdx1, vtkAbstractArray* source1, vtkIdType srcTupleIdx2, vtkAbstractArray* source2, double t) override; /** * Get the data tuple at tupleIdx. Return it as a pointer to an array. * Note: this method is not thread-safe, and the pointer is only valid * as long as another method invocation to a vtk object is not performed. */ virtual double *GetTuple(vtkIdType tupleIdx) VTK_EXPECTS(0 <= tupleIdx && tupleIdx < GetNumberOfTuples()) = 0; /** * Get the data tuple at tupleIdx by filling in a user-provided array, * Make sure that your array is large enough to hold the NumberOfComponents * amount of data being returned. */ virtual void GetTuple(vtkIdType tupleIdx, double * tuple) VTK_EXPECTS(0 <= tupleIdx && tupleIdx < GetNumberOfTuples()) = 0; //@{ /** * These methods are included as convenience for the wrappers. * GetTuple() and SetTuple() which return/take arrays can not be * used from wrapped languages. These methods can be used instead. */ double GetTuple1(vtkIdType tupleIdx) VTK_EXPECTS(0 <= tupleIdx && tupleIdx < GetNumberOfTuples()); double* GetTuple2(vtkIdType tupleIdx) VTK_EXPECTS(0 <= tupleIdx && tupleIdx < GetNumberOfTuples()); double* GetTuple3(vtkIdType tupleIdx) VTK_EXPECTS(0 <= tupleIdx && tupleIdx < GetNumberOfTuples()); double* GetTuple4(vtkIdType tupleIdx) VTK_EXPECTS(0 <= tupleIdx && tupleIdx < GetNumberOfTuples()); double* GetTuple6(vtkIdType tupleIdx) VTK_EXPECTS(0 <= tupleIdx && tupleIdx < GetNumberOfTuples()); double* GetTuple9(vtkIdType tupleIdx) VTK_EXPECTS(0 <= tupleIdx && tupleIdx < GetNumberOfTuples()); //@} void SetTuple(vtkIdType dstTupleIdx, vtkIdType srcTupleIdx, vtkAbstractArray* source) override; //@{ /** * Set the data tuple at tupleIdx. Note that range checking or * memory allocation is not performed; use this method in conjunction * with SetNumberOfTuples() to allocate space. */ virtual void SetTuple(vtkIdType tupleIdx, const float * tuple) VTK_EXPECTS(0 <= tupleIdx && tupleIdx < GetNumberOfTuples()); virtual void SetTuple(vtkIdType tupleIdx, const double * tuple) VTK_EXPECTS(0 <= tupleIdx && tupleIdx < GetNumberOfTuples()); //@} //@{ /** * These methods are included as convenience for the wrappers. * GetTuple() and SetTuple() which return/take arrays can not be * used from wrapped languages. These methods can be used instead. */ void SetTuple1(vtkIdType tupleIdx, double value) VTK_EXPECTS(0 <= tupleIdx && tupleIdx < GetNumberOfTuples()); void SetTuple2(vtkIdType tupleIdx, double val0, double val1) VTK_EXPECTS(0 <= tupleIdx && tupleIdx < GetNumberOfTuples()); void SetTuple3(vtkIdType tupleIdx, double val0, double val1, double val2) VTK_EXPECTS(0 <= tupleIdx && tupleIdx < GetNumberOfTuples()); void SetTuple4(vtkIdType tupleIdx, double val0, double val1, double val2, double val3) VTK_EXPECTS(0 <= tupleIdx && tupleIdx < GetNumberOfTuples()); void SetTuple6(vtkIdType tupleIdx, double val0, double val1, double val2, double val3, double val4, double val5) VTK_EXPECTS(0 <= tupleIdx && tupleIdx < GetNumberOfTuples()); void SetTuple9(vtkIdType tupleIdx, double val0, double val1, double val2, double val3, double val4, double val5, double val6, double val7, double val8) VTK_EXPECTS(0 <= tupleIdx && tupleIdx < GetNumberOfTuples()); //@} //@{ /** * Insert the data tuple at tupleIdx. Note that memory allocation * is performed as necessary to hold the data. */ virtual void InsertTuple(vtkIdType tupleIdx, const float * tuple) VTK_EXPECTS(0 <= tupleIdx) = 0; virtual void InsertTuple(vtkIdType tupleIdx, const double * tuple) VTK_EXPECTS(0 <= tupleIdx) = 0; //@} //@{ /** * These methods are included as convenience for the wrappers. * InsertTuple() which takes arrays can not be * used from wrapped languages. These methods can be used instead. */ void InsertTuple1(vtkIdType tupleIdx, double value) VTK_EXPECTS(0 <= tupleIdx); void InsertTuple2(vtkIdType tupleIdx, double val0, double val1) VTK_EXPECTS(0 <= tupleIdx); void InsertTuple3(vtkIdType tupleIdx, double val0, double val1, double val2) VTK_EXPECTS(0 <= tupleIdx); void InsertTuple4(vtkIdType tupleIdx, double val0, double val1, double val2, double val3) VTK_EXPECTS(0 <= tupleIdx); void InsertTuple6(vtkIdType tupleIdx, double val0, double val1, double val2, double val3, double val4, double val5) VTK_EXPECTS(0 <= tupleIdx); void InsertTuple9(vtkIdType tupleIdx, double val0, double val1, double val2, double val3, double val4, double val5, double val6, double val7, double val8) VTK_EXPECTS(0 <= tupleIdx); //@} //@{ /** * Insert the data tuple at the end of the array and return the tuple index at * which the data was inserted. Memory is allocated as necessary to hold * the data. */ virtual vtkIdType InsertNextTuple(const float * tuple) = 0; virtual vtkIdType InsertNextTuple(const double * tuple) = 0; //@} //@{ /** * These methods are included as convenience for the wrappers. * InsertTuple() which takes arrays can not be * used from wrapped languages. These methods can be used instead. */ void InsertNextTuple1(double value); void InsertNextTuple2(double val0, double val1); void InsertNextTuple3(double val0, double val1, double val2); void InsertNextTuple4(double val0, double val1, double val2, double val3); void InsertNextTuple6(double val0, double val1, double val2, double val3, double val4, double val5); void InsertNextTuple9(double val0, double val1, double val2, double val3, double val4, double val5, double val6, double val7, double val8); //@} //@{ /** * These methods remove tuples from the data array. They shift data and * resize array, so the data array is still valid after this operation. Note, * this operation is fairly slow. */ virtual void RemoveTuple(vtkIdType tupleIdx) VTK_EXPECTS(0 <= tupleIdx && tupleIdx < GetNumberOfTuples()) = 0; virtual void RemoveFirstTuple() { this->RemoveTuple(0); } virtual void RemoveLastTuple(); //@} /** * Return the data component at the location specified by tupleIdx and * compIdx. */ virtual double GetComponent(vtkIdType tupleIdx, int compIdx) VTK_EXPECTS(0 <= tupleIdx && tupleIdx < GetNumberOfTuples()) VTK_EXPECTS(0 <= compIdx && compIdx < GetNumberOfComponents()); /** * Set the data component at the location specified by tupleIdx and compIdx * to value. * Note that i is less than NumberOfTuples and j is less than * NumberOfComponents. Make sure enough memory has been allocated * (use SetNumberOfTuples() and SetNumberOfComponents()). */ virtual void SetComponent(vtkIdType tupleIdx, int compIdx, double value) VTK_EXPECTS(0 <= tupleIdx && tupleIdx < GetNumberOfTuples()) VTK_EXPECTS(0 <= compIdx && compIdx < GetNumberOfComponents()); /** * Insert value at the location specified by tupleIdx and compIdx. * Note that memory allocation is performed as necessary to hold the data. */ virtual void InsertComponent(vtkIdType tupleIdx, int compIdx, double value) VTK_EXPECTS(0 <= tupleIdx) VTK_EXPECTS(0 <= compIdx && compIdx < GetNumberOfComponents()); /** * Get the data as a double array in the range (tupleMin,tupleMax) and * (compMin, compMax). The resulting double array consists of all data in * the tuple range specified and only the component range specified. This * process typically requires casting the data from native form into * doubleing point values. This method is provided as a convenience for data * exchange, and is not very fast. */ virtual void GetData(vtkIdType tupleMin, vtkIdType tupleMax, int compMin, int compMax, vtkDoubleArray* data); //@{ /** * Deep copy of data. Copies data from different data arrays even if * they are different types (using doubleing-point exchange). */ void DeepCopy(vtkAbstractArray *aa) override; virtual void DeepCopy(vtkDataArray *da); //@} /** * Create a shallow copy of other into this, if possible. Shallow copies are * only possible: * (a) if both arrays are the same data type * (b) if both arrays are the same array type (e.g. AOS vs. SOA) * (c) if both arrays support shallow copies (e.g. vtkBitArray currently * does not.) * If a shallow copy is not possible, a deep copy will be performed instead. */ virtual void ShallowCopy(vtkDataArray *other); /** * Fill a component of a data array with a specified value. This method * sets the specified component to specified value for all tuples in the * data array. This methods can be used to initialize or reinitialize a * single component of a multi-component array. */ virtual void FillComponent(int compIdx, double value) VTK_EXPECTS(0 <= compIdx && compIdx < GetNumberOfComponents()); /** * Fill all values of a data array with a specified value. */ virtual void Fill(double value); /** * Copy a component from one data array into a component on this data array. * This method copies the specified component ("srcComponent") from the * specified data array ("src") to the specified component ("dstComponent") * over all the tuples in this data array. This method can be used to extract * a component (column) from one data array and paste that data into * a component on this data array. */ virtual void CopyComponent(int dstComponent, vtkDataArray *src, int srcComponent); /** * Get the address of a particular data index. Make sure data is allocated * for the number of items requested. If needed, increase MaxId to mark any * new value ranges as in-use. */ virtual void* WriteVoidPointer(vtkIdType valueIdx, vtkIdType numValues) = 0; /** * Return the memory in kibibytes (1024 bytes) consumed by this data array. Used to * support streaming and reading/writing data. The value returned is * guaranteed to be greater than or equal to the memory required to * actually represent the data represented by this object. The * information returned is valid only after the pipeline has * been updated. */ unsigned long GetActualMemorySize() override; /** * Create default lookup table. Generally used to create one when none * is available. */ void CreateDefaultLookupTable(); //@{ /** * Set/get the lookup table associated with this scalar data, if any. */ void SetLookupTable(vtkLookupTable *lut); vtkGetObjectMacro(LookupTable,vtkLookupTable); //@} /** * The range of the data array values for the given component will be * returned in the provided range array argument. If comp is -1, the range * of the magnitude (L2 norm) over all components will be provided. The * range is computed and then cached, and will not be re-computed on * subsequent calls to GetRange() unless the array is modified or the * requested component changes. * THIS METHOD IS NOT THREAD SAFE. */ void GetRange(double range[2], int comp) { this->ComputeRange(range, comp); } //@{ /** * Return the range of the data array values for the given component. If * comp is -1, return the range of the magnitude (L2 norm) over all * components.The range is computed and then cached, and will not be * re-computed on subsequent calls to GetRange() unless the array is * modified or the requested component changes. * THIS METHOD IS NOT THREAD SAFE. */ double* GetRange(int comp) { this->GetRange(this->Range, comp); return this->Range; } //@} /** * Return the range of the data array. If the array has multiple components, * then this will return the range of only the first component (component * zero). The range is computed and then cached, and will not be re-computed * on subsequent calls to GetRange() unless the array is modified. * THIS METHOD IS NOT THREAD SAFE. */ double* GetRange() { return this->GetRange(0); } /** * The the range of the data array values will be returned in the provided * range array argument. If the data array has multiple components, then * this will return the range of only the first component (component zero). * The range is computend and then cached, and will not be re-computed on * subsequent calls to GetRange() unless the array is modified. * THIS METHOD IS NOT THREAD SAFE. */ void GetRange(double range[2]) { this->GetRange(range,0); } /** * The range of the data array values for the given component will be * returned in the provided range array argument. If comp is -1, the range * of the magnitude (L2 norm) over all components will be provided. The * range is computed and then cached, and will not be re-computed on * subsequent calls to GetRange() unless the array is modified or the * requested component changes. * THIS METHOD IS NOT THREAD SAFE. */ void GetFiniteRange(double range[2], int comp) { this->ComputeFiniteRange(range, comp); } //@{ /** * Return the range of the data array values for the given component. If * comp is -1, return the range of the magnitude (L2 norm) over all * components.The range is computed and then cached, and will not be * re-computed on subsequent calls to GetRange() unless the array is * modified or the requested component changes. * THIS METHOD IS NOT THREAD SAFE. */ double *GetFiniteRange(int comp) { this->GetFiniteRange(this->FiniteRange, comp); return this->FiniteRange; } //@} /** * Return the range of the data array. If the array has multiple components, * then this will return the range of only the first component (component * zero). The range is computed and then cached, and will not be re-computed * on subsequent calls to GetRange() unless the array is modified. * THIS METHOD IS NOT THREAD SAFE. */ double *GetFiniteRange() { return this->GetFiniteRange(0); } /** * The the range of the data array values will be returned in the provided * range array argument. If the data array has multiple components, then * this will return the range of only the first component (component zero). * The range is computend and then cached, and will not be re-computed on * subsequent calls to GetRange() unless the array is modified. * THIS METHOD IS NOT THREAD SAFE. */ void GetFiniteRange(double range[2]) { this->GetFiniteRange(range, 0); } //@{ /** * These methods return the Min and Max possible range of the native * data type. For example if a vtkScalars consists of unsigned char * data these will return (0,255). */ void GetDataTypeRange(double range[2]); double GetDataTypeMin(); double GetDataTypeMax(); static void GetDataTypeRange(int type, double range[2]); static double GetDataTypeMin(int type); static double GetDataTypeMax(int type); //@} /** * Return the maximum norm for the tuples. * Note that the max. is computed every time GetMaxNorm is called. */ virtual double GetMaxNorm(); /** * Creates an array for dataType where dataType is one of * VTK_BIT, VTK_CHAR, VTK_SIGNED_CHAR, VTK_UNSIGNED_CHAR, VTK_SHORT, * VTK_UNSIGNED_SHORT, VTK_INT, VTK_UNSIGNED_INT, VTK_LONG, * VTK_UNSIGNED_LONG, VTK_DOUBLE, VTK_DOUBLE, VTK_ID_TYPE. * Note that the data array returned has be deleted by the * user. */ VTK_NEWINSTANCE static vtkDataArray* CreateDataArray(int dataType); /** * This key is used to hold tight bounds on the range of * one component over all tuples of the array. * Two values (a minimum and maximum) are stored for each component. * When GetRange() is called when no tuples are present in the array * this value is set to { VTK_DOUBLE_MAX, VTK_DOUBLE_MIN }. */ static vtkInformationDoubleVectorKey* COMPONENT_RANGE(); /** * This key is used to hold tight bounds on the $L_2$ norm * of tuples in the array. * Two values (a minimum and maximum) are stored for each component. * When GetRange() is called when no tuples are present in the array * this value is set to { VTK_DOUBLE_MAX, VTK_DOUBLE_MIN }. */ static vtkInformationDoubleVectorKey* L2_NORM_RANGE(); /** * This key is used to hold tight bounds on the $L_2$ norm * of tuples in the array. * Two values (a minimum and maximum) are stored for each component. * When GetFiniteRange() is called when no tuples are present in the array * this value is set to { VTK_DOUBLE_MAX, VTK_DOUBLE_MIN }. */ static vtkInformationDoubleVectorKey* L2_NORM_FINITE_RANGE(); /** * Removes out-of-date L2_NORM_RANGE() and L2_NORM_FINITE_RANGE() values. */ void Modified() override; /** * A human-readable string indicating the units for the array data. */ static vtkInformationStringKey *UNITS_LABEL(); /** * Copy information instance. Arrays use information objects * in a variety of ways. It is important to have flexibility in * this regard because certain keys should not be copied, while * others must be. NOTE: Up to the implmenter to make sure that * keys not inteneded to be coppied are excluded here. */ int CopyInformation(vtkInformation *infoFrom, int deep=1) override; /** * Method for type-checking in FastDownCast implementations. */ int GetArrayType() override { return DataArray; } protected: friend class vtkPoints; /** * Compute the range for a specific component. If comp is set -1 * then L2 norm is computed on all components. Call ClearRange * to force a recomputation if it is needed. The range is copied * to the range argument. * THIS METHOD IS NOT THREAD SAFE. */ virtual void ComputeRange(double range[2], int comp); /** * Compute the range for a specific component. If comp is set -1 * then L2 norm is computed on all components. Call ClearRange * to force a recomputation if it is needed. The range is copied * to the range argument. * THIS METHOD IS NOT THREAD SAFE. */ virtual void ComputeFiniteRange(double range[2], int comp); /** * Computes the range for each component of an array, the length * of \a ranges must be two times the number of components. * Returns true if the range was computed. Will return false * if you try to compute the range of an array of length zero. */ virtual bool ComputeScalarRange(double* ranges); // Returns true if the range was computed. Will return false // if you try to compute the range of an array of length zero. virtual bool ComputeVectorRange(double range[2]); /** * Computes the range for each component of an array, the length * of \a ranges must be two times the number of components. * Returns true if the range was computed. Will return false * if you try to compute the range of an array of length zero. */ virtual bool ComputeFiniteScalarRange(double* ranges); // Returns true if the range was computed. Will return false // if you try to compute the range of an array of length zero. virtual bool ComputeFiniteVectorRange(double range[2]); // Construct object with default tuple dimension (number of components) of 1. vtkDataArray(); ~vtkDataArray() override; vtkLookupTable *LookupTable; double Range[2]; double FiniteRange[2]; private: double* GetTupleN(vtkIdType i, int n); private: vtkDataArray(const vtkDataArray&) = delete; void operator=(const vtkDataArray&) = delete; }; //------------------------------------------------------------------------------ inline vtkDataArray* vtkDataArray::FastDownCast(vtkAbstractArray *source) { if (source) { switch (source->GetArrayType()) { case AoSDataArrayTemplate: case SoADataArrayTemplate: case TypedDataArray: case DataArray: case MappedDataArray: return static_cast(source); default: break; } } return nullptr; } vtkArrayDownCast_FastCastMacro(vtkDataArray) #endif