View | Details | Raw Unified
Collapse All | Expand All

(-) ParaView3.orig/VTK/IO/vtkOpenFOAMReader.h (-2757 / +4665 lines)
 Lines 3412-3474    Link Here 
   </SourceProxy>
   </SourceProxy>
    <!-- Beginning of FOAM Reader -->
    <!-- Beginning of FOAM Reader -->
    <SourceProxy name="OpenFOAMReader" 
    <SourceProxy
                    class="vtkOpenFOAMReader">
      <StringVectorProperty name="FileName"
        name="OpenFOAMReader" 
                            command="SetFileName"
        class="vtkOpenFOAMReader"
                            animateable="0"
	output="vtkDataSet">
                            number_of_elements="1">
        <FileListDomain name="files"/>
       <StringVectorProperty
        <Documentation>
           name="FileName"
          Set the file name for the OpenFOAM reader.
           command="SetFileName"
        </Documentation>
           number_of_elements="1">
      </StringVectorProperty>
           <FileListDomain name="files"/>
      <StringVectorProperty name="CellArrayInfo"
        </StringVectorProperty>
                            information_only="1">
        <ArraySelectionInformationHelper attribute_name="Cell"/>
	<IntVectorProperty 
      </StringVectorProperty>
           name="CacheMesh" 
      <StringVectorProperty name="CellArrayStatus"
           command="SetCacheMesh" 
                            command="SetCellArrayStatus"
           number_of_elements="1"
                            number_of_elements="0" 
           default_values="1">
                            repeat_command="1"
           <BooleanDomain name="bool"/>
                            number_of_elements_per_command="2"
                <Documentation>
                            element_types="2 0" 
                   Cache the OpenFOAM mesh between GUI selection changes.
                            information_property="CellArrayInfo"
                </Documentation>
                            label="Cell Arrays">
        </IntVectorProperty>
        <ArraySelectionDomain name="array_list">
          <RequiredProperties>
        <IntVectorProperty name="ReadZones" 
            <Property name="CellArrayInfo" function="ArrayList"/>
                           command="SetReadZones"
          </RequiredProperties>
                           number_of_elements="1" 
        </ArraySelectionDomain>
                           default_values="0"
        <Documentation>
                           label="Read Zones">
          Select which cell-centered arrays to read.
          <BooleanDomain name="bool"/>
        </Documentation>
          <Documentation>
      </StringVectorProperty>
            Read point/face/cell-Zones?
      <IntVectorProperty name="TimeStepRangeInfo"
          </Documentation>
                         command="GetTimeStepRange"
        </IntVectorProperty>
                         information_only="1">
        <SimpleIntInformationHelper/>
	    <IntVectorProperty name="AccumulatePatches" 
      </IntVectorProperty>
			       command="SetKeepPatches"
      <IntVectorProperty name="TimeStep"
			       number_of_elements="1" 
                           command="SetTimeStep"
			       default_values="1"
                           number_of_elements="1"
			       label="Accumulate Patches to Selection List">
                           animateable="1"
		    <BooleanDomain name="bool"/>
                           default_values="0">
		    <Documentation>
        <IntRangeDomain name="range">
			    Accumulate patches into selection list across time-steps even if they stop existing
          <RequiredProperties>
		    </Documentation>
            <Property name="TimeStepRangeInfo" function="Range"/>
	    </IntVectorProperty>
          </RequiredProperties>
        </IntRangeDomain>
	<DoubleVectorProperty
        <Documentation>
           name="TimestepValues"
          Set the current timestep.
	   repeatable="1"
        </Documentation>
	   information_only="1">
      </IntVectorProperty>
           <TimeStepsInformationHelper/>
      <DoubleVectorProperty 
        </DoubleVectorProperty>
          name="TimestepValues"
          repeatable="1"
	<StringVectorProperty 
          information_only="1">
            name="PatchArrayInfo"
        <TimeStepsInformationHelper/>
            information_only="1">
      </DoubleVectorProperty>
            <ArraySelectionInformationHelper attribute_name="Patch"/>
	</StringVectorProperty>
	<StringVectorProperty
            name="MeshRegions"
            command="SetPatchArrayStatus"
            number_of_elements="0" 
            repeat_command="1"
            number_of_elements_per_command="2"
            element_types="2 0"
            information_property="PatchArrayInfo">
            <ArraySelectionDomain name="array_list">
                <RequiredProperties>
                    <Property name="PatchArrayInfo"
                        function="ArrayList"/>
                    </RequiredProperties>
            </ArraySelectionDomain>
        </StringVectorProperty>
	
        <StringVectorProperty 
            name="CellArrayInfo"
            information_only="1">
            <ArraySelectionInformationHelper attribute_name="Cell"/>
        </StringVectorProperty>
        <StringVectorProperty
            name="CellArrays"
            command="SetCellArrayStatus"
            number_of_elements="0" 
            repeat_command="1"
            number_of_elements_per_command="2"
            element_types="2 0"
    	    information_property="CellArrayInfo">
            <ArraySelectionDomain name="array_list">
                <RequiredProperties>
                    <Property name="CellArrayInfo"
                        function="ArrayList"/>
                </RequiredProperties>
            </ArraySelectionDomain>
        </StringVectorProperty>
        <StringVectorProperty 
            name="PointArrayInfo"
            information_only="1">
            <ArraySelectionInformationHelper attribute_name="Point"/>
        </StringVectorProperty>
        <StringVectorProperty
            name="PointArrays"
            command="SetPointArrayStatus"
            number_of_elements="0" 
            repeat_command="1"
            number_of_elements_per_command="2"
            element_types="2 0"
	        information_property="PointArrayInfo">
            <ArraySelectionDomain name="array_list">
                <RequiredProperties>
                    <Property name="PointArrayInfo"
                        function="ArrayList"/>
                </RequiredProperties>
            </ArraySelectionDomain>
        </StringVectorProperty>
    </SourceProxy>
    </SourceProxy>
    <!-- End of foam Reader -->
    <!-- End of foam Reader -->
 Lines 16-26    Link Here 
// Technology Laboratory who developed this class.
// Technology Laboratory who developed this class.
// Please address all comments to Terry Jordan (terry.jordan@sa.netl.doe.gov)
// Please address all comments to Terry Jordan (terry.jordan@sa.netl.doe.gov)
//
//
// Token-based FoamFile format lexer/parser, performance enhancements,
// gzipped file and lagrangian field support by Takuya Oshima
// (oshima@eng.niigata-u.ac.jp)
//
// * GUI Based selection of mesh regions and fields available in the case
// * Minor bug fixes / Strict memory allocation checks
// * Minor performance enhancements
// by Philippose Rajan (sarith@rocketmail.com)
#include "vtkOpenFOAMReader.h"
#include "vtkOpenFOAMReader.h"
#include <vtksys/ios/sstream>
#include <vtkstd/string>
#include <vtkstd/string>
#include <vtkstd/vector>
#include <vtkstd/vector>
#include <vtksys/ios/sstream>
#include <vtk_zlib.h>
#include "vtkInformation.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkInformationVector.h"
 Lines 28-37    Link Here 
#include "vtkDataArraySelection.h"
#include "vtkDataArraySelection.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkCellArray.h"
#include "vtkCellArray.h"
#include "vtkCallbackCommand.h"
#include "vtkDataArraySelection.h"
#include "vtkDataArraySelection.h"
#include "vtkIntArray.h"
#include "vtkIntArray.h"
#include "vtkFloatArray.h"
#include "vtkDoubleArray.h"
#include "vtkDoubleArray.h"
#include "vtkStringArray.h"
#include "vtkSortDataArray.h"
#include "vtkPoints.h"
#include "vtkPoints.h"
#include "vtkCellData.h"
#include "vtkCellData.h"
#include "vtkHexahedron.h"
#include "vtkHexahedron.h"
 Lines 48-90    Link Here 
