text: /*=========================================================================
  
    Program:   Visualization Toolkit
    Module:    $RCSfile$
  
    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.
  
  =========================================================================*/
  // .NAME vtkFieldData - represent and manipulate fields of data
  // .SECTION Description
  // vtkFieldData represents and manipulates fields of data. The model of a field
  // is a m x n matrix of data values, where m is the number of tuples, and n
  // is the number of components. (A tuple is a row of n components in the
  // matrix.) The field is assumed to be composed of a set of one or more data
  // arrays, where the data in the arrays are of different types (e.g., int,
  // double, char, etc.), and there may be variable numbers of components in
  // each array. Note that each data array is assumed to be "m" in length
  // (i.e., number of tuples), which typically corresponds to the number of
  // points or cells in a dataset. Also, each data array must have a
  // character-string name. (This is used to manipulate data.)
  //
  // There are two ways of manipulating and interfacing to fields. You can do
  // it generically by manipulating components/tuples via a double-type data
  // exchange, or you can do it by grabbing the arrays and manipulating them
  // directly. The former is simpler but performs type conversion, which is bad
  // if your data has non-castable types like (void) pointers, or you lose
  // information as a result of the cast. The, more efficient method means
  // managing each array in the field.  Using this method you can create
  // faster, more efficient algorithms that do not lose information.
  
  // .SECTION See Also
  // vtkAbstractArray vtkDataSetAttributes vtkPointData vtkCellData
  
  #ifndef __vtkFieldData_h
  #define __vtkFieldData_h
  
  #include "vtkObject.h"
  
  #include "vtkAbstractArray.h" // Needed for inline methods.
  
  #ifndef VTK_LEGACY_REMOVE
  # include "vtkDataArray.h" // Needed for backwards compatibility.
  #endif
  
  class vtkIdList;
  
  class VTK_FILTERING_EXPORT vtkFieldData : public vtkObject
  {
  public:
    static vtkFieldData *New();
  
    vtkTypeRevisionMacro(vtkFieldData,vtkObject);
    void PrintSelf(ostream& os, vtkIndent indent);
  
    // Description:
    // Release all data but do not delete object.
    // Also, clear the copy flags.
    virtual void Initialize();
  
    // Description:
    // Allocate data for each array.
    // Note that ext is no longer used.
    int Allocate(const vtkIdType sz, const vtkIdType ext=1000);
  
    // Description:
    // Copy data array structure from a given field.  The same arrays
    // will exist with the same types, but will contain nothing in the
    // copy.
    void CopyStructure(vtkFieldData*);
  
    // Description:
    // AllocateOfArrays actually sets the number of
    // vtkAbstractArray pointers in the vtkFieldData object, not the
    // number of used pointers (arrays). Adding more arrays will
    // cause the object to dynamically adjust the number of pointers
    // if it needs to extend. Although AllocateArrays can
    // be used if the number of arrays which will be added is
    // known, it can be omitted with a small computation cost.
    void AllocateArrays(int num);
  
    // Description:
    // Get the number of arrays of data available.
    // This does not include NULL array pointers therefore after
    // fd->AllocateArray(n); nArrays = GetNumberOfArrays()
    // nArrays is not necessarily equal to n.
    int GetNumberOfArrays()
      {
        return this->NumberOfActiveArrays;
      }
  
    // Description:
    // Add an array to the array list. If an array with the same name
    // already exists - then the added array will replace it.
    int AddArray(vtkAbstractArray *array);
  
    // Description:
    // Remove an array (with the given name) from the list of arrays.
    virtual void RemoveArray(const char *name)
      {
        int i;
        this->GetAbstractArray(name, i);
        this->RemoveArray(i);
      }
  
    // Description:
    // Return the ith array in the field. A NULL is returned if the
    // index i is out of range. A NULL is returned if the array at the given 
    // index is not a vtkDataArray.
    vtkDataArray *GetArray(int i);
  
    // Description:
    // Return the array with the name given. Returns NULL is array not found.
    // A NULL is also returned if the array with the given name is not a 
    // vtkDataArray. Also returns index of array if found, -1 otherwise.
    vtkDataArray *GetArray(const char *arrayName, int &index);
  
    // Description:
    // Return the array with the name given. Returns NULL is array not found.
    // A NULL is also returned if the array with the given name is not a 
    // vtkDataArray.
    vtkDataArray *GetArray(const char *arrayName)
      {
        int i;
        return this->GetArray(arrayName, i);
      }
  
    // Description:
    // Returns the ith array in the field. Unlike GetArray(), this method returns
    // a vtkAbstractArray. A NULL is returned only if the index i is 
    // out of range.
    vtkAbstractArray* GetAbstractArray(int i);
  
    // Description:
    // Return the array with the name given. Returns NULL is array not found.
    // Unlike GetArray(), this method returns a vtkAbstractArray.
    // Also returns index of array if found, -1 otherwise.
    vtkAbstractArray* GetAbstractArray(const char* arrayName, int &index);
  
    // Description:
    // Return the array with the name given. Returns NULL is array not found.
    // Unlike GetArray(), this method returns a vtkAbstractArray.
    vtkAbstractArray* GetAbstractArray(const char* arrayName)
      {
      int i;
      return this->GetAbstractArray(arrayName, i);
      }
    
    // Description:
    // Return 1 if an array with the given name could be found. 0 otherwise.
    int HasArray(const char *name)
      {
        int i;
        vtkAbstractArray *array = this->GetAbstractArray(name, i);
        // assert( i == -1);
        return array ? 1 : 0;
      }
  
    // Description:
    // Get the name of ith array.
    // Note that this is equivalent to:
    // GetAbstractArray(i)->GetName() if ith array pointer is not NULL
    const char* GetArrayName(int i)
      {
      vtkAbstractArray* da = this->GetAbstractArray(i);
      return da ? da->GetName() : 0;
      }
  
    // Description:
    // Pass entire arrays of input data through to output. Obey the "copy"
    // flags.
    virtual void PassData(vtkFieldData* fd);
  
    // Description:
    // Turn on/off the copying of the field specified by name.
    // During the copying/passing, the following rules are followed for each
    // array:
    // 1. If the copy flag for an array is set (on or off), it is applied
    //    This overrides rule 2.
    // 2. If CopyAllOn is set, copy the array.
    //    If CopyAllOff is set, do not copy the array
    void CopyFieldOn(const char* name) { this->CopyFieldOnOff(name, 1); }
    void CopyFieldOff(const char* name) { this->CopyFieldOnOff(name, 0); }
  
    // Description:
    // Turn on copying of all data.
    // During the copying/passing, the following rules are followed for each
    // array:
    // 1. If the copy flag for an array is set (on or off), it is applied
    //    This overrides rule 2.
    // 2. If CopyAllOn is set, copy the array.
    //    If CopyAllOff is set, do not copy the array
    virtual void CopyAllOn(int unused=0);
  
    // Description:
    // Turn off copying of all data.
    // During the copying/passing, the following rules are followed for each
    // array:
    // 1. If the copy flag for an array is set (on or off), it is applied
    //    This overrides rule 2.
    // 2. If CopyAllOn is set, copy the array.
    //    If CopyAllOff is set, do not copy the array
    virtual void CopyAllOff(int unused=0);
  
    // Description:
    // Copy a field by creating new data arrays (i.e., duplicate storage).
    virtual void DeepCopy(vtkFieldData *da);
  
    // Description:
    // Copy a field by reference counting the data arrays.
    virtual void ShallowCopy(vtkFieldData *da);
  
    // Description:
    // Squeezes each data array in the field (Squeeze() reclaims unused memory.)
    void Squeeze();
  
    // Description:
    // Resets each data array in the field (Reset() does not release memory but
    // it makes the arrays look like they are empty.)
    void Reset();
  
    // Description:
    // Return the memory in kilobytes consumed by this field data. 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.
    virtual unsigned long GetActualMemorySize();
  
    // Description:
    // Check object's components for modified times.
    unsigned long int GetMTime();
    
    // Description:
    // Get a field from a list of ids. Supplied field f should have same
    // types and number of data arrays as this one (i.e., like
    // CopyStructure() creates).  This method should not be used if the
    // instance is from a subclass of vtkFieldData (vtkPointData or
    // vtkCellData).  This is because in those cases, the attribute data
    // is stored with the other fields and will cause the method to
    // behave in an unexpected way.
    void GetField(vtkIdList *ptId, vtkFieldData *f);
  
    // Description:
    // Return the array containing the ith component of the field. The
    // return value is an integer number n 0<=n<this->NumberOfArrays. Also,
    // an integer value is returned indicating the component in the array
    // is returned. Method returns -1 if specified component is not
    // in the field.
    int GetArrayContainingComponent(int i, int& arrayComp);
  
    // Description:
    // Get the number of components in the field. This is determined by adding
    // up the components in each non-NULL array.
    // This method should not be used if the instance is from a
    // subclass of vtkFieldData (vtkPointData or vtkCellData).
    // This is because in those cases, the attribute data is 
    // stored with the other fields and will cause the method
    // to behave in an unexpected way.
    int GetNumberOfComponents();
  
    // Description:
    // Get the number of tuples in the field. Note: some fields have arrays with
    // different numbers of tuples; this method returns the number of tuples in
    // the first array. Mixed-length arrays may have to be treated specially.
    // This method should not be used if the instance is from a
    // subclass of vtkFieldData (vtkPointData or vtkCellData).
    // This is because in those cases, the attribute data is 
    // stored with the other fields and will cause the method
    // to behave in an unexpected way.
    vtkIdType GetNumberOfTuples();
  
    // Description:
    // Set the number of tuples for each data array in the field.
    // This method should not be used if the instance is from a
    // subclass of vtkFieldData (vtkPointData or vtkCellData).
    // This is because in those cases, the attribute data is 
    // stored with the other fields and will cause the method
    // to behave in an unexpected way.
    void SetNumberOfTuples(const vtkIdType number);
  
    // Description:
    // Set the jth tuple in source field data at the ith location. 
    // Set operations mean that no range checking is performed, so 
    // they're faster.
    void SetTuple(const vtkIdType i, const vtkIdType j, vtkFieldData* source);
  
    // Description:
    // Insert the jth tuple in source field data at the ith location. 
    // Range checking is performed and memory allocates as necessary.
    void InsertTuple(const vtkIdType i, const vtkIdType j, vtkFieldData* source);
  
    // Description:
    // Insert the jth tuple in source field data  at the end of the 
    // tuple matrix. Range checking is performed and memory is allocated 
    // as necessary.
    vtkIdType InsertNextTuple(const vtkIdType j, vtkFieldData* source);
  
    // Following are LEGACY methods. Using these methods for FieldData
    // having arrays that are not subclasses of vtkDataArray may
    // yield unexpected results.
    
    // Description:
    // Return a tuple consisting of a concatenation of all data from all
    // the different arrays. Note that everything is converted to and from
    // double values.
    // @deprecated as of VTK 5.2. Using this method for FieldData
    // having arrays that are not subclasses of vtkDataArray may
    // yield unexpected results.
    VTK_LEGACY(double *GetTuple(const vtkIdType i));
  
    // Description:
    // Copy the ith tuple value into a user provided tuple array. Make
    // sure that you've allocated enough space for the copy.
    // @deprecated as of VTK 5.2. Using this method for FieldData
    // having arrays that are not subclasses of vtkDataArray may
    // yield unexpected results.
    VTK_LEGACY(void GetTuple(const vtkIdType i, double * tuple));
  
    // Description:
    // Set the tuple value at the ith location. Set operations
    // mean that no range checking is performed, so they're faster.
    // @deprecated as of VTK 5.2. Using this method for FieldData
    // having arrays that are not subclasses of vtkDataArray may
    // yield unexpected results.
    VTK_LEGACY(void SetTuple(const vtkIdType i, const double * tuple));
  
    // Description:
    // Insert the tuple value at the ith location. Range checking is
    // performed and memory allocates as necessary.
    // @deprecated as of VTK 5.2. Using this method for FieldData
    // having arrays that are not subclasses of vtkDataArray may
    // yield unexpected results.
    VTK_LEGACY(void InsertTuple(const vtkIdType i, const double * tuple));
  
    // Description:
    // Insert the tuple value at the end of the tuple matrix. Range
    // checking is performed and memory is allocated as necessary.
    // @deprecated as of VTK 5.2. Using this method for FieldData
    // having arrays that are not subclasses of vtkDataArray may
    // yield unexpected results.
    VTK_LEGACY(vtkIdType InsertNextTuple(const double * tuple));
    
    // Description:
    // Get the component value at the ith tuple (or row) and jth component (or
    // column).
    // @deprecated as of VTK 5.2. Using this method for FieldData
    // having arrays that are not subclasses of vtkDataArray may
    // yield unexpected results.
    VTK_LEGACY(double GetComponent(const vtkIdType i, const int j));
  
    // Description:
    // Set the component value at the ith tuple (or row) and jth component (or
    // column).  Range checking is not performed, so set the object up properly
    // before invoking.
    // @deprecated as of VTK 5.2. Using this method for FieldData
    // having arrays that are not subclasses of vtkDataArray may
    // yield unexpected results.
    VTK_LEGACY(void SetComponent(const vtkIdType i, const int j, const double c));
    
    // Description:
    // Insert the component value at the ith tuple (or row) and jth component
    // (or column).  Range checking is performed and memory allocated as
    // necessary o hold data.
    // @deprecated as of VTK 5.2. Using this method for FieldData
    // having arrays that are not subclasses of vtkDataArray may
    // yield unexpected results.
    VTK_LEGACY(void InsertComponent(const vtkIdType i, const int j, const double c));
  protected:
  
    vtkFieldData();
    ~vtkFieldData();
  
    int NumberOfArrays;
    int NumberOfActiveArrays;
    vtkAbstractArray **Data;
  
    // Description:
    // Set an array to define the field.
    void SetArray(int i, vtkAbstractArray *array);
  
    virtual void RemoveArray(int index);
  
    // Description:
    // Release all data but do not delete object.
    virtual void InitializeFields();
  
  //BTX
  
    struct CopyFieldFlag
    {
      char* ArrayName;
      int IsCopied;
    };
  
    CopyFieldFlag* CopyFieldFlags; //the names of fields not to be copied
    int NumberOfFieldFlags; //the number of fields not to be copied
    void CopyFieldOnOff(const char* name, int onOff);
    void ClearFieldFlags();
    int FindFlag(const char* field);
    int GetFlag(const char* field);
    void CopyFlags(const vtkFieldData* source);
    int DoCopyAllOn;
    int DoCopyAllOff;
  
  
  private:
    vtkFieldData(const vtkFieldData&);  // Not implemented.
    void operator=(const vtkFieldData&);  // Not implemented.
  
  #ifndef VTK_LEGACY_REMOVE
    // Must be removed when support for Legacy GetTuple is removed.
    int TupleSize; // used for type conversion in Legacy support.
    double* Tuple;
  #endif
  public:
  
    class VTK_FILTERING_EXPORT BasicIterator
    {
    public:
      BasicIterator();
      BasicIterator(const BasicIterator& source);
      BasicIterator(const int* list, unsigned int listSize);
      BasicIterator& operator=(const BasicIterator& source);
      virtual ~BasicIterator();
      void PrintSelf(ostream &os, vtkIndent indent);
  
      int GetListSize() const
        {
          return this->ListSize;
        }
      int GetCurrentIndex()
        {
          return this->List[this->Position];
        }
      int BeginIndex()
        {
          this->Position = -1;
          return this->NextIndex();
        }
      int End() const
        {
          return (this->Position >= this->ListSize);
        }
      int NextIndex()
        {
          this->Position++;
          return (this->End() ? -1 : this->List[this->Position]);
        }
      
    protected:
  
      int* List;
      int ListSize;
      int Position;
    };
  
    class VTK_FILTERING_EXPORT Iterator : public BasicIterator
    {
    public:
  
      Iterator(const Iterator& source);
      Iterator& operator=(const Iterator& source);
      virtual ~Iterator();
      Iterator(vtkFieldData* dsa, const int* list=0, 
               unsigned int listSize=0);
  
      vtkDataArray* Begin()
        {
          this->Position = -1;
          return this->Next();
        }
  
      vtkDataArray* Next()
        {
          this->Position++;
          if (this->End())
            {
            return 0;
            }
        
          // vtkFieldData::GetArray() can return null, which implies that
          // a the array at the given index in not a vtkDataArray subclass.
          // This iterator skips such arrays.
          vtkDataArray* cur =  Fields->GetArray(this->List[this->Position]);
          return (cur? cur : this->Next());
        }
  
      void DetachFieldData();
  
    protected:
      vtkFieldData* Fields;
      int Detached;
    };
  
  
  //ETX
  
  };
  
  
  #endif
  