Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 202685 | Differences between
and this patch

Collapse All | Expand All

(-)ParaView3.orig/Servers/ServerManager/Resources/readers.xml (-57 / +116 lines)
Lines 3412-3474 Link Here
3412
   </SourceProxy>
3412
   </SourceProxy>
3413
3413
3414
    <!-- Beginning of FOAM Reader -->
3414
    <!-- Beginning of FOAM Reader -->
3415
    <SourceProxy name="OpenFOAMReader" 
3415
    <SourceProxy
3416
                    class="vtkOpenFOAMReader">
3416
3417
      <StringVectorProperty name="FileName"
3417
        name="OpenFOAMReader" 
3418
                            command="SetFileName"
3418
        class="vtkOpenFOAMReader"
3419
                            animateable="0"
3419
	output="vtkDataSet">
3420
                            number_of_elements="1">
3420
3421
        <FileListDomain name="files"/>
3421
       <StringVectorProperty
3422
        <Documentation>
3422
           name="FileName"
3423
          Set the file name for the OpenFOAM reader.
3423
           command="SetFileName"
3424
        </Documentation>
3424
           number_of_elements="1">
3425
      </StringVectorProperty>
3425
           <FileListDomain name="files"/>
3426
      <StringVectorProperty name="CellArrayInfo"
3426
        </StringVectorProperty>
3427
                            information_only="1">
3427
3428
        <ArraySelectionInformationHelper attribute_name="Cell"/>
3428
	<IntVectorProperty 
3429
      </StringVectorProperty>
3429
           name="CacheMesh" 
3430
      <StringVectorProperty name="CellArrayStatus"
3430
           command="SetCacheMesh" 
3431
                            command="SetCellArrayStatus"
3431
           number_of_elements="1"
3432
                            number_of_elements="0" 
3432
           default_values="1">
3433
                            repeat_command="1"
3433
           <BooleanDomain name="bool"/>
3434
                            number_of_elements_per_command="2"
3434
                <Documentation>
3435
                            element_types="2 0" 
3435
                   Cache the OpenFOAM mesh between GUI selection changes.
3436
                            information_property="CellArrayInfo"
3436
                </Documentation>
3437
                            label="Cell Arrays">
3437
        </IntVectorProperty>
3438
        <ArraySelectionDomain name="array_list">
3438
3439
          <RequiredProperties>
3439
        <IntVectorProperty name="ReadZones" 
3440
            <Property name="CellArrayInfo" function="ArrayList"/>
3440
                           command="SetReadZones"
3441
          </RequiredProperties>
3441
                           number_of_elements="1" 
3442
        </ArraySelectionDomain>
3442
                           default_values="0"
3443
        <Documentation>
3443
                           label="Read Zones">
3444
          Select which cell-centered arrays to read.
3444
          <BooleanDomain name="bool"/>
3445
        </Documentation>
3445
          <Documentation>
3446
      </StringVectorProperty>
3446
            Read point/face/cell-Zones?
3447
      <IntVectorProperty name="TimeStepRangeInfo"
3447
          </Documentation>
3448
                         command="GetTimeStepRange"
3448
        </IntVectorProperty>
3449
                         information_only="1">
3449
3450
        <SimpleIntInformationHelper/>
3450
	    <IntVectorProperty name="AccumulatePatches" 
3451
      </IntVectorProperty>
3451
			       command="SetKeepPatches"
3452
      <IntVectorProperty name="TimeStep"
3452
			       number_of_elements="1" 
3453
                           command="SetTimeStep"
3453
			       default_values="1"
3454
                           number_of_elements="1"
3454
			       label="Accumulate Patches to Selection List">
3455
                           animateable="1"
3455
		    <BooleanDomain name="bool"/>
3456
                           default_values="0">
3456
		    <Documentation>
3457
        <IntRangeDomain name="range">
3457
			    Accumulate patches into selection list across time-steps even if they stop existing
3458
          <RequiredProperties>
3458
		    </Documentation>
3459
            <Property name="TimeStepRangeInfo" function="Range"/>
3459
	    </IntVectorProperty>
3460
          </RequiredProperties>
3460
3461
        </IntRangeDomain>
3461
	<DoubleVectorProperty
3462
        <Documentation>
3462
           name="TimestepValues"
3463
          Set the current timestep.
3463
	   repeatable="1"
3464
        </Documentation>
3464
	   information_only="1">
3465
      </IntVectorProperty>
3465
           <TimeStepsInformationHelper/>
3466
      <DoubleVectorProperty 
3466
        </DoubleVectorProperty>
3467
          name="TimestepValues"
3467
3468
          repeatable="1"
3468
	<StringVectorProperty 
3469
          information_only="1">
3469
            name="PatchArrayInfo"
3470
        <TimeStepsInformationHelper/>
3470
            information_only="1">
3471
      </DoubleVectorProperty>
3471
            <ArraySelectionInformationHelper attribute_name="Patch"/>
3472
	</StringVectorProperty>
3473
	<StringVectorProperty
3474
            name="MeshRegions"
3475
            command="SetPatchArrayStatus"
3476
            number_of_elements="0" 
3477
            repeat_command="1"
3478
            number_of_elements_per_command="2"
3479
            element_types="2 0"
3480
            information_property="PatchArrayInfo">
3481
            <ArraySelectionDomain name="array_list">
3482
                <RequiredProperties>
3483
                    <Property name="PatchArrayInfo"
3484
                        function="ArrayList"/>
3485
                    </RequiredProperties>
3486
            </ArraySelectionDomain>
3487
        </StringVectorProperty>
3488
	
3489
        <StringVectorProperty 
3490
            name="CellArrayInfo"
3491
            information_only="1">
3492
            <ArraySelectionInformationHelper attribute_name="Cell"/>
3493
        </StringVectorProperty>
3494
        <StringVectorProperty
3495
            name="CellArrays"
3496
            command="SetCellArrayStatus"
3497
            number_of_elements="0" 
3498
            repeat_command="1"
3499
            number_of_elements_per_command="2"
3500
            element_types="2 0"
3501
    	    information_property="CellArrayInfo">
3502
            <ArraySelectionDomain name="array_list">
3503
                <RequiredProperties>
3504
                    <Property name="CellArrayInfo"
3505
                        function="ArrayList"/>
3506
                </RequiredProperties>
3507
            </ArraySelectionDomain>
3508
        </StringVectorProperty>
3509
3510
        <StringVectorProperty 
3511
            name="PointArrayInfo"
3512
            information_only="1">
3513
            <ArraySelectionInformationHelper attribute_name="Point"/>
3514
        </StringVectorProperty>
3515
        <StringVectorProperty
3516
            name="PointArrays"
3517
            command="SetPointArrayStatus"
3518
            number_of_elements="0" 
3519
            repeat_command="1"
3520
            number_of_elements_per_command="2"
3521
            element_types="2 0"
3522
	        information_property="PointArrayInfo">
3523
            <ArraySelectionDomain name="array_list">
3524
                <RequiredProperties>
3525
                    <Property name="PointArrayInfo"
3526
                        function="ArrayList"/>
3527
                </RequiredProperties>
3528
            </ArraySelectionDomain>
3529
        </StringVectorProperty>
3530
3472
    </SourceProxy>
3531
    </SourceProxy>
3473
    <!-- End of foam Reader -->
3532
    <!-- End of foam Reader -->
3474
3533
(-)ParaView3.orig/VTK/IO/vtkOpenFOAMReader.cxx (-2654 / +4395 lines)
Lines 16-26 Link Here
16
// Technology Laboratory who developed this class.
16
// Technology Laboratory who developed this class.
17
// Please address all comments to Terry Jordan (terry.jordan@sa.netl.doe.gov)
17
// Please address all comments to Terry Jordan (terry.jordan@sa.netl.doe.gov)
18
//
18
//
19
// Token-based FoamFile format lexer/parser, performance enhancements,
20
// gzipped file and lagrangian field support by Takuya Oshima
21
// (oshima@eng.niigata-u.ac.jp)
22
//
23
// * GUI Based selection of mesh regions and fields available in the case
24
// * Minor bug fixes / Strict memory allocation checks
25
// * Minor performance enhancements
26
// by Philippose Rajan (sarith@rocketmail.com)
27
19
#include "vtkOpenFOAMReader.h"
28
#include "vtkOpenFOAMReader.h"
20
29
30
#include <vtksys/ios/sstream>
21
#include <vtkstd/string>
31
#include <vtkstd/string>
22
#include <vtkstd/vector>
32
#include <vtkstd/vector>
23
#include <vtksys/ios/sstream>
33
#include <vtk_zlib.h>
24
34
25
#include "vtkInformation.h"
35
#include "vtkInformation.h"
26
#include "vtkInformationVector.h"
36
#include "vtkInformationVector.h"
Lines 28-37 Link Here
28
#include "vtkDataArraySelection.h"
38
#include "vtkDataArraySelection.h"
29
#include "vtkStreamingDemandDrivenPipeline.h"
39
#include "vtkStreamingDemandDrivenPipeline.h"
30
#include "vtkCellArray.h"
40
#include "vtkCellArray.h"
41
#include "vtkCallbackCommand.h"
31
#include "vtkDataArraySelection.h"
42
#include "vtkDataArraySelection.h"
32
#include "vtkIntArray.h"
43
#include "vtkIntArray.h"
33
#include "vtkFloatArray.h"
34
#include "vtkDoubleArray.h"
44
#include "vtkDoubleArray.h"
45
#include "vtkStringArray.h"
46
#include "vtkSortDataArray.h"
35
#include "vtkPoints.h"
47
#include "vtkPoints.h"
36
#include "vtkCellData.h"
48
#include "vtkCellData.h"
37
#include "vtkHexahedron.h"
49
#include "vtkHexahedron.h"
Lines 48-90 Link Here
48
#include "vtkUnstructuredGridAlgorithm.h"
60
#include "vtkUnstructuredGridAlgorithm.h"
49
#include "vtkObjectFactory.h"
61
#include "vtkObjectFactory.h"
50
#include "vtkDirectory.h"
62
#include "vtkDirectory.h"
63
#include "vtkPolyData.h"
64
#include "vtkPointData.h"
65
#include "vtkPVConfig.h" // for PARAVIEW_VERSION_MAJOR
51
66
52
#include <ctype.h>
67
#include <ctype.h>
53
#include <sys/stat.h>
68
#include <sys/stat.h>
54
69
70
#if 0
55
#ifdef VTK_USE_ANSI_STDLIB
71
#ifdef VTK_USE_ANSI_STDLIB
56
#define VTK_IOS_NOCREATE
72
#define VTK_IOS_NOCREATE
57
#else
73
#else
58
#define VTK_IOS_NOCREATE | ios::nocreate
74
#define VTK_IOS_NOCREATE | ios::nocreate
59
#endif
75
#endif
76
#endif
77
78
// The input buffer size in bytes. The purpose of the buffering is to
79
// reduce the number of costly gzread() calls so the buffer size
80
// doesn't have to be large.
81
#define VTK_FOAMFILE_BUFSIZE (2048)
82
83
// If the macro is set to 1 fast (but inaccurate) string to floating
84
// point number conversion routine is used instead of the system
85
// strtod(). This affects about 15% in performance for ascii cases.
86
#define VTK_FOAMFILE_FAST_STRTOD 1
60
87
61
vtkCxxRevisionMacro(vtkOpenFOAMReader, "$Revision: 1.10 $");
88
vtkCxxRevisionMacro(vtkOpenFOAMReader, "$Revision: 1.7.2.2 $");
62
vtkStandardNewMacro(vtkOpenFOAMReader);
89
vtkStandardNewMacro(vtkOpenFOAMReader);
63
90
64
struct stdString
91
struct stringVector
65
{
92
{
66
  vtkstd::string value;
93
  vtkstd::vector< vtkStdString > value;
67
};
94
};
68
95
69
struct stringVector
96
struct intVector
97
{
98
  vtkstd::vector< int > value;
99
};
100
101
struct doubleVector
102
{
103
  vtkstd::vector<double> value;
104
};
105
106
struct intVectorVector
107
{
108
  vtkstd::vector< vtkstd::vector< int > > value;
109
};
110
111
struct faceVectorVector
112
{
113
  vtkstd::vector< vtkstd::vector< face > > value;
114
};
115
116
struct unstructuredGridVector
117
{
118
  vtkstd::vector<vtkUnstructuredGrid*> value;
119
};
120
121
struct vtkOpenFOAMReader::vtkFoamError
122
{
123
private:
124
  vtkStdString str_;
125
public:
126
  vtkFoamError(): str_() {}
127
  vtkFoamError(vtkFoamError& e): str_(e.str()) {}
128
  const vtkStdString str() const { return str_; }
129
  // a super-easy way to make use of operator<<()'s defined in
130
  // vtkstd::ostringstream class
131
  template <class T> vtkFoamError& operator<<(const T& t)
132
  { vtkstd::ostringstream os; os << t; str_ += os.str(); return *this; }
133
};
134
135
// token class
136
// based on src/OpenFOAM/db/IOstreams/token/{token|tokenI}.H
137
// a word token is treated as a string token.
138
struct vtkOpenFOAMReader::vtkFoamToken
70
{
139
{
71
  vtkstd::vector< vtkstd::string > value;
140
public:
141
  enum tokenType { UNDEFINED, PUNCTUATION, STRING, LABEL, SCALAR, ERROR };
142
private:
143
  tokenType type_;
144
145
  vtkFoamToken(const vtkFoamToken&);
146
  void clear() { if(type_ == STRING) delete stringTokenPtr_; }
147
148
public:
149
  union
150
  {
151
    char punctuationToken_; vtkStdString* stringTokenPtr_; int labelToken_;
152
    double scalarToken_;
153
  };
154
155
  vtkFoamToken(): type_(UNDEFINED) {}
156
  ~vtkFoamToken() { clear(); }
157
  void setBad() { clear(); type_ = ERROR; }
158
  tokenType type() const { return type_; }
159
  bool isNumber() const { return type_ == LABEL || type_ == SCALAR; }
160
161
  char punctuationToken() const { return punctuationToken_; }
162
  int labelToken() const { return labelToken_; }
163
  double number() const
164
  { if(type_ == LABEL) return labelToken_; else return scalarToken_; }
165
  const vtkStdString& stringToken() const
166
  { return *stringTokenPtr_; }
167
168
  void operator=(const char c)
169
  { clear(); type_ = PUNCTUATION; punctuationToken_ = c; }
170
  void operator=(const char *s)
171
  { clear(); type_ = STRING; stringTokenPtr_ = new vtkStdString(s); }
172
  void operator=(const vtkStdString& s)
173
  { clear(); type_ = STRING; stringTokenPtr_ = new vtkStdString(s); }
174
  void operator=(const int l)
175
  { clear(); type_ = LABEL; labelToken_ = l; }
176
  void operator=(const double d)
177
  { clear(); type_ = SCALAR; scalarToken_ = d; }
178
  bool operator==(const char c) const
179
  { return type_ == PUNCTUATION && punctuationToken_ == c; }
180
  bool operator==(const int i) const
181
  { return type_ == LABEL && labelToken_ == i; }
182
  bool operator==(const vtkStdString& str) const
183
  { return type_ == STRING && *stringTokenPtr_ == str; }
184
  bool operator!=(const vtkStdString& str) const
185
  { return type_ != STRING || *stringTokenPtr_ != str; }
186
  bool operator!=(const char c) const { return !operator==(c); }
187
188
  friend vtkstd::ostringstream& operator<<(vtkstd::ostringstream& str,
189
    const vtkFoamToken& t)
190
  {
191
    if(t.type() == PUNCTUATION)
192
      {
193
      str << t.punctuationToken_;
194
      }
195
    else if(t.type() == STRING)
196
      {
197
      str << *t.stringTokenPtr_;
198
      }
199
    else if(t.type() == LABEL)
200
      {
201
      str << t.labelToken_;
202
      }
203
    else if(t.type() == SCALAR)
204
      {
205
      str << t.scalarToken_;
206
      }
207
    else if(t.type() == ERROR)
208
      {
209
      str << "badToken (an unexpected EOF?)";
210
      }
211
    return str;
212
  }
72
};
213
};
73
214
74
struct intVector
215
// read and tokenize the input
216
// line number counting is based on
217
// src/OpenFOAM/db/IOstreams/Sstreams/ISstreamI.H
218
struct vtkOpenFOAMReader::vtkFoamFile
219
{
220
private:
221
  gzFile file_;
222
  bool putBack_;
223
  int putBackC_;
224
  int lineNumber_;
225
226
  // buffer pointers. using raw pointers for performance reason.
227
  unsigned char *buf_;
228
  unsigned char *bufPtr_;
229
  unsigned char *bufEndPtr_;
230
231
  // declare and define as private
232
  void putBack(const int c)
233
  {
234
    if(putBack_)
235
      {
236
      throw vtkFoamError() << "Attempted duplicated putBack()";
237
      }
238
    else
239
      {
240
      if(c == '\n')
241
        {
242
        lineNumber_--;
243
        }
244
      *--bufPtr_ = c;
245
      putBack_ = true;
246
      }
247
  }
248
249
  // get a character
250
  int getc()
251
  {
252
    putBack_ = false;
253
    if(bufPtr_ == bufEndPtr_)
254
      {
255
      bufPtr_ = buf_ + 1; // reserve the first byte for getback char
256
      const int readSize = gzread(file_, bufPtr_, VTK_FOAMFILE_BUFSIZE - 1);
257
      if(readSize <= 0) // 0 byte read or EOF
258
        {
259
        // set the current location to the end of the buffer so that
260
        // getc() returns EOF again when called next time
261
        bufPtr_ = bufEndPtr_;
262
        return EOF;
263
        }
264
      bufEndPtr_ = bufPtr_ + readSize;
265
      }
266
    const int c = *bufPtr_++;
267
    if(c == '\n')
268
      {
269
      lineNumber_++;
270
      }
271
    return c;
272
  }
273
274
  // get next semantically valid character
275
  // based on src/OpenFOAM/db/IOstreams/Sstream/ISnextValid.C
276
  int nextValid()
277
  {
278
    int c;
279
    for(;;)
280
      {
281
      if((c = getc()) != EOF && isspace(c))
282
        {
283
        while((c = getc()) != EOF && isspace(c));
284
        }
285
      if(c == '/')
286
        {
287
        if((c = getc()) == EOF)
288
          {
289
          return '/';
290
          }
291
        if(c == '/') // one-line comment
292
          {
293
          while(EOF != (c = getc()) && c != '\n' && c != '\r');
294
          }
295
        else if(c == '*') // multi-line comment
296
          {
297
          for(;;)
298
            {
299
            if((c = getc()) == '*')
300
              {
301
              if((c = getc()) == '/')
302
                {
303
                break;
304
                }
305
              else if(c == EOF)
306
                {
307
                return EOF;
308
                }
309
              else
310
                {
311
                putBack(c);
312
                }
313
              }
314
            else if(c == EOF)
315
              {
316
              return EOF;
317
              }
318
            }
319
          }
320
        else
321
          {
322
          putBack(c);
323
          return '/';
324
          }
325
        }
326
      else // a valid character or an EOF
327
        {
328
        return c;
329
        }
330
      }
331
  }
332
333
  // valid as a character that constitutes a word or not
334
  // based on src/OpenFOAM/primitives/strings/word/wordI.H
335
  bool valid(const int c) const
336
  {
337
    return (!isspace(c) && c != '"' && c != '/' && c != ';' && c != '{'
338
      && c != '}');
339
  }
340
341
public:
342
  vtkFoamFile(): file_(NULL), putBack_(false), putBackC_(0), lineNumber_(0),
343
    buf_(NULL) {}
344
  ~vtkFoamFile() { close(); }
345
346
  void open(const vtkStdString& path)
347
  {
348
    lineNumber_ = 0;
349
350
    buf_ = new unsigned char[VTK_FOAMFILE_BUFSIZE];
351
    bufPtr_ = buf_;
352
    bufEndPtr_ = buf_;
353
354
    if(file_ != NULL)
355
      {
356
      throw vtkFoamError() << "File already opened";
357
      }
358
    if((file_ = gzopen(path.c_str(), "rb")) == NULL)
359
      {
360
      throw vtkFoamError() << "Can't open";
361
      }
362
363
    lineNumber_ = 1;
364
  }
365
366
  void close()
367
  {
368
    if(buf_ != NULL)
369
      {
370
      delete [] buf_;
371
      buf_ = NULL;
372
      }
373
    putBack_ = false;
374
    putBackC_ = 0;
375
    if(file_ != NULL)
376
      {
377
      gzclose(file_);
378
      file_ = NULL;
379
      }
380
    // don't reset the line number so that the last line number is
381
    // retained after close
382
    // lineNumber_ = 0;
383
  }
384
385
  int lineNumber() const { return lineNumber_; }
386
387
  // gzread with buffering handling
388
  int read(char *buf, const int len)
389
  {
390
    int readlen;
391
    const int buflen = bufEndPtr_ - bufPtr_;
392
    if(len > buflen)
393
      {
394
      memcpy(buf, bufPtr_, buflen);
395
      readlen = gzread(file_, buf + buflen, len - buflen);
396
      if(readlen >= 0)
397
        {
398
        readlen += buflen;
399
        }
400
      else
401
        {
402
        if(buflen == 0) // return EOF
403
          {
404
          readlen = -1;
405
          }
406
        else
407
          {
408
          readlen = buflen;
409
          }
410
        }
411
      bufPtr_ = bufEndPtr_;
412
      }
413
    else
414
      {
415
      memcpy(buf, bufPtr_, len);
416
      bufPtr_ += len;
417
      readlen = len;
418
      }
419
    for(int i = 0; i < readlen; i++)
420
      {
421
      if(buf[i] == '\n')
422
        {
423
        lineNumber_++;
424
        }
425
      }
426
    return readlen;
427
  }
428
429
  // the tokenizer
430
  // based on src/OpenFOAM/db/IOstreams/Sstreams/{ISreadToken|ISread}.C
431
  // returns true if success, false if encountered EOF
432
  bool read(vtkFoamToken& token)
433
  {
434
    int c = nextValid();
435
    if(c == EOF)
436
      {
437
      token.setBad();
438
      return false;
439
      }
440
    switch(c)
441
      {
442
      case ';': case '(': case ')': case '{': case '}': case '[': case ']':
443
      case ':': case ',': case '=': case '+': case '*': case '/':
444
        // punctuation token
445
        token = (char)c;
446
        return true;
447
      case '-': case '.': case '0': case '1': case '2': case '3': case '4':
448
      case '5': case '6': case '7': case '8': case '9':
449
        // number token
450
        {
451
        const int MAX_NUM = 100;
452
        static char numberBuffer[MAX_NUM];
453
        bool isScalar = false;
454
        if(c == '.')
455
          {
456
          isScalar = true;
457
          }
458
        int i = 0, isDigit;
459
        numberBuffer[i++] = c;
460
        while(EOF != (c = getc()) && i < MAX_NUM && ((isDigit = isdigit(c))
461
          || c == '.' || c == 'e' || c == 'E' || c == '+' || c == '-'))
462
          {
463
          numberBuffer[i++] = c;
464
          if(!isDigit)
465
            {
466
            isScalar = true;
467
            }
468
          }
469
        if(i == MAX_NUM)
470
          {
471
          if(c != EOF)
472
            {
473
            putBack(c);
474
            }
475
          numberBuffer[MAX_NUM - 1] = '\0';
476
          token.setBad();
477
          throw vtkFoamError() << "Reached the maximum allowed number length";
478
          }
479
        numberBuffer[i] = '\0';
480
        if(c != EOF)
481
          {
482
          putBack(c);
483
          if(i == 1 && numberBuffer[0] == '-')
484
            {
485
            token = '-';
486
            }
487
          else if(isScalar)
488
            {
489
            token = strtod(numberBuffer, NULL);
490
            }
491
          else
492
            {
493
            token = static_cast<int>(strtol(numberBuffer, NULL, 10));
494
            }
495
          return true;
496
          }
497
        else
498
          {
499
          throw vtkFoamError() << "Encountered EOF while tokenizing a number";
500
          }
501
        }
502
      case '"':
503
        // string token
504
        {
505
        const int MAX_STR = 1024;
506
        static char stringBuffer[MAX_STR];
507
        int i = 0;
508
        bool escape = false;
509
        while((c = getc()) != EOF)
510
          {
511
          if(c == '"' && !escape)
512
            {
513
            stringBuffer[i] = '\0';
514
            token = stringBuffer;
515
            return true;
516
            }
517
          if((c == '\n' || c == '\r') && !escape)
518
            {
519
            stringBuffer[i] = '\0';
520
            token = stringBuffer;
521
            throw vtkFoamError() << "Found a newline while reading string \""
522
                << stringBuffer << "\"";
523
            }
524
          if(c == '\\')
525
            {
526
            escape = true;
527
            }
528
          else
529
            {
530
            escape = false;
531
            stringBuffer[i] = c;
532
            if(++i == MAX_STR)
533
              {
534
              stringBuffer[MAX_STR - 1] = '\0';
535
              token = stringBuffer;
536
              throw vtkFoamError()
537
                << "Reached the maximum allowed string length";
538
              }
539
            }
540
          }
541
        stringBuffer[i] = '\0';
542
        token = stringBuffer;
543
        throw vtkFoamError() << "Encountered EOF while reading string";
544
        }
545
      default:
546
        // parses as a word token, but gives the STRING type for simplicity
547
        {
548
        putBack(c);
549
        const int MAX_WORD = 1024;
550
        static char wordBuffer[MAX_WORD];
551
        int i = 0;
552
        int bc = 0;
553
        while((EOF != (c = getc())) && valid(c))
554
          {
555
          if(i >= MAX_WORD)
556
            {
557
            wordBuffer[MAX_WORD - 1] = '\0';
558
            token = wordBuffer;
559
            throw vtkFoamError() << "Reached the maximum allowed word length.";
560
            }
561
          if(c == '(')
562
            {
563
            bc++;
564
            }
565
          else if(c == ')')
566
            {
567
            bc--;
568
            if(bc == -1)
569
              {
570
              break;
571
              }
572
            }
573
          wordBuffer[i++] = c;
574
          }
575
        if(i == 0)
576
          {
577
          token.setBad();
578
          throw vtkFoamError() << "Invalid first character as a token";
579
          }
580
        wordBuffer[i] = '\0';
581
        token = wordBuffer;
582
        if(c != EOF)
583
          {
584
          putBack(c);
585
          }
586
        return true;
587
        }
588
      }
589
  }
590
591
  void readExpecting(const char c)
592
  {
593
    vtkFoamToken t;
594
    if(!read(t))
595
      {
596
      throw vtkFoamError() << "Unexpected EOF";
597
      }
598
    if(t != c)
599
      {
600
      throw vtkFoamError() << "Expected punctuation token " << c << ", found "
601
        << t;
602
      }
603
  }
604
605
  void readExpecting(const char* str)
606
  {
607
    vtkFoamToken t;
608
    if(!read(t))
609
      {
610
      throw vtkFoamError() << "Unexpected EOF";
611
      }
612
    if(t != str)
613
      {
614
      throw vtkFoamError() << "Expected string \"" << str << "\", found " << t;
615
      }
616
  }
617
618
  // specialized for reading an integer value.
619
  // not using the standard strtol() for speed reason.
620
  int readLabel()
621
  {
622
    int c = nextValid();
623
624
    bool negative = false;
625
    if(c == '-')
626
      {
627
      negative = true;
628
      c = getc();
629
      }
630
631
    if(!isdigit(c))
632
      {
633
      throw vtkFoamError()
634
        << "Expected an integer, found a non-digit character" << (char)c;
635
      }
636
637
    int num = c - '0';
638
    while(EOF != (c = getc()) && isdigit(c))
639
      {
640
      num = 10 * num + c - '0';
641
      }
642
643
    if(c == EOF)
644
      {
645
      throw vtkFoamError() << "Encountered EOF while reading integer";
646
      }
647
    putBack(c);
648
649
    return negative ? -num : num;
650
  }
651
652
#if VTK_FOAMFILE_FAST_STRTOD
653
  // extreamely simplified high-performing string to floating point
654
  // conversion code based on
655
  // ParaView3/VTK/Utilities/vtksqlite/vtk_sqlite3.c
656
  double readNumber()
657
  {
658
    int c = nextValid();
659
660
    // determine sign
661
    bool negative = false;
662
    if(c == '-')
663
      {
664
      negative = true;
665
      c = getc();
666
      }
667
668
    if(c == EOF || (!isdigit(c) && c != '.' && c != 'e' && c != 'E'))
669
      {
670
      throw vtkFoamError()
671
        << "Expected a number, found a non-digit character" << (char)c;
672
      }
673
674
    // read integer part
675
    long double num = 0.0;
676
    while(c != EOF && isdigit(c))
677
      {
678
      num = num * 10.0 + (c - '0');
679
      c = getc();
680
      }
681
682
    // read decimal part
683
    if(c == '.')
684
      {
685
      long double divisor = 1.0;
686
687
      c = getc();
688
      while(c != EOF && isdigit(c))
689
        {
690
        num = num * 10.0 + (c - '0');
691
        divisor *= 10.0;
692
        c = getc();
693
        }
694
      num /= divisor;
695
      }
696
697
    // read exponent part
698
    if(c == 'e' || c == 'E')
699
      {
700
      int esign = 1;
701
      int eval = 0;
702
      long double scale = 1.0;
703
704
      c = getc();
705
      if(c == '-')
706
        {
707
        esign = -1;
708
        c = getc();
709
        }
710
      else if(c == '+')
711
        {
712
        c = getc();
713
        }
714
715
      while(c != EOF && isdigit(c))
716
        {
717
        eval = eval * 10 + c - '0';
718
        c = getc();
719
        }
720
721
      // fast exponent multiplication!
722
      while(eval >= 64)
723
        {
724
        scale *= 1.0e+64;
725
        eval -= 64;
726
        }
727
      while(eval >= 16)
728
        {
729
        scale *= 1.0e+16;
730
        eval -= 16;
731
        }
732
      while(eval >= 4)
733
        {
734
        scale *= 1.0e+4;
735
        eval -= 4;
736
        }
737
      while(eval >= 1)
738
        {
739
        scale *= 1.0e+1;
740
        eval -= 1;
741
        }
742
743
      if(esign < 0)
744
        {
745
        num /= scale;
746
        }
747
      else
748
        {
749
        num *= scale;
750
        }
751
      }
752
753
    if(c == EOF)
754
      {
755
      throw vtkFoamError() << "Unexpected EOF";
756
      }
757
    putBack(c);
758
759
    return static_cast<double>(negative ? -num : num);
760
  }
761
#else
762
  // specialized for reading a scalar value
763
  double readNumber()
764
  {
765
    int c = nextValid();
766
    if(c == EOF || (!isdigit(c) && c != '-' && c != '.'))
767
      {
768
      if(c == EOF)
769
        {
770
        throw vtkFoamError() << "Unexpected EOF";
771
        }
772
      else
773
        {
774
        throw vtkFoamError() << "Expected a number, found " << (char)c;
775
        }
776
      }
777
778
    const int MAX_NUM = 100;
779
    static char numberBuffer[MAX_NUM];
780
    int i = 0;
781
    numberBuffer[i++] = c;
782
    if(EOF != (c = getc()) && i < MAX_NUM && (isdigit(c)
783
      || c == '.' || c == 'e' || c == 'E')) // signs do not come as a 2nd char
784
      {
785
      numberBuffer[i++] = c;
786
      while(EOF != (c = getc()) && i < MAX_NUM && (isdigit(c)
787
        || c == '.' || c == 'e' || c == 'E' || c == '+' || c == '-'))
788
        {
789
        numberBuffer[i++] = c;
790
        }
791
      }
792
    if(i == MAX_NUM)
793
      {
794
      throw vtkFoamError() << "Reached the maximum allowed number length";
795
      }
796
    numberBuffer[i] = '\0';
797
    if(c == EOF)
798
      {
799
      throw vtkFoamError() << "Unexpected EOF";
800
      }
801
    else
802
      {
803
      putBack(c);
804
      if(i == 1 && numberBuffer[0] == '-')
805
        {
806
        throw vtkFoamError() << "Expected a number, found a minus sign";
807
        }
808
      }
809
    return strtod(numberBuffer, NULL);
810
  }
811
#endif
812
};
813
814
// IOobject class
815
// holds file handle, file format, name of the object the file holds and
816
// type of the object.
817
struct vtkOpenFOAMReader::vtkFoamIOobject: public vtkFoamFile
818
{
819
public:
820
  enum fileFormat { UNDEFINED, ASCII, BINARY };
821
822
private:
823
  vtkStdString fileName_;
824
  fileFormat format_;
825
  vtkStdString objectName_;
826
  vtkStdString headerClassName_;
827
  vtkFoamError* e_;
828
829
  void readHeader(); // defined later
830
public:
831
  vtkFoamIOobject(): vtkFoamFile(), format_(UNDEFINED), e_(NULL) {}
832
  ~vtkFoamIOobject() { close(); }
833
834
  bool open(const vtkStdString& file)
835
  {
836
    fileName_ = file;
837
    try
838
      {
839
      vtkFoamFile::open(file);
840
      }
841
    catch(vtkFoamError& e)
842
      {
843
      e_ = new vtkFoamError(e);
844
      return false;
845
      }
846
847
    try
848
      {
849
      readHeader();
850
      }
851
    catch(vtkFoamError& e)
852
      {
853
      vtkFoamFile::close();
854
      e_ = new vtkFoamError(e);
855
      return false;
856
      }
857
    e_ = NULL;
858
    return true;
859
  }
860
861
  void close()
862
  {
863
    vtkFoamFile::close();
864
    format_ = UNDEFINED;
865
    objectName_.erase();
866
    headerClassName_.erase();
867
    if(e_ != NULL)
868
      {
869
      delete e_;
870
      }
871
  }
872
  const vtkStdString& fileName() { return fileName_; }
873
  const fileFormat format() const { return format_; }
874
  const vtkStdString& className() const { return headerClassName_; }
875
  const vtkStdString& objectName() const { return objectName_; }
876
  const vtkFoamError& error() const { return *e_; }
877
  void setError(vtkFoamError& e)
878
  { if(e_ != NULL) delete e_; e_ = new vtkFoamError(e); }
879
};
880
881
// a class that represents a value of a dictionary entry that corresponds to
882
// its keyword. note that an entry can have more than one value.
883
struct vtkOpenFOAMReader::vtkFoamEntryValue
884
{
885
public:
886
  enum entryValueType
887
    {
888
    UNDEFINED, PUNCTUATION, STRING, LABEL, SCALAR, STRINGLIST, LABELLIST,
889
    LABELLISTLIST, SCALARLIST, VECTORLIST, ENTRYVALUELIST, EMPTYLIST,
890
    DICTIONARY, ERROR
891
    };
892
893
private:
894
  entryValueType type_;
895
  bool isUniform_;
896
  bool managed_;
897
898
  // don't pack them into a union
899
  vtkFoamToken t_;
900
  vtkstd::vector<vtkFoamEntryValue*> entryValuePtrs_;
901
902
  union
903
  {
904
    intVector *labelListPtr_; vtkDoubleArray *scalarListPtr_, *vectorListPtr_;
905
    stringVector *stringListPtr_; intVectorVector *labelListListPtr_;
906
    vtkFoamDict *dictPtr_;
907
  };
908
909
  void clear();
910
  void readList(vtkFoamIOobject& io);
911
912
public:
913
  vtkFoamEntryValue(): type_(UNDEFINED), isUniform_(false), managed_(true),
914
    labelListPtr_(NULL) {}
915
  ~vtkFoamEntryValue() { clear(); }
916
917
  entryValueType type() const { return type_; }
918
  void setEmptyList() { clear(); isUniform_ = false; type_ = EMPTYLIST; }
919
  bool isUniform() const { return isUniform_; }
920
  void read(vtkFoamIOobject& io);
921
  void readDictionary(vtkFoamIOobject& io,
922
    const vtkStdString& firstKeyword = "");
923
  const vtkFoamToken& token() const { return t_; }
924
  vtkFoamToken& token() { return t_; }
925
  const vtkstd::vector<int>& labelList() const
926
  { return labelListPtr_->value; }
927
  const vtkstd::vector<vtkstd::vector<int> >& labelListList() const
928
  { return labelListListPtr_->value; }
929
  vtkDoubleArray& scalarList()
930
  { return *scalarListPtr_; }
931
  vtkDoubleArray& vectorList()
932
  { return *vectorListPtr_; }
933
  vtkFoamDict& dictionary()
934
  { return *dictPtr_; }
935
  bool operator==(const char c) const
936
  { return type_ == PUNCTUATION && t_ == c; }
937
  bool operator!=(const char c) const
938
  { return type_ != PUNCTUATION || t_ != c; }
939
  bool operator==(const int i) const
940
  { return type_ == LABEL && t_ == i; }
941
942
  void *ptr()
943
  {
944
    managed_ = false; // the returned pointer will not be deleted by the d'tor
945
    return (void *)labelListPtr_; // all list pointers are in a single union
946
  }
947
948
  // the following two are for an exceptional expression of
949
  // `LABEL{LABELorSCALAR}' without type prefix (e. g. `2{-0}' in
950
  // mixedRhoE B.C. in rhopSonicFoam/shockTube)
951
  void makeLabelList(const int labelValue, const int size)
952
  {
953
    labelListPtr_ = new intVector;
954
    type_ = LABELLIST;
955
    vtkstd::vector<int>& ll = labelListPtr_->value;
956
    ll.resize(size);
957
    for(int i = 0; i < size; i++)
958
      {
959
      ll[i] = labelValue;
960
      }
961
  }
962
  void makeScalarList(const double scalarValue, const int size)
963
  {
964
    scalarListPtr_ = vtkDoubleArray::New();
965
    type_ = SCALARLIST;
966
    vtkDoubleArray& sl = *scalarListPtr_;
967
    sl.SetNumberOfValues(size);
968
    for(vtkIdType i = 0; i < size; i++)
969
      {
970
      sl.SetValue(i, scalarValue);
971
      }
972
  }
973
974
  // read a labelList
975
  void readLabelList(vtkFoamIOobject& io)
976
  {
977
    vtkFoamToken currToken;
978
    if(!io.read(currToken))
979
      {
980
      throw vtkFoamError() << "Unexpected EOF";
981
      }
982
    labelListPtr_ = new intVector;
983
    type_ = LABELLIST;
984
    if(currToken.type() == vtkFoamToken::LABEL)
985
      {
986
      const int size = currToken.labelToken();
987
      labelListPtr_->value.resize(size);
988
      if(!io.read(currToken))
989
        {
990
        throw vtkFoamError() << "Unexpected EOF";
991
        }
992
      vtkstd::vector<int>& ll = labelListPtr_->value;
993
      // some objects have lists with only one element enclosed by {}
994
      // e. g. simpleFoam/pitzDaily3Blocks/constant/polyMesh/faceZones
995
      if(currToken == '{')
996
        {
997
        int labelValue = io.readLabel();
998
        for(int i = 0; i < size; i++)
999
          {
1000
          ll[i] = labelValue;
1001
          }
1002
        io.readExpecting('}');
1003
        return;
1004
        }
1005
      if(currToken != '(')
1006
        {
1007
        throw vtkFoamError() << "Expected (, found " << currToken;
1008
        }
1009
      if(io.format() == vtkFoamIOobject::ASCII)
1010
        {
1011
        for(int i = 0; i < size; i++)
1012
          {
1013
          ll[i] = io.readLabel();
1014
          }
1015
        }
1016
      else
1017
        {
1018
        if(size > 0) // avoid invalid access to ll.at(0)
1019
          {
1020
          io.read(reinterpret_cast<char*>(&ll.at(0)), size * sizeof(int));
1021
          }
1022
        }
1023
      io.readExpecting(')');
1024
      }
1025
    else if(currToken == '(')
1026
      {
1027
      while(io.read(currToken) && currToken != ')')
1028
        {
1029
        if(currToken.type() != vtkFoamToken::LABEL)
1030
          {
1031
          throw vtkFoamError() << "Expected an integer or a (, found "
1032
            << currToken;
1033
          }
1034
        labelListPtr_->value.push_back(currToken.labelToken());
1035
        }
1036
      }
1037
    else
1038
      {
1039
      throw vtkFoamError() << "Expected integer or (, found " << currToken;
1040
      }
1041
  }
1042
1043
  // reads a list of labelLists. requires size prefix of the listList
1044
  // to be present. size of the list must be present in the stream if
1045
  // the format is binary.
1046
  void readLabelListList(vtkFoamIOobject& io)
1047
  {
1048
    vtkFoamToken currToken;
1049
    if(!io.read(currToken))
1050
      {
1051
      throw vtkFoamError() << "Unexpected EOF";
1052
      }
1053
    if(currToken.type() == vtkFoamToken::LABEL)
1054
      {
1055
      labelListListPtr_ = new intVectorVector;
1056
      type_ = LABELLISTLIST;
1057
1058
      const int sizeI = currToken.labelToken();
1059
      labelListListPtr_->value.resize(sizeI);
1060
      io.readExpecting('(');
1061
      for(int i = 0; i < sizeI; i++)
1062
        {
1063
        if(!io.read(currToken))
1064
          {
1065
          throw vtkFoamError() << "Unexpected EOF";
1066
          }
1067
        if(currToken.type() == vtkFoamToken::LABEL)
1068
          {
1069
          const int sizeJ = currToken.labelToken();
1070
          labelListListPtr_->value[i].resize(sizeJ);
1071
          io.readExpecting('(');
1072
          vtkstd::vector<int>& labelListI = labelListListPtr_->value[i];
1073
          if(io.format() == vtkFoamIOobject::ASCII)
1074
            {
1075
            for(int j = 0; j < sizeJ; j++)
1076
              {
1077
              labelListI[j] = io.readLabel();
1078
              }
1079
            }
1080
          else
1081
            {
1082
            if(sizeJ > 0) // avoid invalid reference to labelListI.at(0)
1083
              {
1084
              io.read(reinterpret_cast<char*>(&labelListI.at(0)),
1085
                sizeJ * sizeof(int));
1086
              }
1087
            }
1088
          io.readExpecting(')');
1089
          }
1090
        else if(currToken == '(')
1091
          {
1092
          while(io.read(currToken) && currToken != ')')
1093
            {
1094
            if(currToken.type() != vtkFoamToken::LABEL)
1095
              {
1096
              throw vtkFoamError() << "Expected an integer, found "
1097
                << currToken;
1098
              }
1099
            labelListListPtr_->value[i].push_back(currToken.labelToken());
1100
            }
1101
          }
1102
        else
1103
          {
1104
          throw vtkFoamError() << "Expected integer or (, found " << currToken;
1105
          }
1106
        }
1107
      io.readExpecting(')');
1108
      }
1109
    else
1110
      {
1111
      throw vtkFoamError() << "Expected integer, found " << currToken;
1112
      }
1113
  }
1114
1115
  // reads a scalarList. requires size prefix of the list to be
1116
  // present in the stream if the format is binary.
1117
  void readScalarList(vtkFoamIOobject& io)
1118
  {
1119
    vtkFoamToken currToken;
1120
    if(!io.read(currToken))
1121
      {
1122
      throw vtkFoamError() << "Unexpected EOF";
1123
      }
1124
    scalarListPtr_ = vtkDoubleArray::New();
1125
    type_ = SCALARLIST;
1126
    if(currToken.type() == vtkFoamToken::LABEL)
1127
      {
1128
      const vtkIdType size = currToken.labelToken();
1129
      scalarListPtr_->SetNumberOfValues(size);
1130
      if(!io.read(currToken))
1131
        {
1132
        throw vtkFoamError() << "Unexpected EOF";
1133
        }
1134
      vtkDoubleArray& sl = *scalarListPtr_;
1135
      // some objects have lists with only one element enclosed by {}
1136
      // to represent a field with an uniform value
1137
      if(currToken == '{')
1138
        {
1139
        double scalarValue = io.readNumber();
1140
        for(vtkIdType i = 0; i < size; i++)
1141
          {
1142
          sl.SetValue(i, scalarValue);
1143
          }
1144
        io.readExpecting('}');
1145
        return;
1146
        }
1147
      if(currToken != '(')
1148
        {
1149
        throw vtkFoamError() << "Expected (, found " << currToken;
1150
        }
1151
      if(io.format() == vtkFoamIOobject::ASCII)
1152
        {
1153
        for(vtkIdType i = 0; i < size; i++)
1154
          {
1155
          sl.SetValue(i, io.readNumber());
1156
          }
1157
        }
1158
      else
1159
        {
1160
        if(size > 0) // avoid invalid access to GetPointer(0)
1161
          {
1162
          io.read(reinterpret_cast<char*>(sl.GetPointer(0)),
1163
            size * sizeof(double));
1164
          }
1165
        }
1166
      io.readExpecting(')');
1167
      }
1168
    else if(currToken == '(')
1169
      {
1170
      while(io.read(currToken) && currToken != ')')
1171
        {
1172
        if(!io.read(currToken) || !currToken.isNumber())
1173
          {
1174
          throw vtkFoamError() << "Expected an integer or a (, found "
1175
            << currToken;
1176
          }
1177
        scalarListPtr_->InsertNextValue(currToken.number());
1178
        }
1179
      scalarListPtr_->Squeeze();
1180
      }
1181
    else
1182
      {
1183
      throw vtkFoamError() << "Expected integer or (, found " << currToken;
1184
      }
1185
  }
1186
1187
  // reads a vectorList. requires size prefix of the list to be
1188
  // present in the stream if the format is binary.
1189
  // if isPositions is true read Cloud type of data as particle positions
1190
  // based on src/lagrangian/basic/particle/particleIO.C
1191
  void readVectorList(vtkFoamIOobject& io, const bool isPositions)
1192
  {
1193
    vtkFoamToken currToken;
1194
    if(!io.read(currToken))
1195
      {
1196
      throw vtkFoamError() << "Unexpected EOF";
1197
      }
1198
    vectorListPtr_ = vtkDoubleArray::New();
1199
    vectorListPtr_->SetNumberOfComponents(3);
1200
    type_ = VECTORLIST;
1201
    if(currToken.type() == vtkFoamToken::LABEL)
1202
      {
1203
      const int size = currToken.labelToken();
1204
      vectorListPtr_->SetNumberOfTuples(size);
1205
      if(!io.read(currToken))
1206
        {
1207
        throw vtkFoamError() << "Unexpected EOF";
1208
        }
1209
      // some objects may have a vector list with one element enclosed by {}
1210
      if(currToken == '{')
1211
        {
1212
        io.readExpecting('(');
1213
        double vectorValue[3];
1214
        vectorValue[0] = io.readNumber();
1215
        vectorValue[1] = io.readNumber();
1216
        vectorValue[2] = io.readNumber();
1217
        for(int i = 0; i < size; i++)
1218
          {
1219
          vectorListPtr_->SetTuple(i, vectorValue);
1220
          }
1221
        io.readExpecting(')');
1222
        if(isPositions)
1223
          {
1224
          // skip label celli
1225
          io.readLabel();
1226
          }
1227
        io.readExpecting('}');
1228
        return;
1229
        }
1230
1231
      if(currToken != '(')
1232
        {
1233
        throw vtkFoamError() << "Expected (, found " << currToken;
1234
        }
1235
      if(io.format() == vtkFoamIOobject::ASCII)
1236
        {
1237
        if(size > 0) // avoid invalid access to GetPointer(0)
1238
          {
1239
          double* vectorComponentI = vectorListPtr_->GetPointer(0);
1240
          for(int i = 0; i < size; i++)
1241
            {
1242
            io.readExpecting('(');
1243
            *vectorComponentI++ = io.readNumber();
1244
            *vectorComponentI++ = io.readNumber();
1245
            *vectorComponentI++ = io.readNumber();
1246
            io.readExpecting(')');
1247
            if(isPositions)
1248
              {
1249
              // skip label celli
1250
              io.readLabel();
1251
              }
1252
            }
1253
          }
1254
        }
1255
      else // binary
1256
        {
1257
        if(isPositions) // lagrangian/positions (class Cloud)
1258
          {
1259
          if(size > 0) // avoid invalid access to GetPointer()
1260
            {
1261
            for(int i = 0, index = 0; i < size; i++, index += 3)
1262
              {
1263
              io.readExpecting('(');
1264
              io.read(reinterpret_cast<char*>(vectorListPtr_
1265
                ->GetPointer(index)), sizeof(double) * 3);
1266
1267
              // skip label celli, label facei and scalar stepFraction
1268
              const int dummySize = 2 * sizeof(int) + sizeof(double);
1269
              char dummyBuf[dummySize];
1270
              io.read(dummyBuf, dummySize);
1271
              io.readExpecting(')');
1272
              }
1273
            }
1274
          }
1275
        else // regular vectorField
1276
          {
1277
          if(size > 0) // avoid invalid access to GetPointer()
1278
            {
1279
            io.read(reinterpret_cast<char*>(vectorListPtr_->GetPointer(0)),
1280
              size * sizeof(double) * 3);
1281
            }
1282
          }
1283
        }
1284
      io.readExpecting(')');
1285
      }
1286
    else if(currToken == '(')
1287
      {
1288
      while(io.read(currToken) && currToken != ')')
1289
        {
1290
        if(currToken != '(')
1291
          {
1292
          throw vtkFoamError() << "Expected (, found " << currToken;
1293
          }
1294
        double v[3];
1295
        v[0] = io.readNumber();
1296
        v[1] = io.readNumber();
1297
        v[2] = io.readNumber();
1298
        vectorListPtr_->InsertNextTuple(v);
1299
        io.readExpecting(')');
1300
        }
1301
      vectorListPtr_->Squeeze();
1302
      }
1303
    else
1304
      {
1305
      throw vtkFoamError() << "Expected integer or (, found " << currToken;
1306
      }
1307
  }
1308
1309
  const vtkFoamEntryValue& operator>>(vtkStdString& str) const
1310
  {
1311
    if(type_ == STRING)
1312
      {
1313
      str = vtkStdString(t_.stringToken());
1314
      }
1315
    else
1316
      {
1317
      //vtkErrorMacro("token type does not match");
1318
      str = "";
1319
      }
1320
    return *this;
1321
  }
1322
1323
  const vtkFoamEntryValue& operator>>(double& d) const
1324
  {
1325
    if(type_ == SCALAR || type_ == LABEL)
1326
      {
1327
      d = t_.number();
1328
      }
1329
    else
1330
      {
1331
      //vtkErrorMacro("token type does not match");
1332
      d = 0.0;
1333
      }
1334
    return *this;
1335
  }
1336
1337
  const vtkFoamEntryValue& operator>>(int& i) const
1338
  {
1339
    if(type_ == LABEL)
1340
      {
1341
      i = t_.labelToken();
1342
      }
1343
    else
1344
      {
1345
      //vtkErrorMacro("token type does not match");
1346
      i = 0;
1347
      }
1348
    return *this;
1349
  }
1350
};
1351
1352
// a class that represents an entry of a dictionary. note that an
1353
// entry can have more than one value.
1354
struct vtkOpenFOAMReader::vtkFoamEntry
1355
{
1356
private:
1357
  vtkStdString keyword_;
1358
  vtkstd::vector<vtkFoamEntryValue*> valuePtrs_;
1359
1360
public:
1361
  vtkFoamEntry() {}
1362
  ~vtkFoamEntry()
1363
  {
1364
    for(size_t i = 0; i < valuePtrs_.size(); i++)
1365
      {
1366
      delete valuePtrs_[i];
1367
      }
1368
  }
1369
1370
  vtkStdString& keyword() { return keyword_; }
1371
  size_t size() const { return valuePtrs_.size(); }
1372
  // returns false if the number of the values is 0 to simplify things
1373
  bool found() const { return valuePtrs_.size() > 0; }
1374
  vtkFoamEntryValue& firstValue() const { return *valuePtrs_[0]; }
1375
  const vtkstd::vector<int>& labelList() const
1376
  { return firstValue().labelList(); }
1377
  const vtkstd::vector<vtkstd::vector<int> >& labelListList() const
1378
  { return firstValue().labelListList(); }
1379
  vtkDoubleArray& scalarList()
1380
  { return firstValue().scalarList(); }
1381
  vtkDoubleArray& vectorList()
1382
  { return firstValue().vectorList(); }
1383
  vtkFoamDict& dictionary() // not using firstValue() for breaking constness
1384
  { return valuePtrs_[0]->dictionary(); }
1385
  void *ptr() { return firstValue().ptr(); }
1386
1387
  void readDictionary(vtkFoamIOobject& io)
1388
  {
1389
    valuePtrs_.push_back(new vtkFoamEntryValue);
1390
    valuePtrs_.back()->readDictionary(io);
1391
  }
1392
1393
  // read values of an entry
1394
  void read(vtkFoamIOobject& io);
1395
1396
  const vtkFoamEntry& operator>>(vtkStdString& str) const
1397
  {
1398
    if(!found() || valuePtrs_[0]->type() != vtkFoamEntryValue::STRING)
1399
      {
1400
      str = "";
1401
      }
1402
    else
1403
      {
1404
      valuePtrs_[0]->operator>>(str);
1405
      }
1406
    return *this;
1407
  }
1408
1409
  const vtkFoamEntry& operator>>(double& d) const
1410
  {
1411
    if(!found() || (valuePtrs_[0]->type() != vtkFoamEntryValue::SCALAR
1412
      && valuePtrs_[0]->type() != vtkFoamEntryValue::LABEL))
1413
      {
1414
      d = 0.0;
1415
      }
1416
    else
1417
      {
1418
      valuePtrs_[0]->operator>>(d);
1419
      }
1420
    return *this;
1421
  }
1422
1423
  const vtkFoamEntry& operator>>(int& i) const
1424
  {
1425
    if(!found() || valuePtrs_[0]->type() != vtkFoamEntryValue::LABEL)
1426
      {
1427
      i = 0;
1428
      }
1429
    else
1430
      {
1431
      valuePtrs_[0]->operator>>(i);
1432
      }
1433
    return *this;
1434
  }
1435
};
1436
1437
// a class that holds a FoamFile data structure
1438
struct vtkOpenFOAMReader::vtkFoamDict: public vtkFoamEntryValue
1439
{
1440
public:
1441
  enum dictType
1442
    { UNDEFINED, DICTIONARY, SCALARLIST, VECTORLIST, LABELLIST, LABELLISTLIST,
1443
      UNIFORMLABELLIST, UNIFORMSCALARLIST };
1444
1445
private:
1446
  dictType type_;
1447
  vtkstd::vector<vtkFoamEntry*> entryPtrs_;
1448
  vtkFoamEntry* dummyEntryPtr_;
1449
1450
  vtkFoamDict(const vtkFoamDict &);
1451
1452
public:
1453
  vtkFoamDict(): vtkFoamEntryValue(), type_(UNDEFINED), dummyEntryPtr_(NULL) {}
1454
  ~vtkFoamDict()
1455
  {
1456
    if(type_ == DICTIONARY)
1457
      {
1458
      for(size_t i = 0; i < entryPtrs_.size(); i++)
1459
        {
1460
        delete entryPtrs_[i];
1461
        }
1462
      }
1463
    if(dummyEntryPtr_ != NULL)
1464
      {
1465
      delete dummyEntryPtr_;
1466
      }
1467
  }
1468
1469
  dictType type() const { return type_; }
1470
  size_t size() const { return entryPtrs_.size(); }
1471
  vtkFoamEntry& entry(const int i) { return *entryPtrs_[i]; }
1472
  vtkFoamEntry& lookup(const vtkStdString& keyword)
1473
  {
1474
    if(type_ == DICTIONARY)
1475
      {
1476
      for(size_t i = 0; i < entryPtrs_.size(); i++)
1477
        {
1478
        if(entryPtrs_[i]->keyword() == keyword) // found
1479
          {
1480
          return *entryPtrs_[i];
1481
          }
1482
        }
1483
      }
1484
1485
    // not found
1486
    if(dummyEntryPtr_ == NULL)
1487
      {
1488
      dummyEntryPtr_ = new vtkFoamEntry;
1489
      }
1490
    return *dummyEntryPtr_;
1491
  }
1492
1493
  // reads a FoamFile or a subdictionary. if the stream to be read is
1494
  // a subdictionary the preceding '{' is assumed to have already been
1495
  // thrown away.
1496
  bool read(vtkFoamIOobject& io, const bool isSubDictionary = false,
1497
    const vtkStdString& firstKeyword = "")
1498
  {
1499
    try
1500
      {
1501
      vtkFoamToken currToken;
1502
      if(firstKeyword == "")
1503
        {
1504
        if(!isSubDictionary)
1505
          {
1506
          // polyMesh/points, lagrangian vectors
1507
          if(io.className() == "vectorField")
1508
            {
1509
            readVectorList(io, false);
1510
            type_ = VECTORLIST;
1511
            return true;
1512
            }
1513
          else if(io.className() == "scalarField") // lagrangian scalars
1514
            {
1515
            readScalarList(io);
1516
            type_ = SCALARLIST;
1517
            return true;
1518
            }
1519
          else if(io.className() == "Cloud") // lagrangian/positions
1520
            {
1521
            readVectorList(io, true);
1522
            type_ = VECTORLIST;
1523
            return true;
1524
            }
1525
          else if(io.className() == "faceList") // polyMesh/faces
1526
            {
1527
            readLabelListList(io);
1528
            type_ = LABELLISTLIST;
1529
            return true;
1530
            }
1531
          else if(io.className() == "labelList") // polyMesh/{owner|neighbour}
1532
            {
1533
            readLabelList(io);
1534
            type_ = LABELLIST;
1535
            return true;
1536
            }
1537
          }
1538
1539
        // read the first token
1540
        if(!io.read(currToken))
1541
          {
1542
          throw vtkFoamError() << "Unexpected EOF";
1543
          }
1544
1545
        // list of dictionaries is read as a usual dictionary
1546
        // polyMesh/boundary, point/face/cell-Zones
1547
        if(!isSubDictionary && currToken.type() == vtkFoamToken::LABEL)
1548
          {
1549
          io.readExpecting('(');
1550
          if(currToken.labelToken() > 0)
1551
            {
1552
            if(!io.read(currToken))
1553
              {
1554
              throw vtkFoamError() << "Unexpected EOF";
1555
              }
1556
            // continue to read as a usual dictionary
1557
            }
1558
          else // return as empty dictionary
1559
            {
1560
            io.readExpecting(')');
1561
            type_ = DICTIONARY;
1562
            return true;
1563
            }
1564
          }
1565
        // some boundary files does not have the number of boundary
1566
        // patches (e.g. settlingFoam/tank3D). in this case we need to
1567
        // explicitly read the file as a dictionary.
1568
        else if(!isSubDictionary && currToken == '('
1569
          && io.className() == "polyBoundaryMesh") // polyMesh/boundary
1570
          {
1571
	    if(!io.read(currToken)) // read the first keyword
1572
            {
1573
            throw vtkFoamError() << "Unexpected EOF";
1574
            }
1575
          if(currToken == ')') // return as empty dictionary
1576
            {
1577
            type_ = DICTIONARY;
1578
            return true;
1579
            }
1580
          }
1581
	// the following two else-if clauses are for an exceptional
1582
	// expression of `LABEL{LABELorSCALAR}' without type prefix
1583
	// (e. g. `2{-0}' in mixedRhoE B.C. in
1584
	// rhopSonicFoam/shockTube)
1585
	else if(isSubDictionary && currToken.type() == vtkFoamToken::LABEL)
1586
	  {
1587
          token() = currToken.labelToken();
1588
          type_ = UNIFORMLABELLIST;
1589
          io.readExpecting('}');
1590
          return true;
1591
          }
1592
	else if(isSubDictionary && currToken.type() == vtkFoamToken::SCALAR)
1593
	  {
1594
          token() = currToken.number();
1595
          type_ = UNIFORMSCALARLIST;
1596
          io.readExpecting('}');
1597
          return true;
1598
          }
1599
        // return as empty dictionary
1600
        else if(isSubDictionary && currToken == '}')
1601
          {
1602
          type_ = DICTIONARY;
1603
          return true;
1604
          }
1605
        }
1606
      // if firstKeyword is set read the following stream as subdictionary
1607
      else
1608
        {
1609
        entryPtrs_.push_back(new vtkFoamEntry);
1610
        entryPtrs_.back()->keyword() = firstKeyword;
1611
        entryPtrs_.back()->readDictionary(io);
1612
        if(!io.read(currToken) || currToken == '}' || currToken == ')')
1613
          {
1614
          type_ = DICTIONARY;
1615
          return true;
1616
          }
1617
        }
1618
1619
      if(currToken.type() == vtkFoamToken::STRING) // general dictionary
1620
        {
1621
        // based on src/OpenFOAM/db/dictionary/dictionaryIO.C
1622
        do
1623
          {
1624
          if(currToken != ';') // ignore empty entry
1625
            {
1626
            entryPtrs_.push_back(new vtkFoamEntry);
1627
            entryPtrs_.back()->keyword() = currToken.stringToken();
1628
            entryPtrs_.back()->read(io);
1629
            if(currToken == "FoamFile")
1630
              {
1631
              // delete the FoamFile header subdictionary entry
1632
              delete entryPtrs_.back();
1633
              entryPtrs_.pop_back();
1634
              }
1635
            }
1636
          } while(io.read(currToken)
1637
            && (currToken.type() == vtkFoamToken::STRING || currToken == ';'));
1638
1639
        if(currToken.type() == vtkFoamToken::ERROR || currToken == '}'
1640
          || currToken == ')')
1641
          {
1642
          type_ = DICTIONARY;
1643
          return true;
1644
          }
1645
        throw vtkFoamError()
1646
          << "Expected keyword, closing brace, ; or EOF, found " << currToken;
1647
        }
1648
      throw vtkFoamError() << "Bad first keyword for dictionary " << currToken;
1649
      }
1650
    catch(vtkFoamError& e)
1651
      {
1652
      if(isSubDictionary)
1653
        {
1654
        throw;
1655
        }
1656
      else
1657
        {
1658
        io.setError(e);
1659
        return false;
1660
        }
1661
      }
1662
  }
1663
};
1664
1665
void vtkOpenFOAMReader::vtkFoamIOobject::readHeader()
1666
{
1667
  vtkFoamToken firstToken;
1668
1669
  readExpecting("FoamFile");
1670
  readExpecting('{');
1671
1672
  vtkFoamDict headerDict;
1673
  headerDict.read(*this, true); // throw exception in case of error
1674
1675
  vtkFoamEntry& formatEntry = headerDict.lookup("format");
1676
  if(!formatEntry.found())
1677
    {
1678
    throw vtkFoamError()
1679
      << "the format entry (binary/ascii) not found in FoamFile header";
1680
    }
1681
  vtkStdString format;
1682
  formatEntry >> format;
1683
  // case does matter (e. g. "BINARY" is treated as ascii)
1684
  // see src/OpenFOAM/db/IOstreams/IOstreams/IOstream.C
1685
  if(format == "binary")
1686
    {
1687
    format_ = BINARY;
1688
    }
1689
  else
1690
    {
1691
    format_ = ASCII;
1692
    }
1693
1694
  vtkFoamEntry& classEntry = headerDict.lookup("class");
1695
  if(!classEntry.found())
1696
    {
1697
    throw vtkFoamError() << "class name not found in FoamFile header";
1698
    }
1699
  classEntry >> headerClassName_;
1700
1701
  vtkFoamEntry& objectEntry = headerDict.lookup("object");
1702
  if(!objectEntry.found())
1703
    {
1704
    throw vtkFoamError() << "object name not found in FoamFile header";
1705
    }
1706
  objectEntry >> objectName_;
1707
}
1708
1709
void vtkOpenFOAMReader::vtkFoamEntryValue::clear()
1710
{
1711
  if(managed_)
1712
    {
1713
    if(type_ == LABELLIST)
1714
      {
1715
      delete labelListPtr_;
1716
      }
1717
    else if(type_ == LABELLISTLIST)
1718
      {
1719
      delete labelListListPtr_;
1720
      }
1721
    else if(type_ == SCALARLIST)
1722
      {
1723
      scalarListPtr_->Delete();
1724
      }
1725
    else if(type_ == VECTORLIST)
1726
      {
1727
      vectorListPtr_->Delete();
1728
      }
1729
    else if(type_ == STRINGLIST)
1730
      {
1731
      delete stringListPtr_;
1732
      }
1733
    else if(type_ == ENTRYVALUELIST)
1734
      {
1735
      for(size_t i = 0; i < entryValuePtrs_.size() ; i++)
1736
        {
1737
        delete entryValuePtrs_[i];
1738
        }
1739
      }
1740
    else if(type_ == DICTIONARY)
1741
      {
1742
      delete dictPtr_;
1743
      }
1744
    }
1745
}
1746
1747
// general-purpose list reader - guess the type of the list and read
1748
// it. only supports ascii format and assumes the preceding '(' has
1749
// already been thrown away.  the reader supports nested list with
1750
// variable lengths (e. g. `((token token) (token token token)).'
1751
// also supports compound of tokens and lists (e. g. `((token token)
1752
// token)') only if a list comes as the first value.
1753
void vtkOpenFOAMReader::vtkFoamEntryValue::readList(vtkFoamIOobject& io)
1754
{
1755
  io.read(t_);
1756
1757
  // initial guess of the list type
1758
  if(t_.type() == vtkFoamToken::LABEL)
1759
    {
1760
    // if the first token is of type LABEL it might be either an element of
1761
    // a labelList or the size of a sublist so proceed to the next token
1762
    vtkFoamToken nextToken;
1763
    if(!io.read(nextToken))
1764
      {
1765
      throw vtkFoamError() << "Unexpected EOF";
1766
      }
1767
    if(nextToken.type() == vtkFoamToken::LABEL)
1768
      {
1769
      labelListPtr_ = new intVector;
1770
      labelListPtr_->value.push_back(t_.labelToken());
1771
      labelListPtr_->value.push_back(nextToken.labelToken());
1772
      type_ = LABELLIST;
1773
      }
1774
    else if(nextToken.type() == vtkFoamToken::SCALAR)
1775
      {
1776
      scalarListPtr_ = vtkDoubleArray::New();
1777
      scalarListPtr_->InsertNextValue(t_.number());
1778
      scalarListPtr_->InsertNextValue(nextToken.number());
1779
      type_ = SCALARLIST;
1780
      }
1781
    else if(nextToken == '(') // list of list: read recursively
1782
      {
1783
      entryValuePtrs_.push_back(new vtkFoamEntryValue);
1784
      entryValuePtrs_.back()->readList(io);
1785
      type_ = ENTRYVALUELIST;
1786
      }
1787
    else if(nextToken == ')') // list with only one label element
1788
      {
1789
      labelListPtr_ = new intVector;
1790
      labelListPtr_->value.push_back(t_.labelToken());
1791
      type_ = LABELLIST;
1792
      return;
1793
      }
1794
    else
1795
      {
1796
      throw vtkFoamError() << "Expected number, ( or ), found " << nextToken;
1797
      }
1798
    }
1799
  else if(t_.type() == vtkFoamToken::SCALAR)
1800
    {
1801
    scalarListPtr_ = vtkDoubleArray::New();
1802
    scalarListPtr_->InsertNextValue(t_.number());
1803
    type_ = SCALARLIST;
1804
    }
1805
  // if the first word is a string we have to read another token to determine
1806
  // if the first word is a keyword for the following dictionary
1807
  else if(t_.type() == vtkFoamToken::STRING)
1808
    {
1809
    vtkFoamToken nextToken;
1810
    if(!io.read(nextToken))
1811
      {
1812
      throw vtkFoamError() << "Unexpected EOF";
1813
      }
1814
    if(nextToken.type() == vtkFoamToken::STRING) // list of strings
1815
      {
1816
      stringListPtr_ = new stringVector;
1817
      stringListPtr_->value.push_back(t_.stringToken());
1818
      stringListPtr_->value.push_back(nextToken.stringToken());
1819
      type_ = STRINGLIST;
1820
      }
1821
    // dictionary with the already read stringToken as the first keyword
1822
    else if(nextToken == '{')
1823
      {
1824
      if(t_.stringToken() == "")
1825
        {
1826
        throw "Empty string is invalid as a keyword for dictionary entry";
1827
        }
1828
      readDictionary(io, t_.stringToken());
1829
      // the dictionary read as list has the entry terminator ';' so
1830
      // we have to skip it
1831
      return;
1832
      }
1833
    else if(nextToken == ')') // list with only one string element
1834
      {
1835
      stringListPtr_ = new stringVector;
1836
      stringListPtr_->value.push_back(t_.stringToken());
1837
      type_ = STRINGLIST;
1838
      return;
1839
      }
1840
    else
1841
      {
1842
      throw vtkFoamError() << "Expected string, { or ), found " << nextToken;
1843
      }
1844
    }
1845
  else if(t_ == '(') // list of lists: read recursively
1846
    {
1847
    entryValuePtrs_.push_back(new vtkFoamEntryValue);
1848
    entryValuePtrs_.back()->readList(io);
1849
    // read all the following values as arbitrary entryValues
1850
    // the alphaContactAngle b.c. in multiphaseInterFoam/damBreak4phase
1851
    // reaquires this treatment (reading by readList() is not enough)
1852
    do
1853
      {
1854
      entryValuePtrs_.push_back(new vtkFoamEntryValue);
1855
      entryValuePtrs_.back()->read(io);
1856
      }
1857
    while(*entryValuePtrs_.back() != ')' && *entryValuePtrs_.back() != '}'
1858
      && *entryValuePtrs_.back() != ';');
1859
1860
    if(*entryValuePtrs_.back() != ')')
1861
      {
1862
      throw vtkFoamError() << "Expected ) before "
1863
        << entryValuePtrs_.back()->token();
1864
      }
1865
1866
    // delete ')'
1867
    delete entryValuePtrs_.back();
1868
    entryValuePtrs_.pop_back();
1869
    type_ = ENTRYVALUELIST;
1870
    return;
1871
    }
1872
  else if(t_ == ')') // empty list
1873
    {
1874
    type_ = EMPTYLIST;
1875
    return;
1876
    }
1877
1878
  while(io.read(t_) && t_ != ')')
1879
    {
1880
    if(type_ == LABELLIST)
1881
      {
1882
      if(t_.type() == vtkFoamToken::SCALAR) // switch to scalarList
1883
        {
1884
        // labelListPtr_ and scalarListPtr_ are packed into a single union so
1885
        // we need a temprary pointer
1886
        vtkDoubleArray* slPtr = vtkDoubleArray::New();
1887
        const vtkIdType size = labelListPtr_->value.size();
1888
        slPtr->SetNumberOfValues(size);
1889
        for(vtkIdType i = 0; i < size; i++)
1890
          {
1891
          slPtr->SetValue(i, double(labelListPtr_->value[i]));
1892
          }
1893
        delete labelListPtr_;
1894
        slPtr->InsertNextValue(t_.number());
1895
        scalarListPtr_ = slPtr; // copy after labelListPtr_ is deleted
1896
        type_ = SCALARLIST;
1897
        }
1898
      else if(t_.type() == vtkFoamToken::LABEL)
1899
        {
1900
        labelListPtr_->value.push_back(t_.labelToken());
1901
        }
1902
      else
1903
        {
1904
        throw vtkFoamError() << "Expected a number, found " << t_;
1905
        }
1906
      }
1907
    else if(type_ == SCALARLIST)
1908
      {
1909
      if(t_.isNumber())
1910
        {
1911
        scalarListPtr_->InsertNextValue(t_.number());
1912
        }
1913
      else
1914
        {
1915
        throw vtkFoamError() << "Expected a number, found " << t_;
1916
        }
1917
      }
1918
    else if(type_ == STRINGLIST)
1919
      {
1920
      if(t_.type() == vtkFoamToken::STRING)
1921
        {
1922
        stringListPtr_->value.push_back(t_.stringToken());
1923
        }
1924
      else
1925
        {
1926
        throw vtkFoamError() << "Expected a string, found " << t_;
1927
        }
1928
      }
1929
    else if(type_ == ENTRYVALUELIST)
1930
      {
1931
      if(t_.type() == vtkFoamToken::LABEL)
1932
        {
1933
        // skip the number of elements to make things simple
1934
        if(!io.read(t_))
1935
          {
1936
          throw vtkFoamError() << "Unexpected EOF";
1937
          }
1938
        }
1939
      if(t_ != '(')
1940
        {
1941
        throw vtkFoamError() << "Expected (, found " << t_;
1942
        }
1943
      entryValuePtrs_.push_back(new vtkFoamEntryValue);
1944
      entryValuePtrs_.back()->readList(io);
1945
      }
1946
    else
1947
      {
1948
      throw vtkFoamError() << "Unexpected token " << t_;
1949
      }
1950
    }
1951
1952
  if(type_ == SCALARLIST)
1953
    {
1954
    scalarListPtr_->Squeeze();
1955
    }
1956
}
1957
1958
// a list of dictionaries is actually read as a dictionary
1959
void vtkOpenFOAMReader::vtkFoamEntryValue::readDictionary(vtkFoamIOobject& io,
1960
  const vtkStdString& firstKeyword)
1961
{
1962
  dictPtr_ = new vtkFoamDict;
1963
  type_ = DICTIONARY;
1964
  dictPtr_->read(io, true, firstKeyword);
1965
}
1966
1967
// guess the type of the given entry value and read it
1968
void vtkOpenFOAMReader::vtkFoamEntryValue::read(vtkFoamIOobject& io)
1969
{
1970
  if(!io.read(t_))
1971
    {
1972
    throw vtkFoamError() << "Unexpected EOF";
1973
    }
1974
1975
  if(t_ == '{')
1976
    {
1977
    readDictionary(io);
1978
    return;
1979
    }
1980
  // for reading sublist from vtkFoamEntryValue::readList() or there
1981
  // are cases where lists without the (non)uniform keyword appear
1982
  // (e. g. coodles/pitsDaily/0/U, Hrv's uniformFixedValue b.c.)
1983
  else if(t_ == '(')
1984
    {
1985
    readList(io);
1986
    return;
1987
    }
1988
  else if(t_ == "uniform")
1989
    {
1990
    if(!io.read(t_))
1991
      {
1992
      throw vtkFoamError()
1993
        << "Expected a uniform value or a list, found unexpected EOF";
1994
      }
1995
    if(t_ == '(')
1996
      {
1997
      readList(io);
1998
      }
1999
    else if(t_.type() == vtkFoamToken::LABEL)
2000
      {
2001
      type_ = LABEL;
2002
      }
2003
    else if(t_.type() == vtkFoamToken::SCALAR)
2004
      {
2005
      type_ = SCALAR;
2006
      }
2007
    else if(t_.type() == vtkFoamToken::STRING)
2008
      {
2009
      type_ = STRING;
2010
      }
2011
    else // unexpected punctuation token
2012
      {
2013
      throw vtkFoamError() << "Expected number, string or (, found " << t_;
2014
      }
2015
    isUniform_ = true;
2016
    }
2017
  else if(t_ == "nonuniform")
2018
    {
2019
    if(!io.read(t_))
2020
      {
2021
      throw vtkFoamError() << "Expected list type specifier, found EOF";
2022
      }
2023
    if(t_ == "List<vector>")
2024
      {
2025
      isUniform_ = false;
2026
      readVectorList(io, false);
2027
      }
2028
    else if(t_ == "List<scalar>")
2029
      {
2030
      isUniform_ = false;
2031
      readScalarList(io);
2032
      }
2033
    // List<bool> is read as List<label>
2034
    else if(t_ == "List<label>" || t_ == "List<bool>")
2035
      {
2036
      isUniform_ = false;
2037
      readLabelList(io);
2038
      }
2039
    // an empty list doesn't have a list type specifier
2040
    else if(t_.type() == vtkFoamToken::LABEL && t_.labelToken() == 0)
2041
      {
2042
      type_ = EMPTYLIST;
2043
      isUniform_ = false;
2044
      io.readExpecting('(');
2045
      io.readExpecting(')');
2046
      }
2047
    else
2048
      {
2049
      throw vtkFoamError() << "Unsupported nonuniform list type " << t_;
2050
      }
2051
    }
2052
  // zones have list without a uniform/nonuniform keyword
2053
  // List<bool> is read as List<label>
2054
  // (e. g. flipMap entry in point/face/cellZones)
2055
  else if(t_ == "List<label>" || t_ == "List<bool>")
2056
    {
2057
    isUniform_ = false;
2058
    readLabelList(io);
2059
    }
2060
  else if(t_.type() == vtkFoamToken::LABEL)
2061
    {
2062
    type_ = LABEL;
2063
    }
2064
  else if(t_.type() == vtkFoamToken::SCALAR)
2065
    {
2066
    type_ = SCALAR;
2067
    }
2068
  else if(t_.type() == vtkFoamToken::STRING)
2069
    {
2070
    type_ = STRING;
2071
    }
2072
  else if(t_.type() == vtkFoamToken::PUNCTUATION)
2073
    {
2074
    type_ = PUNCTUATION;
2075
    }
2076
}
2077
2078
// read values of an entry
2079
void vtkOpenFOAMReader::vtkFoamEntry::read(vtkFoamIOobject& io)
75
{
2080
{
76
  vtkstd::vector< int > value;
2081
  for(;;)
77
};
2082
    {
2083
    valuePtrs_.push_back(new vtkFoamEntryValue);
2084
    valuePtrs_.back()->read(io);
78
2085
79
struct intVectorVector
2086
    if(valuePtrs_.size() >= 2)
80
{
2087
      {
81
  vtkstd::vector< vtkstd::vector< int > > value;
2088
      vtkFoamEntryValue& secondLastValue
82
};
2089
        = *valuePtrs_[valuePtrs_.size() - 2];
2090
      if(secondLastValue.type() == vtkFoamEntryValue::LABEL)
2091
        {
2092
        vtkFoamEntryValue& lastValue = *valuePtrs_.back();
2093
2094
        // a zero-sized nonuniform list without prefixing "nonuniform"
2095
        // keyword nor list type specifier (i. e. `0()';
2096
        // e. g. simpleEngine/0/polyMesh/pointZones) requires special
2097
        // care (one with nonuniform prefix is treated within
2098
        // vtkFoamEntryValue::read()). still this causes errornous
2099
        // behavior for `0 nonuniform 0()' but this should be extremely
2100
        // rare
2101
        if(lastValue.type() == vtkFoamEntryValue::EMPTYLIST
2102
          && secondLastValue == 0)
2103
          {
2104
          delete valuePtrs_.back();
2105
          valuePtrs_.pop_back(); // delete the last value
2106
          valuePtrs_.back()->setEmptyList(); // mark new last value as empty
2107
          }
2108
        // for an exceptional expression of `LABEL{LABELorSCALAR}' without
2109
        // type prefix (e. g. `2{-0}' in mixedRhoE B.C. in
2110
        // rhopSonicFoam/shockTube)
2111
        else if(lastValue.type() == vtkFoamEntryValue::DICTIONARY)
2112
          {
2113
          if(lastValue.dictionary().type() == vtkFoamDict::UNIFORMLABELLIST)
2114
            {
2115
            const int size = secondLastValue.token().labelToken();
2116
            const int value = lastValue.dictionary().token().labelToken();
2117
            // delete last two values
2118
            delete valuePtrs_.back();
2119
            valuePtrs_.pop_back();
2120
            delete valuePtrs_.back();
2121
            valuePtrs_.pop_back();
2122
            // make new labelList
2123
            valuePtrs_.push_back(new vtkFoamEntryValue);
2124
            valuePtrs_.back()->makeLabelList(value, size);
2125
            }
2126
          else if(lastValue.dictionary().type()
2127
            == vtkFoamDict::UNIFORMSCALARLIST)
2128
            {
2129
            const int size = secondLastValue.token().labelToken();
2130
            const double value = lastValue.dictionary().token().number();
2131
            // delete last two values
2132
            delete valuePtrs_.back();
2133
            valuePtrs_.pop_back();
2134
            delete valuePtrs_.back();
2135
            valuePtrs_.pop_back();
2136
            // make new labelList
2137
            valuePtrs_.push_back(new vtkFoamEntryValue);
2138
            valuePtrs_.back()->makeScalarList(value, size);
2139
            }
2140
          }
2141
        }
2142
      }
83
2143
84
struct faceVectorVector
2144
    if(*valuePtrs_.back() == ';')
85
{
2145
      {
86
  vtkstd::vector< vtkstd::vector< face > > value;
2146
      delete valuePtrs_.back();
87
};
2147
      valuePtrs_.pop_back();
2148
      break;
2149
      }
2150
    else if(valuePtrs_.back()->type() == vtkFoamEntryValue::DICTIONARY)
2151
      {
2152
      // subdictionary is not suffixed by an entry terminator ';'
2153
      break;
2154
      }
2155
    else if(*valuePtrs_.back() == '}' || *valuePtrs_.back() == ')')
2156
      {
2157
      throw vtkFoamError() << "Unmatched " << valuePtrs_.back()->token();
2158
      }
2159
    }
2160
}
88
2161
89
vtkOpenFOAMReader::vtkOpenFOAMReader()
2162
vtkOpenFOAMReader::vtkOpenFOAMReader()
90
{
2163
{
Lines 95-154 Link Here
95
  this->FileName = NULL;
2168
  this->FileName = NULL;
96
2169
97
  //VTK CLASSES
2170
  //VTK CLASSES
98
  this->Points = vtkPoints::New();
2171
  this->PatchDataArraySelection = vtkDataArraySelection::New();
99
  this->CellDataArraySelection = vtkDataArraySelection::New();
2172
  this->CellDataArraySelection = vtkDataArraySelection::New();
2173
  this->PointDataArraySelection = vtkDataArraySelection::New();
2174
2175
  // Setup the Selection observer for the above selection arrays
2176
  this->SelectionObserver = vtkCallbackCommand::New();
2177
  this->SelectionObserver
2178
    ->SetCallback(&vtkOpenFOAMReader::SelectionModifiedCallback);
2179
  this->SelectionObserver->SetClientData(this);
2180
2181
  this->PatchDataArraySelection
2182
    ->AddObserver(vtkCommand::ModifiedEvent,this->SelectionObserver);
2183
  this->CellDataArraySelection
2184
    ->AddObserver(vtkCommand::ModifiedEvent,this->SelectionObserver);
2185
  this->PointDataArraySelection
2186
    ->AddObserver(vtkCommand::ModifiedEvent,this->SelectionObserver);
2187
2188
  // Initialise the Selection status arrays
2189
  this->CellSelectionOldStatus = 0;
2190
  this->PointSelectionOldStatus = 0;
2191
  this->PatchSelectionOldStatus = 0;
2192
  this->CellSelectionStatus = 0;
2193
  this->PointSelectionStatus = 0;
2194
  this->PatchSelectionStatus = 0;
100
2195
101
  //DATA COUNTS
2196
  //DATA COUNTS
102
  this->NumFaces = 0;
103
  this->NumPoints = 0;
104
  this->NumCells = 0;
2197
  this->NumCells = 0;
105
2198
106
  this->TimeStepData = new stringVector;
2199
  this->TimeStepData = new stringVector;
107
  this->Path = new stdString;
2200
  this->LagrangianTimeStepData = new stringVector;
108
  this->PathPrefix = new stdString;
2201
  this->OldFileName = new vtkStdString;
2202
  this->PathPrefix = new vtkStdString;
109
  this->PolyMeshPointsDir = new stringVector;
2203
  this->PolyMeshPointsDir = new stringVector;
110
  this->PolyMeshFacesDir = new stringVector;
2204
  this->PolyMeshFacesDir = new stringVector;
111
  this->BoundaryNames = new stringVector;
112
  this->PointZoneNames = new stringVector;
113
  this->FaceZoneNames = new stringVector;
114
  this->CellZoneNames = new stringVector;
115
116
  this->FacePoints = new intVectorVector;
117
  this->FacesOwnerCell = new intVectorVector;
118
  this->FacesNeighborCell = new intVectorVector;
119
  this->FacesOfCell = new faceVectorVector;
120
  this->SizeOfBoundary = new intVector;
121
2205
122
  //DATA TIMES
2206
  //DATA TIMES
123
  this->NumberOfTimeSteps = 0;
2207
  this->NumberOfTimeSteps = 0;
124
  this->Steps = NULL;
2208
  this->Steps = NULL;
2209
  this->TimeNames = vtkStringArray::New();
125
  this->TimeStep = 0;
2210
  this->TimeStep = 0;
126
  this->TimeStepRange[0] = 0;
2211
  this->TimeStepRange[0] = 0;
127
  this->TimeStepRange[1] = 0;
2212
  this->TimeStepRange[1] = 0;
128
  this->RequestInformationFlag = true;
2213
2214
  // for caching mesh
2215
  this->CacheMesh = 1;
2216
  this->OldTimeStep = -1;
2217
  this->InternalMesh = NULL;
2218
  this->BoundaryMesh = NULL;
2219
  this->BoundaryDict = NULL;
2220
  this->FaceOwner = NULL;
2221
  this->PointZoneMesh = NULL;
2222
  this->FaceZoneMesh = NULL;
2223
  this->CellZoneMesh = NULL;
2224
2225
  // for reading zones
2226
  this->ReadZones = 0; // turned off by default
2227
  // for accumulating patches across time-steps (Turned on by default)
2228
  // As of now, only accumulation of patches is implemented
2229
  this->KeepPatches = 1;
129
}
2230
}
130
2231
131
vtkOpenFOAMReader::~vtkOpenFOAMReader()
2232
vtkOpenFOAMReader::~vtkOpenFOAMReader()
132
{
2233
{
133
  vtkDebugMacro(<<"DeConstructor");
2234
  vtkDebugMacro(<<"DeConstructor");
134
  this->Points->Delete();
2235
2236
  // Delete the Observers before deleting the Selection Arrays !!!
2237
  this->PatchDataArraySelection->RemoveObserver(this->SelectionObserver);
2238
  this->CellDataArraySelection->RemoveObserver(this->SelectionObserver);
2239
  this->PointDataArraySelection->RemoveObserver(this->SelectionObserver);
2240
2241
  // Now delete the Selection Observer itself
2242
  this->SelectionObserver->Delete();
2243
2244
  // Finally delete the Selection Arrays
2245
  this->PatchDataArraySelection->Delete();
135
  this->CellDataArraySelection->Delete();
2246
  this->CellDataArraySelection->Delete();
136
  delete [] this->Steps;
2247
  this->PointDataArraySelection->Delete();
137
2248
138
  delete this->TimeStepData;
2249
  delete this->OldFileName;
139
  delete this->Path;
140
  delete this->PathPrefix;
2250
  delete this->PathPrefix;
141
  delete this->PolyMeshPointsDir;
2251
  delete this->PolyMeshPointsDir;
142
  delete this->PolyMeshFacesDir;
2252
  delete this->PolyMeshFacesDir;
143
  delete this->BoundaryNames;
2253
  this->TimeNames->Delete();
144
  delete this->PointZoneNames;
2254
  delete this->TimeStepData;
145
  delete this->FaceZoneNames;
2255
  delete this->LagrangianTimeStepData;
146
  delete this->CellZoneNames;
2256
147
  delete this->FacePoints;
2257
  this->ClearMeshes();
148
  delete this->FacesOwnerCell;
2258
}
149
  delete this->FacesNeighborCell;
2259
150
  delete this->FacesOfCell;
2260
void vtkOpenFOAMReader::ClearMeshes()
151
  delete this->SizeOfBoundary;
2261
{
2262
  if(this->FaceOwner != NULL)
2263
    {
2264
    this->FaceOwner->Delete();
2265
    this->FaceOwner = NULL;
2266
    }
2267
  if(this->InternalMesh != NULL)
2268
    {
2269
    this->InternalMesh->Delete();
2270
    this->InternalMesh = NULL;
2271
    }
2272
  if(this->BoundaryMesh != NULL)
2273
    {
2274
    for(size_t i = 0; i < this->BoundaryMesh->value.size(); i++)
2275
      {
2276
      this->BoundaryMesh->value[i]->Delete();
2277
      }
2278
    delete this->BoundaryMesh;
2279
    this->BoundaryMesh = NULL;
2280
    }
2281
  delete this->BoundaryDict;
2282
  if(this->PointZoneMesh != NULL)
2283
    {
2284
    for(size_t i = 0; i < this->PointZoneMesh->value.size(); i++)
2285
      {
2286
      this->PointZoneMesh->value[i]->Delete();
2287
      }
2288
    delete this->PointZoneMesh;
2289
    this->PointZoneMesh = NULL;
2290
    }
2291
  if(this->FaceZoneMesh != NULL)
2292
    {
2293
    for(size_t i = 0; i < this->FaceZoneMesh->value.size(); i++)
2294
      {
2295
      this->FaceZoneMesh->value[i]->Delete();
2296
      }
2297
    delete this->FaceZoneMesh;
2298
    this->FaceZoneMesh = NULL;
2299
    }
2300
  if(this->CellZoneMesh != NULL)
2301
    {
2302
    for(size_t i = 0; i < this->CellZoneMesh->value.size(); i++)
2303
      {
2304
      this->CellZoneMesh->value[i]->Delete();
2305
      }
2306
    delete this->CellZoneMesh;
2307
    this->CellZoneMesh = NULL;
2308
    }
152
}
2309
}
153
2310
154
int vtkOpenFOAMReader::RequestData(
2311
int vtkOpenFOAMReader::RequestData(
Lines 160-172 Link Here
160
  vtkInformation* outInfo = outputVector->GetInformationObject(0);
2317
  vtkInformation* outInfo = outputVector->GetInformationObject(0);
161
  vtkMultiBlockDataSet *output = vtkMultiBlockDataSet::SafeDownCast(
2318
  vtkMultiBlockDataSet *output = vtkMultiBlockDataSet::SafeDownCast(
162
    outInfo->Get(vtkMultiBlockDataSet::DATA_OBJECT()));
2319
    outInfo->Get(vtkMultiBlockDataSet::DATA_OBJECT()));
2320
163
  if(!this->FileName)
2321
  if(!this->FileName)
164
    {
2322
    {
165
    vtkErrorMacro("FileName has to be specified!");
2323
    vtkErrorMacro("FileName has to be specified!");
166
    return 0;
2324
    return 0;
167
    }
2325
    }
168
  this->CreateDataSet(output);
2326
169
  return 1;
2327
  if(this->NumberOfTimeSteps == 0)
2328
    {
2329
    vtkErrorMacro(<< this->FileName << " contains no timestep data.");
2330
    return 0;
2331
    }
2332
    
2333
  if(this->TimeStep < this->TimeStepRange[0]
2334
     || this->TimeStep > this->TimeStepRange[1])
2335
    {
2336
    vtkErrorMacro("TimeStep out of range");
2337
    return 0;
2338
    }
2339
2340
#if PARAVIEW_VERSION_MAJOR >= 3
2341
  if(outInfo->Has(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEPS()))
2342
    {
2343
    double* requestedTimeValues
2344
      = outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEPS());
2345
    int nSteps
2346
      = outInfo->Length(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
2347
    double* steps
2348
      = outInfo->Get(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
2349
    int timeI = 0;
2350
    while(timeI < nSteps - 1 && steps[timeI] < requestedTimeValues[0])
2351
      {
2352
      timeI++;
2353
      }
2354
    this->SetTimeStep(timeI);
2355
2356
    outInfo->Set(vtkDataObject::DATA_TIME_STEPS(), &steps[timeI], 1);
2357
    }
2358
#endif
2359
  this->MakeTimeStepData();
2360
2361
  const int ret = this->CreateDataSet(output, this->TimeStep);
2362
2363
  // update selection status
2364
  this->CellSelectionOldStatus = this->CellSelectionStatus;
2365
  this->PointSelectionOldStatus = this->PointSelectionStatus;
2366
  this->PatchSelectionOldStatus = this->PatchSelectionStatus;
2367
2368
  return ret;
170
}
2369
}
171
2370
172
void vtkOpenFOAMReader::PrintSelf(ostream& os, vtkIndent indent)
2371
void vtkOpenFOAMReader::PrintSelf(ostream& os, vtkIndent indent)
Lines 175-181 Link Here
175
  this->Superclass::PrintSelf(os,indent);
2374
  this->Superclass::PrintSelf(os,indent);
176
  os << indent << "File Name: "
2375
  os << indent << "File Name: "
177
     << (this->FileName ? this->FileName : "(none)") << "\n";
2376
     << (this->FileName ? this->FileName : "(none)") << "\n";
178
  os << indent << "Number Of Nodes: " << this->NumPoints << "\n";
2377
//  os << indent << "Number Of Nodes: " << this->NumPoints << "\n";
179
  os << indent << "Number Of Cells: " << this->NumCells << "\n";
2378
  os << indent << "Number Of Cells: " << this->NumCells << "\n";
180
  os << indent << "Number of Time Steps: " << this->NumberOfTimeSteps << endl;
2379
  os << indent << "Number of Time Steps: " << this->NumberOfTimeSteps << endl;
181
  os << indent << "TimeStepRange: " 
2380
  os << indent << "TimeStepRange: " 
Lines 190-263 Link Here
190
  vtkInformationVector **vtkNotUsed(inputVector),
2389
  vtkInformationVector **vtkNotUsed(inputVector),
191
  vtkInformationVector *outputVector)
2390
  vtkInformationVector *outputVector)
192
{
2391
{
193
  if(!this->FileName)
2392
  if(!this->FileName || strlen(this->FileName) == 0)
194
    {
2393
    {
195
    vtkErrorMacro("FileName has to be specified!");
2394
    vtkErrorMacro("FileName has to be specified!");
196
    return 0;
2395
    return 0;
197
    }
2396
    }
198
  vtkDebugMacro(<<"Request Info");
2397
  vtkDebugMacro(<<"Request Info: " <<this->FileName);
199
  if(RequestInformationFlag)
2398
2399
  if(*this->OldFileName != vtkStdString(this->FileName))
200
    {
2400
    {
201
    vtkDebugMacro(<<this->FileName);
2401
    // updated this->OldFileName
202
    this->Path->value.append(this->FileName);
2402
    *this->OldFileName = vtkStdString(this->FileName);
203
    this->ReadControlDict();
2403
2404
    // clear prior case information
2405
    this->OldTimeStep = -1;
2406
    if(this->Steps != NULL)
2407
      {
2408
      delete [] this->Steps;
2409
      this->Steps = NULL;
2410
      }
2411
    this->ClearMeshes();
2412
2413
    this->CellDataArraySelection->RemoveAllArrays();
2414
    this->PointDataArraySelection->RemoveAllArrays();
2415
    this->PatchDataArraySelection->RemoveAllArrays();
2416
2417
    // make case information
2418
    if(!this->ReadControlDict(this->FileName))
2419
      {
2420
      return 0;
2421
      }
2422
    if(this->NumberOfTimeSteps == 0)
2423
      {
2424
      vtkErrorMacro(<< this->FileName << " contains no timestep data.");
2425
      return 0;
2426
      }
204
    this->TimeStepRange[0] = 0;
2427
    this->TimeStepRange[0] = 0;
205
    this->TimeStepRange[1] = this->NumberOfTimeSteps-1;
2428
    this->TimeStepRange[1] = this->NumberOfTimeSteps;
206
    this->PopulatePolyMeshDirArrays();
2429
    this->PopulatePolyMeshDirArrays();
207
    outputVector->GetInformationObject(0)->Set(
2430
    outputVector->GetInformationObject(0)->Set(
208
      vtkStreamingDemandDrivenPipeline::TIME_STEPS(), this->Steps,
2431
      vtkStreamingDemandDrivenPipeline::TIME_STEPS(), this->Steps,
209
      this->NumberOfTimeSteps);
2432
      this->NumberOfTimeSteps);
210
    this->RequestInformationFlag = false;
2433
#if PARAVIEW_VERSION_MAJOR >= 3
211
    }
2434
    double timeRange[2];
212
2435
    timeRange[0] = this->Steps[0];
213
  //Add scalars and vectors to metadata
2436
    timeRange[1] = this->Steps[this->NumberOfTimeSteps - 1];
214
  //create path to current time step
2437
    outputVector->GetInformationObject(0)->Set(
215
  vtksys_ios::stringstream tempPath;
2438
      vtkStreamingDemandDrivenPipeline::TIME_RANGE(), timeRange, 2);
216
  tempPath << this->PathPrefix->value.c_str();
2439
#endif
217
  tempPath << this->Steps[this->TimeStep];
218
219
  //open the directory and get num of files
220
  int numSolvers;
221
  vtkDirectory * directory = vtkDirectory::New();
222
  int opened = directory->Open(tempPath.str().c_str());
223
  if(opened)
224
    {
225
    numSolvers = directory->GetNumberOfFiles();
226
    }
227
  else
228
    {
229
    numSolvers = -1; //no dir
230
    }
2440
    }
231
2441
232
  //clear prior timestep data
2442
  this->MakeTimeStepData();
233
  this->TimeStepData->value.clear();
234
235
  //loop over all files and locate
236
  //volScalars and volVectors
237
  for(int j = 0; j < numSolvers; j++)
238
    {
239
    const char * tempSolver = directory->GetFile(j);
240
    if(tempSolver != (char *)"polyMesh")
241
      {
242
      if(tempSolver != (char *)"." && tempSolver != (char *)"..")
243
        {
244
        vtkstd::string type(this->GetDataType(tempPath.str().c_str(),
245
                                              tempSolver));
246
        if(strcmp(type.c_str(), "Scalar") == 0)
247
        {
248
          this->TimeStepData->value.push_back(vtkstd::string(tempSolver));
249
          this->CellDataArraySelection->AddArray(tempSolver);
250
          }
251
        else if(strcmp(type.c_str(), "Vector") == 0)
252
          {
253
          this->TimeStepData->value.push_back(vtkstd::string(tempSolver));
254
          this->CellDataArraySelection->AddArray(tempSolver);
255
          }
256
        }
257
      }
258
    }
259
2443
260
  directory->Delete();
261
  return 1;
2444
  return 1;
262
}
2445
}
263
2446
Lines 304-2374 Link Here
304
  return;
2487
  return;
305
}
2488
}
306
2489
307
// ****************************************************************************
2490
//
308
//  Method: vtkOpenFOAMReader::CombineOwnerNeigbor
2491
// POINT METHODS
309
//
2492
//
310
//  Purpose:
2493
int vtkOpenFOAMReader::GetNumberOfPointArrays()
311
//  add Owner faces to the faces of a cell and then add the neighor faces
2494
{
312
//
2495
  return this->PointDataArraySelection->GetNumberOfArrays();
313
// ****************************************************************************
2496
}
314
void vtkOpenFOAMReader::CombineOwnerNeigbor()
2497
315
{
2498
const char* vtkOpenFOAMReader::GetPointArrayName(int index)
316
  vtkDebugMacro(<<"Combine owner & neighbor faces");
2499
{
317
  //reintialize faces of the cells
2500
  return this->PointDataArraySelection->GetArrayName(index);
318
  face tempFace;
2501
}
319
  this->FacesOfCell->value.clear();
2502
320
  this->FacesOfCell->value.resize(this->NumCells);
2503
int vtkOpenFOAMReader::GetPointArrayStatus(const char* name)
2504
{
2505
  return this->PointDataArraySelection->ArrayIsEnabled(name);
2506
}
2507
2508
void vtkOpenFOAMReader::SetPointArrayStatus(const char* name, int status)
2509
{
2510
  if(status)
2511
    {
2512
    this->PointDataArraySelection->EnableArray(name);
2513
    }
2514
  else
2515
    {
2516
    this->PointDataArraySelection->DisableArray(name);
2517
    }
2518
  return;
2519
}
2520
2521
void vtkOpenFOAMReader::DisableAllPointArrays()
2522
{
2523
  this->PointDataArraySelection->DisableAllArrays();
2524
  return;
2525
}
2526
2527
void vtkOpenFOAMReader::EnableAllPointArrays()
2528
{
2529
  this->PointDataArraySelection->EnableAllArrays();
2530
  return;
2531
}
2532
2533
2534
//
2535
// PATCH METHODS
2536
//
2537
int vtkOpenFOAMReader::GetNumberOfPatchArrays()
2538
{
2539
  return this->PatchDataArraySelection->GetNumberOfArrays();
2540
}
2541
2542
const char* vtkOpenFOAMReader::GetPatchArrayName(int index)
2543
{
2544
  return this->PatchDataArraySelection->GetArrayName(index);
2545
}
2546
2547
int vtkOpenFOAMReader::GetPatchArrayStatus(const char* name)
2548
{
2549
  return this->PatchDataArraySelection->ArrayIsEnabled(name);
2550
}
2551
2552
void vtkOpenFOAMReader::SetPatchArrayStatus(const char* name, int status)
2553
{
2554
  if(status)
2555
    {
2556
    this->PatchDataArraySelection->EnableArray(name);
2557
    }
2558
  else
2559
    {
2560
    this->PatchDataArraySelection->DisableArray(name);
2561
    }
2562
  return;
2563
}
2564
2565
void vtkOpenFOAMReader::DisableAllPatchArrays()
2566
{
2567
  this->PatchDataArraySelection->DisableAllArrays();
2568
  return;
2569
}
2570
2571
void vtkOpenFOAMReader::EnableAllPatchArrays()
2572
{
2573
  this->PatchDataArraySelection->EnableAllArrays();
2574
  return;
2575
}
2576
2577
// Define the Selection Observer 
2578
void vtkOpenFOAMReader::SelectionModifiedCallback(vtkObject*,
2579
  unsigned long, void* clientdata, void*)
2580
{
2581
  static_cast<vtkOpenFOAMReader*>(clientdata)->SelectionModified();
2582
}
2583
2584
void vtkOpenFOAMReader::SelectionModified()
2585
{
2586
  // Change the pipeline modification time to force update
2587
  // Update the selection status to detect changes
2588
2589
  // Cell Selection Arrays
2590
  // we loop from the last element of the selection array since we'd
2591
  // like to place newly added variables to extra higher bits (we
2592
  // wouldn't like to move the locations of already existing variables)
2593
  this->CellSelectionStatus = 0;
2594
  for(int i = this->GetNumberOfCellArrays() - 1; i >= 0; i--)
2595
    {
2596
    this->CellSelectionStatus = (this->CellSelectionStatus << 1) 
2597
      + this->GetCellArrayStatus(this->GetCellArrayName(i));
2598
    }
2599
  // if the status flag overflows we'd like to fall onto the safe side
2600
  // (properly refresh the dataset without mesh caching) so we use the
2601
  // last bit (LSB) as overflow control flag.  if overflow occurs the
2602
  // LSB is negated from the old status
2603
  if(this->GetNumberOfCellArrays()
2604
    <= static_cast<int>(sizeof(this->CellSelectionStatus) * 8 - 1))
2605
    {
2606
    this->CellSelectionStatus = (this->CellSelectionStatus << 1)
2607
      + (this->CellSelectionOldStatus & 0x1);
2608
    }
2609
  else
2610
    {
2611
    this->CellSelectionStatus = (this->CellSelectionStatus << 1) 
2612
      + ((~this->CellSelectionOldStatus) & 0x1);
2613
    }
2614
  // Point Selection Arrays
2615
  // this->PointSelectionOldStatus = this->PointSelectionStatus;
2616
  this->PointSelectionStatus = 0;
2617
  for(int i = this->GetNumberOfPointArrays() - 1; i >= 0; i--)
2618
    {
2619
    this->PointSelectionStatus = (this->PointSelectionStatus << 1) 
2620
      + this->GetPointArrayStatus(this->GetPointArrayName(i));
2621
    }
2622
  if(this->GetNumberOfPointArrays()
2623
    <= static_cast<int>(sizeof(this->PointSelectionStatus) * 8 - 1))
2624
    {
2625
    this->PointSelectionStatus = (this->PointSelectionStatus << 1)
2626
      + (this->PointSelectionOldStatus & 0x1);
2627
    }
2628
  else
2629
    {
2630
    this->PointSelectionStatus = (this->PointSelectionStatus << 1) 
2631
      + (~(this->PointSelectionOldStatus) & 0x1);
2632
    }
2633
  // Patch Selection Arrays
2634
  // this->PatchSelectionOldStatus = this->PatchSelectionStatus;
2635
  this->PatchSelectionStatus = 0;
2636
  for(int i = this->GetNumberOfPatchArrays() - 1; i >= 0; i--)
2637
    {
2638
    this->PatchSelectionStatus = (this->PatchSelectionStatus << 1) 
2639
      + this->GetPatchArrayStatus(this->GetPatchArrayName(i));
2640
    }
2641
  if(this->GetNumberOfPatchArrays()
2642
    <= static_cast<int>(sizeof(this->PatchSelectionStatus) * 8 - 1))
2643
    {
2644
    this->PatchSelectionStatus = (this->PatchSelectionStatus << 1)
2645
      + (this->PatchSelectionOldStatus & 0x1);
2646
    }
2647
  else
2648
    {
2649
    this->PatchSelectionStatus = (this->PatchSelectionStatus << 1) 
2650
      + (~(this->PatchSelectionOldStatus) & 0x1);
2651
    }
2652
2653
  // Indicate that the pipeline needs to be updated (VTK Command)
2654
  this->Modified();
2655
}
2656
2657
2658
// create field data lists and cell/point array selection lists
2659
void vtkOpenFOAMReader::MakeTimeStepData()
2660
{
2661
  // Read the patches from the boundary file into selection array
2662
  int timeState = this->TimeStep;
2663
  vtkFoamDict* boundaryDictPtr
2664
    = this->GatherBlocks("boundary", timeState, true);
2665
  if(boundaryDictPtr == NULL)
2666
    {
2667
    vtkErrorMacro(<< "Couldn't read polyMesh/boundary");
2668
    return;
2669
    }
2670
2671
  vtkFoamDict& boundaryDictTmp = *boundaryDictPtr;
2672
2673
  // Add the internal mesh by default always
2674
  const vtkStdString tmpStr = "Internal Mesh";
2675
  this->PatchDataArraySelection->AddArray(tmpStr.c_str());
2676
2677
  // iterate through each entry in the boundary file
2678
  for(size_t i = 0; i < boundaryDictTmp.size(); i++)
2679
    {
2680
    vtkFoamEntry& boundaryEntryI = boundaryDictTmp.entry(i);
2681
    int nFaces;
2682
    boundaryEntryI.dictionary().lookup("nFaces") >> nFaces;
2683
2684
    // extract name of the current patch for insertion
2685
    const vtkStdString& boundaryNameI = boundaryEntryI.keyword();
2686
2687
    // If the size of patch becomes zero, but KeepPatches is selected,
2688
    // do not remove from list, else, remove patch from list
2689
    if(nFaces == 0)
2690
      {
2691
      if((this->PatchDataArraySelection->ArrayExists(boundaryNameI.c_str()))
2692
        && (!this->GetKeepPatches()))
2693
        {
2694
        this->PatchDataArraySelection->RemoveArrayByName(boundaryNameI.c_str());
2695
        }
2696
      }
2697
    else
2698
      {
2699
      this->PatchDataArraySelection->AddArray(boundaryNameI.c_str());
2700
      }
2701
    }
2702
  delete boundaryDictPtr;
2703
2704
  // Commented out the "RemoveAllArrays()" line....
2705
  //this->CellDataArraySelection->RemoveAllArrays();
2706
2707
  //clear prior timestep data
2708
  this->TimeStepData->value.clear();
2709
2710
  //Add scalars and vectors to metadata
2711
  //create path to current time step
2712
  vtkStdString tempPath
2713
    = *this->PathPrefix + this->TimeNames->GetValue(this->TimeStep);
2714
2715
  //open the directory and get num of files
2716
  vtkDirectory * directory = vtkDirectory::New();
2717
  if(!directory->Open(tempPath.c_str()))
2718
    {
2719
    // no data
2720
    directory->Delete();
2721
    return;
2722
    }
321
2723
322
  //add owner faces to cell
2724
  //loop over all files and locate
323
  for(int i = 0; i < (int)this->FacesOwnerCell->value.size(); i++)
2725
  //volScalars and volVectors
2726
  int nFieldFiles = directory->GetNumberOfFiles();
2727
  for(int j = 0; j < nFieldFiles; j++)
324
    {
2728
    {
325
    for(int j = 0; j < (int)this->FacesOwnerCell->value[i].size(); j++)
2729
    const vtkStdString fieldFile(directory->GetFile(j));
2730
    const int len = fieldFile.length();
2731
2732
    // excluded extensions based on src/OpenFOAM/OSspecific/Unix/Unix.C
2733
    if(!directory->FileIsDirectory(fieldFile.c_str())
2734
      && fieldFile.substr(len - 1) != "~"
2735
      && (len < 4 || (fieldFile.substr(len - 4) != ".bak"
2736
      && fieldFile.substr(len - 4) != ".BAK"
2737
      && fieldFile.substr(len - 4) != ".old"))
2738
      && (len < 5 || fieldFile.substr(len - 5) != ".save"))
326
      {
2739
      {
327
      tempFace.faceIndex = this->FacesOwnerCell->value[i][j];
2740
      vtkFoamIOobject io;
328
      tempFace.neighborFace = false;
2741
      if(io.open(tempPath + "/" + fieldFile)) // file exists and readable
329
      this->FacesOfCell->value[i].push_back(tempFace);
2742
        {
2743
        if(io.className() == "volScalarField" ||
2744
          io.className() == "volVectorField")
2745
          {
2746
          // real file name
2747
          this->TimeStepData->value.push_back(fieldFile);
2748
          // object name
2749
          this->CellDataArraySelection->AddArray(io.objectName().c_str());
2750
          }
2751
        io.close();
2752
        }
2753
#if 0
2754
      // warning is turned off in favor of silence
2755
      else
2756
        {
2757
        vtkWarningMacro(<< "File " << io.fileName().c_str()
2758
          << " is not a valid OpenFOAM object. Reason: "
2759
          << io.error().str().c_str() << " in line "
2760
          << io.lineNumber());
2761
        }
2762
#endif
330
      }
2763
      }
331
    }
2764
    }
2765
  directory->Delete();
332
2766
333
  //add neighbor faces to cell
2767
  // locate laglangian fields
334
  for(int i = 0; i < (int)this->FacesNeighborCell->value.size(); i++)
2768
335
    {
2769
  //clear prior timestep data
336
    for(int j = 0; j < (int)this->FacesNeighborCell->value[i].size(); j++)
2770
  this->LagrangianTimeStepData->value.clear();
337
      {
2771
  // Commented out the "RemoveAllArrays()" line....
338
      tempFace.faceIndex = this->FacesNeighborCell->value[i][j];
2772
  //this->PointDataArraySelection->RemoveAllArrays();
339
      tempFace.neighborFace = true;
2773
340
      this->FacesOfCell->value[i].push_back(tempFace);
2774
  //open the directory and get num of files
2775
  tempPath += "/lagrangian";
2776
  directory = vtkDirectory::New();
2777
  if(directory->Open(tempPath.c_str()))
2778
    {
2779
    nFieldFiles = directory->GetNumberOfFiles();
2780
    for(int j = 0; j < nFieldFiles; j++)
2781
      {
2782
      const vtkStdString fieldFile(directory->GetFile(j));
2783
      const int len = fieldFile.length();
2784
2785
      // excluded extensions based on src/OpenFOAM/OSspecific/Unix/Unix.C
2786
      if(!directory->FileIsDirectory(fieldFile.c_str())
2787
        && fieldFile.substr(len - 1) != "~"
2788
        && (len < 4 || (fieldFile.substr(len - 4) != ".bak"
2789
        && fieldFile.substr(len - 4) != ".BAK"
2790
        && fieldFile.substr(len - 4) != ".old"))
2791
        && (len < 5 || fieldFile.substr(len - 5) != ".save"))
2792
        {
2793
        vtkFoamIOobject io;
2794
        if(io.open(tempPath + "/" + fieldFile))
2795
          {
2796
          if(io.className() == "scalarField"
2797
            || io.className() == "vectorField")
2798
            {
2799
            // real file name
2800
            this->LagrangianTimeStepData->value.push_back(fieldFile);
2801
            // object name
2802
            this->PointDataArraySelection->AddArray(
2803
	      (vtkStdString("lagrangian/") + io.objectName()).c_str());
2804
            }
2805
          else if(io.className() == "Cloud" && io.objectName() == "positions")
2806
            {
2807
            this->PatchDataArraySelection->AddArray("Lagrangian Particles");
2808
            }
2809
          io.close();
2810
          }
2811
        }
341
      }
2812
      }
342
    }
2813
    }
2814
  directory->Delete();
343
2815
344
  //clean up memory
2816
  // refresh selection status
345
  this->FacesOwnerCell->value.clear();
2817
  this->SelectionModified();
346
  this->FacesNeighborCell->value.clear();
347
  return;
348
}
2818
}
349
2819
350
// ****************************************************************************
2820
// ****************************************************************************
351
//  Method: vtkOpenFOAMReader::MakeInternalMesh
2821
//  Method: vtkOpenFOAMReader::InsertCellToGrid
352
//
2822
//
353
//  Purpose:
2823
//  Purpose:
354
//  derive cell types and create the internal mesh
2824
//  determine cell shape and insert the cell into the mesh
2825
//  hexahedron, prism, pyramid, tetrahedron, wedge&tetWedge
355
//
2826
//
356
// ****************************************************************************
2827
// ****************************************************************************
357
vtkUnstructuredGrid * vtkOpenFOAMReader::MakeInternalMesh()
2828
void vtkOpenFOAMReader::InsertCellToGrid(vtkUnstructuredGrid* internalMesh,
2829
  int cellId, faceVectorVector *facesOfCell, intVectorVector* facesPoints)
358
{
2830
{
359
  vtkDebugMacro(<<"Make internal mesh");
2831
  // aliases
360
  //initialize variables
2832
  const vtkstd::vector<vtkstd::vector<int> >& facePoints
361
  bool foundDup = false;
2833
    = facesPoints->value;
362
  vtkstd::vector< int > cellPoints;
2834
  const vtkstd::vector<face>& cellFaces = facesOfCell->value[cellId];
363
  vtkstd::vector< int > tempFaces[2];
2835
  const size_t nCellFaces = cellFaces.size();
364
  vtkstd::vector< int > firstFace;
365
  int pivotPoint = 0;
366
  int i, j, k, l, pCount;
367
  int faceCount = 0;
368
369
  //Create Mesh
370
  vtkUnstructuredGrid *  internalMesh = vtkUnstructuredGrid::New();
371
  //loop through each cell, derive type and insert it into the mesh
372
  //hexahedron, prism, pyramid, tetrahedron, wedge&tetWedge
373
  for(i = 0; i < (int)this->FacesOfCell->value.size(); i++)  //each cell
374
    {
375
2836
376
    //calculate the total points for the cell
2837
  vtkIdList* cellPoints = vtkIdList::New();
377
    //used to derive cell type
378
    int totalPointCount = 0;
379
    for(j = 0; j < (int)this->FacesOfCell->value[i].size(); j++)  //each face
380
      {
381
      totalPointCount += 
382
        (int)this->FacePoints->
383
                 value[this->FacesOfCell->value[i][j].faceIndex].size();
384
      }
385
2838
386
    // using cell type - order points, create cell, & add to mesh
2839
  // determine type of the cell
387
    //OFhex | vtkHexahedron
2840
  // based on src/OpenFOAM/meshes/meshShapes/cellMatcher/{hex|prism|pyr|tet}-
388
    if (totalPointCount == 24)
2841
  // Matcher.C
2842
  int cellType = VTK_CONVEX_POINT_SET;
2843
  if(nCellFaces == 6)
2844
    {
2845
    size_t j = 0;
2846
    for(j = 0; j < nCellFaces; j++)
389
      {
2847
      {
390
      faceCount = 0;
2848
      if(facePoints[cellFaces[j].faceIndex].size() != 4)
391
392
      //get first face
393
      for(j = 0; j <
394
        (int)this->FacePoints->
395
                    value[this->FacesOfCell->value[i][0].faceIndex].size(); j++)
396
        {
2849
        {
397
        firstFace.push_back(this->FacePoints->value[
2850
        break;
398
          this->FacesOfCell->value[i][0].faceIndex][j]);
399
        }
2851
        }
400
2852
      }
401
      //patch: if it is a neighbor face flip the points
2853
    if(j == nCellFaces)
402
      if(this->FacesOfCell->value[i][0].neighborFace)
2854
      {
2855
      cellType = VTK_HEXAHEDRON;
2856
      }
2857
    }
2858
  else if(nCellFaces == 5)
2859
    {
2860
    int nTris = 0, nQuads = 0;
2861
    for(size_t j = 0; j < nCellFaces; j++)
2862
      {
2863
      const int nPoints = facePoints[cellFaces[j].faceIndex].size();
2864
      if(nPoints == 3)
403
        {
2865
        {
404
        int tempPop;
2866
        nTris++;
405
        for(k = 0; k < (int)firstFace.size() - 1; k++)
406
          {
407
          tempPop = firstFace[firstFace.size()-1];
408
          firstFace.pop_back();
409
          firstFace.insert(firstFace.begin()+1+k, tempPop);
410
          }
411
        }
2867
        }
412
2868
      else if(nPoints == 4)
413
      //add first face to cell points
414
      for(j =0; j < (int)firstFace.size(); j++)
415
        {
2869
        {
416
        cellPoints.push_back(firstFace[j]);
2870
        nQuads++;
417
        }
2871
        }
418
2872
      else
419
      //find the opposite face and order the points correctly
420
      for(int pointCount = 0; pointCount < (int)firstFace.size(); pointCount++)
421
        {
2873
        {
422
2874
        break;
423
        //find the other 2 faces containing each point
424
        for(j = 1; j < (int)this->FacesOfCell->value[i].size(); j++) //each face
425
          {
426
          for(k = 0; k < (int)this->FacePoints->value[
427
            this->FacesOfCell->value[i][j].faceIndex].size(); k++) //each point
428
            {
429
            if(firstFace[pointCount] == this->FacePoints->value[
430
              this->FacesOfCell->value[i][j].faceIndex][k])
431
              {
432
              //ANOTHER FACE WITH THE POINT
433
              for(l = 0; l < (int)this->FacePoints->value[
434
                this->FacesOfCell->value[i][j].faceIndex].size(); l++)
435
                {
436
                tempFaces[faceCount].push_back(this->FacePoints->value[
437
                  this->FacesOfCell->value[i][j].faceIndex][l]);
438
                }
439
              faceCount++;
440
              }
441
            }
442
          }
443
444
        //locate the pivot point contained in faces 0 & 1
445
        for(j = 0; j < (int)tempFaces[0].size(); j++)
446
          {
447
          for(k = 0; k < (int)tempFaces[1].size(); k++)
448
            {
449
            if(tempFaces[0][j] == tempFaces[1][k] && tempFaces[0][j] !=
450
              firstFace[pointCount])
451
              {
452
              pivotPoint = tempFaces[0][j];
453
              break;
454
              }
455
            }
456
          }
457
        cellPoints.push_back(pivotPoint);
458
        tempFaces[0].clear();
459
        tempFaces[1].clear();
460
        faceCount=0;
461
        }
2875
        }
462
2876
      }
463
      //create the hex cell and insert it into the mesh
2877
    if(nTris == 2 && nQuads == 3)
464
      vtkHexahedron * hexahedron= vtkHexahedron::New();
2878
      {
465
      for(pCount = 0; pCount < (int)cellPoints.size(); pCount++)
2879
      cellType = VTK_WEDGE;
2880
      }
2881
    else if(nTris == 4 && nQuads == 1)
2882
      {
2883
      cellType = VTK_PYRAMID;
2884
      }
2885
    }
2886
  else if(nCellFaces == 4)
2887
    {
2888
    size_t j = 0;
2889
    for(j = 0; j < nCellFaces; j++)
2890
      {
2891
      if(facePoints[cellFaces[j].faceIndex].size() != 3)
466
        {
2892
        {
467
        hexahedron->GetPointIds()->SetId(pCount, cellPoints[pCount]);
2893
        break;
468
        }
2894
        }
469
      internalMesh->InsertNextCell(hexahedron->GetCellType(),
470
        hexahedron->GetPointIds());
471
      hexahedron->Delete();
472
      cellPoints.clear();
473
      firstFace.clear();
474
      }
2895
      }
2896
    if(j == nCellFaces)
2897
      {
2898
      cellType = VTK_TETRA;
2899
      }
2900
    }
475
2901
476
    //OFprism | vtkWedge
2902
  // not an Hex/Wedge/Pyramid/Tetra
477
    else if (totalPointCount == 18)
2903
  if(cellType == VTK_CONVEX_POINT_SET)
2904
    {
2905
    int nPoints = 0;
2906
    for(size_t j = 0; j < nCellFaces; j++)
478
      {
2907
      {
479
      faceCount = 0;
2908
      nPoints += facePoints[cellFaces[j].faceIndex].size();
480
      int index = 0;
2909
      }
2910
    if(nPoints == 0)
2911
      {
2912
      cellType = VTK_EMPTY_CELL;
2913
      }
2914
    }
481
2915
482
      //find first triangular face
2916
  // Cell shape constructor based on the one implementd by Terry
483
      for(j = 0; j < (int)this->FacesOfCell->value[i].size(); j++)  //each face
2917
  // Jordan, with some improvements. not as elegant as the one in
2918
  // OpenFOAM but works reasonably fast.
2919
2920
  // OFhex | vtkHexahedron || OFprism | vtkWedge
2921
  if (cellType == VTK_HEXAHEDRON || cellType == VTK_WEDGE)
2922
    {
2923
    // find the base face number
2924
    size_t face0Id = 0;
2925
    if(cellType == VTK_HEXAHEDRON)
2926
      {
2927
      cellPoints->SetNumberOfIds(8);
2928
      face0Id = 0;
2929
      }
2930
    else // VTK_WEDGE
2931
      {
2932
      cellPoints->SetNumberOfIds(6);
2933
      for(size_t j = 0; j < nCellFaces; j++)
484
        {
2934
        {
485
        if((int)this->FacePoints->
2935
        if(facePoints[cellFaces[j].faceIndex].size() == 3)
486
            value[this->FacesOfCell->value[i][j].faceIndex].size() == 3)
487
          {
2936
          {
488
          for(k = 0; k < (int)this->FacePoints->value[
2937
          face0Id = j;
489
              this->FacesOfCell->value[i][j].faceIndex].size(); k++)
490
            {
491
            firstFace.push_back(this->FacePoints->value[
492
              this->FacesOfCell->value[i][j].faceIndex][k]);
493
            index = j;
494
            }
495
          break;
2938
          break;
496
          }
2939
          }
497
        }
2940
        }
2941
      }
498
2942
2943
    //get first face in correct order
2944
    const vtkstd::vector<int>& face0Points
2945
      = facePoints[cellFaces[face0Id].faceIndex];
2946
    size_t nFace0Points = face0Points.size();
2947
    vtkstd::vector<int> baseFace(nFace0Points); // ordered point list
2948
    if(cellFaces[face0Id].neighborFace)
2949
      {
499
      //patch: if it is a neighbor face flip the points
2950
      //patch: if it is a neighbor face flip the points
500
      if(this->FacesOfCell->value[i][0].neighborFace)
2951
      for(size_t j = 0; j < nFace0Points; j++)
501
        {
2952
        {
502
        int tempPop;
2953
        baseFace[j] = face0Points[nFace0Points - 1 - j];
503
        for(k = 0; k < (int)firstFace.size() - 1; k++)
2954
        //add base face to cell points
504
          {
2955
        cellPoints->SetId(j, baseFace[j]);
505
          tempPop = firstFace[firstFace.size()-1];
506
          firstFace.pop_back();
507
          firstFace.insert(firstFace.begin()+1+k, tempPop);
508
          }
509
        }
2956
        }
510
2957
      }
511
      //add first face to cell points
2958
    else
512
      for(j =0; j < (int)firstFace.size(); j++)
2959
      {
2960
      for(size_t j = 0; j < nFace0Points; j++)
513
        {
2961
        {
514
        cellPoints.push_back(firstFace[j]);
2962
        baseFace[j] = face0Points[j];
2963
        //add base face to cell points
2964
        cellPoints->SetId(j, baseFace[j]);
515
        }
2965
        }
2966
      }
516
2967
517
      //find the opposite face and order the points correctly
2968
    //find the opposite face points and order the points correctly
518
      for(int pointCount = 0; pointCount < (int)firstFace.size(); pointCount++)
2969
    const size_t nBaseFacePoints = baseFace.size();
2970
    for(size_t pointCount = 0; pointCount < nBaseFacePoints; pointCount++)
2971
      {
2972
      int pivotPoint = -1;
2973
      const int baseFacePointI = baseFace[pointCount];
2974
      for(size_t j = 0; j < nCellFaces; j++) //each face
519
        {
2975
        {
520
        //find the 2 other faces containing each point
2976
        if(j == face0Id)
521
        for(j = 0; j < (int)this->FacesOfCell->value[i].size(); j++) //each face
2977
          {
2978
          continue;
2979
          }
2980
        const vtkstd::vector<int>& faceJPoints
2981
          = facePoints[cellFaces[j].faceIndex];
2982
        const size_t sizeK = faceJPoints.size();
2983
        if(sizeK == 3) // omit the other triangular wedge face
2984
          {
2985
          continue;
2986
          }
2987
        for(size_t k = 0; k < sizeK; k++) //each point
522
          {
2988
          {
523
          for(k = 0; k < (int)this->FacePoints->value[
2989
          // if the point matches the point of the base face...
524
              this->FacesOfCell->value[i][j].faceIndex].size(); k++)
2990
          if(baseFacePointI == faceJPoints[k])
525
            {
2991
            {
526
            if(firstFace[pointCount] == this->FacePoints->value[
2992
            const bool isNeighbor = cellFaces[j].neighborFace;
527
               this->FacesOfCell->value[i][j].faceIndex][k] && j != index)
2993
            const int faceJPrevPoint = faceJPoints[(sizeK + k - 1) % sizeK];
2994
            const int faceJNextPoint = faceJPoints[(k + 1) % sizeK];
2995
            const int baseFacePrevPoint = baseFace[(nBaseFacePoints
2996
              + pointCount - 1) % nBaseFacePoints];
2997
            const int baseFaceNextPoint
2998
              = baseFace[(pointCount + 1) % nBaseFacePoints];
2999
3000
            // if the next point of the j-th face matches the
3001
            // previous point of the base face use the previous
3002
            // point of the j-th face as the pivot point and use the
3003
            // next point otherwise
3004
            if(faceJNextPoint == (isNeighbor ? baseFaceNextPoint
3005
              : baseFacePrevPoint))
528
              {
3006
              {
529
              //ANOTHER FACE WITH POINT
3007
              pivotPoint = faceJPrevPoint;
530
              for(l = 0; l < (int)this->FacePoints->value[
531
                  this->FacesOfCell->value[i][j].faceIndex].size(); l++)
532
                {
533
                tempFaces[faceCount].push_back(this->FacePoints->value[
534
                  this->FacesOfCell->value[i][j].faceIndex][l]);
535
                }
536
              faceCount++;
537
              }
3008
              }
538
            }
3009
            else
539
          }
3010
              {
3011
              pivotPoint = faceJNextPoint;
3012
              }
3013
            cellPoints->SetId(nBaseFacePoints + pointCount, pivotPoint);
540
3014
541
        //locate the pivot point of faces 0 & 1
3015
            // we further look at one more vertex:
542
        for(j = 0; j < (int)tempFaces[0].size(); j++)
3016
            // if the j-th face also shares next point of the base face
543
          {
3017
            // add the corresponding opposite point to cell points
544
          for(k = 0; k < (int)tempFaces[1].size(); k++)
3018
            if(pointCount < nBaseFacePoints - 1 && baseFaceNextPoint
545
            {
3019
              == (isNeighbor ? faceJNextPoint : faceJPrevPoint))
546
            if(tempFaces[0][j] == tempFaces[1][k] && tempFaces[0][j] !=
547
              firstFace[pointCount])
548
              {
3020
              {
549
              pivotPoint = tempFaces[0][j];
3021
              pointCount++;
550
              break;
3022
              cellPoints->SetId(nBaseFacePoints + pointCount,
3023
                faceJPoints[(k + 2) % sizeK]);
551
              }
3024
              }
3025
            break; // look no more points as to the face
552
            }
3026
            }
553
          }
3027
          }
554
        cellPoints.push_back(pivotPoint);
3028
        if(pivotPoint >= 0) // break if the pivot point is found
555
        tempFaces[0].clear();
556
        tempFaces[1].clear();
557
        faceCount=0;
558
        }
559
560
      //create the wedge cell and insert it into the mesh
561
      vtkWedge * wedge= vtkWedge::New();
562
      for(pCount = 0; pCount < (int)cellPoints.size(); pCount++)
563
        {
564
        wedge->GetPointIds()->SetId(pCount, cellPoints[pCount]);
565
        }
566
      internalMesh->InsertNextCell(wedge->GetCellType(),
567
        wedge->GetPointIds());
568
      cellPoints.clear();
569
      wedge->Delete();
570
      firstFace.clear();
571
      }
572
573
    //OFpyramid | vtkPyramid
574
    else if (totalPointCount == 16)
575
      {
576
      foundDup = false;
577
578
      //find the quadratic face
579
      for(j = 0; j < (int)this->FacesOfCell->value[i].size(); j++)  //each face
580
        {
581
        if((int)this->FacePoints->
582
            value[this->FacesOfCell->value[i][j].faceIndex].size() == 4)
583
          {
3029
          {
584
          for(k = 0; k < (int)this->FacePoints->value[
585
              this->FacesOfCell->value[i][j].faceIndex].size(); k++)
586
            {
587
            cellPoints.push_back(this->FacePoints->value[
588
              this->FacesOfCell->value[i][j].faceIndex][k]);
589
            }
590
          break;
3030
          break;
591
          }
3031
          }
592
        }
3032
        }
3033
      }
3034
    //create the hex cell and insert it into the mesh
3035
    internalMesh->InsertNextCell(cellType, cellPoints);
3036
    }
593
3037
594
      //compare first face points to other faces
3038
  //OFpyramid | vtkPyramid || OFtet | vtkTetrahedron
595
      for(j = 0; j < (int)cellPoints.size(); j++) //each point
3039
  else if (cellType == VTK_PYRAMID || cellType == VTK_TETRA)
3040
    {
3041
    int baseFaceId = -1;
3042
    if(cellType == VTK_PYRAMID)
3043
      {
3044
      for(size_t j = 0; j < nCellFaces; j++)
596
        {
3045
        {
597
        for(k = 0; k < (int)this->FacePoints->value[
3046
        if(facePoints[cellFaces[j].faceIndex].size() == 4)
598
          this->FacesOfCell->value[i][1].faceIndex].size(); k++)
599
          {
600
          if(cellPoints[j] == this->FacePoints->value[
601
            this->FacesOfCell->value[i][1].faceIndex][k])
602
            {
603
            foundDup = true;
604
            }
605
          }
606
        if(!foundDup)
607
          {
3047
          {
608
          cellPoints.push_back(this->FacePoints->value[
3048
          baseFaceId = j;
609
            this->FacesOfCell->value[i][j].faceIndex][k]);
610
          break;
3049
          break;
611
          }
3050
          }
612
        }
3051
        }
613
3052
      cellPoints->SetNumberOfIds(5);
614
      //create the pyramid cell and insert it into the mesh
615
      vtkPyramid * pyramid = vtkPyramid::New();
616
      for(pCount = 0; pCount < (int)cellPoints.size(); pCount++)
617
        {
618
        pyramid->GetPointIds()->SetId(pCount, cellPoints[pCount]);
619
        }
620
      internalMesh->InsertNextCell(pyramid->GetCellType(),
621
        pyramid->GetPointIds());
622
      cellPoints.clear();
623
      pyramid->Delete();
624
      }
3053
      }
625
3054
    else // VTK_TETRA
626
    //OFtet | vtkTetrahedron
627
    else if (totalPointCount == 12)
628
      {
3055
      {
629
      foundDup = false;
3056
      baseFaceId = 0;
3057
      cellPoints->SetNumberOfIds(4);
3058
      }
630
3059
631
      //add first face to cell points
3060
    //add first face to cell points
632
      for(j = 0; j < (int)this->FacePoints->value[
3061
    const vtkstd::vector<int>& baseFacePoints
633
        this->FacesOfCell->value[i][0].faceIndex].size(); j++)
3062
      = facePoints[cellFaces[baseFaceId].faceIndex];
3063
    const size_t nBaseFacePoints = baseFacePoints.size();
3064
    if(cellFaces[baseFaceId].neighborFace)
3065
      {
3066
      // if it is a neighbor face flip the points
3067
      for(size_t j = 0; j < nBaseFacePoints; j++)
634
        {
3068
        {
635
        cellPoints.push_back(this->FacePoints->value[
3069
        cellPoints->SetId(j, baseFacePoints[nBaseFacePoints - 1 - j]);
636
          this->FacesOfCell->value[i][0].faceIndex][j]);
637
        }
3070
        }
638
3071
      }
639
      //compare first face to the points of second face
3072
    else
640
      for(j = 0; j < (int)cellPoints.size(); j++) //each point
3073
      {
3074
      for(size_t j = 0; j < nBaseFacePoints; j++)
641
        {
3075
        {
642
        for(k = 0; k < (int)this->FacePoints->value[
3076
        cellPoints->SetId(j, baseFacePoints[j]);
643
          this->FacesOfCell->value[i][1].faceIndex].size(); k++)
644
          {
645
          if(cellPoints[j] == this->FacePoints->value[
646
            this->FacesOfCell->value[i][1].faceIndex][k])
647
            {
648
            foundDup = true;
649
            }
650
          }
651
        if(!foundDup)
652
          {
653
          cellPoints.push_back(this->FacePoints->value[
654
            this->FacesOfCell->value[i][j].faceIndex][k]);
655
          break;
656
          }
657
        }
3077
        }
3078
      }
658
3079
659
      //create the wedge cell and insert it into the mesh
3080
    // compare an adjacent face (any non base face is ok) point 1 to
660
      vtkTetra * tetra = vtkTetra::New();
3081
    // base face points
661
      for(pCount = 0; pCount < (int)cellPoints.size(); pCount++)
3082
    const int adjacentFaceId = (baseFaceId == 0) ? 1 : baseFaceId - 1;
3083
    const vtkstd::vector<int>& adjacentFacePoints
3084
      = facePoints[cellFaces[adjacentFaceId].faceIndex];
3085
    const int adjacentFacePoint1 = adjacentFacePoints[1];
3086
    bool foundDup = false;
3087
    for(size_t j = 0; j < nBaseFacePoints; j++)
3088
      {
3089
      // if point 1 of the adjacent face matchs point j of the base face...
3090
      if(cellPoints->GetId(j) == adjacentFacePoint1)
662
        {
3091
        {
663
        tetra->GetPointIds()->SetId(pCount, cellPoints[pCount]);
3092
        // if point 2 of the adjacent face matches the previous point
3093
        // of the base face use point 0 of the adjacent face as the
3094
        // pivot point; use point 2 otherwise
3095
        cellPoints->SetId(nBaseFacePoints, (adjacentFacePoints[2]
3096
          == cellPoints->GetId((cellFaces[adjacentFaceId].neighborFace
3097
          ? (j + 1) : (nBaseFacePoints + j - 1)) % nBaseFacePoints)) ? 
3098
          adjacentFacePoints[0] : adjacentFacePoints[2]);
3099
        foundDup = true;
3100
        break;
664
        }
3101
        }
665
      internalMesh->InsertNextCell(tetra->GetCellType(),
666
        tetra->GetPointIds());
667
      cellPoints.clear();
668
      tetra->Delete();
669
      }
3102
      }
670
3103
    // if point 1 of the adjacent face does not match any points of
671
    //erronous cells
3104
    // the base face, it's the pivot point
672
    else if(totalPointCount == 0)
3105
    if(!foundDup)
673
      {
3106
      {
674
      vtkWarningMacro("Warning: No points in cell.");
3107
      cellPoints->SetId(nBaseFacePoints, adjacentFacePoint1);
675
      }
3108
      }
676
3109
677
    //OFpolyhedron || vtkConvexPointSet
3110
    //create the tetra cell and insert it into the mesh
678
    else
3111
    internalMesh->InsertNextCell(cellType, cellPoints);
679
      {
3112
    }
680
      vtkWarningMacro("Warning: Polyhedral Data is very Slow!");
681
      foundDup = false;
682
3113
683
      //get first face
3114
  //erronous cells
684
      for(j = 0; j < (int)this->FacePoints->value[
3115
  else if(cellType == VTK_EMPTY_CELL)
685
        this->FacesOfCell->value[i][0].faceIndex].size(); j++)
3116
    {
3117
    vtkWarningMacro("Warning: No points in cell.");
3118
    }
3119
3120
  //OFpolyhedron || vtkConvexPointSet
3121
  else
3122
    {
3123
    // vtkWarningMacro("Warning: Polyhedral Data is very Slow!");
3124
3125
    //get first face
3126
    const vtkstd::vector<int>& baseFacePoints
3127
      = facePoints[cellFaces[0].faceIndex];
3128
    const size_t nBaseFacePoints = baseFacePoints.size();
3129
    //add first face to cell points
3130
    // not sure if flipping is necessary but do it anyway
3131
    if(cellFaces[0].neighborFace)
3132
      {
3133
      // if it is a neighbor face flip the points
3134
      for(size_t j = 0; j < nBaseFacePoints; j++)
686
        {
3135
        {
687
        firstFace.push_back(this->FacePoints->value[
3136
        cellPoints->InsertNextId(baseFacePoints[nBaseFacePoints - 1 - j]);
688
          this->FacesOfCell->value[i][0].faceIndex][j]);
689
        }
3137
        }
690
3138
      }
691
      //add first face to cell points
3139
    else
692
      for(j =0; j < (int)firstFace.size(); j++)
3140
      {
3141
      for(size_t j = 0; j < nBaseFacePoints; j++)
693
        {
3142
        {
694
        cellPoints.push_back(firstFace[j]);
3143
        cellPoints->InsertNextId(baseFacePoints[j]);
695
        }
3144
        }
3145
      }
696
3146
697
      //loop through faces and create a list of all points
3147
    //loop through faces and create a list of all points
698
      //j = 1 skip firstFace
3148
    //j = 1 skip baseFace
699
      for(j = 1; j < (int)this->FacesOfCell->value[i].size(); j++)
3149
    for(size_t j = 1; j < nCellFaces; j++)
3150
      {
3151
      //remove duplicate points from faces
3152
      const vtkstd::vector<int>& faceJPoints
3153
        = facePoints[cellFaces[j].faceIndex];
3154
      const size_t nFaceJPoints = faceJPoints.size();
3155
      for(size_t k = 0; k < nFaceJPoints; k++)
700
        {
3156
        {
701
        //remove duplicate points from faces
3157
        const int faceJPointK = faceJPoints[k];
702
        for(k = 0; k < (int)this->FacePoints->value[
3158
        bool foundDup = false;
703
          this->FacesOfCell->value[i][j].faceIndex].size(); k++)
3159
        for(int l = 0; l < cellPoints->GetNumberOfIds(); l++)
704
          {
3160
          {
705
          for(l = 0; l < (int)cellPoints.size(); l++);
3161
          if(cellPoints->GetId(l) == faceJPointK)
706
            {
707
            if(cellPoints[l] == this->FacePoints->value[
708
              this->FacesOfCell->value[i][j].faceIndex][k])
709
              {
710
              foundDup = true;
711
              }
712
            }
713
          if(!foundDup)
714
            {
3162
            {
715
            cellPoints.push_back(this->FacePoints->value[
3163
            foundDup = true;
716
              this->FacesOfCell->value[i][j].faceIndex][k]);
3164
            break; // look no more
717
            foundDup = false;
718
            }
3165
            }
719
          }
3166
          }
3167
        if(!foundDup)
3168
          {
3169
          cellPoints->InsertNextId(faceJPointK);
3170
          }
720
        }
3171
        }
721
722
      //create the poly cell and insert it into the mesh
723
      vtkConvexPointSet * poly = vtkConvexPointSet::New();
724
      poly->GetPointIds()->SetNumberOfIds(cellPoints.size());
725
      for(pCount = 0; pCount < (int)cellPoints.size(); pCount++)
726
        {
727
        poly->GetPointIds()->SetId(pCount, cellPoints[pCount]);
728
        }
729
      internalMesh->InsertNextCell(poly->GetCellType(),
730
        poly->GetPointIds());
731
      cellPoints.clear();
732
      firstFace.clear();
733
      poly->Delete();
734
      }
3172
      }
735
    }
736
3173
737
  //set the internal mesh points
3174
    //create the poly cell and insert it into the mesh
738
  internalMesh->SetPoints(Points);
3175
    internalMesh->InsertNextCell(VTK_CONVEX_POINT_SET, cellPoints);
739
  vtkDebugMacro(<<"Internal mesh made");
3176
    }
740
  return internalMesh;
3177
  cellPoints->Delete();
741
}
3178
}
742
3179
743
// ****************************************************************************
3180
// ****************************************************************************
744
//  Method: vtkOpenFOAMReader::ControlDictDataParser
3181
//  Method: vtkOpenFOAMReader::MakeInternalMesh
745
//
3182
//
746
//  Purpose:
3183
//  Purpose:
747
//  parse out double values for controlDict entries
3184
//  derive cell types and create the internal mesh
748
//  utility function
749
//
3185
//
750
// ****************************************************************************
3186
// ****************************************************************************
751
double vtkOpenFOAMReader::ControlDictDataParser(const char * lineIn)
3187
vtkUnstructuredGrid * vtkOpenFOAMReader::MakeInternalMesh(
3188
  faceVectorVector *facesOfCell, intVectorVector* facesPoints,
3189
  vtkPoints* points)
752
{
3190
{
753
  double value;
3191
  vtkDebugMacro(<<"Make internal mesh");
754
  vtkstd::string line(lineIn);
755
  line.erase(line.begin()+line.find(";"));
756
  vtkstd::string token;
757
  vtksys_ios::stringstream tokenizer(line);
758
3192
759
  //parse to the final entry - double
3193
  //Create Mesh
760
  //while(tokenizer>>token);
3194
  vtkUnstructuredGrid* internalMesh = vtkUnstructuredGrid::New();
761
  while(!tokenizer.eof())
3195
  internalMesh->Allocate(facesOfCell->value.size());
3196
3197
  //loop through each cell, derive type and insert it into the mesh
3198
  //hexahedron, prism, pyramid, tetrahedron, wedge&tetWedge
3199
  for(size_t i = 0; i < facesOfCell->value.size(); i++)  //each cell
762
    {
3200
    {
763
    tokenizer >> token;
3201
    this->InsertCellToGrid(internalMesh, i, facesOfCell, facesPoints);
764
    }
3202
    }
3203
  //set the internal mesh points
3204
  internalMesh->SetPoints(points);
3205
  vtkDebugMacro(<<"Internal mesh made");
765
3206
766
  vtksys_ios::stringstream conversion(token);
3207
  return internalMesh;
767
  conversion >> value;
768
  return value;
769
}
3208
}
770
3209
771
// ****************************************************************************
3210
// List time directories according to controlDict
772
//  Method: vtkOpenFOAMReader::ReadControlDict
3211
bool vtkOpenFOAMReader::ListTimeDirectoriesByControlDict(vtkFoamDict* dictPtr)
773
//
774
//  Pupose:
775
//  reads the controlDict File
776
//  gather the necessary information to create a path to the data
777
//
778
// ****************************************************************************
779
void vtkOpenFOAMReader::ReadControlDict ()
780
{
3212
{
781
  vtkDebugMacro(<<"Read controlDict");
3213
  vtkFoamDict& dict = *dictPtr;
782
  //create variables
783
  vtkstd::string temp;
784
  double startTime;
785
  double endTime;
786
  double deltaT;
787
  double writeInterval;
788
  double timeStepIncrement;
789
  vtkstd::string writeControl;
790
  vtkstd::string timeFormat;
791
  stdString* tempStringStruct;
792
793
  ifstream * input = new ifstream(this->Path->value.c_str(), ios::in VTK_IOS_NOCREATE);
794
795
  //create the path to the data directory
796
  this->PathPrefix->value = this->Path->value;
797
  this->PathPrefix->value.erase(this->PathPrefix->value.begin()+
798
    this->PathPrefix->value.find("system"),this->PathPrefix->value.end());
799
  vtkDebugMacro(<<"Path: "<<this->PathPrefix->value.c_str());
800
801
  //find Start Time
802
  tempStringStruct = this->GetLine(input);
803
  temp = tempStringStruct->value;
804
  delete tempStringStruct;
805
3214
806
  //while(!(temp.compare(0,8,"startTime",0,8) == 0))
3215
  vtkFoamEntry& startTimeEntry = dict.lookup("startTime");
807
  while (strcmp(temp.substr(0,9).c_str(), "startTime"))
3216
  if(!startTimeEntry.found())
808
    {
3217
    {
809
    tempStringStruct = this->GetLine(input);
3218
    vtkErrorMacro(<< "startTime entry not found in controlDict");
810
    temp = tempStringStruct->value;
3219
    return false;
811
    delete tempStringStruct;
812
    }
3220
    }
813
  startTime = this->ControlDictDataParser(temp.c_str());
3221
  double startTime;
814
  vtkDebugMacro(<<"Start time: "<<startTime);
3222
  startTimeEntry >> startTime;
815
3223
816
  //find End Time
3224
  vtkFoamEntry& endTimeEntry = dict.lookup("endTime");
817
  //while(!(temp.compare(0,6,"endTime",0,6) == 0))
3225
  if(!endTimeEntry.found())
818
  while (strcmp(temp.substr(0,7).c_str(), "endTime"))
819
    {
3226
    {
820
    tempStringStruct = this->GetLine(input);
3227
    vtkErrorMacro(<< "endTime entry not found in controlDict");
821
    temp = tempStringStruct->value;
3228
    return false;
822
    delete tempStringStruct;
823
    }
3229
    }
824
  endTime = this->ControlDictDataParser(temp.c_str());
3230
  double endTime;
825
  vtkDebugMacro(<<"End time: "<<endTime);
3231
  endTimeEntry >> endTime;
826
3232
827
  //find Delta T
3233
  vtkFoamEntry& deltaTEntry = dict.lookup("deltaT");
828
  //while(!(temp.compare(0,5,"deltaT",0,5) == 0))
3234
  if(!deltaTEntry.found())
829
  while (strcmp(temp.substr(0,6).c_str(), "deltaT"))
830
    {
3235
    {
831
    tempStringStruct = this->GetLine(input);
3236
    vtkErrorMacro(<< "deltaT entry not found in controlDict");
832
    temp = tempStringStruct->value;
3237
    return false;
833
    delete tempStringStruct;
834
    }
3238
    }
835
  deltaT = this->ControlDictDataParser(temp.c_str());
3239
  double deltaT;
836
  vtkDebugMacro(<<"deltaT: "<<deltaT);
3240
  deltaTEntry >> deltaT;
837
3241
838
  //find write control
3242
  vtkFoamEntry& writeIntervalEntry = dict.lookup("writeInterval");
839
  //while(!(temp.compare(0,11,"writeControl",0,11) == 0))
3243
  if(!writeIntervalEntry.found())
840
  while (strcmp(temp.substr(0,12).c_str(), "writeControl"))
841
    {
3244
    {
842
    tempStringStruct = this->GetLine(input);
3245
    vtkErrorMacro(<< "writeInterval entry not found in controlDict");
843
    temp = tempStringStruct->value;
3246
    return false;
844
    delete tempStringStruct;
845
    }
3247
    }
3248
  double writeInterval;
3249
  writeIntervalEntry >> writeInterval;
846
3250
847
  temp.erase(temp.begin()+temp.find(";"));
3251
  vtkFoamEntry& timeFormatEntry = dict.lookup("timeFormat");
848
  vtkstd::string token;
3252
  if(!timeFormatEntry.found())
849
  vtksys_ios::stringstream tokenizer(temp);
850
851
  //while(tokenizer >> token);
852
  while(!tokenizer.eof())
853
    {
3253
    {
854
    tokenizer >> token;
3254
    vtkErrorMacro(<< "timeFormat entry not found in controlDict");
3255
    return false;
855
    }
3256
    }
856
  writeControl = token;
3257
  vtkStdString timeFormat;
857
  vtkDebugMacro(<<"Write control: "<<writeControl.c_str());
3258
  timeFormatEntry >> timeFormat;
858
3259
859
  //find write interval
3260
  vtkFoamEntry& timePrecisionEntry = dict.lookup("timePrecision");
860
  //while(!(temp.compare(0,12,"writeInterval",0,12) == 0))
3261
  int timePrecision;
861
  while (strcmp(temp.substr(0,13).c_str(), "writeInterval"))
3262
  if(timePrecisionEntry.found())
3263
    {
3264
    timePrecisionEntry >> timePrecision;
3265
    }
3266
  else
862
    {
3267
    {
863
    tempStringStruct = this->GetLine(input);
3268
    timePrecision = 6; // the default value
864
    temp = tempStringStruct->value;
865
    delete tempStringStruct;
866
    }
3269
    }
867
  writeInterval = this->ControlDictDataParser(temp.c_str());
868
  vtkDebugMacro(<<"Write interval: "<<writeInterval);
869
3270
870
  //calculate the time step increment based on type of run
3271
  //calculate the time step increment based on type of run
871
  //if(writeControl.compare(0,7,"timeStep",0,7) == 0)
3272
  vtkStdString writeControl;
872
  if(!strcmp(writeControl.substr(0,8).c_str(), "timeStep"))
3273
  dict.lookup("writeControl") >> writeControl;
3274
  double timeStepIncrement;
3275
  if(writeControl == "timeStep")
873
    {
3276
    {
874
    vtkDebugMacro(<<"Time step type data");
3277
    vtkDebugMacro(<<"Time step type data");
875
    timeStepIncrement = writeInterval * deltaT;
3278
    timeStepIncrement = writeInterval * deltaT;
876
    }
3279
    }
877
  else
3280
  else if(writeControl == "runTime" || writeControl == "adjustableRunTime")
878
    {
3281
    {
879
    vtkDebugMacro(<<"Run time type data");
3282
    vtkDebugMacro(<<"Run time type data");
880
    timeStepIncrement = writeInterval;
3283
    timeStepIncrement = writeInterval;
881
    }
3284
    }
882
3285
  else
883
  //find time format
884
  while(temp.find("timeFormat") == vtkstd::string::npos)
885
    {
3286
    {
886
    tempStringStruct = this->GetLine(input);
3287
    vtkErrorMacro(<<"Time step can't be determined because writeControl is"
887
    temp = tempStringStruct->value;
3288
      " set to " << writeControl.c_str());
888
    delete tempStringStruct;
3289
    return false;
889
    }
3290
    }
890
  timeFormat = temp;
891
3291
892
  //calculate how many timesteps there should be
3292
  //calculate how many timesteps there should be
893
  float tempResult = ((endTime-startTime)/timeStepIncrement);
3293
  double tempResult = (endTime - startTime) / timeStepIncrement;
894
  int tempNumTimeSteps = (int)(tempResult+0.5)+1;  //+0.1 to round up
3294
  int tempNumTimeSteps = (int)(tempResult + 0.5) + 1;  //+0.1 to round up
3295
895
  //make sure time step dir exists
3296
  //make sure time step dir exists
896
  vtkstd::vector< double > tempSteps;
3297
  vtkstd::vector< double > tempSteps;
897
  vtkDirectory * test = vtkDirectory::New();
3298
  vtkDirectory * test = vtkDirectory::New();
898
  vtksys_ios::stringstream parser;
3299
  this->TimeNames->Initialize();
899
  double tempStep;
900
  for(int i = 0; i < tempNumTimeSteps; i++)
3300
  for(int i = 0; i < tempNumTimeSteps; i++)
901
    {
3301
    {
902
    tempStep = i*timeStepIncrement + startTime;
3302
    vtkstd::ostringstream parser;
903
    parser.clear();
3303
    const double tempStep = i * timeStepIncrement + startTime;
904
    if(timeFormat.find("general") != vtkstd::string::npos)
3304
3305
    // determine time name based on Foam::Time::timeName()
3306
    // in src/OpenFOAM/db/Time/Time.C
3307
#ifdef _MSC_VER
3308
    bool correctExponent = true;
3309
#endif
3310
    if(timeFormat == "general")
3311
      {
3312
      // "do not use std:: or vtkstd:: when using anything declared in
3313
      // iostream," according to VTK coding standards, but following
3314
      // the instruction causes errors...
3315
      parser.setf(vtkstd::ios_base::fmtflags(0), vtkstd::ios_base::floatfield);
3316
      }
3317
    else if(timeFormat == "fixed")
3318
      {
3319
      parser.setf(vtkstd::ios_base::fmtflags(vtkstd::ios_base::fixed),
3320
        vtkstd::ios_base::floatfield);
3321
#ifdef _MSC_VER
3322
      correctExponent = false;
3323
#endif
3324
      }
3325
    else if(timeFormat == "scientific")
3326
      {
3327
      parser.setf(vtkstd::ios_base::fmtflags(vtkstd::ios_base::scientific),
3328
        vtkstd::ios_base::floatfield);
3329
      }
3330
    else
905
      {
3331
      {
906
      parser << tempStep;
3332
      vtkWarningMacro("Warning: unsupported time format. Assuming general.");
3333
      parser.setf(vtkstd::ios_base::fmtflags(0), vtkstd::ios_base::floatfield);
3334
      }
3335
    parser.precision(timePrecision);
3336
    parser << tempStep; // stringstream doesn't require ends
3337
#ifdef _MSC_VER
3338
    // workaround for format difference in MSVC++:
3339
    // remove an extra 0 from exponent
3340
    if(correctExponent)
3341
      {
3342
      vtkStdString tempStr(parser.str());
3343
      size_t pos = tempStr.find('e');
3344
      if(pos != vtkStdString::npos && tempStr.length() >= pos + 3
3345
        && tempStr[pos + 2] == '0')
3346
        {
3347
        tempStr.erase(pos + 2, 1);
3348
        parser.str(tempStr);
3349
        }
907
      }
3350
      }
908
    else
3351
#endif
3352
    if(test->Open((*this->PathPrefix + parser.str()).c_str()))
909
      {
3353
      {
910
      parser << ios::scientific <<tempStep;
3354
      tempSteps.push_back(tempStep);
3355
      this->TimeNames->InsertNextValue(parser.str());
911
      }
3356
      }
912
    if(test->Open((this->PathPrefix->value+parser.str().c_str()).c_str()))
3357
    // necessary for reading the case/0 directory whatever the timeFormat is
3358
    // based on Foam::Time::operator++() in src/OpenFOAM/db/Time/Time.C
3359
    else if((fabs(tempStep) < 1.0e-14L) // 10*SMALL
3360
      && test->Open((*this->PathPrefix + vtkStdString("0")).c_str()))
913
      {
3361
      {
914
      tempSteps.push_back(tempStep);
3362
      tempSteps.push_back(tempStep);
3363
      this->TimeNames->InsertNextValue(vtkStdString("0"));
915
      }
3364
      }
916
    }
3365
    }
917
  test->Delete();
3366
  test->Delete();
3367
  this->TimeNames->Squeeze();
918
3368
919
  //Add the time steps that actually exist to steps
3369
  //Add the time steps that actually exist to steps
920
  //allows the run to be stopped short of controlDict spec
3370
  //allows the run to be stopped short of controlDict spec
921
  //allows for removal of timesteps
3371
  //allows for removal of timesteps
922
  this->NumberOfTimeSteps = tempSteps.size();
3372
  this->NumberOfTimeSteps = tempSteps.size();
923
  this->Steps = new double[this->NumberOfTimeSteps];
3373
  if(this->NumberOfTimeSteps > 0)
924
  for(int i = 0; i < this->NumberOfTimeSteps; i++)
3374
    {
3375
    this->Steps = new double[this->NumberOfTimeSteps];
3376
    for(int i = 0; i < this->NumberOfTimeSteps; i++)
3377
      {
3378
      this->Steps[i] = tempSteps[i];
3379
      }
3380
    }
3381
  else
925
    {
3382
    {
926
    this->Steps[i] =tempSteps[i];
3383
    // dummy for safely deleting later
3384
    this->Steps = new double[1];
3385
    this->Steps[0] = 0.0;
927
    }
3386
    }
3387
  return true;
3388
}
928
3389
929
  input->close();
3390
// list time directories by searching all valid time instances in a
930
  delete input;
3391
// case directory
931
  vtkDebugMacro(<<"controlDict read");
3392
bool vtkOpenFOAMReader::ListTimeDirectoriesByInstances()
932
  return;
3393
{
3394
  // open the case directory
3395
  vtkDirectory* test = vtkDirectory::New();
3396
  if(!test->Open(this->PathPrefix->c_str()))
3397
    {
3398
    test->Delete();
3399
    vtkErrorMacro(<<"Can't open directory "<<this->PathPrefix->c_str());
3400
    return false;
3401
    }
3402
3403
  // search all the directories in the case directory and detect
3404
  // directories with names convertible to numbers
3405
  this->TimeNames->Initialize();
3406
  vtkDoubleArray* timeValues = vtkDoubleArray::New();
3407
  const int nFiles = test->GetNumberOfFiles();
3408
  for(int i = 0; i < nFiles; i++)
3409
    {
3410
    const vtkStdString dir = test->GetFile(i);
3411
    if(test->FileIsDirectory(dir.c_str()))
3412
      {
3413
      // check if the name is convertible to a number
3414
      bool isTimeDir = true;
3415
      for(size_t j = 0; j < dir.length(); j++)
3416
        {
3417
        const char c = dir[j];
3418
        if(!isdigit(c) && c != '+' && c != '-' && c != '.' && c != 'e'
3419
          && c != 'E')
3420
          {
3421
          isTimeDir = false;
3422
          break;
3423
          }
3424
        }
3425
      if(!isTimeDir)
3426
        {
3427
        continue;
3428
        }
3429
3430
      // convert to a number
3431
      char *endptr;
3432
      double timeValue = strtod(dir.c_str(), &endptr);
3433
      // check if the value really was converted to a number
3434
      if(timeValue == 0.0 && endptr == dir.c_str())
3435
        {
3436
        continue;
3437
        }
3438
3439
      // add to the instance list
3440
      timeValues->InsertNextValue(timeValue);
3441
      this->TimeNames->InsertNextValue(dir);
3442
      }
3443
    }
3444
  test->Delete();
3445
  this->TimeNames->Squeeze();
3446
3447
  // sort the detected time directories and set as timesteps
3448
  this->NumberOfTimeSteps = this->TimeNames->GetSize();
3449
  if(this->NumberOfTimeSteps > 0)
3450
    {
3451
    if(this->NumberOfTimeSteps > 1)
3452
      {
3453
      vtkSortDataArray::Sort(timeValues, this->TimeNames);
3454
      }
3455
    this->Steps = new double[this->NumberOfTimeSteps];
3456
    for(int i = 0; i < this->NumberOfTimeSteps; i++)
3457
      {
3458
      this->Steps[i] = timeValues->GetValue(i);
3459
      }
3460
    }
3461
  else
3462
    {
3463
    // dummy for safely deleting later
3464
    this->Steps = new double[1];
3465
    this->Steps[0] = 0.0;
3466
    }
3467
  timeValues->Delete();
3468
3469
  return true;
933
}
3470
}
934
3471
935
// ****************************************************************************
3472
// ****************************************************************************
936
//  Method: vtkOpenFOAMReader::GetPoints
3473
//  Method: vtkOpenFOAMReader::ReadControlDict
937
//
3474
//
938
//  Purpose:
3475
//  Pupose:
939
//  read the points file into a vtkPoints
3476
//  reads the controlDict File
3477
//  gather the necessary information to create a path to the data
940
//
3478
//
941
// ****************************************************************************
3479
// ****************************************************************************
942
void vtkOpenFOAMReader::GetPoints (int timeState)
3480
bool vtkOpenFOAMReader::ReadControlDict(const char* pathIn)
943
{
3481
{
944
  //path to points file
3482
  vtkStdString path(pathIn);
945
  vtkstd::string pointPath = this->PathPrefix->value +
3483
  vtkFoamIOobject io;
946
                             this->PolyMeshPointsDir->value[timeState] +
947
                             "/polyMesh/points";
948
  vtkDebugMacro(<<"Read points file: "<<pointPath.c_str());
949
3484
950
  vtkstd::string temp;
3485
  if(!io.open(path))
951
  bool binaryWriteFormat;
952
  stdString* tempStringStruct;
953
  ifstream * input = new ifstream(pointPath.c_str(), ios::in VTK_IOS_NOCREATE);
954
  //make sure file exists
955
  if(input->fail())
956
    {
3486
    {
957
    input->close();
3487
    vtkErrorMacro(<<"Error opening " << io.fileName().c_str() << ": "
958
    delete input;
3488
      << io.error().str().c_str());
959
    return;
3489
    return false;
960
    }
3490
    }
961
3491
  vtkFoamDict dict;
962
  //determine if file is binary or ascii
3492
  if(!dict.read(io))
963
  while(temp.find("format") == vtkstd::string::npos)
3493
    {
3494
    vtkErrorMacro(<<"Error reading line " << io.lineNumber()
3495
      << " of " << io.fileName().c_str() << ": " << io.error().str().c_str());
3496
    return false;
3497
    }
3498
  if(dict.type() != vtkFoamDict::DICTIONARY)
964
    {
3499
    {
965
    tempStringStruct = this->GetLine(input);
3500
    vtkErrorMacro(<<"The file type of " << io.fileName().c_str()
966
    temp = tempStringStruct->value;
3501
      << " is not a dictionary");
967
    delete tempStringStruct;
3502
    return false;
968
    }
3503
    }
969
  input->close();
970
3504
971
  //reopen file in correct format
3505
  //create the path to the data directory
972
  if(temp.find("binary") != vtkstd::string::npos)
3506
  // note that if a file is specified from command line (with
3507
  // --data=opt) its path may be a relative one
3508
  vtkStdString prefix(path);
3509
  // remove trailing "/controlDict.foam"
3510
#if defined(_WIN32)
3511
  size_t pos = prefix.find_last_of("/\\");
3512
#else
3513
  size_t pos = prefix.find_last_of('/');
3514
#endif
3515
  if(pos != vtkStdString::npos)
973
    {
3516
    {
974
#ifdef _WIN32
3517
    prefix.erase(pos);
975
    input->open(pointPath.c_str(), ios::binary | ios::in VTK_IOS_NOCREATE);
3518
    // remove trailing "/system" (or any other directory name)
3519
#if defined(_WIN32)
3520
    pos = prefix.find_last_of("/\\");
3521
#else
3522
    pos = prefix.find_last_of('/');
3523
#endif
3524
    if(pos != vtkStdString::npos)
3525
      {
3526
      prefix.erase(pos + 1); // preserve the last "/"
3527
      }
3528
    else
3529
      {
3530
#if defined(_WIN32) && PARAVIEW_VERSION_MAJOR >= 3
3531
      prefix = ".\\";
976
#else
3532
#else
977
    input->open(pointPath.c_str(), ios::in VTK_IOS_NOCREATE);
3533
      prefix = "./";
978
#endif
3534
#endif
979
    binaryWriteFormat = true;
3535
      }
980
    }
3536
    }
981
  else
3537
  else
982
    {
3538
    {
983
    input->open(pointPath.c_str(),ios::in);
3539
#if defined(_WIN32) && PARAVIEW_VERSION_MAJOR >= 3
984
    binaryWriteFormat = false;
3540
    prefix = "..\\";
985
    }
3541
#else
986
3542
    prefix = "../";
987
  double x,y,z;
3543
#endif
988
  vtksys_ios::stringstream tokenizer;
989
990
  //instantiate the points class
991
  this->Points->Reset();
992
993
  //find end of header
994
  //while(temp.compare(0,4, "// *", 0, 4) != 0)
995
  while (strcmp(temp.substr(0,4).c_str(), "// *"))
996
    {
997
    tempStringStruct = this->GetLine(input);
998
    temp = tempStringStruct->value;
999
    delete tempStringStruct;
1000
    }
3544
    }
3545
  *this->PathPrefix = prefix;
3546
  vtkDebugMacro(<<"Path: "<<this->PathPrefix->c_str());
1001
3547
1002
  //find number of points
3548
  vtkFoamEntry& writeControlEntry = dict.lookup("writeControl");
1003
  tempStringStruct = this->GetLine(input);
3549
  if(!writeControlEntry.found())
1004
  temp = tempStringStruct->value;
1005
  delete tempStringStruct;
1006
  while(temp.empty())
1007
    {
3550
    {
1008
    tempStringStruct = this->GetLine(input);
3551
    vtkErrorMacro(<< "writeControl entry not found in " << pathIn);
1009
    temp = tempStringStruct->value;
3552
    return false;
1010
    delete tempStringStruct;
1011
    }
3553
    }
1012
3554
  vtkStdString writeControl;
1013
  //read number of points
3555
  writeControlEntry >> writeControl;
1014
  tokenizer << temp;
3556
1015
  tokenizer >> NumPoints;
3557
  vtkStdString adjustTimeStep;
1016
  //binary data
3558
  dict.lookup("adjustTimeStep") >> adjustTimeStep; // empty if not found
1017
  if(binaryWriteFormat)
3559
3560
  // list time directories according to controlDict if (adjustTimeStep
3561
  // writeControl) == (off, timeStep) or (on, adjustableRunTime); list
3562
  // by time instances in the case directory otherwise (different behavior
3563
  // from paraFoam)
3564
  // valid switching words taken from src/OpenFOAM/db/Switch/Switch.C
3565
  if(((adjustTimeStep == "off" || adjustTimeStep == "no"
3566
    || adjustTimeStep == "n" || adjustTimeStep == "false"
3567
    || adjustTimeStep == "") && writeControl == "timeStep")
3568
    || ((adjustTimeStep == "on" || adjustTimeStep == "yes"
3569
    || adjustTimeStep == "y" || adjustTimeStep == "true")
3570
    && writeControl == "adjustableRunTime"))
1018
    {
3571
    {
1019
    input->get(); //parenthesis
3572
    return this->ListTimeDirectoriesByControlDict(&dict);
1020
    for(int i = 0; i < NumPoints; i++)
1021
      {
1022
      input->read((char *)&x,sizeof(double));
1023
      input->read((char *)&y,sizeof(double));
1024
      input->read((char *)&z,sizeof(double));
1025
      this->Points->InsertPoint(i,x,y,z);
1026
      }
1027
    }
3573
    }
1028
1029
  //ascii data
1030
  else
3574
  else
1031
    {
3575
    {
1032
    tempStringStruct = this->GetLine(input);
3576
    return this->ListTimeDirectoriesByInstances();
1033
    temp = tempStringStruct->value;
1034
    delete tempStringStruct;
1035
    for(int i = 0; i < this->NumPoints; i++)
1036
      {
1037
      tempStringStruct = this->GetLine(input);
1038
      temp = tempStringStruct->value;
1039
      delete tempStringStruct;
1040
      temp.erase(temp.begin()+temp.find("("));
1041
      temp.erase(temp.begin()+temp.find(")"));
1042
      tokenizer.clear();
1043
      tokenizer << temp;
1044
      tokenizer >> x;
1045
      tokenizer >> y;
1046
      tokenizer >> z;
1047
      this->Points->InsertPoint(i,x,y,z);
1048
      }
1049
    }
3577
    }
1050
1051
  input->close();
1052
  delete input;
1053
  vtkDebugMacro(<<"Point file read");
1054
  return;
1055
}
3578
}
1056
3579
1057
// ****************************************************************************
3580
// ****************************************************************************
1058
//  Method: vtkOpenFOAMReader::ReadFacesFile
3581
//  Method: vtkOpenFOAMReader::GetPoints
1059
//
3582
//
1060
//  Purpose:
3583
//  Purpose:
1061
//  read the faces into a vtkstd::vector
3584
//  read the points file into a vtkPoints
1062
//
3585
//
1063
// ****************************************************************************
3586
// ****************************************************************************
1064
void vtkOpenFOAMReader::ReadFacesFile (const char * facePathIn)
3587
vtkPoints* vtkOpenFOAMReader::GetPoints (int timeState)
1065
{
3588
{
1066
  vtkstd::string facePath(facePathIn);
3589
  //path to points file
1067
  vtkDebugMacro(<<"Read faces file: "<<facePath.c_str());
3590
  vtkStdString pointPath = *this->PathPrefix +
1068
  vtkstd::string temp;
3591
    this->PolyMeshPointsDir->value[timeState] + "/polyMesh/points";
1069
  stdString* tempStringStruct;
3592
  vtkDebugMacro(<<"Read points file: "<<pointPath.c_str());
1070
  bool binaryWriteFormat;
1071
  ifstream * input = new ifstream(facePath.c_str(), ios::in VTK_IOS_NOCREATE);
1072
  //make sure file exists
1073
  if(input->fail())
1074
    {
1075
    input->close();
1076
    delete input;
1077
    return;
1078
    }
1079
3593
1080
  //determine if file is binary or ascii
3594
  vtkFoamIOobject io;
1081
  while(temp.find("format") == vtkstd::string::npos)
3595
  if(!(io.open(pointPath) || io.open(pointPath + ".gz")))
1082
    {
3596
    {
1083
    tempStringStruct = this->GetLine(input);
3597
    vtkErrorMacro(<<"Error opening " << io.fileName().c_str() << ": "
1084
    temp = tempStringStruct->value;
3598
      << io.error().str().c_str());
1085
    delete tempStringStruct;
3599
    return NULL;
1086
    }
3600
    }
1087
  input->close();
3601
  vtkFoamDict dict;
1088
3602
  if(!dict.read(io))
1089
  //reopen file in correct format
1090
  if(temp.find("binary") != vtkstd::string::npos)
1091
    {
3603
    {
1092
#ifdef _WIN32
3604
    vtkErrorMacro(<<"Error reading line " << io.lineNumber()
1093
    input->open(facePath.c_str(), ios::binary | ios::in VTK_IOS_NOCREATE);
3605
      << " of " << io.fileName().c_str() << ": " << io.error().str().c_str());
1094
#else
3606
    return NULL;
1095
    input->open(facePath.c_str(), ios::in VTK_IOS_NOCREATE);
1096
#endif
1097
    binaryWriteFormat = true;
1098
    }
3607
    }
1099
  else
3608
  if(dict.type() != vtkFoamDict::VECTORLIST)
1100
    {
3609
    {
1101
    input->open(facePath.c_str(),ios::in);
3610
    vtkErrorMacro(<<"The file type of " << io.fileName().c_str()
1102
    binaryWriteFormat = false;
3611
      << " is not a vectorList");
3612
    return NULL;
1103
    }
3613
    }
1104
3614
1105
  vtksys_ios::stringstream tokenizer;
3615
  vtkDoubleArray& vl = dict.vectorList();
1106
  size_t pos;
1107
  int numFacePoints;
1108
  this->FacePoints->value.clear();
1109
3616
1110
  //find end of header
3617
  //instantiate the points class
1111
  //while(temp.compare(0,4, "// *", 0, 4) != 0)
3618
  vtkPoints* points = vtkPoints::New();
1112
  while (strcmp(temp.substr(0,4).c_str(), "// *"))
3619
  const int nPoints = vl.GetNumberOfTuples();
1113
    {
3620
  points->SetNumberOfPoints(nPoints);
1114
    tempStringStruct = this->GetLine(input);
1115
    temp = tempStringStruct->value;
1116
    delete tempStringStruct;
1117
    }
1118
3621
1119
  //find number of faces
3622
  for(int i = 0, index = 0; i < nPoints; i++, index += 3)
1120
  tempStringStruct = this->GetLine(input);
1121
  temp = tempStringStruct->value;
1122
  delete tempStringStruct;
1123
  while(temp.empty())
1124
    {
3623
    {
1125
    tempStringStruct = this->GetLine(input);
3624
    points->SetPoint(i, vl.GetPointer(index));
1126
    temp = tempStringStruct->value;
1127
    delete tempStringStruct;
1128
    }
3625
    }
3626
  vtkDebugMacro(<<"Point file read");
3627
  return points;
3628
}
1129
3629
1130
  //read number of faces
3630
// ****************************************************************************
1131
  tokenizer << temp;
3631
//  Method: vtkOpenFOAMReader::ReadFacesFile
1132
  tokenizer >> this->NumFaces;
3632
//
1133
  this->FacePoints->value.resize(this->NumFaces);
3633
//  Purpose:
1134
3634
//  read the faces into a vtkstd::vector
1135
  tempStringStruct = this->GetLine(input);
3635
//
1136
  temp = tempStringStruct->value;
3636
// ****************************************************************************
1137
  delete tempStringStruct;//THROW OUT "("
3637
intVectorVector* vtkOpenFOAMReader::ReadFacesFile (const char* facePathIn)
3638
{
3639
  const vtkStdString facePath(facePathIn);
3640
  vtkDebugMacro(<<"Read faces file: "<<facePath.c_str());
1138
3641
1139
  //binary data
3642
  vtkFoamIOobject io;
1140
  if(binaryWriteFormat)
3643
  if(!(io.open(facePath) || io.open(facePath + ".gz")))
1141
    {
3644
    {
1142
    //char paren;
3645
    vtkErrorMacro(<<"Error opening " << io.fileName().c_str() << ": "
1143
    int tempPoint;
3646
      << io.error().str().c_str());
1144
    for(int i = 0; i < NumFaces; i++)
3647
    return NULL;
1145
      {
1146
      tempStringStruct = this->GetLine(input);
1147
      temp = tempStringStruct->value;
1148
      delete tempStringStruct;//THROW OUT blankline
1149
1150
      tempStringStruct = this->GetLine(input);
1151
      temp = tempStringStruct->value;
1152
      delete tempStringStruct; //grab point count
1153
1154
      tokenizer.clear();
1155
      tokenizer << temp;
1156
      tokenizer >> numFacePoints;
1157
      this->FacePoints->value[i].resize(numFacePoints);
1158
      //paren = input->get();  //grab (
1159
      input->get();  //grab (
1160
      for(int j = 0; j < numFacePoints; j++)
1161
        {
1162
        input->read((char *) &tempPoint, sizeof(int));
1163
        this->FacePoints->value[i][j] = tempPoint;
1164
        }
1165
        tempStringStruct = this->GetLine(input);
1166
        temp = tempStringStruct->value;
1167
        delete tempStringStruct; //throw out ) and rest of line
1168
      }
1169
    }
3648
    }
1170
3649
  vtkFoamDict dict;
1171
  //ascii data
3650
  if(!dict.read(io))
1172
  else
1173
    {
3651
    {
1174
    //create vtkstd::vector of points in each face
3652
    vtkErrorMacro(<<"Error reading line " << io.lineNumber()
1175
    for(int i = 0; i < this->NumFaces; i++)
3653
      << " of " << io.fileName().c_str() << ": " << io.error().str().c_str());
1176
      {
3654
    return NULL;
1177
      tempStringStruct = this->GetLine(input);
3655
    }
1178
      temp = tempStringStruct->value;
3656
  if(dict.type() != vtkFoamDict::LABELLISTLIST)
1179
      delete tempStringStruct;
3657
    {
1180
3658
    vtkErrorMacro(<<"The file type of " << io.fileName().c_str()
1181
      pos = temp.find("(");
3659
      << " is not a labelListList");
1182
      vtksys_ios::stringstream ascTokenizer;
3660
    return NULL;
1183
      ascTokenizer << temp.substr(0, pos);
1184
      temp.erase(0, pos+1);
1185
      ascTokenizer >> numFacePoints;
1186
      this->FacePoints->value[i].resize(numFacePoints);
1187
      for(int j = 0; j < numFacePoints; j++)
1188
        {
1189
        pos = temp.find(" ");
1190
        vtksys_ios::stringstream lineTokenizer;
1191
        lineTokenizer << temp.substr(0, pos);
1192
        temp.erase(0, pos+1);
1193
        lineTokenizer >> this->FacePoints->value[i][j];
1194
        }
1195
      }
1196
    }
3661
    }
1197
3662
1198
  input->close();
1199
  delete input;
1200
  vtkDebugMacro(<<"Faces read");
3663
  vtkDebugMacro(<<"Faces read");
1201
  return;
3664
  return (intVectorVector *)dict.ptr();
1202
}
3665
}
1203
3666
1204
// ****************************************************************************
3667
// ****************************************************************************
1205
//  Method: vtkOpenFOAMReader::ReadOwnerFile
3668
//  Method: vtkOpenFOAMReader::ReadOwnerNeighborFiles
1206
//
3669
//
1207
//  Purpose:
3670
//  Purpose:
1208
//  read the owner file into a vtkstd::vector
3671
//  read the owner file into a vtkstd::vector
1209
//
3672
//
1210
// ****************************************************************************
3673
// ****************************************************************************
1211
void vtkOpenFOAMReader::ReadOwnerFile(const char * ownerPathIn)
3674
bool vtkOpenFOAMReader::ReadOwnerNeighborFiles(faceVectorVector* facesOfCell,
3675
  const char* ownerPathIn, const char* neighborPathIn)
1212
{
3676
{
1213
  vtkstd::string ownerPath(ownerPathIn);
3677
  const vtkStdString ownerPath(ownerPathIn);
1214
  vtkDebugMacro(<<"Read owner file: "<<ownerPath.c_str());
3678
  vtkDebugMacro(<<"Read owner file: "<<ownerPath.c_str());
1215
  vtkstd::string temp;
1216
  stdString* tempStringStruct;
1217
  bool binaryWriteFormat;
1218
  ifstream * input = new ifstream(ownerPath.c_str(), ios::in VTK_IOS_NOCREATE);
1219
  //make sure file exists
1220
  if(input->fail())
1221
    {
1222
    input->close();
1223
    delete input;
1224
    return;
1225
    }
1226
3679
1227
  //determine if file is binary or ascii
3680
  vtkFoamIOobject io;
1228
  while(temp.find("format") == vtkstd::string::npos)
3681
  if(!(io.open(ownerPath) || io.open(ownerPath + ".gz")))
1229
    {
3682
    {
1230
    tempStringStruct = this->GetLine(input);
3683
    vtkErrorMacro(<<"Error opening " << io.fileName().c_str() << ": "
1231
    temp = tempStringStruct->value;
3684
      << io.error().str().c_str());
1232
    delete tempStringStruct;
3685
    return false;
1233
    }
3686
    }
1234
  input->close();
3687
  vtkFoamDict ownerDict;
1235
3688
  if(!ownerDict.read(io))
1236
  //reopen file in correct format
1237
  if(temp.find("binary") != vtkstd::string::npos)
1238
    {
3689
    {
1239
#ifdef _WIN32
3690
    vtkErrorMacro(<<"Error reading line " << io.lineNumber()
1240
    input->open(ownerPath.c_str(), ios::binary | ios::in VTK_IOS_NOCREATE);
3691
      << " of " << io.fileName().c_str() << ": " << io.error().str().c_str());
1241
#else
3692
    return false;
1242
    input->open(ownerPath.c_str(), ios::in VTK_IOS_NOCREATE);
1243
#endif
1244
    binaryWriteFormat = true;
1245
    }
3693
    }
1246
  else
3694
  if(ownerDict.type() != vtkFoamDict::LABELLIST)
1247
    {
3695
    {
1248
    input->open(ownerPath.c_str(),ios::in);
3696
    vtkErrorMacro(<<"The file type of " << io.fileName().c_str()
1249
    binaryWriteFormat = false;
3697
      << " is not a labelList");
3698
    return false;
1250
    }
3699
    }
3700
  io.close();
1251
3701
1252
  vtkstd::string numFacesStr;
3702
  const vtkStdString neighborPath(neighborPathIn);
1253
  int faceValue;
3703
  vtkDebugMacro(<<"Read neighbor file: "<<neighborPath.c_str());
1254
1255
  this->FaceOwner = vtkIntArray::New();
1256
3704
1257
  vtksys_ios::stringstream tokenizer;
3705
  if(!(io.open(neighborPath) || io.open(neighborPath + ".gz")))
1258
  tokenizer << this->NumFaces;
1259
  tokenizer >> numFacesStr;
1260
  //find end of header & number of faces
1261
  //while(temp.compare(0,numFacesStr.size(),numFacesStr,
1262
  //0,numFacesStr.size())!=0)
1263
  while(strcmp(temp.substr(0,numFacesStr.size()).c_str(), numFacesStr.c_str()))
1264
    {
3706
    {
1265
    tempStringStruct = this->GetLine(input);
3707
    vtkErrorMacro(<<"Error opening " << io.fileName().c_str() << ": "
1266
    temp = tempStringStruct->value;
3708
      << io.error().str().c_str());
1267
    delete tempStringStruct;
3709
    return false;
1268
    }
3710
    }
1269
3711
  vtkFoamDict neighborDict;
1270
  this->FaceOwner->SetNumberOfValues(this->NumFaces);
3712
  if(!neighborDict.read(io))
1271
1272
  //binary data
1273
  if(binaryWriteFormat)
1274
    {
3713
    {
1275
    input->get(); //parenthesis
3714
    vtkErrorMacro(<<"Error reading line " << io.lineNumber()
1276
    for(int i = 0; i < NumFaces; i++)
3715
      << " of " << io.fileName().c_str() << ": " << io.error().str().c_str());
1277
      {
3716
    return false;
1278
      input->read((char *) &faceValue, sizeof(int));
1279
      this->FaceOwner->SetValue(i, faceValue);
1280
      }
1281
    }
3717
    }
1282
3718
  if(neighborDict.type() != vtkFoamDict::LABELLIST)
1283
  //ascii data
1284
  else
1285
    {
3719
    {
1286
    tempStringStruct = this->GetLine(input);
3720
    vtkErrorMacro(<<"The file type of " << io.fileName().c_str()
1287
    temp = tempStringStruct->value;
3721
      << " is not a labelList");
1288
    delete tempStringStruct;
3722
    return false;
1289
1290
    //read face owners into int array
1291
    for(int i = 0; i < this->NumFaces; i++)
1292
      {
1293
      tempStringStruct = this->GetLine(input);
1294
      temp = tempStringStruct->value;
1295
      delete tempStringStruct;
1296
1297
      tokenizer.clear();
1298
      tokenizer << temp;
1299
      tokenizer >> faceValue;
1300
      this->FaceOwner->SetValue(i, faceValue);
1301
      }
1302
    }
3723
    }
1303
3724
1304
  //find the number of cells
3725
  const vtkstd::vector<int>& faceOwner = ownerDict.labelList();
1305
  double  * range;
3726
  const vtkstd::vector<int>& faceNeighbor = neighborDict.labelList();
1306
  range = this->FaceOwner->GetRange();
1307
  this->NumCells = (int)range[1]+1;
1308
3727
1309
  //add the face number to the correct cell
3728
  if(faceOwner.size() != faceNeighbor.size())
1310
  //according to owner
1311
  this->FacesOwnerCell->value.resize(this->NumCells);
1312
  int tempCellId;
1313
  for(int j = 0; j < this->NumFaces; j++)
1314
    {
3729
    {
1315
    tempCellId = this->FaceOwner->GetValue(j);
3730
    vtkErrorMacro(<<"Numbers of faces in owner and neighbor don't match");
1316
    if(tempCellId != -1)
3731
    return false;
1317
      {
1318
      this->FacesOwnerCell->value[tempCellId].push_back(j);
1319
      }
1320
    }
3732
    }
1321
3733
1322
  input->close();
3734
  const size_t nFaces = faceOwner.size();
1323
  delete input;
1324
  vtkDebugMacro(<<"Owner file read");
1325
  return;
1326
}
1327
3735
1328
// ****************************************************************************
3736
  if(nFaces == 0)
1329
//  Method: vtkOpenFOAMReader::ReadNeighborFile
1330
//
1331
//  Purpose:
1332
//  read the neighbor file into a vtkstd::vector
1333
//
1334
// ****************************************************************************
1335
void vtkOpenFOAMReader::ReadNeighborFile(const char * neighborPathIn)
1336
{
1337
  vtkstd::string neighborPath(neighborPathIn);
1338
  vtkDebugMacro(<<"Read neighbor file: "<<neighborPath.c_str());
1339
  vtkstd::string temp;
1340
  stdString* tempStringStruct;
1341
  bool binaryWriteFormat;
1342
  ifstream * input = new ifstream(neighborPath.c_str(), ios::in VTK_IOS_NOCREATE);
1343
  //make sure file exists
1344
  if(input->fail())
1345
    {
3737
    {
1346
    input->close();
3738
    vtkWarningMacro(<<"The mesh contains no faces");
1347
    delete input;
1348
    return;
1349
    }
3739
    }
1350
3740
1351
  //determine if file is binary or ascii
3741
  this->FaceOwner = vtkIntArray::New();
1352
  while(temp.find("format") == vtkstd::string::npos)
3742
  vtkIntArray& fo = *this->FaceOwner;
1353
    {
3743
  fo.SetNumberOfValues(nFaces);
1354
    tempStringStruct = this->GetLine(input);
1355
    temp = tempStringStruct->value;
1356
    delete tempStringStruct;
1357
    }
1358
  input->close();
1359
3744
1360
  //reopen file in correct format
3745
  //read face owners into int array
1361
  if(temp.find("binary") != vtkstd::string::npos)
3746
  for(size_t i = 0; i < nFaces; i++)
1362
    {
1363
#ifdef _WIN32
1364
    input->open(neighborPath.c_str(), ios::binary | ios::in VTK_IOS_NOCREATE);
1365
#else
1366
    input->open(neighborPath.c_str(), ios::in VTK_IOS_NOCREATE);
1367
#endif
1368
    binaryWriteFormat = true;
1369
    }
1370
  else
1371
    {
3747
    {
1372
    input->open(neighborPath.c_str(),ios::in);
3748
    fo.SetValue(i, faceOwner[i]);
1373
    binaryWriteFormat = false;
1374
    }
1375
1376
  vtkstd::string numFacesStr;
1377
  int faceValue;
1378
  vtkIntArray * faceNeighbor = vtkIntArray::New();
1379
1380
  vtksys_ios::stringstream tokenizer;
1381
  tokenizer << this->NumFaces;
1382
  tokenizer >> numFacesStr;
1383
  //find end of header & number of faces
1384
  //while(temp.compare(0,numFacesStr.size(),numFacesStr,0,
1385
  //numFacesStr.size())!=0)
1386
  while (strcmp(temp.substr(0,numFacesStr.size()).c_str(), numFacesStr.c_str()))
1387
    {
1388
    tempStringStruct = this->GetLine(input);
1389
    temp = tempStringStruct->value;
1390
    delete tempStringStruct;
1391
    }
3749
    }
1392
3750
1393
  //read face owners into int array
3751
  //add the face numbers to the correct cell
1394
  faceNeighbor->SetNumberOfValues(this->NumFaces);
3752
  // based on Terry's code and
3753
  // src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCells.C
1395
3754
1396
  //binary data
3755
  //find the number of cells
1397
  if(binaryWriteFormat)
3756
  int nCells = -1;
3757
  for(size_t i = 0; i < nFaces; i++)
1398
    {
3758
    {
1399
    input->get(); //parenthesis
3759
    if(nCells < faceOwner[i]) // max(nCells, faceOwner[i])
1400
    for(int i = 0; i < this->NumFaces; i++)
3760
      {
3761
      nCells = faceOwner[i];
3762
      }
3763
    if(nCells < faceNeighbor[i]) // max(nCells, faceNeighbor[i])
1401
      {
3764
      {
1402
      input->read((char *) &faceValue, sizeof(int));
3765
      nCells = faceNeighbor[i];
1403
      faceNeighbor->SetValue(i, faceValue);
1404
      }
3766
      }
1405
    }
3767
    }
3768
  nCells++;
1406
3769
1407
  //ascii data
3770
  if(nCells == 0)
1408
  else
1409
    {
3771
    {
1410
    tempStringStruct = this->GetLine(input);
3772
    vtkWarningMacro(<<"The mesh contains no cells");
1411
    temp = tempStringStruct->value;
1412
    delete tempStringStruct;//throw away (
1413
    //read face owners into int array
1414
    for(int i = 0; i < this->NumFaces; i++)
1415
      {
1416
      tempStringStruct = this->GetLine(input);
1417
      temp = tempStringStruct->value;
1418
      delete tempStringStruct;
1419
1420
      tokenizer.clear();
1421
      tokenizer << temp;
1422
      tokenizer >> faceValue;
1423
      faceNeighbor->SetValue(i, faceValue);
1424
      }
1425
    }
3773
    }
1426
  //No need to recalulate the Number of Cells
1427
  this->FacesNeighborCell->value.resize(this->NumCells);
1428
3774
1429
  //add face number to correct cell
3775
  this->NumCells = nCells;
1430
  int tempCellId;
3776
1431
  for(int j = 0; j < this->NumFaces; j++)
3777
  // count number of faces per cell
3778
  vtkstd::vector<int> nCellFaces(nCells, 0);
3779
  for(size_t i = 0; i < nFaces; i++)
1432
    {
3780
    {
1433
    tempCellId = faceNeighbor->GetValue(j);
3781
    // simpleFoam/pitzDaily3Blocks has faces with owner cell number -1
1434
    if(tempCellId != -1)
3782
    if(faceOwner[i] >= 0)
3783
      {
3784
      nCellFaces[faceOwner[i]]++;
3785
      }
3786
    if(faceNeighbor[i] >= 0)
1435
      {
3787
      {
1436
      this->FacesNeighborCell->value[tempCellId].push_back(j);
3788
      nCellFaces[faceNeighbor[i]]++;
1437
      }
3789
      }
1438
    }
3790
    }
1439
3791
1440
  faceNeighbor->Delete();
3792
  // size cellFaces
1441
  input->close();
3793
  vtkstd::vector<vtkstd::vector<face> >& cellFaces = facesOfCell->value;
1442
  delete input;
3794
  cellFaces.resize(nCells);
1443
  vtkDebugMacro(<<"Neighbor file read");
3795
  for(int i = 0; i < nCells; i++)
1444
  return;
1445
}
1446
1447
// ****************************************************************************
1448
//  Method: vtkOpenFOAMReader::PopulatePolyMeshDirArrays
1449
//
1450
//  Purpose:
1451
//  create a Lookup Table containing the location of the points
1452
//  and faces files for each time steps mesh
1453
//
1454
// ****************************************************************************
1455
void vtkOpenFOAMReader::PopulatePolyMeshDirArrays()
1456
{
1457
  vtkDebugMacro(<<"Create list of points/faces file directories");
1458
  vtksys_ios::stringstream path;
1459
  vtksys_ios::stringstream timeStep;
1460
  bool facesFound;
1461
  bool pointsFound;
1462
  bool polyMeshFound;
1463
1464
  //intialize size to number of timesteps
1465
  this->PolyMeshPointsDir->value.resize(this->NumberOfTimeSteps);
1466
  this->PolyMeshFacesDir->value.resize(this->NumberOfTimeSteps);
1467
1468
  //loop through each timestep
1469
  for(int i = 0; i < this->NumberOfTimeSteps; i++)
1470
    {
3796
    {
1471
    polyMeshFound = false;
3797
    cellFaces[i].resize(nCellFaces[i]);
1472
    facesFound = false;
3798
    }
1473
    pointsFound = false;
1474
1475
    //create the path to the timestep
1476
    path.clear();
1477
    timeStep.clear();
1478
    timeStep << Steps[i];
1479
    path << this->PathPrefix->value <<timeStep.str() << "/";
1480
3799
1481
    //get the number of files
3800
  //add face numbers to correct cell
1482
    vtkDirectory * directory = vtkDirectory::New();
3801
  for(size_t i = 0; i < nFaces; i++)
1483
    directory->Open(path.str().c_str());
3802
    {
1484
    int numFiles = directory->GetNumberOfFiles();
3803
    const int ownerCell = faceOwner[i]; // must be a signed int
1485
    //Look for polyMesh Dir
3804
    // simpleFoam/pitzDaily3Blocks has faces with owner cell number -1
1486
    for(int j = 0; j < numFiles; j++)
3805
    if(ownerCell >= 0)
1487
      {
3806
      {
1488
      vtkstd::string tempFile(directory->GetFile(j));
3807
      face& ownerCellFace = cellFaces[ownerCell][--nCellFaces[ownerCell]];
1489
      if(tempFile.find("polyMesh") != vtkstd::string::npos)
3808
      ownerCellFace.faceIndex = i;
1490
        {
3809
      ownerCellFace.neighborFace = false;
1491
        polyMeshFound = true;
1492
1493
        path << "polyMesh/";
1494
1495
        //get number of files in the polyMesh dir
1496
        vtkDirectory * polyMeshDirectory = vtkDirectory::New();
1497
        polyMeshDirectory->Open(path.str().c_str());
1498
        int numPolyMeshFiles = polyMeshDirectory->GetNumberOfFiles();
1499
        //Look for points/faces files
1500
        for(int k = 0; k < numPolyMeshFiles; k++)
1501
          {
1502
          vtkstd::string tempFile2 = vtkstd::string(polyMeshDirectory->
1503
                                                    GetFile(k));
1504
          if(tempFile2.find("points") != vtkstd::string::npos)
1505
            {
1506
            this->PolyMeshPointsDir->value[i] = timeStep.str();
1507
            pointsFound = true;
1508
            }
1509
          else if(tempFile2.find("faces") != vtkstd::string::npos)
1510
            {
1511
            this->PolyMeshFacesDir->value[i] = timeStep.str();
1512
            facesFound = true;
1513
            }
1514
          }
1515
1516
        //if there is no points or faces found in this timestep
1517
        //set it equal to previous time step if no previous
1518
        //set it equal to "constant" dir
1519
        if(!pointsFound)
1520
          {
1521
          if(i != 0)
1522
            {
1523
            this->PolyMeshPointsDir->value[i] =
1524
              this->PolyMeshPointsDir->value[i-1];
1525
            }
1526
          else
1527
            {
1528
            this->PolyMeshPointsDir->value[i] = vtkstd::string("constant");
1529
            }
1530
          }
1531
        if(!facesFound)
1532
          {
1533
          if(i != 0)
1534
            {
1535
            this->PolyMeshFacesDir->value[i] =
1536
              this->PolyMeshFacesDir->value[i-1];
1537
            }
1538
          else
1539
            {
1540
            this->PolyMeshFacesDir->value[i] = vtkstd::string("constant");
1541
            }
1542
          }
1543
1544
        polyMeshDirectory->Delete();
1545
        break;  //found - stop looking
1546
        }
1547
      }
3810
      }
1548
3811
1549
    //if there is no polyMesh dir
3812
    const int neighborCell = faceNeighbor[i]; // must be a signed int
1550
    //set  it equal to prev timestep
3813
    if(neighborCell >= 0)
1551
    //if no prev set to "constant" dir
1552
    if(!polyMeshFound)
1553
      {
3814
      {
1554
      if(i != 0)
3815
      face& neighborCellFace
1555
        {
3816
        = cellFaces[neighborCell][--nCellFaces[neighborCell]];
1556
        //set points/faces location to previous timesteps value
3817
      neighborCellFace.faceIndex = i;
1557
        this->PolyMeshPointsDir->value[i] = this->PolyMeshPointsDir->value[i-1];
3818
      neighborCellFace.neighborFace = true;
1558
        this->PolyMeshFacesDir->value[i] = this->PolyMeshFacesDir->value[i-1];
1559
        }
1560
      else
1561
        {
1562
        //set points/faces to constant
1563
        this->PolyMeshPointsDir->value[i] = vtkstd::string("constant");
1564
        this->PolyMeshFacesDir->value[i] = vtkstd::string("constant");
1565
        }
1566
      }
3819
      }
1567
    directory->Delete();
1568
    }
3820
    }
1569
3821
1570
  vtkDebugMacro(<<"Points/faces list created");
3822
  vtkDebugMacro(<<"Owner file read");
1571
  return;
3823
  return true;
1572
}
3824
}
1573
3825
1574
// ****************************************************************************
3826
// ****************************************************************************
1575
//  Method: vtkOpenFOAMReader::GetDataType
3827
//  Method: vtkOpenFOAMReader::PopulatePolyMeshDirArrays
1576
//
3828
//
1577
//  Purpose:
3829
//  Purpose:
1578
//  determines whether a variable is a volume scalar, vector or neither
3830
//  create a Lookup Table containing the location of the points
1579
//  for meta data
3831
//  and faces files for each time steps mesh
1580
//
3832
//
1581
// ****************************************************************************
3833
// ****************************************************************************
1582
const char * vtkOpenFOAMReader::GetDataType(const char * pathIn,
3834
void vtkOpenFOAMReader::PopulatePolyMeshDirArrays()
1583
                                      const char * fileNameIn)
1584
{
3835
{
1585
  vtkstd::string path(pathIn);
3836
  vtkDebugMacro(<<"Create list of points/faces file directories");
1586
  vtkstd::string fileName(fileNameIn);
1587
  vtkstd::string filePath = path+"/"+fileName;
1588
  vtkDebugMacro(<<"Get data type of: "<<filePath.c_str());
1589
  stdString* tempStringStruct;
1590
  ifstream * input = new ifstream(filePath.c_str(), ios::in VTK_IOS_NOCREATE);
1591
  //make sure file exists
1592
  if(input->fail())
1593
    {
1594
    input->close();
1595
    delete input;
1596
    return "Null";
1597
    }
1598
1599
  vtkstd::string temp;
1600
  vtkstd::string foamClass;
1601
  vtksys_ios::stringstream tokenizer;
1602
  int opened;
1603
1604
  //see if fileName is a file or directory
1605
  vtkDirectory * directory = vtkDirectory::New();
1606
  opened = directory->Open(filePath.c_str());
1607
  directory->Delete();
1608
  if(opened)
1609
    {
1610
    input->close();
1611
    delete input;
1612
    return "Directory";
1613
    }
1614
3837
1615
  //find class entry
3838
  //intialize size to number of timesteps
1616
  tempStringStruct = this->GetLine(input);
3839
  this->PolyMeshPointsDir->value.resize(this->NumberOfTimeSteps);
1617
  temp = tempStringStruct->value;
3840
  this->PolyMeshFacesDir->value.resize(this->NumberOfTimeSteps);
1618
  delete tempStringStruct;
1619
  while(temp.find("class") == vtkstd::string::npos && !input->eof())
1620
    {
1621
    tempStringStruct = this->GetLine(input);
1622
    temp = tempStringStruct->value;
1623
    delete tempStringStruct;
1624
    }
1625
3841
1626
  //return type
3842
  //loop through each timestep
1627
  if(!input->eof())
3843
  for(int i = 0; i < this->NumberOfTimeSteps; i++)
1628
    {
3844
    {
1629
    temp.erase(temp.begin()+temp.find(";"));
3845
    //create the path to the timestep
1630
    //PARSE OUT CLASS TYPE
3846
    vtkStdString polyMeshPath
1631
    tokenizer << temp;
3847
      = *this->PathPrefix + this->TimeNames->GetValue(i) + "/polyMesh/";
1632
    //while(tokenizer >> foamClass);
3848
    vtkFoamIOobject io;
1633
    while(!tokenizer.eof())
3849
1634
      {
3850
    if(io.open(polyMeshPath + "faces") || io.open(polyMeshPath + "faces.gz"))
1635
      tokenizer >> foamClass;
3851
      {
3852
      io.close();
3853
      //set points/faces location to current timesteps value
3854
      this->PolyMeshFacesDir->value[i] = this->TimeNames->GetValue(i);
1636
      }
3855
      }
1637
    //return scalar, vector, or invalid
3856
    else
1638
    if(foamClass =="volScalarField")
1639
      {
3857
      {
1640
      input->close();
3858
      if(i != 0)
1641
      delete input;
3859
        {
1642
      return "Scalar";
3860
        //set points/faces location to previous timesteps value
3861
        this->PolyMeshFacesDir->value[i] = this->PolyMeshFacesDir->value[i-1];
3862
        }
3863
      else
3864
        {
3865
        //set points/faces to constant
3866
        this->PolyMeshFacesDir->value[i] = vtkStdString("constant");
3867
        }
1643
      }
3868
      }
1644
    else if (foamClass =="volVectorField")
3869
3870
    if(io.open(polyMeshPath + "points") || io.open(polyMeshPath + "points.gz"))
1645
      {
3871
      {
1646
      input->close();
3872
      io.close();
1647
      delete input;
3873
      //set points/faces location to current timesteps value
1648
      return "Vector";
3874
      this->PolyMeshPointsDir->value[i] = this->TimeNames->GetValue(i);
1649
      }
3875
      }
1650
    else
3876
    else
1651
      {
3877
      {
1652
      input->close();
3878
      if(i != 0)
1653
      delete input;
3879
        {
1654
      return "Invalid";
3880
        //set points/faces location to previous timesteps value
3881
        this->PolyMeshPointsDir->value[i]
3882
          = this->PolyMeshPointsDir->value[i-1];
3883
        }
3884
      else
3885
        {
3886
        //set points/faces to constant
3887
        this->PolyMeshPointsDir->value[i] = vtkStdString("constant");
3888
        }
1655
      }
3889
      }
1656
    }
3890
    }
1657
3891
  vtkDebugMacro(<<"Points/faces list created");
1658
  //if the file format is wrong return invalid
3892
  return;
1659
  else
1660
    {
1661
    input->close();
1662
    delete input;
1663
    return "invalid";
1664
    }
1665
}
3893
}
1666
3894
1667
// ****************************************************************************
3895
// ****************************************************************************
1668
//  Method: vtkOpenFOAMReader::GetInternalVariableAtTimestep
3896
//  Method: vtkOpenFOAMReader::GetVariableAtTimestep
1669
//
3897
//
1670
//  Purpose:
3898
//  Purpose:
1671
//  returns the values for a request variable for the internal mesh
3899
//  returns the values for a request variable for the internal and boundary
3900
//  meshes
1672
//
3901
//
1673
// ****************************************************************************
3902
// ****************************************************************************
1674
vtkDoubleArray * vtkOpenFOAMReader::GetInternalVariableAtTimestep
3903
bool vtkOpenFOAMReader::GetVariableAtTimestep(
1675
                 (const char * varNameIn, int timeState)
3904
  vtkUnstructuredGrid* internalMesh, unstructuredGridVector* boundaryMesh,
3905
  vtkFoamDict* boundaryDictPtr, const char* varNameIn, int timeState)
1676
{
3906
{
1677
  vtkstd::string varName(varNameIn);
3907
  vtkStdString varPath = *this->PathPrefix
1678
  vtksys_ios::stringstream varPath;
3908
    + this->TimeNames->GetValue(timeState) + "/" + vtkStdString(varNameIn);
1679
  varPath << this->PathPrefix->value << this->Steps[timeState] << "/" << varName;
3909
  vtkDebugMacro(<<"Get variable: "<<varPath.c_str());
1680
  vtkDebugMacro(<<"Get internal variable: "<<varPath.str().c_str());
1681
  vtkDoubleArray *data = vtkDoubleArray::New();
1682
3910
1683
  vtkstd::string temp;
3911
  // open the file
1684
  stdString* tempStringStruct;
3912
  vtkFoamIOobject io;
1685
  bool binaryWriteFormat;
3913
  if(!io.open(varPath))
1686
  ifstream * input = new ifstream(varPath.str().c_str(), ios::in VTK_IOS_NOCREATE);
1687
  //make sure file exists
1688
  if(input->fail())
1689
    {
3914
    {
1690
    input->close();
3915
    vtkErrorMacro(<<"Error opening " << io.fileName().c_str() << ": "
1691
    delete input;
3916
      << io.error().str().c_str());
1692
    return data;
3917
    return false;
1693
    }
3918
    }
1694
3919
1695
  //determine if file is binary or ascii
3920
  // if the variable is disabled on selection panel then skip it
1696
  while(temp.find("format") == vtkstd::string::npos)
3921
  if(this->CellDataArraySelection->ArrayExists(io.objectName().c_str())
3922
    && !this->CellDataArraySelection->ArrayIsEnabled(io.objectName().c_str()))
1697
    {
3923
    {
1698
    tempStringStruct = this->GetLine(input);
3924
    return true;
1699
    temp = tempStringStruct->value;
1700
    delete tempStringStruct;
1701
    }
3925
    }
1702
  input->close();
1703
3926
1704
  //reopen file in correct format
3927
  // read the field file into dictionary
1705
  if(temp.find("binary") != vtkstd::string::npos)
3928
  vtkFoamDict dict;
1706
    {
3929
  if(!dict.read(io))
1707
#ifdef _WIN32
1708
    input->open(varPath.str().c_str(), ios::binary | ios::in VTK_IOS_NOCREATE);
1709
#else
1710
    input->open(varPath.str().c_str(), ios::in VTK_IOS_NOCREATE);
1711
#endif
1712
    binaryWriteFormat = true;
1713
    }
1714
  else
1715
    {
3930
    {
1716
    input->open(varPath.str().c_str(),ios::in);
3931
    vtkErrorMacro(<<"Error reading line " << io.lineNumber()
1717
    binaryWriteFormat = false;
3932
      << " of " << io.fileName().c_str() << ": " << io.error().str().c_str());
3933
    return false;
1718
    }
3934
    }
1719
3935
1720
  vtkstd::string foamClass;
3936
  if(dict.type() != vtkFoamDict::DICTIONARY)
1721
  vtksys_ios::stringstream tokenizer;
1722
  double value;
1723
1724
  //find class
1725
  tempStringStruct = this->GetLine(input);
1726
  temp = tempStringStruct->value;
1727
  delete tempStringStruct;
1728
1729
  while(temp.find("class") == vtkstd::string::npos)
1730
    {
3937
    {
1731
    tempStringStruct = this->GetLine(input);
3938
    vtkErrorMacro(<<"File " << io.fileName().c_str()
1732
    temp = tempStringStruct->value;
3939
      << "is not valid as a field file");
1733
    delete tempStringStruct;
3940
    return false;
1734
    }
3941
    }
1735
  temp.erase(temp.begin()+temp.find(";"));
3942
1736
  tokenizer << temp;
3943
  // set internal values
1737
  //while(tokenizer >> foamClass);
3944
  vtkDoubleArray* iData;
1738
  while(!tokenizer.eof())
3945
  vtkFoamEntry& iEntry = dict.lookup("internalField");
3946
  if(!iEntry.found())
1739
    {
3947
    {
1740
    tokenizer >> foamClass;
3948
    vtkErrorMacro(<<"internalField not found in " << io.fileName().c_str());
3949
    return false;
1741
    }
3950
    }
1742
  temp="";
3951
  if(iEntry.firstValue().type() == vtkFoamEntryValue::EMPTYLIST)
1743
  //create scalar arrays
1744
  if(foamClass =="volScalarField")
1745
    {
3952
    {
1746
    while(temp.find("internalField") == vtkstd::string::npos)
3953
    if(this->NumCells == 0)
1747
      {
3954
      {
1748
      tempStringStruct = this->GetLine(input);
3955
      // if there's no cell there shouldn't be any boundary faces either
1749
      temp = tempStringStruct->value;
3956
      return true;
1750
      delete tempStringStruct;
1751
      }
3957
      }
1752
    //nonuniform
3958
    else
1753
    if(!(temp.find("nonuniform") == vtkstd::string::npos))
1754
      {
3959
      {
1755
      //create an array
3960
      vtkErrorMacro(<<"internalField is empty");
1756
      tempStringStruct = this->GetLine(input);
3961
      return false;
1757
      temp = tempStringStruct->value;
3962
      }
1758
      delete tempStringStruct;
3963
    }
1759
1760
      int scalarCount;
1761
      tokenizer.clear();
1762
      tokenizer << temp;
1763
      tokenizer >> scalarCount;
1764
      data->SetNumberOfValues(NumCells);
1765
1766
      //binary data
1767
      if(binaryWriteFormat)
1768
        {
1769
        //add values to array
1770
        input->get(); //parenthesis
1771
        for(int i = 0; i < scalarCount; i++)
1772
          {
1773
          input->read((char *) &value, sizeof(double));
1774
          data->SetValue(i, value);
1775
          }
1776
        }
1777
3964
1778
      //ascii data
3965
  if(io.className() == "volScalarField")
1779
      else
3966
    {
3967
    if(iEntry.firstValue().isUniform())
3968
      {
3969
      iData = vtkDoubleArray::New();
3970
      iData->SetNumberOfValues(this->NumCells);
3971
      double num;
3972
      iEntry >> num;
3973
      for(int i = 0; i < this->NumCells; i++)
1780
        {
3974
        {
1781
        //add values to array
3975
        iData->SetValue(i, num);
1782
        tempStringStruct = this->GetLine(input);
1783
        temp = tempStringStruct->value;
1784
        delete tempStringStruct; //discard (
1785
1786
        for(int i = 0; i < scalarCount; i++)
1787
          {
1788
          tempStringStruct = this->GetLine(input);
1789
          temp = tempStringStruct->value;
1790
          delete tempStringStruct;
1791
          tokenizer.clear();
1792
          tokenizer << temp;
1793
          tokenizer >> value;
1794
          data->SetValue(i, value);
1795
          }
1796
        }
3976
        }
1797
      }
3977
      }
1798
3978
    else // nonuniform
1799
    //uniform
1800
    else if(!(temp.find("uniform") == vtkstd::string::npos))
1801
      {
3979
      {
1802
      //parse out the uniform value
3980
      if(iEntry.firstValue().type() != vtkFoamEntryValue::SCALARLIST)
1803
      vtkstd::string token;
1804
      temp.erase(temp.begin()+temp.find(";"));
1805
      tokenizer.clear();
1806
      tokenizer << temp;
1807
      //while(tokenizer>>token);
1808
      while(!tokenizer.eof())
1809
        {
3981
        {
1810
        tokenizer >> token;
3982
        vtkErrorMacro(<<"internalField is not a scalarField");
3983
        return false;
1811
        }
3984
        }
1812
      tokenizer.clear();
3985
      if(iEntry.scalarList().GetSize() != this->NumCells)
1813
      tokenizer << token;
1814
      tokenizer >> value;
1815
      data->SetNumberOfValues(NumCells);
1816
1817
      //create array of uniform values
1818
      for(int i = 0; i < NumCells; i++)
1819
        {
3986
        {
1820
        data->SetValue(i, value);
3987
        vtkErrorMacro(<<"Number of cells in mesh and field don't match: "
3988
          << "mesh = " << this->NumCells << ", field = "
3989
          << iEntry.scalarList().GetSize());
3990
        return false;
1821
        }
3991
        }
1822
      }
3992
      iData = (vtkDoubleArray *)iEntry.ptr();
1823
1824
    //no data
1825
    else
1826
      {
1827
      input->close();
1828
      delete input;
1829
      return data;
1830
      }
3993
      }
1831
    }
3994
    }
1832
3995
  else if(io.className() == "volVectorField")
1833
  //create vector arrays
1834
  else if(foamClass == "volVectorField")
1835
    {
3996
    {
1836
    tempStringStruct = this->GetLine(input);
3997
    if(iEntry.firstValue().isUniform())
1837
    temp = tempStringStruct->value;
1838
    delete tempStringStruct;
1839
    while(temp.find("internalField") == vtkstd::string::npos)
1840
      {
3998
      {
1841
      tempStringStruct = this->GetLine(input);
3999
      iData = vtkDoubleArray::New();
1842
      temp = tempStringStruct->value;
4000
      iData->SetNumberOfComponents(3);
1843
      delete tempStringStruct;
4001
      iData->SetNumberOfTuples(this->NumCells);
1844
      }
4002
      // have to determine the type of vector
1845
    if(!(temp.find("nonuniform") == vtkstd::string::npos))
4003
      if(iEntry.firstValue().type() == vtkFoamEntryValue::LABELLIST)
1846
      {
1847
      //create an array
1848
      tempStringStruct = this->GetLine(input);
1849
      temp = tempStringStruct->value;
1850
      delete tempStringStruct;
1851
1852
      int vectorCount;
1853
      tokenizer.clear();
1854
      tokenizer << temp;
1855
      tokenizer >> vectorCount;
1856
      data->SetNumberOfComponents(3);
1857
1858
      //binary data
1859
      if(binaryWriteFormat)
1860
        {
4004
        {
1861
        //add values to the array
4005
        const vtkstd::vector<int>& ll = iEntry.labelList();
1862
        input->get(); //parenthesis
4006
        if(ll.size() != 3)
1863
        for(int i = 0; i < vectorCount; i++)
1864
          {
4007
          {
1865
          input->read((char *) &value, sizeof(double));
4008
          vtkErrorMacro(<<"The uniform list isn't a vector of size 3");
1866
          data->InsertComponent(i, 0, value);
4009
          iData->Delete();
1867
          input->read((char *) &value, sizeof(double));
4010
          return false;
1868
          data->InsertComponent(i, 1, value);
4011
          }
1869
          input->read((char *) &value, sizeof(double));
4012
        double v[3];
1870
          data->InsertComponent(i, 2, value);
4013
        v[0] = static_cast<double>(ll[0]);
4014
        v[1] = static_cast<double>(ll[1]);
4015
        v[2] = static_cast<double>(ll[2]);
4016
        for(int i = 0; i < this->NumCells; i++)
4017
          {
4018
          iData->SetTuple(i, v);
1871
          }
4019
          }
1872
        }
4020
        }
1873
4021
      else if(iEntry.firstValue().type() == vtkFoamEntryValue::SCALARLIST)
1874
      //ascii data
1875
      else
1876
        {
4022
        {
1877
        //add values to the array
4023
        vtkDoubleArray& sl = iEntry.scalarList();
1878
        tempStringStruct = this->GetLine(input);
4024
        if(sl.GetSize() != 3)
1879
        temp = tempStringStruct->value;
1880
        delete tempStringStruct; //discard (
1881
        for(int i = 0; i < vectorCount; i++)
1882
          {
4025
          {
1883
          tempStringStruct = this->GetLine(input);
4026
          vtkErrorMacro(
1884
          temp = tempStringStruct->value;
4027
            << "The uniform list isn't a vector of size 3 (actual size "
1885
          delete tempStringStruct;
4028
            << sl.GetSize() << ")");
1886
4029
          iData->Delete();
1887
          //REMOVE BRACKETS
4030
          return false;
1888
          temp.erase(temp.begin()+temp.find("("));
4031
          }
1889
          temp.erase(temp.begin()+temp.find(")"));
4032
        double* v = sl.GetPointer(0);
1890
4033
        for(int i = 0; i < this->NumCells; i++)
1891
          //GRAB X,Y,&Z VALUES
4034
          {
1892
          tokenizer.clear();
4035
          iData->SetTuple(i, v);
1893
          tokenizer << temp;
1894
          tokenizer >> value;
1895
          data->InsertComponent(i, 0, value);
1896
          tokenizer >> value;
1897
          data->InsertComponent(i, 1, value);
1898
          tokenizer >> value;
1899
          data->InsertComponent(i, 2, value);
1900
          }
4036
          }
1901
        }
4037
        }
1902
      }
4038
      else
1903
    else if(!(temp.find("uniform") == vtkstd::string::npos))
1904
      {
1905
      //create an array of uniform values
1906
      double value1, value2, value3;
1907
1908
      //parse out the uniform values
1909
      temp.erase(temp.begin(), temp.begin()+temp.find("(")+1);
1910
      temp.erase(temp.begin()+temp.find(")"), temp.end());
1911
      tokenizer.clear();
1912
      tokenizer << temp;
1913
      tokenizer >> value1;
1914
      tokenizer >> value2;
1915
      tokenizer >> value3;
1916
      data->SetNumberOfComponents(3);
1917
      for(int i = 0; i < NumCells; i++)
1918
        {
4039
        {
1919
        data->InsertComponent(i, 0, value1);
4040
        vtkErrorMacro(<<"Wrong list type");
1920
        data->InsertComponent(i, 1, value2);
4041
        iData->Delete();
1921
        data->InsertComponent(i, 2, value3);
4042
        return false;
1922
        }
4043
        }
1923
      }
4044
      }
1924
4045
    else // nonuniform
1925
    //no data
1926
    else
1927
      {
4046
      {
1928
      input->close();
4047
      if(iEntry.firstValue().type() != vtkFoamEntryValue::VECTORLIST)
1929
      delete input;
4048
        {
1930
      return data;
4049
        vtkErrorMacro(<<"internalField is not a vectorField");
4050
        return false;
4051
        }        
4052
      if(iEntry.vectorList().GetNumberOfTuples() != this->NumCells)
4053
        {
4054
        vtkErrorMacro(<<"Number of cells in mesh and field don't match: "
4055
          << "mesh = " << this->NumCells << ", field = "
4056
          << iEntry.vectorList().GetNumberOfTuples());
4057
        return false;
4058
        }
4059
      iData = (vtkDoubleArray *)iEntry.ptr();
1931
      }
4060
      }
1932
    }
4061
    }
1933
  input->close();
4062
  else
1934
  delete input;
1935
  vtkDebugMacro(<<"Internal variable data read");
1936
  return data;
1937
}
1938
1939
// ****************************************************************************
1940
//  Method: vtkOpenFOAMReader::GetBoundaryVariableAtTimestep
1941
//
1942
//  Purpose:
1943
//  returns the values for a request variable for a bondary region
1944
//
1945
// ****************************************************************************
1946
vtkDoubleArray * vtkOpenFOAMReader::GetBoundaryVariableAtTimestep
1947
                (int boundaryIndex, const char * varNameIn, int timeState,
1948
                 vtkUnstructuredGrid * internalMesh)
1949
{
1950
  vtkstd::string varName(varNameIn);
1951
  vtksys_ios::stringstream varPath;
1952
  varPath << this->PathPrefix->value << this->Steps[timeState] << "/" << varName;
1953
  vtkDebugMacro(<<"Get boundary variable: "<<varPath.str().c_str());
1954
  vtkDoubleArray *data = vtkDoubleArray::New();
1955
1956
  vtkstd::string temp;
1957
  stdString* tempStringStruct;
1958
  bool binaryWriteFormat;
1959
  ifstream * input = new ifstream(varPath.str().c_str(), ios::in VTK_IOS_NOCREATE);
1960
  //make sure file exists
1961
  if(input->fail())
1962
    {
4063
    {
1963
    input->close();
4064
    vtkErrorMacro(<<"Unsupported field class");
1964
    delete input;
4065
    return false;
1965
    return data;
1966
    }
4066
    }
1967
4067
1968
  //determine if file is binary or ascii
4068
  // Add field only if internal Mesh exists (skip if not selected)
1969
  while(temp.find("format") == vtkstd::string::npos)
4069
  // Note we still need to read internalField even if internal mesh is
4070
  // not selected, since boundaries without value entries may refer to
4071
  // the internalField.
4072
  if((iData->GetSize() > 0) 
4073
    && (this->GetPatchArrayStatus(this->GetPatchArrayName(0)))
4074
    && (internalMesh != NULL))
1970
    {
4075
    {
1971
    tempStringStruct = this->GetLine(input);
4076
    iData->SetName(io.objectName().c_str());
1972
    temp = tempStringStruct->value;
4077
    internalMesh->GetCellData()->AddArray(iData);
1973
    delete tempStringStruct;
1974
    }
4078
    }
1975
  input->close();
1976
4079
1977
  //reopen file in correct format
4080
  // set boundary values
1978
  if(temp.find("binary") != vtkstd::string::npos)
4081
  vtkFoamEntry& bEntry = dict.lookup("boundaryField");
1979
    {
4082
  vtkFoamDict& boundaryDict = *boundaryDictPtr;
1980
#ifdef _WIN32
4083
  for(size_t boundaryIndex = 0, i = 0; i < boundaryDict.size(); i++)
1981
    input->open(varPath.str().c_str(), ios::binary | ios::in VTK_IOS_NOCREATE);
1982
#else
1983
    input->open(varPath.str().c_str(), ios::in VTK_IOS_NOCREATE);
1984
#endif
1985
    binaryWriteFormat = true;
1986
    }
1987
  else
1988
    {
4084
    {
1989
    input->open(varPath.str().c_str(),ios::in);
4085
    vtkFoamEntry& boundaryEntryI = boundaryDict.entry(i);
1990
    binaryWriteFormat = false;
4086
    int nFaces;
1991
    }
4087
    boundaryEntryI.dictionary().lookup("nFaces") >> nFaces;
1992
1993
  vtkstd::string foamClass;
1994
  vtksys_ios::stringstream tokenizer;
1995
  double value;
1996
4088
1997
  //find class
4089
    // skip empty boundary
1998
  tempStringStruct = this->GetLine(input);
4090
    if(nFaces == 0)
1999
  temp = tempStringStruct->value;
2000
  delete tempStringStruct;
2001
  while(temp.find("class") == vtkstd::string::npos)
2002
    {
2003
    tempStringStruct = this->GetLine(input);
2004
    temp = tempStringStruct->value;
2005
    delete tempStringStruct;
2006
    }
2007
  temp.erase(temp.begin()+temp.find(";"));
2008
  tokenizer << temp;
2009
  //while(tokenizer >> foamClass);
2010
  while(!tokenizer.eof())
2011
    {
2012
    tokenizer >> foamClass;
2013
    }
2014
  temp="";
2015
  //create scalar arrays
2016
  if(foamClass =="volScalarField")
2017
    {
2018
    //find desired mesh
2019
    while(temp.find(this->BoundaryNames->value[boundaryIndex]) == 
2020
            vtkstd::string::npos && !input->eof())
2021
      {
4091
      {
2022
      tempStringStruct = this->GetLine(input);
4092
      continue;
2023
      temp = tempStringStruct->value;
2024
      delete tempStringStruct;
2025
      }
4093
      }
2026
    if(input->eof())
4094
4095
    const vtkStdString& boundaryNameI = boundaryEntryI.keyword();
4096
4097
    // Add field only if given boundary is selected for display
4098
    if(!this->GetPatchArrayStatus(boundaryNameI.c_str()))
2027
      {
4099
      {
2028
      input->close();
4100
      continue;
2029
      delete input;
2030
      return data;
2031
      }
4101
      }
2032
    //find value entry
4102
2033
    while(temp.find("}") == vtkstd::string::npos &&
4103
    vtkFoamEntry& bEntryI = bEntry.dictionary().lookup(boundaryNameI);
2034
          temp.find("value ") == vtkstd::string::npos)
4104
    if(!bEntryI.found())
2035
      {
4105
      {
2036
      tempStringStruct = this->GetLine(input);
4106
      vtkErrorMacro(<< "boundaryField " << boundaryNameI.c_str()
2037
      temp = tempStringStruct->value;
4107
        << " not found in object " << varNameIn << " at time = "
2038
      delete tempStringStruct; //find value
4108
        << this->TimeNames->GetValue(timeState).c_str());
4109
      iData->Delete();
4110
      return false;
2039
      }
4111
      }
2040
4112
2041
    //nonuniform
4113
    if(bEntryI.firstValue().type() != vtkFoamEntryValue::DICTIONARY)
2042
    if(!(temp.find("nonuniform") == vtkstd::string::npos))
2043
      {
4114
      {
4115
      vtkErrorMacro(<< "Type of boundaryField " << boundaryNameI.c_str()
4116
        << " is not a subdictionary in object " << varNameIn << " at time = "
4117
        << this->TimeNames->GetValue(timeState).c_str());
4118
      iData->Delete();
4119
      return false;
4120
      }
2044
4121
2045
      //binary data
4122
    vtkDoubleArray* vData;
2046
      if(binaryWriteFormat)
2047
        {
2048
        //create an array
2049
        tempStringStruct = this->GetLine(input);
2050
        temp = tempStringStruct->value;
2051
        delete tempStringStruct;
2052
2053
        int scalarCount;
2054
        tokenizer.clear();
2055
        tokenizer << temp;
2056
        tokenizer >> scalarCount;
2057
        data->SetNumberOfValues(scalarCount);
2058
4123
2059
        //assign values to the array
4124
    vtkFoamEntry& vEntry = bEntryI.dictionary().lookup("value");
2060
        input->get(); //parenthesis
4125
    // uniformValue is for Hrv's dev version
2061
        for(int i = 0; i < scalarCount; i++)
4126
    vtkFoamEntry& uvEntry = bEntryI.dictionary().lookup("uniformValue");
4127
    
4128
    if(vEntry.found() || uvEntry.found()) // the boundary has a value entry
4129
      {
4130
      if(io.className() == "volScalarField")
4131
        {
4132
        if((vEntry.found() && vEntry.firstValue().isUniform())
4133
          || uvEntry.found())
4134
          {
4135
          vData = vtkDoubleArray::New();
4136
          vData->SetNumberOfValues(nFaces);
4137
          double num;
4138
          if(vEntry.found()) // "value" entry has the priority
4139
            {
4140
            vEntry >> num;
4141
            }
4142
          else
4143
            {
4144
            uvEntry >> num;
4145
            }
4146
          for(int j = 0; j < nFaces; j++)
4147
            {
4148
            vData->SetValue(j, num);
4149
            }
4150
          }
4151
        else // nonuniform
2062
          {
4152
          {
2063
          input->read((char *) &value, sizeof(double));
4153
          if(vEntry.firstValue().type() != vtkFoamEntryValue::SCALARLIST)
2064
          data->SetValue(i, value);
4154
            {
4155
            vtkErrorMacro(<<"boundaryField " << boundaryNameI.c_str()
4156
              << " is not a scalarField");
4157
            iData->Delete();
4158
            return false;
4159
            }
4160
          if(vEntry.scalarList().GetSize() != nFaces)
4161
            {
4162
            vtkErrorMacro(<<"Number of faces in field and bondary don't match");
4163
            iData->Delete();
4164
            return false;
4165
            }
4166
          vData = (vtkDoubleArray *)vEntry.ptr();
2065
          }
4167
          }
2066
        }
4168
        }
2067
4169
      else if(io.className() == "volVectorField")
2068
      //ascii data
2069
      else
2070
        {
4170
        {
2071
        temp.erase(temp.begin(), temp.begin()+temp.find(">")+1);
4171
        if((vEntry.found() && vEntry.firstValue().isUniform())
2072
        //ascii data with 10 or less values are on the same line
4172
          || uvEntry.found())
2073
        //>10
4173
          {
2074
        if(temp == vtkstd::string(" "))
4174
          vData = vtkDoubleArray::New();
2075
          {
4175
          vData->SetNumberOfComponents(3);
2076
          //create an array of data
4176
          vData->SetNumberOfTuples(nFaces);
2077
          tempStringStruct = this->GetLine(input);
4177
          // the "value" entry has the priority
2078
          temp = tempStringStruct->value;
4178
          vtkFoamEntry& vvEntry = vEntry.found() ? vEntry : uvEntry;
2079
          delete tempStringStruct;
4179
          // have to determine the type of vector
2080
4180
          if(vvEntry.firstValue().type() == vtkFoamEntryValue::LABELLIST)
2081
          int scalarCount;
4181
            {
2082
          tokenizer.clear();
4182
            const vtkstd::vector<int>& ll = vvEntry.labelList();
2083
          tokenizer << temp;
4183
            if(ll.size() != 3)
2084
          tokenizer >> scalarCount;
4184
              {
2085
          data->SetNumberOfValues(scalarCount);
4185
              vtkErrorMacro(<<"The uniform list isn't a vector of size 3");
2086
          tempStringStruct = this->GetLine(input);
4186
              iData->Delete();
2087
          temp = tempStringStruct->value;
4187
              vData->Delete();
2088
          delete tempStringStruct; //discard (
4188
              return false;
2089
4189
              }
2090
          for(int i = 0; i < scalarCount; i++)
4190
            double v[3];
2091
            {
4191
            v[0] = static_cast<double>(ll[0]);
2092
            tempStringStruct = this->GetLine(input);
4192
            v[1] = static_cast<double>(ll[1]);
2093
            temp = tempStringStruct->value;
4193
            v[2] = static_cast<double>(ll[2]);
2094
            delete tempStringStruct;
4194
            for(int j = 0; j < nFaces; j++)
2095
4195
              {
2096
            tokenizer.clear();
4196
              vData->SetTuple(j, v);
2097
            tokenizer << temp;
4197
              }
2098
            tokenizer >> value;
4198
            }
2099
            data->SetValue(i, value);
4199
          else if(vvEntry.firstValue().type() == vtkFoamEntryValue::SCALARLIST)
4200
            {
4201
            vtkDoubleArray& sl = vvEntry.scalarList();
4202
            if(sl.GetSize() != 3)
4203
              {
4204
              vtkErrorMacro(<< "The uniform value list in patch "
4205
                << boundaryNameI.c_str() << " of file "
4206
                << io.fileName().c_str()
4207
                << " isn't a vector of size 3 (actual size " << sl.GetSize()
4208
                << ")");
4209
              iData->Delete();
4210
              vData->Delete();
4211
              return false;
4212
              }
4213
            double* v = sl.GetPointer(0);
4214
            for(int j = 0; j < nFaces; j++)
4215
              {
4216
              vData->SetTuple(j, v);
4217
              }
4218
            }
4219
          else
4220
            {
4221
            vtkErrorMacro(<<"Wrong list type");
4222
            iData->Delete();
4223
            vData->Delete();
4224
            return false;
2100
            }
4225
            }
2101
          }
4226
          }
2102
        //=<10
4227
        else // nonuniform
2103
        else
2104
          {
4228
          {
2105
          //create an array with data
4229
          if(vEntry.firstValue().type() != vtkFoamEntryValue::VECTORLIST)
2106
          int scalarCount;
4230
            {
2107
          tokenizer.clear();
4231
            vtkErrorMacro(<<"boundaryField " << boundaryNameI.c_str()
2108
          tokenizer << temp;
4232
              << " is not a vectorField");
2109
          tokenizer >> scalarCount;
4233
            iData->Delete();
2110
          data->SetNumberOfValues(scalarCount);
4234
            return false;
2111
          temp.erase(temp.begin(), temp.begin()+temp.find("(")+1);
4235
            }
2112
          temp.erase(temp.begin()+temp.find(")"), temp.end());
4236
          if(vEntry.vectorList().GetNumberOfTuples() != nFaces)
2113
2114
          tokenizer.clear();
2115
          tokenizer << temp;
2116
          for(int i = 0; i < scalarCount; i++)
2117
            {
4237
            {
2118
            tokenizer >> value;
4238
            vtkErrorMacro(<<"Number of faces in field and bondary don't match");
2119
            data->SetValue(i, value);
4239
            iData->Delete();
4240
            return false;
2120
            }
4241
            }
4242
          vData = (vtkDoubleArray *)vEntry.ptr();
2121
          }
4243
          }
2122
        }
4244
        }
2123
      }
4245
      else // other field types
2124
2125
    //uniform
2126
    else if(!(temp.find("uniform") == vtkstd::string::npos))
2127
      {
2128
      //create an array of uniform values
2129
      double value1 = 0;
2130
      temp.erase(temp.begin(), temp.begin()+temp.find("uniform")+7);
2131
      temp.erase(temp.begin()+temp.find(";"), temp.end());
2132
      tokenizer.clear();
2133
      tokenizer << temp;
2134
      tokenizer >> value1;
2135
      data->SetNumberOfValues(this->SizeOfBoundary->value[boundaryIndex]);
2136
      for(int i = 0; i < this->SizeOfBoundary->value[boundaryIndex]; i++)
2137
        {
2138
        data->SetValue(i, value1);
2139
        }
2140
      }
2141
2142
    //no data
2143
    else
2144
      {
2145
      int cellId;
2146
      vtkDataArray * internalData = internalMesh->GetCellData()->
2147
                                    GetArray(varName.c_str());
2148
      data->SetNumberOfValues(this->SizeOfBoundary->value[boundaryIndex]);
2149
      for(int i = 0; i < this->SizeOfBoundary->value[boundaryIndex]; i++)
2150
        {
4246
        {
2151
        cellId = this->FaceOwner->GetValue(this->StartFace + i);
4247
        vtkErrorMacro(<<"Unsupported field class");
2152
        data->SetValue(i, internalData->GetComponent(cellId, 0));
4248
        iData->Delete();
4249
        return false;
2153
        }
4250
        }
2154
      input->close();
2155
      delete input;
2156
      return data;
2157
      }
2158
    }
2159
  //CREATE VECTOR ARRAYS
2160
  else if(foamClass == "volVectorField")
2161
    {
2162
    while(temp.find(this->BoundaryNames->value[boundaryIndex]) == 
2163
          vtkstd::string::npos && !input->eof())
2164
      {
2165
      tempStringStruct = this->GetLine(input);
2166
      temp = tempStringStruct->value;
2167
      delete tempStringStruct;
2168
      }
2169
    if(input->eof())
2170
      {
2171
      input->close();
2172
      delete input;
2173
      return data;
2174
      }
4251
      }
2175
    while(temp.find("}") == vtkstd::string::npos &&
4252
    else // doesn't have a value entry
2176
          temp.find("value ") == vtkstd::string::npos)
2177
      {
4253
      {
2178
      tempStringStruct = this->GetLine(input);
4254
      int startFace;
2179
      temp = tempStringStruct->value;
4255
      boundaryEntryI.dictionary().lookup("startFace") >> startFace;
2180
      delete tempStringStruct; //find value
4256
      vData = vtkDoubleArray::New();
2181
      }
2182
    //nonuniform
2183
    if(!(temp.find("nonuniform") == vtkstd::string::npos))
2184
      {
2185
      //create an array
2186
      tempStringStruct = this->GetLine(input);
2187
      temp = tempStringStruct->value;
2188
      delete tempStringStruct;
2189
4257
2190
      int vectorCount;
4258
      if(io.className() == "volScalarField")
2191
      tokenizer.clear();
2192
      tokenizer << temp;
2193
      tokenizer >> vectorCount;
2194
      data->SetNumberOfComponents(3);
2195
2196
      //binary data
2197
      if(binaryWriteFormat)
2198
        {
4259
        {
2199
        //insert values into the array
4260
        vData->SetNumberOfValues(nFaces);
2200
        input->get(); //parenthesis
4261
        for(int j = 0; j < nFaces; j++)
2201
        for(int i = 0; i < vectorCount; i++)
2202
          {
4262
          {
2203
          input->read((char *) &value, sizeof(double));
4263
          const int cellId = this->FaceOwner->GetValue(startFace + j);
2204
          data->InsertComponent(i, 0, value);
4264
          vData->SetValue(j, iData->GetValue(cellId));
2205
          input->read((char *) &value, sizeof(double));
2206
          data->InsertComponent(i, 1, value);
2207
          input->read((char *) &value, sizeof(double));
2208
          data->InsertComponent(i, 2, value);
2209
          }
4265
          }
2210
        }
4266
        }
2211
4267
      else if(io.className() == "volVectorField")
2212
        //ascii data
4268
        {
2213
        else
4269
        vData->SetNumberOfComponents(3);
4270
        vData->SetNumberOfTuples(nFaces);
4271
        for(int j = 0; j < nFaces; j++)
2214
          {
4272
          {
2215
          //insert values into the array
4273
          const int cellId = this->FaceOwner->GetValue(startFace + j);
2216
          tempStringStruct = this->GetLine(input);
4274
          // in this case GetTuple should be thread-safe accoding to
2217
          temp = tempStringStruct->value;
4275
          // the FAQ on ParaView Wiki
2218
          delete tempStringStruct; //discard (
4276
          vData->SetTuple(j, iData->GetTuple(cellId));
2219
          for(int i = 0; i < vectorCount; i++)
2220
            {
2221
            tempStringStruct = this->GetLine(input);
2222
            temp = tempStringStruct->value;
2223
            delete tempStringStruct;
2224
2225
            //REMOVE BRACKETS
2226
            temp.erase(temp.begin()+temp.find("("));
2227
            temp.erase(temp.begin()+temp.find(")"));
2228
2229
            //GRAB X,Y,&Z VALUES
2230
            tokenizer.clear();
2231
            tokenizer << temp;
2232
            tokenizer >> value;
2233
            data->InsertComponent(i, 0, value);
2234
            tokenizer >> value;
2235
            data->InsertComponent(i, 1, value);
2236
            tokenizer >> value;
2237
            data->InsertComponent(i, 2, value);
2238
            }
2239
          }
4277
          }
2240
        }
4278
        }
2241
4279
      else
2242
    //uniform
2243
    else if(!(temp.find("uniform") == vtkstd::string::npos))
2244
      {
2245
      //create an array of uniform values
2246
      double value1 = 0, value2 = 0, value3 = 0;
2247
      temp.erase(temp.begin(), temp.begin()+temp.find("(")+1);
2248
      temp.erase(temp.begin()+temp.find(")"), temp.end());
2249
      tokenizer.clear();
2250
      tokenizer << temp;
2251
      tokenizer >> value1;
2252
      tokenizer >> value2;
2253
      tokenizer >> value3;
2254
2255
      data->SetNumberOfComponents(3);
2256
      for(int i = 0; i < this->SizeOfBoundary->value[boundaryIndex]; i++)
2257
        {
4280
        {
2258
        data->InsertComponent(i, 0, value1);
4281
        vtkErrorMacro(<<"Unsupported field class");
2259
        data->InsertComponent(i, 1, value2);
4282
        iData->Delete();
2260
        data->InsertComponent(i, 2, value3);
4283
        vData->Delete();
4284
        return false;
2261
        }
4285
        }
2262
      }
4286
      }
2263
4287
    if(vData->GetSize() > 0)
2264
    //no data
2265
    else
2266
      {
4288
      {
2267
      int cellId;
4289
      vData->SetName(io.objectName().c_str());
2268
      vtkDataArray * internalData = internalMesh->GetCellData()->
4290
      boundaryMesh->value[boundaryIndex]->GetCellData()
2269
                                    GetArray(varName.c_str());
4291
        ->AddArray(vData);
2270
      data->SetNumberOfComponents(3);
2271
      for(int i = 0; i < this->SizeOfBoundary->value[boundaryIndex]; i++)
2272
        {
2273
        cellId = this->FaceOwner->GetValue(this->StartFace + i);
2274
        data->InsertComponent(i, 0, internalData->GetComponent(cellId, 0));
2275
        data->InsertComponent(i, 1, internalData->GetComponent(cellId, 1));
2276
        data->InsertComponent(i, 2, internalData->GetComponent(cellId, 2));
2277
        }
2278
      input->close();
2279
      delete input;
2280
      return data;
2281
      }
4292
      }
4293
    vData->Delete();
4294
    boundaryIndex++;
2282
    }
4295
    }
2283
  input->close();
4296
2284
  delete input;
4297
  iData->Delete();
2285
  vtkDebugMacro(<<"Boundary data read");
4298
  vtkDebugMacro(<<"Internal variable data read");
2286
  return data;
4299
  return true;
2287
}
4300
}
2288
4301
2289
// ****************************************************************************
4302
// ****************************************************************************
2290
//  Method: vtkOpenFOAMReader::GatherBlocks
4303
//  Method: vtkOpenFOAMReader::GatherBlocks
2291
//
4304
//
2292
//  Purpose:
4305
//  Purpose:
2293
//  returns a vector of block names for a specified domain
4306
//  returns a dictionary of block names for a specified domain
2294
//
4307
//
2295
// ****************************************************************************
4308
// ****************************************************************************
2296
stringVector * vtkOpenFOAMReader::GatherBlocks(const char * typeIn,
4309
vtkOpenFOAMReader::vtkFoamDict* vtkOpenFOAMReader::GatherBlocks(
2297
                                              int timeState)
4310
  const char* typeIn, int timeState, bool mustRead)
2298
{
4311
{
2299
  vtkstd::string type(typeIn);
4312
  vtkStdString type(typeIn);
2300
  vtkstd::string blockPath = this->PathPrefix->value +
4313
  vtkStdString blockPath = *this->PathPrefix
2301
                             this->PolyMeshFacesDir->value[timeState] +
4314
    + this->PolyMeshFacesDir->value[timeState] + "/polyMesh/" + type;
2302
                             "/polyMesh/"+type;
4315
2303
  vtkstd::vector< vtkstd::string > blocks;
4316
  vtkFoamIOobject io;
2304
  stringVector *returnValue = new stringVector;
4317
  if(!(io.open(blockPath) || io.open(blockPath + ".gz")))
2305
  vtkDebugMacro(<<"Get blocks: "<<blockPath.c_str());
4318
    {
2306
4319
    if(mustRead)
2307
  ifstream * input = new ifstream(blockPath.c_str(), ios::in VTK_IOS_NOCREATE);
4320
      {
2308
  //if there is no file return a null vector
4321
      vtkErrorMacro(<<"Error opening " << io.fileName().c_str() << ": "
2309
  if(input->fail())
4322
        << io.error().str().c_str());
2310
    {
4323
      }
2311
    input->close();
4324
    return NULL;
2312
    delete input;
4325
    }
2313
    returnValue->value = blocks;
4326
2314
    return returnValue;
4327
  vtkFoamDict* dictPtr = new vtkFoamDict;
2315
    }
4328
  vtkFoamDict& dict = *dictPtr;
2316
4329
  if(!dict.read(io))
2317
  vtkstd::string temp;
4330
    {
2318
  stdString* tempStringStruct;
4331
    vtkErrorMacro(<<"Error reading line " << io.lineNumber()
2319
  vtkstd::string token;
4332
      << " of " << io.fileName().c_str() << ": " << io.error().str().c_str());
2320
  vtksys_ios::stringstream tokenizer;
4333
    delete dictPtr;
2321
  vtkstd::string tempName;
4334
    return NULL;
2322
4335
    }
2323
  //find end of header
4336
  if(dict.type() != vtkFoamDict::DICTIONARY)
2324
  //while(temp.compare(0,4,"// *",0,4)!=0)
4337
    {
2325
  while (strcmp(temp.substr(0,4).c_str(), "// *"))
4338
    vtkErrorMacro(<<"The file type of " << io.fileName().c_str()
2326
    {
4339
      << " is not a dictionary");
2327
    tempStringStruct = this->GetLine(input);
4340
    delete dictPtr;
2328
    temp = tempStringStruct->value;
4341
    return NULL;
2329
    delete tempStringStruct;
4342
    }
2330
    }
4343
  return dictPtr;
2331
  tempStringStruct = this->GetLine(input);
2332
  temp = tempStringStruct->value;
2333
  delete tempStringStruct;
2334
2335
  tempStringStruct = this->GetLine(input);
2336
  temp = tempStringStruct->value;
2337
  delete tempStringStruct; //throw out blank line
2338
2339
  //Number of blocks
2340
  tokenizer << temp;
2341
  tokenizer >> this->NumBlocks;
2342
  blocks.resize(this->NumBlocks);
2343
2344
  //loop through each block
2345
  for(int i = 0; i < this->NumBlocks; i++)
2346
    {
2347
    tempStringStruct = this->GetLine(input);
2348
    temp = tempStringStruct->value;
2349
    delete tempStringStruct; //throw out blank line
2350
2351
    //NAME
2352
    tempStringStruct = this->GetLine(input);
2353
    temp = tempStringStruct->value;
2354
    delete tempStringStruct; //name
2355
2356
    tokenizer.clear();
2357
    tokenizer << temp;
2358
    tokenizer >> tempName;
2359
    blocks[i] = tempName;
2360
    //while(temp.compare(0,1,"}",0,1) != 0)
2361
    while (strcmp(temp.substr(0,1).c_str(), "}"))
2362
      {
2363
      tempStringStruct = this->GetLine(input);
2364
      temp = tempStringStruct->value;
2365
      delete tempStringStruct;
2366
      }
2367
    }
2368
  returnValue->value = blocks;
2369
  input->close();
2370
  delete input;
2371
  return returnValue;
2372
}
4344
}
2373
4345
2374
// ****************************************************************************
4346
// ****************************************************************************
Lines 2378-2515 Link Here
2378
//  returns a requested boundary mesh
4350
//  returns a requested boundary mesh
2379
//
4351
//
2380
// ****************************************************************************
4352
// ****************************************************************************
2381
vtkUnstructuredGrid * vtkOpenFOAMReader::GetBoundaryMesh(int timeState,
4353
unstructuredGridVector* vtkOpenFOAMReader::GetBoundaryMesh(
2382
                                                         int boundaryIndex)
4354
  vtkFoamDict* boundaryDictPtr, intVectorVector* facesPoints,
4355
  vtkPoints* points)
2383
{
4356
{
2384
  vtkUnstructuredGrid * boundaryMesh = vtkUnstructuredGrid::New();
4357
  vtkFoamDict& boundaryDict = *boundaryDictPtr;
2385
  vtkstd::string boundaryPath = this->PathPrefix->value +
4358
  unstructuredGridVector* boundaryMesh = new unstructuredGridVector;
2386
                                this->PolyMeshFacesDir->value[timeState] +
2387
                                "/polyMesh/boundary";
2388
  vtkDebugMacro(<<"Create boundary mesh: "<<boundaryPath.c_str());
2389
4359
2390
  int nFaces;
4360
  for(size_t boundaryIndex = 0; boundaryIndex < boundaryDict.size();
2391
4361
    boundaryIndex++)
2392
  ifstream * input = new ifstream(boundaryPath.c_str(), ios::in VTK_IOS_NOCREATE);
2393
  //return a Null object
2394
  if(input->fail())
2395
    {
4362
    {
2396
    input->close();
4363
    vtkFoamDict& dict = boundaryDict.entry(boundaryIndex).dictionary();
2397
    delete input;
2398
    return boundaryMesh;
2399
    }
2400
4364
2401
  vtkstd::string temp;
4365
    int nFaces;
2402
  stdString* tempStringStruct;
4366
    vtkFoamEntry& nFacesEntry = dict.lookup("nFaces");
2403
  vtkstd::string token;
4367
    vtkFoamEntry& startFaceEntry = dict.lookup("startFace");
2404
  vtksys_ios::stringstream tokenizer;
4368
    if(!nFacesEntry.found() || !startFaceEntry.found())
4369
      {
4370
      vtkWarningMacro(
4371
        << "Entry nFaces or startFace not found in boundary entry "
4372
        << boundaryDict.entry(boundaryIndex).keyword().c_str());
4373
      for(size_t i = 0; i < boundaryMesh->value.size(); i++)
4374
        {
4375
        boundaryMesh->value[i]->Delete();
4376
        }
4377
      delete boundaryMesh;
4378
      return NULL;
4379
      }
4380
    nFacesEntry >> nFaces;
2405
4381
2406
  //find desired mesh entry
4382
    // skip empty boundary
2407
  while(temp.find(this->BoundaryNames->value[boundaryIndex]) == 
4383
    if(nFaces == 0)
2408
        vtkstd::string::npos)
4384
      {
2409
    {
4385
      continue;
2410
    tempStringStruct = this->GetLine(input);
4386
      }
2411
    temp = tempStringStruct->value;
2412
    delete tempStringStruct;
2413
    }
2414
4387
2415
  //get nFaces
4388
    // Create a boundary mesh only if selected in the list for display
2416
  while(temp.find("nFaces") == vtkstd::string::npos)
4389
    vtkFoamEntry& boundaryEntryI = boundaryDict.entry(boundaryIndex);
2417
    {
4390
    const vtkStdString& boundaryNameI = boundaryEntryI.keyword();
2418
    tempStringStruct = this->GetLine(input);
4391
    if(!this->GetPatchArrayStatus(boundaryNameI.c_str()))
2419
    temp = tempStringStruct->value;
4392
      {
2420
    delete tempStringStruct;
4393
      continue;
2421
    }
4394
      }
2422
  temp.erase(temp.begin()+temp.find(";")); //remove ;
2423
  tokenizer << temp;
2424
  //while(tokenizer >> token);
2425
  while(!tokenizer.eof())
2426
    {
2427
    tokenizer >> token;
2428
    }
2429
  tokenizer.clear();
2430
  tokenizer << token;
2431
  tokenizer >> nFaces;
2432
4395
2433
  //get startface
4396
    int startFace;
2434
  tempStringStruct = this->GetLine(input);
4397
    startFaceEntry >> startFace;
2435
  temp = tempStringStruct->value;
2436
  delete tempStringStruct;
2437
4398
2438
  //look for "startFaces"
4399
    int endFace = startFace + nFaces;
2439
  while(temp.find("startFace") == vtkstd::string::npos)
2440
    {
2441
    tempStringStruct = this->GetLine(input);
2442
    temp = tempStringStruct->value;
2443
    delete tempStringStruct;
2444
    }
2445
  temp.erase(temp.begin()+temp.find(";")); //remove ;
2446
  tokenizer.clear();
2447
  tokenizer << temp;
2448
  //while(tokenizer >> token);
2449
  while(!tokenizer.eof())
2450
    {
2451
    tokenizer >> token;
2452
    }
2453
  tokenizer.clear();
2454
  tokenizer << token;
2455
  tokenizer >> this->StartFace;
2456
4400
2457
  //Create the mesh
4401
    //Create the mesh
2458
  int j, k;
4402
    boundaryMesh->value.push_back(vtkUnstructuredGrid::New());
2459
  vtkTriangle * triangle;
4403
    vtkUnstructuredGrid& bm = *boundaryMesh->value.back();
2460
  vtkQuad * quad;
4404
    bm.Allocate(nFaces);
2461
  vtkPolygon * polygon;
2462
  int endFace = this->StartFace + nFaces;
2463
  //loop through each face
2464
  for(j = this->StartFace; j < endFace; j++)
2465
    {
2466
4405
2467
    //triangle
4406
    // aloocate array for converting int vector to vtkIdType vector:
2468
    if(this->FacePoints->value[j].size() == 3)
4407
    // workaround for 64bit machines
4408
    int maxNFacePoints = 0;
4409
    for(int j = startFace; j < endFace; j++)
2469
      {
4410
      {
2470
      triangle = vtkTriangle::New();
4411
      const int nFacePoints = facesPoints->value[j].size();
2471
      for(k = 0; k < 3; k++)
4412
      if(nFacePoints > maxNFacePoints)
2472
        {
4413
        {
2473
        triangle->GetPointIds()->SetId(k, this->FacePoints->value[j][k]);
4414
        maxNFacePoints = nFacePoints;
2474
        }
4415
        }
2475
      boundaryMesh->InsertNextCell(triangle->GetCellType(),
2476
      triangle->GetPointIds());
2477
      triangle->Delete();
2478
      }
4416
      }
4417
    vtkIdType* facePointsVtkId = new vtkIdType[maxNFacePoints];
2479
4418
2480
    //quad
4419
    //loop through each face
2481
    else if(this->FacePoints->value[j].size() == 4)
4420
    for(int j = startFace; j < endFace; j++)
2482
      {
4421
      {
2483
      quad = vtkQuad::New();
4422
      vtkstd::vector<int>& facePoints = facesPoints->value[j];
2484
      for(k = 0; k < 4; k++)
4423
      size_t nFacePoints = facePoints.size();
4424
4425
      for(size_t k = 0; k < nFacePoints; k++)
2485
        {
4426
        {
2486
        quad->GetPointIds()->SetId(k, this->FacePoints->value[j][k]);
4427
        facePointsVtkId[k] = facePoints[k];
2487
        }
4428
        }
2488
      boundaryMesh->InsertNextCell(quad->GetCellType(),
2489
      quad->GetPointIds());
2490
      quad->Delete();
2491
      }
2492
4429
2493
    //polygon
4430
      //triangle
2494
    else
4431
      if(nFacePoints == 3)
2495
      {
4432
        {
2496
      polygon = vtkPolygon::New();
4433
        bm.InsertNextCell(VTK_TRIANGLE, 3, facePointsVtkId);
2497
      for(k = 0; k < (int)this->FacePoints->value[j].size(); k++)
4434
        }
4435
      // quad
4436
      else if(nFacePoints == 4)
2498
        {
4437
        {
2499
        polygon->GetPointIds()->InsertId(k, this->FacePoints->value[j][k]);
4438
        bm.InsertNextCell(VTK_QUAD, 4, facePointsVtkId);
4439
        }
4440
      //polygon
4441
      else
4442
        {
4443
        bm.InsertNextCell(VTK_POLYGON, nFacePoints,
4444
          facePointsVtkId);
2500
        }
4445
        }
2501
      boundaryMesh->InsertNextCell(polygon->GetCellType(),
2502
      polygon->GetPointIds());
2503
      polygon->Delete();
2504
      }
4446
      }
2505
    }
4447
    delete [] facePointsVtkId;
2506
4448
2507
  //set points for boundary
4449
    //set points for boundary
2508
  boundaryMesh->SetPoints(this->Points);
4450
    bm.SetPoints(points);
2509
  //add size of mesh
4451
    }
2510
  this->SizeOfBoundary->value.push_back(boundaryMesh->GetNumberOfCells());
2511
  input->close();
2512
  delete input;
2513
  vtkDebugMacro(<<"Boundary mesh created");
4452
  vtkDebugMacro(<<"Boundary mesh created");
2514
  return boundaryMesh;
4453
  return boundaryMesh;
2515
}
4454
}
Lines 2521-2668 Link Here
2521
//  returns a requested point zone mesh
4460
//  returns a requested point zone mesh
2522
//
4461
//
2523
// ****************************************************************************
4462
// ****************************************************************************
2524
vtkUnstructuredGrid * vtkOpenFOAMReader::GetPointZoneMesh(int timeState,
4463
bool vtkOpenFOAMReader::GetPointZoneMesh(unstructuredGridVector* pointZoneMesh,
2525
                                                          int pointZoneIndex)
4464
  vtkPoints* points, int timeState)
2526
{
4465
{
2527
  vtkUnstructuredGrid * pointZoneMesh = vtkUnstructuredGrid::New();
4466
  vtkDebugMacro(<<"Create point zone mesh");
2528
  vtkstd::string pointZonesPath = this->PathPrefix->value[timeState]+
2529
                               "/polyMesh/pointZones";
2530
  vtkDebugMacro(<<"Create point zone mesh: "<<pointZonesPath.c_str());
2531
4467
2532
  vtkstd::string temp;
4468
  vtkFoamDict* pointZoneDictPtr
2533
  stdString* tempStringStruct;
4469
    = this->GatherBlocks("pointZones", timeState, false);
2534
  bool binaryWriteFormat;
2535
  ifstream * input = new ifstream(pointZonesPath.c_str(), ios::in VTK_IOS_NOCREATE);
2536
  //make sure file exists
2537
  if(input->fail())
2538
    {
2539
    input->close();
2540
    delete input;
2541
    return pointZoneMesh;
2542
    }
2543
4470
2544
  //determine if file is binary or ascii
4471
  if(pointZoneDictPtr == NULL)
2545
  while(temp.find("format") == vtkstd::string::npos)
2546
    {
4472
    {
2547
    tempStringStruct = this->GetLine(input);
4473
    // not an error
2548
    temp = tempStringStruct->value;
4474
    return true;
2549
    delete tempStringStruct;
2550
    }
4475
    }
2551
  input->close();
2552
4476
2553
  //reopen file in correct format
4477
  vtkFoamDict& pointZoneDict = *pointZoneDictPtr;
2554
  if(temp.find("binary") != vtkstd::string::npos)
4478
  size_t nPointZones = pointZoneDict.size();
2555
    {
2556
#ifdef _WIN32
2557
    input->open(pointZonesPath.c_str(), ios::binary | ios::in VTK_IOS_NOCREATE);
2558
#else
2559
    input->open(pointZonesPath.c_str(), ios::in VTK_IOS_NOCREATE);
2560
#endif
2561
    binaryWriteFormat = true;
2562
    }
2563
  else
2564
    {
2565
    input->open(pointZonesPath.c_str(),ios::in);
2566
    binaryWriteFormat = false;
2567
    }
2568
4479
2569
  vtkstd::string token;
4480
  for(size_t i = 0; i < nPointZones; i++)
2570
  vtksys_ios::stringstream tokenizer;
4481
    {
2571
  vtkVertex * pointCell;
4482
    // look up point labels
2572
  int tempElement;
4483
    vtkFoamDict& dict = pointZoneDict.entry(i).dictionary();
2573
  vtkstd::vector< vtkstd::vector < int > > tempElementZones;
4484
    vtkFoamEntry& pointLabelsEntry = dict.lookup("pointLabels");
2574
  int numElement;
4485
    if(!pointLabelsEntry.found())
2575
2576
  //find desired mesh entry
2577
  while(temp.find(this->PointZoneNames->value[pointZoneIndex]) == 
2578
        vtkstd::string::npos)
2579
    {
2580
    tempStringStruct = this->GetLine(input);
2581
    temp = tempStringStruct->value;
2582
    delete tempStringStruct;
2583
    }
2584
  tempStringStruct = this->GetLine(input);
2585
  temp = tempStringStruct->value;
2586
  delete tempStringStruct;//throw out {
2587
2588
  tempStringStruct = this->GetLine(input);
2589
  temp = tempStringStruct->value;
2590
  delete tempStringStruct;//type
2591
2592
  tempStringStruct = this->GetLine(input);
2593
  temp = tempStringStruct->value;
2594
  delete tempStringStruct;//label
2595
2596
  tempStringStruct = this->GetLine(input);
2597
  temp = tempStringStruct->value;
2598
  delete tempStringStruct;//number of elements or {
2599
2600
  //number of elements
2601
  if(temp.find("}") == vtkstd::string::npos)
2602
    {
2603
    tokenizer << temp;
2604
    tokenizer >> numElement;
2605
    if(numElement == 0)
2606
      {
4486
      {
2607
      input->close();
4487
      vtkErrorMacro(<<"pointLabels not found in pointZones");
2608
      delete input;
4488
      return false;
2609
      return NULL;
2610
      }
4489
      }
2611
4490
    // skip if the list is empty
2612
    //binary data
4491
    if(pointLabelsEntry.firstValue().type() == vtkFoamEntryValue::EMPTYLIST)
2613
    if(binaryWriteFormat)
2614
      {
4492
      {
2615
      input->get(); //parenthesis
4493
      continue;
2616
      for(int j = 0; j < numElement; j++)
2617
        {
2618
        input->read((char *) &tempElement, sizeof(int));
2619
        pointCell = vtkVertex::New();
2620
        pointCell->GetPointIds()->SetId(0,tempElement);
2621
        pointZoneMesh->InsertNextCell(pointCell->GetCellType(),
2622
                                      pointCell->GetPointIds());
2623
        pointCell->Delete();
2624
        }
2625
      }
4494
      }
2626
4495
    if(pointLabelsEntry.firstValue().type() != vtkFoamEntryValue::LABELLIST)
2627
    //ascii data
2628
    else
2629
      {
4496
      {
2630
      tempStringStruct = this->GetLine(input);
4497
      vtkErrorMacro(<<"pointLabels not of type labelList: type = "
2631
      temp = tempStringStruct->value;
4498
        << pointLabelsEntry.firstValue().type());
2632
      delete tempStringStruct;//THROW OUT (
4499
      return false;
4500
      }
2633
4501
2634
      //GET EACH ELEMENT & ADD TO VECTOR
4502
    const vtkstd::vector<int>& labels = pointLabelsEntry.labelList();
2635
      for(int j = 0; j < numElement; j++)
2636
        {
2637
        tempStringStruct = this->GetLine(input);
2638
        temp = tempStringStruct->value;
2639
        delete tempStringStruct;
2640
4503
2641
        tokenizer.clear();
4504
    // allocate new grid: we do not use resize() beforehand since it
2642
        tokenizer << temp;
4505
    // could lead to undefined pointer if we return by error
2643
        tokenizer >> tempElement;
4506
    pointZoneMesh->value.push_back(vtkUnstructuredGrid::New());
2644
        pointCell = vtkVertex::New();
4507
    vtkUnstructuredGrid& pzm = *pointZoneMesh->value.back();
2645
        pointCell->GetPointIds()->SetId(0,tempElement);
2646
        pointZoneMesh->InsertNextCell(pointCell->GetCellType(),
2647
                                      pointCell->GetPointIds());
2648
        pointCell->Delete();
2649
        }
2650
      }
2651
    }
2652
4508
2653
  //there is no entry
4509
    // set pointZone size
2654
  else
4510
    size_t nPoints = labels.size();
2655
    {
4511
    pzm.Allocate(nPoints);
2656
    input->close();
4512
2657
    delete input;
4513
    // insert points
2658
    return NULL;
4514
    for(size_t j = 0; j < nPoints; j++)
4515
      {
4516
      vtkIdType pointLabel = labels[j];
4517
      pzm.InsertNextCell(VTK_VERTEX, 1, &pointLabel);
4518
      }
4519
    pzm.SetPoints(points);
2659
    }
4520
    }
2660
  //set point zone points
4521
2661
  pointZoneMesh->SetPoints(Points);
4522
  delete pointZoneDictPtr;
2662
  input->close();
4523
2663
  delete input;
2664
  vtkDebugMacro(<<"Point zone mesh created");
4524
  vtkDebugMacro(<<"Point zone mesh created");
2665
  return pointZoneMesh;
4525
  return true;
2666
}
4526
}
2667
4527
2668
// ****************************************************************************
4528
// ****************************************************************************
Lines 2672-2860 Link Here
2672
//  returns a requested face zone mesh
4532
//  returns a requested face zone mesh
2673
//
4533
//
2674
// ****************************************************************************
4534
// ****************************************************************************
2675
vtkUnstructuredGrid * vtkOpenFOAMReader::GetFaceZoneMesh(int timeState,
4535
bool vtkOpenFOAMReader::GetFaceZoneMesh(
2676
                                                         int faceZoneIndex)
4536
  unstructuredGridVector* faceZoneMesh, intVectorVector* facesPoints,
4537
  vtkPoints* points, int timeState)
2677
{
4538
{
2678
  vtkUnstructuredGrid * faceZoneMesh = vtkUnstructuredGrid::New();
4539
  vtkDebugMacro(<<"Create face zone mesh");
2679
  vtkstd::string faceZonesPath = this->PathPrefix->value +
2680
                                 this->PolyMeshFacesDir->value[timeState] +
2681
                                 "/polyMesh/faceZones";
2682
  vtkDebugMacro(<<"Create face zone mesh: "<<faceZonesPath.c_str());
2683
2684
  vtkstd::string temp;
2685
  stdString* tempStringStruct;
2686
  bool binaryWriteFormat;
2687
  ifstream * input = new ifstream(faceZonesPath.c_str(), ios::in VTK_IOS_NOCREATE);
2688
  //make sure file exists
2689
  if(input->fail())
2690
    {
2691
    input->close();
2692
    delete input;
2693
    return faceZoneMesh;
2694
    }
2695
2696
  //determine if file is binary or ascii
2697
  while(temp.find("format") == vtkstd::string::npos)
2698
    {
2699
    tempStringStruct = this->GetLine(input);
2700
    temp = tempStringStruct->value;
2701
    delete tempStringStruct;
2702
    }
2703
  input->close();
2704
2705
  //reopen file in correct format
2706
  if(temp.find("binary") != vtkstd::string::npos)
2707
    {
2708
#ifdef _WIN32
2709
    input->open(faceZonesPath.c_str(), ios::binary | ios::in VTK_IOS_NOCREATE);
2710
#else
2711
    input->open(faceZonesPath.c_str(), ios::in);
2712
#endif
2713
    binaryWriteFormat = true;
2714
    }
2715
  else
2716
    {
2717
    input->open(faceZonesPath.c_str(),ios::in);
2718
    binaryWriteFormat = false;
2719
    }
2720
4540
2721
  vtkstd::string token;
4541
  vtkFoamDict* faceZoneDictPtr
2722
  vtksys_ios::stringstream tokenizer;
4542
    = this->GatherBlocks("faceZones", timeState, false);
2723
  vtkstd::vector< int > faceZone;
2724
  int tempElement;
2725
  vtkstd::vector< vtkstd::vector < int > > tempElementZones;
2726
  int numElement;
2727
4543
2728
  //find desired mesh entry
4544
  if(faceZoneDictPtr == NULL)
2729
  while(temp.find(this->FaceZoneNames->value[faceZoneIndex]) == 
2730
        vtkstd::string::npos)
2731
    {
4545
    {
2732
    tempStringStruct = this->GetLine(input);
4546
    // not an error
2733
    temp = tempStringStruct->value;
4547
    return true;
2734
    delete tempStringStruct;
2735
    }
4548
    }
2736
4549
2737
  tempStringStruct = this->GetLine(input);
4550
  vtkFoamDict& faceZoneDict = *faceZoneDictPtr;
2738
  temp = tempStringStruct->value;
4551
  size_t nFaceZones = faceZoneDict.size();
2739
  delete tempStringStruct;//throw out {
2740
4552
2741
  tempStringStruct = this->GetLine(input);
4553
  for(size_t i = 0; i < nFaceZones; i++)
2742
  temp = tempStringStruct->value;
2743
  delete tempStringStruct;//type
2744
2745
  tempStringStruct = this->GetLine(input);
2746
  temp = tempStringStruct->value;
2747
  delete tempStringStruct;//label
2748
2749
  tempStringStruct = this->GetLine(input);
2750
  temp = tempStringStruct->value;
2751
  delete tempStringStruct;//number of values or flipmap
2752
2753
  if(temp.find("flipMap") == vtkstd::string::npos)
2754
    {
4554
    {
2755
    //number of elements
4555
    // look up face labels
2756
    tokenizer << temp;
4556
    vtkFoamDict& dict = faceZoneDict.entry(i).dictionary();
2757
    tokenizer >> numElement;
4557
    vtkFoamEntry& faceLabelsEntry = dict.lookup("faceLabels");
2758
    if(numElement == 0)
4558
    if(!faceLabelsEntry.found())
2759
      {
4559
      {
2760
      input->close();
4560
      delete faceZoneDictPtr;
2761
      delete input;
4561
      vtkErrorMacro(<<"faceLabels not found in faceZones");
2762
      return NULL;
4562
      return false;
2763
      }
4563
      }
2764
4564
    // skip if the list is empty
2765
    //binary
4565
    if(faceLabelsEntry.firstValue().type() == vtkFoamEntryValue::EMPTYLIST)
2766
    if(binaryWriteFormat)
2767
      {
4566
      {
2768
      input->get(); //parenthesis
4567
      continue;
2769
      for(int j = 0; j < numElement; j++)
2770
        {
2771
        input->read((char *) &tempElement, sizeof(int));
2772
        faceZone.push_back(tempElement);
2773
        }
2774
      }
4568
      }
2775
4569
    if(faceLabelsEntry.firstValue().type() != vtkFoamEntryValue::LABELLIST)
2776
    //ascii
2777
    else
2778
      {
4570
      {
2779
      //THROW OUT (
4571
      delete faceZoneDictPtr;
2780
      tempStringStruct = this->GetLine(input);
4572
      vtkErrorMacro(<<"faceLabels not of type labelList");
2781
      temp = tempStringStruct->value;
4573
      return false;
2782
      delete tempStringStruct;
2783
2784
      //get each element & add to vector
2785
      for(int j = 0; j < numElement; j++)
2786
        {
2787
        tempStringStruct = this->GetLine(input);
2788
        temp = tempStringStruct->value;
2789
        delete tempStringStruct;
2790
2791
        tokenizer.clear();
2792
        tokenizer << temp;
2793
        tokenizer >> tempElement;
2794
        faceZone.push_back(tempElement);
2795
        }
2796
      }
4574
      }
2797
    }
2798
4575
2799
  //Create the mesh
4576
    const vtkstd::vector<int>& labels = faceLabelsEntry.labelList();
2800
  int k;
2801
  vtkTriangle * triangle;
2802
  vtkQuad * quad;
2803
  vtkPolygon * polygon;
2804
4577
2805
  //LOOP THROUGH EACH FACE
4578
    // allocate new grid: we do not use resize() beforehand since it
2806
  for(int j = 0; j < (int)faceZone.size(); j++)
4579
    // could lead to undefined pointer if we return by error
2807
    {
4580
    faceZoneMesh->value.push_back(vtkUnstructuredGrid::New());
4581
    vtkUnstructuredGrid& fzm = *faceZoneMesh->value.back();
4582
4583
    // set faceZone size
4584
    size_t nFaces = labels.size();
4585
    fzm.Allocate(nFaces);
2808
4586
2809
    //Triangular Face
4587
    // aloocate array for converting int vector to vtkIdType vector:
2810
    if(this->FacePoints->value[faceZone[j]].size() == 3)
4588
    // workaround for 64bit machines
4589
    int maxNFacePoints = 0;
4590
    for(size_t j = 0; j < nFaces; j++)
2811
      {
4591
      {
2812
      triangle = vtkTriangle::New();
4592
      const int nFacePoints = facesPoints->value[labels[j]].size();
2813
      for(k = 0; k < 3; k++)
4593
      if(nFacePoints > maxNFacePoints)
2814
        {
4594
        {
2815
        triangle->GetPointIds()->SetId(k, this->FacePoints->value[
4595
        maxNFacePoints = nFacePoints;
2816
        faceZone[j]][k]);
2817
        }
4596
        }
2818
      faceZoneMesh->InsertNextCell(triangle->GetCellType(),
2819
        triangle->GetPointIds());
2820
      triangle->Delete();
2821
      }
4597
      }
4598
    vtkIdType* facePointsVtkId = new vtkIdType[maxNFacePoints];
2822
4599
2823
    //Quadraic Face
4600
    // insert faces
2824
    else if(this->FacePoints->value[faceZone[j]].size() == 4)
4601
    for(size_t j = 0; j < nFaces; j++)
2825
      {
4602
      {
2826
      quad = vtkQuad::New();
4603
      vtkstd::vector<int>& facePoints = facesPoints->value[labels[j]];
2827
      for(k = 0; k < 4; k++)
4604
      size_t nFacePoints = facePoints.size();
4605
4606
      for(size_t k = 0; k < nFacePoints; k++)
2828
        {
4607
        {
2829
        quad->GetPointIds()->SetId(k,
4608
        facePointsVtkId[k] = facePoints[k];
2830
          this->FacePoints->value[faceZone[j]][k]);
2831
        }
4609
        }
2832
      faceZoneMesh->InsertNextCell(quad->GetCellType(),
2833
        quad->GetPointIds());
2834
      quad->Delete();
2835
      }
2836
4610
2837
    //Polygonal Face
4611
      //triangle
2838
    else
4612
      if(nFacePoints == 3)
2839
      {
4613
        {
2840
      polygon = vtkPolygon::New();
4614
        fzm.InsertNextCell(VTK_TRIANGLE, 3, facePointsVtkId);
2841
      for(k = 0; k < (int)this->FacePoints->value[faceZone[j]].size(); k++)
4615
        }
4616
      // quad
4617
      else if(nFacePoints == 4)
4618
        {
4619
        fzm.InsertNextCell(VTK_QUAD, 4, facePointsVtkId);
4620
        }
4621
      //polygon
4622
      else
2842
        {
4623
        {
2843
        polygon->GetPointIds()->InsertId(k, this->FacePoints->value[
4624
        fzm.InsertNextCell(VTK_POLYGON, nFacePoints,
2844
          faceZone[j]][k]);
4625
          facePointsVtkId);
2845
        }
4626
        }
2846
      faceZoneMesh->InsertNextCell(polygon->GetCellType(),
2847
        polygon->GetPointIds());
2848
      polygon->Delete();
2849
      }
4627
      }
4628
4629
    delete [] facePointsVtkId;
4630
    fzm.SetPoints(points);
2850
    }
4631
    }
2851
4632
2852
  //set the face zone points
4633
  delete faceZoneDictPtr;
2853
  faceZoneMesh->SetPoints(this->Points);
4634
2854
  input->close();
2855
  delete input;
2856
  vtkDebugMacro(<<"Face zone mesh created");
4635
  vtkDebugMacro(<<"Face zone mesh created");
2857
  return faceZoneMesh;
4636
  return true;
2858
}
4637
}
2859
4638
2860
// ****************************************************************************
4639
// ****************************************************************************
Lines 2864-3491 Link Here
2864
//  returns a requested cell zone mesh
4643
//  returns a requested cell zone mesh
2865
//
4644
//
2866
// ****************************************************************************
4645
// ****************************************************************************
2867
vtkUnstructuredGrid * vtkOpenFOAMReader::GetCellZoneMesh(int timeState,
4646
bool vtkOpenFOAMReader::GetCellZoneMesh(
2868
                                                         int cellZoneIndex)
4647
  unstructuredGridVector* cellZoneMesh, faceVectorVector* facesOfCell,
4648
  intVectorVector* facesPoints, vtkPoints* points, int timeState)
2869
{
4649
{
2870
  vtkUnstructuredGrid * cellZoneMesh = vtkUnstructuredGrid::New();
4650
  vtkDebugMacro(<<"Create cell zone mesh");
2871
  vtkstd::string cellZonesPath = this->PathPrefix->value +
2872
                                 this->PolyMeshFacesDir->value[timeState] +
2873
                                 "/polyMesh/cellZones";
2874
  vtkDebugMacro(<<"Create cell zone mesh: "<<cellZonesPath.c_str());
2875
  vtkstd::string temp;
2876
  stdString* tempStringStruct;
2877
  bool binaryWriteFormat;
2878
  ifstream * input = new ifstream(cellZonesPath.c_str(), ios::in VTK_IOS_NOCREATE);
2879
  //make sure file exists
2880
  if(input->fail())
2881
    {
2882
    input->close();
2883
    delete input;
2884
    return cellZoneMesh;
2885
    }
2886
2887
  //determine if file is binary or ascii
2888
  while(temp.find("format") == vtkstd::string::npos)
2889
    {
2890
    tempStringStruct = this->GetLine(input);
2891
    temp = tempStringStruct->value;
2892
    delete tempStringStruct;
2893
    }
2894
  input->close();
2895
4651
2896
  //reopen file in correct format
4652
  vtkFoamDict* cellZoneDictPtr
2897
  if(temp.find("binary") != vtkstd::string::npos)
4653
    = this->GatherBlocks("cellZones", timeState, false);
4654
4655
  if(cellZoneDictPtr == NULL)
2898
    {
4656
    {
2899
#ifdef _WIN32
4657
    // not an error
2900
    input->open(cellZonesPath.c_str(), ios::binary | ios::in VTK_IOS_NOCREATE);
4658
    return true;
2901
#else
2902
    input->open(cellZonesPath.c_str(), ios::in VTK_IOS_NOCREATE);
2903
#endif
2904
    binaryWriteFormat = true;
2905
    }
4659
    }
2906
  else
4660
4661
  vtkFoamDict& cellZoneDict = *cellZoneDictPtr;
4662
  size_t nCellZones = cellZoneDict.size();
4663
4664
  for(size_t i = 0; i < nCellZones; i++)
2907
    {
4665
    {
2908
    input->open(cellZonesPath.c_str(),ios::in);
4666
    // look up cell labels
2909
    binaryWriteFormat = false;
4667
    vtkFoamDict& dict = cellZoneDict.entry(i).dictionary();
4668
    vtkFoamEntry& cellLabelsEntry = dict.lookup("cellLabels");
4669
    if(!cellLabelsEntry.found())
4670
      {
4671
      delete cellZoneDictPtr;
4672
      vtkErrorMacro(<<"cellLabels not found in cellZones");
4673
      return false;
4674
      }
4675
    // skip if the list is empty
4676
    if(cellLabelsEntry.firstValue().type() == vtkFoamEntryValue::EMPTYLIST)
4677
      {
4678
      continue;
4679
      }
4680
    if(cellLabelsEntry.firstValue().type() != vtkFoamEntryValue::LABELLIST)
4681
      {
4682
      delete cellZoneDictPtr;
4683
      vtkErrorMacro(<<"cellLabels not of type labelList");
4684
      return false;
4685
      }
4686
4687
    const vtkstd::vector<int>& labels = cellLabelsEntry.labelList();
4688
4689
    // allocate new grid: we do not use resize() beforehand since it
4690
    // could lead to undefined pointer if we return by error
4691
    cellZoneMesh->value.push_back(vtkUnstructuredGrid::New());
4692
    vtkUnstructuredGrid* czm = cellZoneMesh->value.back();
4693
4694
    // set cellZone size
4695
    size_t nCells = labels.size();
4696
    czm->Allocate(nCells);
4697
4698
    // insert cells
4699
    for(size_t j = 0; j < nCells; j++)
4700
      {
4701
      this->InsertCellToGrid(czm, labels[j], facesOfCell, facesPoints);
4702
      }
4703
4704
    //set cell zone points
4705
    cellZoneMesh->value[i]->SetPoints(points);
2910
    }
4706
    }
2911
4707
2912
  vtkstd::string token;
4708
  delete cellZoneDictPtr;
2913
  vtksys_ios::stringstream tokenizer;
4709
  vtkDebugMacro(<<"Cell zone mesh created");
2914
  vtkstd::vector< int > cellZone;
4710
  return true;
2915
  int tempElement;
4711
}
2916
  vtkstd::vector< vtkstd::vector < int > > tempElementZones;
4712
2917
  int numElement;
4713
vtkPolyData* vtkOpenFOAMReader::MakeLagrangianMesh(int timeState)
4714
{
4715
  vtkStdString positionsPath = *this->PathPrefix
4716
    + this->TimeNames->GetValue(timeState) +  "/lagrangian/positions";
2918
4717
2919
  //find desired mesh entry
4718
  vtkFoamIOobject io;
2920
  while(temp.find(this->CellZoneNames->value[cellZoneIndex]) == 
4719
  if(!(io.open(positionsPath) || io.open(positionsPath + ".gz")))
2921
        vtkstd::string::npos)
4720
    {
4721
    vtkErrorMacro(<<"Error opening " << io.fileName().c_str() << ": "
4722
      << io.error().str().c_str());
4723
    return NULL;
4724
    }
4725
  vtkFoamDict dict;
4726
  if(!dict.read(io))
4727
    {
4728
    vtkErrorMacro(<<"Error reading line " << io.lineNumber()
4729
      << " of " << io.fileName().c_str() << ": " << io.error().str().c_str());
4730
    return NULL;
4731
    }
4732
  if(dict.type() != vtkFoamDict::VECTORLIST)
2922
    {
4733
    {
2923
    tempStringStruct = this->GetLine(input);
4734
    vtkErrorMacro(<<"The file type of " << io.fileName().c_str()
2924
    temp = tempStringStruct->value;
4735
      << " is not a vectorList");
2925
    delete tempStringStruct;
4736
    return NULL;
2926
    }
4737
    }
2927
  tempStringStruct = this->GetLine(input);
2928
  temp = tempStringStruct->value;
2929
  delete tempStringStruct;//throw out {
2930
4738
2931
  tempStringStruct = this->GetLine(input);
4739
  vtkDoubleArray& vl = dict.vectorList();
2932
  temp = tempStringStruct->value;
4740
  const vtkIdType nParticles = vl.GetNumberOfTuples();
2933
  delete tempStringStruct;//type
4741
  //instantiate the points class
4742
  vtkPoints* points = vtkPoints::New();
4743
  points->SetNumberOfPoints(nParticles);
4744
  vtkPolyData* lagrangianMesh = vtkPolyData::New();
4745
  lagrangianMesh->Allocate(nParticles);
2934
4746
2935
  tempStringStruct = this->GetLine(input);
4747
  for(vtkIdType i = 0, index = 0; i < nParticles; i++, index += 3)
2936
  temp = tempStringStruct->value;
4748
    {
2937
  delete tempStringStruct;
4749
    points->SetPoint(i, vl.GetPointer(index));
4750
    lagrangianMesh->InsertNextCell(VTK_VERTEX, 1, &i);
4751
    }
2938
4752
2939
  tempStringStruct = this->GetLine(input);
4753
  lagrangianMesh->SetPoints(points);
2940
  temp = tempStringStruct->value;
4754
  points->Delete();
2941
  delete tempStringStruct;
4755
  return lagrangianMesh;
4756
}
2942
4757
2943
  //number of elements
4758
bool vtkOpenFOAMReader::GetLagrangianVariableAtTimestep(
2944
  tokenizer << temp;
4759
  vtkPolyData* lagrangianMesh, const char* varNameIn, int timeState)
2945
  tokenizer >> numElement;
4760
{
4761
  vtkStdString varPath = *this->PathPrefix
4762
    + this->TimeNames->GetValue(timeState) + "/lagrangian/"
4763
    + vtkStdString(varNameIn);
2946
4764
2947
  //binary
4765
  // open the file
2948
  if(binaryWriteFormat)
4766
  vtkFoamIOobject io;
4767
  if(!io.open(varPath))
2949
    {
4768
    {
2950
    input->get(); //parenthesis
4769
    vtkErrorMacro(<<"Error opening " << io.fileName().c_str() << ": "
2951
    for(int j = 0; j < numElement; j++)
4770
      << io.error().str().c_str());
2952
      {
4771
    return false;
2953
      input->read((char *) &tempElement, sizeof(int));
2954
      cellZone.push_back(tempElement);
2955
      }
2956
    }
4772
    }
2957
4773
2958
  //ascii
4774
  // if the variable is disabled on selection panel then skip it
2959
  else
4775
  vtkStdString selectionName
4776
    = vtkStdString("lagrangian/") + io.objectName();
4777
  if(this->PointDataArraySelection->ArrayExists(selectionName.c_str())
4778
    && !this->PointDataArraySelection->ArrayIsEnabled(selectionName.c_str()))
2960
    {
4779
    {
2961
    tempStringStruct = this->GetLine(input);
4780
    return true;
2962
    temp = tempStringStruct->value;
2963
    delete tempStringStruct;//throw out (
2964
2965
    //get each element & add to vector
2966
    for(int j = 0; j < numElement; j++)
2967
      {
2968
      tempStringStruct = this->GetLine(input);
2969
      temp = tempStringStruct->value;
2970
      delete tempStringStruct;
2971
2972
      tokenizer.clear();
2973
      tokenizer << temp;
2974
      tokenizer >> tempElement;
2975
      cellZone.push_back(tempElement);
2976
      }
2977
    }
4781
    }
2978
4782
2979
  //Create the mesh
4783
  // read the field file into dictionary
2980
  bool foundDup = false;
4784
  vtkFoamDict dict;
2981
  vtkstd::vector< int > cellPoints;
4785
  if(!dict.read(io))
2982
  vtkstd::vector< int > tempFaces[2];
4786
    {
2983
  vtkstd::vector< int > firstFace;
4787
    vtkErrorMacro(<<"Error reading line " << io.lineNumber()
2984
  int pivotPoint = 0;
4788
      << " of " << io.fileName().c_str() << ": " << io.error().str().c_str());
2985
  int i, j, k, l, pCount;
4789
    return false;
2986
  int faceCount = 0;
4790
    }
2987
4791
2988
  //Create Mesh
4792
  // set lagrangian values
2989
  for(i = 0; i < (int)cellZone.size(); i++)  //each cell
4793
  if(dict.type() != vtkFoamDict::SCALARLIST
4794
    && dict.type() != vtkFoamDict::VECTORLIST)
2990
    {
4795
    {
2991
    //calculate total points for all faces of a cell
4796
    vtkErrorMacro(<<"Unsupported lagrangian field type");
2992
    //used to determine cell type
4797
    return false;
2993
    int totalPointCount = 0;
4798
    }
2994
    for(j = 0; j < (int)this->FacesOfCell->value[
2995
      cellZone[i]].size(); j++)  //each face
2996
      {
2997
      totalPointCount += (int)this->FacePoints->value[this->FacesOfCell->value[
2998
        cellZone[i]][j].faceIndex].size();
2999
      }
3000
4799
3001
      // using cell type - order points, create cell, add to mesh
4800
  vtkDoubleArray* lData = (vtkDoubleArray *)dict.ptr();
3002
4801
3003
    //OFhex | vtkHexahedron
4802
  // GetNumberOfTuples() works for both scalar and vector
3004
    if (totalPointCount == 24)
4803
  const int nParticles = lData->GetNumberOfTuples();
3005
      {
4804
  if(nParticles != lagrangianMesh->GetNumberOfCells())
3006
      faceCount = 0;
4805
    {
4806
    vtkErrorMacro(<<"Sizes of lagrangian mesh and field don't match");
4807
    return false;
4808
    }
3007
4809
3008
      //get first face
4810
  lData->SetName(selectionName.c_str());
3009
      for(j = 0; j < (int)this->FacePoints->value[this->FacesOfCell->value[
4811
  lagrangianMesh->GetPointData()->AddArray(lData);
3010
        cellZone[i]][0].faceIndex].size(); j++)
4812
  lData->Delete();
3011
        {
4813
3012
        firstFace.push_back(this->FacePoints->value[this->FacesOfCell->value[
4814
  return true;
3013
          cellZone[i]][0].faceIndex][j]);
4815
}
3014
        }
3015
4816
3016
      //-if it is a neighbor face flip it
4817
// return 0 if there's any error, 1 if success
3017
      if(FacesOfCell->value[i][0].neighborFace)
4818
int vtkOpenFOAMReader::CreateDataSet(vtkMultiBlockDataSet *output,
4819
  int timeState)
4820
{
4821
  int oldTimeState = this->OldTimeStep;
4822
  vtkPolyData* lagrangianMesh = NULL;
4823
  bool updateVariables = true;
4824
4825
  // determine if we need to reconstruct meshes
4826
  if(this->CacheMesh && oldTimeState >= 0
4827
    && this->PolyMeshFacesDir->value[timeState]
4828
       == this->PolyMeshFacesDir->value[oldTimeState]
4829
    && this->FaceOwner != NULL
4830
    && this->PatchSelectionStatus == this->PatchSelectionOldStatus)
4831
    {
4832
    if((timeState == oldTimeState) 
4833
       && (this->CellSelectionStatus == this->CellSelectionOldStatus)
4834
       && (this->PointSelectionStatus == this->PointSelectionOldStatus))
4835
      {
4836
      updateVariables = false;
4837
      }
4838
    else
4839
      {
4840
      // clean up arrays of the previous timestep
4841
      // Check if Internal Mesh Exists first...
4842
      if(this->InternalMesh != NULL)
3018
        {
4843
        {
3019
        int tempPop;
4844
        vtkCellData* internalCellData = this->InternalMesh->GetCellData();
3020
        for(k = 0; k < (int)firstFace.size() - 1; k++)
4845
        while(internalCellData->GetArrayName(0))
3021
          {
4846
          {
3022
          tempPop = firstFace[firstFace.size()-1];
4847
          internalCellData->RemoveArray(internalCellData->GetArrayName(0));
3023
          firstFace.pop_back();
3024
          firstFace.insert(firstFace.begin()+1+k, tempPop);
3025
          }
4848
          }
3026
        }
4849
        }
3027
4850
      // Check if Boundary Mesh Exists first...
3028
      //add first face to cell points
4851
      if(this->BoundaryMesh != NULL)
3029
      for(j =0; j < (int)firstFace.size(); j++)
3030
        {
3031
        cellPoints.push_back(firstFace[j]);
3032
        }
3033
3034
      for(int pointCount = 0;pointCount < (int)firstFace.size();pointCount++)
3035
        {
4852
        {
3036
        //find the 2 other faces containing each point - start with face 1
4853
        for(size_t i = 0; i < this->BoundaryMesh->value.size(); i++)
3037
        for(j = 1; j < (int)this->FacesOfCell->value[
3038
          cellZone[i]].size(); j++)  //each face
3039
          {
4854
          {
3040
          for(k = 0; k < (int)this->FacePoints->value[this->FacesOfCell->
4855
          vtkCellData* boundaryCellData
3041
              value[cellZone[i]][j].faceIndex].size(); k++)
4856
            = this->BoundaryMesh->value[i]->GetCellData();
4857
          while(boundaryCellData->GetArrayName(0))
3042
            {
4858
            {
3043
            if(firstFace[pointCount] == this->FacePoints->
4859
            boundaryCellData->RemoveArray(boundaryCellData->GetArrayName(0));
3044
               value[this->FacesOfCell->value[cellZone[i]][j].faceIndex][k])
3045
              {
3046
              //another face with the point
3047
              for(l = 0; l < (int)this->FacePoints->value[this->FacesOfCell->
3048
                                  value[cellZone[i]][j].faceIndex].size(); l++)
3049
                {
3050
                tempFaces[faceCount].push_back(this->FacePoints->value[
3051
                  this->FacesOfCell->value[cellZone[i]][j].faceIndex]
3052
                  [l]);
3053
                }
3054
              faceCount++;
3055
              }
3056
            }
4860
            }
3057
          }
4861
          }
3058
4862
        }
3059
        //locate the pivot point contained in faces 0 & 1
4863
      // if only point coordinates change refresh point vector
3060
        for(j = 0; j < (int)tempFaces[0].size(); j++)
4864
      if(this->PolyMeshPointsDir->value[timeState]
4865
        != this->PolyMeshPointsDir->value[oldTimeState])
4866
        {
4867
        //get the points
4868
        vtkPoints* points = this->GetPoints(timeState);
4869
        if(points == NULL)
3061
          {
4870
          {
3062
          for(k = 0; k < (int)tempFaces[1].size(); k++)
4871
          return 0;
3063
            {
3064
            if(tempFaces[0][j] == tempFaces[1][k] && tempFaces[0][j] !=
3065
              firstFace[pointCount])
3066
              {
3067
              pivotPoint = tempFaces[0][j];
3068
              break;
3069
              }
3070
            }
3071
          }
4872
          }
3072
        cellPoints.push_back(pivotPoint);
3073
        tempFaces[0].clear();
3074
        tempFaces[1].clear();
3075
        faceCount=0;
3076
        }
3077
4873
3078
        //create the hex cell and insert it into the mesh
4874
        // refresh the points in each mesh
3079
        vtkHexahedron * hexahedron = vtkHexahedron::New();
4875
        // Check if Internal Mesh exists first....
3080
        for(pCount = 0; pCount < (int)cellPoints.size(); pCount++)
4876
        if(this->InternalMesh != NULL)
3081
          {
4877
          {
3082
          hexahedron->GetPointIds()->SetId(pCount, cellPoints[pCount]);
4878
          this->InternalMesh->SetPoints(points);
3083
          }
4879
          }
3084
        cellZoneMesh->InsertNextCell(hexahedron->GetCellType(),
4880
        // Check if Boundary Mesh exists first....
3085
                                     hexahedron->GetPointIds());
4881
        if(this->BoundaryMesh != NULL)
3086
        hexahedron->Delete();
3087
        cellPoints.clear();
3088
        firstFace.clear();
3089
        }
3090
3091
    //OFprism | vtkWedge
3092
    else if (totalPointCount == 18)
3093
      {
3094
      faceCount = 0;
3095
      int index = 0;
3096
3097
      //find first triangular face
3098
      for(j = 0; j < (int)this->FacesOfCell->value[
3099
        cellZone[i]].size(); j++)  //each face
3100
        {
3101
        if((int)this->FacePoints->value[this->FacesOfCell->value[
3102
          cellZone[i]][j].faceIndex].size() == 3)
3103
          {
4882
          {
3104
          for(k = 0; k < (int)this->FacePoints->value[this->FacesOfCell->value[
4883
          for(size_t i = 0; i < this->BoundaryMesh->value.size(); i++)
3105
            cellZone[i]][j].faceIndex].size(); k++)
3106
            {
4884
            {
3107
            firstFace.push_back(this->FacePoints->value[this->FacesOfCell->
4885
            this->BoundaryMesh->value[i]->SetPoints(points);
3108
                                  value[cellZone[i]][j].faceIndex][k]);
3109
            index = j;
3110
            }
4886
            }
3111
          break;
3112
          }
4887
          }
3113
        }
4888
        if(this->PointZoneMesh != NULL)
3114
3115
      //-if it is a neighbor face flip it
3116
      if(this->FacesOfCell->value[i][0].neighborFace)
3117
        {
3118
        int tempPop;
3119
        for(k = 0; k < (int)firstFace.size() - 1; k++)
3120
          {
4889
          {
3121
          tempPop = firstFace[firstFace.size()-1];
4890
          for(size_t i = 0; i < this->PointZoneMesh->value.size(); i++)
3122
          firstFace.pop_back();
4891
            {
3123
          firstFace.insert(firstFace.begin()+1+k, tempPop);
4892
            this->PointZoneMesh->value[i]->SetPoints(points);
4893
            }
3124
          }
4894
          }
3125
        }
4895
        if(this->FaceZoneMesh != NULL)
3126
3127
      //add first face to cell points
3128
      for(j =0; j < (int)firstFace.size(); j++)
3129
        {
3130
        cellPoints.push_back(firstFace[j]);
3131
        }
3132
3133
      for(int pointCount = 0;pointCount < (int)firstFace.size();pointCount++)
3134
        {
3135
        //find the 2 other faces containing each point
3136
        for(j = 0; j < (int)this->FacesOfCell->value[
3137
          cellZone[i]].size(); j++)  //each face
3138
          {
4896
          {
3139
          for(k = 0; k < (int)this->FacePoints->value[this->FacesOfCell->value[
4897
          for(size_t i = 0; i < this->FaceZoneMesh->value.size(); i++)
3140
            cellZone[i]][j].faceIndex].size(); k++) //each point
3141
            {
4898
            {
3142
            if(firstFace[pointCount] == this->FacePoints->
4899
            this->FaceZoneMesh->value[i]->SetPoints(points);
3143
               value[this->FacesOfCell->value[cellZone[i]][j].faceIndex][k] &&
3144
               j != index)
3145
              {
3146
              //another face with point
3147
              for(l = 0; l < (int)this->FacePoints->value[this->
3148
                  FacesOfCell->value[cellZone[i]][j].faceIndex].size(); l++)
3149
                {
3150
                tempFaces[faceCount].push_back(this->FacePoints->value[
3151
                  this->FacesOfCell->value[cellZone[i]][j].faceIndex]
3152
                  [l]);
3153
                }
3154
              faceCount++;
3155
              }
3156
            }
4900
            }
3157
          }
4901
          }
3158
4902
        if(this->CellZoneMesh != NULL)
3159
        //locate the pivot point contained in faces 0 & 1
3160
        for(j = 0; j < (int)tempFaces[0].size(); j++)
3161
          {
4903
          {
3162
          for(k = 0; k < (int)tempFaces[1].size(); k++)
4904
          for(size_t i = 0; i < this->CellZoneMesh->value.size(); i++)
3163
            {
4905
            {
3164
            if(tempFaces[0][j] == tempFaces[1][k] && tempFaces[0][j] !=
4906
            this->CellZoneMesh->value[i]->SetPoints(points);
3165
              firstFace[pointCount])
3166
              {
3167
              pivotPoint = tempFaces[0][j];
3168
              break;
3169
              }
3170
            }
4907
            }
3171
          }
4908
          }
3172
        cellPoints.push_back(pivotPoint);
4909
        points->Delete();
3173
        tempFaces[0].clear();
3174
        tempFaces[1].clear();
3175
        faceCount=0;
3176
        }
4910
        }
4911
      }
4912
    }
4913
  else
4914
    {
4915
    this->ClearMeshes();
3177
4916
3178
      //create the wedge cell and insert it into the mesh
4917
    vtkStdString meshDir = *this->PathPrefix
3179
      vtkWedge * wedge = vtkWedge::New();
4918
      + this->PolyMeshFacesDir->value[timeState] + "/polyMesh/";
3180
      for(pCount = 0; pCount < (int)cellPoints.size(); pCount++)
4919
3181
        {
4920
    //create paths to polyMesh files
3182
        wedge->GetPointIds()->SetId(pCount, cellPoints[pCount]);
4921
    vtkStdString facePath = meshDir + "faces";
3183
        }
4922
    vtkStdString ownerPath = meshDir + "owner";
3184
      cellZoneMesh->InsertNextCell(wedge->GetCellType(),
4923
    vtkStdString neighborPath = meshDir + "neighbour";
3185
                                   wedge->GetPointIds());
4924
3186
      cellPoints.clear();
4925
    //create the faces vector
3187
      wedge->Delete();
4926
    intVectorVector* facePoints = this->ReadFacesFile(facePath.c_str());
3188
      firstFace.clear();
4927
    if(facePoints == NULL)
4928
      {
4929
      return 0;
3189
      }
4930
      }
4931
    this->UpdateProgress(0.2);
3190
4932
3191
    //OFpyramid | vtkPyramid
4933
    //read owner/neighbor and create the faces owner/facesOfCell vector
3192
    else if (totalPointCount == 16)
4934
    faceVectorVector* facesOfCell = new faceVectorVector;
4935
    if(!this->ReadOwnerNeighborFiles(facesOfCell, ownerPath.c_str(),
4936
      neighborPath.c_str()))
3193
      {
4937
      {
3194
      foundDup = false;
4938
      delete facePoints;
4939
      delete facesOfCell;
4940
      return 0;
4941
      }
4942
    this->UpdateProgress(0.3);
3195
4943
3196
      //find quad
4944
    //get the points
3197
      for(j = 0; j < (int)this->FacesOfCell->value[
4945
    vtkPoints* points = this->GetPoints(timeState);
3198
        cellZone[i]].size(); j++)  //each face
4946
    if(points == NULL)
3199
        {
4947
      {
3200
        if((int)this->FacePoints->value[this->FacesOfCell->value[
4948
      delete facePoints;
3201
          cellZone[i]][j].faceIndex].size() == 4)
4949
      delete facesOfCell;
3202
          {
4950
      return 0;
3203
          for(k = 0; k < (int)this->FacePoints->value[this->FacesOfCell->value[
4951
      }
3204
            cellZone[i]][j].faceIndex].size(); k++)
4952
    this->UpdateProgress(0.4);
3205
            {
3206
            cellPoints.push_back(this->FacePoints->value[this->FacesOfCell->
3207
              value[cellZone[i]][j].faceIndex][k]);
3208
            }
3209
          break;
3210
          }
3211
        }
3212
4953
3213
      //compare first face points to second faces
4954
    // make internal mesh
3214
      for(j = 0; j < (int)cellPoints.size(); j++) //each point
4955
    // Create Internal Mesh only if required for display
4956
    if(this->GetPatchArrayStatus(GetPatchArrayName(0)))
4957
      {
4958
      this->InternalMesh = this->MakeInternalMesh(facesOfCell, facePoints,
4959
        points);
4960
      }
4961
    else
4962
      {
4963
      if(this->InternalMesh != NULL)
3215
        {
4964
        {
3216
        for(k = 0; k < (int)this->FacePoints->value[this->FacesOfCell->value[
4965
        this->InternalMesh->Delete();
3217
          cellZone[i]][1].faceIndex].size(); k++)
4966
        this->InternalMesh = NULL;
3218
          {
3219
          if(cellPoints[j] == this->FacePoints->value[this->FacesOfCell->value[
3220
            cellZone[i]][1].faceIndex][k])
3221
            {
3222
            foundDup = true;
3223
            }
3224
          }
3225
        if(!foundDup)
3226
          {
3227
          cellPoints.push_back(this->FacePoints->value[this->FacesOfCell->value[
3228
            cellZone[i]][j].faceIndex][k]);
3229
          break;
3230
          }
3231
        }
4967
        }
4968
      }
3232
4969
3233
      //create the pyramid cell and insert it into the mesh
4970
    // read polyMesh/bondary
3234
      vtkPyramid * pyramid = vtkPyramid::New();
4971
    this->BoundaryDict = this->GatherBlocks("boundary", timeState, true);
3235
      for(pCount = 0; pCount < (int)cellPoints.size(); pCount++)
4972
    if(this->BoundaryDict == NULL)
3236
        {
4973
      {
3237
        pyramid->GetPointIds()->SetId(pCount, cellPoints[pCount]);
4974
      delete facePoints;
3238
        }
4975
      delete facesOfCell;
3239
      cellZoneMesh->InsertNextCell(pyramid->GetCellType(),
4976
      points->Delete();
3240
                                   pyramid->GetPointIds());
4977
      vtkErrorMacro("Couldn't read polyMesh/boundary");
3241
      cellPoints.clear();
4978
      return 0;
3242
      pyramid->Delete();
3243
      }
4979
      }
3244
4980
3245
    //OFtet | vtkTetrahedron
4981
    // create boundary mesh
3246
    else if (totalPointCount == 12)
4982
    this->BoundaryMesh = this->GetBoundaryMesh(this->BoundaryDict, facePoints,
4983
      points);
4984
    if(this->BoundaryMesh == NULL)
3247
      {
4985
      {
3248
      foundDup = false;
4986
      delete facePoints;
4987
      delete facesOfCell;
4988
      points->Delete();
4989
      return 0;
4990
      }
3249
4991
3250
      //grab first face
4992
    // read and construct zones
3251
      for(j = 0; j < (int)this->FacePoints->value[this->FacesOfCell->value[
4993
    if(ReadZones)
3252
        cellZone[i]][0].faceIndex].size(); j++)
4994
      {
4995
      this->PointZoneMesh = new unstructuredGridVector;
4996
      if(!this->GetPointZoneMesh(this->PointZoneMesh, points, timeState))
4997
        {
4998
        for(size_t i = 0; i < this->PointZoneMesh->value.size(); i++)
4999
          {
5000
          this->PointZoneMesh->value[i]->Delete();
5001
          }
5002
        delete this->PointZoneMesh;
5003
        this->PointZoneMesh = NULL;
5004
        delete facePoints;
5005
        delete facesOfCell;
5006
        points->Delete();
5007
        return 0;
5008
        }
5009
      if(this->PointZoneMesh->value.size() == 0)
3253
        {
5010
        {
3254
        cellPoints.push_back(this->FacePoints->value[this->FacesOfCell->value[
5011
        delete this->PointZoneMesh;
3255
          cellZone[i]][0].faceIndex][j]);
5012
        this->PointZoneMesh = NULL;
3256
        }
5013
        }
3257
5014
3258
      //compare first face points to second faces
5015
      this->FaceZoneMesh = new unstructuredGridVector;
3259
      for(j = 0; j < (int)cellPoints.size(); j++) //each point
5016
      if(!this->GetFaceZoneMesh(this->FaceZoneMesh, facePoints, points,
5017
        timeState))
3260
        {
5018
        {
3261
        for(k = 0; k < (int)this->FacePoints->value[this->FacesOfCell->value[
5019
        for(size_t i = 0; i < this->FaceZoneMesh->value.size(); i++)
3262
          cellZone[i]][1].faceIndex].size(); k++)
3263
          {
5020
          {
3264
          if(cellPoints[j] == this->FacePoints->value[this->FacesOfCell->value[
5021
          this->FaceZoneMesh->value[i]->Delete();
3265
            cellZone[i]][1].faceIndex][k])
3266
            {
3267
            foundDup = true;
3268
            }
3269
          }
5022
          }
3270
        if(!foundDup)
5023
        delete this->FaceZoneMesh;
5024
        this->FaceZoneMesh = NULL;
5025
        delete facePoints;
5026
        delete facesOfCell;
5027
        points->Delete();
5028
        return 0;
5029
        }
5030
      if(this->FaceZoneMesh->value.size() == 0)
5031
        {
5032
        delete this->FaceZoneMesh;
5033
        this->FaceZoneMesh = NULL;
5034
        }
5035
          
5036
      this->CellZoneMesh = new unstructuredGridVector;
5037
      if(!this->GetCellZoneMesh(this->CellZoneMesh, facesOfCell, facePoints,
5038
         points, timeState))
5039
        {
5040
        for(size_t i = 0; i < this->CellZoneMesh->value.size(); i++)
3271
          {
5041
          {
3272
          cellPoints.push_back(this->FacePoints->value[this->FacesOfCell->value[
5042
          this->CellZoneMesh->value[i]->Delete();
3273
            cellZone[i]][j].faceIndex][k]);
3274
          break;
3275
          }
5043
          }
5044
        delete this->CellZoneMesh;
5045
        this->CellZoneMesh = NULL;
5046
        delete facePoints;
5047
        delete facesOfCell;
5048
        points->Delete();
5049
        return 0;
3276
        }
5050
        }
3277
5051
      if(this->CellZoneMesh->value.size() == 0)
3278
      //create the wedge cell and insert it into the mesh
3279
      vtkTetra * tetra = vtkTetra::New();
3280
      for(pCount = 0; pCount < (int)cellPoints.size(); pCount++)
3281
        {
5052
        {
3282
        tetra->GetPointIds()->SetId(pCount, cellPoints[pCount]);
5053
        delete this->CellZoneMesh;
5054
        this->CellZoneMesh = NULL;
3283
        }
5055
        }
3284
      cellZoneMesh->InsertNextCell(tetra->GetCellType(),
3285
                                   tetra->GetPointIds());
3286
      cellPoints.clear();
3287
      tetra->Delete();
3288
      }
5056
      }
3289
5057
3290
    //erronous cells
5058
    delete facesOfCell;
3291
    else if(totalPointCount == 0)
5059
    delete facePoints;
3292
      {
5060
    points->Delete();
3293
      vtkWarningMacro("Warning: No points in cell.");
5061
    }
3294
      }
5062
  this->UpdateProgress(0.5);
3295
5063
3296
    //OFpolyhedron || vtkConvexPointSet
5064
  if(updateVariables)
3297
    else
5065
    {
5066
    // read field data variables into Internal/Boundary meshes
5067
    for(int i = 0; i < (int)this->TimeStepData->value.size(); i++)
3298
      {
5068
      {
3299
      vtkWarningMacro("Warning: Polyhedral Data is very Slow!");
5069
      if(!this->GetVariableAtTimestep(this->InternalMesh, this->BoundaryMesh,
3300
      foundDup = false;
5070
        this->BoundaryDict, this->TimeStepData->value[i].c_str(), timeState))
3301
3302
      //grab face 0
3303
      for(j = 0; j < (int)this->FacePoints->value[this->FacesOfCell->value[
3304
        cellZone[i]][0].faceIndex].size(); j++)
3305
        {
5071
        {
3306
        firstFace.push_back(this->FacePoints->value[
5072
        // error occurred while reading a field data variable, but continue
3307
          this->FacesOfCell->value[i][0].faceIndex][j]);
5073
        // to the next variable
5074
        continue;
3308
        }
5075
        }
5076
      this->UpdateProgress(0.5
5077
        + 0.5 * ((float)(i + 1) / (float)this->TimeStepData->value.size()));
5078
      }
3309
5079
3310
      //ADD FIRST FACE TO CELL POINTS
5080
    // read lagrangian mesh and fields
3311
      for(j =0; j < (int)firstFace.size(); j++)
5081
    if(this->LagrangianTimeStepData->value.size() > 0
5082
      && this->GetPatchArrayStatus("Lagrangian Particles"))
5083
      {
5084
      // construct lagrangian mesh
5085
      lagrangianMesh = this->MakeLagrangianMesh(timeState);
5086
      if(lagrangianMesh == NULL)
3312
        {
5087
        {
3313
        cellPoints.push_back(firstFace[j]);
5088
        return 0;
3314
        }
5089
        }
3315
      //j = 1 skip firstFace
5090
3316
      for(j = 1; j < (int) this->FacesOfCell->value[
5091
      // read lagrangian variables
3317
           cellZone[i]].size(); j++)
5092
      for(size_t i = 0; i < this->LagrangianTimeStepData->value.size(); i++)
3318
        {
5093
        {
3319
        //remove duplicate points from faces
5094
        if(!this->GetLagrangianVariableAtTimestep(lagrangianMesh,
3320
        for(k = 0; k < (int)this->FacePoints->value[
5095
          this->LagrangianTimeStepData->value[i].c_str(), timeState))
3321
            this->FacesOfCell->value[i][j].faceIndex].size(); k++)
3322
          {
5096
          {
3323
          for(l = 0; l < (int)cellPoints.size(); l++);
5097
          // error occurred while reading a field data variable, but continue
3324
            {
5098
          // to the next variable
3325
            if(cellPoints[l] == this->FacePoints->value[this->FacesOfCell->
5099
          continue;
3326
                                value[cellZone[i]][j].faceIndex][k])
3327
              {
3328
              foundDup = true;
3329
              }
3330
            }
3331
          if(!foundDup)
3332
            {
3333
            cellPoints.push_back(this->FacePoints->value[this->FacesOfCell->
3334
                                 value[cellZone[i]][j].faceIndex][k]);
3335
            foundDup = false;
3336
            }
3337
          }
5100
          }
3338
        }
5101
        }
5102
      }
5103
    }
3339
5104
3340
      //create the poly cell and insert it into the mesh
5105
  // assign group to each of data and point/face/cell-Zones
3341
      vtkConvexPointSet * poly = vtkConvexPointSet::New();
5106
  int nGroups = 1 + ((lagrangianMesh != NULL
3342
      poly->GetPointIds()->SetNumberOfIds(cellPoints.size());
5107
    && lagrangianMesh->GetPointData()->GetNumberOfArrays() > 0) ? 1 : 0)
3343
      for(pCount = 0; pCount < (int)cellPoints.size(); pCount++)
5108
    + (this->PointZoneMesh != NULL ? 1 : 0)
3344
        {
5109
    + (this->FaceZoneMesh != NULL ? 1 : 0)
3345
        poly->GetPointIds()->SetId(pCount, cellPoints[pCount]);
5110
    + (this->CellZoneMesh != NULL ? 1 : 0);
3346
        }
5111
  output->SetNumberOfGroups(nGroups);
3347
      cellZoneMesh->InsertNextCell(poly->GetCellType(),
5112
3348
                                   poly->GetPointIds());
5113
  // set internal mesh/data as output
3349
      cellPoints.clear();
5114
  //output->SetNumberOfDataSets(0,output->GetNumberOfDataSets(0));
3350
      firstFace.clear();
5115
3351
      poly->Delete();
5116
  // Add Internal Mesh to final output only if selected for display
5117
  if(GetPatchArrayStatus(GetPatchArrayName(0)))
5118
    {
5119
    output->SetDataSet(0, output->GetNumberOfDataSets(0), this->InternalMesh);
5120
    }
5121
5122
  // set boundary meshes/data as output
5123
  for(size_t j = 0; j < this->BoundaryMesh->value.size(); j++)
5124
    {
5125
    output->SetDataSet(0, output->GetNumberOfDataSets(0),
5126
      this->BoundaryMesh->value[j]);
5127
    if(!this->CacheMesh)
5128
      {
5129
      this->BoundaryMesh->value[j]->Delete();
3352
      }
5130
      }
3353
    }
5131
    }
3354
  //set cell zone points
3355
  cellZoneMesh->SetPoints(Points);
3356
  input->close();
3357
  delete input;
3358
  vtkDebugMacro(<<"Cell zone mesh created");
3359
  return cellZoneMesh;
3360
}
3361
5132
3362
void vtkOpenFOAMReader::CreateDataSet(vtkMultiBlockDataSet *output)
5133
  if(!this->CacheMesh)
3363
{
5134
    {
3364
  int timeState = this->TimeStep;
5135
    // First check if these meshes exist before deleting them....
3365
  //create paths to polyMesh files
5136
    if(this->BoundaryMesh != NULL)
3366
  vtkstd::string boundaryPath = this->PathPrefix->value +
3367
                                this->PolyMeshFacesDir->value[timeState] +
3368
                                "/polyMesh/boundary";
3369
  vtkstd::string facePath = this->PathPrefix->value +
3370
                            this->PolyMeshFacesDir->value[timeState] +
3371
                            "/polyMesh/faces";
3372
  vtkstd::string ownerPath = this->PathPrefix->value +
3373
                             this->PolyMeshFacesDir->value[timeState] +
3374
                             "/polyMesh/owner";
3375
  vtkstd::string neighborPath = this->PathPrefix->value +
3376
                                this->PolyMeshFacesDir->value[timeState] +
3377
                                "/polyMesh/neighbour";
3378
  //create the faces vector
3379
  this->ReadFacesFile(facePath.c_str());
3380
3381
  //create the faces owner vector
3382
  this->ReadOwnerFile(ownerPath.c_str());
3383
3384
  //create the faces neighbor vector
3385
  this->ReadNeighborFile(neighborPath.c_str());
3386
3387
  //create a vector containing a faces of each cell
3388
  this->CombineOwnerNeigbor();
3389
3390
  this->GetPoints(timeState); //get the points
3391
3392
  //get the names of the regions
3393
  //this->BoundaryNames->value =
3394
  //  this->GatherBlocks("boundary", timeState)->value;
3395
  //this->PointZoneNames->value =
3396
  //  this->GatherBlocks("pointZones", timeState)->value;
3397
  //this->FaceZoneNames->value =
3398
  //  this->GatherBlocks("faceZones", timeState)->value;
3399
  //this->CellZoneNames->value =
3400
  //  this->GatherBlocks("cellZones", timeState)->value;
3401
3402
  //get the names of the regions
3403
  this->BoundaryNames =
3404
    this->GatherBlocks("boundary", timeState);
3405
  this->PointZoneNames =
3406
    this->GatherBlocks("pointZones", timeState);
3407
  this->FaceZoneNames =
3408
    this->GatherBlocks("faceZones", timeState);
3409
  this->CellZoneNames =
3410
    this->GatherBlocks("cellZones", timeState);
3411
3412
  int numBoundaries = this->BoundaryNames->value.size();
3413
  int numPointZones = this->PointZoneNames->value.size();
3414
  int numFaceZones = this->FaceZoneNames->value.size();
3415
  int numCellZones = this->CellZoneNames->value.size();
3416
3417
  //Internal Mesh
3418
  vtkUnstructuredGrid * internalMesh = this->MakeInternalMesh();
3419
  for(int i = 0; i < (int)this->TimeStepData->value.size(); i++)
3420
    {
3421
    vtkDoubleArray * data =
3422
      this->GetInternalVariableAtTimestep(this->TimeStepData->value[i].c_str(),
3423
                                          timeState);
3424
    if(data->GetSize() > 0)
3425
      {
5137
      {
3426
      data->SetName(this->TimeStepData->value[i].c_str());
5138
      delete this->BoundaryMesh;
3427
      internalMesh->GetCellData()->AddArray(data);
5139
      this->BoundaryMesh = NULL;
3428
      }
5140
      }
3429
    data->Delete();
5141
    if(this->InternalMesh != NULL)
5142
      {
5143
      this->InternalMesh->Delete();
5144
      this->InternalMesh = NULL;
5145
      }
5146
    delete this->BoundaryDict;
5147
    this->BoundaryDict = NULL;
5148
    this->FaceOwner->Delete();
5149
    this->FaceOwner = NULL;
3430
    }
5150
    }
3431
  //output->SetNumberOfDataSets(0,output->GetNumberOfDataSets(0));
3432
  output->SetDataSet(0, output->GetNumberOfDataSets(0), internalMesh);
3433
5151
3434
  //Boundary Meshes
5152
  int groupI = 0;
3435
  for(int i = 0; i < (int)numBoundaries; i++)
5153
5154
  // set lagrangian mesh as output
5155
  if(lagrangianMesh != NULL
5156
    && lagrangianMesh->GetPointData()->GetNumberOfArrays() > 0)
3436
    {
5157
    {
3437
    vtkUnstructuredGrid * boundaryMesh = this->GetBoundaryMesh(timeState, i);
5158
    groupI++;
3438
    for(int j = 0; j < (int)this->TimeStepData->value.size(); j++)
5159
    output->SetDataSet(groupI, output->GetNumberOfDataSets(groupI),
5160
      lagrangianMesh);
5161
    lagrangianMesh->Delete();
5162
    }
5163
5164
  // set Zone Meshes as output
5165
  if(this->PointZoneMesh != NULL)
5166
    {
5167
    groupI++;
5168
    for(size_t i = 0; i < this->PointZoneMesh->value.size(); i++)
3439
      {
5169
      {
3440
      vtkDoubleArray * data =
5170
      output->SetDataSet(groupI, output->GetNumberOfDataSets(groupI),
3441
        this->GetBoundaryVariableAtTimestep(i, TimeStepData->value[j].c_str(),
5171
        this->PointZoneMesh->value[i]);
3442
                                            timeState, internalMesh);
5172
      if(!this->CacheMesh)
3443
      if(data->GetSize() > 0)
3444
        {
5173
        {
3445
        data->SetName(this->TimeStepData->value[j].c_str());
5174
        this->PointZoneMesh->value[i]->Delete();
3446
        boundaryMesh->GetCellData()->AddArray(data);
3447
        }
5175
        }
3448
      data->Delete();
3449
      }
5176
      }
3450
    output->SetDataSet(0, output->GetNumberOfDataSets(0), boundaryMesh);
5177
    if(!this->CacheMesh)
3451
    boundaryMesh->Delete();
5178
      {
5179
      delete this->PointZoneMesh;
5180
      this->PointZoneMesh = NULL;
5181
      }
3452
    }
5182
    }
3453
5183
3454
  internalMesh->Delete();
5184
  if(this->FaceZoneMesh != NULL)
3455
  this->FaceOwner->Delete();
3456
  //Zone Meshes
3457
  for(int i = 0; i < (int)numPointZones; i++)
3458
    {
5185
    {
3459
    vtkUnstructuredGrid * pointMesh = this->GetPointZoneMesh(timeState, i);
5186
    groupI++;
3460
    output->SetDataSet(0, output->GetNumberOfDataSets(0),
5187
    for(size_t i = 0; i < this->FaceZoneMesh->value.size(); i++)
3461
                       pointMesh);
5188
      {
3462
    pointMesh->Delete();
5189
      output->SetDataSet(groupI, output->GetNumberOfDataSets(groupI),
5190
        this->FaceZoneMesh->value[i]);
5191
      if(!this->CacheMesh)
5192
        {
5193
        this->FaceZoneMesh->value[i]->Delete();
5194
        }
5195
      }
5196
    if(!this->CacheMesh)
5197
      {
5198
      delete this->FaceZoneMesh;
5199
      this->FaceZoneMesh = NULL;
5200
      }
3463
    }
5201
    }
3464
  for(int i = 0; i < (int)numFaceZones; i++)
5202
5203
  if(this->CellZoneMesh != NULL)
3465
    {
5204
    {
3466
    vtkUnstructuredGrid * faceMesh = this->GetFaceZoneMesh(timeState, i);
5205
    groupI++;
3467
    output->SetDataSet(0, output->GetNumberOfDataSets(0),
5206
    for(size_t i = 0; i < this->CellZoneMesh->value.size(); i++)
3468
                       faceMesh);
5207
      {
3469
    faceMesh->Delete();
5208
      output->SetDataSet(groupI, output->GetNumberOfDataSets(groupI),
5209
        this->CellZoneMesh->value[i]);
5210
      if(!this->CacheMesh)
5211
        {
5212
        this->CellZoneMesh->value[i]->Delete();
5213
        }
5214
      }
5215
    if(!this->CacheMesh)
5216
      {
5217
      delete this->CellZoneMesh;
5218
      this->CellZoneMesh = NULL;
5219
      }
3470
    }
5220
    }
3471
  for(int i = 0; i < (int)numCellZones; i++)
5221
5222
  if(this->CacheMesh)
3472
    {
5223
    {
3473
    vtkUnstructuredGrid * cellMesh = this->GetCellZoneMesh(timeState, i);
5224
    this->OldTimeStep = timeState;
3474
    output->SetDataSet(0, output->GetNumberOfDataSets(0),
3475
                       cellMesh);
3476
    cellMesh->Delete();
3477
    }
5225
    }
3478
  return;
5226
  else
3479
}
3480
stdString * vtkOpenFOAMReader::GetLine(ifstream * file)
3481
{
3482
  char tempChar;
3483
  stdString * buffer = new stdString;
3484
  while(file->peek() != '\n')
3485
    {
5227
    {
3486
    file->get(tempChar);
5228
    this->OldTimeStep = -1;
3487
    buffer->value += tempChar;
3488
    }
5229
    }
3489
  file->get(tempChar); //throw out \n
5230
3490
  return buffer;
5231
  return 1;
3491
}
5232
}
(-)ParaView3.orig/VTK/IO/vtkOpenFOAMReader.h (-46 / +154 lines)
Lines 37-52 Link Here
37
} face;
37
} face;
38
38
39
class vtkUnstructuredGrid;
39
class vtkUnstructuredGrid;
40
class vtkPolyData;
40
class vtkPoints;
41
class vtkPoints;
41
class vtkIntArray;
42
class vtkIntArray;
42
class vtkFloatArray;
43
class vtkStringArray;
43
class vtkDoubleArray;
44
class vtkDataArraySelection;
44
class vtkDataArraySelection;
45
struct stdString;
45
class vtkCallbackCommand;
46
class vtkStdString;
46
struct stringVector;
47
struct stringVector;
47
struct intVector;
48
struct intVector;
48
struct intVectorVector;
49
struct intVectorVector;
49
struct faceVectorVector;
50
struct faceVectorVector;
51
struct unstructuredGridVector;
50
52
51
class VTK_IO_EXPORT vtkOpenFOAMReader : public vtkMultiBlockDataSetAlgorithm
53
class VTK_IO_EXPORT vtkOpenFOAMReader : public vtkMultiBlockDataSetAlgorithm
52
{
54
{
Lines 93-108 Link Here
93
  void DisableAllCellArrays();
95
  void DisableAllCellArrays();
94
  void EnableAllCellArrays();
96
  void EnableAllCellArrays();
95
97
98
  // Description:
99
  // Get the number of point arrays available in the input.
100
  int GetNumberOfPointArrays(void);
101
102
  // Description:
103
  // Get/Set whether the point array with the given name is to
104
  // be read.
105
  int GetPointArrayStatus(const char* name);
106
  void SetPointArrayStatus(const char* name, int status);
107
108
  // Description:
109
  // Get the name of the  point array with the given index in
110
  // the input.
111
  const char* GetPointArrayName(int index);
112
113
  // Description:
114
  // Turn on/off all point arrays.
115
  void DisableAllPointArrays();
116
  void EnableAllPointArrays();
117
118
  // Description:
119
  // Get the number of Patches (inlcuding Internal Mesh) available in the input.
120
  int GetNumberOfPatchArrays(void);
121
122
  // Description:
123
  // Get/Set whether the Patch with the given name is to
124
  // be read.
125
  int GetPatchArrayStatus(const char* name);
126
  void SetPatchArrayStatus(const char* name, int status);
127
128
  // Description:
129
  // Get the name of the Patch with the given index in
130
  // the input.
131
  const char* GetPatchArrayName(int index);
132
133
  // Description:
134
  // Turn on/off all Patches including the Internal Mesh.
135
  void DisableAllPatchArrays();
136
  void EnableAllPatchArrays();
137
138
  // Selection observer callback functions
139
  static void SelectionModifiedCallback
140
  (
141
    vtkObject* caller,
142
    unsigned long eid,
143
    void* clientdata,
144
    void* calldata
145
  );
146
147
  void SelectionModified();
148
149
  // Description:
150
  // Set/Get whether mesh is to be cached.
151
  vtkSetMacro(CacheMesh, int);
152
  vtkGetMacro(CacheMesh, int);
153
  vtkBooleanMacro(CacheMesh, int);
154
155
  // Option to accumulate patches and fields across time steps
156
  // Description:
157
  // Set/Get whether the patches are listed even if size = 0
158
  vtkSetMacro(KeepPatches,int);
159
  vtkGetMacro(KeepPatches,int);
160
  vtkBooleanMacro(KeepPatches, int);
161
162
  // Description:
163
  // Set/Get whether zones will be read.
164
  vtkSetMacro(ReadZones, int);
165
  vtkGetMacro(ReadZones, int);
166
  vtkBooleanMacro(ReadZones, int);
96
167
97
protected:
168
protected:
169
  // for caching mesh
170
  int CacheMesh;
171
  // for reading point/face/cell-Zones
172
  int ReadZones;
173
174
  // for accumulating patches across time steps
175
  int KeepPatches;
176
98
  vtkOpenFOAMReader();
177
  vtkOpenFOAMReader();
99
  ~vtkOpenFOAMReader();
178
  ~vtkOpenFOAMReader();
100
  int RequestData(vtkInformation *,
179
  int RequestData(vtkInformation *, vtkInformationVector **,
101
    vtkInformationVector **, vtkInformationVector *);
180
    vtkInformationVector *);
102
  int RequestInformation(vtkInformation *,
181
  int RequestInformation(vtkInformation *, vtkInformationVector **,
103
    vtkInformationVector **, vtkInformationVector *);
182
    vtkInformationVector *);
104
183
105
private:
184
private:
185
186
  struct vtkFoamError;
187
  struct vtkFoamToken;
188
  struct vtkFoamFile;
189
  struct vtkFoamIOobject;
190
  struct vtkFoamEntryValue;
191
  struct vtkFoamEntry;
192
  struct vtkFoamDict;
193
106
  vtkOpenFOAMReader(const vtkOpenFOAMReader&);  // Not implemented.
194
  vtkOpenFOAMReader(const vtkOpenFOAMReader&);  // Not implemented.
107
  void operator=(const vtkOpenFOAMReader&);  // Not implemented.
195
  void operator=(const vtkOpenFOAMReader&);  // Not implemented.
108
196
Lines 113-164 Link Here
113
  int TimeStep;
201
  int TimeStep;
114
  int TimeStepRange[2];
202
  int TimeStepRange[2];
115
  double * Steps;
203
  double * Steps;
116
  bool RequestInformationFlag;
117
  int StartFace;
118
204
119
  stdString * Path;
205
  // Selection Observer for translating GUI Changes to Mesh Updates
120
  stdString * PathPrefix;
206
  vtkCallbackCommand * SelectionObserver;
121
  stringVector * TimeStepData;
207
208
  // DataArraySelection for Patch / Region Data
209
  vtkDataArraySelection * PatchDataArraySelection;
122
  vtkDataArraySelection * CellDataArraySelection;
210
  vtkDataArraySelection * CellDataArraySelection;
123
  intVectorVector * FacePoints;
211
  vtkDataArraySelection * PointDataArraySelection;
124
  intVectorVector * FacesOwnerCell;
212
125
  intVectorVector * FacesNeighborCell;
213
  // Previous and Current Status of each of the selection arrays (in
126
  faceVectorVector * FacesOfCell;
214
  // Bitwise form). Maximum 31 patches or fields support as of now
127
  vtkPoints * Points;
215
  // (since we use LSB for overflow handling)
216
  unsigned long CellSelectionOldStatus;
217
  unsigned long PointSelectionOldStatus;
218
  unsigned long PatchSelectionOldStatus;
219
  unsigned long CellSelectionStatus;
220
  unsigned long PointSelectionStatus;
221
  unsigned long PatchSelectionStatus;
222
223
  vtkStdString* OldFileName;
224
  vtkStdString* PathPrefix;
225
  vtkStringArray *TimeNames;
226
  stringVector * TimeStepData;
227
  stringVector * LagrangianTimeStepData;
228
128
  vtkIdType NumCells;
229
  vtkIdType NumCells;
129
  vtkIdType NumFaces;
130
  vtkIntArray * FaceOwner;
230
  vtkIntArray * FaceOwner;
131
  //vtkIntArray * FaceNeighbor;
132
  stringVector * PolyMeshPointsDir;
231
  stringVector * PolyMeshPointsDir;
133
  stringVector * PolyMeshFacesDir;
232
  stringVector * PolyMeshFacesDir;
134
  vtkIdType NumPoints;
233
135
  intVector * SizeOfBoundary;
234
  // for caching mesh
136
  stringVector * BoundaryNames;
235
  int OldTimeStep;
137
  stringVector * PointZoneNames;
236
  vtkUnstructuredGrid* InternalMesh;
138
  stringVector * FaceZoneNames;
237
  unstructuredGridVector* BoundaryMesh;
139
  stringVector * CellZoneNames;
238
  vtkFoamDict* BoundaryDict;
140
  int NumBlocks;
239
  unstructuredGridVector* PointZoneMesh;
141
240
  unstructuredGridVector* FaceZoneMesh;
142
  void CombineOwnerNeigbor();
241
  unstructuredGridVector* CellZoneMesh;
143
  vtkUnstructuredGrid * MakeInternalMesh();
242
144
  double ControlDictDataParser(const char *);
243
  // member functions
145
  void ReadControlDict ();
244
  void ClearMeshes();
146
  void GetPoints (int);
245
  void MakeTimeStepData();
147
  void ReadFacesFile (const char *);
246
  void InsertCellToGrid(vtkUnstructuredGrid *, int, faceVectorVector *,
148
  void ReadOwnerFile(const char *);
247
    intVectorVector*);
149
  void ReadNeighborFile(const char *);
248
  vtkUnstructuredGrid * MakeInternalMesh(faceVectorVector *, intVectorVector *,
249
    vtkPoints *);
250
  bool ListTimeDirectoriesByControlDict(vtkFoamDict* dict);
251
  bool ListTimeDirectoriesByInstances();
252
  bool ReadControlDict(const char *);
253
  vtkPoints* GetPoints (int);
254
  intVectorVector* ReadFacesFile (const char *);
255
  bool ReadOwnerNeighborFiles(faceVectorVector *, const char *, const char *);
150
  void PopulatePolyMeshDirArrays();
256
  void PopulatePolyMeshDirArrays();
151
  const char * GetDataType(const char *, const char *);
257
  bool GetVariableAtTimestep(vtkUnstructuredGrid*, unstructuredGridVector*,
152
  vtkDoubleArray * GetInternalVariableAtTimestep(const char *, int);
258
    vtkFoamDict*, const char*, int);
153
  vtkDoubleArray * GetBoundaryVariableAtTimestep(int, const char *, int,
259
  vtkFoamDict* GatherBlocks(const char *, int, bool);
154
                                                 vtkUnstructuredGrid *);
260
  unstructuredGridVector* GetBoundaryMesh(vtkFoamDict*, intVectorVector *,
155
  stringVector *GatherBlocks(const char *, int);
261
    vtkPoints *);
156
  vtkUnstructuredGrid * GetBoundaryMesh(int, int);
262
  bool GetPointZoneMesh(unstructuredGridVector*, vtkPoints*, int);
157
  vtkUnstructuredGrid * GetPointZoneMesh(int, int);
263
  bool GetFaceZoneMesh(unstructuredGridVector *, intVectorVector *,
158
  vtkUnstructuredGrid * GetFaceZoneMesh(int, int);
264
    vtkPoints *, int);
159
  vtkUnstructuredGrid * GetCellZoneMesh(int, int);
265
  bool GetCellZoneMesh(unstructuredGridVector *, faceVectorVector *,
160
  void CreateDataSet(vtkMultiBlockDataSet *);
266
    intVectorVector *, vtkPoints *, int);
161
  stdString * GetLine(ifstream *);
267
  vtkPolyData* MakeLagrangianMesh(int);
268
  bool GetLagrangianVariableAtTimestep(vtkPolyData*, const char*, int);
269
  int CreateDataSet(vtkMultiBlockDataSet *, int);
162
};
270
};
163
271
164
#endif
272
#endif

Return to bug 202685