#include "vtkUnstructuredGridAlgorithm.h"
#include "vtkUnstructuredGridAlgorithm.h"
#include "vtkObjectFactory.h"
#include "vtkObjectFactory.h"
#include "vtkDirectory.h"
#include "vtkDirectory.h"
#include "vtkPolyData.h"
#include "vtkPointData.h"
#include "vtkPVConfig.h" // for PARAVIEW_VERSION_MAJOR
#include <ctype.h>
#include <ctype.h>
#include <sys/stat.h>
#include <sys/stat.h>
#if 0
#ifdef VTK_USE_ANSI_STDLIB
#ifdef VTK_USE_ANSI_STDLIB
#define VTK_IOS_NOCREATE
#define VTK_IOS_NOCREATE
#else
#else
#define VTK_IOS_NOCREATE | ios::nocreate
#define VTK_IOS_NOCREATE | ios::nocreate
#endif
#endif
#endif
// The input buffer size in bytes. The purpose of the buffering is to
// reduce the number of costly gzread() calls so the buffer size
// doesn't have to be large.
#define VTK_FOAMFILE_BUFSIZE (2048)
// If the macro is set to 1 fast (but inaccurate) string to floating
// point number conversion routine is used instead of the system
// strtod(). This affects about 15% in performance for ascii cases.
#define VTK_FOAMFILE_FAST_STRTOD 1
vtkCxxRevisionMacro(vtkOpenFOAMReader, "$Revision: 1.10 $");
vtkCxxRevisionMacro(vtkOpenFOAMReader, "$Revision: 1.7.2.2 $");
vtkStandardNewMacro(vtkOpenFOAMReader);
vtkStandardNewMacro(vtkOpenFOAMReader);
struct stdString
struct stringVector
{
{
  vtkstd::string value;
  vtkstd::vector< vtkStdString > value;
};
};
struct stringVector
struct intVector
{
  vtkstd::vector< int > value;
};
struct doubleVector
{
  vtkstd::vector<double> value;
};
struct intVectorVector
{
  vtkstd::vector< vtkstd::vector< int > > value;
};
struct faceVectorVector
{
  vtkstd::vector< vtkstd::vector< face > > value;
};
struct unstructuredGridVector
{
  vtkstd::vector<vtkUnstructuredGrid*> value;
};
struct vtkOpenFOAMReader::vtkFoamError
{
private:
  vtkStdString str_;
public:
  vtkFoamError(): str_() {}
  vtkFoamError(vtkFoamError& e): str_(e.str()) {}
  const vtkStdString str() const { return str_; }
  // a super-easy way to make use of operator<<()'s defined in
  // vtkstd::ostringstream class
  template <class T> vtkFoamError& operator<<(const T& t)
  { vtkstd::ostringstream os; os << t; str_ += os.str(); return *this; }
};
// token class
// based on src/OpenFOAM/db/IOstreams/token/{token|tokenI}.H
// a word token is treated as a string token.
struct vtkOpenFOAMReader::vtkFoamToken
{
{
  vtkstd::vector< vtkstd::string > value;
public:
  enum tokenType { UNDEFINED, PUNCTUATION, STRING, LABEL, SCALAR, ERROR };
private:
  tokenType type_;
  vtkFoamToken(const vtkFoamToken&);
  void clear() { if(type_ == STRING) delete stringTokenPtr_; }
public:
  union
  {
    char punctuationToken_; vtkStdString* stringTokenPtr_; int labelToken_;
    double scalarToken_;
  };
  vtkFoamToken(): type_(UNDEFINED) {}
  ~vtkFoamToken() { clear(); }
  void setBad() { clear(); type_ = ERROR; }
  tokenType type() const { return type_; }
  bool isNumber() const { return type_ == LABEL || type_ == SCALAR; }
  char punctuationToken() const { return punctuationToken_; }
  int labelToken() const { return labelToken_; }
  double number() const
  { if(type_ == LABEL) return labelToken_; else return scalarToken_; }
  const vtkStdString& stringToken() const
  { return *stringTokenPtr_; }
  void operator=(const char c)
  { clear(); type_ = PUNCTUATION; punctuationToken_ = c; }
  void operator=(const char *s)
  { clear(); type_ = STRING; stringTokenPtr_ = new vtkStdString(s); }
  void operator=(const vtkStdString& s)
  { clear(); type_ = STRING; stringTokenPtr_ = new vtkStdString(s); }
  void operator=(const int l)
  { clear(); type_ = LABEL; labelToken_ = l; }
  void operator=(const double d)
  { clear(); type_ = SCALAR; scalarToken_ = d; }
  bool operator==(const char c) const
  { return type_ == PUNCTUATION && punctuationToken_ == c; }
  bool operator==(const int i) const
  { return type_ == LABEL && labelToken_ == i; }
  bool operator==(const vtkStdString& str) const
  { return type_ == STRING && *stringTokenPtr_ == str; }
  bool operator!=(const vtkStdString& str) const
  { return type_ != STRING || *stringTokenPtr_ != str; }
  bool operator!=(const char c) const { return !operator==(c); }
  friend vtkstd::ostringstream& operator<<(vtkstd::ostringstream& str,
    const vtkFoamToken& t)
  {
    if(t.type() == PUNCTUATION)
      {
      str << t.punctuationToken_;
      }
    else if(t.type() == STRING)
      {
      str << *t.stringTokenPtr_;
      }
    else if(t.type() == LABEL)
      {
      str << t.labelToken_;
      }
    else if(t.type() == SCALAR)
      {
      str << t.scalarToken_;
      }
    else if(t.type() == ERROR)
      {
      str << "badToken (an unexpected EOF?)";
      }
    return str;
  }
};
};
struct intVector
// read and tokenize the input
// line number counting is based on
// src/OpenFOAM/db/IOstreams/Sstreams/ISstreamI.H
struct vtkOpenFOAMReader::vtkFoamFile
{
private:
  gzFile file_;
  bool putBack_;
  int putBackC_;
  int lineNumber_;
  // buffer pointers. using raw pointers for performance reason.
  unsigned char *buf_;
  unsigned char *bufPtr_;
  unsigned char *bufEndPtr_;
  // declare and define as private
  void putBack(const int c)
  {
    if(putBack_)
      {
      throw vtkFoamError() << "Attempted duplicated putBack()";
      }
    else
      {
      if(c == '\n')
        {
        lineNumber_--;
        }
      *--bufPtr_ = c;
      putBack_ = true;
      }
  }
  // get a character
  int getc()
  {
    putBack_ = false;
    if(bufPtr_ == bufEndPtr_)
      {
      bufPtr_ = buf_ + 1; // reserve the first byte for getback char
      const int readSize = gzread(file_, bufPtr_, VTK_FOAMFILE_BUFSIZE - 1);
      if(readSize <= 0) // 0 byte read or EOF
        {
        // set the current location to the end of the buffer so that
        // getc() returns EOF again when called next time
        bufPtr_ = bufEndPtr_;
        return EOF;
        }
      bufEndPtr_ = bufPtr_ + readSize;
      }
    const int c = *bufPtr_++;
    if(c == '\n')
      {
      lineNumber_++;
      }
    return c;
  }
  // get next semantically valid character
  // based on src/OpenFOAM/db/IOstreams/Sstream/ISnextValid.C
  int nextValid()
  {
    int c;
    for(;;)
      {
      if((c = getc()) != EOF && isspace(c))
        {
        while((c = getc()) != EOF && isspace(c));
        }
      if(c == '/')
        {
        if((c = getc()) == EOF)
          {
          return '/';
          }
        if(c == '/') // one-line comment
          {
          while(EOF != (c = getc()) && c != '\n' && c != '\r');
          }
        else if(c == '*') // multi-line comment
          {
          for(;;)
            {
            if((c = getc()) == '*')
              {
              if((c = getc()) == '/')
                {
                break;
                }
              else if(c == EOF)
                {
                return EOF;
                }
              else
                {
                putBack(c);
                }
              }
            else if(c == EOF)
              {
              return EOF;
              }
            }
          }
        else
          {
          putBack(c);
          return '/';
          }
        }
      else // a valid character or an EOF
        {
        return c;
        }
      }
  }
  // valid as a character that constitutes a word or not
  // based on src/OpenFOAM/primitives/strings/word/wordI.H
  bool valid(const int c) const
  {
    return (!isspace(c) && c != '"' && c != '/' && c != ';' && c != '{'
      && c != '}');
  }
public:
  vtkFoamFile(): file_(NULL), putBack_(false), putBackC_(0), lineNumber_(0),
    buf_(NULL) {}
  ~vtkFoamFile() { close(); }
  void open(const vtkStdString& path)
  {
    lineNumber_ = 0;
    buf_ = new unsigned char[VTK_FOAMFILE_BUFSIZE];
    bufPtr_ = buf_;
    bufEndPtr_ = buf_;
    if(file_ != NULL)
      {
      throw vtkFoamError() << "File already opened";
      }
    if((file_ = gzopen(path.c_str(), "rb")) == NULL)
      {
      throw vtkFoamError() << "Can't open";
      }
    lineNumber_ = 1;
  }
  void close()
  {
    if(buf_ != NULL)
      {
      delete [] buf_;
      buf_ = NULL;
      }
    putBack_ = false;
    putBackC_ = 0;
    if(file_ != NULL)
      {
      gzclose(file_);
      file_ = NULL;
      }
    // don't reset the line number so that the last line number is
    // retained after close
    // lineNumber_ = 0;
  }
  int lineNumber() const { return lineNumber_; }
  // gzread with buffering handling
  int read(char *buf, const int len)
  {
    int readlen;
    const int buflen = bufEndPtr_ - bufPtr_;
    if(len > buflen)
      {
      memcpy(buf, bufPtr_, buflen);
      readlen = gzread(file_, buf + buflen, len - buflen);
      if(readlen >= 0)
        {
        readlen += buflen;
        }
      else
        {
        if(buflen == 0) // return EOF
          {
          readlen = -1;
          }
        else
          {
          readlen = buflen;
          }
        }
      bufPtr_ = bufEndPtr_;
      }
    else
      {
      memcpy(buf, bufPtr_, len);
      bufPtr_ += len;
      readlen = len;
      }
    for(int i = 0; i < readlen; i++)
      {
      if(buf[i] == '\n')
        {
        lineNumber_++;
        }
      }
    return readlen;
  }
  // the tokenizer
  // based on src/OpenFOAM/db/IOstreams/Sstreams/{ISreadToken|ISread}.C
  // returns true if success, false if encountered EOF
  bool read(vtkFoamToken& token)
  {
    int c = nextValid();
    if(c == EOF)
      {
      token.setBad();
      return false;
      }
    switch(c)
      {
      case ';': case '(': case ')': case '{': case '}': case '[': case ']':
      case ':': case ',': case '=': case '+': case '*': case '/':
        // punctuation token
        token = (char)c;
        return true;
      case '-': case '.': case '0': case '1': case '2': case '3': case '4':
      case '5': case '6': case '7': case '8': case '9':
        // number token
        {
        const int MAX_NUM = 100;
        static char numberBuffer[MAX_NUM];
        bool isScalar = false;
        if(c == '.')
          {
          isScalar = true;
          }
        int i = 0, isDigit;
        numberBuffer[i++] = c;
        while(EOF != (c = getc()) && i < MAX_NUM && ((isDigit = isdigit(c))
          || c == '.' || c == 'e' || c == 'E' || c == '+' || c == '-'))
          {
          numberBuffer[i++] = c;
          if(!isDigit)
            {
            isScalar = true;
            }
          }
        if(i == MAX_NUM)
          {
          if(c != EOF)
            {
            putBack(c);
            }
          numberBuffer[MAX_NUM - 1] = '\0';
          token.setBad();
          throw vtkFoamError() << "Reached the maximum allowed number length";
          }
        numberBuffer[i] = '\0';
        if(c != EOF)
          {
          putBack(c);
          if(i == 1 && numberBuffer[0] == '-')
            {
            token = '-';
            }
          else if(isScalar)
            {
            token = strtod(numberBuffer, NULL);
            }
          else
            {
            token = static_cast<int>(strtol(numberBuffer, NULL, 10));
            }
          return true;
          }
        else
          {
          throw vtkFoamError() << "Encountered EOF while tokenizing a number";
          }
        }
      case '"':
        // string token
        {
        const int MAX_STR = 1024;
        static char stringBuffer[MAX_STR];
        int i = 0;
        bool escape = false;
        while((c = getc()) != EOF)
          {
          if(c == '"' && !escape)
            {
            stringBuffer[i] = '\0';
            token = stringBuffer;
            return true;
            }
          if((c == '\n' || c == '\r') && !escape)
            {
            stringBuffer[i] = '\0';
            token = stringBuffer;
            throw vtkFoamError() << "Found a newline while reading string \""
                << stringBuffer << "\"";
            }
          if(c == '\\')
            {
            escape = true;
            }
          else
            {
            escape = false;
            stringBuffer[i] = c;
            if(++i == MAX_STR)
              {
              stringBuffer[MAX_STR - 1] = '\0';
              token = stringBuffer;
              throw vtkFoamError()
                << "Reached the maximum allowed string length";
              }
            }
          }
        stringBuffer[i] = '\0';
        token = stringBuffer;
        throw vtkFoamError() << "Encountered EOF while reading string";
        }
      default:
        // parses as a word token, but gives the STRING type for simplicity
        {
        putBack(c);
        const int MAX_WORD = 1024;
        static char wordBuffer[MAX_WORD];
        int i = 0;
        int bc = 0;
        while((EOF != (c = getc())) && valid(c))
          {
          if(i >= MAX_WORD)
            {
            wordBuffer[MAX_WORD - 1] = '\0';
            token = wordBuffer;
            throw vtkFoamError() << "Reached the maximum allowed word length.";
            }
          if(c == '(')
            {
            bc++;
            }
          else if(c == ')')
            {
            bc--;
            if(bc == -1)
              {
              break;
              }
            }
          wordBuffer[i++] = c;
          }
        if(i == 0)
          {
          token.setBad();
          throw vtkFoamError() << "Invalid first character as a token";
          }
        wordBuffer[i] = '\0';
        token = wordBuffer;
        if(c != EOF)
          {
          putBack(c);
          }
        return true;
        }
      }
  }
  void readExpecting(const char c)
  {
    vtkFoamToken t;
    if(!read(t))
      {
      throw vtkFoamError() << "Unexpected EOF";
      }
    if(t != c)
      {
      throw vtkFoamError() << "Expected punctuation token " << c << ", found "
        << t;
      }
  }
  void readExpecting(const char* str)
  {
    vtkFoamToken t;
    if(!read(t))
      {
      throw vtkFoamError() << "Unexpected EOF";
      }
    if(t != str)
      {
      throw vtkFoamError() << "Expected string \"" << str << "\", found " << t;
      }
  }
  // specialized for reading an integer value.
  // not using the standard strtol() for speed reason.
  int readLabel()
  {
    int c = nextValid();
    bool negative = false;
    if(c == '-')
      {
      negative = true;
      c = getc();
      }
    if(!isdigit(c))
      {
      throw vtkFoamError()
        << "Expected an integer, found a non-digit character" << (char)c;
      }
    int num = c - '0';
    while(EOF != (c = getc()) && isdigit(c))
      {
      num = 10 * num + c - '0';
      }
    if(c == EOF)
      {
      throw vtkFoamError() << "Encountered EOF while reading integer";
      }
    putBack(c);
    return negative ? -num : num;
  }
#if VTK_FOAMFILE_FAST_STRTOD
  // extreamely simplified high-performing string to floating point
  // conversion code based on
  // ParaView3/VTK/Utilities/vtksqlite/vtk_sqlite3.c
  double readNumber()
  {
    int c = nextValid();
    // determine sign
    bool negative = false;
    if(c == '-')
      {
      negative = true;
      c = getc();
      }
    if(c == EOF || (!isdigit(c) && c != '.' && c != 'e' && c != 'E'))
      {
      throw vtkFoamError()
        << "Expected a number, found a non-digit character" << (char)c;
      }
    // read integer part
    long double num = 0.0;
    while(c != EOF && isdigit(c))
      {
      num = num * 10.0 + (c - '0');
      c = getc();
      }
    // read decimal part
    if(c == '.')
      {
      long double divisor = 1.0;
      c = getc();
      while(c != EOF && isdigit(c))
        {
        num = num * 10.0 + (c - '0');
        divisor *= 10.0;
        c = getc();
        }
      num /= divisor;
      }
    // read exponent part
    if(c == 'e' || c == 'E')
      {
      int esign = 1;
      int eval = 0;
      long double scale = 1.0;
      c = getc();
      if(c == '-')
        {
        esign = -1;
        c = getc();
        }
      else if(c == '+')
        {
        c = getc();
        }
      while(c != EOF && isdigit(c))
        {
        eval = eval * 10 + c - '0';
        c = getc();
        }
      // fast exponent multiplication!
      while(eval >= 64)
        {
        scale *= 1.0e+64;
        eval -= 64;
        }
      while(eval >= 16)
        {
        scale *= 1.0e+16;
        eval -= 16;
        }
      while(eval >= 4)
        {
        scale *= 1.0e+4;
        eval -= 4;
        }
      while(eval >= 1)
        {
        scale *= 1.0e+1;
        eval -= 1;
        }
      if(esign < 0)
        {
        num /= scale;
        }
      else
        {
        num *= scale;
        }
      }
    if(c == EOF)
      {
      throw vtkFoamError() << "Unexpected EOF";
      }
    putBack(c);
    return static_cast<double>(negative ? -num : num);
  }
#else
  // specialized for reading a scalar value
  double readNumber()
  {
    int c = nextValid();
    if(c == EOF || (!isdigit(c) && c != '-' && c != '.'))
      {
      if(c == EOF)
        {
        throw vtkFoamError() << "Unexpected EOF";
        }
      else
        {
        throw vtkFoamError() << "Expected a number, found " << (char)c;
        }
      }
    const int MAX_NUM = 100;
    static char numberBuffer[MAX_NUM];
    int i = 0;
    numberBuffer[i++] = c;
    if(EOF != (c = getc()) && i < MAX_NUM && (isdigit(c)
      || c == '.' || c == 'e' || c == 'E')) // signs do not come as a 2nd char
      {
      numberBuffer[i++] = c;
      while(EOF != (c = getc()) && i < MAX_NUM && (isdigit(c)
        || c == '.' || c == 'e' || c == 'E' || c == '+' || c == '-'))
        {
        numberBuffer[i++] = c;
        }
      }
    if(i == MAX_NUM)
      {
      throw vtkFoamError() << "Reached the maximum allowed number length";
      }
    numberBuffer[i] = '\0';
    if(c == EOF)
      {
      throw vtkFoamError() << "Unexpected EOF";
      }
    else
      {
      putBack(c);
      if(i == 1 && numberBuffer[0] == '-')
        {
        throw vtkFoamError() << "Expected a number, found a minus sign";
        }
      }
    return strtod(numberBuffer, NULL);
  }
#endif
};
// IOobject class
// holds file handle, file format, name of the object the file holds and
// type of the object.
struct vtkOpenFOAMReader::vtkFoamIOobject: public vtkFoamFile
{
public:
  enum fileFormat { UNDEFINED, ASCII, BINARY };
private:
  vtkStdString fileName_;
  fileFormat format_;
  vtkStdString objectName_;
  vtkStdString headerClassName_;
  vtkFoamError* e_;
  void readHeader(); // defined later
public:
  vtkFoamIOobject(): vtkFoamFile(), format_(UNDEFINED), e_(NULL) {}
  ~vtkFoamIOobject() { close(); }
  bool open(const vtkStdString& file)
  {
    fileName_ = file;
    try
      {
      vtkFoamFile::open(file);
      }
    catch(vtkFoamError& e)
      {
      e_ = new vtkFoamError(e);
      return false;
      }
    try
      {
      readHeader();
      }
    catch(vtkFoamError& e)
      {
      vtkFoamFile::close();
      e_ = new vtkFoamError(e);
      return false;
      }
    e_ = NULL;
    return true;
  }
  void close()
  {
    vtkFoamFile::close();
    format_ = UNDEFINED;
    objectName_.erase();
    headerClassName_.erase();
    if(e_ != NULL)
      {
      delete e_;
      }
  }
  const vtkStdString& fileName() { return fileName_; }
  const fileFormat format() const { return format_; }
  const vtkStdString& className() const { return headerClassName_; }
  const vtkStdString& objectName() const { return objectName_; }
  const vtkFoamError& error() const { return *e_; }
  void setError(vtkFoamError& e)
  { if(e_ != NULL) delete e_; e_ = new vtkFoamError(e); }
};
// a class that represents a value of a dictionary entry that corresponds to
// its keyword. note that an entry can have more than one value.
struct vtkOpenFOAMReader::vtkFoamEntryValue
{
public:
  enum entryValueType
    {
    UNDEFINED, PUNCTUATION, STRING, LABEL, SCALAR, STRINGLIST, LABELLIST,
    LABELLISTLIST, SCALARLIST, VECTORLIST, ENTRYVALUELIST, EMPTYLIST,
    DICTIONARY, ERROR
    };
private:
  entryValueType type_;
  bool isUniform_;
  bool managed_;
  // don't pack them into a union
  vtkFoamToken t_;
  vtkstd::vector<vtkFoamEntryValue*> entryValuePtrs_;
  union
  {
    intVector *labelListPtr_; vtkDoubleArray *scalarListPtr_, *vectorListPtr_;
    stringVector *stringListPtr_; intVectorVector *labelListListPtr_;
    vtkFoamDict *dictPtr_;
  };
  void clear();
  void readList(vtkFoamIOobject& io);
public:
  vtkFoamEntryValue(): type_(UNDEFINED), isUniform_(false), managed_(true),
    labelListPtr_(NULL) {}
  ~vtkFoamEntryValue() { clear(); }
  entryValueType type() const { return type_; }
  void setEmptyList() { clear(); isUniform_ = false; type_ = EMPTYLIST; }
  bool isUniform() const { return isUniform_; }
  void read(vtkFoamIOobject& io);
  void readDictionary(vtkFoamIOobject& io,
    const vtkStdString& firstKeyword = "");
  const vtkFoamToken& token() const { return t_; }
  vtkFoamToken& token() { return t_; }
  const vtkstd::vector<int>& labelList() const
  { return labelListPtr_->value; }
  const vtkstd::vector<vtkstd::vector<int> >& labelListList() const
  { return labelListListPtr_->value; }
  vtkDoubleArray& scalarList()
  { return *scalarListPtr_; }
  vtkDoubleArray& vectorList()
  { return *vectorListPtr_; }
  vtkFoamDict& dictionary()
  { return *dictPtr_; }
  bool operator==(const char c) const
  { return type_ == PUNCTUATION && t_ == c; }
  bool operator!=(const char c) const
  { return type_ != PUNCTUATION || t_ != c; }
  bool operator==(const int i) const
  { return type_ == LABEL && t_ == i; }
  void *ptr()
  {
    managed_ = false; // the returned pointer will not be deleted by the d'tor
    return (void *)labelListPtr_; // all list pointers are in a single union
  }
  // the following two are for an exceptional expression of
  // `LABEL{LABELorSCALAR}' without type prefix (e. g. `2{-0}' in
  // mixedRhoE B.C. in rhopSonicFoam/shockTube)
  void makeLabelList(const int labelValue, const int size)
  {
    labelListPtr_ = new intVector;
    type_ = LABELLIST;
    vtkstd::vector<int>& ll = labelListPtr_->value;
    ll.resize(size);
    for(int i = 0; i < size; i++)
      {
      ll[i] = labelValue;
      }
  }
  void makeScalarList(const double scalarValue, const int size)
  {
    scalarListPtr_ = vtkDoubleArray::New();
    type_ = SCALARLIST;
    vtkDoubleArray& sl = *scalarListPtr_;
    sl.SetNumberOfValues(size);
    for(vtkIdType i = 0; i < size; i++)
      {
      sl.SetValue(i, scalarValue);
      }
  }
  // read a labelList
  void readLabelList(vtkFoamIOobject& io)
  {
    vtkFoamToken currToken;
    if(!io.read(currToken))
      {
      throw vtkFoamError() << "Unexpected EOF";
      }
    labelListPtr_ = new intVector;
    type_ = LABELLIST;
    if(currToken.type() == vtkFoamToken::LABEL)
      {
      const int size = currToken.labelToken();
      labelListPtr_->value.resize(size);
      if(!io.read(currToken))
        {
        throw vtkFoamError() << "Unexpected EOF";
        }
      vtkstd::vector<int>& ll = labelListPtr_->value;
      // some objects have lists with only one element enclosed by {}
      // e. g. simpleFoam/pitzDaily3Blocks/constant/polyMesh/faceZones
      if(currToken == '{')
        {
        int labelValue = io.readLabel();
        for(int i = 0; i < size; i++)
          {
          ll[i] = labelValue;
          }
        io.readExpecting('}');
        return;
        }
      if(currToken != '(')
        {
        throw vtkFoamError() << "Expected (, found " << currToken;
        }
      if(io.format() == vtkFoamIOobject::ASCII)
        {
        for(int i = 0; i < size; i++)
          {
          ll[i] = io.readLabel();
          }
        }
      else
        {
        if(size > 0) // avoid invalid access to ll.at(0)
          {
          io.read(reinterpret_cast<char*>(&ll.at(0)), size * sizeof(int));
          }
        }
      io.readExpecting(')');
      }
    else if(currToken == '(')
      {
      while(io.read(currToken) && currToken != ')')
        {
        if(currToken.type() != vtkFoamToken::LABEL)
          {
          throw vtkFoamError() << "Expected an integer or a (, found "
            << currToken;
          }
        labelListPtr_->value.push_back(currToken.labelToken());
        }
      }
    else
      {
      throw vtkFoamError() << "Expected integer or (, found " << currToken;
      }
  }
  // reads a list of labelLists. requires size prefix of the listList
  // to be present. size of the list must be present in the stream if
  // the format is binary.
  void readLabelListList(vtkFoamIOobject& io)
  {
    vtkFoamToken currToken;
    if(!io.read(currToken))
      {
      throw vtkFoamError() << "Unexpected EOF";
      }
    if(currToken.type() == vtkFoamToken::LABEL)
      {
      labelListListPtr_ = new intVectorVector;
      type_ = LABELLISTLIST;
      const int sizeI = currToken.labelToken();
      labelListListPtr_->value.resize(sizeI);
      io.readExpecting('(');
      for(int i = 0; i < sizeI; i++)
        {
        if(!io.read(currToken))
          {
          throw vtkFoamError() << "Unexpected EOF";
          }
        if(currToken.type() == vtkFoamToken::LABEL)
          {
          const int sizeJ = currToken.labelToken();
          labelListListPtr_->value[i].resize(sizeJ);
          io.readExpecting('(');
          vtkstd::vector<int>& labelListI = labelListListPtr_->value[i];
          if(io.format() == vtkFoamIOobject::ASCII)
            {
            for(int j = 0; j < sizeJ; j++)
              {
              labelListI[j] = io.readLabel();
              }
            }
          else
            {
            if(sizeJ > 0) // avoid invalid reference to labelListI.at(0)
              {
              io.read(reinterpret_cast<char*>(&labelListI.at(0)),
                sizeJ * sizeof(int));
              }
            }
          io.readExpecting(')');
          }
        else if(currToken == '(')
          {
          while(io.read(currToken) && currToken != ')')
            {
            if(currToken.type() != vtkFoamToken::LABEL)
              {
              throw vtkFoamError() << "Expected an integer, found "
                << currToken;
              }
            labelListListPtr_->value[i].push_back(currToken.labelToken());
            }
          }
        else
          {
          throw vtkFoamError() << "Expected integer or (, found " << currToken;
          }
        }
      io.readExpecting(')');
      }
    else
      {
      throw vtkFoamError() << "Expected integer, found " << currToken;
      }
  }
  // reads a scalarList. requires size prefix of the list to be
  // present in the stream if the format is binary.
  void readScalarList(vtkFoamIOobject& io)
  {
    vtkFoamToken currToken;
    if(!io.read(currToken))
      {
      throw vtkFoamError() << "Unexpected EOF";
      }
    scalarListPtr_ = vtkDoubleArray::New();
    type_ = SCALARLIST;
    if(currToken.type() == vtkFoamToken::LABEL)
      {
      const vtkIdType size = currToken.labelToken();
      scalarListPtr_->SetNumberOfValues(size);
      if(!io.read(currToken))
        {
        throw vtkFoamError() << "Unexpected EOF";
        }
      vtkDoubleArray& sl = *scalarListPtr_;
      // some objects have lists with only one element enclosed by {}
      // to represent a field with an uniform value
      if(currToken == '{')
        {
        double scalarValue = io.readNumber();
        for(vtkIdType i = 0; i < size; i++)
          {
          sl.SetValue(i, scalarValue);
          }
        io.readExpecting('}');
        return;
        }
      if(currToken != '(')
        {
        throw vtkFoamError() << "Expected (, found " << currToken;
        }
      if(io.format() == vtkFoamIOobject::ASCII)
        {
        for(vtkIdType i = 0; i < size; i++)
          {
          sl.SetValue(i, io.readNumber());
          }
        }
      else
        {
        if(size > 0) // avoid invalid access to GetPointer(0)
          {
          io.read(reinterpret_cast<char*>(sl.GetPointer(0)),
            size * sizeof(double));
          }
        }
      io.readExpecting(')');
      }
    else if(currToken == '(')
      {
      while(io.read(currToken) && currToken != ')')
        {
        if(!io.read(currToken) || !currToken.isNumber())
          {
          throw vtkFoamError() << "Expected an integer or a (, found "
            << currToken;
          }
        scalarListPtr_->InsertNextValue(currToken.number());
        }
      scalarListPtr_->Squeeze();
      }
    else
      {
      throw vtkFoamError() << "Expected integer or (, found " << currToken;
      }
  }
  // reads a vectorList. requires size prefix of the list to be
  // present in the stream if the format is binary.
  // if isPositions is true read Cloud type of data as particle positions
  // based on src/lagrangian/basic/particle/particleIO.C
  void readVectorList(vtkFoamIOobject& io, const bool isPositions)
  {
    vtkFoamToken currToken;
    if(!io.read(currToken))
      {
      throw vtkFoamError() << "Unexpected EOF";
      }
    vectorListPtr_ = vtkDoubleArray::New();
    vectorListPtr_->SetNumberOfComponents(3);
    type_ = VECTORLIST;
    if(currToken.type() == vtkFoamToken::LABEL)
      {
      const int size = currToken.labelToken();
      vectorListPtr_->SetNumberOfTuples(size);
      if(!io.read(currToken))
        {
        throw vtkFoamError() << "Unexpected EOF";
        }
      // some objects may have a vector list with one element enclosed by {}
      if(currToken == '{')
        {
        io.readExpecting('(');
        double vectorValue[3];
        vectorValue[0] = io.readNumber();
        vectorValue[1] = io.readNumber();
        vectorValue[2] = io.readNumber();
        for(int i = 0; i < size; i++)
          {
          vectorListPtr_->SetTuple(i, vectorValue);
          }
        io.readExpecting(')');
        if(isPositions)
          {
          // skip label celli
          io.readLabel();
          }
        io.readExpecting('}');
        return;
        }
      if(currToken != '(')
        {
        throw vtkFoamError() << "Expected (, found " << currToken;
        }
      if(io.format() == vtkFoamIOobject::ASCII)
        {
        if(size > 0) // avoid invalid access to GetPointer(0)
          {
          double* vectorComponentI = vectorListPtr_->GetPointer(0);
          for(int i = 0; i < size; i++)
            {
            io.readExpecting('(');
            *vectorComponentI++ = io.readNumber();
            *vectorComponentI++ = io.readNumber();
            *vectorComponentI++ = io.readNumber();
            io.readExpecting(')');
            if(isPositions)
              {
              // skip label celli
              io.readLabel();
              }
            }
          }
        }
      else // binary
        {
        if(isPositions) // lagrangian/positions (class Cloud)
          {
          if(size > 0) // avoid invalid access to GetPointer()
            {
            for(int i = 0, index = 0; i < size; i++, index += 3)
              {
              io.readExpecting('(');
              io.read(reinterpret_cast<char*>(vectorListPtr_
                ->GetPointer(index)), sizeof(double) * 3);
              // skip label celli, label facei and scalar stepFraction
              const int dummySize = 2 * sizeof(int) + sizeof(double);
              char dummyBuf[dummySize];
              io.read(dummyBuf, dummySize);
              io.readExpecting(')');
              }
            }
          }
        else // regular vectorField
          {
          if(size > 0) // avoid invalid access to GetPointer()
            {
            io.read(reinterpret_cast<char*>(vectorListPtr_->GetPointer(0)),
              size * sizeof(double) * 3);
            }
          }
        }
      io.readExpecting(')');
      }
    else if(currToken == '(')
      {
      while(io.read(currToken) && currToken != ')')
        {
        if(currToken != '(')
          {
          throw vtkFoamError() << "Expected (, found " << currToken;
          }
        double v[3];
        v[0] = io.readNumber();
        v[1] = io.readNumber();
        v[2] = io.readNumber();
        vectorListPtr_->InsertNextTuple(v);
        io.readExpecting(')');
        }
      vectorListPtr_->Squeeze();
      }
    else
      {
      throw vtkFoamError() << "Expected integer or (, found " << currToken;
      }
  }
  const vtkFoamEntryValue& operator>>(vtkStdString& str) const
  {
    if(type_ == STRING)
      {
      str = vtkStdString(t_.stringToken());
      }
    else
      {
      //vtkErrorMacro("token type does not match");
      str = "";
      }
    return *this;
  }
  const vtkFoamEntryValue& operator>>(double& d) const
  {
    if(type_ == SCALAR || type_ == LABEL)
      {
      d = t_.number();
      }
    else
      {
      //vtkErrorMacro("token type does not match");
      d = 0.0;
      }
    return *this;
  }
  const vtkFoamEntryValue& operator>>(int& i) const
  {
    if(type_ == LABEL)
      {
      i = t_.labelToken();
      }
    else
      {
      //vtkErrorMacro("token type does not match");
      i = 0;
      }
    return *this;
  }
};
// a class that represents an entry of a dictionary. note that an
// entry can have more than one value.
struct vtkOpenFOAMReader::vtkFoamEntry
{
private:
  vtkStdString keyword_;
  vtkstd::vector<vtkFoamEntryValue*> valuePtrs_;
public:
  vtkFoamEntry() {}
  ~vtkFoamEntry()
  {
    for(size_t i = 0; i < valuePtrs_.size(); i++)
      {
      delete valuePtrs_[i];
      }
  }
  vtkStdString& keyword() { return keyword_; }
  size_t size() const { return valuePtrs_.size(); }
  // returns false if the number of the values is 0 to simplify things
  bool found() const { return valuePtrs_.size() > 0; }
  vtkFoamEntryValue& firstValue() const { return *valuePtrs_[0]; }
  const vtkstd::vector<int>& labelList() const
  { return firstValue().labelList(); }
  const vtkstd::vector<vtkstd::vector<int> >& labelListList() const
  { return firstValue().labelListList(); }
  vtkDoubleArray& scalarList()
  { return firstValue().scalarList(); }
  vtkDoubleArray& vectorList()
  { return firstValue().vectorList(); }
  vtkFoamDict& dictionary() // not using firstValue() for breaking constness
  { return valuePtrs_[0]->dictionary(); }
  void *ptr() { return firstValue().ptr(); }
  void readDictionary(vtkFoamIOobject& io)
  {
    valuePtrs_.push_back(new vtkFoamEntryValue);
    valuePtrs_.back()->readDictionary(io);
  }
  // read values of an entry
  void read(vtkFoamIOobject& io);
  const vtkFoamEntry& operator>>(vtkStdString& str) const
  {
    if(!found() || valuePtrs_[0]->type() != vtkFoamEntryValue::STRING)
      {
      str = "";
      }
    else
      {
      valuePtrs_[0]->operator>>(str);
      }
    return *this;
  }
  const vtkFoamEntry& operator>>(double& d) const
  {
    if(!found() || (valuePtrs_[0]->type() != vtkFoamEntryValue::SCALAR
      && valuePtrs_[0]->type() != vtkFoamEntryValue::LABEL))
      {
      d = 0.0;
      }
    else
      {
      valuePtrs_[0]->operator>>(d);
      }
    return *this;
  }
  const vtkFoamEntry& operator>>(int& i) const
  {
    if(!found() || valuePtrs_[0]->type() != vtkFoamEntryValue::LABEL)
      {
      i = 0;
      }
    else
      {
      valuePtrs_[0]->operator>>(i);
      }
    return *this;
  }
};
// a class that holds a FoamFile data structure
struct vtkOpenFOAMReader::vtkFoamDict: public vtkFoamEntryValue
{
public:
  enum dictType
    { UNDEFINED, DICTIONARY, SCALARLIST, VECTORLIST, LABELLIST, LABELLISTLIST,
      UNIFORMLABELLIST, UNIFORMSCALARLIST };
private:
  dictType type_;
  vtkstd::vector<vtkFoamEntry*> entryPtrs_;
  vtkFoamEntry* dummyEntryPtr_;
  vtkFoamDict(const vtkFoamDict &);
public:
  vtkFoamDict(): vtkFoamEntryValue(), type_(UNDEFINED), dummyEntryPtr_(NULL) {}
  ~vtkFoamDict()
  {
    if(type_ == DICTIONARY)
      {
      for(size_t i = 0; i < entryPtrs_.size(); i++)
        {
        delete entryPtrs_[i];
        }
      }
    if(dummyEntryPtr_ != NULL)
      {
      delete dummyEntryPtr_;
      }
  }
  dictType type() const { return type_; }
  size_t size() const { return entryPtrs_.size(); }
  vtkFoamEntry& entry(const int i) { return *entryPtrs_[i]; }
  vtkFoamEntry& lookup(const vtkStdString& keyword)
  {
    if(type_ == DICTIONARY)
      {
      for(size_t i = 0; i < entryPtrs_.size(); i++)
        {
        if(entryPtrs_[i]->keyword() == keyword) // found
          {
          return *entryPtrs_[i];
          }
        }
      }
    // not found
    if(dummyEntryPtr_ == NULL)
      {
      dummyEntryPtr_ = new vtkFoamEntry;
      }
    return *dummyEntryPtr_;
  }
  // reads a FoamFile or a subdictionary. if the stream to be read is
  // a subdictionary the preceding '{' is assumed to have already been
  // thrown away.
  bool read(vtkFoamIOobject& io, const bool isSubDictionary = false,
    const vtkStdString& firstKeyword = "")
  {
    try
      {
      vtkFoamToken currToken;
      if(firstKeyword == "")
        {
        if(!isSubDictionary)
          {
          // polyMesh/points, lagrangian vectors
          if(io.className() == "vectorField")
            {
            readVectorList(io, false);
            type_ = VECTORLIST;
            return true;
            }
          else if(io.className() == "scalarField") // lagrangian scalars
            {
            readScalarList(io);
            type_ = SCALARLIST;
            return true;
            }
          else if(io.className() == "Cloud") // lagrangian/positions
            {
            readVectorList(io, true);
            type_ = VECTORLIST;
            return true;
            }
          else if(io.className() == "faceList") // polyMesh/faces
            {
            readLabelListList(io);
            type_ = LABELLISTLIST;
            return true;
            }
          else if(io.className() == "labelList") // polyMesh/{owner|neighbour}
            {
            readLabelList(io);
            type_ = LABELLIST;
            return true;
            }
          }
        // read the first token
        if(!io.read(currToken))
          {
          throw vtkFoamError() << "Unexpected EOF";
          }
        // list of dictionaries is read as a usual dictionary
        // polyMesh/boundary, point/face/cell-Zones
        if(!isSubDictionary && currToken.type() == vtkFoamToken::LABEL)
          {
          io.readExpecting('(');
          if(currToken.labelToken() > 0)
            {
            if(!io.read(currToken))
              {
              throw vtkFoamError() << "Unexpected EOF";
              }
            // continue to read as a usual dictionary
            }
          else // return as empty dictionary
            {
            io.readExpecting(')');
            type_ = DICTIONARY;
            return true;
            }
          }
        // some boundary files does not have the number of boundary
        // patches (e.g. settlingFoam/tank3D). in this case we need to
        // explicitly read the file as a dictionary.
        else if(!isSubDictionary && currToken == '('
          && io.className() == "polyBoundaryMesh") // polyMesh/boundary
          {
	    if(!io.read(currToken)) // read the first keyword
            {
            throw vtkFoamError() << "Unexpected EOF";
            }
          if(currToken == ')') // return as empty dictionary
            {
            type_ = DICTIONARY;
            return true;
            }
          }
	// the following two else-if clauses are for an exceptional
	// expression of `LABEL{LABELorSCALAR}' without type prefix
	// (e. g. `2{-0}' in mixedRhoE B.C. in
	// rhopSonicFoam/shockTube)
	else if(isSubDictionary && currToken.type() == vtkFoamToken::LABEL)
	  {
          token() = currToken.labelToken();
          type_ = UNIFORMLABELLIST;
          io.readExpecting('}');
          return true;
          }
	else if(isSubDictionary && currToken.type() == vtkFoamToken::SCALAR)
	  {
          token() = currToken.number();
          type_ = UNIFORMSCALARLIST;
          io.readExpecting('}');
          return true;
          }
        // return as empty dictionary
        else if(isSubDictionary && currToken == '}')
          {
          type_ = DICTIONARY;
          return true;
          }
        }
      // if firstKeyword is set read the following stream as subdictionary
      else
        {
        entryPtrs_.push_back(new vtkFoamEntry);
        entryPtrs_.back()->keyword() = firstKeyword;
        entryPtrs_.back()->readDictionary(io);
        if(!io.read(currToken) || currToken == '}' || currToken == ')')
          {
          type_ = DICTIONARY;
          return true;
          }
        }
      if(currToken.type() == vtkFoamToken::STRING) // general dictionary
        {
        // based on src/OpenFOAM/db/dictionary/dictionaryIO.C
        do
          {
          if(currToken != ';') // ignore empty entry
            {
            entryPtrs_.push_back(new vtkFoamEntry);
            entryPtrs_.back()->keyword() = currToken.stringToken();
            entryPtrs_.back()->read(io);
            if(currToken == "FoamFile")
              {
              // delete the FoamFile header subdictionary entry
              delete entryPtrs_.back();
              entryPtrs_.pop_back();
              }
            }
          } while(io.read(currToken)
            && (currToken.type() == vtkFoamToken::STRING || currToken == ';'));
        if(currToken.type() == vtkFoamToken::ERROR || currToken == '}'
          || currToken == ')')
          {
          type_ = DICTIONARY;
          return true;
          }
        throw vtkFoamError()
          << "Expected keyword, closing brace, ; or EOF, found " << currToken;
        }
      throw vtkFoamError() << "Bad first keyword for dictionary " << currToken;
      }
    catch(vtkFoamError& e)
      {
      if(isSubDictionary)
        {
        throw;
        }
      else
        {
        io.setError(e);
        return false;
        }
      }
  }
};
void vtkOpenFOAMReader::vtkFoamIOobject::readHeader()
{
  vtkFoamToken firstToken;
  readExpecting("FoamFile");
  readExpecting('{');
  vtkFoamDict headerDict;
  headerDict.read(*this, true); // throw exception in case of error
  vtkFoamEntry& formatEntry = headerDict.lookup("format");
  if(!formatEntry.found())
    {
    throw vtkFoamError()
      << "the format entry (binary/ascii) not found in FoamFile header";
    }
  vtkStdString format;
  formatEntry >> format;
  // case does matter (e. g. "BINARY" is treated as ascii)
  // see src/OpenFOAM/db/IOstreams/IOstreams/IOstream.C
  if(format == "binary")
    {
    format_ = BINARY;
    }
  else
    {
    format_ = ASCII;
    }
  vtkFoamEntry& classEntry = headerDict.lookup("class");
  if(!classEntry.found())
    {
    throw vtkFoamError() << "class name not found in FoamFile header";
    }
  classEntry >> headerClassName_;
  vtkFoamEntry& objectEntry = headerDict.lookup("object");
  if(!objectEntry.found())
    {
    throw vtkFoamError() << "object name not found in FoamFile header";
    }
  objectEntry >> objectName_;
}
void vtkOpenFOAMReader::vtkFoamEntryValue::clear()
{
  if(managed_)
    {
    if(type_ == LABELLIST)
      {
      delete labelListPtr_;
      }
    else if(type_ == LABELLISTLIST)
      {
      delete labelListListPtr_;
      }
    else if(type_ == SCALARLIST)
      {
      scalarListPtr_->Delete();
      }
    else if(type_ == VECTORLIST)
      {
      vectorListPtr_->Delete();
      }
    else if(type_ == STRINGLIST)
      {
      delete stringListPtr_;
      }
    else if(type_ == ENTRYVALUELIST)
      {
      for(size_t i = 0; i < entryValuePtrs_.size() ; i++)
        {
        delete entryValuePtrs_[i];
        }
      }
    else if(type_ == DICTIONARY)
      {
      delete dictPtr_;
      }
    }
}
// general-purpose list reader - guess the type of the list and read
// it. only supports ascii format and assumes the preceding '(' has
// already been thrown away.  the reader supports nested list with
// variable lengths (e. g. `((token token) (token token token)).'
// also supports compound of tokens and lists (e. g. `((token token)
// token)') only if a list comes as the first value.
void vtkOpenFOAMReader::vtkFoamEntryValue::readList(vtkFoamIOobject& io)
{
  io.read(t_);
  // initial guess of the list type
  if(t_.type() == vtkFoamToken::LABEL)
    {
    // if the first token is of type LABEL it might be either an element of
    // a labelList or the size of a sublist so proceed to the next token
    vtkFoamToken nextToken;
    if(!io.read(nextToken))
      {
      throw vtkFoamError() << "Unexpected EOF";
      }
    if(nextToken.type() == vtkFoamToken::LABEL)
      {
      labelListPtr_ = new intVector;
      labelListPtr_->value.push_back(t_.labelToken());
      labelListPtr_->value.push_back(nextToken.labelToken());
      type_ = LABELLIST;
      }
    else if(nextToken.type() == vtkFoamToken::SCALAR)
      {
      scalarListPtr_ = vtkDoubleArray::New();
      scalarListPtr_->InsertNextValue(t_.number());
      scalarListPtr_->InsertNextValue(nextToken.number());
      type_ = SCALARLIST;
      }
    else if(nextToken == '(') // list of list: read recursively
      {
      entryValuePtrs_.push_back(new vtkFoamEntryValue);
      entryValuePtrs_.back()->readList(io);
      type_ = ENTRYVALUELIST;
      }
    else if(nextToken == ')') // list with only one label element
      {
      labelListPtr_ = new intVector;
      labelListPtr_->value.push_back(t_.labelToken());
      type_ = LABELLIST;
      return;
      }
    else
      {
      throw vtkFoamError() << "Expected number, ( or ), found " << nextToken;
      }
    }
  else if(t_.type() == vtkFoamToken::SCALAR)
    {
    scalarListPtr_ = vtkDoubleArray::New();
    scalarListPtr_->InsertNextValue(t_.number());
    type_ = SCALARLIST;
    }
  // if the first word is a string we have to read another token to determine
  // if the first word is a keyword for the following dictionary
  else if(t_.type() == vtkFoamToken::STRING)
    {
    vtkFoamToken nextToken;
    if(!io.read(nextToken))
      {
      throw vtkFoamError() << "Unexpected EOF";
      }
    if(nextToken.type() == vtkFoamToken::STRING) // list of strings
      {
      stringListPtr_ = new stringVector;
      stringListPtr_->value.push_back(t_.stringToken());
      stringListPtr_->value.push_back(nextToken.stringToken());
      type_ = STRINGLIST;
      }
    // dictionary with the already read stringToken as the first keyword
    else if(nextToken == '{')
      {
      if(t_.stringToken() == "")
        {
        throw "Empty string is invalid as a keyword for dictionary entry";
        }
      readDictionary(io, t_.stringToken());
      // the dictionary read as list has the entry terminator ';' so
      // we have to skip it
      return;
      }
    else if(nextToken == ')') // list with only one string element
      {
      stringListPtr_ = new stringVector;
      stringListPtr_->value.push_back(t_.stringToken());
      type_ = STRINGLIST;
      return;
      }
    else
      {
      throw vtkFoamError() << "Expected string, { or ), found " << nextToken;
      }
    }
  else if(t_ == '(') // list of lists: read recursively
    {
    entryValuePtrs_.push_back(new vtkFoamEntryValue);
    entryValuePtrs_.back()->readList(io);
    // read all the following values as arbitrary entryValues
    // the alphaContactAngle b.c. in multiphaseInterFoam/damBreak4phase
    // reaquires this treatment (reading by readList() is not enough)
    do
      {
      entryValuePtrs_.push_back(new vtkFoamEntryValue);
      entryValuePtrs_.back()->read(io);
      }
    while(*entryValuePtrs_.back() != ')' && *entryValuePtrs_.back() != '}'
      && *entryValuePtrs_.back() != ';');
    if(*entryValuePtrs_.back() != ')')
      {
      throw vtkFoamError() << "Expected ) before "
        << entryValuePtrs_.back()->token();
      }
    // delete ')'
    delete entryValuePtrs_.back();
    entryValuePtrs_.pop_back();
    type_ = ENTRYVALUELIST;
    return;
    }
  else if(t_ == ')') // empty list
    {
    type_ = EMPTYLIST;
    return;
    }
  while(io.read(t_) && t_ != ')')
    {
    if(type_ == LABELLIST)
      {
      if(t_.type() == vtkFoamToken::SCALAR) // switch to scalarList
        {
        // labelListPtr_ and scalarListPtr_ are packed into a single union so
        // we need a temprary pointer
        vtkDoubleArray* slPtr = vtkDoubleArray::New();
        const vtkIdType size = labelListPtr_->value.size();
        slPtr->SetNumberOfValues(size);
        for(vtkIdType i = 0; i < size; i++)
          {
          slPtr->SetValue(i, double(labelListPtr_->value[i]));
          }
        delete labelListPtr_;
        slPtr->InsertNextValue(t_.number());
        scalarListPtr_ = slPtr; // copy after labelListPtr_ is deleted
        type_ = SCALARLIST;
        }
      else if(t_.type() == vtkFoamToken::LABEL)
        {
        labelListPtr_->value.push_back(t_.labelToken());
        }
      else
        {
        throw vtkFoamError() << "Expected a number, found " << t_;
        }
      }
    else if(type_ == SCALARLIST)
      {
      if(t_.isNumber())
        {
        scalarListPtr_->InsertNextValue(t_.number());
        }
      else
        {
        throw vtkFoamError() << "Expected a number, found " << t_;
        }
      }
    else if(type_ == STRINGLIST)
      {
      if(t_.type() == vtkFoamToken::STRING)
        {
        stringListPtr_->value.push_back(t_.stringToken());
        }
      else
        {
        throw vtkFoamError() << "Expected a string, found " << t_;
        }
      }
    else if(type_ == ENTRYVALUELIST)
      {
      if(t_.type() == vtkFoamToken::LABEL)
        {
        // skip the number of elements to make things simple
        if(!io.read(t_))
          {
          throw vtkFoamError() << "Unexpected EOF";
          }
        }
      if(t_ != '(')
        {
        throw vtkFoamError() << "Expected (, found " << t_;
        }
      entryValuePtrs_.push_back(new vtkFoamEntryValue);
      entryValuePtrs_.back()->readList(io);
      }
    else
      {
      throw vtkFoamError() << "Unexpected token " << t_;
      }
    }
  if(type_ == SCALARLIST)
    {
    scalarListPtr_->Squeeze();
    }
}
// a list of dictionaries is actually read as a dictionary
void vtkOpenFOAMReader::vtkFoamEntryValue::readDictionary(vtkFoamIOobject& io,
  const vtkStdString& firstKeyword)
{
  dictPtr_ = new vtkFoamDict;
  type_ = DICTIONARY;
  dictPtr_->read(io, true, firstKeyword);
}
// guess the type of the given entry value and read it
void vtkOpenFOAMReader::vtkFoamEntryValue::read(vtkFoamIOobject& io)
{
  if(!io.read(t_))
    {
    throw vtkFoamError() << "Unexpected EOF";
    }
  if(t_ == '{')
    {
    readDictionary(io);
    return;
    }
  // for reading sublist from vtkFoamEntryValue::readList() or there
  // are cases where lists without the (non)uniform keyword appear
  // (e. g. coodles/pitsDaily/0/U, Hrv's uniformFixedValue b.c.)
  else if(t_ == '(')
    {
    readList(io);
    return;
    }
  else if(t_ == "uniform")
    {
    if(!io.read(t_))
      {
      throw vtkFoamError()
        << "Expected a uniform value or a list, found unexpected EOF";
      }
    if(t_ == '(')
      {
      readList(io);
      }
    else if(t_.type() == vtkFoamToken::LABEL)
      {
      type_ = LABEL;
      }
    else if(t_.type() == vtkFoamToken::SCALAR)
      {
      type_ = SCALAR;
      }
    else if(t_.type() == vtkFoamToken::STRING)
      {
      type_ = STRING;
      }
    else // unexpected punctuation token
      {
      throw vtkFoamError() << "Expected number, string or (, found " << t_;
      }
    isUniform_ = true;
    }
  else if(t_ == "nonuniform")
    {
    if(!io.read(t_))
      {
      throw vtkFoamError() << "Expected list type specifier, found EOF";
      }
    if(t_ == "List<vector>")
      {
      isUniform_ = false;
      readVectorList(io, false);
      }
    else if(t_ == "List<scalar>")
      {
      isUniform_ = false;
      readScalarList(io);
      }
    // List<bool> is read as List<label>
    else if(t_ == "List<label>" || t_ == "List<bool>")
      {
      isUniform_ = false;
      readLabelList(io);
      }
    // an empty list doesn't have a list type specifier
    else if(t_.type() == vtkFoamToken::LABEL && t_.labelToken() == 0)
      {
      type_ = EMPTYLIST;
      isUniform_ = false;
      io.readExpecting('(');
      io.readExpecting(')');
      }
    else
      {
      throw vtkFoamError() << "Unsupported nonuniform list type " << t_;
      }
    }
  // zones have list without a uniform/nonuniform keyword
  // List<bool> is read as List<label>
  // (e. g. flipMap entry in point/face/cellZones)
  else if(t_ == "List<label>" || t_ == "List<bool>")
    {
    isUniform_ = false;
    readLabelList(io);
    }
  else if(t_.type() == vtkFoamToken::LABEL)
    {
    type_ = LABEL;
    }
  else if(t_.type() == vtkFoamToken::SCALAR)
    {
    type_ = SCALAR;
    }
  else if(t_.type() == vtkFoamToken::STRING)
    {
    type_ = STRING;
    }
  else if(t_.type() == vtkFoamToken::PUNCTUATION)
    {
    type_ = PUNCTUATION;
    }
}
// read values of an entry
void vtkOpenFOAMReader::vtkFoamEntry::read(vtkFoamIOobject& io)
{
{
  vtkstd::vector< int > value;
  for(;;)
};
    {
    valuePtrs_.push_back(new vtkFoamEntryValue);
    valuePtrs_.back()->read(io);
struct intVectorVector
    if(valuePtrs_.size() >= 2)
{
      {
  vtkstd::vector< vtkstd::vector< int > > value;
      vtkFoamEntryValue& secondLastValue
};
        = *valuePtrs_[valuePtrs_.size() - 2];
      if(secondLastValue.type() == vtkFoamEntryValue::LABEL)
        {
        vtkFoamEntryValue& lastValue = *valuePtrs_.back();
        // a zero-sized nonuniform list without prefixing "nonuniform"
        // keyword nor list type specifier (i. e. `0()';
        // e. g. simpleEngine/0/polyMesh/pointZones) requires special
        // care (one with nonuniform prefix is treated within
        // vtkFoamEntryValue::read()). still this causes errornous
        // behavior for `0 nonuniform 0()' but this should be extremely
        // rare
        if(lastValue.type() == vtkFoamEntryValue::EMPTYLIST
          && secondLastValue == 0)
          {
          delete valuePtrs_.back();
          valuePtrs_.pop_back(); // delete the last value
          valuePtrs_.back()->setEmptyList(); // mark new last value as empty
          }
        // for an exceptional expression of `LABEL{LABELorSCALAR}' without
        // type prefix (e. g. `2{-0}' in mixedRhoE B.C. in
        // rhopSonicFoam/shockTube)
        else if(lastValue.type() == vtkFoamEntryValue::DICTIONARY)
          {
          if(lastValue.dictionary().type() == vtkFoamDict::UNIFORMLABELLIST)
            {
            const int size = secondLastValue.token().labelToken();
            const int value = lastValue.dictionary().token().labelToken();
            // delete last two values
            delete valuePtrs_.back();
            valuePtrs_.pop_back();
            delete valuePtrs_.back();
            valuePtrs_.pop_back();
            // make new labelList
            valuePtrs_.push_back(new vtkFoamEntryValue);
            valuePtrs_.back()->makeLabelList(value, size);
            }
          else if(lastValue.dictionary().type()
            == vtkFoamDict::UNIFORMSCALARLIST)
            {
            const int size = secondLastValue.token().labelToken();
            const double value = lastValue.dictionary().token().number();
            // delete last two values
            delete valuePtrs_.back();
            valuePtrs_.pop_back();
            delete valuePtrs_.back();
            valuePtrs_.pop_back();
            // make new labelList
            valuePtrs_.push_back(new vtkFoamEntryValue);
            valuePtrs_.back()->makeScalarList(value, size);
            }
          }
        }
      }
struct faceVectorVector
    if(*valuePtrs_.back() == ';')
{
      {
  vtkstd::vector< vtkstd::vector< face > > value;
      delete valuePtrs_.back();
};
      valuePtrs_.pop_back();
      break;
      }
    else if(valuePtrs_.back()->type() == vtkFoamEntryValue::DICTIONARY)
      {
      // subdictionary is not suffixed by an entry terminator ';'
      break;
      }
    else if(*valuePtrs_.back() == '}' || *valuePtrs_.back() == ')')
      {
      throw vtkFoamError() << "Unmatched " << valuePtrs_.back()->token();
      }
    }
}
vtkOpenFOAMReader::vtkOpenFOAMReader()
vtkOpenFOAMReader::vtkOpenFOAMReader()
{
{
 Lines 95-154    Link Here 
  this->FileName = NULL;
  this->FileName = NULL;
  //VTK CLASSES
  //VTK CLASSES
  this->Points = vtkPoints::New();
  this->PatchDataArraySelection = vtkDataArraySelection::New();
  this->CellDataArraySelection = vtkDataArraySelection::New();
  this->CellDataArraySelection = vtkDataArraySelection::New();
  this->PointDataArraySelection = vtkDataArraySelection::New();
  // Setup the Selection observer for the above selection arrays
  this->SelectionObserver = vtkCallbackCommand::New();
  this->SelectionObserver
    ->SetCallback(&vtkOpenFOAMReader::SelectionModifiedCallback);
  this->SelectionObserver->SetClientData(this);
  this->PatchDataArraySelection
    ->AddObserver(vtkCommand::ModifiedEvent,this->SelectionObserver);
  this->CellDataArraySelection
    ->AddObserver(vtkCommand::ModifiedEvent,this->SelectionObserver);
  this->PointDataArraySelection
    ->AddObserver(vtkCommand::ModifiedEvent,this->SelectionObserver);
  // Initialise the Selection status arrays
  this->CellSelectionOldStatus = 0;
  this->PointSelectionOldStatus = 0;
  this->PatchSelectionOldStatus = 0;
  this->CellSelectionStatus = 0;
  this->PointSelectionStatus = 0;
  this->PatchSelectionStatus = 0;
  //DATA COUNTS
  //DATA COUNTS
  this->NumFaces = 0;
  this->NumPoints = 0;
  this->NumCells = 0;
  this->NumCells = 0;
  this->TimeStepData = new stringVector;
  this->TimeStepData = new stringVector;
  this->Path = new stdString;
  this->LagrangianTimeStepData = new stringVector;
  this->PathPrefix = new stdString;
  this->OldFileName = new vtkStdString;
  this->PathPrefix = new vtkStdString;
  this->PolyMeshPointsDir = new stringVector;
  this->PolyMeshPointsDir = new stringVector;
  this->PolyMeshFacesDir = new stringVector;
  this->PolyMeshFacesDir = new stringVector;
  this->BoundaryNames = new stringVector;
  this->PointZoneNames = new stringVector;
  this->FaceZoneNames = new stringVector;
  this->CellZoneNames = new stringVector;
  this->FacePoints = new intVectorVector;
  this->FacesOwnerCell = new intVectorVector;
  this->FacesNeighborCell = new intVectorVector;
  this->FacesOfCell = new faceVectorVector;
  this->SizeOfBoundary = new intVector;
  //DATA TIMES
  //DATA TIMES
  this->NumberOfTimeSteps = 0;
  this->NumberOfTimeSteps = 0;
  this->Steps = NULL;
  this->Steps = NULL;
  this->TimeNames = vtkStringArray::New();
  this->TimeStep = 0;
  this->TimeStep = 0;
  this->TimeStepRange[0] = 0;
  this->TimeStepRange[0] = 0;
  this->TimeStepRange[1] = 0;
  this->TimeStepRange[1] = 0;
  this->RequestInformationFlag = true;
  // for caching mesh
  this->CacheMesh = 1;
  this->OldTimeStep = -1;
  this->InternalMesh = NULL;
  this->BoundaryMesh = NULL;
  this->BoundaryDict = NULL;
  this->FaceOwner = NULL;
  this->PointZoneMesh = NULL;
  this->FaceZoneMesh = NULL;
  this->CellZoneMesh = NULL;
  // for reading zones
  this->ReadZones = 0; // turned off by default
  // for accumulating patches across time-steps (Turned on by default)
  // As of now, only accumulation of patches is implemented
  this->KeepPatches = 1;
}
}
vtkOpenFOAMReader::~vtkOpenFOAMReader()
vtkOpenFOAMReader::~vtkOpenFOAMReader()
{
{
  vtkDebugMacro(<<"DeConstructor");
  vtkDebugMacro(<<"DeConstructor");
  this->Points->Delete();
  // Delete the Observers before deleting the Selection Arrays !!!
  this->PatchDataArraySelection->RemoveObserver(this->SelectionObserver);
  this->CellDataArraySelection->RemoveObserver(this->SelectionObserver);
  this->PointDataArraySelection->RemoveObserver(this->SelectionObserver);
  // Now delete the Selection Observer itself
  this->SelectionObserver->Delete();
  // Finally delete the Selection Arrays
  this->PatchDataArraySelection->Delete();
  this->CellDataArraySelection->Delete();
  this->CellDataArraySelection->Delete();
  delete [] this->Steps;
  this->PointDataArraySelection->Delete();
  delete this->TimeStepData;
  delete this->OldFileName;
  delete this->Path;
  delete this->PathPrefix;
  delete this->PathPrefix;
  delete this->PolyMeshPointsDir;
  delete this->PolyMeshPointsDir;
  delete this->PolyMeshFacesDir;
  delete this->PolyMeshFacesDir;
  delete this->BoundaryNames;
  this->TimeNames->Delete();
  delete this->PointZoneNames;
  delete this->TimeStepData;
  delete this->FaceZoneNames;
  delete this->LagrangianTimeStepData;
  delete this->CellZoneNames;
  delete this->FacePoints;
  this->ClearMeshes();
  delete this->FacesOwnerCell;
}
  delete this->FacesNeighborCell;
  delete this->FacesOfCell;
void vtkOpenFOAMReader::ClearMeshes()
  delete this->SizeOfBoundary;
{
  if(this->FaceOwner != NULL)
    {
    this->FaceOwner->Delete();
    this->FaceOwner = NULL;
    }
  if(this->InternalMesh != NULL)
    {
    this->InternalMesh->Delete();
    this->InternalMesh = NULL;
    }
  if(this->BoundaryMesh != NULL)
    {
    for(size_t i = 0; i < this->BoundaryMesh->value.size(); i++)
      {
      this->BoundaryMesh->value[i]->Delete();
      }
    delete this->BoundaryMesh;
    this->BoundaryMesh = NULL;
    }
  delete this->BoundaryDict;
  if(this->PointZoneMesh != NULL)
    {
    for(size_t i = 0; i < this->PointZoneMesh->value.size(); i++)
      {
      this->PointZoneMesh->value[i]->Delete();
      }
    delete this->PointZoneMesh;
    this->PointZoneMesh = NULL;
    }
  if(this->FaceZoneMesh != NULL)
    {
    for(size_t i = 0; i < this->FaceZoneMesh->value.size(); i++)
      {
      this->FaceZoneMesh->value[i]->Delete();
      }
    delete this->FaceZoneMesh;
    this->FaceZoneMesh = NULL;
    }
  if(this->CellZoneMesh != NULL)
    {
    for(size_t i = 0; i < this->CellZoneMesh->value.size(); i++)
      {
      this->CellZoneMesh->value[i]->Delete();
      }
    delete this->CellZoneMesh;
    this->CellZoneMesh = NULL;
    }
}
}
int vtkOpenFOAMReader::RequestData(
int vtkOpenFOAMReader::RequestData(
 Lines 160-172    Link Here 
  vtkInformation* outInfo = outputVector->GetInformationObject(0);
  vtkInformation* outInfo = outputVector->GetInformationObject(0);
  vtkMultiBlockDataSet *output = vtkMultiBlockDataSet::SafeDownCast(
  vtkMultiBlockDataSet *output = vtkMultiBlockDataSet::SafeDownCast(
    outInfo->Get(vtkMultiBlockDataSet::DATA_OBJECT()));
    outInfo->Get(vtkMultiBlockDataSet::DATA_OBJECT()));
  if(!this->FileName)
  if(!this->FileName)
    {
    {
    vtkErrorMacro("FileName has to be specified!");
    vtkErrorMacro("FileName has to be specified!");
    return 0;
    return 0;
    }
    }
  this->CreateDataSet(output);
  return 1;
  if(this->NumberOfTimeSteps == 0)
    {
    vtkErrorMacro(<< this->FileName << " contains no timestep data.");
    return 0;
    }
    
  if(this->TimeStep < this->TimeStepRange[0]
     || this->TimeStep > this->TimeStepRange[1])
    {
    vtkErrorMacro("TimeStep out of range");
    return 0;
    }
#if PARAVIEW_VERSION_MAJOR >= 3
  if(outInfo->Has(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEPS()))
    {
    double* requestedTimeValues
      = outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEPS());
    int nSteps
      = outInfo->Length(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
    double* steps
      = outInfo->Get(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
    int timeI = 0;
    while(timeI < nSteps - 1 && steps[timeI] < requestedTimeValues[0])
      {
      timeI++;
      }
    this->SetTimeStep(timeI);
    outInfo->Set(vtkDataObject::DATA_TIME_STEPS(), &steps[timeI], 1);
    }
#endif
  this->MakeTimeStepData();
  const int ret = this->CreateDataSet(output, this->TimeStep);
  // update selection status
  this->CellSelectionOldStatus = this->CellSelectionStatus;
  this->PointSelectionOldStatus = this->PointSelectionStatus;
  this->PatchSelectionOldStatus = this->PatchSelectionStatus;
  return ret;
}
}
void vtkOpenFOAMReader::PrintSelf(ostream& os, vtkIndent indent)
void vtkOpenFOAMReader::PrintSelf(ostream& os, vtkIndent indent)
 Lines 175-181    Link Here 
  this->Superclass::PrintSelf(os,indent);
  this->Superclass::PrintSelf(os,indent);
  os << indent << "File Name: "
  os << indent << "File Name: "
     << (this->FileName ? this->FileName : "(none)") << "\n";
     << (this->FileName ? this->FileName : "(none)") << "\n";
  os << indent << "Number Of Nodes: " << this->NumPoints << "\n";
//  os << indent << "Number Of Nodes: " << this->NumPoints << "\n";
  os << indent << "Number Of Cells: " << this->NumCells << "\n";
  os << indent << "Number Of Cells: " << this->NumCells << "\n";
  os << indent << "Number of Time Steps: " << this->NumberOfTimeSteps << endl;
  os << indent << "Number of Time Steps: " << this->NumberOfTimeSteps << endl;
  os << indent << "TimeStepRange: " 
  os << indent << "TimeStepRange: " 
 Lines 190-263    Link Here 
  vtkInformationVector **vtkNotUsed(inputVector),
  vtkInformationVector **vtkNotUsed(inputVector),
  vtkInformationVector *outputVector)
  vtkInformationVector *outputVector)
{
{
  if(!this->FileName)
  if(!this->FileName || strlen(this->FileName) == 0)
    {
    {
    vtkErrorMacro("FileName has to be specified!");
    vtkErrorMacro("FileName has to be specified!");
    return 0;
    return 0;
    }
    }
  vtkDebugMacro(<<"Request Info");
  vtkDebugMacro(<<"Request Info: " <<this->FileName);
  if(RequestInformationFlag)
  if(*this->OldFileName != vtkStdString(this->FileName))
    {
    {
    vtkDebugMacro(<<this->FileName);
    // updated this->OldFileName
    this->Path->value.append(this->FileName);
    *this->OldFileName = vtkStdString(this->FileName);
    this->ReadControlDict();
    // clear prior case information
    this->OldTimeStep = -1;
    if(this->Steps != NULL)
      {
      delete [] this->Steps;
      this->Steps = NULL;
      }
    this->ClearMeshes();
    this->CellDataArraySelection->RemoveAllArrays();
    this->PointDataArraySelection->RemoveAllArrays();
    this->PatchDataArraySelection->RemoveAllArrays();
    // make case information
    if(!this->ReadControlDict(this->FileName))
      {
      return 0;
      }
    if(this->NumberOfTimeSteps == 0)
      {
      vtkErrorMacro(<< this->FileName << " contains no timestep data.");
      return 0;
      }
    this->TimeStepRange[0] = 0;
    this->TimeStepRange[0] = 0;
    this->TimeStepRange[1] = this->NumberOfTimeSteps-1;
    this->TimeStepRange[1] = this->NumberOfTimeSteps;
    this->PopulatePolyMeshDirArrays();
    this->PopulatePolyMeshDirArrays();
    outputVector->GetInformationObject(0)->Set(
    outputVector->GetInformationObject(0)->Set(
      vtkStreamingDemandDrivenPipeline::TIME_STEPS(), this->Steps,
      vtkStreamingDemandDrivenPipeline::TIME_STEPS(), this->Steps,
      this->NumberOfTimeSteps);
      this->NumberOfTimeSteps);
    this->RequestInformationFlag = false;
#if PARAVIEW_VERSION_MAJOR >= 3
    }
    double timeRange[2];
    timeRange[0] = this->Steps[0];
  //Add scalars and vectors to metadata
    timeRange[1] = this->Steps[this->NumberOfTimeSteps - 1];
  //create path to current time step
    outputVector->GetInformationObject(0)->Set(
  vtksys_ios::stringstream tempPath;
      vtkStreamingDemandDrivenPipeline::TIME_RANGE(), timeRange, 2);
  tempPath << this->PathPrefix->value.c_str();
#endif
  tempPath << this->Steps[this->TimeStep];
  //open the directory and get num of files
  int numSolvers;
  vtkDirectory * directory = vtkDirectory::New();
  int opened = directory->Open(tempPath.str().c_str());
  if(opened)
    {
    numSolvers = directory->GetNumberOfFiles();
    }
  else
    {
    numSolvers = -1; //no dir
    }
    }
  //clear prior timestep data
  this->MakeTimeStepData();
  this->TimeStepData->value.clear();
  //loop over all files and locate
  //volScalars and volVectors
  for(int j = 0; j < numSolvers; j++)
    {
    const char * tempSolver = directory->GetFile(j);
    if(tempSolver != (char *)"polyMesh")
      {
      if(tempSolver != (char *)"." && tempSolver != (char *)"..")
        {
        vtkstd::string type(this->GetDataType(tempPath.str().c_str(),
                                              tempSolver));
        if(strcmp(type.c_str(), "Scalar") == 0)
        {
          this->TimeStepData->value.push_back(vtkstd::string(tempSolver));
          this->CellDataArraySelection->AddArray(tempSolver);
          }
        else if(strcmp(type.c_str(), "Vector") == 0)
          {
          this->TimeStepData->value.push_back(vtkstd::string(tempSolver));
          this->CellDataArraySelection->AddArray(tempSolver);
          }
        }
      }
    }
  directory->Delete();
  return 1;
  return 1;
}
}
 Lines 304-2374    Link Here 
  return;
  return;
}
}
// ****************************************************************************
//
//  Method: vtkOpenFOAMReader::CombineOwnerNeigbor
// POINT METHODS
//
//
//  Purpose:
int vtkOpenFOAMReader::GetNumberOfPointArrays()
//  add Owner faces to the faces of a cell and then add the neighor faces
{
//
  return this->PointDataArraySelection->GetNumberOfArrays();
// ****************************************************************************
}
void vtkOpenFOAMReader::CombineOwnerNeigbor()
{
const char* vtkOpenFOAMReader::GetPointArrayName(int index)
  vtkDebugMacro(<<"Combine owner & neighbor faces");
{
  //reintialize faces of the cells
  return this->PointDataArraySelection->GetArrayName(index);
  face tempFace;
}
  this->FacesOfCell->value.clear();
  this->FacesOfCell->value.resize(this->NumCells);
int vtkOpenFOAMReader::GetPointArrayStatus(const char* name)
{
  return this->PointDataArraySelection->ArrayIsEnabled(name);
}
void vtkOpenFOAMReader::SetPointArrayStatus(const char* name, int status)
{
  if(status)
    {
    this->PointDataArraySelection->EnableArray(name);
    }
  else
    {
    this->PointDataArraySelection->DisableArray(name);
    }
  return;
}
void vtkOpenFOAMReader::DisableAllPointArrays()
{
  this->PointDataArraySelection->DisableAllArrays();
  return;
}
void vtkOpenFOAMReader::EnableAllPointArrays()
{
  this->PointDataArraySelection->EnableAllArrays();
  return;
}
//
// PATCH METHODS
//
int vtkOpenFOAMReader::GetNumberOfPatchArrays()
{
  return this->PatchDataArraySelection->GetNumberOfArrays();
}
const char* vtkOpenFOAMReader::GetPatchArrayName(int index)
{
  return this->PatchDataArraySelection->GetArrayName(index);
}
int vtkOpenFOAMReader::GetPatchArrayStatus(const char* name)
{
  return this->PatchDataArraySelection->ArrayIsEnabled(name);
}
void vtkOpenFOAMReader::SetPatchArrayStatus(const char* name, int status)
{
  if(status)
    {
    this->PatchDataArraySelection->EnableArray(name);
    }
  else
    {
    this->PatchDataArraySelection->DisableArray(name);
    }
  return;
}
void vtkOpenFOAMReader::DisableAllPatchArrays()
{
  this->PatchDataArraySelection->DisableAllArrays();
  return;
}
void vtkOpenFOAMReader::EnableAllPatchArrays()
{
  this->PatchDataArraySelection->EnableAllArrays();
  return;
}
// Define the Selection Observer 
void vtkOpenFOAMReader::SelectionModifiedCallback(vtkObject*,
  unsigned long, void* clientdata, void*)
{
  static_cast<vtkOpenFOAMReader*>(clientdata)->SelectionModified();
}
void vtkOpenFOAMReader::SelectionModified()
{
  // Change the pipeline modification time to force update
  // Update the selection status to detect changes
  // Cell Selection Arrays
  // we loop from the last element of the selection array since we'd
  // like to place newly added variables to extra higher bits (we
  // wouldn't like to move the locations of already existing variables)
  this->CellSelectionStatus = 0;
  for(int i = this->GetNumberOfCellArrays() - 1; i >= 0; i--)
    {
    this->CellSelectionStatus = (this->CellSelectionStatus << 1) 
      + this->GetCellArrayStatus(this->GetCellArrayName(i));
    }
  // if the status flag overflows we'd like to fall onto the safe side
  // (properly refresh the dataset without mesh caching) so we use the
  // last bit (LSB) as overflow control flag.  if overflow occurs the
  // LSB is negated from the old status
  if(this->GetNumberOfCellArrays()
    <= static_cast<int>(sizeof(this->CellSelectionStatus) * 8 - 1))
    {
    this->CellSelectionStatus = (this->CellSelectionStatus << 1)
      + (this->CellSelectionOldStatus & 0x1);
    }
  else
    {
    this->CellSelectionStatus = (this->CellSelectionStatus << 1) 
      + ((~this->CellSelectionOldStatus) & 0x1);
    }
  // Point Selection Arrays
  // this->PointSelectionOldStatus = this->PointSelectionStatus;
  this->PointSelectionStatus = 0;
  for(int i = this->GetNumberOfPointArrays() - 1; i >= 0; i--)
    {
    this->PointSelectionStatus = (this->PointSelectionStatus << 1) 
      + this->GetPointArrayStatus(this->GetPointArrayName(i));
    }
  if(this->GetNumberOfPointArrays()
    <= static_cast<int>(sizeof(this->PointSelectionStatus) * 8 - 1))
    {
    this->PointSelectionStatus = (this->PointSelectionStatus << 1)
      + (this->PointSelectionOldStatus & 0x1);
    }
  else
    {
    this->PointSelectionStatus = (this->PointSelectionStatus << 1) 
      + (~(this->PointSelectionOldStatus) & 0x1);
    }
  // Patch Selection Arrays
  // this->PatchSelectionOldStatus = this->PatchSelectionStatus;
  this->PatchSelectionStatus = 0;
  for(int i = this->GetNumberOfPatchArrays() - 1; i >= 0; i--)
    {
    this->PatchSelectionStatus = (this->PatchSelectionStatus << 1) 
      + this->GetPatchArrayStatus(this->GetPatchArrayName(i));
    }
  if(this->GetNumberOfPatchArrays()
    <= static_cast<int>(sizeof(this->PatchSelectionStatus) * 8 - 1))
    {
    this->PatchSelectionStatus = (this->PatchSelectionStatus << 1)
      + (this->PatchSelectionOldStatus & 0x1);
    }
  else
    {
    this->PatchSelectionStatus = (this->PatchSelectionStatus << 1) 
      + (~(this->PatchSelectionOldStatus) & 0x1);
    }
  // Indicate that the pipeline needs to be updated (VTK Command)
  this->Modified();
}
// create field data lists and cell/point array selection lists
void vtkOpenFOAMReader::MakeTimeStepData()
{
  // Read the patches from the boundary file into selection array
  int timeState = this->TimeStep;
  vtkFoamDict* boundaryDictPtr
    = this->GatherBlocks("boundary", timeState, true);
  if(boundaryDictPtr == NULL)
    {
    vtkErrorMacro(<< "Couldn't read polyMesh/boundary");
    return;
    }
  vtkFoamDict& boundaryDictTmp = *boundaryDictPtr;
  // Add the internal mesh by default always
  const vtkStdString tmpStr = "Internal Mesh";
  this->PatchDataArraySelection->AddArray(tmpStr.c_str());
  // iterate through each entry in the boundary file
  for(size_t i = 0; i < boundaryDictTmp.size(); i++)
    {
    vtkFoamEntry& boundaryEntryI = boundaryDictTmp.entry(i);
    int nFaces;
    boundaryEntryI.dictionary().lookup("nFaces") >> nFaces;
    // extract name of the current patch for insertion
    const vtkStdString& boundaryNameI = boundaryEntryI.keyword();
    // If the size of patch becomes zero, but KeepPatches is selected,
    // do not remove from list, else, remove patch from list
    if(nFaces == 0)
      {
      if((this->PatchDataArraySelection->ArrayExists(boundaryNameI.c_str()))
        && (!this->GetKeepPatches()))
        {
        this->PatchDataArraySelection->RemoveArrayByName(boundaryNameI.c_str());
        }
      }
    else
      {
      this->PatchDataArraySelection->AddArray(boundaryNameI.c_str());
      }
    }
  delete boundaryDictPtr;
  // Commented out the "RemoveAllArrays()" line....
  //this->CellDataArraySelection->RemoveAllArrays();
  //clear prior timestep data
  this->TimeStepData->value.clear();
  //Add scalars and vectors to metadata
  //create path to current time step
  vtkStdString tempPath
    = *this->PathPrefix + this->TimeNames->GetValue(this->TimeStep);
  //open the directory and get num of files
  vtkDirectory * directory = vtkDirectory::New();
  if(!directory->Open(tempPath.c_str()))
    {
    // no data
    directory->Delete();
    return;
    }
  //add owner faces to cell
  //loop over all files and locate
  for(int i = 0; i < (int)this->FacesOwnerCell->value.size(); i++)
  //volScalars and volVectors
  int nFieldFiles = directory->GetNumberOfFiles();
  for(int j = 0; j < nFieldFiles; j++)
    {
    {
    for(int j = 0; j < (int)this->FacesOwnerCell->value[i].size(); j++)
    const vtkStdString fieldFile(directory->GetFile(j));
    const int len = fieldFile.length();
    // excluded extensions based on src/OpenFOAM/OSspecific/Unix/Unix.C
    if(!directory->FileIsDirectory(fieldFile.c_str())
      && fieldFile.substr(len - 1) != "~"
      && (len < 4 || (fieldFile.substr(len - 4) != ".bak"
      && fieldFile.substr(len - 4) != ".BAK"
      && fieldFile.substr(len - 4) != ".old"))
      && (len < 5 || fieldFile.substr(len - 5) != ".save"))
      {
      {
      tempFace.faceIndex = this->FacesOwnerCell->value[i][j];
      vtkFoamIOobject io;
      tempFace.neighborFace = false;
      if(io.open(tempPath + "/" + fieldFile)) // file exists and readable
      this->FacesOfCell->value[i].push_back(tempFace);
        {
        if(io.className() == "volScalarField" ||
          io.className() == "volVectorField")
          {
          // real file name
          this->TimeStepData->value.push_back(fieldFile);
          // object name
          this->CellDataArraySelection->AddArray(io.objectName().c_str());
          }
        io.close();
        }
#if 0
      // warning is turned off in favor of silence
      else
        {
        vtkWarningMacro(<< "File " << io.fileName().c_str()
          << " is not a valid OpenFOAM object. Reason: "
          << io.error().str().c_str() << " in line "
          << io.lineNumber());
        }
#endif
      }
      }
    }
    }
  directory->Delete();
  //add neighbor faces to cell
  // locate laglangian fields
  for(int i = 0; i < (int)this->FacesNeighborCell->value.size(); i++)
    {
  //clear prior timestep data
    for(int j = 0; j < (int)this->FacesNeighborCell->value[i].size(); j++)
  this->LagrangianTimeStepData->value.clear();
      {
  // Commented out the "RemoveAllArrays()" line....
      tempFace.faceIndex = this->FacesNeighborCell->value[i][j];
  //this->PointDataArraySelection->RemoveAllArrays();
      tempFace.neighborFace = true;
      this->FacesOfCell->value[i].push_back(tempFace);
  //open the directory and get num of files
  tempPath += "/lagrangian";
  directory = vtkDirectory::New();
  if(directory->Open(tempPath.c_str()))
    {
    nFieldFiles = directory->GetNumberOfFiles();
    for(int j = 0; j < nFieldFiles; j++)
      {
      const vtkStdString fieldFile(directory->GetFile(j));
      const int len = fieldFile.length();
      // excluded extensions based on src/OpenFOAM/OSspecific/Unix/Unix.C
      if(!directory->FileIsDirectory(fieldFile.c_str())
        && fieldFile.substr(len - 1) != "~"
        && (len < 4 || (fieldFile.substr(len - 4) != ".bak"
        && fieldFile.substr(len - 4) != ".BAK"
        && fieldFile.substr(len - 4) != ".old"))
        && (len < 5 || fieldFile.substr(len - 5) != ".save"))
        {
        vtkFoamIOobject io;
        if(io.open(tempPath + "/" + fieldFile))
          {
          if(io.className() == "scalarField"
            || io.className() == "vectorField")
            {
            // real file name
            this->LagrangianTimeStepData->value.push_back(fieldFile);
            // object name
            this->PointDataArraySelection->AddArray(
	      (vtkStdString("lagrangian/") + io.objectName()).c_str());
            }
          else if(io.className() == "Cloud" && io.objectName() == "positions")
            {
            this->PatchDataArraySelection->AddArray("Lagrangian Particles");
            }
          io.close();
          }
        }
      }
      }
    }
    }
  directory->Delete();
  //clean up memory
  // refresh selection status
  this->FacesOwnerCell->value.clear();
  this->SelectionModified();
  this->FacesNeighborCell->value.clear();
  return;
}
}
// ****************************************************************************
// ****************************************************************************
//  Method: vtkOpenFOAMReader::MakeInternalMesh
//  Method: vtkOpenFOAMReader::InsertCellToGrid
//
//
//  Purpose:
//  Purpose:
//  derive cell types and create the internal mesh
//  determine cell shape and insert the cell into the mesh
//  hexahedron, prism, pyramid, tetrahedron, wedge&tetWedge
//
//
// ****************************************************************************
// ****************************************************************************
vtkUnstructuredGrid * vtkOpenFOAMReader::MakeInternalMesh()
void vtkOpenFOAMReader::InsertCellToGrid(vtkUnstructuredGrid* internalMesh,
  int cellId, faceVectorVector *facesOfCell, intVectorVector* facesPoints)
{
{
  vtkDebugMacro(<<"Make internal mesh");
  // aliases
  //initialize variables
  const vtkstd::vector<vtkstd::vector<int> >& facePoints
  bool foundDup = false;
    = facesPoints->value;
  vtkstd::vector< int > cellPoints;
  const vtkstd::vector<face>& cellFaces = facesOfCell->value[cellId];
  vtkstd::vector< int > tempFaces[2];
  const size_t nCellFaces = cellFaces.size();
  vtkstd::vector< int > firstFace;
  int pivotPoint = 0;
  int i, j, k, l, pCount;
  int faceCount = 0;
  //Create Mesh
  vtkUnstructuredGrid *  internalMesh = vtkUnstructuredGrid::New();
  //loop through each cell, derive type and insert it into the mesh
  //hexahedron, prism, pyramid, tetrahedron, wedge&tetWedge
  for(i = 0; i < (int)this->FacesOfCell->value.size(); i++)  //each cell
    {
    //calculate the total points for the cell
  vtkIdList* cellPoints = vtkIdList::New();
    //used to derive cell type
    int totalPointCount = 0;
    for(j = 0; j < (int)this->FacesOfCell->value[i].size(); j++)  //each face
      {
      totalPointCount += 
        (int)this->FacePoints->
                 value[this->FacesOfCell->value[i][j].faceIndex].size();
      }
    // using cell type - order points, create cell, & add to mesh
  // determine type of the cell
    //OFhex | vtkHexahedron
  // based on src/OpenFOAM/meshes/meshShapes/cellMatcher/{hex|prism|pyr|tet}-
    if (totalPointCount == 24)
  // Matcher.C
  int cellType = VTK_CONVEX_POINT_SET;
  if(nCellFaces == 6)
    {
    size_t j = 0;
    for(j = 0; j < nCellFaces; j++)
      {
      {
      faceCount = 0;
      if(facePoints[cellFaces[j].faceIndex].size() != 4)
      //get first face
      for(j = 0; j <
        (int)this->FacePoints->
                    value[this->FacesOfCell->value[i][0].faceIndex].size(); j++)
        {
        {
        firstFace.push_back(this->FacePoints->value[
        break;
          this->FacesOfCell->value[i][0].faceIndex][j]);
        }
        }
      }
      //patch: if it is a neighbor face flip the points
    if(j == nCellFaces)
      if(this->FacesOfCell->value[i][0].neighborFace)
      {
      cellType = VTK_HEXAHEDRON;
      }
    }
  else if(nCellFaces == 5)
    {
    int nTris = 0, nQuads = 0;
    for(size_t j = 0; j < nCellFaces; j++)
      {
      const int nPoints = facePoints[cellFaces[j].faceIndex].size();
      if(nPoints == 3)
        {
        {
        int tempPop;
        nTris++;
        for(k = 0; k < (int)firstFace.size() - 1; k++)
          {
          tempPop = firstFace[firstFace.size()-1];
          firstFace.pop_back();
          firstFace.insert(firstFace.begin()+1+k, tempPop);
          }
        }
        }
      else if(nPoints == 4)
      //add first face to cell points
      for(j =0; j < (int)firstFace.size(); j++)
        {
        {
        cellPoints.push_back(firstFace[j]);
        nQuads++;
        }
        }
      else
      //find the opposite face and order the points correctly
      for(int pointCount = 0; pointCount < (int)firstFace.size(); pointCount++)
        {
        {
        break;
        //find the other 2 faces containing each point
        for(j = 1; j < (int)this->FacesOfCell->value[i].size(); j++) //each face
          {
          for(k = 0; k < (int)this->FacePoints->value[
            this->FacesOfCell->value[i][j].faceIndex].size(); k++) //each point
            {
            if(firstFace[pointCount] == this->FacePoints->value[
              this->FacesOfCell->value[i][j].faceIndex][k])
              {
              //ANOTHER FACE WITH THE POINT
              for(l = 0; l < (int)this->FacePoints->value[
                this->FacesOfCell->value[i][j].faceIndex].size(); l++)
                {
                tempFaces[faceCount].push_back(this->FacePoints->value[
                  this->FacesOfCell->value[i][j].faceIndex][l]);
                }
              faceCount++;
              }
            }
          }
        //locate the pivot point contained in faces 0 & 1
        for(j = 0; j < (int)tempFaces[0].size(); j++)
          {
          for(k = 0; k < (int)tempFaces[1].size(); k++)
            {
            if(tempFaces[0][j] == tempFaces[1][k] && tempFaces[0][j] !=
              firstFace[pointCount])
              {
              pivotPoint = tempFaces[0][j];
              break;
              }
            }
          }
        cellPoints.push_back(pivotPoint);
        tempFaces[0].clear();
        tempFaces[1].clear();
        faceCount=0;
        }
        }
      }
      //create the hex cell and insert it into the mesh
    if(nTris == 2 && nQuads == 3)
      vtkHexahedron * hexahedron= vtkHexahedron::New();
      {
      for(pCount = 0; pCount < (int)cellPoints.size(); pCount++)
      cellType = VTK_WEDGE;
      }
    else if(nTris == 4 && nQuads == 1)
      {
      cellType = VTK_PYRAMID;
      }
    }
  else if(nCellFaces == 4)
    {
    size_t j = 0;
    for(j = 0; j < nCellFaces; j++)
      {
      if(facePoints[cellFaces[j].faceIndex].size() != 3)
        {
        {
        hexahedron->GetPointIds()->SetId(pCount, cellPoints[pCount]);
        break;
        }
        }
      internalMesh->InsertNextCell(hexahedron->GetCellType(),
        hexahedron->GetPointIds());
      hexahedron->Delete();
      cellPoints.clear();
      firstFace.clear();
      }
      }
    if(j == nCellFaces)
      {
      cellType = VTK_TETRA;
      }
    }
    //OFprism | vtkWedge
  // not an Hex/Wedge/Pyramid/Tetra
    else if (totalPointCount == 18)
  if(cellType == VTK_CONVEX_POINT_SET)
    {
    int nPoints = 0;
    for(size_t j = 0; j < nCellFaces; j++)
      {
      {
      faceCount = 0;
      nPoints += facePoints[cellFaces[j].faceIndex].size();
      int index = 0;
      }
    if(nPoints == 0)
      {
      cellType = VTK_EMPTY_CELL;
      }
    }
      //find first triangular face
  // Cell shape constructor based on the one implementd by Terry
      for(j = 0; j < (int)this->FacesOfCell->value[i].size(); j++)  //each face
  // Jordan, with some improvements. not as elegant as the one in
  // OpenFOAM but works reasonably fast.
  // OFhex | vtkHexahedron || OFprism | vtkWedge
  if (cellType == VTK_HEXAHEDRON || cellType == VTK_WEDGE)
    {
    // find the base face number
    size_t face0Id = 0;
    if(cellType == VTK_HEXAHEDRON)
      {
      cellPoints->SetNumberOfIds(8);
      face0Id = 0;
      }
    else // VTK_WEDGE
      {
      cellPoints->SetNumberOfIds(6);
      for(size_t j = 0; j < nCellFaces; j++)
        {
        {
        if((int)this->FacePoints->
        if(facePoints[cellFaces[j].faceIndex].size() == 3)
            value[this->FacesOfCell->value[i][j].faceIndex].size() == 3)
          {
          {
          for(k = 0; k < (int)this->FacePoints->value[
          face0Id = j;
              this->FacesOfCell->value[i][j].faceIndex].size(); k++)
            {
            firstFace.push_back(this->FacePoints->value[
              this->FacesOfCell->value[i][j].faceIndex][k]);
            index = j;
            }
          break;
          break;
          }
          }
        }
        }
      }
    //get first face in correct order
    const vtkstd::vector<int>& face0Points
      = facePoints[cellFaces[face0Id].faceIndex];
    size_t nFace0Points = face0Points.size();
    vtkstd::vector<int> baseFace(nFace0Points); // ordered point list
    if(cellFaces[face0Id].neighborFace)
      {
      //patch: if it is a neighbor face flip the points
      //patch: if it is a neighbor face flip the points
      if(this->FacesOfCell->value[i][0].neighborFace)
      for(size_t j = 0; j < nFace0Points; j++)
        {
        {
        int tempPop;
        baseFace[j] = face0Points[nFace0Points - 1 - j];
        for(k = 0; k < (int)firstFace.size() - 1; k++)
        //add base face to cell points
          {
        cellPoints->SetId(j, baseFace[j]);
          tempPop = firstFace[firstFace.size()-1];
          firstFace.pop_back();
          firstFace.insert(firstFace.begin()+1+k, tempPop);
          }
        }
        }
      }
      //add first face to cell points
    else
      for(j =0; j < (int)firstFace.size(); j++)
      {
      for(size_t j = 0; j < nFace0Points; j++)
        {
        {
        cellPoints.push_back(firstFace[j]);
        baseFace[j] = face0Points[j];
        //add base face to cell points
        cellPoints->SetId(j, baseFace[j]);
        }
        }
      }
      //find the opposite face and order the points correctly
    //find the opposite face points and order the points correctly
      for(int pointCount = 0; pointCount < (int)firstFace.size(); pointCount++)
    const size_t nBaseFacePoints = baseFace.size();
    for(size_t pointCount = 0; pointCount < nBaseFacePoints; pointCount++)
      {
      int pivotPoint = -1;
      const int baseFacePointI = baseFace[pointCount];
      for(size_t j = 0; j < nCellFaces; j++) //each face
        {
        {
        //find the 2 other faces containing each point
        if(j == face0Id)
        for(j = 0; j < (int)this->FacesOfCell->value[i].size(); j++) //each face
          {
          continue;
          }
        const vtkstd::vector<int>& faceJPoints
          = facePoints[cellFaces[j].faceIndex];
        const size_t sizeK = faceJPoints.size();
        if(sizeK == 3) // omit the other triangular wedge face
          {
          continue;
          }
        for(size_t k = 0; k < sizeK; k++) //each point
          {
          {
          for(k = 0; k < (int)this->FacePoints->value[
          // if the point matches the point of the base face...
              this->FacesOfCell->value[i][j].faceIndex].size(); k++)
          if(baseFacePointI == faceJPoints[k])
            {
            {
            if(firstFace[pointCount] == this->FacePoints->value[
            const bool isNeighbor = cellFaces[j].neighborFace;
               this->FacesOfCell->value[i][j].faceIndex][k] && j != index)
            const int faceJPrevPoint = faceJPoints[(sizeK + k - 1) % sizeK];
            const int faceJNextPoint = faceJPoints[(k + 1) % sizeK];
            const int baseFacePrevPoint = baseFace[(nBaseFacePoints
              + pointCount - 1) % nBaseFacePoints];
            const int baseFaceNextPoint
              = baseFace[(pointCount + 1) % nBaseFacePoints];
            // if the next point of the j-th face matches the
            // previous point of the base face use the previous
            // point of the j-th face as the pivot point and use the
            // next point otherwise
            if(faceJNextPoint == (isNeighbor ? baseFaceNextPoint
              : baseFacePrevPoint))
              {
              {
              //ANOTHER FACE WITH POINT
              pivotPoint = faceJPrevPoint;
              for(l = 0; l < (int)this->FacePoints->value[
                  this->FacesOfCell->value[i][j].faceIndex].size(); l++)
                {
                tempFaces[faceCount].push_back(this->FacePoints->value[
                  this->FacesOfCell->value[i][j].faceIndex][l]);
                }
              faceCount++;
              }
              }
            }
            else
          }
              {
              pivotPoint = faceJNextPoint;
              }
            cellPoints->SetId(nBaseFacePoints + pointCount, pivotPoint);
        //locate the pivot point of faces 0 & 1
            // we further look at one more vertex:
        for(j = 0; j < (int)tempFaces[0].size(); j++)
            // if the j-th face also shares next point of the base face
          {
            // add the corresponding opposite point to cell points
          for(k = 0; k < (int)tempFaces[1].size(); k++)
            if(pointCount < nBaseFacePoints - 1 && baseFaceNextPoint
            {
              == (isNeighbor ? faceJNextPoint : faceJPrevPoint))
            if(tempFaces[0][j] == tempFaces[1][k] && tempFaces[0][j] !=
              firstFace[pointCount])
              {
              {
              pivotPoint = tempFaces[0][j];
              pointCount++;
              break;
              cellPoints->SetId(nBaseFacePoints + pointCount,
                faceJPoints[(k + 2) % sizeK]);
              }
              }
            break; // look no more points as to the face
            }
            }
          }
          }
        cellPoints.push_back(pivotPoint);
        if(pivotPoint >= 0) // break if the pivot point is found
        tempFaces[0].clear();
        tempFaces[1].clear();
        faceCount=0;
        }
      //create the wedge cell and insert it into the mesh
      vtkWedge * wedge= vtkWedge::New();
      for(pCount = 0; pCount < (int)cellPoints.size(); pCount++)
        {
        wedge->GetPointIds()->SetId(pCount, cellPoints[pCount]);
        }
      internalMesh->InsertNextCell(wedge->GetCellType(),
        wedge->GetPointIds());
      cellPoints.clear();
      wedge->Delete();
      firstFace.clear();
      }
    //OFpyramid | vtkPyramid
    else if (totalPointCount == 16)
      {
      foundDup = false;
      //find the quadratic face
      for(j = 0; j < (int)this->FacesOfCell->value[i].size(); j++)  //each face
        {
        if((int)this->FacePoints->
            value[this->FacesOfCell->value[i][j].faceIndex].size() == 4)
          {
          {
          for(k = 0; k < (int)this->FacePoints->value[
              this->FacesOfCell->value[i][j].faceIndex].size(); k++)
            {
            cellPoints.push_back(this->FacePoints->value[
              this->FacesOfCell->value[i][j].faceIndex][k]);
            }
          break;
          break;
          }
          }
        }
        }
      }
    //create the hex cell and insert it into the mesh
    internalMesh->InsertNextCell(cellType, cellPoints);
    }
      //compare first face points to other faces
  //OFpyramid | vtkPyramid || OFtet | vtkTetrahedron
      for(j = 0; j < (int)cellPoints.size(); j++) //each point
  else if (cellType == VTK_PYRAMID || cellType == VTK_TETRA)
    {
    int baseFaceId = -1;
    if(cellType == VTK_PYRAMID)
      {
      for(size_t j = 0; j < nCellFaces; j++)
        {
        {
        for(k = 0; k < (int)this->FacePoints->value[
        if(facePoints[cellFaces[j].faceIndex].size() == 4)
          this->FacesOfCell->value[i][1].faceIndex].size(); k++)
          {
          if(cellPoints[j] == this->FacePoints->value[
            this->FacesOfCell->value[i][1].faceIndex][k])
            {
            foundDup = true;
            }
          }
        if(!foundDup)
          {
          {
          cellPoints.push_back(this->FacePoints->value[
          baseFaceId = j;
            this->FacesOfCell->value[i][j].faceIndex][k]);
          break;
          break;
          }
          }
        }
        }
      cellPoints->SetNumberOfIds(5);
      //create the pyramid cell and insert it into the mesh
      vtkPyramid * pyramid = vtkPyramid::New();
      for(pCount = 0; pCount < (int)cellPoints.size(); pCount++)
        {
        pyramid->GetPointIds()->SetId(pCount, cellPoints[pCount]);
        }
      internalMesh->InsertNextCell(pyramid->GetCellType(),
        pyramid->GetPointIds());
      cellPoints.clear();
      pyramid->Delete();
      }
      }
    else // VTK_TETRA
    //OFtet | vtkTetrahedron
    else if (totalPointCount == 12)
      {
      {
      foundDup = false;
      baseFaceId = 0;
      cellPoints->SetNumberOfIds(4);
      }
      //add first face to cell points
    //add first face to cell points
      for(j = 0; j < (int)this->FacePoints->value[
    const vtkstd::vector<int>& baseFacePoints
        this->FacesOfCell->value[i][0].faceIndex].size(); j++)
      = facePoints[cellFaces[baseFaceId].faceIndex];
    const size_t nBaseFacePoints = baseFacePoints.size();
    if(cellFaces[baseFaceId].neighborFace)
      {
      // if it is a neighbor face flip the points
      for(size_t j = 0; j < nBaseFacePoints; j++)
        {
        {
        cellPoints.push_back(this->FacePoints->value[
        cellPoints->SetId(j, baseFacePoints[nBaseFacePoints - 1 - j]);
          this->FacesOfCell->value[i][0].faceIndex][j]);
        }
        }
      }
      //compare first face to the points of second face
    else
      for(j = 0; j < (int)cellPoints.size(); j++) //each point
      {
      for(size_t j = 0; j < nBaseFacePoints; j++)
        {
        {
        for(k = 0; k < (int)this->FacePoints->value[
        cellPoints->SetId(j, baseFacePoints[j]);
          this->FacesOfCell->value[i][1].faceIndex].size(); k++)
          {
          if(cellPoints[j] == this->FacePoints->value[
            this->FacesOfCell->value[i][1].faceIndex][k])
            {
            foundDup = true;
            }
          }
        if(!foundDup)
          {
          cellPoints.push_back(this->FacePoints->value[
            this->FacesOfCell->value[i][j].faceIndex][k]);
          break;
          }
        }
        }
      }
      //create the wedge cell and insert it into the mesh
    // compare an adjacent face (any non base face is ok) point 1 to
      vtkTetra * tetra = vtkTetra::New();
    // base face points
      for(pCount = 0; pCount < (int)cellPoints.size(); pCount++)
    const int adjacentFaceId = (baseFaceId == 0) ? 1 : baseFaceId - 1;
    const vtkstd::vector<int>& adjacentFacePoints
      = facePoints[cellFaces[adjacentFaceId].faceIndex];
    const int adjacentFacePoint1 = adjacentFacePoints[1];
    bool foundDup = false;
    for(size_t j = 0; j < nBaseFacePoints; j++)
      {
      // if point 1 of the adjacent face matchs point j of the base face...
      if(cellPoints->GetId(j) == adjacentFacePoint1)
        {
        {
        tetra->GetPointIds()->SetId(pCount, cellPoints[pCount]);
        // if point 2 of the adjacent face matches the previous point
        // of the base face use point 0 of the adjacent face as the
        // pivot point; use point 2 otherwise
        cellPoints->SetId(nBaseFacePoints, (adjacentFacePoints[2]
          == cellPoints->GetId((cellFaces[adjacentFaceId].neighborFace
          ? (j + 1) : (nBaseFacePoints + j - 1)) % nBaseFacePoints)) ? 
          adjacentFacePoints[0] : adjacentFacePoints[2]);
        foundDup = true;
        break;
        }
        }
      internalMesh->InsertNextCell(tetra->GetCellType(),
        tetra->GetPointIds());
      cellPoints.clear();
      tetra->Delete();
      }
      }
    // if point 1 of the adjacent face does not match any points of
    //erronous cells
    // the base face, it's the pivot point
    else if(totalPointCount == 0)
    if(!foundDup)
      {
      {
      vtkWarningMacro("Warning: No points in cell.");
      cellPoints->SetId(nBaseFacePoints, adjacentFacePoint1);
      }
      }
    //OFpolyhedron || vtkConvexPointSet
    //create the tetra cell and insert it into the mesh
    else
    internalMesh->InsertNextCell(cellType, cellPoints);
      {
    }
      vtkWarningMacro("Warning: Polyhedral Data is very Slow!");
      foundDup = false;
      //get first face
  //erronous cells
      for(j = 0; j < (int)this->FacePoints->value[
  else if(cellType == VTK_EMPTY_CELL)
        this->FacesOfCell->value[i][0].faceIndex].size(); j++)
    {
    vtkWarningMacro("Warning: No points in cell.");
    }
  //OFpolyhedron || vtkConvexPointSet
  else
    {
    // vtkWarningMacro("Warning: Polyhedral Data is very Slow!");
    //get first face
    const vtkstd::vector<int>& baseFacePoints
      = facePoints[cellFaces[0].faceIndex];
    const size_t nBaseFacePoints = baseFacePoints.size();
    //add first face to cell points
    // not sure if flipping is necessary but do it anyway
    if(cellFaces[0].neighborFace)
      {
      // if it is a neighbor face flip the points
      for(size_t j = 0; j < nBaseFacePoints; j++)
        {
        {
        firstFace.push_back(this->FacePoints->value[
        cellPoints->InsertNextId(baseFacePoints[nBaseFacePoints - 1 - j]);
          this->FacesOfCell->value[i][0].faceIndex][j]);
        }
        }
      }
      //add first face to cell points
    else
      for(j =0; j < (int)firstFace.size(); j++)
      {
      for(size_t j = 0; j < nBaseFacePoints; j++)
        {
        {
        cellPoints.push_back(firstFace[j]);
        cellPoints->InsertNextId(baseFacePoints[j]);
        }
        }
      }
      //loop through faces and create a list of all points
    //loop through faces and create a list of all points
      //j = 1 skip firstFace
    //j = 1 skip baseFace
      for(j = 1; j < (int)this->FacesOfCell->value[i].size(); j++)
    for(size_t j = 1; j < nCellFaces; j++)
      {
      //remove duplicate points from faces
      const vtkstd::vector<int>& faceJPoints
        = facePoints[cellFaces[j].faceIndex];
      const size_t nFaceJPoints = faceJPoints.size();
      for(size_t k = 0; k < nFaceJPoints; k++)
        {
        {
        //remove duplicate points from faces
        const int faceJPointK = faceJPoints[k];
        for(k = 0; k < (int)this->FacePoints->value[
        bool foundDup = false;
          this->FacesOfCell->value[i][j].faceIndex].size(); k++)
        for(int l = 0; l < cellPoints->GetNumberOfIds(); l++)
          {
          {
          for(l = 0; l < (int)cellPoints.size(); l++);
          if(cellPoints->GetId(l) == faceJPointK)
            {
            if(cellPoints[l] == this->FacePoints->value[
              this->FacesOfCell->value[i][j].faceIndex][k])
              {
              foundDup = true;
              }
            }
          if(!foundDup)
            {
            {
            cellPoints.push_back(this->FacePoints->value[
            foundDup = true;
              this->FacesOfCell->value[i][j].faceIndex][k]);
            break; // look no more
            foundDup = false;
            }
            }
          }
          }
        if(!foundDup)
          {
          cellPoints->InsertNextId(faceJPointK);
          }
        }
        }
      //create the poly cell and insert it into the mesh
      vtkConvexPointSet * poly = vtkConvexPointSet::New();
      poly->GetPointIds()->SetNumberOfIds(cellPoints.size());
      for(pCount = 0; pCount < (int)cellPoints.size(); pCount++)
        {
        poly->GetPointIds()->SetId(pCount, cellPoints[pCount]);
        }
      internalMesh->InsertNextCell(poly->GetCellType(),
        poly->GetPointIds());
      cellPoints.clear();
      firstFace.clear();
      poly->Delete();
      }
      }
    }
  //set the internal mesh points
    //create the poly cell and insert it into the mesh
  internalMesh->SetPoints(Points);
    internalMesh->InsertNextCell(VTK_CONVEX_POINT_SET, cellPoints);
  vtkDebugMacro(<<"Internal mesh made");
    }
  return internalMesh;
  cellPoints->Delete();
}
}
// ****************************************************************************
// ****************************************************************************
//  Method: vtkOpenFOAMReader::ControlDictDataParser
//  Method: vtkOpenFOAMReader::MakeInternalMesh
//
//
//  Purpose:
//  Purpose:
//  parse out double values for controlDict entries
//  derive cell types and create the internal mesh
//  utility function
//
//
// ****************************************************************************
// ****************************************************************************
double vtkOpenFOAMReader::ControlDictDataParser(const char * lineIn)
vtkUnstructuredGrid * vtkOpenFOAMReader::MakeInternalMesh(
  faceVectorVector *facesOfCell, intVectorVector* facesPoints,
  vtkPoints* points)
{
{
  double value;
  vtkDebugMacro(<<"Make internal mesh");
  vtkstd::string line(lineIn);
  line.erase(line.begin()+line.find(";"));
  vtkstd::string token;
  vtksys_ios::stringstream tokenizer(line);
  //parse to the final entry - double
  //Create Mesh
  //while(tokenizer>>token);
  vtkUnstructuredGrid* internalMesh = vtkUnstructuredGrid::New();
  while(!tokenizer.eof())
  internalMesh->Allocate(facesOfCell->value.size());
  //loop through each cell, derive type and insert it into the mesh
  //hexahedron, prism, pyramid, tetrahedron, wedge&tetWedge
  for(size_t i = 0; i < facesOfCell->value.size(); i++)  //each cell
    {
    {
    tokenizer >> token;
    this->InsertCellToGrid(internalMesh, i, facesOfCell, facesPoints);
    }
    }
  //set the internal mesh points
  internalMesh->SetPoints(points);
  vtkDebugMacro(<<"Internal mesh made");
  vtksys_ios::stringstream conversion(token);
  return internalMesh;
  conversion >> value;
  return value;
}
}
// ****************************************************************************
// List time directories according to controlDict
//  Method: vtkOpenFOAMReader::ReadControlDict
bool vtkOpenFOAMReader::ListTimeDirectoriesByControlDict(vtkFoamDict* dictPtr)
//
//  Pupose:
//  reads the controlDict File
//  gather the necessary information to create a path to the data
//
// ****************************************************************************
void vtkOpenFOAMReader::ReadControlDict ()
{
{
  vtkDebugMacro(<<"Read controlDict");
  vtkFoamDict& dict = *dictPtr;
  //create variables
  vtkstd::string temp;
  double startTime;
  double endTime;
  double deltaT;
  double writeInterval;
  double timeStepIncrement;
  vtkstd::string writeControl;
  vtkstd::string timeFormat;
  stdString* tempStringStruct;
  ifstream * input = new ifstream(this->Path->value.c_str(), ios::in VTK_IOS_NOCREATE);
  //create the path to the data directory
  this->PathPrefix->value = this->Path->value;
  this->PathPrefix->value.erase(this->PathPrefix->value.begin()+
    this->PathPrefix->value.find("system"),this->PathPrefix->value.end());
  vtkDebugMacro(<<"Path: "<<this->PathPrefix->value.c_str());
  //find Start Time
  tempStringStruct = this->GetLine(input);
  temp = tempStringStruct->value;
  delete tempStringStruct;
  //while(!(temp.compare(0,8,"startTime",0,8) == 0))
  vtkFoamEntry& startTimeEntry = dict.lookup("startTime");
  while (strcmp(temp.substr(0,9).c_str(), "startTime"))
  if(!startTimeEntry.found())
    {
    {
    tempStringStruct = this->GetLine(input);
    vtkErrorMacro(<< "startTime entry not found in controlDict");
    temp = tempStringStruct->value;
    return false;
    delete tempStringStruct;
    }
    }
  startTime = this->ControlDictDataParser(temp.c_str());
  double startTime;
  vtkDebugMacro(<<"Start time: "<<startTime);
  startTimeEntry >> startTime;
  //find End Time
  vtkFoamEntry& endTimeEntry = dict.lookup("endTime");
  //while(!(temp.compare(0,6,"endTime",0,6) == 0))
  if(!endTimeEntry.found())
  while (strcmp(temp.substr(0,7).c_str(), "endTime"))
    {
    {
    tempStringStruct = this->GetLine(input);
    vtkErrorMacro(<< "endTime entry not found in controlDict");
    temp = tempStringStruct->value;
    return false;
    delete tempStringStruct;
    }
    }
  endTime = this->ControlDictDataParser(temp.c_str());
  double endTime;
  vtkDebugMacro(<<"End time: "<<endTime);
  endTimeEntry >> endTime;
  //find Delta T
  vtkFoamEntry& deltaTEntry = dict.lookup("deltaT");
  //while(!(temp.compare(0,5,"deltaT",0,5) == 0))
  if(!deltaTEntry.found())
  while (strcmp(temp.substr(0,6).c_str(), "deltaT"))
    {
    {
    tempStringStruct = this->GetLine(input);
    vtkErrorMacro(<< "deltaT entry not found in controlDict");
    temp = tempStringStruct->value;
    return false;
    delete tempStringStruct;
    }
    }
  deltaT = this->ControlDictDataParser(temp.c_str());
  double deltaT;
  vtkDebugMacro(<<"deltaT: "<<deltaT);
  deltaTEntry >> deltaT;
  //find write control
  vtkFoamEntry& writeIntervalEntry = dict.lookup("writeInterval");
  //while(!(temp.compare(0,11,"writeControl",0,11) == 0))
  if(!writeIntervalEntry.found())
  while (strcmp(temp.substr(0,12).c_str(), "writeControl"))
    {
    {
    tempStringStruct = this->GetLine(input);
    vtkErrorMacro(<< "writeInterval entry not found in controlDict");
    temp = tempStringStruct->value;
    return false;
    delete tempStringStruct;
    }
    }
  double writeInterval;
  writeIntervalEntry >> writeInterval;
  temp.erase(temp.begin()+temp.find(";"));
  vtkFoamEntry& timeFormatEntry = dict.lookup("timeFormat");
  vtkstd::string token;
  if(!timeFormatEntry.found())
  vtksys_ios::stringstream tokenizer(temp);
  //while(tokenizer >> token);
  while(!tokenizer.eof())
    {
    {
    tokenizer >> token;
    vtkErrorMacro(<< "timeFormat entry not found in controlDict");
    return false;
    }
    }
  writeControl = token;
  vtkStdString timeFormat;
  vtkDebugMacro(<<"Write control: "<<writeControl.c_str());
  timeFormatEntry >> timeFormat;
  //find write interval
  vtkFoamEntry& timePrecisionEntry = dict.lookup("timePrecision");
  //while(!(temp.compare(0,12,"writeInterval",0,12) == 0))
  int timePrecision;
  while (strcmp(temp.substr(0,13).c_str(), "writeInterval"))
  if(timePrecisionEntry.found())
    {
    timePrecisionEntry >> timePrecision;
    }
  else
    {
    {
    tempStringStruct = this->GetLine(input);
    timePrecision = 6; // the default value
    temp = tempStringStruct->value;
    delete tempStringStruct;
    }
    }
  writeInterval = this->ControlDictDataParser(temp.c_str());
  vtkDebugMacro(<<"Write interval: "<<writeInterval);
  //calculate the time step increment based on type of run
  //calculate the time step increment based on type of run
  //if(writeControl.compare(0,7,"timeStep",0,7) == 0)
  vtkStdString writeControl;
  if(!strcmp(writeControl.substr(0,8).c_str(), "timeStep"))
  dict.lookup("writeControl") >> writeControl;
  double timeStepIncrement;
  if(writeControl == "timeStep")
    {
    {
    vtkDebugMacro(<<"Time step type data");
    vtkDebugMacro(<<"Time step type data");
    timeStepIncrement = writeInterval * deltaT;
    timeStepIncrement = writeInterval * deltaT;
    }
    }
  else
  else if(writeControl == "runTime" || writeControl == "adjustableRunTime")
    {
    {
    vtkDebugMacro(<<"Run time type data");
    vtkDebugMacro(<<"Run time type data");
    timeStepIncrement = writeInterval;
    timeStepIncrement = writeInterval;
    }
    }
  else
  //find time format
  while(temp.find("timeFormat") == vtkstd::string::npos)
    {
    {
    tempStringStruct = this->GetLine(input);
    vtkErrorMacro(<<"Time step can't be determined because writeControl is"
    temp = tempStringStruct->value;
      " set to " << writeControl.c_str());
    delete tempStringStruct;
    return false;
    }
    }
  timeFormat = temp;
  //calculate how many timesteps there should be
  //calculate how many timesteps there should be
  float tempResult = ((endTime-startTime)/timeStepIncrement);
  double tempResult = (endTime - startTime) / timeStepIncrement;
  int tempNumTimeSteps = (int)(tempResult+0.5)+1;  //+0.1 to round up
  int tempNumTimeSteps = (int)(tempResult + 0.5) + 1;  //+0.1 to round up
  //make sure time step dir exists
  //make sure time step dir exists
  vtkstd::vector< double > tempSteps;
  vtkstd::vector< double > tempSteps;
  vtkDirectory * test = vtkDirectory::New();
  vtkDirectory * test = vtkDirectory::New();
  vtksys_ios::stringstream parser;
  this->TimeNames->Initialize();
  double tempStep;
  for(int i = 0; i < tempNumTimeSteps; i++)
  for(int i = 0; i < tempNumTimeSteps; i++)
    {
    {
    tempStep = i*timeStepIncrement + startTime;
    vtkstd::ostringstream parser;
    parser.clear();
    const double tempStep = i * timeStepIncrement + startTime;
    if(timeFormat.find("general") != vtkstd::string::npos)
    // determine time name based on Foam::Time::timeName()
    // in src/OpenFOAM/db/Time/Time.C
#ifdef _MSC_VER
    bool correctExponent = true;
#endif
    if(timeFormat == "general")
      {
      // "do not use std:: or vtkstd:: when using anything declared in
      // iostream," according to VTK coding standards, but following
      // the instruction causes errors...
      parser.setf(vtkstd::ios_base::fmtflags(0), vtkstd::ios_base::floatfield);
      }
    else if(timeFormat == "fixed")
      {
      parser.setf(vtkstd::ios_base::fmtflags(vtkstd::ios_base::fixed),
        vtkstd::ios_base::floatfield);
#ifdef _MSC_VER
      correctExponent = false;
#endif
      }
    else if(timeFormat == "scientific")
      {
      parser.setf(vtkstd::ios_base::fmtflags(vtkstd::ios_base::scientific),
        vtkstd::ios_base::floatfield);
      }
    else
      {
      {
      parser << tempStep;
      vtkWarningMacro("Warning: unsupported time format. Assuming general.");
      parser.setf(vtkstd::ios_base::fmtflags(0), vtkstd::ios_base::floatfield);
      }
    parser.precision(timePrecision);
    parser << tempStep; // stringstream doesn't require ends
#ifdef _MSC_VER
    // workaround for format difference in MSVC++:
    // remove an extra 0 from exponent
    if(correctExponent)
      {
      vtkStdString tempStr(parser.str());
      size_t pos = tempStr.find('e');
      if(pos != vtkStdString::npos && tempStr.length() >= pos + 3
        && tempStr[pos + 2] == '0')
        {
        tempStr.erase(pos + 2, 1);
        parser.str(tempStr);
        }
      }
      }
    else
#endif
    if(test->Open((*this->PathPrefix + parser.str()).c_str()))
      {
      {
      parser << ios::scientific <<tempStep;
      tempSteps.push_back(tempStep);
      this->TimeNames->InsertNextValue(parser.str());
      }
      }
    if(test->Open((this->PathPrefix->value+parser.str().c_str()).c_str()))
    // necessary for reading the case/0 directory whatever the timeFormat is
    // based on Foam::Time::operator++() in src/OpenFOAM/db/Time/Time.C
    else if((fabs(tempStep) < 1.0e-14L) // 10*SMALL
      && test->Open((*this->PathPrefix + vtkStdString("0")).c_str()))
      {
      {
      tempSteps.push_back(tempStep);
      tempSteps.push_back(tempStep);
      this->TimeNames->InsertNextValue(vtkStdString("0"));
      }
      }
    }
    }
  test->Delete();
  test->Delete();
  this->TimeNames->Squeeze();
  //Add the time steps that actually exist to steps
  //Add the time steps that actually exist to steps
  //allows the run to be stopped short of controlDict spec
  //allows the run to be stopped short of controlDict spec
  //allows for removal of timesteps
  //allows for removal of timesteps
  this->NumberOfTimeSteps = tempSteps.size();
  this->NumberOfTimeSteps = tempSteps.size();
  this->Steps = new double[this->NumberOfTimeSteps];
  if(this->NumberOfTimeSteps > 0)
  for(int i = 0; i < this->NumberOfTimeSteps; i++)
    {
    this->Steps = new double[this->NumberOfTimeSteps];
    for(int i = 0; i < this->NumberOfTimeSteps; i++)
      {
      this->Steps[i] = tempSteps[i];
      }
    }
  else
    {
    {
    this->Steps[i] =tempSteps[i];
    // dummy for safely deleting later
    this->Steps = new double[1];
    this->Steps[0] = 0.0;
    }
    }
  return true;
}
  input->close();
// list time directories by searching all valid time instances in a
  delete input;
// case directory
  vtkDebugMacro(<<"controlDict read");
bool vtkOpenFOAMReader::ListTimeDirectoriesByInstances()
  return;
{
  // open the case directory
  vtkDirectory* test = vtkDirectory::New();
  if(!test->Open(this->PathPrefix->c_str()))
    {
    test->Delete();
    vtkErrorMacro(<<"Can't open directory "<<this->PathPrefix->c_str());
    return false;
    }
  // search all the directories in the case directory and detect
  // directories with names convertible to numbers
  this->TimeNames->Initialize();
  vtkDoubleArray* timeValues = vtkDoubleArray::New();
  const int nFiles = test->GetNumberOfFiles();
  for(int i = 0; i < nFiles; i++)
    {
    const vtkStdString dir = test->GetFile(i);
    if(test->FileIsDirectory(dir.c_str()))
      {
      // check if the name is convertible to a number
      bool isTimeDir = true;
      for(size_t j = 0; j < dir.length(); j++)
        {
        const char c = dir[j];
        if(!isdigit(c) && c != '+' && c != '-' && c != '.' && c != 'e'
          && c != 'E')
          {
          isTimeDir = false;
          break;
          }
        }
      if(!isTimeDir)
        {
        continue;
        }
      // convert to a number
      char *endptr;
      double timeValue = strtod(dir.c_str(), &endptr);
      // check if the value really was converted to a number
      if(timeValue == 0.0 && endptr == dir.c_str())
        {
        continue;
        }
      // add to the instance list
      timeValues->InsertNextValue(timeValue);
      this->TimeNames->InsertNextValue(dir);
      }
    }
  test->Delete();
  this->TimeNames->Squeeze();
  // sort the detected time directories and set as timesteps
  this->NumberOfTimeSteps = this->TimeNames->GetSize();
  if(this->NumberOfTimeSteps > 0)
    {
    if(this->NumberOfTimeSteps > 1)
      {
      vtkSortDataArray::Sort(timeValues, this->TimeNames);
      }
    this->Steps = new double[this->NumberOfTimeSteps];
    for(int i = 0; i < this->NumberOfTimeSteps; i++)
      {
      this->Steps[i] = timeValues->GetValue(i);
      }
    }
  else
    {
    // dummy for safely deleting later
    this->Steps = new double[1];
    this->Steps[0] = 0.0;
    }
  timeValues->Delete();
  return true;
}
}
// ****************************************************************************
// ****************************************************************************
//  Method: vtkOpenFOAMReader::GetPoints
//  Method: vtkOpenFOAMReader::ReadControlDict
//
//
//  Purpose:
//  Pupose:
//  read the points file into a vtkPoints
//  reads the controlDict File
//  gather the necessary information to create a path to the data
//
//
// ****************************************************************************
// ****************************************************************************
void vtkOpenFOAMReader::GetPoints (int timeState)
bool vtkOpenFOAMReader::ReadControlDict(const char* pathIn)
{
{
  //path to points file
  vtkStdString path(pathIn);
  vtkstd::string pointPath = this->PathPrefix->value +
  vtkFoamIOobject io;
                             this->PolyMeshPointsDir->value[timeState] +
                             "/polyMesh/points";
  vtkDebugMacro(<<"Read points file: "<<pointPath.c_str());
  vtkstd::string temp;
  if(!io.open(path))
  bool binaryWriteFormat;
  stdString* tempStringStruct;
  ifstream * input = new ifstream(pointPath.c_str(), ios::in VTK_IOS_NOCREATE);
  //make sure file exists
  if(input->fail())
    {
    {
    input->close();
    vtkErrorMacro(<<"Error opening " << io.fileName().c_str() << ": "
    delete input;
      << io.error().str().c_str());
    return;
    return false;
    }
    }
  vtkFoamDict dict;
  //determine if file is binary or ascii
  if(!dict.read(io))
  while(temp.find("format") == vtkstd::string::npos)
    {
    vtkErrorMacro(<<"Error reading line " << io.lineNumber()
      << " of " << io.fileName().c_str() << ": " << io.error().str().c_str());
    return false;
    }
  if(dict.type() != vtkFoamDict::DICTIONARY)
    {
    {
    tempStringStruct = this->GetLine(input);
    vtkErrorMacro(<<"The file type of " << io.fileName().c_str()
    temp = tempStringStruct->value;
      << " is not a dictionary");
    delete tempStringStruct;
    return false;
    }
    }
  input->close();
  //reopen file in correct format
  //create the path to the data directory
  if(temp.find("binary") != vtkstd::string::npos)
  // note that if a file is specified from command line (with
  // --data=opt) its path may be a relative one
  vtkStdString prefix(path);
  // remove trailing "/controlDict.foam"
#if defined(_WIN32)
  size_t pos = prefix.find_last_of("/\\");
#else
  size_t pos = prefix.find_last_of('/');
#endif
  if(pos != vtkStdString::npos)
    {
    {
#ifdef _WIN32
    prefix.erase(pos);
    input->open(pointPath.c_str(), ios::binary | ios::in VTK_IOS_NOCREATE);
    // remove trailing "/system" (or any other directory name)
#if defined(_WIN32)
    pos = prefix.find_last_of("/\\");
#else
    pos = prefix.find_last_of('/');
#endif
    if(pos != vtkStdString::npos)
      {
      prefix.erase(pos + 1); // preserve the last "/"
      }
    else
      {
#if defined(_WIN32) && PARAVIEW_VERSION_MAJOR >= 3
      prefix = ".\\";
#else
#else
    input->open(pointPath.c_str(), ios::in VTK_IOS_NOCREATE);
      prefix = "./";
#endif
#endif
    binaryWriteFormat = true;
      }
    }
    }
  else
  else
    {
    {
    input->open(pointPath.c_str(),ios::in);
#if defined(_WIN32) && PARAVIEW_VERSION_MAJOR >= 3
    binaryWriteFormat = false;
    prefix = "..\\";
    }
#else
    prefix = "../";
  double x,y,z;
#endif
  vtksys_ios::stringstream tokenizer;
  //instantiate the points class
  this->Points->Reset();
  //find end of header
  //while(temp.compare(0,4, "// *", 0, 4) != 0)
  while (strcmp(temp.substr(0,4).c_str(), "// *"))
    {
    tempStringStruct = this->GetLine(input);
    temp = tempStringStruct->value;
    delete tempStringStruct;
    }
    }
  *this->PathPrefix = prefix;
  vtkDebugMacro(<<"Path: "<<this->PathPrefix->c_str());
  //find number of points
  vtkFoamEntry& writeControlEntry = dict.lookup("writeControl");
  tempStringStruct = this->GetLine(input);
  if(!writeControlEntry.found())
  temp = tempStringStruct->value;
  delete tempStringStruct;
  while(temp.empty())
    {
    {
    tempStringStruct = this->GetLine(input);
    vtkErrorMacro(<< "writeControl entry not found in " << pathIn);
    temp = tempStringStruct->value;
    return false;
    delete tempStringStruct;
    }
    }
  vtkStdString writeControl;
  //read number of points
  writeControlEntry >> writeControl;
  tokenizer << temp;
  tokenizer >> NumPoints;
  vtkStdString adjustTimeStep;
  //binary data
  dict.lookup("adjustTimeStep") >> adjustTimeStep; // empty if not found
  if(binaryWriteFormat)
  // list time directories according to controlDict if (adjustTimeStep
  // writeControl) == (off, timeStep) or (on, adjustableRunTime); list
  // by time instances in the case directory otherwise (different behavior
  // from paraFoam)
  // valid switching words taken from src/OpenFOAM/db/Switch/Switch.C
  if(((adjustTimeStep == "off" || adjustTimeStep == "no"
    || adjustTimeStep == "n" || adjustTimeStep == "false"
    || adjustTimeStep == "") && writeControl == "timeStep")
    || ((adjustTimeStep == "on" || adjustTimeStep == "yes"
    || adjustTimeStep == "y" || adjustTimeStep == "true")
    && writeControl == "adjustableRunTime"))
    {
    {
    input->get(); //parenthesis
    return this->ListTimeDirectoriesByControlDict(&dict);
    for(int i = 0; i < NumPoints; i++)
      {
      input->read((char *)&x,sizeof(double));
      input->read((char *)&y,sizeof(double));
      input->read((char *)&z,sizeof(double));
      this->Points->InsertPoint(i,x,y,z);
      }
    }
    }
  //ascii data
  else
  else
    {
    {
    tempStringStruct = this->GetLine(input);
    return this->ListTimeDirectoriesByInstances();
    temp = tempStringStruct->value;
    delete tempStringStruct;
    for(int i = 0; i < this->NumPoints; i++)
      {
      tempStringStruct = this->GetLine(input);
      temp = tempStringStruct->value;
      delete tempStringStruct;
      temp.erase(temp.begin()+temp.find("("));
      temp.erase(temp.begin()+temp.find(")"));
      tokenizer.clear();
      tokenizer << temp;
      tokenizer >> x;
      tokenizer >> y;
      tokenizer >> z;
      this->Points->InsertPoint(i,x,y,z);
      }
    }
    }
  input->close();
  delete input;
  vtkDebugMacro(<<"Point file read");
  return;
}
}
// ****************************************************************************
// ****************************************************************************
//  Method: vtkOpenFOAMReader::ReadFacesFile
//  Method: vtkOpenFOAMReader::GetPoints
//
//
//  Purpose:
//  Purpose:
//  read the faces into a vtkstd::vector
//  read the points file into a vtkPoints
//
//
// ****************************************************************************
// ****************************************************************************
void vtkOpenFOAMReader::ReadFacesFile (const char * facePathIn)
vtkPoints* vtkOpenFOAMReader::GetPoints (int timeState)
{
{
  vtkstd::string facePath(facePathIn);
  //path to points file
  vtkDebugMacro(<<"Read faces file: "<<facePath.c_str());
  vtkStdString pointPath = *this->PathPrefix +
  vtkstd::string temp;
    this->PolyMeshPointsDir->value[timeState] + "/polyMesh/points";
  stdString* tempStringStruct;
  vtkDebugMacro(<<"Read points file: "<<pointPath.c_str());
  bool binaryWriteFormat;
  ifstream * input = new ifstream(facePath.c_str(), ios::in VTK_IOS_NOCREATE);
  //make sure file exists
  if(input->fail())
    {
    input->close();
    delete input;
    return;
    }
  //determine if file is binary or ascii
  vtkFoamIOobject io;
  while(temp.find("format") == vtkstd::string::npos)
  if(!(io.open(pointPath) || io.open(pointPath + ".gz")))
    {
    {
    tempStringStruct = this->GetLine(input);
    vtkErrorMacro(<<"Error opening " << io.fileName().c_str() << ": "
    temp = tempStringStruct->value;
      << io.error().str().c_str());
    delete tempStringStruct;
    return NULL;
    }
    }
  input->close();
  vtkFoamDict dict;
  if(!dict.read(io))
  //reopen file in correct format
  if(temp.find("binary") != vtkstd::string::npos)
    {
    {
#ifdef _WIN32
    vtkErrorMacro(<<"Error reading line " << io.lineNumber()
    input->open(facePath.c_str(), ios::binary | ios::in VTK_IOS_NOCREATE);
      << " of " << io.fileName().c_str() << ": " << io.error().str().c_str());
#else
    return NULL;
    input->open(facePath.c_str(), ios::in VTK_IOS_NOCREATE);
#endif
    binaryWriteFormat = true;
    }
    }
  else
  if(dict.type() != vtkFoamDict::VECTORLIST)
    {
    {
    input->open(facePath.c_str(),ios::in);
    vtkErrorMacro(<<"The file type of " << io.fileName().c_str()
    binaryWriteFormat = false;
      << " is not a vectorList");
    return NULL;
    }
    }
  vtksys_ios::stringstream tokenizer;
  vtkDoubleArray& vl = dict.vectorList();
  size_t pos;
  int numFacePoints;
  this->FacePoints->value.clear();
  //find end of header
  //instantiate the points class
  //while(temp.compare(0,4, "// *", 0, 4) != 0)
  vtkPoints* points = vtkPoints::New();
  while (strcmp(temp.substr(0,4).c_str(), "// *"))
  const int nPoints = vl.GetNumberOfTuples();
    {
  points->SetNumberOfPoints(nPoints);
    tempStringStruct = this->GetLine(input);
    temp = tempStringStruct->value;
    delete tempStringStruct;
    }
  //find number of faces
  for(int i = 0, index = 0; i < nPoints; i++, index += 3)
  tempStringStruct = this->GetLine(input);
  temp = tempStringStruct->value;
  delete tempStringStruct;
  while(temp.empty())
    {
    {
    tempStringStruct = this->GetLine(input);
    points->SetPoint(i, vl.GetPointer(index));
    temp = tempStringStruct->value;
    delete tempStringStruct;
    }
    }
  vtkDebugMacro(<<"Point file read");
  return points;
}
  //read number of faces
// ****************************************************************************
  tokenizer << temp;
//  Method: vtkOpenFOAMReader::ReadFacesFile
  tokenizer >> this->NumFaces;
//
  this->FacePoints->value.resize(this->NumFaces);
//  Purpose:
//  read the faces into a vtkstd::vector
  tempStringStruct = this->GetLine(input);
//
  temp = tempStringStruct->value;
// ****************************************************************************
  delete tempStringStruct;//THROW OUT "("
intVectorVector* vtkOpenFOAMReader::ReadFacesFile (const char* facePathIn)
{
  const vtkStdString facePath(facePathIn);
  vtkDebugMacro(<<"Read faces file: "<<facePath.c_str());
  //binary data
  vtkFoamIOobject io;
  if(binaryWriteFormat)
  if(!(io.open(facePath) || io.open(facePath + ".gz")))
    {
    {
    //char paren;
    vtkErrorMacro(<<"Error opening " << io.fileName().c_str() << ": "
    int tempPoint;
      << io.error().str().c_str());
    for(int i = 0; i < NumFaces; i++)
    return NULL;
      {
      tempStringStruct = this->GetLine(input);
      temp = tempStringStruct->value;
      delete tempStringStruct;//THROW OUT blankline
      tempStringStruct = this->GetLine(input);
      temp = tempStringStruct->value;
      delete tempStringStruct; //grab point count
      tokenizer.clear();
      tokenizer << temp;
      tokenizer >> numFacePoints;
      this->FacePoints->value[i].resize(numFacePoints);
      //paren = input->get();  //grab (
      input->get();  //grab (
      for(int j = 0; j < numFacePoints; j++)
        {
        input->read((char *) &tempPoint, sizeof(int));
        this->FacePoints->value[i][j] = tempPoint;
        }
        tempStringStruct = this->GetLine(input);
        temp = tempStringStruct->value;
        delete tempStringStruct; //throw out ) and rest of line
      }
    }
    }
  vtkFoamDict dict;
  //ascii data
  if(!dict.read(io))
  else
    {
    {
    //create vtkstd::vector of points in each face
    vtkErrorMacro(<<"Error reading line " << io.lineNumber()
    for(int i = 0; i < this->NumFaces; i++)
      << " of " << io.fileName().c_str() << ": " << io.error().str().c_str());
      {
    return NULL;
      tempStringStruct = this->GetLine(input);
    }
      temp = tempStringStruct->value;
  if(dict.type() != vtkFoamDict::LABELLISTLIST)
      delete tempStringStruct;
    {
    vtkErrorMacro(<<"The file type of " << io.fileName().c_str()
      pos = temp.find("(");
      << " is not a labelListList");
      vtksys_ios::stringstream ascTokenizer;
    return NULL;
      ascTokenizer << temp.substr(0, pos);
      temp.erase(0, pos+1);
      ascTokenizer >> numFacePoints;
      this->FacePoints->value[i].resize(numFacePoints);
      for(int j = 0; j < numFacePoints; j++)
        {
        pos = temp.find(" ");
        vtksys_ios::stringstream lineTokenizer;
        lineTokenizer << temp.substr(0, pos);
        temp.erase(0, pos+1);
        lineTokenizer >> this->FacePoints->value[i][j];
        }
      }
    }
    }
  input->close();
  delete input;
  vtkDebugMacro(<<"Faces read");
  vtkDebugMacro(<<"Faces read");
  return;
  return (intVectorVector *)dict.ptr();
}
}
// ****************************************************************************
// ****************************************************************************
//  Method: vtkOpenFOAMReader::ReadOwnerFile
//  Method: vtkOpenFOAMReader::ReadOwnerNeighborFiles
//
//
//  Purpose:
//  Purpose:
//  read the owner file into a vtkstd::vector
//  read the owner file into a vtkstd::vector
//
//
// ****************************************************************************
// ****************************************************************************
void vtkOpenFOAMReader::ReadOwnerFile(const char * ownerPathIn)
bool vtkOpenFOAMReader::ReadOwnerNeighborFiles(faceVectorVector* facesOfCell,
  const char* ownerPathIn, const char* neighborPathIn)
{
{
  vtkstd::string ownerPath(ownerPathIn);
  const vtkStdString ownerPath(ownerPathIn);
  vtkDebugMacro(<<"Read owner file: "<<ownerPath.c_str());
  vtkDebugMacro(<<"Read owner file: "<<ownerPath.c_str());
  vtkstd::string temp;
  stdString* tempStringStruct;
  bool binaryWriteFormat;
  ifstream * input = new ifstream(ownerPath.c_str(), ios::in VTK_IOS_NOCREATE);
  //make sure file exists
  if(input->fail())
    {
    input->close();
    delete input;
    return;
    }
  //determine if file is binary or ascii
  vtkFoamIOobject io;
  while(temp.find("format") == vtkstd::string::npos)
  if(!(io.open(ownerPath) || io.open(ownerPath + ".gz")))
    {
    {
    tempStringStruct = this->GetLine(input);
    vtkErrorMacro(<<"Error opening " << io.fileName().c_str() << ": "
    temp = tempStringStruct->value;
      << io.error().str().c_str());
    delete tempStringStruct;
    return false;
    }
    }
  input->close();
  vtkFoamDict ownerDict;
  if(!ownerDict.read(io))
  //reopen file in correct format
  if(temp.find("binary") != vtkstd::string::npos)
    {
    {
#ifdef _WIN32
    vtkErrorMacro(<<"Error reading line " << io.lineNumber()
    input->open(ownerPath.c_str(), ios::binary | ios::in VTK_IOS_NOCREATE);
      << " of " << io.fileName().c_str() << ": " << io.error().str().c_str());
#else
    return false;
    input->open(ownerPath.c_str(), ios::in VTK_IOS_NOCREATE);
#endif
    binaryWriteFormat = true;
    }
    }
  else
  if(ownerDict.type() != vtkFoamDict::LABELLIST)
    {
    {
    input->open(ownerPath.c_str(),ios::in);
    vtkErrorMacro(<<"The file type of " << io.fileName().c_str()
    binaryWriteFormat = false;
      << " is not a labelList");
    return false;
    }
    }
  io.close();
  vtkstd::string numFacesStr;
  const vtkStdString neighborPath(neighborPathIn);
  int faceValue;
  vtkDebugMacro(<<"Read neighbor file: "<<neighborPath.c_str());
  this->FaceOwner = vtkIntArray::New();
  vtksys_ios::stringstream tokenizer;
  if(!(io.open(neighborPath) || io.open(neighborPath + ".gz")))
  tokenizer << this->NumFaces;
  tokenizer >> numFacesStr;
  //find end of header & number of faces
  //while(temp.compare(0,numFacesStr.size(),numFacesStr,
  //0,numFacesStr.size())!=0)
  while(strcmp(temp.substr(0,numFacesStr.size()).c_str(), numFacesStr.c_str()))
    {
    {
    tempStringStruct = this->GetLine(input);
    vtkErrorMacro(<<"Error opening " << io.fileName().c_str() << ": "
    temp = tempStringStruct->value;
      << io.error().str().c_str());
    delete tempStringStruct;
    return false;
    }
    }
  vtkFoamDict neighborDict;
  this->FaceOwner->SetNumberOfValues(this->NumFaces);
  if(!neighborDict.read(io))
  //binary data
  if(binaryWriteFormat)
    {
    {
    input->get(); //parenthesis
    vtkErrorMacro(<<"Error reading line " << io.lineNumber()
    for(int i = 0; i < NumFaces; i++)
      << " of " << io.fileName().c_str() << ": " << io.error().str().c_str());
      {
    return false;
      input->read((char *) &faceValue, sizeof(int));
      this->FaceOwner->SetValue(i, faceValue);
      }
    }
    }
  if(neighborDict.type() != vtkFoamDict::LABELLIST)
  //ascii data
  else
    {
    {
    tempStringStruct = this->GetLine(input);
    vtkErrorMacro(<<"The file type of " << io.fileName().c_str()
    temp = tempStringStruct->value;
      << " is not a labelList");
    delete tempStringStruct;
    return false;
    //read face owners into int array
    for(int i = 0; i < this->NumFaces; i++)
      {
      tempStringStruct = this->GetLine(input);
      temp = tempStringStruct->value;
      delete tempStringStruct;
      tokenizer.clear();
      tokenizer << temp;
      tokenizer >> faceValue;
      this->FaceOwner->SetValue(i, faceValue);
      }
    }
    }
  //find the number of cells
  const vtkstd::vector<int>& faceOwner = ownerDict.labelList();
  double  * range;
  const vtkstd::vector<int>& faceNeighbor = neighborDict.labelList();
  range = this->FaceOwner->GetRange();
  this->NumCells = (int)range[1]+1;
  //add the face number to the correct cell
  if(faceOwner.size() != faceNeighbor.size())
  //according to owner
  this->FacesOwnerCell->value.resize(this->NumCells);
  int tempCellId;
  for(int j = 0; j < this->NumFaces; j++)
    {
    {
    tempCellId = this->FaceOwner->GetValue(j);
    vtkErrorMacro(<<"Numbers of faces in owner and neighbor don't match");
    if(tempCellId != -1)
    return false;
      {
      this->FacesOwnerCell->value[tempCellId].push_back(j);
      }
    }
    }
  input->close();
  const size_t nFaces = faceOwner.size();
  delete input;
  vtkDebugMacro(<<"Owner file read");
  return;
}
// ****************************************************************************
  if(nFaces == 0)
//  Method: vtkOpenFOAMReader::ReadNeighborFile
//
//  Purpose:
//  read the neighbor file into a vtkstd::vector
//
// ****************************************************************************
void vtkOpenFOAMReader::ReadNeighborFile(const char * neighborPathIn)
{
  vtkstd::string neighborPath(neighborPathIn);
  vtkDebugMacro(<<"Read neighbor file: "<<neighborPath.c_str());
  vtkstd::string temp;
  stdString* tempStringStruct;
  bool binaryWriteFormat;
  ifstream * input = new ifstream(neighborPath.c_str(), ios::in VTK_IOS_NOCREATE);
  //make sure file exists
  if(input->fail())
    {
    {
    input->close();
    vtkWarningMacro(<<"The mesh contains no faces");
    delete input;
    return;
    }
    }
  //determine if file is binary or ascii
  this->FaceOwner = vtkIntArray::New();
  while(temp.find("format") == vtkstd::string::npos)
  vtkIntArray& fo = *this->FaceOwner;
    {
  fo.SetNumberOfValues(nFaces);
    tempStringStruct = this->GetLine(input);
    temp = tempStringStruct->value;
    delete tempStringStruct;
    }
  input->close();
  //reopen file in correct format
  //read face owners into int array
  if(temp.find("binary") != vtkstd::string::npos)
  for(size_t i = 0; i < nFaces; i++)
    {
#ifdef _WIN32
    input->open(neighborPath.c_str(), ios::binary | ios::in VTK_IOS_NOCREATE);
#else
    input->open(neighborPath.c_str(), ios::in VTK_IOS_NOCREATE);
#endif
    binaryWriteFormat = true;
    }
  else
    {
    {
    input->open(neighborPath.c_str(),ios::in);
    fo.SetValue(i, faceOwner[i]);
    binaryWriteFormat = false;
    }
  vtkstd::string numFacesStr;
  int faceValue;
  vtkIntArray * faceNeighbor = vtkIntArray::New();
  vtksys_ios::stringstream tokenizer;
  tokenizer << this->NumFaces;
  tokenizer >> numFacesStr;
  //find end of header & number of faces
  //while(temp.compare(0,numFacesStr.size(),numFacesStr,0,
  //numFacesStr.size())!=0)
  while (strcmp(temp.substr(0,numFacesStr.size()).c_str(), numFacesStr.c_str()))
    {
    tempStringStruct = this->GetLine(input);
    temp = tempStringStruct->value;
    delete tempStringStruct;
    }
    }
  //read face owners into int array
  //add the face numbers to the correct cell
  faceNeighbor->SetNumberOfValues(this->NumFaces);
  // based on Terry's code and
  // src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCells.C
  //binary data
  //find the number of cells
  if(binaryWriteFormat)
  int nCells = -1;
  for(size_t i = 0; i < nFaces; i++)
    {
    {
    input->get(); //parenthesis
    if(nCells < faceOwner[i]) // max(nCells, faceOwner[i])
    for(int i = 0; i < this->NumFaces; i++)
      {
      nCells = faceOwner[i];
      }
    if(nCells < faceNeighbor[i]) // max(nCells, faceNeighbor[i])
      {
      {
      input->read((char *) &faceValue, sizeof(int));
      nCells = faceNeighbor[i];
      faceNeighbor->SetValue(i, faceValue);
      }
      }
    }
    }
  nCells++;
  //ascii data
  if(nCells == 0)
  else
    {
    {
    tempStringStruct = this->GetLine(input);
    vtkWarningMacro(<<"The mesh contains no cells");
    temp = tempStringStruct->value;
    delete tempStringStruct;//throw away (
    //read face owners into int array
    for(int i = 0; i < this->NumFaces; i++)
      {
      tempStringStruct = this->GetLine(input);
      temp = tempStringStruct->value;
      delete tempStringStruct;
      tokenizer.clear();
      tokenizer << temp;
      tokenizer >> faceValue;
      faceNeighbor->SetValue(i, faceValue);
      }
    }
    }
  //No need to recalulate the Number of Cells
  this->FacesNeighborCell->value.resize(this->NumCells);
  //add face number to correct cell
  this->NumCells = nCells;
  int tempCellId;
  for(int j = 0; j < this->NumFaces; j++)
  // count number of faces per cell
  vtkstd::vector<int> nCellFaces(nCells, 0);
  for(size_t i = 0; i < nFaces; i++)
    {
    {
    tempCellId = faceNeighbor->GetValue(j);
    // simpleFoam/pitzDaily3Blocks has faces with owner cell number -1
    if(tempCellId != -1)
    if(faceOwner[i] >= 0)
      {
      nCellFaces[faceOwner[i]]++;
      }
    if(faceNeighbor[i] >= 0)
      {
      {
      this->FacesNeighborCell->value[tempCellId].push_back(j);
      nCellFaces[faceNeighbor[i]]++;
      }
      }
    }
    }
  faceNeighbor->Delete();
  // size cellFaces
  input->close();
  vtkstd::vector<vtkstd::vector<face> >& cellFaces = facesOfCell->value;
  delete input;
  cellFaces.resize(nCells);
  vtkDebugMacro(<<"Neighbor file read");
  for(int i = 0; i < nCells; i++)
  return;
}
// ****************************************************************************
//  Method: vtkOpenFOAMReader::PopulatePolyMeshDirArrays
//
//  Purpose:
//  create a Lookup Table containing the location of the points
//  and faces files for each time steps mesh
//
// ****************************************************************************
void vtkOpenFOAMReader::PopulatePolyMeshDirArrays()
{
  vtkDebugMacro(<<"Create list of points/faces file directories");
  vtksys_ios::stringstream path;
  vtksys_ios::stringstream timeStep;
  bool facesFound;
  bool pointsFound;
  bool polyMeshFound;
  //intialize size to number of timesteps
  this->PolyMeshPointsDir->value.resize(this->NumberOfTimeSteps);
  this->PolyMeshFacesDir->value.resize(this->NumberOfTimeSteps);
  //loop through each timestep
  for(int i = 0; i < this->NumberOfTimeSteps; i++)
    {
    {
    polyMeshFound = false;
    cellFaces[i].resize(nCellFaces[i]);
    facesFound = false;
    }
    pointsFound = false;
    //create the path to the timestep
    path.clear();
    timeStep.clear();
    timeStep << Steps[i];
    path << this->PathPrefix->value <<timeStep.str() << "/";
    //get the number of files
  //add face numbers to correct cell
    vtkDirectory * directory = vtkDirectory::New();
  for(size_t i = 0; i < nFaces; i++)
    directory->Open(path.str().c_str());
    {
    int numFiles = directory->GetNumberOfFiles();
    const int ownerCell = faceOwner[i]; // must be a signed int
    //Look for polyMesh Dir
    // simpleFoam/pitzDaily3Blocks has faces with owner cell number -1
    for(int j = 0; j < numFiles; j++)
    if(ownerCell >= 0)
      {
      {
      vtkstd::string tempFile(directory->GetFile(j));
      face& ownerCellFace = cellFaces[ownerCell][--nCellFaces[ownerCell]];
      if(tempFile.find("polyMesh") != vtkstd::string::npos)
      ownerCellFace.faceIndex = i;
        {
      ownerCellFace.neighborFace = false;
        polyMeshFound = true;
        path << "polyMesh/";
        //get number of files in the polyMesh dir
        vtkDirectory * polyMeshDirectory = vtkDirectory::New();
        polyMeshDirectory->Open(path.str().c_str());
        int numPolyMeshFiles = polyMeshDirectory->GetNumberOfFiles();
        //Look for points/faces files
        for(int k = 0; k < numPolyMeshFiles; k++)
          {
          vtkstd::string tempFile2 = vtkstd::string(polyMeshDirectory->
                                                    GetFile(k));
          if(tempFile2.find("points") != vtkstd::string::npos)
            {
            this->PolyMeshPointsDir->value[i] = timeStep.str();
            pointsFound = true;
            }
          else if(tempFile2.find("faces") != vtkstd::string::npos)
            {
            this->PolyMeshFacesDir->value[i] = timeStep.str();
            facesFound = true;
            }
          }
        //if there is no points or faces found in this timestep
        //set it equal to previous time step if no previous
        //set it equal to "constant" dir
        if(!pointsFound)
          {
          if(i != 0)
            {
            this->PolyMeshPointsDir->value[i] =
              this->PolyMeshPointsDir->value[i-1];
            }
          else
            {
            this->PolyMeshPointsDir->value[i] = vtkstd::string("constant");
            }
          }
        if(!facesFound)
          {
          if(i != 0)
            {
            this->PolyMeshFacesDir->value[i] =
              this->PolyMeshFacesDir->value[i-1];
            }
          else
            {
            this->PolyMeshFacesDir->value[i] = vtkstd::string("constant");
            }
          }
        polyMeshDirectory->Delete();
        break;  //found - stop looking
        }
      }
      }
    //if there is no polyMesh dir
    const int neighborCell = faceNeighbor[i]; // must be a signed int
    //set  it equal to prev timestep
    if(neighborCell >= 0)
    //if no prev set to "constant" dir
    if(!polyMeshFound)
      {
      {
      if(i != 0)
      face& neighborCellFace
        {
        = cellFaces[neighborCell][--nCellFaces[neighborCell]];
        //set points/faces location to previous timesteps value
      neighborCellFace.faceIndex = i;
        this->PolyMeshPointsDir->value[i] = this->PolyMeshPointsDir->value[i-1];
      neighborCellFace.neighborFace = true;
        this->PolyMeshFacesDir->value[i] = this->PolyMeshFacesDir->value[i-1];
        }
      else
        {
        //set points/faces to constant
        this->PolyMeshPointsDir->value[i] = vtkstd::string("constant");
        this->PolyMeshFacesDir->value[i] = vtkstd::string("constant");
        }
      }
      }
    directory->Delete();
    }
    }
  vtkDebugMacro(<<"Points/faces list created");
  vtkDebugMacro(<<"Owner file read");
  return;
  return true;
}
}
// ****************************************************************************
// ****************************************************************************
//  Method: vtkOpenFOAMReader::GetDataType
//  Method: vtkOpenFOAMReader::PopulatePolyMeshDirArrays
//
//
//  Purpose:
//  Purpose:
//  determines whether a variable is a volume scalar, vector or neither
//  create a Lookup Table containing the location of the points
//  for meta data
//  and faces files for each time steps mesh
//
//
// ****************************************************************************
// ****************************************************************************
const char * vtkOpenFOAMReader::GetDataType(const char * pathIn,
void vtkOpenFOAMReader::PopulatePolyMeshDirArrays()
                                      const char * fileNameIn)
{
{
  vtkstd::string path(pathIn);
  vtkDebugMacro(<<"Create list of points/faces file directories");
  vtkstd::string fileName(fileNameIn);
  vtkstd::string filePath = path+"/"+fileName;
  vtkDebugMacro(<<"Get data type of: "<<filePath.c_str());
  stdString* tempStringStruct;
  ifstream * input = new ifstream(filePath.c_str(), ios::in VTK_IOS_NOCREATE);
  //make sure file exists
  if(input->fail())
    {
    input->close();
    delete input;
    return "Null";
    }
  vtkstd::string temp;
  vtkstd::string foamClass;
  vtksys_ios::stringstream tokenizer;
  int opened;
  //see if fileName is a file or directory
  vtkDirectory * directory = vtkDirectory::New();
  opened = directory->Open(filePath.c_str());
  directory->Delete();
  if(opened)
    {
    input->close();
    delete input;
    return "Directory";
    }
  //find class entry
  //intialize size to number of timesteps
  tempStringStruct = this->GetLine(input);
  this->PolyMeshPointsDir->value.resize(this->NumberOfTimeSteps);
  temp = tempStringStruct->value;
  this->PolyMeshFacesDir->value.resize(this->NumberOfTimeSteps);
  delete tempStringStruct;
  while(temp.find("class") == vtkstd::string::npos && !input->eof())
    {
    tempStringStruct = this->GetLine(input);
    temp = tempStringStruct->value;
    delete tempStringStruct;
    }
  //return type
  //loop through each timestep
  if(!input->eof())
  for(int i = 0; i < this->NumberOfTimeSteps; i++)
    {
    {
    temp.erase(temp.begin()+temp.find(";"));
    //create the path to the timestep
    //PARSE OUT CLASS TYPE
    vtkStdString polyMeshPath
    tokenizer << temp;
      = *this->PathPrefix + this->TimeNames->GetValue(i) + "/polyMesh/";
    //while(tokenizer >> foamClass);
    vtkFoamIOobject io;
    while(!tokenizer.eof())
      {
    if(io.open(polyMeshPath + "faces") || io.open(polyMeshPath + "faces.gz"))
      tokenizer >> foamClass;
      {
      io.close();
      //set points/faces location to current timesteps value
      this->PolyMeshFacesDir->value[i] = this->TimeNames->GetValue(i);
      }
      }
    //return scalar, vector, or invalid
    else
    if(foamClass =="volScalarField")
      {
      {
      input->close();
      if(i != 0)
      delete input;
        {
      return "Scalar";
        //set points/faces location to previous timesteps value
        this->PolyMeshFacesDir->value[i] = this->PolyMeshFacesDir->value[i-1];
        }
      else
        {
        //set points/faces to constant
        this->PolyMeshFacesDir->value[i] = vtkStdString("constant");
        }
      }
      }
    else if (foamClass =="volVectorField")
    if(io.open(polyMeshPath + "points") || io.open(polyMeshPath + "points.gz"))
      {
      {
      input->close();
      io.close();
      delete input;
      //set points/faces location to current timesteps value
      return "Vector";
      this->PolyMeshPointsDir->value[i] = this->TimeNames->GetValue(i);
      }
      }
    else
    else
      {
      {
      input->close();
      if(i != 0)
      delete input;
        {
      return "Invalid";
        //set points/faces location to previous timesteps value
        this->PolyMeshPointsDir->value[i]
          = this->PolyMeshPointsDir->value[i-1];
        }
      else
        {
        //set points/faces to constant
        this->PolyMeshPointsDir->value[i] = vtkStdString("constant");
        }
      }
      }
    }
    }
  vtkDebugMacro(<<"Points/faces list created");
  //if the file format is wrong return invalid
  return;
  else
    {
    input->close();
    delete input;
    return "invalid";
    }
}
}
// ****************************************************************************
// ****************************************************************************
//  Method: vtkOpenFOAMReader::GetInternalVariableAtTimestep
//  Method: vtkOpenFOAMReader::GetVariableAtTimestep
//
//
//  Purpose:
//  Purpose:
//  returns the values for a request variable for the internal mesh
//  returns the values for a request variable for the internal and boundary
//  meshes
//
//
// ****************************************************************************
// ****************************************************************************
vtkDoubleArray * vtkOpenFOAMReader::GetInternalVariableAtTimestep
bool vtkOpenFOAMReader::GetVariableAtTimestep(
                 (const char * varNameIn, int timeState)
  vtkUnstructuredGrid* internalMesh, unstructuredGridVector* boundaryMesh,
  vtkFoamDict* boundaryDictPtr, const char* varNameIn, int timeState)
{
{
  vtkstd::string varName(varNameIn);
  vtkStdString varPath = *this->PathPrefix
  vtksys_ios::stringstream varPath;
    + this->TimeNames->GetValue(timeState) + "/" + vtkStdString(varNameIn);
  varPath << this->PathPrefix->value << this->Steps[timeState] << "/" << varName;
  vtkDebugMacro(<<"Get variable: "<<varPath.c_str());
  vtkDebugMacro(<<"Get internal variable: "<<varPath.str().c_str());
  vtkDoubleArray *data = vtkDoubleArray::New();
  vtkstd::string temp;
  // open the file
  stdString* tempStringStruct;
  vtkFoamIOobject io;
  bool binaryWriteFormat;
  if(!io.open(varPath))
  ifstream * input = new ifstream(varPath.str().c_str(), ios::in VTK_IOS_NOCREATE);
  //make sure file exists
  if(input->fail())
    {
    {
    input->close();
    vtkErrorMacro(<<"Error opening " << io.fileName().c_str() << ": "
    delete input;
      << io.error().str().c_str());
    return data;
    return false;
    }
    }
  //determine if file is binary or ascii
  // if the variable is disabled on selection panel then skip it
  while(temp.find("format") == vtkstd::string::npos)
  if(this->CellDataArraySelection->ArrayExists(io.objectName().c_str())
    && !this->CellDataArraySelection->ArrayIsEnabled(io.objectName().c_str()))
    {
    {
    tempStringStruct = this->GetLine(input);
    return true;
    temp = tempStringStruct->value;
    delete tempStringStruct;
    }
    }
  input->close();
  //reopen file in correct format
  // read the field file into dictionary
  if(temp.find("binary") != vtkstd::string::npos)
  vtkFoamDict dict;
    {
  if(!dict.read(io))
#ifdef _WIN32
    input->open(varPath.str().c_str(), ios::binary | ios::in VTK_IOS_NOCREATE);
#else
    input->open(varPath.str().c_str(), ios::in VTK_IOS_NOCREATE);
#endif
    binaryWriteFormat = true;
    }
  else
    {
    {
    input->open(varPath.str().c_str(),ios::in);
    vtkErrorMacro(<<"Error reading line " << io.lineNumber()
    binaryWriteFormat = false;
      << " of " << io.fileName().c_str() << ": " << io.error().str().c_str());
    return false;
    }
    }
  vtkstd::string foamClass;
  if(dict.type() != vtkFoamDict::DICTIONARY)
  vtksys_ios::stringstream tokenizer;
  double value;
  //find class
  tempStringStruct = this->GetLine(input);
  temp = tempStringStruct->value;
  delete tempStringStruct;
  while(temp.find("class") == vtkstd::string::npos)
    {
    {
    tempStringStruct = this->GetLine(input);
    vtkErrorMacro(<<"File " << io.fileName().c_str()
    temp = tempStringStruct->value;
      << "is not valid as a field file");
    delete tempStringStruct;
    return false;
    }
    }
  temp.erase(temp.begin()+temp.find(";"));
  tokenizer << temp;
  // set internal values
  //while(tokenizer >> foamClass);
  vtkDoubleArray* iData;
  while(!tokenizer.eof())
  vtkFoamEntry& iEntry = dict.lookup("internalField");
  if(!iEntry.found())
    {
    {
    tokenizer >> foamClass;
    vtkErrorMacro(<<"internalField not found in " << io.fileName().c_str());
    return false;
    }
    }
  temp="";
  if(iEntry.firstValue().type() == vtkFoamEntryValue::EMPTYLIST)
  //create scalar arrays
  if(foamClass =="volScalarField")
    {
    {
    while(temp.find("internalField") == vtkstd::string::npos)
    if(this->NumCells == 0)
      {
      {
      tempStringStruct = this->GetLine(input);
      // if there's no cell there shouldn't be any boundary faces either
      temp = tempStringStruct->value;
      return true;
      delete tempStringStruct;
      }
      }
    //nonuniform
    else
    if(!(temp.find("nonuniform") == vtkstd::string::npos))
      {
      {
      //create an array
      vtkErrorMacro(<<"internalField is empty");
      tempStringStruct = this->GetLine(input);
      return false;
      temp = tempStringStruct->value;
      }
      delete tempStringStruct;
    }
      int scalarCount;
      tokenizer.clear();
      tokenizer << temp;
      tokenizer >> scalarCount;
      data->SetNumberOfValues(NumCells);
      //binary data
      if(binaryWriteFormat)
        {
        //add values to array
        input->get(); //parenthesis
        for(int i = 0; i < scalarCount; i++)
          {
          input->read((char *) &value, sizeof(double));
          data->SetValue(i, value);
          }
        }
      //ascii data
  if(io.className() == "volScalarField")
      else
    {
    if(iEntry.firstValue().isUniform())
      {
      iData = vtkDoubleArray::New();
      iData->SetNumberOfValues(this->NumCells);
      double num;
      iEntry >> num;
      for(int i = 0; i < this->NumCells; i++)
        {
        {
        //add values to array
        iData->SetValue(i, num);
        tempStringStruct = this->GetLine(input);
        temp = tempStringStruct->value;
        delete tempStringStruct; //discard (
        for(int i = 0; i < scalarCount; i++)
          {
          tempStringStruct = this->GetLine(input);
          temp = tempStringStruct->value;
          delete tempStringStruct;
          tokenizer.clear();
          tokenizer << temp;
          tokenizer >> value;
          data->SetValue(i, value);
          }
        }
        }
      }
      }
    else // nonuniform
    //uniform
    else if(!(temp.find("uniform") == vtkstd::string::npos))
      {
      {
      //parse out the uniform value
      if(iEntry.firstValue().type() != vtkFoamEntryValue::SCALARLIST)
      vtkstd::string token;
      temp.erase(temp.begin()+temp.find(";"));
      tokenizer.clear();
      tokenizer << temp;
      //while(tokenizer>>token);
      while(!tokenizer.eof())
        {
        {
        tokenizer >> token;
        vtkErrorMacro(<<"internalField is not a scalarField");
        return false;
        }
        }
      tokenizer.clear();
      if(iEntry.scalarList().GetSize() != this->NumCells)
      tokenizer << token;
      tokenizer >> value;
      data->SetNumberOfValues(NumCells);
      //create array of uniform values
      for(int i = 0; i < NumCells; i++)
        {
        {
        data->SetValue(i, value);
        vtkErrorMacro(<<"Number of cells in mesh and field don't match: "
          << "mesh = " << this->NumCells << ", field = "
          << iEntry.scalarList().GetSize());
        return false;
        }
        }
      }
      iData = (vtkDoubleArray *)iEntry.ptr();
    //no data
    else
      {
      input->close();
      delete input;
      return data;
      }
      }
    }
    }
  else if(io.className() == "volVectorField")
  //create vector arrays
  else if(foamClass == "volVectorField")
    {
    {
    tempStringStruct = this->GetLine(input);
    if(iEntry.firstValue().isUniform())
    temp = tempStringStruct->value;
    delete tempStringStruct;
    while(temp.find("internalField") == vtkstd::string::npos)
      {
      {
      tempStringStruct = this->GetLine(input);
      iData = vtkDoubleArray::New();
      temp = tempStringStruct->value;
      iData->SetNumberOfComponents(3);
      delete tempStringStruct;
      iData->SetNumberOfTuples(this->NumCells);
      }
      // have to determine the type of vector
    if(!(temp.find("nonuniform") == vtkstd::string::npos))
      if(iEntry.firstValue().type() == vtkFoamEntryValue::LABELLIST)
      {
      //create an array
      tempStringStruct = this->GetLine(input);
      temp = tempStringStruct->value;
      delete tempStringStruct;
      int vectorCount;
      tokenizer.clear();
      tokenizer << temp;
      tokenizer >> vectorCount;
      data->SetNumberOfComponents(3);
      //binary data
      if(binaryWriteFormat)
        {
        {
        //add values to the array
        const vtkstd::vector<int>& ll = iEntry.labelList();
        input->get(); //parenthesis
        if(ll.size() != 3)
        for(int i = 0; i < vectorCount; i++)
          {
          {
          input->read((char *) &value, sizeof(double));
          vtkErrorMacro(<<"The uniform list isn't a vector of size 3");
          data->InsertComponent(i, 0, value);
          iData->Delete();
          input->read((char *) &value, sizeof(double));
          return false;
          data->InsertComponent(i, 1, value);
          }
          input->read((char *) &value, sizeof(double));
        double v[3];
          data->InsertComponent(i, 2, value);
        v[0] = static_cast<double>(ll[0]);
        v[1] = static_cast<double>(ll[1]);
        v[2] = static_cast<double>(ll[2]);
        for(int i = 0; i < this->NumCells; i++)
          {
          iData->SetTuple(i, v);
          }
          }
        }
        }
      else if(iEntry.firstValue().type() == vtkFoamEntryValue::SCALARLIST)
      //ascii data
      else
        {
        {
        //add values to the array
        vtkDoubleArray& sl = iEntry.scalarList();
        tempStringStruct = this->GetLine(input);
        if(sl.GetSize() != 3)
        temp = tempStringStruct->value;
        delete tempStringStruct; //discard (
        for(int i = 0; i < vectorCount; i++)
          {
          {
          tempStringStruct = this->GetLine(input);
          vtkErrorMacro(
          temp = tempStringStruct->value;
            << "The uniform list isn't a vector of size 3 (actual size "
          delete tempStringStruct;
            << sl.GetSize() << ")");
          iData->Delete();
          //REMOVE BRACKETS
          return false;
          temp.erase(temp.begin()+temp.find("("));
          }
          temp.erase(temp.begin()+temp.find(")"));
        double* v = sl.GetPointer(0);
        for(int i = 0; i < this->NumCells; i++)
          //GRAB X,Y,&Z VALUES
          {
          tokenizer.clear();
          iData->SetTuple(i, v);
          tokenizer << temp;
          tokenizer >> value;
          data->InsertComponent(i, 0, value);
          tokenizer >> value;
          data->InsertComponent(i, 1, value);
          tokenizer >> value;
          data->InsertComponent(i, 2, value);
          }
          }
        }
        }
      }
      else
    else if(!(temp.find("uniform") == vtkstd::string::npos))
      {
      //create an array of uniform values
      double value1, value2, value3;
      //parse out the uniform values
      temp.erase(temp.begin(), temp.begin()+temp.find("(")+1);
      temp.erase(temp.begin()+temp.find(")"), temp.end());
      tokenizer.clear();
      tokenizer << temp;
      tokenizer >> value1;
      tokenizer >> value2;
      tokenizer >> value3;
      data->SetNumberOfComponents(3);
      for(int i = 0; i < NumCells; i++)
        {
        {
        data->InsertComponent(i, 0, value1);
        vtkErrorMacro(<<"Wrong list type");
        data->InsertComponent(i, 1, value2);
        iData->Delete();
        data->InsertComponent(i, 2, value3);
        return false;
        }
        }
      }
      }
    else // nonuniform
    //no data
    else
      {
      {
      input->close();
      if(iEntry.firstValue().type() != vtkFoamEntryValue::VECTORLIST)
      delete input;
        {
      return data;
        vtkErrorMacro(<<"internalField is not a vectorField");
        return false;
        }        
      if(iEntry.vectorList().GetNumberOfTuples() != this->NumCells)
        {
        vtkErrorMacro(<<"Number of cells in mesh and field don't match: "
          << "mesh = " << this->NumCells << ", field = "
          << iEntry.vectorList().GetNumberOfTuples());
        return false;
        }
      iData = (vtkDoubleArray *)iEntry.ptr();
      }
      }
    }
    }
  input->close();
  else
  delete input;
  vtkDebugMacro(<<"Internal variable data read");
  return data;
}
// ****************************************************************************
//  Method: vtkOpenFOAMReader::GetBoundaryVariableAtTimestep
//
//  Purpose:
//  returns the values for a request variable for a bondary region
//
// ****************************************************************************
vtkDoubleArray * vtkOpenFOAMReader::GetBoundaryVariableAtTimestep
                (int boundaryIndex, const char * varNameIn, int timeState,
                 vtkUnstructuredGrid * internalMesh)
{
  vtkstd::string varName(varNameIn);
  vtksys_ios::stringstream varPath;
  varPath << this->PathPrefix->value << this->Steps[timeState] << "/" << varName;
  vtkDebugMacro(<<"Get boundary variable: "<<varPath.str().c_str());
  vtkDoubleArray *data = vtkDoubleArray::New();
  vtkstd::string temp;
  stdString* tempStringStruct;
  bool binaryWriteFormat;
  ifstream * input = new ifstream(varPath.str().c_str(), ios::in VTK_IOS_NOCREATE);
  //make sure file exists
  if(input->fail())
    {
    {
    input->close();
    vtkErrorMacro(<<"Unsupported field class");
    delete input;
    return false;
    return data;
    }
    }
  //determine if file is binary or ascii
  // Add field only if internal Mesh exists (skip if not selected)
  while(temp.find("format") == vtkstd::string::npos)
  // Note we still need to read internalField even if internal mesh is
  // not selected, since boundaries without value entries may refer to
  // the internalField.
  if((iData->GetSize() > 0) 
    && (this->GetPatchArrayStatus(this->GetPatchArrayName(0)))
    && (internalMesh != NULL))
    {
    {
    tempStringStruct = this->GetLine(input);
    iData->SetName(io.objectName().c_str());
    temp = tempStringStruct->value;
    internalMesh->GetCellData()->AddArray(iData);
    delete tempStringStruct;
    }
    }
  input->close();
  //reopen file in correct format
  // set boundary values
  if(temp.find("binary") != vtkstd::string::npos)
  vtkFoamEntry& bEntry = dict.lookup("boundaryField");
    {
  vtkFoamDict& boundaryDict = *boundaryDictPtr;
#ifdef _WIN32
  for(size_t boundaryIndex = 0, i = 0; i < boundaryDict.size(); i++)
    input->open(varPath.str().c_str(), ios::binary | ios::in VTK_IOS_NOCREATE);
#else
    input->open(varPath.str().c_str(), ios::in VTK_IOS_NOCREATE);
#endif
    binaryWriteFormat = true;
    }
  else
    {
    {
    input->open(varPath.str().c_str(),ios::in);
    vtkFoamEntry& boundaryEntryI = boundaryDict.entry(i);
    binaryWriteFormat = false;
    int nFaces;
    }
    boundaryEntryI.dictionary().lookup("nFaces") >> nFaces;
  vtkstd::string foamClass;
  vtksys_ios::stringstream tokenizer;
  double value;
  //find class
    // skip empty boundary
  tempStringStruct = this->GetLine(input);
    if(nFaces == 0)
  temp = tempStringStruct->value;
  delete tempStringStruct;
  while(temp.find("class") == vtkstd::string::npos)
    {
    tempStringStruct = this->GetLine(input);
    temp = tempStringStruct->value;
    delete tempStringStruct;
    }
  temp.erase(temp.begin()+temp.find(";"));
  tokenizer << temp;
  //while(tokenizer >> foamClass);
  while(!tokenizer.eof())
    {
    tokenizer >> foamClass;
    }
  temp="";
  //create scalar arrays
  if(foamClass =="volScalarField")
    {
    //find desired mesh
    while(temp.find(this->BoundaryNames->value[boundaryIndex]) == 
            vtkstd::string::npos && !input->eof())
      {
      {
      tempStringStruct = this->GetLine(input);
      continue;
      temp = tempStringStruct->value;
      delete tempStringStruct;
      }
      }
    if(input->eof())
    const vtkStdString& boundaryNameI = boundaryEntryI.keyword();
    // Add field only if given boundary is selected for display
    if(!this->GetPatchArrayStatus(boundaryNameI.c_str()))
      {
      {
      input->close();
      continue;
      delete input;
      return data;
      }
      }
    //find value entry
    while(temp.find("}") == vtkstd::string::npos &&
    vtkFoamEntry& bEntryI = bEntry.dictionary().lookup(boundaryNameI);
          temp.find("value ") == vtkstd::string::npos)
    if(!bEntryI.found())
      {
      {
      tempStringStruct = this->GetLine(input);
      vtkErrorMacro(<< "boundaryField " << boundaryNameI.c_str()
      temp = tempStringStruct->value;
        << " not found in object " << varNameIn << " at time = "
      delete tempStringStruct; //find value
        << this->TimeNames->GetValue(timeState).c_str());
      iData->Delete();
      return false;
      }
      }
    //nonuniform
    if(bEntryI.firstValue().type() != vtkFoamEntryValue::DICTIONARY)
    if(!(temp.find("nonuniform") == vtkstd::string::npos))
      {
      {
      vtkErrorMacro(<< "Type of boundaryField " << boundaryNameI.c_str()
        << " is not a subdictionary in object " << varNameIn << " at time = "
        << this->TimeNames->GetValue(timeState).c_str());
      iData->Delete();
      return false;
      }
      //binary data
    vtkDoubleArray* vData;
      if(binaryWriteFormat)
        {
        //create an array
        tempStringStruct = this->GetLine(input);
        temp = tempStringStruct->value;
        delete tempStringStruct;
        int scalarCount;
        tokenizer.clear();
        tokenizer << temp;
        tokenizer >> scalarCount;
        data->SetNumberOfValues(scalarCount);
        //assign values to the array
    vtkFoamEntry& vEntry = bEntryI.dictionary().lookup("value");
        input->get(); //parenthesis
    // uniformValue is for Hrv's dev version
        for(int i = 0; i < scalarCount; i++)
    vtkFoamEntry& uvEntry = bEntryI.dictionary().lookup("uniformValue");
    
    if(vEntry.found() || uvEntry.found()) // the boundary has a value entry
      {
      if(io.className() == "volScalarField")
        {
        if((vEntry.found() && vEntry.firstValue().isUniform())
          || uvEntry.found())
          {
          vData = vtkDoubleArray::New();
          vData->SetNumberOfValues(nFaces);
          double num;
          if(vEntry.found()) // "value" entry has the priority
            {
            vEntry >> num;
            }
          else
            {
            uvEntry >> num;
            }
          for(int j = 0; j < nFaces; j++)
            {
            vData->SetValue(j, num);
            }
          }
        else // nonuniform
          {
          {
          input->read((char *) &value, sizeof(double));
          if(vEntry.firstValue().type() != vtkFoamEntryValue::SCALARLIST)
          data->SetValue(i, value);
            {
            vtkErrorMacro(<<"boundaryField " << boundaryNameI.c_str()
              << " is not a scalarField");
            iData->Delete();
            return false;
            }
          if(vEntry.scalarList().GetSize() != nFaces)
            {
            vtkErrorMacro(<<"Number of faces in field and bondary don't match");
            iData->Delete();
            return false;
            }
          vData = (vtkDoubleArray *)vEntry.ptr();
          }
          }
        }
        }
      else if(io.className() == "volVectorField")
      //ascii data
      else
        {
        {
        temp.erase(temp.begin(), temp.begin()+temp.find(">")+1);
        if((vEntry.found() && vEntry.firstValue().isUniform())
        //ascii data with 10 or less values are on the same line
          || uvEntry.found())
        //>10
          {
        if(temp == vtkstd::string(" "))
          vData = vtkDoubleArray::New();
          {
          vData->SetNumberOfComponents(3);
          //create an array of data
          vData->SetNumberOfTuples(nFaces);
          tempStringStruct = this->GetLine(input);
          // the "value" entry has the priority
          temp = tempStringStruct->value;
          vtkFoamEntry& vvEntry = vEntry.found() ? vEntry : uvEntry;
          delete tempStringStruct;
          // have to determine the type of vector
          if(vvEntry.firstValue().type() == vtkFoamEntryValue::LABELLIST)
          int scalarCount;
            {
          tokenizer.clear();
            const vtkstd::vector<int>& ll = vvEntry.labelList();
          tokenizer << temp;
            if(ll.size() != 3)
          tokenizer >> scalarCount;
              {
          data->SetNumberOfValues(scalarCount);
              vtkErrorMacro(<<"The uniform list isn't a vector of size 3");
          tempStringStruct = this->GetLine(input);
              iData->Delete();
          temp = tempStringStruct->value;
              vData->Delete();
          delete tempStringStruct; //discard (
              return false;
              }
          for(int i = 0; i < scalarCount; i++)
            double v[3];
            {
            v[0] = static_cast<double>(ll[0]);
            tempStringStruct = this->GetLine(input);
            v[1] = static_cast<double>(ll[1]);
            temp = tempStringStruct->value;
            v[2] = static_cast<double>(ll[2]);
            delete tempStringStruct;
            for(int j = 0; j < nFaces; j++)
              {
            tokenizer.clear();
              vData->SetTuple(j, v);
            tokenizer << temp;
              }
            tokenizer >> value;
            }
            data->SetValue(i, value);
          else if(vvEntry.firstValue().type() == vtkFoamEntryValue::SCALARLIST)
            {
            vtkDoubleArray& sl = vvEntry.scalarList();
            if(sl.GetSize() != 3)
              {
              vtkErrorMacro(<< "The uniform value list in patch "
                << boundaryNameI.c_str() << " of file "
                << io.fileName().c_str()
                << " isn't a vector of size 3 (actual size " << sl.GetSize()
                << ")");
              iData->Delete();
              vData->Delete();
              return false;
              }
            double* v = sl.GetPointer(0);
            for(int j = 0; j < nFaces; j++)
              {
              vData->SetTuple(j, v);
              }
            }
          else
            {
            vtkErrorMacro(<<"Wrong list type");
            iData->Delete();
            vData->Delete();
            return false;
            }
            }
          }
          }
        //=<10
        else // nonuniform
        else
          {
          {
          //create an array with data
          if(vEntry.firstValue().type() != vtkFoamEntryValue::VECTORLIST)
          int scalarCount;
            {
          tokenizer.clear();
            vtkErrorMacro(<<"boundaryField " << boundaryNameI.c_str()
          tokenizer << temp;
              << " is not a vectorField");
          tokenizer >> scalarCount;
            iData->Delete();
          data->SetNumberOfValues(scalarCount);
            return false;
          temp.erase(temp.begin(), temp.begin()+temp.find("(")+1);
            }
          temp.erase(temp.begin()+temp.find(")"), temp.end());
          if(vEntry.vectorList().GetNumberOfTuples() != nFaces)
          tokenizer.clear();
          tokenizer << temp;
          for(int i = 0; i < scalarCount; i++)
            {
            {
            tokenizer >> value;
            vtkErrorMacro(<<"Number of faces in field and bondary don't match");
            data->SetValue(i, value);
            iData->Delete();
            return false;
            }
            }
          vData = (vtkDoubleArray *)vEntry.ptr();
          }
          }
        }
        }
      }
      else // other field types
    //uniform
    else if(!(temp.find("uniform") == vtkstd::string::npos))
      {
      //create an array of uniform values
      double value1 = 0;
      temp.erase(temp.begin(), temp.begin()+temp.find("uniform")+7);
      temp.erase(temp.begin()+temp.find(";"), temp.end());
      tokenizer.clear();
      tokenizer << temp;
      tokenizer >> value1;
      data->SetNumberOfValues(this->SizeOfBoundary->value[boundaryIndex]);
      for(int i = 0; i < this->SizeOfBoundary->value[boundaryIndex]; i++)
        {
        data->SetValue(i, value1);
        }
      }
    //no data
    else
      {
      int cellId;
      vtkDataArray * internalData = internalMesh->GetCellData()->
                                    GetArray(varName.c_str());
      data->SetNumberOfValues(this->SizeOfBoundary->value[boundaryIndex]);
      for(int i = 0; i < this->SizeOfBoundary->value[boundaryIndex]; i++)
        {
        {
        cellId = this->FaceOwner->GetValue(this->StartFace + i);
        vtkErrorMacro(<<"Unsupported field class");
        data->SetValue(i, internalData->GetComponent(cellId, 0));
        iData->Delete();
        return false;
        }
        }
      input->close();
      delete input;
      return data;
      }
    }
  //CREATE VECTOR ARRAYS
  else if(foamClass == "volVectorField")
    {
    while(temp.find(this->BoundaryNames->value[boundaryIndex]) == 
          vtkstd::string::npos && !input->eof())
      {
      tempStringStruct = this->GetLine(input);
      temp = tempStringStruct->value;
      delete tempStringStruct;
      }
    if(input->eof())
      {
      input->close();
      delete input;
      return data;
      }
      }
    while(temp.find("}") == vtkstd::string::npos &&
    else // doesn't have a value entry
          temp.find("value ") == vtkstd::string::npos)
      {
      {
      tempStringStruct = this->GetLine(input);
      int startFace;
      temp = tempStringStruct->value;
      boundaryEntryI.dictionary().lookup("startFace") >> startFace;
      delete tempStringStruct; //find value
      vData = vtkDoubleArray::New();
      }
    //nonuniform
    if(!(temp.find("nonuniform") == vtkstd::string::npos))
      {
      //create an array
      tempStringStruct = this->GetLine(input);
      temp = tempStringStruct->value;
      delete tempStringStruct;
      int vectorCount;
      if(io.className() == "volScalarField")
      tokenizer.clear();
      tokenizer << temp;
      tokenizer >> vectorCount;
      data->SetNumberOfComponents(3);
      //binary data
      if(binaryWriteFormat)
        {
        {
        //insert values into the array
        vData->SetNumberOfValues(nFaces);
        input->get(); //parenthesis
        for(int j = 0; j < nFaces; j++)
        for(int i = 0; i < vectorCount; i++)
          {
          {
          input->read((char *) &value, sizeof(double));
          const int cellId = this->FaceOwner->GetValue(startFace + j);
          data->InsertComponent(i, 0, value);
          vData->SetValue(j, iData->GetValue(cellId));
          input->read((char *) &value, sizeof(double));
          data->InsertComponent(i, 1, value);
          input->read((char *) &value, sizeof(double));
          data->InsertComponent(i, 2, value);
          }
          }
        }
        }
      else if(io.className() == "volVectorField")
        //ascii data
        {
        else
        vData->SetNumberOfComponents(3);
        vData->SetNumberOfTuples(nFaces);
        for(int j = 0; j < nFaces; j++)
          {
          {
          //insert values into the array
          const int cellId = this->FaceOwner->GetValue(startFace + j);
          tempStringStruct = this->GetLine(input);
          // in this case GetTuple should be thread-safe accoding to
          temp = tempStringStruct->value;
          // the FAQ on ParaView Wiki
          delete tempStringStruct; //discard (
          vData->SetTuple(j, iData->GetTuple(cellId));
          for(int i = 0; i < vectorCount; i++)
            {
            tempStringStruct = this->GetLine(input);
            temp = tempStringStruct->value;
            delete tempStringStruct;
            //REMOVE BRACKETS
            temp.erase(temp.begin()+temp.find("("));
            temp.erase(temp.begin()+temp.find(")"));
            //GRAB X,Y,&Z VALUES
            tokenizer.clear();
            tokenizer << temp;
            tokenizer >> value;
            data->InsertComponent(i, 0, value);
            tokenizer >> value;
            data->InsertComponent(i, 1, value);
            tokenizer >> value;
            data->InsertComponent(i, 2, value);
            }
          }
          }
        }
        }
      else
    //uniform
    else if(!(temp.find("uniform") == vtkstd::string::npos))
      {
      //create an array of uniform values
      double value1 = 0, value2 = 0, value3 = 0;
      temp.erase(temp.begin(), temp.begin()+temp.find("(")+1);
      temp.erase(temp.begin()+temp.find(")"), temp.end());
      tokenizer.clear();
      tokenizer << temp;
      tokenizer >> value1;
      tokenizer >> value2;
      tokenizer >> value3;
      data->SetNumberOfComponents(3);
      for(int i = 0; i < this->SizeOfBoundary->value[boundaryIndex]; i++)
        {
        {
        data->InsertComponent(i, 0, value1);
        vtkErrorMacro(<<"Unsupported field class");
        data->InsertComponent(i, 1, value2);
        iData->Delete();
        data->InsertComponent(i, 2, value3);
        vData->Delete();
        return false;
        }
        }
      }
      }
    if(vData->GetSize() > 0)
    //no data
    else
      {
      {
      int cellId;
      vData->SetName(io.objectName().c_str());
      vtkDataArray * internalData = internalMesh->GetCellData()->
      boundaryMesh->value[boundaryIndex]->GetCellData()
                                    GetArray(varName.c_str());
        ->AddArray(vData);
      data->SetNumberOfComponents(3);
      for(int i = 0; i < this->SizeOfBoundary->value[boundaryIndex]; i++)
        {
        cellId = this->FaceOwner->GetValue(this->StartFace + i);
        data->InsertComponent(i, 0, internalData->GetComponent(cellId, 0));
        data->InsertComponent(i, 1, internalData->GetComponent(cellId, 1));
        data->InsertComponent(i, 2, internalData->GetComponent(cellId, 2));
        }
      input->close();
      delete input;
      return data;
      }
      }
    vData->Delete();
    boundaryIndex++;
    }
    }
  input->close();
  delete input;
  iData->Delete();
  vtkDebugMacro(<<"Boundary data read");
  vtkDebugMacro(<<"Internal variable data read");
  return data;
  return true;
}
}
// ****************************************************************************
// ****************************************************************************
//  Method: vtkOpenFOAMReader::GatherBlocks
//  Method: vtkOpenFOAMReader::GatherBlocks
//
//
//  Purpose:
//  Purpose:
//  returns a vector of block names for a specified domain
//  returns a dictionary of block names for a specified domain
//
//
// ****************************************************************************
// ****************************************************************************
stringVector * vtkOpenFOAMReader::GatherBlocks(const char * typeIn,
vtkOpenFOAMReader::vtkFoamDict* vtkOpenFOAMReader::GatherBlocks(
                                              int timeState)
  const char* typeIn, int timeState, bool mustRead)
{
{
  vtkstd::string type(typeIn);
  vtkStdString type(typeIn);
  vtkstd::string blockPath = this->PathPrefix->value +
  vtkStdString blockPath = *this->PathPrefix
                             this->PolyMeshFacesDir->value[timeState] +
    + this->PolyMeshFacesDir->value[timeState] + "/polyMesh/" + type;
                             "/polyMesh/"+type;
  vtkstd::vector< vtkstd::string > blocks;
  vtkFoamIOobject io;
  stringVector *returnValue = new stringVector;
  if(!(io.open(blockPath) || io.open(blockPath + ".gz")))
  vtkDebugMacro(<<"Get blocks: "<<blockPath.c_str());
    {
    if(mustRead)
  ifstream * input = new ifstream(blockPath.c_str(), ios::in VTK_IOS_NOCREATE);
      {
  //if there is no file return a null vector
      vtkErrorMacro(<<"Error opening " << io.fileName().c_str() << ": "
  if(input->fail())
        << io.error().str().c_str());
    {
      }
    input->close();
    return NULL;
    delete input;
    }
    returnValue->value = blocks;
    return returnValue;
  vtkFoamDict* dictPtr = new vtkFoamDict;
    }
  vtkFoamDict& dict = *dictPtr;
  if(!dict.read(io))
  vtkstd::string temp;
    {
  stdString* tempStringStruct;
    vtkErrorMacro(<<"Error reading line " << io.lineNumber()
  vtkstd::string token;
      << " of " << io.fileName().c_str() << ": " << io.error().str().c_str());
  vtksys_ios::stringstream tokenizer;
    delete dictPtr;
  vtkstd::string tempName;
    return NULL;
    }
  //find end of header
  if(dict.type() != vtkFoamDict::DICTIONARY)
  //while(temp.compare(0,4,"// *",0,4)!=0)
    {
  while (strcmp(temp.substr(0,4).c_str(), "// *"))
    vtkErrorMacro(<<"The file type of " << io.fileName().c_str()
    {
      << " is not a dictionary");
    tempStringStruct = this->GetLine(input);
    delete dictPtr;
    temp = tempStringStruct->value;
    return NULL;
    delete tempStringStruct;
    }
    }
  return dictPtr;
  tempStringStruct = this->GetLine(input);
  temp = tempStringStruct->value;
  delete tempStringStruct;
  tempStringStruct = this->GetLine(input);
  temp = tempStringStruct->value;
  delete tempStringStruct; //throw out blank line
  //Number of blocks
  tokenizer << temp;
  tokenizer >> this->NumBlocks;
  blocks.resize(this->NumBlocks);
  //loop through each block
  for(int i = 0; i < this->NumBlocks; i++)
    {
    tempStringStruct = this->GetLine(input);
    temp = tempStringStruct->value;
    delete tempStringStruct; //throw out blank line
    //NAME
    tempStringStruct = this->GetLine(input);
    temp = tempStringStruct->value;
    delete tempStringStruct; //name
    tokenizer.clear();
    tokenizer << temp;
    tokenizer >> tempName;
    blocks[i] = tempName;
    //while(temp.compare(0,1,"}",0,1) != 0)
    while (strcmp(temp.substr(0,1).c_str(), "}"))
      {
      tempStringStruct = this->GetLine(input);
      temp = tempStringStruct->value;
      delete tempStringStruct;
      }
    }
  returnValue->value = blocks;
  input->close();
  delete input;
  return returnValue;
}
}
// ****************************************************************************
// ****************************************************************************
 Lines 2378-2515    Link Here 
