text: /*=========================================================================
  
    Program:   Visualization Toolkit
    Module:    vtkExodusReader.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.
  
  =========================================================================*/
  /*----------------------------------------------------------------------------
   Copyright (c) Sandia Corporation
   See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
  ----------------------------------------------------------------------------*/
  
  // .NAME vtkExodusReader - Read exodus 2 files .ex2
  // .SECTION Description
  // vtkExodusReader is a unstructured grid source object that reads ExodusII
  // files.  Most of the meta data associated with the file is loaded when 
  // UpdateInformation is called.  This includes information like Title, number
  // of blocks, number and names of arrays. This data can be retrieved from 
  // methods in this reader. Separate arrays that are meant to be a single 
  // vector, are combined internally for convenience.  To be combined, the array 
  // names have to be identical except for a trailing X,Y and Z (or x,y,z).  By 
  // default cell and point arrays are not loaded.  However, the user can flag 
  // arrays to load with the methods "SetPointArrayStatus" and
  // "SetCellArrayStatus".  The reader DOES NOT respond to piece requests
  // 
  
  
  #ifndef __vtkExodusReader_h
  #define __vtkExodusReader_h
  
  #define ARRAY_TYPE_NAMES_IN_CXX_FILE
  
  #include "vtkUnstructuredGridAlgorithm.h"
  
  class vtkIntArray;
  class vtkFloatArray;
  class vtkDataArray;
  class vtkDataSet;
  class vtkPoints;
  class vtkExodusMetadata;
  class vtkExodusModel;
  class vtkExodusXMLParser;
  
  
  #include "vtkDSPFilterGroup.h" //for USE_EXO_DSP_FILTERS
  
  
  class VTK_HYBRID_EXPORT vtkExodusReader : public vtkUnstructuredGridAlgorithm 
  {
  public:
    static vtkExodusReader *New();
    vtkTypeRevisionMacro(vtkExodusReader,vtkUnstructuredGridAlgorithm);
    void PrintSelf(ostream& os, vtkIndent indent);
    
    // Description:
    // Determine if the file can be readed with this reader.
    int CanReadFile(const char* fname);
  
    // Description:
    // Specify file name of the Exodus file.
    vtkSetStringMacro(FileName);
    vtkGetStringMacro(FileName);
  
    // Description:
    // Specify file name of the xml file.
    vtkSetStringMacro(XMLFileName);
    vtkGetStringMacro(XMLFileName);
  
    // Description:
    // Which TimeStep to read.    
    vtkSetMacro(TimeStep, int);
    vtkGetMacro(TimeStep, int);
  
    // Description:
    // Extra cell data array that can be generated.  By default, this array
    // is ON.  The value of the array is the integer id found
    // in the exodus file. The name of the array is returned by 
    // GetBlockIdArrayName()
    vtkSetMacro(GenerateBlockIdCellArray, int);
    vtkGetMacro(GenerateBlockIdCellArray, int);
    vtkBooleanMacro(GenerateBlockIdCellArray, int);
    const char *GetBlockIdArrayName() { return "BlockId"; }  
  
  
    // Description:
    // Extra cell data array that can be generated.  By default, this array
    // is off.  The value of the array is the integer global id of the cell.
    // The name of the array is returned by GetGlobalElementIdArrayName()
    vtkSetMacro(GenerateGlobalElementIdArray, int);
    vtkGetMacro(GenerateGlobalElementIdArray, int);
    vtkBooleanMacro(GenerateGlobalElementIdArray, int);
  //BTX
    enum {
      SEARCH_TYPE_ELEMENT=0,
      SEARCH_TYPE_NODE,
      SEARCH_TYPE_ELEMENT_THEN_NODE,
      SEARCH_TYPE_NODE_THEN_ELEMENT,
      ID_NOT_FOUND=-234121312
    };
  //ETX
    static const char *GetGlobalElementIdArrayName() { return "GlobalElementId"; }
    static const char *GetPedigreeElementIdArrayName() { return "PedigreeElementId"; }
    static int GetGlobalElementID( vtkDataSet *data, int localID );
    static int GetGlobalElementID ( vtkDataSet *data, int localID, 
        int searchType );
    
    // Description:
    // Extra point data array that can be generated.  By default, this array
    // is ON.  The value of the array is the integer id of the node.
    // The id is relative to the entire data set.
    // The name of the array is returned by GlobalNodeIdArrayName().
    vtkSetMacro(GenerateGlobalNodeIdArray, int);
    vtkGetMacro(GenerateGlobalNodeIdArray, int);
    vtkBooleanMacro(GenerateGlobalNodeIdArray, int);
    static const char *GetGlobalNodeIdArrayName() { return "GlobalNodeId"; }  
    static const char *GetPedigreeNodeIdArrayName() { return "PedigreeNodeId"; }  
    static int GetGlobalNodeID( vtkDataSet *data, int localID );
    static int GetGlobalNodeID( vtkDataSet *data, int localID, 
        int searchType );
  
    // Description:
    // Geometric locations can include displacements.  By default, 
    // this is ON.  The nodal positions are 'displaced' by the
    // standard exodus displacment vector. If displacements
    // are turned 'off', the user can explicitly add them by
    // applying a warp filter.
    vtkSetMacro(ApplyDisplacements, int);
    vtkGetMacro(ApplyDisplacements, int);
    vtkBooleanMacro(ApplyDisplacements, int);
    vtkSetMacro(DisplacementMagnitude, float);
    vtkGetMacro(DisplacementMagnitude, float);
    
    // Description:
    // Access to meta data generated by UpdateInformation.
    vtkGetStringMacro(Title);
    vtkGetMacro(Dimensionality, int);
    vtkGetMacro(NumberOfTimeSteps, int);
    int GetNumberOfElements() { return this->NumberOfUsedElements; }
    vtkGetMacro(NumberOfNodeSets, int);
    vtkGetMacro(NumberOfSideSets, int);
    vtkGetMacro(NumberOfBlocks, int);
    vtkGetVector2Macro(TimeStepRange, int);
    vtkSetVector2Macro(TimeStepRange, int);
    int GetNumberOfNodes() { return this->NumberOfUsedNodes; }
    int GetNumberOfElementsInBlock(int block_idx);
    int GetBlockId(int block_idx);
    virtual int GetTotalNumberOfNodes() { return this->NumberOfNodesInFile; }
    
    
    // Descriptions:
    // By default arrays are not loaded.  These methods allow the user to select
    // which arrays they want to load.  You can get information about the arrays
    // by first caling UpdateInformation, and using GetPointArrayName ...
    // (Developer Note) This meta data is all accessed through vtkExodusMetadata
    int GetNumberOfPointArrays();
    const char *GetPointArrayName(int index);
    int GetPointArrayID( const char *name );
    int GetPointArrayNumberOfComponents(int index);
    void SetPointArrayStatus(int index, int flag);
    void SetPointArrayStatus(const char*, int flag);
    int GetPointArrayStatus(int index);
    int GetPointArrayStatus(const char*);
  
    int GetNumberOfCellArrays();
    const char *GetCellArrayName(int index);
    int GetCellArrayID( const char *name );
    int GetCellArrayNumberOfComponents(int index);
    void SetCellArrayStatus(int index, int flag);
    void SetCellArrayStatus(const char*, int flag);
    int GetCellArrayStatus(int index);
    int GetCellArrayStatus(const char*);
    virtual int GetTotalNumberOfElements() 
        { return this->NumberOfElementsInFile; }
  
    // Descriptions:
    // By default all blocks are loaded. These methods allow the user to select
    // which blocks they want to load.  You can get information about the blocks
    // by first caling UpdateInformation, and using GetBlockArrayName ... 
    int GetNumberOfBlockArrays();
    const char *GetBlockArrayName(int index);
    int GetBlockArrayID( const char *name );
    void SetBlockArrayStatus(int index, int flag);
    void SetBlockArrayStatus(const char*, int flag);
    int GetBlockArrayStatus(int index);
    int GetBlockArrayStatus(const char*);  
  
  
    // Description:
    // By default Node/Side sets are not loaded, These methods allow the user to
    // select which Node/Side sets they want to load. NumberOfNodeSets and
    // NumberOfSideSets (set by vtk macros) are stored in vtkExodusReader 
    // but other Node/Side set metadata are stored in vtkExodusMetaData
    // Note: GetNumberOfNodeSetArrays and GetNumberOfSideSetArrays are
    // just syntatic sugar for paraview server xml
    int GetNumberOfNodeSetArrays(){return this->GetNumberOfNodeSets();}
    int GetNodeSetArrayStatus(int index);
    int GetNodeSetArrayStatus(const char* name);
    void SetNodeSetArrayStatus(int index, int flag);
    void SetNodeSetArrayStatus(const char* name, int flag);
    const char *GetNodeSetArrayName(int index);
    
    int GetNumberOfSideSetArrays(){return this->GetNumberOfSideSets();}
    int GetSideSetArrayStatus(int index);
    int GetSideSetArrayStatus(const char* name);
    void SetSideSetArrayStatus(int index, int flag);
    void SetSideSetArrayStatus(const char* name, int flag);
    const char *GetSideSetArrayName(int index);
  
    // Descriptions:
    // By default all parts are loaded. These methods allow the user to select
    // which parts they want to load.  You can get information about the parts
    // by first caling UpdateInformation, and using GetPartArrayName ... 
    int GetNumberOfPartArrays();
    const char *GetPartArrayName(int arrayIdx);
    int GetPartArrayID( const char *name );
    const char *GetPartBlockInfo(int arrayIdx);
    void SetPartArrayStatus(int index, int flag);
    void SetPartArrayStatus(const char*, int flag);
    int GetPartArrayStatus(int index);
    int GetPartArrayStatus(const char*);
    
  
    // Descriptions:
    // By default all materials are loaded. These methods allow the user to 
    // select which materials they want to load.  You can get information 
    // about the materials by first caling UpdateInformation, and using 
    // GetMaterialArrayName ... 
    int GetNumberOfMaterialArrays();
    const char *GetMaterialArrayName(int arrayIdx);
    int GetMaterialArrayID( const char *name );
    void SetMaterialArrayStatus(int index, int flag);
    void SetMaterialArrayStatus(const char*, int flag);
    int GetMaterialArrayStatus(int index);
    int GetMaterialArrayStatus(const char*);
  
    // Descriptions:
    // By default all assemblies are loaded. These methods allow the user to 
    // select which assemblies they want to load.  You can get information 
    // about the assemblies by first caling UpdateInformation, and using 
    // GetAssemblyArrayName ... 
    int GetNumberOfAssemblyArrays();
    const char *GetAssemblyArrayName(int arrayIdx);
    int GetAssemblyArrayID( const char *name );
    void SetAssemblyArrayStatus(int index, int flag);
    void SetAssemblyArrayStatus(const char*, int flag);
    int GetAssemblyArrayStatus(int index);
    int GetAssemblyArrayStatus(const char*);
  
    // Descriptions:
    // By default all hierarchy entries are loaded. These methods allow 
    //the user to 
    // select which hierarchy entries they want to load.  You can get information 
    // about the hierarchy entries by first caling UpdateInformation, and using 
    // GetHierarchyArrayName ... 
    //these methods do not call functions in metaData. They call functions on
    //the ExodusXMLParser since it seemed silly to duplicate all the information
    int GetNumberOfHierarchyArrays();
    const char *GetHierarchyArrayName(int arrayIdx);
    void SetHierarchyArrayStatus(int index, int flag);
    void SetHierarchyArrayStatus(const char*, int flag);
    int GetHierarchyArrayStatus(int index);
    int GetHierarchyArrayStatus(const char*);
  
    // Description:
    // Some simulations overload the Exodus time steps to represent mode shapes.
    // In this case, it does not make sense to iterate over the "time steps",
    // because they are not meant to be played in order.  Rather, each represents
    // the vibration at a different "mode."  Setting this to 1 changes the
    // semantics of the reader to not report the time steps to downstream filters.
    // By default, this is off, which is the case for most Exodus files.
    vtkGetMacro(HasModeShapes, int);
    vtkSetMacro(HasModeShapes, int);
    vtkBooleanMacro(HasModeShapes, int);
  
    vtkGetMacro(DisplayType,int);
    virtual void SetDisplayType(int type);
  
    // Description:
    //   There is a great deal of model information lost when an Exodus II
    //   file is read in to a vtkUnstructuredGrid.  Turn this option ON 
    //   if you want this metadata to be read in to a vtkExodusModel object.
    //   The default is OFF.
  
    vtkBooleanMacro(ExodusModelMetadata, int);
    vtkSetMacro(ExodusModelMetadata, int);
    vtkGetMacro(ExodusModelMetadata, int);
  
    // Description:
    //   Returns the object which encapsulates the model metadata.
  
    vtkExodusModel *GetExodusModel(){return this->ExodusModel;}
  
    // Description:
    //  By default, the ExodusModel metadata (if requested with
    //  ExodusModelMetadataOn()) is also encoded into field arrays 
    //  and attached to the output unstructured grid.  Set this OFF
    //  if you don't want this to happen.  (The vtkExodusIIWriter and
    //  the vtkEnSightWriter can unpack this metadata from the field
    //  arrays and use it when writing out Exodus or EnSight files.)
  
    vtkSetMacro(PackExodusModelOntoOutput, int);
    vtkGetMacro(PackExodusModelOntoOutput, int);
    vtkBooleanMacro(PackExodusModelOntoOutput, int);
  
  //BTX
    // Descriptions:
    // Syntactic sugar funtions.
    enum ArrayType {
      CELL=0,
      POINT,
      BLOCK,
      PART,
      MATERIAL,
      ASSEMBLY,
      HIERARCHY,
      NUM_ARRAY_TYPES,
      UNKNOWN_TYPE
    };
  //ETX
  
    // Descriptions:
    // return boolean indicating whether the type,name is a valid variable 
    int IsValidVariable( const char *type, const char *name );
  
  //BTX
    // Description:
    // Named type accessor for array information
    int GetNumberOfArrays( vtkExodusReader::ArrayType type );
    const char *GetArrayName( vtkExodusReader::ArrayType type, int id );
  //ETX
  
    // Descriptions:
    // Return the id of the type,name variable
    int GetVariableID ( const char *type, const char *name );
  
    void SetAllAssemblyArrayStatus( int status );
    void SetAllBlockArrayStatus( int status );
    void SetAllCellArrayStatus( int status );
    void SetAllHierarchyArrayStatus( int status );
    void SetAllMaterialArrayStatus( int status );
    void SetAllPartArrayStatus( int status );
    void SetAllPointArrayStatus( int status );
  //BTX
    void SetAllArrayStatus ( vtkExodusReader::ArrayType type, int flag );
    void SetArrayStatus ( vtkExodusReader::ArrayType type, const char *name, 
        int flag );
  //ETX
    void SetArrayStatus ( const char *type, const char *name, int flag )
      {
      this->SetArrayStatus( this->GetArrayTypeID(type), name, flag );
      }
  //BTX
    int  GetArrayStatus ( vtkExodusReader::ArrayType type, const char *name );
  //ETX
    int  GetArrayStatus ( const char *type, const char *name )
      {
      return this->GetArrayStatus( this->GetArrayTypeID( type ), name );
      }
  
    // Helper functions
    static int StringsEqual(const char* s1, char* s2);
    static void StringUppercase(const char* str, char* upperstr);
    static char *StrDupWithNew(const char *s);
  
    // time series query functions
    int GetTimeSeriesData( int ID, const char *vName, const char *vType, 
                           vtkFloatArray *result );
    
  
    //begin USE_EXO_DSP_FILTERS
    int GetNumberOfVariableArrays();
    const char *GetVariableArrayName(int a_which);
    void EnableDSPFiltering(); 
    void AddFilter(vtkDSPFilterDefinition *a_filter);
    void StartAddingFilter();
    void AddFilterInputVar(char *name);
    void AddFilterOutputVar(char *name);
    void AddFilterNumeratorWeight(double weight);
    void AddFilterForwardNumeratorWeight(double weight);
    void AddFilterDenominatorWeight(double weight);
    void FinishAddingFilter();
    void RemoveFilter(char *a_outputVariableName);
    void GetDSPOutputArrays(int exoid, vtkUnstructuredGrid* output);
  //BTX
    vtkExodusReader::ArrayType GetArrayTypeID( const char *type ); 
  
  #ifdef ARRAY_TYPE_NAMES_IN_CXX_FILE
    static const char *GetArrayTypeName( vtkExodusReader::ArrayType type );
  #else
    static const char *ArrayTypeNames[NUM_ARRAY_TYPES];
  
    static const char *GetArrayTypeName( vtkExodusReader::ArrayType type )
      {
      return ArrayTypeNames[type];
      }
  #endif
  //ETX
  
    vtkDSPFilterDefinition *AddingFilter;
    int DSPFilteringIsEnabled;
    vtkDSPFilterGroup **DSPFilters;
    //end USE_EXO_DSP_FILTERS
  
  
  
  protected:
    vtkExodusReader();
    ~vtkExodusReader();
  
    void NewExodusModel();
  
    void ReadGeometry(int exoid, vtkUnstructuredGrid* output);
    void ReadCells(int exoid, vtkUnstructuredGrid* output);
    void ReadPoints(int exoid, vtkUnstructuredGrid* output);
    void ReadArrays(int exoid, vtkUnstructuredGrid* output);
    void ReadNodeAndSideSets(int exoid, vtkUnstructuredGrid* output);
    vtkDataArray *ReadPointArray(int exoid, int varIndex);
    vtkDataArray *ReadPointVector(int handle, int varIndex, int dim);
    vtkDataArray *ReadCellArray(int exoid, int varIndex);
    vtkDataArray *ReadCellVector(int handle, int varIndex, int dim);
    void ReadNodeSetMetadata();
    void ReadSideSetMetadata();
  
    // helper for finding IDs
    static int GetIDHelper ( const char *arrayName, vtkDataSet *data, int localID,
        int searchType );
    static int GetGlobalID( const char *arrayName, vtkDataSet *data, int localID, 
        int searchType );
    
    // This method is a helper for determining the
    // number of additional cell scalar field
    // values needed to 'pad' for node and side sets
    int GetExtraCellCountForNodeSideSets();
    
    // This method generates arrays like blockid, global nodeid
    // and global element id
    void GenerateExtraArrays(vtkUnstructuredGrid* output);
  
    // Parameters for controlling what is read in.
    char *FileName;
    char *XMLFileName;
    int TimeStep;
    int ActualTimeStep;
    double TimeValue;
    int GenerateBlockIdCellArray;
    int GenerateGlobalElementIdArray;
    int GenerateGlobalNodeIdArray;
    int ApplyDisplacements;
    double DisplacementMagnitude;
    
    // Information specific for exodus files.
    vtkSetStringMacro(Title);
    char *Title;
    int Dimensionality;
    int NumberOfNodeSets;
    int NumberOfSideSets;
    int NumberOfBlocks;
    int NumberOfUsedNodes;
    int NumberOfNodesInFile;
    int NumberOfUsedElements;
    int NumberOfElementsInFile;
    int NumberOfTimeSteps;
    int ExodusCPUWordSize;
    int ExodusIOWordSize;
    float ExodusVersion;
    vtkIntArray *CellVarTruthTable;
  
    //1=display Block names
    //2=display Part names
    //3=display Material names
    int DisplayType;
    
    //Parser that understands the xml part and material file
    vtkExodusXMLParser *Parser;
  
    // **KEN** By VTK convention, metaData should be Metadata.
   
    ////////////////////////////////////////
    // Scalar Array and Block Info
    ////////////////////////////////////////
    vtkExodusMetadata *MetaData;
    
   
    // Descriptions:
    // Store current file name and current handle.
    int CurrentHandle;
    char* CurrentFileName;
    char* CurrentXMLFileName;
    vtkSetStringMacro(CurrentFileName);
    vtkSetStringMacro(CurrentXMLFileName);
  
    // Open the exodus file, and set some basic information
    int OpenCurrentFile();
  
    // Close the exodus file
    void CloseCurrentFile();
  
    
    // Descriptions:
    // Store the range of time steps
    int TimeStepRange[2];
  
    // DataCache: this object keeps the points and cells
    // around so they don't need to be re-read when the
    // timestep changes or an scalar array is switched
    vtkUnstructuredGrid *DataCache;
  
    // Should I re-read in the geometry and topology of the dataset
    int RemakeDataCacheFlag;
  
    // vtkExodusModel needs to count changes in geometry, so it knows
    //   if geometry has changed since it last updated model data.
  
    int NewGeometryCount;
  
    // PointMap keeps track of which points are actually
    // used by the cells that are read in (blocks)
    vtkIntArray *PointMap;
    vtkIntArray *ReversePointMap;
    void SetUpPointMap(int num_points);
    int GetPointMapIndex(int point_id);
  
    // Global element ID cache
    int *GlobalElementIdCache;
    void SetGlobalElementIdCache(int *list);
  
    // Time query function. Called by ExecuteInformation().
    // Fills the TimestepValues array.
    void GetAllTimes(vtkInformationVector *);
  
    int HasModeShapes;
  
    vtkExodusModel *ExodusModel;
    int PackExodusModelOntoOutput;
    int ExodusModelMetadata;
  
    double *TimeSteps;
  
    int RequestInformation(
      vtkInformation *, vtkInformationVector **, vtkInformationVector *);
    int RequestData(
      vtkInformation *, vtkInformationVector **, vtkInformationVector *);
  
    // Used to determine current progress.
    double ProgressOffset;
    double ProgressScale;
  
  private:
    vtkExodusReader(const vtkExodusReader&); // Not implemented
    void operator=(const vtkExodusReader&); // Not implemented
  
    void AddDisplacements(vtkUnstructuredGrid* output);
    void RemoveBeginningAndTrailingSpaces(char **names, int len);
    
    void FixMetadataTruthTable(int *table, int len);
  };
  
  #endif
  