//  returns a requested boundary mesh
//  returns a requested boundary mesh
//
//
// ****************************************************************************
// ****************************************************************************
vtkUnstructuredGrid * vtkOpenFOAMReader::GetBoundaryMesh(int timeState,
unstructuredGridVector* vtkOpenFOAMReader::GetBoundaryMesh(
                                                         int boundaryIndex)
  vtkFoamDict* boundaryDictPtr, intVectorVector* facesPoints,
  vtkPoints* points)
{
{
  vtkUnstructuredGrid * boundaryMesh = vtkUnstructuredGrid::New();
  vtkFoamDict& boundaryDict = *boundaryDictPtr;
  vtkstd::string boundaryPath = this->PathPrefix->value +
  unstructuredGridVector* boundaryMesh = new unstructuredGridVector;
                                this->PolyMeshFacesDir->value[timeState] +
                                "/polyMesh/boundary";
  vtkDebugMacro(<<"Create boundary mesh: "<<boundaryPath.c_str());
  int nFaces;
  for(size_t boundaryIndex = 0; boundaryIndex < boundaryDict.size();
    boundaryIndex++)
  ifstream * input = new ifstream(boundaryPath.c_str(), ios::in VTK_IOS_NOCREATE);
  //return a Null object
  if(input->fail())
    {
    {
    input->close();
    vtkFoamDict& dict = boundaryDict.entry(boundaryIndex).dictionary();
    delete input;
    return boundaryMesh;
    }
  vtkstd::string temp;
    int nFaces;
  stdString* tempStringStruct;
    vtkFoamEntry& nFacesEntry = dict.lookup("nFaces");
  vtkstd::string token;
    vtkFoamEntry& startFaceEntry = dict.lookup("startFace");
  vtksys_ios::stringstream tokenizer;
    if(!nFacesEntry.found() || !startFaceEntry.found())
      {
      vtkWarningMacro(
        << "Entry nFaces or startFace not found in boundary entry "
        << boundaryDict.entry(boundaryIndex).keyword().c_str());
      for(size_t i = 0; i < boundaryMesh->value.size(); i++)
        {
        boundaryMesh->value[i]->Delete();
        }
      delete boundaryMesh;
      return NULL;
      }
    nFacesEntry >> nFaces;
  //find desired mesh entry
    // skip empty boundary
  while(temp.find(this->BoundaryNames->value[boundaryIndex]) == 
    if(nFaces == 0)
        vtkstd::string::npos)
      {
    {
      continue;
    tempStringStruct = this->GetLine(input);
      }
    temp = tempStringStruct->value;
    delete tempStringStruct;
    }
  //get nFaces
    // Create a boundary mesh only if selected in the list for display
  while(temp.find("nFaces") == vtkstd::string::npos)
    vtkFoamEntry& boundaryEntryI = boundaryDict.entry(boundaryIndex);
    {
    const vtkStdString& boundaryNameI = boundaryEntryI.keyword();
    tempStringStruct = this->GetLine(input);
    if(!this->GetPatchArrayStatus(boundaryNameI.c_str()))
    temp = tempStringStruct->value;
      {
    delete tempStringStruct;
      continue;
    }
      }
  temp.erase(temp.begin()+temp.find(";")); //remove ;
  tokenizer << temp;
  //while(tokenizer >> token);
  while(!tokenizer.eof())
    {
    tokenizer >> token;
    }
  tokenizer.clear();
  tokenizer << token;
  tokenizer >> nFaces;
  //get startface
    int startFace;
  tempStringStruct = this->GetLine(input);
    startFaceEntry >> startFace;
  temp = tempStringStruct->value;
  delete tempStringStruct;
  //look for "startFaces"
    int endFace = startFace + nFaces;
  while(temp.find("startFace") == vtkstd::string::npos)
    {
    tempStringStruct = this->GetLine(input);
    temp = tempStringStruct->value;
    delete tempStringStruct;
    }
  temp.erase(temp.begin()+temp.find(";")); //remove ;
  tokenizer.clear();
  tokenizer << temp;
  //while(tokenizer >> token);
  while(!tokenizer.eof())
    {
    tokenizer >> token;
    }
  tokenizer.clear();
  tokenizer << token;
  tokenizer >> this->StartFace;
  //Create the mesh
    //Create the mesh
  int j, k;
    boundaryMesh->value.push_back(vtkUnstructuredGrid::New());
  vtkTriangle * triangle;
    vtkUnstructuredGrid& bm = *boundaryMesh->value.back();
  vtkQuad * quad;
    bm.Allocate(nFaces);
  vtkPolygon * polygon;
  int endFace = this->StartFace + nFaces;
  //loop through each face
  for(j = this->StartFace; j < endFace; j++)
    {
    //triangle
    // aloocate array for converting int vector to vtkIdType vector:
    if(this->FacePoints->value[j].size() == 3)
    // workaround for 64bit machines
    int maxNFacePoints = 0;
    for(int j = startFace; j < endFace; j++)
      {
      {
      triangle = vtkTriangle::New();
      const int nFacePoints = facesPoints->value[j].size();
      for(k = 0; k < 3; k++)
      if(nFacePoints > maxNFacePoints)
        {
        {
        triangle->GetPointIds()->SetId(k, this->FacePoints->value[j][k]);
        maxNFacePoints = nFacePoints;
        }
        }
      boundaryMesh->InsertNextCell(triangle->GetCellType(),
      triangle->GetPointIds());
      triangle->Delete();
      }
      }
    vtkIdType* facePointsVtkId = new vtkIdType[maxNFacePoints];
    //quad
    //loop through each face
    else if(this->FacePoints->value[j].size() == 4)
    for(int j = startFace; j < endFace; j++)
      {
      {
      quad = vtkQuad::New();
      vtkstd::vector<int>& facePoints = facesPoints->value[j];
      for(k = 0; k < 4; k++)
      size_t nFacePoints = facePoints.size();
      for(size_t k = 0; k < nFacePoints; k++)
        {
        {
        quad->GetPointIds()->SetId(k, this->FacePoints->value[j][k]);
        facePointsVtkId[k] = facePoints[k];
        }
        }
      boundaryMesh->InsertNextCell(quad->GetCellType(),
      quad->GetPointIds());
      quad->Delete();
      }
    //polygon
      //triangle
    else
      if(nFacePoints == 3)
      {
        {
      polygon = vtkPolygon::New();
        bm.InsertNextCell(VTK_TRIANGLE, 3, facePointsVtkId);
      for(k = 0; k < (int)this->FacePoints->value[j].size(); k++)
        }
      // quad
      else if(nFacePoints == 4)
        {
        {
        polygon->GetPointIds()->InsertId(k, this->FacePoints->value[j][k]);
        bm.InsertNextCell(VTK_QUAD, 4, facePointsVtkId);
        }
      //polygon
      else
        {
        bm.InsertNextCell(VTK_POLYGON, nFacePoints,
          facePointsVtkId);
        }
        }
      boundaryMesh->InsertNextCell(polygon->GetCellType(),
      polygon->GetPointIds());
      polygon->Delete();
      }
      }
    }
    delete [] facePointsVtkId;
  //set points for boundary
    //set points for boundary
  boundaryMesh->SetPoints(this->Points);
    bm.SetPoints(points);
  //add size of mesh
    }
  this->SizeOfBoundary->value.push_back(boundaryMesh->GetNumberOfCells());
  input->close();
  delete input;
  vtkDebugMacro(<<"Boundary mesh created");
  vtkDebugMacro(<<"Boundary mesh created");
  return boundaryMesh;
  return boundaryMesh;
}
}
 Lines 2521-2668    Link Here 
//  returns a requested point zone mesh
//  returns a requested point zone mesh
//
//
// ****************************************************************************
// ****************************************************************************
vtkUnstructuredGrid * vtkOpenFOAMReader::GetPointZoneMesh(int timeState,
bool vtkOpenFOAMReader::GetPointZoneMesh(unstructuredGridVector* pointZoneMesh,
                                                          int pointZoneIndex)
  vtkPoints* points, int timeState)
{
{
  vtkUnstructuredGrid * pointZoneMesh = vtkUnstructuredGrid::New();
  vtkDebugMacro(<<"Create point zone mesh");
  vtkstd::string pointZonesPath = this->PathPrefix->value[timeState]+
                               "/polyMesh/pointZones";
  vtkDebugMacro(<<"Create point zone mesh: "<<pointZonesPath.c_str());
  vtkstd::string temp;
  vtkFoamDict* pointZoneDictPtr
  stdString* tempStringStruct;
    = this->GatherBlocks("pointZones", timeState, false);
  bool binaryWriteFormat;
  ifstream * input = new ifstream(pointZonesPath.c_str(), ios::in VTK_IOS_NOCREATE);
  //make sure file exists
  if(input->fail())
    {
    input->close();
    delete input;
    return pointZoneMesh;
    }
  //determine if file is binary or ascii
  if(pointZoneDictPtr == NULL)
  while(temp.find("format") == vtkstd::string::npos)
    {
    {
    tempStringStruct = this->GetLine(input);
    // not an error
    temp = tempStringStruct->value;
    return true;
    delete tempStringStruct;
    }
    }
  input->close();
  //reopen file in correct format
  vtkFoamDict& pointZoneDict = *pointZoneDictPtr;
  if(temp.find("binary") != vtkstd::string::npos)
  size_t nPointZones = pointZoneDict.size();
    {
#ifdef _WIN32
    input->open(pointZonesPath.c_str(), ios::binary | ios::in VTK_IOS_NOCREATE);
#else
    input->open(pointZonesPath.c_str(), ios::in VTK_IOS_NOCREATE);
#endif
    binaryWriteFormat = true;
    }
  else
    {
    input->open(pointZonesPath.c_str(),ios::in);
    binaryWriteFormat = false;
    }
  vtkstd::string token;
  for(size_t i = 0; i < nPointZones; i++)
  vtksys_ios::stringstream tokenizer;
    {
  vtkVertex * pointCell;
    // look up point labels
  int tempElement;
    vtkFoamDict& dict = pointZoneDict.entry(i).dictionary();
  vtkstd::vector< vtkstd::vector < int > > tempElementZones;
    vtkFoamEntry& pointLabelsEntry = dict.lookup("pointLabels");
  int numElement;
    if(!pointLabelsEntry.found())
  //find desired mesh entry
  while(temp.find(this->PointZoneNames->value[pointZoneIndex]) == 
        vtkstd::string::npos)
    {
    tempStringStruct = this->GetLine(input);
    temp = tempStringStruct->value;
    delete tempStringStruct;
    }
  tempStringStruct = this->GetLine(input);
  temp = tempStringStruct->value;
  delete tempStringStruct;//throw out {
  tempStringStruct = this->GetLine(input);
  temp = tempStringStruct->value;
  delete tempStringStruct;//type
  tempStringStruct = this->GetLine(input);
  temp = tempStringStruct->value;
  delete tempStringStruct;//label
  tempStringStruct = this->GetLine(input);
  temp = tempStringStruct->value;
  delete tempStringStruct;//number of elements or {
  //number of elements
  if(temp.find("}") == vtkstd::string::npos)
    {
    tokenizer << temp;
    tokenizer >> numElement;
    if(numElement == 0)
      {
      {
      input->close();
      vtkErrorMacro(<<"pointLabels not found in pointZones");
      delete input;
      return false;
      return NULL;
      }
      }
    // skip if the list is empty
    //binary data
    if(pointLabelsEntry.firstValue().type() == vtkFoamEntryValue::EMPTYLIST)
    if(binaryWriteFormat)
      {
      {
      input->get(); //parenthesis
      continue;
      for(int j = 0; j < numElement; j++)
        {
        input->read((char *) &tempElement, sizeof(int));
        pointCell = vtkVertex::New();
        pointCell->GetPointIds()->SetId(0,tempElement);
        pointZoneMesh->InsertNextCell(pointCell->GetCellType(),
                                      pointCell->GetPointIds());
        pointCell->Delete();
        }
      }
      }
    if(pointLabelsEntry.firstValue().type() != vtkFoamEntryValue::LABELLIST)
    //ascii data
    else
      {
      {
      tempStringStruct = this->GetLine(input);
      vtkErrorMacro(<<"pointLabels not of type labelList: type = "
      temp = tempStringStruct->value;
        << pointLabelsEntry.firstValue().type());
      delete tempStringStruct;//THROW OUT (
      return false;
      }
      //GET EACH ELEMENT & ADD TO VECTOR
    const vtkstd::vector<int>& labels = pointLabelsEntry.labelList();
      for(int j = 0; j < numElement; j++)
        {
        tempStringStruct = this->GetLine(input);
        temp = tempStringStruct->value;
        delete tempStringStruct;
        tokenizer.clear();
    // allocate new grid: we do not use resize() beforehand since it
        tokenizer << temp;
    // could lead to undefined pointer if we return by error
        tokenizer >> tempElement;
    pointZoneMesh->value.push_back(vtkUnstructuredGrid::New());
        pointCell = vtkVertex::New();
    vtkUnstructuredGrid& pzm = *pointZoneMesh->value.back();
        pointCell->GetPointIds()->SetId(0,tempElement);
        pointZoneMesh->InsertNextCell(pointCell->GetCellType(),
                                      pointCell->GetPointIds());
        pointCell->Delete();
        }
      }
    }
  //there is no entry
    // set pointZone size
  else
    size_t nPoints = labels.size();
    {
    pzm.Allocate(nPoints);
    input->close();
    delete input;
    // insert points
    return NULL;
    for(size_t j = 0; j < nPoints; j++)
      {
      vtkIdType pointLabel = labels[j];
      pzm.InsertNextCell(VTK_VERTEX, 1, &pointLabel);
      }
    pzm.SetPoints(points);
    }
    }
  //set point zone points
  pointZoneMesh->SetPoints(Points);
  delete pointZoneDictPtr;
  input->close();
  delete input;
  vtkDebugMacro(<<"Point zone mesh created");
  vtkDebugMacro(<<"Point zone mesh created");
  return pointZoneMesh;
  return true;
}
}
// ****************************************************************************
// ****************************************************************************
 Lines 2672-2860    Link Here 
//  returns a requested face zone mesh
//  returns a requested face zone mesh
//
//
// ****************************************************************************
// ****************************************************************************
vtkUnstructuredGrid * vtkOpenFOAMReader::GetFaceZoneMesh(int timeState,
bool vtkOpenFOAMReader::GetFaceZoneMesh(
                                                         int faceZoneIndex)
  unstructuredGridVector* faceZoneMesh, intVectorVector* facesPoints,
  vtkPoints* points, int timeState)
{
{
  vtkUnstructuredGrid * faceZoneMesh = vtkUnstructuredGrid::New();
  vtkDebugMacro(<<"Create face zone mesh");
  vtkstd::string faceZonesPath = this->PathPrefix->value +
                                 this->PolyMeshFacesDir->value[timeState] +
                                 "/polyMesh/faceZones";
  vtkDebugMacro(<<"Create face zone mesh: "<<faceZonesPath.c_str());
  vtkstd::string temp;
  stdString* tempStringStruct;
  bool binaryWriteFormat;
  ifstream * input = new ifstream(faceZonesPath.c_str(), ios::in VTK_IOS_NOCREATE);
  //make sure file exists
  if(input->fail())
    {
    input->close();
    delete input;
    return faceZoneMesh;
    }
  //determine if file is binary or ascii
  while(temp.find("format") == vtkstd::string::npos)
    {
    tempStringStruct = this->GetLine(input);
    temp = tempStringStruct->value;
    delete tempStringStruct;
    }
  input->close();
  //reopen file in correct format
  if(temp.find("binary") != vtkstd::string::npos)
    {
#ifdef _WIN32
    input->open(faceZonesPath.c_str(), ios::binary | ios::in VTK_IOS_NOCREATE);
#else
    input->open(faceZonesPath.c_str(), ios::in);
#endif
    binaryWriteFormat = true;
    }
  else
    {
    input->open(faceZonesPath.c_str(),ios::in);
    binaryWriteFormat = false;
    }
  vtkstd::string token;
  vtkFoamDict* faceZoneDictPtr
  vtksys_ios::stringstream tokenizer;
    = this->GatherBlocks("faceZones", timeState, false);
  vtkstd::vector< int > faceZone;
  int tempElement;
  vtkstd::vector< vtkstd::vector < int > > tempElementZones;
  int numElement;
  //find desired mesh entry
  if(faceZoneDictPtr == NULL)
  while(temp.find(this->FaceZoneNames->value[faceZoneIndex]) == 
        vtkstd::string::npos)
    {
    {
    tempStringStruct = this->GetLine(input);
    // not an error
    temp = tempStringStruct->value;
    return true;
    delete tempStringStruct;
    }
    }
  tempStringStruct = this->GetLine(input);
  vtkFoamDict& faceZoneDict = *faceZoneDictPtr;
  temp = tempStringStruct->value;
  size_t nFaceZones = faceZoneDict.size();
  delete tempStringStruct;//throw out {
  tempStringStruct = this->GetLine(input);
  for(size_t i = 0; i < nFaceZones; i++)
  temp = tempStringStruct->value;
  delete tempStringStruct;//type
  tempStringStruct = this->GetLine(input);
  temp = tempStringStruct->value;
  delete tempStringStruct;//label
  tempStringStruct = this->GetLine(input);
  temp = tempStringStruct->value;
  delete tempStringStruct;//number of values or flipmap
  if(temp.find("flipMap") == vtkstd::string::npos)
    {
    {
    //number of elements
    // look up face labels
    tokenizer << temp;
    vtkFoamDict& dict = faceZoneDict.entry(i).dictionary();
    tokenizer >> numElement;
    vtkFoamEntry& faceLabelsEntry = dict.lookup("faceLabels");
    if(numElement == 0)
    if(!faceLabelsEntry.found())
      {
      {
      input->close();
      delete faceZoneDictPtr;
      delete input;
      vtkErrorMacro(<<"faceLabels not found in faceZones");
      return NULL;
      return false;
      }
      }
    // skip if the list is empty
    //binary
    if(faceLabelsEntry.firstValue().type() == vtkFoamEntryValue::EMPTYLIST)
    if(binaryWriteFormat)
      {
      {
      input->get(); //parenthesis
      continue;
      for(int j = 0; j < numElement; j++)
        {
        input->read((char *) &tempElement, sizeof(int));
        faceZone.push_back(tempElement);
        }
      }
      }
    if(faceLabelsEntry.firstValue().type() != vtkFoamEntryValue::LABELLIST)
    //ascii
    else
      {
      {
      //THROW OUT (
      delete faceZoneDictPtr;
      tempStringStruct = this->GetLine(input);
      vtkErrorMacro(<<"faceLabels not of type labelList");
      temp = tempStringStruct->value;
      return false;
      delete tempStringStruct;
      //get each element & add to vector
      for(int j = 0; j < numElement; j++)
        {
        tempStringStruct = this->GetLine(input);
        temp = tempStringStruct->value;
        delete tempStringStruct;
        tokenizer.clear();
        tokenizer << temp;
        tokenizer >> tempElement;
        faceZone.push_back(tempElement);
        }
      }
      }
    }
  //Create the mesh
    const vtkstd::vector<int>& labels = faceLabelsEntry.labelList();
  int k;
  vtkTriangle * triangle;
  vtkQuad * quad;
  vtkPolygon * polygon;
  //LOOP THROUGH EACH FACE
    // allocate new grid: we do not use resize() beforehand since it
  for(int j = 0; j < (int)faceZone.size(); j++)
    // could lead to undefined pointer if we return by error
    {
    faceZoneMesh->value.push_back(vtkUnstructuredGrid::New());
    vtkUnstructuredGrid& fzm = *faceZoneMesh->value.back();
    // set faceZone size
    size_t nFaces = labels.size();
    fzm.Allocate(nFaces);
    //Triangular Face
    // aloocate array for converting int vector to vtkIdType vector:
    if(this->FacePoints->value[faceZone[j]].size() == 3)
    // workaround for 64bit machines
    int maxNFacePoints = 0;
    for(size_t j = 0; j < nFaces; j++)
      {
      {
      triangle = vtkTriangle::New();
      const int nFacePoints = facesPoints->value[labels[j]].size();
      for(k = 0; k < 3; k++)
      if(nFacePoints > maxNFacePoints)
        {
        {
        triangle->GetPointIds()->SetId(k, this->FacePoints->value[
        maxNFacePoints = nFacePoints;
        faceZone[j]][k]);
        }
        }
      faceZoneMesh->InsertNextCell(triangle->GetCellType(),
        triangle->GetPointIds());
      triangle->Delete();
      }
      }
    vtkIdType* facePointsVtkId = new vtkIdType[maxNFacePoints];
    //Quadraic Face
    // insert faces
    else if(this->FacePoints->value[faceZone[j]].size() == 4)
    for(size_t j = 0; j < nFaces; j++)
      {
      {
      quad = vtkQuad::New();
      vtkstd::vector<int>& facePoints = facesPoints->value[labels[j]];
      for(k = 0; k < 4; k++)
      size_t nFacePoints = facePoints.size();
      for(size_t k = 0; k < nFacePoints; k++)
        {
        {
        quad->GetPointIds()->SetId(k,
        facePointsVtkId[k] = facePoints[k];
          this->FacePoints->value[faceZone[j]][k]);
        }
        }
      faceZoneMesh->InsertNextCell(quad->GetCellType(),
        quad->GetPointIds());
      quad->Delete();
      }
    //Polygonal Face
      //triangle
    else
      if(nFacePoints == 3)
      {
        {
      polygon = vtkPolygon::New();
        fzm.InsertNextCell(VTK_TRIANGLE, 3, facePointsVtkId);
      for(k = 0; k < (int)this->FacePoints->value[faceZone[j]].size(); k++)
        }
      // quad
      else if(nFacePoints == 4)
        {
        fzm.InsertNextCell(VTK_QUAD, 4, facePointsVtkId);
        }
      //polygon
      else
        {
        {
        polygon->GetPointIds()->InsertId(k, this->FacePoints->value[
        fzm.InsertNextCell(VTK_POLYGON, nFacePoints,
          faceZone[j]][k]);
          facePointsVtkId);
        }
        }
      faceZoneMesh->InsertNextCell(polygon->GetCellType(),
        polygon->GetPointIds());
      polygon->Delete();
      }
      }
    delete [] facePointsVtkId;
    fzm.SetPoints(points);
    }
    }
  //set the face zone points
  delete faceZoneDictPtr;
  faceZoneMesh->SetPoints(this->Points);
  input->close();
  delete input;
  vtkDebugMacro(<<"Face zone mesh created");
  vtkDebugMacro(<<"Face zone mesh created");
  return faceZoneMesh;
  return true;
}
}
// ****************************************************************************
// ****************************************************************************
 Lines 2864-3491    Link Here 
//  returns a requested cell zone mesh
//  returns a requested cell zone mesh
//
//
// ****************************************************************************
// ****************************************************************************
vtkUnstructuredGrid * vtkOpenFOAMReader::GetCellZoneMesh(int timeState,
bool vtkOpenFOAMReader::GetCellZoneMesh(
                                                         int cellZoneIndex)
  unstructuredGridVector* cellZoneMesh, faceVectorVector* facesOfCell,
  intVectorVector* facesPoints, vtkPoints* points, int timeState)
{
{
  vtkUnstructuredGrid * cellZoneMesh = vtkUnstructuredGrid::New();
  vtkDebugMacro(<<"Create cell zone mesh");
  vtkstd::string cellZonesPath = this->PathPrefix->value +
                                 this->PolyMeshFacesDir->value[timeState] +
                                 "/polyMesh/cellZones";
  vtkDebugMacro(<<"Create cell zone mesh: "<<cellZonesPath.c_str());
  vtkstd::string temp;
  stdString* tempStringStruct;
  bool binaryWriteFormat;
  ifstream * input = new ifstream(cellZonesPath.c_str(), ios::in VTK_IOS_NOCREATE);
  //make sure file exists
  if(input->fail())
    {
    input->close();
    delete input;
    return cellZoneMesh;
    }
  //determine if file is binary or ascii
  while(temp.find("format") == vtkstd::string::npos)
    {
    tempStringStruct = this->GetLine(input);
    temp = tempStringStruct->value;
    delete tempStringStruct;
    }
  input->close();
  //reopen file in correct format
  vtkFoamDict* cellZoneDictPtr
  if(temp.find("binary") != vtkstd::string::npos)
    = this->GatherBlocks("cellZones", timeState, false);
  if(cellZoneDictPtr == NULL)
    {
    {
#ifdef _WIN32
    // not an error
    input->open(cellZonesPath.c_str(), ios::binary | ios::in VTK_IOS_NOCREATE);
    return true;
#else
    input->open(cellZonesPath.c_str(), ios::in VTK_IOS_NOCREATE);
#endif
    binaryWriteFormat = true;
    }
    }
  else
  vtkFoamDict& cellZoneDict = *cellZoneDictPtr;
  size_t nCellZones = cellZoneDict.size();
  for(size_t i = 0; i < nCellZones; i++)
    {
    {
    input->open(cellZonesPath.c_str(),ios::in);
    // look up cell labels
    binaryWriteFormat = false;
    vtkFoamDict& dict = cellZoneDict.entry(i).dictionary();
    vtkFoamEntry& cellLabelsEntry = dict.lookup("cellLabels");
    if(!cellLabelsEntry.found())
      {
      delete cellZoneDictPtr;
      vtkErrorMacro(<<"cellLabels not found in cellZones");
      return false;
      }
    // skip if the list is empty
    if(cellLabelsEntry.firstValue().type() == vtkFoamEntryValue::EMPTYLIST)
      {
      continue;
      }
    if(cellLabelsEntry.firstValue().type() != vtkFoamEntryValue::LABELLIST)
      {
      delete cellZoneDictPtr;
      vtkErrorMacro(<<"cellLabels not of type labelList");
      return false;
      }
    const vtkstd::vector<int>& labels = cellLabelsEntry.labelList();
    // allocate new grid: we do not use resize() beforehand since it
    // could lead to undefined pointer if we return by error
    cellZoneMesh->value.push_back(vtkUnstructuredGrid::New());
    vtkUnstructuredGrid* czm = cellZoneMesh->value.back();
    // set cellZone size
    size_t nCells = labels.size();
    czm->Allocate(nCells);
    // insert cells
    for(size_t j = 0; j < nCells; j++)
      {
      this->InsertCellToGrid(czm, labels[j], facesOfCell, facesPoints);
      }
    //set cell zone points
    cellZoneMesh->value[i]->SetPoints(points);
    }
    }
  vtkstd::string token;
  delete cellZoneDictPtr;
  vtksys_ios::stringstream tokenizer;
  vtkDebugMacro(<<"Cell zone mesh created");
  vtkstd::vector< int > cellZone;
  return true;
  int tempElement;
}
  vtkstd::vector< vtkstd::vector < int > > tempElementZones;
  int numElement;
vtkPolyData* vtkOpenFOAMReader::MakeLagrangianMesh(int timeState)
{
  vtkStdString positionsPath = *this->PathPrefix
    + this->TimeNames->GetValue(timeState) +  "/lagrangian/positions";
  //find desired mesh entry
  vtkFoamIOobject io;
  while(temp.find(this->CellZoneNames->value[cellZoneIndex]) == 
  if(!(io.open(positionsPath) || io.open(positionsPath + ".gz")))
        vtkstd::string::npos)
    {
    vtkErrorMacro(<<"Error opening " << io.fileName().c_str() << ": "
      << io.error().str().c_str());
    return NULL;
    }
  vtkFoamDict dict;
  if(!dict.read(io))
    {
    vtkErrorMacro(<<"Error reading line " << io.lineNumber()
      << " of " << io.fileName().c_str() << ": " << io.error().str().c_str());
    return NULL;
    }
  if(dict.type() != vtkFoamDict::VECTORLIST)
    {
    {
    tempStringStruct = this->GetLine(input);
    vtkErrorMacro(<<"The file type of " << io.fileName().c_str()
    temp = tempStringStruct->value;
      << " is not a vectorList");
    delete tempStringStruct;
    return NULL;
    }
    }
  tempStringStruct = this->GetLine(input);
  temp = tempStringStruct->value;
  delete tempStringStruct;//throw out {
  tempStringStruct = this->GetLine(input);
  vtkDoubleArray& vl = dict.vectorList();
  temp = tempStringStruct->value;
  const vtkIdType nParticles = vl.GetNumberOfTuples();
  delete tempStringStruct;//type
  //instantiate the points class
  vtkPoints* points = vtkPoints::New();
  points->SetNumberOfPoints(nParticles);
  vtkPolyData* lagrangianMesh = vtkPolyData::New();
  lagrangianMesh->Allocate(nParticles);
  tempStringStruct = this->GetLine(input);
  for(vtkIdType i = 0, index = 0; i < nParticles; i++, index += 3)
  temp = tempStringStruct->value;
    {
  delete tempStringStruct;
    points->SetPoint(i, vl.GetPointer(index));
    lagrangianMesh->InsertNextCell(VTK_VERTEX, 1, &i);
    }
  tempStringStruct = this->GetLine(input);
  lagrangianMesh->SetPoints(points);
  temp = tempStringStruct->value;
  points->Delete();
  delete tempStringStruct;
  return lagrangianMesh;
}
  //number of elements
bool vtkOpenFOAMReader::GetLagrangianVariableAtTimestep(
  tokenizer << temp;
  vtkPolyData* lagrangianMesh, const char* varNameIn, int timeState)
  tokenizer >> numElement;
{
  vtkStdString varPath = *this->PathPrefix
    + this->TimeNames->GetValue(timeState) + "/lagrangian/"
    + vtkStdString(varNameIn);
  //binary
  // open the file
  if(binaryWriteFormat)
  vtkFoamIOobject io;
  if(!io.open(varPath))
    {
    {
    input->get(); //parenthesis
    vtkErrorMacro(<<"Error opening " << io.fileName().c_str() << ": "
    for(int j = 0; j < numElement; j++)
      << io.error().str().c_str());
      {
    return false;
      input->read((char *) &tempElement, sizeof(int));
      cellZone.push_back(tempElement);
      }
    }
    }
  //ascii
  // if the variable is disabled on selection panel then skip it
  else
  vtkStdString selectionName
    = vtkStdString("lagrangian/") + io.objectName();
  if(this->PointDataArraySelection->ArrayExists(selectionName.c_str())
    && !this->PointDataArraySelection->ArrayIsEnabled(selectionName.c_str()))
    {
    {
    tempStringStruct = this->GetLine(input);
    return true;
    temp = tempStringStruct->value;
    delete tempStringStruct;//throw out (
    //get each element & add to vector
    for(int j = 0; j < numElement; j++)
      {
      tempStringStruct = this->GetLine(input);
      temp = tempStringStruct->value;
      delete tempStringStruct;
      tokenizer.clear();
      tokenizer << temp;
      tokenizer >> tempElement;
      cellZone.push_back(tempElement);
      }
    }
    }
  //Create the mesh
  // read the field file into dictionary
  bool foundDup = false;
  vtkFoamDict dict;
  vtkstd::vector< int > cellPoints;
  if(!dict.read(io))
  vtkstd::vector< int > tempFaces[2];
    {
  vtkstd::vector< int > firstFace;
    vtkErrorMacro(<<"Error reading line " << io.lineNumber()
  int pivotPoint = 0;
      << " of " << io.fileName().c_str() << ": " << io.error().str().c_str());
  int i, j, k, l, pCount;
    return false;
  int faceCount = 0;
    }
  //Create Mesh
  // set lagrangian values
  for(i = 0; i < (int)cellZone.size(); i++)  //each cell
  if(dict.type() != vtkFoamDict::SCALARLIST
    && dict.type() != vtkFoamDict::VECTORLIST)
    {
    {
    //calculate total points for all faces of a cell
    vtkErrorMacro(<<"Unsupported lagrangian field type");
    //used to determine cell type
    return false;
    int totalPointCount = 0;
    }
    for(j = 0; j < (int)this->FacesOfCell->value[
      cellZone[i]].size(); j++)  //each face
      {
      totalPointCount += (int)this->FacePoints->value[this->FacesOfCell->value[
        cellZone[i]][j].faceIndex].size();
      }
      // using cell type - order points, create cell, add to mesh
  vtkDoubleArray* lData = (vtkDoubleArray *)dict.ptr();
    //OFhex | vtkHexahedron
  // GetNumberOfTuples() works for both scalar and vector
    if (totalPointCount == 24)
  const int nParticles = lData->GetNumberOfTuples();
      {
  if(nParticles != lagrangianMesh->GetNumberOfCells())
      faceCount = 0;
    {
    vtkErrorMacro(<<"Sizes of lagrangian mesh and field don't match");
    return false;
    }
      //get first face
  lData->SetName(selectionName.c_str());
      for(j = 0; j < (int)this->FacePoints->value[this->FacesOfCell->value[
  lagrangianMesh->GetPointData()->AddArray(lData);
        cellZone[i]][0].faceIndex].size(); j++)
  lData->Delete();
        {
        firstFace.push_back(this->FacePoints->value[this->FacesOfCell->value[
  return true;
          cellZone[i]][0].faceIndex][j]);
}
        }
      //-if it is a neighbor face flip it
// return 0 if there's any error, 1 if success
      if(FacesOfCell->value[i][0].neighborFace)
int vtkOpenFOAMReader::CreateDataSet(vtkMultiBlockDataSet *output,
  int timeState)
{
  int oldTimeState = this->OldTimeStep;
  vtkPolyData* lagrangianMesh = NULL;
  bool updateVariables = true;
  // determine if we need to reconstruct meshes
  if(this->CacheMesh && oldTimeState >= 0
    && this->PolyMeshFacesDir->value[timeState]
       == this->PolyMeshFacesDir->value[oldTimeState]
    && this->FaceOwner != NULL
    && this->PatchSelectionStatus == this->PatchSelectionOldStatus)
    {
    if((timeState == oldTimeState) 
       && (this->CellSelectionStatus == this->CellSelectionOldStatus)
       && (this->PointSelectionStatus == this->PointSelectionOldStatus))
      {
      updateVariables = false;
      }
    else
      {
      // clean up arrays of the previous timestep
      // Check if Internal Mesh Exists first...
      if(this->InternalMesh != NULL)
        {
        {
        int tempPop;
        vtkCellData* internalCellData = this->InternalMesh->GetCellData();
        for(k = 0; k < (int)firstFace.size() - 1; k++)
        while(internalCellData->GetArrayName(0))
          {
          {
          tempPop = firstFace[firstFace.size()-1];
          internalCellData->RemoveArray(internalCellData->GetArrayName(0));
          firstFace.pop_back();
          firstFace.insert(firstFace.begin()+1+k, tempPop);
          }
          }
        }
        }
      // Check if Boundary Mesh Exists first...
      //add first face to cell points
      if(this->BoundaryMesh != NULL)
      for(j =0; j < (int)firstFace.size(); j++)
        {
        cellPoints.push_back(firstFace[j]);
        }
      for(int pointCount = 0;pointCount < (int)firstFace.size();pointCount++)
        {
        {
        //find the 2 other faces containing each point - start with face 1
        for(size_t i = 0; i < this->BoundaryMesh->value.size(); i++)
        for(j = 1; j < (int)this->FacesOfCell->value[
          cellZone[i]].size(); j++)  //each face
          {
          {
          for(k = 0; k < (int)this->FacePoints->value[this->FacesOfCell->
          vtkCellData* boundaryCellData
              value[cellZone[i]][j].faceIndex].size(); k++)
            = this->BoundaryMesh->value[i]->GetCellData();
          while(boundaryCellData->GetArrayName(0))
            {
            {
            if(firstFace[pointCount] == this->FacePoints->
            boundaryCellData->RemoveArray(boundaryCellData->GetArrayName(0));
               value[this->FacesOfCell->value[cellZone[i]][j].faceIndex][k])
              {
              //another face with the point
              for(l = 0; l < (int)this->FacePoints->value[this->FacesOfCell->
                                  value[cellZone[i]][j].faceIndex].size(); l++)
                {
                tempFaces[faceCount].push_back(this->FacePoints->value[
                  this->FacesOfCell->value[cellZone[i]][j].faceIndex]
                  [l]);
                }
              faceCount++;
              }
            }
            }
          }
          }
        }
        //locate the pivot point contained in faces 0 & 1
      // if only point coordinates change refresh point vector
        for(j = 0; j < (int)tempFaces[0].size(); j++)
      if(this->PolyMeshPointsDir->value[timeState]
        != this->PolyMeshPointsDir->value[oldTimeState])
        {
        //get the points
        vtkPoints* points = this->GetPoints(timeState);
        if(points == NULL)
          {
          {
          for(k = 0; k < (int)tempFaces[1].size(); k++)
          return 0;
            {
            if(tempFaces[0][j] == tempFaces[1][k] && tempFaces[0][j] !=
              firstFace[pointCount])
              {
              pivotPoint = tempFaces[0][j];
              break;
              }
            }
          }
          }
        cellPoints.push_back(pivotPoint);
        tempFaces[0].clear();
        tempFaces[1].clear();
        faceCount=0;
        }
        //create the hex cell and insert it into the mesh
        // refresh the points in each mesh
        vtkHexahedron * hexahedron = vtkHexahedron::New();
        // Check if Internal Mesh exists first....
        for(pCount = 0; pCount < (int)cellPoints.size(); pCount++)
        if(this->InternalMesh != NULL)
          {
          {
          hexahedron->GetPointIds()->SetId(pCount, cellPoints[pCount]);
          this->InternalMesh->SetPoints(points);
          }
          }
        cellZoneMesh->InsertNextCell(hexahedron->GetCellType(),
        // Check if Boundary Mesh exists first....
                                     hexahedron->GetPointIds());
        if(this->BoundaryMesh != NULL)
        hexahedron->Delete();
        cellPoints.clear();
        firstFace.clear();
        }
    //OFprism | vtkWedge
    else if (totalPointCount == 18)
      {
      faceCount = 0;
      int index = 0;
      //find first triangular face
      for(j = 0; j < (int)this->FacesOfCell->value[
        cellZone[i]].size(); j++)  //each face
        {
        if((int)this->FacePoints->value[this->FacesOfCell->value[
          cellZone[i]][j].faceIndex].size() == 3)
          {
          {
          for(k = 0; k < (int)this->FacePoints->value[this->FacesOfCell->value[
          for(size_t i = 0; i < this->BoundaryMesh->value.size(); i++)
            cellZone[i]][j].faceIndex].size(); k++)
            {
            {
            firstFace.push_back(this->FacePoints->value[this->FacesOfCell->
            this->BoundaryMesh->value[i]->SetPoints(points);
                                  value[cellZone[i]][j].faceIndex][k]);
            index = j;
            }
            }
          break;
          }
          }
        }
        if(this->PointZoneMesh != NULL)
      //-if it is a neighbor face flip it
      if(this->FacesOfCell->value[i][0].neighborFace)
        {
        int tempPop;
        for(k = 0; k < (int)firstFace.size() - 1; k++)
          {
          {
          tempPop = firstFace[firstFace.size()-1];
          for(size_t i = 0; i < this->PointZoneMesh->value.size(); i++)
          firstFace.pop_back();
            {
          firstFace.insert(firstFace.begin()+1+k, tempPop);
            this->PointZoneMesh->value[i]->SetPoints(points);
            }
          }
          }
        }
        if(this->FaceZoneMesh != NULL)
      //add first face to cell points
      for(j =0; j < (int)firstFace.size(); j++)
        {
        cellPoints.push_back(firstFace[j]);
        }
      for(int pointCount = 0;pointCount < (int)firstFace.size();pointCount++)
        {
        //find the 2 other faces containing each point
        for(j = 0; j < (int)this->FacesOfCell->value[
          cellZone[i]].size(); j++)  //each face
          {
          {
          for(k = 0; k < (int)this->FacePoints->value[this->FacesOfCell->value[
          for(size_t i = 0; i < this->FaceZoneMesh->value.size(); i++)
            cellZone[i]][j].faceIndex].size(); k++) //each point
            {
            {
            if(firstFace[pointCount] == this->FacePoints->
            this->FaceZoneMesh->value[i]->SetPoints(points);
               value[this->FacesOfCell->value[cellZone[i]][j].faceIndex][k] &&
               j != index)
              {
              //another face with point
              for(l = 0; l < (int)this->FacePoints->value[this->
                  FacesOfCell->value[cellZone[i]][j].faceIndex].size(); l++)
                {
                tempFaces[faceCount].push_back(this->FacePoints->value[
                  this->FacesOfCell->value[cellZone[i]][j].faceIndex]
                  [l]);
                }
              faceCount++;
              }
            }
            }
          }
          }
        if(this->CellZoneMesh != NULL)
        //locate the pivot point contained in faces 0 & 1
        for(j = 0; j < (int)tempFaces[0].size(); j++)
          {
          {
          for(k = 0; k < (int)tempFaces[1].size(); k++)
          for(size_t i = 0; i < this->CellZoneMesh->value.size(); i++)
            {
            {
            if(tempFaces[0][j] == tempFaces[1][k] && tempFaces[0][j] !=
            this->CellZoneMesh->value[i]->SetPoints(points);
              firstFace[pointCount])
              {
              pivotPoint = tempFaces[0][j];
              break;
              }
            }
            }
          }
          }
        cellPoints.push_back(pivotPoint);
        points->Delete();
        tempFaces[0].clear();
        tempFaces[1].clear();
        faceCount=0;
        }
        }
      }
    }
  else
    {
    this->ClearMeshes();
      //create the wedge cell and insert it into the mesh
    vtkStdString meshDir = *this->PathPrefix
      vtkWedge * wedge = vtkWedge::New();
      + this->PolyMeshFacesDir->value[timeState] + "/polyMesh/";
      for(pCount = 0; pCount < (int)cellPoints.size(); pCount++)
        {
    //create paths to polyMesh files
        wedge->GetPointIds()->SetId(pCount, cellPoints[pCount]);
    vtkStdString facePath = meshDir + "faces";
        }
    vtkStdString ownerPath = meshDir + "owner";
      cellZoneMesh->InsertNextCell(wedge->GetCellType(),
    vtkStdString neighborPath = meshDir + "neighbour";
                                   wedge->GetPointIds());
      cellPoints.clear();
    //create the faces vector
      wedge->Delete();
    intVectorVector* facePoints = this->ReadFacesFile(facePath.c_str());
      firstFace.clear();
    if(facePoints == NULL)
      {
      return 0;
      }
      }
    this->UpdateProgress(0.2);
    //OFpyramid | vtkPyramid
    //read owner/neighbor and create the faces owner/facesOfCell vector
    else if (totalPointCount == 16)
    faceVectorVector* facesOfCell = new faceVectorVector;
    if(!this->ReadOwnerNeighborFiles(facesOfCell, ownerPath.c_str(),
      neighborPath.c_str()))
      {
      {
      foundDup = false;
      delete facePoints;
      delete facesOfCell;
      return 0;
      }
    this->UpdateProgress(0.3);
      //find quad
    //get the points
      for(j = 0; j < (int)this->FacesOfCell->value[
    vtkPoints* points = this->GetPoints(timeState);
        cellZone[i]].size(); j++)  //each face
    if(points == NULL)
        {
      {
        if((int)this->FacePoints->value[this->FacesOfCell->value[
      delete facePoints;
          cellZone[i]][j].faceIndex].size() == 4)
      delete facesOfCell;
          {
      return 0;
          for(k = 0; k < (int)this->FacePoints->value[this->FacesOfCell->value[
      }
            cellZone[i]][j].faceIndex].size(); k++)
    this->UpdateProgress(0.4);
            {
            cellPoints.push_back(this->FacePoints->value[this->FacesOfCell->
              value[cellZone[i]][j].faceIndex][k]);
            }
          break;
          }
        }
      //compare first face points to second faces
    // make internal mesh
      for(j = 0; j < (int)cellPoints.size(); j++) //each point
    // Create Internal Mesh only if required for display
    if(this->GetPatchArrayStatus(GetPatchArrayName(0)))
      {
      this->InternalMesh = this->MakeInternalMesh(facesOfCell, facePoints,
        points);
      }
    else
      {
      if(this->InternalMesh != NULL)
        {
        {
        for(k = 0; k < (int)this->FacePoints->value[this->FacesOfCell->value[
        this->InternalMesh->Delete();
          cellZone[i]][1].faceIndex].size(); k++)
        this->InternalMesh = NULL;
          {
          if(cellPoints[j] == this->FacePoints->value[this->FacesOfCell->value[
            cellZone[i]][1].faceIndex][k])
            {
            foundDup = true;
            }
          }
        if(!foundDup)
          {
          cellPoints.push_back(this->FacePoints->value[this->FacesOfCell->value[
            cellZone[i]][j].faceIndex][k]);
          break;
          }
        }
        }
      }
      //create the pyramid cell and insert it into the mesh
    // read polyMesh/bondary
      vtkPyramid * pyramid = vtkPyramid::New();
    this->BoundaryDict = this->GatherBlocks("boundary", timeState, true);
      for(pCount = 0; pCount < (int)cellPoints.size(); pCount++)
    if(this->BoundaryDict == NULL)
        {
      {
        pyramid->GetPointIds()->SetId(pCount, cellPoints[pCount]);
      delete facePoints;
        }
      delete facesOfCell;
      cellZoneMesh->InsertNextCell(pyramid->GetCellType(),
      points->Delete();
                                   pyramid->GetPointIds());
      vtkErrorMacro("Couldn't read polyMesh/boundary");
      cellPoints.clear();
      return 0;
      pyramid->Delete();
      }
      }
    //OFtet | vtkTetrahedron
    // create boundary mesh
    else if (totalPointCount == 12)
    this->BoundaryMesh = this->GetBoundaryMesh(this->BoundaryDict, facePoints,
      points);
    if(this->BoundaryMesh == NULL)
      {
      {
      foundDup = false;
      delete facePoints;
      delete facesOfCell;
      points->Delete();
      return 0;
      }
      //grab first face
    // read and construct zones
      for(j = 0; j < (int)this->FacePoints->value[this->FacesOfCell->value[
    if(ReadZones)
        cellZone[i]][0].faceIndex].size(); j++)
      {
      this->PointZoneMesh = new unstructuredGridVector;
      if(!this->GetPointZoneMesh(this->PointZoneMesh, points, timeState))
        {
        for(size_t i = 0; i < this->PointZoneMesh->value.size(); i++)
          {
          this->PointZoneMesh->value[i]->Delete();
          }
        delete this->PointZoneMesh;
        this->PointZoneMesh = NULL;
        delete facePoints;
        delete facesOfCell;
        points->Delete();
        return 0;
        }
      if(this->PointZoneMesh->value.size() == 0)
        {
        {
        cellPoints.push_back(this->FacePoints->value[this->FacesOfCell->value[
        delete this->PointZoneMesh;
          cellZone[i]][0].faceIndex][j]);
        this->PointZoneMesh = NULL;
        }
        }
      //compare first face points to second faces
      this->FaceZoneMesh = new unstructuredGridVector;
      for(j = 0; j < (int)cellPoints.size(); j++) //each point
      if(!this->GetFaceZoneMesh(this->FaceZoneMesh, facePoints, points,
        timeState))
        {
        {
        for(k = 0; k < (int)this->FacePoints->value[this->FacesOfCell->value[
        for(size_t i = 0; i < this->FaceZoneMesh->value.size(); i++)
          cellZone[i]][1].faceIndex].size(); k++)
          {
          {
          if(cellPoints[j] == this->FacePoints->value[this->FacesOfCell->value[
          this->FaceZoneMesh->value[i]->Delete();
            cellZone[i]][1].faceIndex][k])
            {
            foundDup = true;
            }
          }
          }
        if(!foundDup)
        delete this->FaceZoneMesh;
        this->FaceZoneMesh = NULL;
        delete facePoints;
        delete facesOfCell;
        points->Delete();
        return 0;
        }
      if(this->FaceZoneMesh->value.size() == 0)
        {
        delete this->FaceZoneMesh;
        this->FaceZoneMesh = NULL;
        }
          
      this->CellZoneMesh = new unstructuredGridVector;
      if(!this->GetCellZoneMesh(this->CellZoneMesh, facesOfCell, facePoints,
         points, timeState))
        {
        for(size_t i = 0; i < this->CellZoneMesh->value.size(); i++)
          {
          {
          cellPoints.push_back(this->FacePoints->value[this->FacesOfCell->value[
          this->CellZoneMesh->value[i]->Delete();
            cellZone[i]][j].faceIndex][k]);
          break;
          }
          }
        delete this->CellZoneMesh;
        this->CellZoneMesh = NULL;
        delete facePoints;
        delete facesOfCell;
        points->Delete();
        return 0;
        }
        }
      if(this->CellZoneMesh->value.size() == 0)
      //create the wedge cell and insert it into the mesh
      vtkTetra * tetra = vtkTetra::New();
      for(pCount = 0; pCount < (int)cellPoints.size(); pCount++)
        {
        {
        tetra->GetPointIds()->SetId(pCount, cellPoints[pCount]);
        delete this->CellZoneMesh;
        this->CellZoneMesh = NULL;
        }
        }
      cellZoneMesh->InsertNextCell(tetra->GetCellType(),
                                   tetra->GetPointIds());
      cellPoints.clear();
      tetra->Delete();
      }
      }
    //erronous cells
    delete facesOfCell;
    else if(totalPointCount == 0)
    delete facePoints;
      {
    points->Delete();
      vtkWarningMacro("Warning: No points in cell.");
    }
      }
  this->UpdateProgress(0.5);
    //OFpolyhedron || vtkConvexPointSet
  if(updateVariables)
    else
    {
    // read field data variables into Internal/Boundary meshes
    for(int i = 0; i < (int)this->TimeStepData->value.size(); i++)
      {
      {
      vtkWarningMacro("Warning: Polyhedral Data is very Slow!");
      if(!this->GetVariableAtTimestep(this->InternalMesh, this->BoundaryMesh,
      foundDup = false;
        this->BoundaryDict, this->TimeStepData->value[i].c_str(), timeState))
      //grab face 0
      for(j = 0; j < (int)this->FacePoints->value[this->FacesOfCell->value[
        cellZone[i]][0].faceIndex].size(); j++)
        {
        {
        firstFace.push_back(this->FacePoints->value[
        // error occurred while reading a field data variable, but continue
          this->FacesOfCell->value[i][0].faceIndex][j]);
        // to the next variable
        continue;
        }
        }
      this->UpdateProgress(0.5
        + 0.5 * ((float)(i + 1) / (float)this->TimeStepData->value.size()));
      }
      //ADD FIRST FACE TO CELL POINTS
    // read lagrangian mesh and fields
      for(j =0; j < (int)firstFace.size(); j++)
    if(this->LagrangianTimeStepData->value.size() > 0
      && this->GetPatchArrayStatus("Lagrangian Particles"))
      {
      // construct lagrangian mesh
      lagrangianMesh = this->MakeLagrangianMesh(timeState);
      if(lagrangianMesh == NULL)
        {
        {
        cellPoints.push_back(firstFace[j]);
        return 0;
        }
        }
      //j = 1 skip firstFace
      for(j = 1; j < (int) this->FacesOfCell->value[
      // read lagrangian variables
           cellZone[i]].size(); j++)
      for(size_t i = 0; i < this->LagrangianTimeStepData->value.size(); i++)
        {
        {
        //remove duplicate points from faces
        if(!this->GetLagrangianVariableAtTimestep(lagrangianMesh,
        for(k = 0; k < (int)this->FacePoints->value[
          this->LagrangianTimeStepData->value[i].c_str(), timeState))
            this->FacesOfCell->value[i][j].faceIndex].size(); k++)
          {
          {
          for(l = 0; l < (int)cellPoints.size(); l++);
          // error occurred while reading a field data variable, but continue
            {
          // to the next variable
            if(cellPoints[l] == this->FacePoints->value[this->FacesOfCell->
          continue;
                                value[cellZone[i]][j].faceIndex][k])
              {
              foundDup = true;
              }
            }
          if(!foundDup)
            {
            cellPoints.push_back(this->FacePoints->value[this->FacesOfCell->
                                 value[cellZone[i]][j].faceIndex][k]);
            foundDup = false;
            }
          }
          }
        }
        }
      }
    }
      //create the poly cell and insert it into the mesh
  // assign group to each of data and point/face/cell-Zones
      vtkConvexPointSet * poly = vtkConvexPointSet::New();
  int nGroups = 1 + ((lagrangianMesh != NULL
      poly->GetPointIds()->SetNumberOfIds(cellPoints.size());
    && lagrangianMesh->GetPointData()->GetNumberOfArrays() > 0) ? 1 : 0)
      for(pCount = 0; pCount < (int)cellPoints.size(); pCount++)
    + (this->PointZoneMesh != NULL ? 1 : 0)
        {
    + (this->FaceZoneMesh != NULL ? 1 : 0)
        poly->GetPointIds()->SetId(pCount, cellPoints[pCount]);
    + (this->CellZoneMesh != NULL ? 1 : 0);
        }
  output->SetNumberOfGroups(nGroups);
      cellZoneMesh->InsertNextCell(poly->GetCellType(),
                                   poly->GetPointIds());
  // set internal mesh/data as output
      cellPoints.clear();
  //output->SetNumberOfDataSets(0,output->GetNumberOfDataSets(0));
      firstFace.clear();
      poly->Delete();
  // Add Internal Mesh to final output only if selected for display
  if(GetPatchArrayStatus(GetPatchArrayName(0)))
    {
    output->SetDataSet(0, output->GetNumberOfDataSets(0), this->InternalMesh);
    }
  // set boundary meshes/data as output
  for(size_t j = 0; j < this->BoundaryMesh->value.size(); j++)
    {
    output->SetDataSet(0, output->GetNumberOfDataSets(0),
      this->BoundaryMesh->value[j]);
    if(!this->CacheMesh)
      {
      this->BoundaryMesh->value[j]->Delete();
      }
      }
    }
    }
  //set cell zone points
  cellZoneMesh->SetPoints(Points);
  input->close();
  delete input;
  vtkDebugMacro(<<"Cell zone mesh created");
  return cellZoneMesh;
}
void vtkOpenFOAMReader::CreateDataSet(vtkMultiBlockDataSet *output)
  if(!this->CacheMesh)
{
    {
  int timeState = this->TimeStep;
    // First check if these meshes exist before deleting them....
  //create paths to polyMesh files
    if(this->BoundaryMesh != NULL)
  vtkstd::string boundaryPath = this->PathPrefix->value +
                                this->PolyMeshFacesDir->value[timeState] +
                                "/polyMesh/boundary";
  vtkstd::string facePath = this->PathPrefix->value +
                            this->PolyMeshFacesDir->value[timeState] +
                            "/polyMesh/faces";
  vtkstd::string ownerPath = this->PathPrefix->value +
                             this->PolyMeshFacesDir->value[timeState] +
                             "/polyMesh/owner";
  vtkstd::string neighborPath = this->PathPrefix->value +
                                this->PolyMeshFacesDir->value[timeState] +
                                "/polyMesh/neighbour";
  //create the faces vector
  this->ReadFacesFile(facePath.c_str());
  //create the faces owner vector
  this->ReadOwnerFile(ownerPath.c_str());
  //create the faces neighbor vector
  this->ReadNeighborFile(neighborPath.c_str());
  //create a vector containing a faces of each cell
  this->CombineOwnerNeigbor();
  this->GetPoints(timeState); //get the points
  //get the names of the regions
  //this->BoundaryNames->value =
  //  this->GatherBlocks("boundary", timeState)->value;
  //this->PointZoneNames->value =
  //  this->GatherBlocks("pointZones", timeState)->value;
  //this->FaceZoneNames->value =
  //  this->GatherBlocks("faceZones", timeState)->value;
  //this->CellZoneNames->value =
  //  this->GatherBlocks("cellZones", timeState)->value;
  //get the names of the regions
  this->BoundaryNames =
    this->GatherBlocks("boundary", timeState);
  this->PointZoneNames =
    this->GatherBlocks("pointZones", timeState);
  this->FaceZoneNames =
    this->GatherBlocks("faceZones", timeState);
  this->CellZoneNames =
    this->GatherBlocks("cellZones", timeState);
  int numBoundaries = this->BoundaryNames->value.size();
  int numPointZones = this->PointZoneNames->value.size();
  int numFaceZones = this->FaceZoneNames->value.size();
  int numCellZones = this->CellZoneNames->value.size();
  //Internal Mesh
  vtkUnstructuredGrid * internalMesh = this->MakeInternalMesh();
  for(int i = 0; i < (int)this->TimeStepData->value.size(); i++)
    {
    vtkDoubleArray * data =
      this->GetInternalVariableAtTimestep(this->TimeStepData->value[i].c_str(),
                                          timeState);
    if(data->GetSize() > 0)
      {
      {
      data->SetName(this->TimeStepData->value[i].c_str());
      delete this->BoundaryMesh;
      internalMesh->GetCellData()->AddArray(data);
      this->BoundaryMesh = NULL;
      }
      }
    data->Delete();
    if(this->InternalMesh != NULL)
      {
      this->InternalMesh->Delete();
      this->InternalMesh = NULL;
      }
    delete this->BoundaryDict;
    this->BoundaryDict = NULL;
    this->FaceOwner->Delete();
    this->FaceOwner = NULL;
    }
    }
  //output->SetNumberOfDataSets(0,output->GetNumberOfDataSets(0));
  output->SetDataSet(0, output->GetNumberOfDataSets(0), internalMesh);
  //Boundary Meshes
  int groupI = 0;
  for(int i = 0; i < (int)numBoundaries; i++)
  // set lagrangian mesh as output
  if(lagrangianMesh != NULL
    && lagrangianMesh->GetPointData()->GetNumberOfArrays() > 0)
    {
    {
    vtkUnstructuredGrid * boundaryMesh = this->GetBoundaryMesh(timeState, i);
    groupI++;
    for(int j = 0; j < (int)this->TimeStepData->value.size(); j++)
    output->SetDataSet(groupI, output->GetNumberOfDataSets(groupI),
      lagrangianMesh);
    lagrangianMesh->Delete();
    }
  // set Zone Meshes as output
  if(this->PointZoneMesh != NULL)
    {
    groupI++;
    for(size_t i = 0; i < this->PointZoneMesh->value.size(); i++)
      {
      {
      vtkDoubleArray * data =
      output->SetDataSet(groupI, output->GetNumberOfDataSets(groupI),
        this->GetBoundaryVariableAtTimestep(i, TimeStepData->value[j].c_str(),
        this->PointZoneMesh->value[i]);
                                            timeState, internalMesh);
      if(!this->CacheMesh)
      if(data->GetSize() > 0)
        {
        {
        data->SetName(this->TimeStepData->value[j].c_str());
        this->PointZoneMesh->value[i]->Delete();
        boundaryMesh->GetCellData()->AddArray(data);
        }
        }
      data->Delete();
      }
      }
    output->SetDataSet(0, output->GetNumberOfDataSets(0), boundaryMesh);
    if(!this->CacheMesh)
    boundaryMesh->Delete();
      {
      delete this->PointZoneMesh;
      this->PointZoneMesh = NULL;
      }
    }
    }
  internalMesh->Delete();
  if(this->FaceZoneMesh != NULL)
  this->FaceOwner->Delete();
  //Zone Meshes
  for(int i = 0; i < (int)numPointZones; i++)
    {
    {
    vtkUnstructuredGrid * pointMesh = this->GetPointZoneMesh(timeState, i);
    groupI++;
    output->SetDataSet(0, output->GetNumberOfDataSets(0),
    for(size_t i = 0; i < this->FaceZoneMesh->value.size(); i++)
                       pointMesh);
      {